Merge "recovery: use __android_log_pmsg_file_write for log files"
diff --git a/bootloader.cpp b/bootloader.cpp
index d80c5e7..a32f8b4 100644
--- a/bootloader.cpp
+++ b/bootloader.cpp
@@ -29,7 +29,7 @@
 #include "common.h"
 #include "mtdutils/mtdutils.h"
 #include "roots.h"
-#include "unique_fd.h"
+#include <android-base/unique_fd.h>
 
 static int get_bootloader_message_mtd(bootloader_message* out, const Volume* v);
 static int set_bootloader_message_mtd(const bootloader_message* in, const Volume* v);
@@ -191,8 +191,8 @@
 static int set_bootloader_message_block(const bootloader_message* in,
                                         const Volume* v) {
     wait_for_device(v->blk_device);
-    unique_fd fd(open(v->blk_device, O_WRONLY | O_SYNC));
-    if (fd.get() == -1) {
+    android::base::unique_fd fd(open(v->blk_device, O_WRONLY | O_SYNC));
+    if (fd == -1) {
         LOGE("failed to open \"%s\": %s\n", v->blk_device, strerror(errno));
         return -1;
     }
@@ -201,7 +201,7 @@
     const uint8_t* start = reinterpret_cast<const uint8_t*>(in);
     size_t total = sizeof(*in);
     while (written < total) {
-        ssize_t wrote = TEMP_FAILURE_RETRY(write(fd.get(), start + written, total - written));
+        ssize_t wrote = TEMP_FAILURE_RETRY(write(fd, start + written, total - written));
         if (wrote == -1) {
             LOGE("failed to write %" PRId64 " bytes: %s\n",
                  static_cast<off64_t>(written), strerror(errno));
@@ -210,7 +210,7 @@
         written += wrote;
     }
 
-    if (fsync(fd.get()) == -1) {
+    if (fsync(fd) == -1) {
         LOGE("failed to fsync \"%s\": %s\n", v->blk_device, strerror(errno));
         return -1;
     }
diff --git a/tools/recovery_l10n/res/values/strings.xml b/tools/recovery_l10n/res/values/strings.xml
index 3a8aeec..f6193ab 100644
--- a/tools/recovery_l10n/res/values/strings.xml
+++ b/tools/recovery_l10n/res/values/strings.xml
@@ -31,4 +31,8 @@
        LIMIT=60] -->
   <string name="recovery_error">Error!</string>
 
+  <!-- Displayed on the screen beneath the animation while the
+       system is installing a security update. [CHAR LIMIT=60] -->
+  <string name="recovery_installing_security">Installing security update\u2026</string>
+
 </resources>
diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp
index 705744e..43a2c2a 100644
--- a/uncrypt/uncrypt.cpp
+++ b/uncrypt/uncrypt.cpp
@@ -61,6 +61,7 @@
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
+#include <android-base/unique_fd.h>
 #include <cutils/android_reboot.h>
 #include <cutils/properties.h>
 #include <fs_mgr.h>
@@ -69,7 +70,6 @@
 #include <log/log.h>
 
 #include "bootloader.h"
-#include "unique_fd.h"
 
 #define WINDOW_SIZE 5
 
@@ -174,8 +174,9 @@
         return -1;
     }
     std::string tmp_map_file = std::string(map_file) + ".tmp";
-    unique_fd mapfd(open(tmp_map_file.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR));
-    if (!mapfd) {
+    android::base::unique_fd mapfd(open(tmp_map_file.c_str(),
+                                        O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR));
+    if (mapfd == -1) {
         ALOGE("failed to open %s: %s\n", tmp_map_file.c_str(), strerror(errno));
         return -1;
     }
@@ -201,7 +202,7 @@
 
     std::string s = android::base::StringPrintf("%s\n%" PRId64 " %ld\n",
                        blk_dev, sb.st_size, static_cast<long>(sb.st_blksize));
-    if (!android::base::WriteStringToFd(s, mapfd.get())) {
+    if (!android::base::WriteStringToFd(s, mapfd)) {
         ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
         return -1;
     }
@@ -213,16 +214,16 @@
     int head_block = 0;
     int head = 0, tail = 0;
 
-    unique_fd fd(open(path, O_RDONLY));
-    if (!fd) {
+    android::base::unique_fd fd(open(path, O_RDONLY));
+    if (fd == -1) {
         ALOGE("failed to open %s for reading: %s", path, strerror(errno));
         return -1;
     }
 
-    unique_fd wfd(-1);
+    android::base::unique_fd wfd;
     if (encrypted) {
-        wfd = open(blk_dev, O_WRONLY);
-        if (!wfd) {
+        wfd.reset(open(blk_dev, O_WRONLY));
+        if (wfd == -1) {
             ALOGE("failed to open fd for writing: %s", strerror(errno));
             return -1;
         }
@@ -241,14 +242,14 @@
         if ((tail+1) % WINDOW_SIZE == head) {
             // write out head buffer
             int block = head_block;
-            if (ioctl(fd.get(), FIBMAP, &block) != 0) {
+            if (ioctl(fd, FIBMAP, &block) != 0) {
                 ALOGE("failed to find block %d", head_block);
                 return -1;
             }
             add_block_to_ranges(ranges, block);
             if (encrypted) {
-                if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd.get(),
-                        static_cast<off64_t>(sb.st_blksize) * block) != 0) {
+                if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
+                                    static_cast<off64_t>(sb.st_blksize) * block) != 0) {
                     return -1;
                 }
             }
@@ -260,7 +261,7 @@
         if (encrypted) {
             size_t to_read = static_cast<size_t>(
                     std::min(static_cast<off64_t>(sb.st_blksize), sb.st_size - pos));
-            if (!android::base::ReadFully(fd.get(), buffers[tail].data(), to_read)) {
+            if (!android::base::ReadFully(fd, buffers[tail].data(), to_read)) {
                 ALOGE("failed to read: %s", strerror(errno));
                 return -1;
             }
@@ -277,14 +278,14 @@
     while (head != tail) {
         // write out head buffer
         int block = head_block;
-        if (ioctl(fd.get(), FIBMAP, &block) != 0) {
+        if (ioctl(fd, FIBMAP, &block) != 0) {
             ALOGE("failed to find block %d", head_block);
             return -1;
         }
         add_block_to_ranges(ranges, block);
         if (encrypted) {
-            if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd.get(),
-                    static_cast<off64_t>(sb.st_blksize) * block) != 0) {
+            if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
+                                static_cast<off64_t>(sb.st_blksize) * block) != 0) {
                 return -1;
             }
         }
@@ -293,38 +294,36 @@
     }
 
     if (!android::base::WriteStringToFd(
-            android::base::StringPrintf("%zu\n", ranges.size() / 2), mapfd.get())) {
+            android::base::StringPrintf("%zu\n", ranges.size() / 2), mapfd)) {
         ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
         return -1;
     }
     for (size_t i = 0; i < ranges.size(); i += 2) {
         if (!android::base::WriteStringToFd(
-                android::base::StringPrintf("%d %d\n", ranges[i], ranges[i+1]), mapfd.get())) {
+                android::base::StringPrintf("%d %d\n", ranges[i], ranges[i+1]), mapfd)) {
             ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
             return -1;
         }
     }
 
-    if (fsync(mapfd.get()) == -1) {
+    if (fsync(mapfd) == -1) {
         ALOGE("failed to fsync \"%s\": %s", tmp_map_file.c_str(), strerror(errno));
         return -1;
     }
-    if (close(mapfd.get() == -1)) {
+    if (close(mapfd.release()) == -1) {
         ALOGE("failed to close %s: %s", tmp_map_file.c_str(), strerror(errno));
         return -1;
     }
-    mapfd = -1;
 
     if (encrypted) {
-        if (fsync(wfd.get()) == -1) {
+        if (fsync(wfd) == -1) {
             ALOGE("failed to fsync \"%s\": %s", blk_dev, strerror(errno));
             return -1;
         }
-        if (close(wfd.get()) == -1) {
+        if (close(wfd.release()) == -1) {
             ALOGE("failed to close %s: %s", blk_dev, strerror(errno));
             return -1;
         }
-        wfd = -1;
     }
 
     if (rename(tmp_map_file.c_str(), map_file) == -1) {
@@ -334,20 +333,19 @@
     // Sync dir to make rename() result written to disk.
     std::string file_name = map_file;
     std::string dir_name = dirname(&file_name[0]);
-    unique_fd dfd(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY));
-    if (!dfd) {
+    android::base::unique_fd dfd(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY));
+    if (dfd == -1) {
         ALOGE("failed to open dir %s: %s", dir_name.c_str(), strerror(errno));
         return -1;
     }
-    if (fsync(dfd.get()) == -1) {
+    if (fsync(dfd) == -1) {
         ALOGE("failed to fsync %s: %s", dir_name.c_str(), strerror(errno));
         return -1;
     }
-    if (close(dfd.get() == -1)) {
+    if (close(dfd.release()) == -1) {
         ALOGE("failed to close %s: %s", dir_name.c_str(), strerror(errno));
         return -1;
     }
-    dfd = -1;
     return 0;
 }
 
@@ -365,41 +363,23 @@
     return "";
 }
 
-static int read_bootloader_message(bootloader_message* out) {
-    std::string misc_blk_device = get_misc_blk_device();
-    if (misc_blk_device.empty()) {
-        ALOGE("failed to find /misc partition.");
-        return -1;
-    }
-    unique_fd fd(open(misc_blk_device.c_str(), O_RDONLY));
-    if (!fd) {
-        ALOGE("failed to open %s: %s", misc_blk_device.c_str(), strerror(errno));
-        return -1;
-    }
-    if (!android::base::ReadFully(fd.get(), out, sizeof(*out))) {
-        ALOGE("failed to read %s: %s", misc_blk_device.c_str(), strerror(errno));
-        return -1;
-    }
-    return 0;
-}
-
 static int write_bootloader_message(const bootloader_message* in) {
     std::string misc_blk_device = get_misc_blk_device();
     if (misc_blk_device.empty()) {
         ALOGE("failed to find /misc partition.");
         return -1;
     }
-    unique_fd fd(open(misc_blk_device.c_str(), O_WRONLY | O_SYNC));
-    if (!fd) {
+    android::base::unique_fd fd(open(misc_blk_device.c_str(), O_WRONLY | O_SYNC));
+    if (fd == -1) {
         ALOGE("failed to open %s: %s", misc_blk_device.c_str(), strerror(errno));
         return -1;
     }
-    if (!android::base::WriteFully(fd.get(), in, sizeof(*in))) {
+    if (!android::base::WriteFully(fd, in, sizeof(*in))) {
         ALOGE("failed to write %s: %s", misc_blk_device.c_str(), strerror(errno));
         return -1;
     }
     // TODO: O_SYNC and fsync() duplicates each other?
-    if (fsync(fd.get()) == -1) {
+    if (fsync(fd) == -1) {
         ALOGE("failed to fsync %s: %s", misc_blk_device.c_str(), strerror(errno));
         return -1;
     }
@@ -465,8 +445,9 @@
 static int uncrypt_wrapper(const char* input_path, const char* map_file,
                            const std::string& status_file) {
     // The pipe has been created by the system server.
-    unique_fd status_fd(open(status_file.c_str(), O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR));
-    if (!status_fd) {
+    android::base::unique_fd status_fd(open(status_file.c_str(),
+                                            O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR));
+    if (status_fd == -1) {
         ALOGE("failed to open pipe \"%s\": %s", status_file.c_str(), strerror(errno));
         return 1;
     }
@@ -474,46 +455,48 @@
     std::string package;
     if (input_path == nullptr) {
         if (!find_uncrypt_package(UNCRYPT_PATH_FILE, &package)) {
-            android::base::WriteStringToFd("-1\n", status_fd.get());
+            android::base::WriteStringToFd("-1\n", status_fd);
             return 1;
         }
         input_path = package.c_str();
     }
     CHECK(map_file != nullptr);
-    int status = uncrypt(input_path, map_file, status_fd.get());
+    int status = uncrypt(input_path, map_file, status_fd);
     if (status != 0) {
-        android::base::WriteStringToFd("-1\n", status_fd.get());
+        android::base::WriteStringToFd("-1\n", status_fd);
         return 1;
     }
-    android::base::WriteStringToFd("100\n", status_fd.get());
+    android::base::WriteStringToFd("100\n", status_fd);
     return 0;
 }
 
 static int clear_bcb(const std::string& status_file) {
-    unique_fd status_fd(open(status_file.c_str(), O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR));
-    if (!status_fd) {
+    android::base::unique_fd status_fd(open(status_file.c_str(),
+                                            O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR));
+    if (status_fd == -1) {
         ALOGE("failed to open pipe \"%s\": %s", status_file.c_str(), strerror(errno));
         return 1;
     }
     bootloader_message boot = {};
     if (write_bootloader_message(&boot) != 0) {
-        android::base::WriteStringToFd("-1\n", status_fd.get());
+        android::base::WriteStringToFd("-1\n", status_fd);
         return 1;
     }
-    android::base::WriteStringToFd("100\n", status_fd.get());
+    android::base::WriteStringToFd("100\n", status_fd);
     return 0;
 }
 
 static int setup_bcb(const std::string& command_file, const std::string& status_file) {
-    unique_fd status_fd(open(status_file.c_str(), O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR));
-    if (!status_fd) {
+    android::base::unique_fd status_fd(open(status_file.c_str(),
+                                            O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR));
+    if (status_fd == -1) {
         ALOGE("failed to open pipe \"%s\": %s", status_file.c_str(), strerror(errno));
         return 1;
     }
     std::string content;
     if (!android::base::ReadFileToString(command_file, &content)) {
         ALOGE("failed to read \"%s\": %s", command_file.c_str(), strerror(errno));
-        android::base::WriteStringToFd("-1\n", status_fd.get());
+        android::base::WriteStringToFd("-1\n", status_fd);
         return 1;
     }
     bootloader_message boot = {};
@@ -522,21 +505,10 @@
     strlcat(boot.recovery, content.c_str(), sizeof(boot.recovery));
     if (write_bootloader_message(&boot) != 0) {
         ALOGE("failed to set bootloader message");
-        android::base::WriteStringToFd("-1\n", status_fd.get());
+        android::base::WriteStringToFd("-1\n", status_fd);
         return 1;
     }
-    android::base::WriteStringToFd("100\n", status_fd.get());
-    return 0;
-}
-
-static int read_bcb() {
-    bootloader_message boot;
-    if (read_bootloader_message(&boot) != 0) {
-        ALOGE("failed to get bootloader message");
-        return 1;
-    }
-    printf("bcb command: %s\n", boot.command);
-    printf("bcb recovery:\n%s\n", boot.recovery);
+    android::base::WriteStringToFd("100\n", status_fd);
     return 0;
 }
 
@@ -546,7 +518,6 @@
     fprintf(stderr, "%s --reboot  Clear BCB data and reboot to recovery.\n", exename);
     fprintf(stderr, "%s --clear-bcb  Clear BCB data in misc partition.\n", exename);
     fprintf(stderr, "%s --setup-bcb  Setup BCB data by command file.\n", exename);
-    fprintf(stderr, "%s --read-bcb   Read BCB data from misc partition.\n", exename);
 }
 
 int main(int argc, char** argv) {
@@ -557,8 +528,6 @@
             return clear_bcb(STATUS_FILE);
         } else if (strcmp(argv[1], "--setup-bcb") == 0) {
             return setup_bcb(COMMAND_FILE, STATUS_FILE);
-        } else if (strcmp(argv[1], "--read-bcb") == 0) {
-            return read_bcb();
         }
     } else if (argc == 1 || argc == 3) {
         const char* input_path = nullptr;
diff --git a/unique_fd.h b/unique_fd.h
deleted file mode 100644
index cc85383..0000000
--- a/unique_fd.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef UNIQUE_FD_H
-#define UNIQUE_FD_H
-
-#include <stdio.h>
-
-#include <memory>
-
-class unique_fd {
-  public:
-    unique_fd(int fd) : fd_(fd) { }
-
-    unique_fd(unique_fd&& uf) {
-        fd_ = uf.fd_;
-        uf.fd_ = -1;
-    }
-
-    ~unique_fd() {
-        if (fd_ != -1) {
-            close(fd_);
-        }
-    }
-
-    int get() {
-        return fd_;
-    }
-
-    // Movable.
-    unique_fd& operator=(unique_fd&& uf) {
-        fd_ = uf.fd_;
-        uf.fd_ = -1;
-        return *this;
-    }
-
-    explicit operator bool() const {
-        return fd_ != -1;
-    }
-
-  private:
-    int fd_;
-
-    // Non-copyable.
-    unique_fd(const unique_fd&) = delete;
-    unique_fd& operator=(const unique_fd&) = delete;
-};
-
-#endif  // UNIQUE_FD_H
diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp
index 9d329cd..908e116 100644
--- a/updater/blockimg.cpp
+++ b/updater/blockimg.cpp
@@ -40,6 +40,7 @@
 
 #include <android-base/parseint.h>
 #include <android-base/strings.h>
+#include <android-base/unique_fd.h>
 
 #include "applypatch/applypatch.h"
 #include "edify/expr.h"
@@ -48,7 +49,6 @@
 #include "minzip/Hash.h"
 #include "ota_io.h"
 #include "print_sha1.h"
-#include "unique_fd.h"
 #include "updater.h"
 
 #define BLOCKSIZE 4096
@@ -368,7 +368,7 @@
     std::string stashbase;
     bool canwrite;
     int createdstash;
-    int fd;
+    android::base::unique_fd fd;
     bool foundwrites;
     bool isunresumable;
     int version;
@@ -577,9 +577,7 @@
         return -1;
     }
 
-    int fd = TEMP_FAILURE_RETRY(ota_open(fn.c_str(), O_RDONLY));
-    unique_fd fd_holder(fd);
-
+    android::base::unique_fd fd(TEMP_FAILURE_RETRY(ota_open(fn.c_str(), O_RDONLY)));
     if (fd == -1) {
         fprintf(stderr, "open \"%s\" failed: %s\n", fn.c_str(), strerror(errno));
         return -1;
@@ -634,9 +632,9 @@
 
     fprintf(stderr, " writing %d blocks to %s\n", blocks, cn.c_str());
 
-    int fd = TEMP_FAILURE_RETRY(ota_open(fn.c_str(), O_WRONLY | O_CREAT | O_TRUNC, STASH_FILE_MODE));
-    unique_fd fd_holder(fd);
-
+    android::base::unique_fd fd(TEMP_FAILURE_RETRY(ota_open(fn.c_str(),
+                                                            O_WRONLY | O_CREAT | O_TRUNC,
+                                                            STASH_FILE_MODE)));
     if (fd == -1) {
         fprintf(stderr, "failed to create \"%s\": %s\n", fn.c_str(), strerror(errno));
         return -1;
@@ -658,9 +656,8 @@
     }
 
     std::string dname = GetStashFileName(base, "", "");
-    int dfd = TEMP_FAILURE_RETRY(ota_open(dname.c_str(), O_RDONLY | O_DIRECTORY));
-    unique_fd dfd_holder(dfd);
-
+    android::base::unique_fd dfd(TEMP_FAILURE_RETRY(ota_open(dname.c_str(),
+                                                             O_RDONLY | O_DIRECTORY)));
     if (dfd == -1) {
         fprintf(stderr, "failed to open \"%s\" failed: %s\n", dname.c_str(), strerror(errno));
         return -1;
@@ -942,8 +939,8 @@
         tgthash = params.tokens[params.cpos++];
     }
 
-    if (LoadSrcTgtVersion2(params, tgt, src_blocks, params.buffer, params.fd, params.stashbase,
-            &overlap) == -1) {
+    if (LoadSrcTgtVersion2(params, tgt, src_blocks, params.buffer, params.fd,
+                           params.stashbase, &overlap) == -1) {
         return -1;
     }
 
@@ -1385,9 +1382,7 @@
         return StringValue(strdup(""));
     }
 
-    params.fd = TEMP_FAILURE_RETRY(ota_open(blockdev_filename->data, O_RDWR));
-    unique_fd fd_holder(params.fd);
-
+    params.fd.reset(TEMP_FAILURE_RETRY(ota_open(blockdev_filename->data, O_RDWR)));
     if (params.fd == -1) {
         fprintf(stderr, "open \"%s\" failed: %s\n", blockdev_filename->data, strerror(errno));
         return StringValue(strdup(""));
@@ -1532,7 +1527,7 @@
     if (ota_fsync(params.fd) == -1) {
         fprintf(stderr, "fsync failed: %s\n", strerror(errno));
     }
-    // params.fd will be automatically closed because of the fd_holder above.
+    // params.fd will be automatically closed because it's a unique_fd.
 
     // Only delete the stash if the update cannot be resumed, or it's
     // a verification run and we created the stash.
@@ -1653,9 +1648,8 @@
         return StringValue(strdup(""));
     }
 
-    int fd = ota_open(blockdev_filename->data, O_RDWR);
-    unique_fd fd_holder(fd);
-    if (fd < 0) {
+    android::base::unique_fd fd(ota_open(blockdev_filename->data, O_RDWR));
+    if (fd == -1) {
         ErrorAbort(state, "open \"%s\" failed: %s", blockdev_filename->data, strerror(errno));
         return StringValue(strdup(""));
     }
@@ -1676,7 +1670,7 @@
         for (size_t j = rs.pos[i*2]; j < rs.pos[i*2+1]; ++j) {
             if (read_all(fd, buffer, BLOCKSIZE) == -1) {
                 ErrorAbort(state, "failed to read %s: %s", blockdev_filename->data,
-                        strerror(errno));
+                           strerror(errno));
                 return StringValue(strdup(""));
             }
 
@@ -1707,8 +1701,7 @@
         return StringValue(strdup(""));
     }
 
-    int fd = ota_open(arg_filename->data, O_RDONLY);
-    unique_fd fd_holder(fd);
+    android::base::unique_fd fd(ota_open(arg_filename->data, O_RDONLY));
     if (fd == -1) {
         ErrorAbort(state, "open \"%s\" failed: %s", arg_filename->data, strerror(errno));
         return StringValue(strdup(""));
@@ -1718,8 +1711,7 @@
     std::vector<uint8_t> block0_buffer(BLOCKSIZE);
 
     if (ReadBlocks(blk0, block0_buffer, fd) == -1) {
-        ErrorAbort(state, "failed to read %s: %s", arg_filename->data,
-                strerror(errno));
+        ErrorAbort(state, "failed to read %s: %s", arg_filename->data, strerror(errno));
         return StringValue(strdup(""));
     }