Merge "Implement the TargetFile and BuildInfo"
diff --git a/install/adb_install.cpp b/install/adb_install.cpp
index 2de1075..37280a3 100644
--- a/install/adb_install.cpp
+++ b/install/adb_install.cpp
@@ -110,7 +110,11 @@
         break;
       }
     }
-    *result = InstallPackage(FUSE_SIDELOAD_HOST_PATHNAME, false, false, 0, ui);
+
+    auto package =
+        Package::CreateFilePackage(FUSE_SIDELOAD_HOST_PATHNAME,
+                                   std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
+    *result = InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0, ui);
     break;
   }
 
diff --git a/install/fuse_sdcard_install.cpp b/install/fuse_sdcard_install.cpp
index a5caa6e..9fdb2f3 100644
--- a/install/fuse_sdcard_install.cpp
+++ b/install/fuse_sdcard_install.cpp
@@ -182,8 +182,11 @@
         break;
       }
     }
-
-    result = InstallPackage(FUSE_SIDELOAD_HOST_PATHNAME, false, false, 0 /* retry_count */, ui);
+    auto package =
+        Package::CreateFilePackage(FUSE_SIDELOAD_HOST_PATHNAME,
+                                   std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
+    result =
+        InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0 /* retry_count */, ui);
     break;
   }
 
diff --git a/install/include/install/install.h b/install/include/install/install.h
index 44a5cde..b4b3a91 100644
--- a/install/include/install/install.h
+++ b/install/include/install/install.h
@@ -44,11 +44,12 @@
   BRICK,
 };
 
-// Installs the given update package. This function should also wipe the cache partition after a
-// successful installation if |should_wipe_cache| is true or an updater command asks to wipe the
-// cache.
-InstallResult InstallPackage(const std::string& package, bool should_wipe_cache, bool needs_mount,
-                             int retry_count, RecoveryUI* ui);
+// Installs the given update package. The package_id is a string provided by the caller (e.g. the
+// package path) to identify the package and log to last_install. This function should also wipe the
+// cache partition after a successful installation if |should_wipe_cache| is true or an updater
+// command asks to wipe the cache.
+InstallResult InstallPackage(Package* package, const std::string_view package_id,
+                             bool should_wipe_cache, int retry_count, RecoveryUI* ui);
 
 // Verifies the package by ota keys. Returns true if the package is verified successfully,
 // otherwise returns false.
diff --git a/install/include/install/package.h b/install/include/install/package.h
index cd44d10..0b42332 100644
--- a/install/include/install/package.h
+++ b/install/include/install/package.h
@@ -28,6 +28,11 @@
 
 #include "verifier.h"
 
+enum class PackageType {
+  kMemory,
+  kFile,
+};
+
 // This class serves as a wrapper for an OTA update package. It aims to provide the common
 // interface for both packages loaded in memory and packages read from fd.
 class Package : public VerifierInterface {
@@ -41,6 +46,10 @@
 
   virtual ~Package() = default;
 
+  virtual PackageType GetType() const = 0;
+
+  virtual std::string GetPath() const = 0;
+
   // Opens the package as a zip file and returns the ZipArchiveHandle.
   virtual ZipArchiveHandle GetZipArchiveHandle() = 0;
 
diff --git a/install/install.cpp b/install/install.cpp
index 8d46641..09b8839 100644
--- a/install/install.cpp
+++ b/install/install.cpp
@@ -320,16 +320,21 @@
 }
 
 // If the package contains an update binary, extract it and run it.
-static InstallResult TryUpdateBinary(const std::string& package, ZipArchiveHandle zip,
-                                     bool* wipe_cache, std::vector<std::string>* log_buffer,
-                                     int retry_count, int* max_temperature, RecoveryUI* ui) {
+static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache,
+                                     std::vector<std::string>* log_buffer, int retry_count,
+                                     int* max_temperature, RecoveryUI* ui) {
   std::map<std::string, std::string> metadata;
+  auto zip = package->GetZipArchiveHandle();
   if (!ReadMetadataFromPackage(zip, &metadata)) {
     LOG(ERROR) << "Failed to parse metadata in the zip file";
     return INSTALL_CORRUPT;
   }
 
   bool is_ab = android::base::GetBoolProperty("ro.build.ab_update", false);
+  if (is_ab) {
+    CHECK(package->GetType() == PackageType::kFile);
+  }
+
   // Verify against the metadata in the package first.
   if (is_ab && !CheckPackageMetadata(metadata, OtaType::AB)) {
     log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure));
