Merge "Update_verifier: Remove the support for legacy text format CareMap"
diff --git a/install.h b/install.h
index 7b6267b..da8aa5e 100644
--- a/install.h
+++ b/install.h
@@ -57,7 +57,7 @@
 bool ReadMetadataFromPackage(ZipArchiveHandle zip, std::map<std::string, std::string>* metadata);
 
 // Reads the "recovery.wipe" entry in the zip archive returns a list of partitions to wipe.
-std::vector<std::string> GetWipePartitionList(const std::string& wipe_package);
+std::vector<std::string> GetWipePartitionList(Package* wipe_package);
 
 // Verifies the compatibility info in a Treble-compatible package. Returns true directly if the
 // entry doesn't exist.
diff --git a/minui/events.cpp b/minui/events.cpp
index 30f8d50..7d0250e 100644
--- a/minui/events.cpp
+++ b/minui/events.cpp
@@ -23,144 +23,148 @@
 #include <string.h>
 #include <sys/epoll.h>
 #include <sys/ioctl.h>
+#include <sys/types.h>
 #include <unistd.h>
 
 #include <functional>
+#include <memory>
+
+#include <android-base/unique_fd.h>
 
 #include "minui/minui.h"
 
-#define MAX_DEVICES 16
-#define MAX_MISC_FDS 16
+constexpr size_t MAX_DEVICES = 16;
+constexpr size_t MAX_MISC_FDS = 16;
 
-#define BITS_PER_LONG (sizeof(unsigned long) * 8)
-#define BITS_TO_LONGS(x) (((x) + BITS_PER_LONG - 1) / BITS_PER_LONG)
+constexpr size_t BITS_PER_LONG = sizeof(unsigned long) * 8;
+constexpr size_t BITS_TO_LONGS(size_t bits) {
+  return ((bits + BITS_PER_LONG - 1) / BITS_PER_LONG);
+}
 
-struct fd_info {
-  int fd;
+struct FdInfo {
+  android::base::unique_fd fd;
   ev_callback cb;
 };
 
-static int g_epoll_fd;
-static epoll_event polledevents[MAX_DEVICES + MAX_MISC_FDS];
-static int npolledevents;
+static android::base::unique_fd g_epoll_fd;
+static epoll_event g_polled_events[MAX_DEVICES + MAX_MISC_FDS];
+static int g_polled_events_count;
 
-static fd_info ev_fdinfo[MAX_DEVICES + MAX_MISC_FDS];
+static FdInfo ev_fdinfo[MAX_DEVICES + MAX_MISC_FDS];
 
-static unsigned ev_count = 0;
-static unsigned ev_dev_count = 0;
-static unsigned ev_misc_count = 0;
+static size_t g_ev_count = 0;
+static size_t g_ev_dev_count = 0;
+static size_t g_ev_misc_count = 0;
 
 static bool test_bit(size_t bit, unsigned long* array) { // NOLINT
-    return (array[bit/BITS_PER_LONG] & (1UL << (bit % BITS_PER_LONG))) != 0;
+  return (array[bit / BITS_PER_LONG] & (1UL << (bit % BITS_PER_LONG))) != 0;
 }
 
 int ev_init(ev_callback input_cb, bool allow_touch_inputs) {
-  g_epoll_fd = epoll_create1(EPOLL_CLOEXEC);
-  if (g_epoll_fd == -1) {
+  g_epoll_fd.reset();
+
+  android::base::unique_fd epoll_fd(epoll_create1(EPOLL_CLOEXEC));
+  if (epoll_fd == -1) {
     return -1;
   }
 
-  bool epollctlfail = false;
-  DIR* dir = opendir("/dev/input");
-  if (dir != nullptr) {
-    dirent* de;
-    while ((de = readdir(dir))) {
-      if (strncmp(de->d_name, "event", 5)) continue;
-      int fd = openat(dirfd(dir), de->d_name, O_RDONLY | O_CLOEXEC);
-      if (fd == -1) continue;
+  std::unique_ptr<DIR, decltype(&closedir)> dir(opendir("/dev/input"), closedir);
+  if (!dir) {
+    return -1;
+  }
 
-      // Use unsigned long to match ioctl's parameter type.
-      unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];  // NOLINT
+  bool epoll_ctl_failed = false;
+  dirent* de;
+  while ((de = readdir(dir.get())) != nullptr) {
+    if (strncmp(de->d_name, "event", 5)) continue;
+    android::base::unique_fd fd(openat(dirfd(dir.get()), de->d_name, O_RDONLY | O_CLOEXEC));
+    if (fd == -1) continue;
 
-      // Read the evbits of the input device.
-      if (ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
-        close(fd);
-        continue;
-      }
+    // Use unsigned long to match ioctl's parameter type.
+    unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];  // NOLINT
 
-      // We assume that only EV_KEY, EV_REL, and EV_SW event types are ever needed. EV_ABS is also
-      // allowed if allow_touch_inputs is set.
-      if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits) && !test_bit(EV_SW, ev_bits)) {
-        if (!allow_touch_inputs || !test_bit(EV_ABS, ev_bits)) {
-          close(fd);
-          continue;
-        }
-      }
-
-      epoll_event ev;
-      ev.events = EPOLLIN | EPOLLWAKEUP;
-      ev.data.ptr = &ev_fdinfo[ev_count];
-      if (epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
-        close(fd);
-        epollctlfail = true;
-        continue;
-      }
-
-      ev_fdinfo[ev_count].fd = fd;
-      ev_fdinfo[ev_count].cb = std::move(input_cb);
-      ev_count++;
-      ev_dev_count++;
-      if (ev_dev_count == MAX_DEVICES) break;
+    // Read the evbits of the input device.
+    if (ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
+      continue;
     }
 
-    closedir(dir);
+    // We assume that only EV_KEY, EV_REL, and EV_SW event types are ever needed. EV_ABS is also
+    // allowed if allow_touch_inputs is set.
+    if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits) && !test_bit(EV_SW, ev_bits)) {
+      if (!allow_touch_inputs || !test_bit(EV_ABS, ev_bits)) {
+        continue;
+      }
+    }
+
+    epoll_event ev;
+    ev.events = EPOLLIN | EPOLLWAKEUP;
+    ev.data.ptr = &ev_fdinfo[g_ev_count];
+    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
+      epoll_ctl_failed = true;
+      continue;
+    }
+
+    ev_fdinfo[g_ev_count].fd.reset(fd.release());
+    ev_fdinfo[g_ev_count].cb = input_cb;
+    g_ev_count++;
+    g_ev_dev_count++;
+    if (g_ev_dev_count == MAX_DEVICES) break;
   }
 