@@ -379,10 +384,12 @@
   //       updater requests logging the string (e.g. cause of the failure).
   //
 
+  std::string package_path = package->GetPath();
+
   std::vector<std::string> args;
   if (auto setup_result =
-          is_ab ? SetUpAbUpdateCommands(package, zip, pipe_write.get(), &args)
-                : SetUpNonAbUpdateCommands(package, zip, retry_count, pipe_write.get(), &args);
+          is_ab ? SetUpAbUpdateCommands(package_path, zip, pipe_write.get(), &args)
+                : SetUpNonAbUpdateCommands(package_path, zip, retry_count, pipe_write.get(), &args);
       !setup_result) {
     log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure));
     return INSTALL_CORRUPT;
@@ -484,11 +491,11 @@
   }
   if (WIFEXITED(status)) {
     if (WEXITSTATUS(status) != EXIT_SUCCESS) {
-      LOG(ERROR) << "Error in " << package << " (status " << WEXITSTATUS(status) << ")";
+      LOG(ERROR) << "Error in " << package_path << " (status " << WEXITSTATUS(status) << ")";
       return INSTALL_ERROR;
     }
   } else if (WIFSIGNALED(status)) {
-    LOG(ERROR) << "Error in " << package << " (killed by signal " << WTERMSIG(status) << ")";
+    LOG(ERROR) << "Error in " << package_path << " (killed by signal " << WTERMSIG(status) << ")";
     return INSTALL_ERROR;
   } else {
     LOG(FATAL) << "Invalid status code " << status;
@@ -497,7 +504,7 @@
   return INSTALL_SUCCESS;
 }
 
-// Verifes the compatibility info in a Treble-compatible package. Returns true directly if the
+// Verifies the compatibility info in a Treble-compatible package. Returns true directly if the
 // entry doesn't exist. Note that the compatibility info is packed in a zip file inside the OTA
 // package.
 bool verify_package_compatibility(ZipArchiveHandle package_zip) {
@@ -539,7 +546,7 @@
 
   std::vector<std::string> compatibility_info;
   ZipEntry info_entry;
-  std::string info_name;
+  std::string_view info_name;
   while (Next(cookie, &info_entry, &info_name) == 0) {
     std::string content(info_entry.uncompressed_length, '\0');
     int32_t ret = ExtractToMemory(zip_handle, &info_entry, reinterpret_cast<uint8_t*>(&content[0]),
@@ -564,37 +571,16 @@
   return false;
 }
 
-static InstallResult VerifyAndInstallPackage(const std::string& path, bool* wipe_cache,
-                                             bool needs_mount, std::vector<std::string>* log_buffer,
-                                             int retry_count, int* max_temperature,
-                                             RecoveryUI* ui) {
+static InstallResult VerifyAndInstallPackage(Package* package, bool* wipe_cache,
+                                             std::vector<std::string>* log_buffer, int retry_count,
+                                             int* max_temperature, RecoveryUI* ui) {
   ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);
-  ui->Print("Finding update package...\n");
   // Give verification half the progress bar...
   ui->SetProgressType(RecoveryUI::DETERMINATE);
   ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);
-  LOG(INFO) << "Update location: " << path;
-
-  // Map the update package into memory.
-  ui->Print("Opening update package...\n");
-
-  if (needs_mount) {
-    if (path[0] == '@') {
-      ensure_path_mounted(path.substr(1));
-    } else {
-      ensure_path_mounted(path);
-    }
-  }
-
-  auto package = Package::CreateMemoryPackage(
-      path, std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
-  if (!package) {
-    log_buffer->push_back(android::base::StringPrintf("error: %d", kMapFileFailure));
-    return INSTALL_CORRUPT;
-  }
 
   // Verify package.
-  if (!verify_package(package.get(), ui)) {
+  if (!verify_package(package, ui)) {
     log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure));
     return INSTALL_CORRUPT;
   }
@@ -618,18 +604,15 @@
     ui->Print("Retry attempt: %d\n", retry_count);
   }
   ui->SetEnableReboot(false);
-  auto result =
-      TryUpdateBinary(path, zip, wipe_cache, log_buffer, retry_count, max_temperature, ui);
+  auto result = TryUpdateBinary(package, wipe_cache, log_buffer, retry_count, max_temperature, ui);
   ui->SetEnableReboot(true);
   ui->Print("\n");
 
   return result;
 }
 