-  if (epollctlfail && !ev_count) {
-    close(g_epoll_fd);
-    g_epoll_fd = -1;
+  if (epoll_ctl_failed && !g_ev_count) {
     return -1;
   }
 
+  g_epoll_fd.reset(epoll_fd.release());
   return 0;
 }
 
 int ev_get_epollfd(void) {
-    return g_epoll_fd;
+  return g_epoll_fd.get();
 }
 
-int ev_add_fd(int fd, ev_callback cb) {
-  if (ev_misc_count == MAX_MISC_FDS || cb == NULL) {
+int ev_add_fd(android::base::unique_fd&& fd, ev_callback cb) {
+  if (g_ev_misc_count == MAX_MISC_FDS || cb == nullptr) {
     return -1;
   }
 
   epoll_event ev;
   ev.events = EPOLLIN | EPOLLWAKEUP;
-  ev.data.ptr = static_cast<void*>(&ev_fdinfo[ev_count]);
+  ev.data.ptr = static_cast<void*>(&ev_fdinfo[g_ev_count]);
   int ret = epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, fd, &ev);
   if (!ret) {
-    ev_fdinfo[ev_count].fd = fd;
-    ev_fdinfo[ev_count].cb = std::move(cb);
-    ev_count++;
-    ev_misc_count++;
+    ev_fdinfo[g_ev_count].fd.reset(fd.release());
+    ev_fdinfo[g_ev_count].cb = std::move(cb);
+    g_ev_count++;
+    g_ev_misc_count++;
   }
 
   return ret;
 }
 
 void ev_exit(void) {
-    while (ev_count > 0) {
-        close(ev_fdinfo[--ev_count].fd);
-    }
-    ev_misc_count = 0;
-    ev_dev_count = 0;
-    close(g_epoll_fd);
+  while (g_ev_count > 0) {
+    ev_fdinfo[--g_ev_count].fd.reset();
+  }
+  g_ev_misc_count = 0;
+  g_ev_dev_count = 0;
+  g_epoll_fd.reset();
 }
 
 int ev_wait(int timeout) {
-    npolledevents = epoll_wait(g_epoll_fd, polledevents, ev_count, timeout);
-    if (npolledevents <= 0) {
-        return -1;
-    }
-    return 0;
+  g_polled_events_count = epoll_wait(g_epoll_fd, g_polled_events, g_ev_count, timeout);
+  if (g_polled_events_count <= 0) {
+    return -1;
+  }
+  return 0;
 }
 
 void ev_dispatch(void) {
-  for (int n = 0; n < npolledevents; n++) {
-    fd_info* fdi = static_cast<fd_info*>(polledevents[n].data.ptr);
+  for (int n = 0; n < g_polled_events_count; n++) {
+    FdInfo* fdi = static_cast<FdInfo*>(g_polled_events[n].data.ptr);
     const ev_callback& cb = fdi->cb;
     if (cb) {
-      cb(fdi->fd, polledevents[n].events);
+      cb(fdi->fd, g_polled_events[n].events);
     }
   }
 }
@@ -180,7 +184,7 @@
   unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];    // NOLINT
   unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)];  // NOLINT
 