-InstallResult InstallPackage(const std::string& path, bool should_wipe_cache, bool needs_mount,
-                             int retry_count, RecoveryUI* ui) {
-  CHECK(!path.empty());
-
+InstallResult InstallPackage(Package* package, const std::string_view package_id,
+                             bool should_wipe_cache, int retry_count, RecoveryUI* ui) {
   auto start = std::chrono::system_clock::now();
 
   int start_temperature = GetMaxValueFromThermalZone();
@@ -637,13 +620,19 @@
 
   InstallResult result;
   std::vector<std::string> log_buffer;
-  if (setup_install_mounts() != 0) {
+
+  ui->Print("Finding update package...\n");
+  LOG(INFO) << "Update package id: " << package_id;
+  if (!package) {
+    log_buffer.push_back(android::base::StringPrintf("error: %d", kMapFileFailure));
+    result = INSTALL_CORRUPT;
+  } else if (setup_install_mounts() != 0) {
     LOG(ERROR) << "failed to set up expected mounts for install; aborting";
     result = INSTALL_ERROR;
   } else {
     bool updater_wipe_cache = false;
-    result = VerifyAndInstallPackage(path, &updater_wipe_cache, needs_mount, &log_buffer,
-                                     retry_count, &max_temperature, ui);
+    result = VerifyAndInstallPackage(package, &updater_wipe_cache, &log_buffer, retry_count,
+                                     &max_temperature, ui);
     should_wipe_cache = should_wipe_cache || updater_wipe_cache;
   }
 
@@ -671,7 +660,7 @@
 
   // The first two lines need to be the package name and install result.
   std::vector<std::string> log_header = {
-    path,
+    std::string(package_id),
     result == INSTALL_SUCCESS ? "1" : "0",
     "time_total: " + std::to_string(time_total),
     "retry: " + std::to_string(retry_count),
diff --git a/install/package.cpp b/install/package.cpp
index 4402f48..86fc064 100644
--- a/install/package.cpp
+++ b/install/package.cpp
@@ -40,12 +40,20 @@
 
   ~MemoryPackage() override;
 
+  PackageType GetType() const override {
+    return PackageType::kMemory;
+  }
+
   // Memory maps the package file if necessary. Initializes the start address and size of the
   // package.
   uint64_t GetPackageSize() const override {
     return package_size_;
   }
 
+  std::string GetPath() const override {
+    return path_;
+  }
+
   bool ReadFullyAtOffset(uint8_t* buffer, uint64_t byte_count, uint64_t offset) override;
 
   ZipArchiveHandle GetZipArchiveHandle() override;
@@ -82,10 +90,18 @@
 
   ~FilePackage() override;
 
+  PackageType GetType() const override {
+    return PackageType::kFile;
+  }
+
   uint64_t GetPackageSize() const override {
     return package_size_;
   }
 
+  std::string GetPath() const override {
+    return path_;
+  }
+
   bool ReadFullyAtOffset(uint8_t* buffer, uint64_t byte_count, uint64_t offset) override;
 
   ZipArchiveHandle GetZipArchiveHandle() override;
@@ -253,7 +269,7 @@
     return zip_handle_;
   }
 
-  if (auto err = OpenArchiveFd(fd_.get(), path_.c_str(), &zip_handle_); err != 0) {
+  if (auto err = OpenArchiveFd(fd_.get(), path_.c_str(), &zip_handle_, false); err != 0) {
     LOG(ERROR) << "Can't open package" << path_ << " : " << ErrorCodeString(err);
     return nullptr;
   }
diff --git a/install/verifier.cpp b/install/verifier.cpp
index 02759cd..ab75044 100644
--- a/install/verifier.cpp
+++ b/install/verifier.cpp
@@ -320,7 +320,7 @@
 
   std::vector<Certificate> result;
 
-  std::string name;
+  std::string_view name;
   ZipEntry entry;
   while ((iter_status = Next(cookie, &entry, &name)) == 0) {
     std::vector<uint8_t> pem_content(entry.uncompressed_length);
diff --git a/minadbd/minadbd_services.cpp b/minadbd/minadbd_services.cpp
index 8f2b71a..1e6eb31 100644
--- a/minadbd/minadbd_services.cpp
+++ b/minadbd/minadbd_services.cpp
@@ -25,10 +25,10 @@
 
 #include <functional>
 #include <memory>
+#include <set>
 #include <string>
 #include <string_view>
 #include <thread>
-#include <unordered_set>
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
@@ -156,19 +156,36 @@
   }
 }
 
+// Answers the query on a given property |prop|, by writing the result to the given |sfd|. The
+// result will be newline-terminated, so nonexistent or nonallowed query will be answered with "\n".
+// If given an empty string, dumps all the supported properties (analogous to `adb shell getprop`)
+// in lines, e.g. "[prop]: [value]".
 static void RescueGetpropHostService(unique_fd sfd, const std::string& prop) {
-  static const std::unordered_set<std::string> kGetpropAllowedProps = {
-    "ro.build.fingerprint",
+  static const std::set<std::string> kGetpropAllowedProps = {
     "ro.build.date.utc",
+    "ro.build.fingerprint",
+    "ro.build.flavor",
+    "ro.build.id",
+    "ro.build.product",
+    "ro.build.tags",
+    "ro.build.version.incremental",
+    "ro.product.device",
+    "ro.product.vendor.device",
   };
-  auto allowed = kGetpropAllowedProps.find(prop) != kGetpropAllowedProps.end();
-  if (!allowed) {
-    return;
+  std::string result;
+  if (prop.empty()) {
+    for (const auto& key : kGetpropAllowedProps) {
+      auto value = android::base::GetProperty(key, "");
+      if (value.empty()) {
+        continue;
+      }
+      result += "[" + key + "]: [" + value + "]\n";
+    }
+  } else if (kGetpropAllowedProps.find(prop) != kGetpropAllowedProps.end()) {
+    result = android::base::GetProperty(prop, "") + "\n";
   }
-
-  auto result = android::base::GetProperty(prop, "");
   if (result.empty()) {
-    return;
+    result = "\n";
   }
   if (!android::base::WriteFully(sfd, result.data(), result.size())) {
     exit(kMinadbdHostSocketIOError);
diff --git a/recovery.cpp b/recovery.cpp
index eb0c2b2..db66ea7 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -732,7 +732,15 @@
         set_retry_bootloader_message(retry_count + 1, args);
       }
 
-      status = InstallPackage(update_package, should_wipe_cache, true, retry_count, ui);
+      if (update_package[0] == '@') {
+        ensure_path_mounted(update_package + 1);
+      } else {
+        ensure_path_mounted(update_package);
+      }
+      // TODO(xunchang) install package from fuse for large packages on ILP32 builds.
+      auto package = Package::CreateMemoryPackage(
+          update_package, std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
+      status = InstallPackage(package.get(), update_package, should_wipe_cache, retry_count, ui);
       if (status != INSTALL_SUCCESS) {
         ui->Print("Installation aborted.\n");
 
diff --git a/recovery_ui/ui.cpp b/recovery_ui/ui.cpp
index 78b014a..cf0d3b5 100644
--- a/recovery_ui/ui.cpp
+++ b/recovery_ui/ui.cpp
@@ -419,7 +419,7 @@
         LOG(INFO) << "Brightness: " << brightness_normal_value_ << " (" << brightness_normal_
                   << "%)";
       } else {
-        LOG(ERROR) << "Unable to set brightness to normal";
+        LOG(WARNING) << "Unable to set brightness to normal";
       }
       break;
     case ScreensaverState::DIMMED:
@@ -429,7 +429,7 @@
                   << "%)";
         screensaver_state_ = ScreensaverState::DIMMED;
       } else {
-        LOG(ERROR) << "Unable to set brightness to dim";
+        LOG(WARNING) << "Unable to set brightness to dim";
       }
       break;
     case ScreensaverState::OFF:
@@ -437,7 +437,7 @@
         LOG(INFO) << "Brightness: 0 (off)";
         screensaver_state_ = ScreensaverState::OFF;
       } else {
-        LOG(ERROR) << "Unable to set brightness to off";
+        LOG(WARNING) << "Unable to set brightness to off";
       }
       break;
     default:
diff --git a/tools/image_generator/Android.bp b/tools/image_generator/Android.bp
index 2afdd5a..8300040 100644
--- a/tools/image_generator/Android.bp
+++ b/tools/image_generator/Android.bp
@@ -19,7 +19,7 @@
 
     static_libs: [
         "commons-cli-1.2",
-        "icu4j-host",
+        "icu4j",
     ],
 
     srcs: [