-  for (size_t i = 0; i < ev_dev_count; ++i) {
+  for (size_t i = 0; i < g_ev_dev_count; ++i) {
     memset(ev_bits, 0, sizeof(ev_bits));
     memset(key_bits, 0, sizeof(key_bits));
 
@@ -205,37 +209,36 @@
 }
 
 void ev_iterate_available_keys(const std::function<void(int)>& f) {
-    // Use unsigned long to match ioctl's parameter type.
-    unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT
-    unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)]; // NOLINT
+  // Use unsigned long to match ioctl's parameter type.
+  unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];    // NOLINT
+  unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)];  // NOLINT
 
-    for (size_t i = 0; i < ev_dev_count; ++i) {
-        memset(ev_bits, 0, sizeof(ev_bits));
-        memset(key_bits, 0, sizeof(key_bits));
+  for (size_t i = 0; i < g_ev_dev_count; ++i) {
+    memset(ev_bits, 0, sizeof(ev_bits));
+    memset(key_bits, 0, sizeof(key_bits));
 
-        // Does this device even have keys?
-        if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
-            continue;
-        }
-        if (!test_bit(EV_KEY, ev_bits)) {
-            continue;
-        }
-
-        int rc = ioctl(ev_fdinfo[i].fd, EVIOCGBIT(EV_KEY, KEY_MAX), key_bits);
-        if (rc == -1) {
-            continue;
-        }
-
-        for (int key_code = 0; key_code <= KEY_MAX; ++key_code) {
-            if (test_bit(key_code, key_bits)) {
-                f(key_code);
-            }
-        }
+    // Does this device even have keys?
+    if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
+      continue;
     }
+    if (!test_bit(EV_KEY, ev_bits)) {
+      continue;
+    }
+
+    if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(EV_KEY, KEY_MAX), key_bits) == -1) {
+      continue;
+    }
+
+    for (int key_code = 0; key_code <= KEY_MAX; ++key_code) {
+      if (test_bit(key_code, key_bits)) {
+        f(key_code);
+      }
+    }
+  }
 }
 
 void ev_iterate_touch_inputs(const std::function<void(int)>& action) {
-  for (size_t i = 0; i < ev_dev_count; ++i) {
+  for (size_t i = 0; i < g_ev_dev_count; ++i) {
     // Use unsigned long to match ioctl's parameter type.
     unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)] = {};  // NOLINT
     if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
diff --git a/minui/include/minui/minui.h b/minui/include/minui/minui.h
index e49c6ac..36bdcf1 100644
--- a/minui/include/minui/minui.h
+++ b/minui/include/minui/minui.h
@@ -26,6 +26,7 @@
 #include <vector>
 
 #include <android-base/macros.h>
+#include <android-base/unique_fd.h>
 
 //
 // Graphics.
@@ -153,7 +154,7 @@
 
 int ev_init(ev_callback input_cb, bool allow_touch_inputs = false);
 void ev_exit();
-int ev_add_fd(int fd, ev_callback cb);
+int ev_add_fd(android::base::unique_fd&& fd, ev_callback cb);
 void ev_iterate_available_keys(const std::function<void(int)>& f);
 void ev_iterate_touch_inputs(const std::function<void(int)>& action);
 int ev_sync_key_state(const ev_set_key_callback& set_key_cb);
diff --git a/recovery.cpp b/recovery.cpp
index 2c9f9de..0074b64 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -498,41 +498,36 @@
   return true;
 }
 
-static std::string ReadWipePackage(size_t wipe_package_size) {
+static std::unique_ptr<Package> ReadWipePackage(size_t wipe_package_size) {
   if (wipe_package_size == 0) {
     LOG(ERROR) << "wipe_package_size is zero";
-    return "";
+    return nullptr;
   }
 
   std::string wipe_package;
   std::string err_str;
   if (!read_wipe_package(&wipe_package, wipe_package_size, &err_str)) {
     PLOG(ERROR) << "Failed to read wipe package" << err_str;
-    return "";
+    return nullptr;
   }
-  return wipe_package;
+
+  return Package::CreateMemoryPackage(
+      std::vector<uint8_t>(wipe_package.begin(), wipe_package.end()), nullptr);
 }
 
 // Checks if the wipe package matches expectation. If the check passes, reads the list of
 // partitions to wipe from the package. Checks include
 // 1. verify the package.
 // 2. check metadata (ota-type, pre-device and serial number if having one).
-static bool CheckWipePackage(const std::string& wipe_package) {
-  auto package = Package::CreateMemoryPackage(
-      std::vector<uint8_t>(wipe_package.begin(), wipe_package.end()), nullptr);
-
-  if (!package || !verify_package(package.get())) {
+static bool CheckWipePackage(Package* wipe_package) {
+  if (!verify_package(wipe_package)) {
     LOG(ERROR) << "Failed to verify package";
     return false;
   }
 
-  // TODO(xunchang) get zip archive from package.
-  ZipArchiveHandle zip;
-  if (auto err =
-          OpenArchiveFromMemory(const_cast<void*>(static_cast<const void*>(&wipe_package[0])),
-                                wipe_package.size(), "wipe_package", &zip);
-      err != 0) {
-    LOG(ERROR) << "Can't open wipe package : " << ErrorCodeString(err);
+  ZipArchiveHandle zip = wipe_package->GetZipArchiveHandle();
+  if (!zip) {
+    LOG(ERROR) << "Failed to get ZipArchiveHandle";
     return false;
   }
 
@@ -542,19 +537,13 @@
     return false;
   }
 
-  int result = CheckPackageMetadata(metadata, OtaType::BRICK);
-  CloseArchive(zip);
-
-  return result == 0;
+  return CheckPackageMetadata(metadata, OtaType::BRICK) == 0;
 }
 
-std::vector<std::string> GetWipePartitionList(const std::string& wipe_package) {
-  ZipArchiveHandle zip;
-  if (auto err =
-          OpenArchiveFromMemory(const_cast<void*>(static_cast<const void*>(&wipe_package[0])),
-                                wipe_package.size(), "wipe_package", &zip);
-      err != 0) {
-    LOG(ERROR) << "Can't open wipe package : " << ErrorCodeString(err);
+std::vector<std::string> GetWipePartitionList(Package* wipe_package) {
+  ZipArchiveHandle zip = wipe_package->GetZipArchiveHandle();
+  if (!zip) {
+    LOG(ERROR) << "Failed to get ZipArchiveHandle";
     return {};
   }
 
@@ -571,7 +560,6 @@
         err != 0) {
       LOG(ERROR) << "Failed to extract " << RECOVERY_WIPE_ENTRY_NAME << ": "
                  << ErrorCodeString(err);
-      CloseArchive(zip);
       return {};
     }
   } else {
@@ -581,7 +569,6 @@
     static constexpr const char* RECOVERY_WIPE_ON_DEVICE = "/etc/recovery.wipe";
     if (!android::base::ReadFileToString(RECOVERY_WIPE_ON_DEVICE, &partition_list_content)) {
       PLOG(ERROR) << "failed to read \"" << RECOVERY_WIPE_ON_DEVICE << "\"";
-      CloseArchive(zip);
       return {};
     }
   }
@@ -597,7 +584,6 @@
     result.push_back(line);
   }
 
-  CloseArchive(zip);
   return result;
 }
 
@@ -606,17 +592,18 @@
   ui->SetBackground(RecoveryUI::ERASING);
   ui->SetProgressType(RecoveryUI::INDETERMINATE);
 
-  std::string wipe_package = ReadWipePackage(wipe_package_size);
-  if (wipe_package.empty()) {
+  auto wipe_package = ReadWipePackage(wipe_package_size);
+  if (!wipe_package) {
+    LOG(ERROR) << "Failed to open wipe package";
     return false;
   }
 
-  if (!CheckWipePackage(wipe_package)) {
+  if (!CheckWipePackage(wipe_package.get())) {
     LOG(ERROR) << "Failed to verify wipe package";
     return false;
   }
 
-  std::vector<std::string> partition_list = GetWipePartitionList(wipe_package);
+  auto partition_list = GetWipePartitionList(wipe_package.get());
   if (partition_list.empty()) {
     LOG(ERROR) << "Empty wipe ab partition list";
     return false;
diff --git a/tests/component/install_test.cpp b/tests/component/install_test.cpp
index 1178136..969805b 100644
--- a/tests/component/install_test.cpp
+++ b/tests/component/install_test.cpp
@@ -120,7 +120,10 @@
   std::string wipe_package;
   ASSERT_TRUE(android::base::ReadFileToString(temp_file.path, &wipe_package));
 
-  std::vector<std::string> read_partition_list = GetWipePartitionList(wipe_package);
+  auto package = Package::CreateMemoryPackage(
+      std::vector<uint8_t>(wipe_package.begin(), wipe_package.end()), nullptr);
+
+  auto read_partition_list = GetWipePartitionList(package.get());
   std::vector<std::string> expected = {
     "/dev/block/bootdevice/by-name/system_a", "/dev/block/bootdevice/by-name/system_b",
     "/dev/block/bootdevice/by-name/vendor_a", "/dev/block/bootdevice/by-name/vendor_b",