Merge "DO NOT MERGE - Merge Pie Bonito/Sargo into master."
diff --git a/fs_mgr/fs_mgr_remount.cpp b/fs_mgr/fs_mgr_remount.cpp
index 00334bc..6482ed3 100644
--- a/fs_mgr/fs_mgr_remount.cpp
+++ b/fs_mgr/fs_mgr_remount.cpp
@@ -256,7 +256,7 @@
         auto& mount_point = entry.mount_point;
         if (fs_mgr_is_verity_enabled(entry)) {
             retval = VERITY_PARTITION;
-            if (android::base::GetProperty("ro.boot.vbmeta.devices_state", "") != "locked") {
+            if (android::base::GetProperty("ro.boot.vbmeta.device_state", "") != "locked") {
                 if (AvbOps* ops = avb_ops_user_new()) {
                     auto ret = avb_user_verity_set(
                             ops, android::base::GetProperty("ro.boot.slot_suffix", "").c_str(),
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index f069c58..7dd3ad4 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -235,7 +235,7 @@
 
     SetInitAvbVersionInRecovery();
 
-    setenv("FIRST_STAGE_STARTED_AT", std::to_string(start_time.time_since_epoch().count()).c_str(),
+    setenv(kEnvFirstStageStartedAt, std::to_string(start_time.time_since_epoch().count()).c_str(),
            1);
 
     const char* path = "/system/bin/init";
diff --git a/init/first_stage_init.h b/init/first_stage_init.h
index 0476e44..7de816f 100644
--- a/init/first_stage_init.h
+++ b/init/first_stage_init.h
@@ -21,5 +21,7 @@
 
 int FirstStageMain(int argc, char** argv);
 
+static constexpr char kEnvFirstStageStartedAt[] = "FIRST_STAGE_STARTED_AT";
+
 }  // namespace init
 }  // namespace android
diff --git a/init/init.cpp b/init/init.cpp
index a18c2c8..1f3c2fc 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -56,6 +56,7 @@
 #include "action_parser.h"
 #include "boringssl_self_test.h"
 #include "epoll.h"
+#include "first_stage_init.h"
 #include "first_stage_mount.h"
 #include "import_parser.h"
 #include "keychords.h"
@@ -630,20 +631,18 @@
 
 static void RecordStageBoottimes(const boot_clock::time_point& second_stage_start_time) {
     int64_t first_stage_start_time_ns = -1;
-    static constexpr char first_stage_started_at[] = "FIRST_STAGE_STARTED_AT";
-    if (auto first_stage_start_time_str = getenv(first_stage_started_at);
+    if (auto first_stage_start_time_str = getenv(kEnvFirstStageStartedAt);
         first_stage_start_time_str) {
         property_set("ro.boottime.init", first_stage_start_time_str);
         android::base::ParseInt(first_stage_start_time_str, &first_stage_start_time_ns);
     }
-    unsetenv(first_stage_started_at);
+    unsetenv(kEnvFirstStageStartedAt);
 
     int64_t selinux_start_time_ns = -1;
-    static constexpr char selinux_started_at[] = "SELINUX_STARTED_AT";
-    if (auto selinux_start_time_str = getenv(selinux_started_at); selinux_start_time_str) {
+    if (auto selinux_start_time_str = getenv(kEnvSelinuxStartedAt); selinux_start_time_str) {
         android::base::ParseInt(selinux_start_time_str, &selinux_start_time_ns);
     }
-    unsetenv(selinux_started_at);
+    unsetenv(kEnvSelinuxStartedAt);
 
     if (selinux_start_time_ns == -1) return;
     if (first_stage_start_time_ns == -1) return;
diff --git a/init/selinux.cpp b/init/selinux.cpp
index f897170..8a63363 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -544,7 +544,7 @@
         PLOG(FATAL) << "restorecon failed of /system/bin/init failed";
     }
 
-    setenv("SELINUX_STARTED_AT", std::to_string(start_time.time_since_epoch().count()).c_str(), 1);
+    setenv(kEnvSelinuxStartedAt, std::to_string(start_time.time_since_epoch().count()).c_str(), 1);
 
     const char* path = "/system/bin/init";
     const char* args[] = {path, "second_stage", nullptr};
diff --git a/init/selinux.h b/init/selinux.h
index 3aa9406..c7d6647 100644
--- a/init/selinux.h
+++ b/init/selinux.h
@@ -35,6 +35,8 @@
                                        const std::vector<std::string>& aliases, int type,
                                        std::string* result);
 
+static constexpr char kEnvSelinuxStartedAt[] = "SELINUX_STARTED_AT";
+
 }  // namespace init
 }  // namespace android
 
diff --git a/libnativeloader/public_libraries.cpp b/libnativeloader/public_libraries.cpp
index c473f2c..64fedae 100644
--- a/libnativeloader/public_libraries.cpp
+++ b/libnativeloader/public_libraries.cpp
@@ -68,6 +68,16 @@
   return "";
 }
 
+// For debuggable platform builds use ANDROID_ADDITIONAL_PUBLIC_LIBRARIES environment
+// variable to add libraries to the list. This is intended for platform tests only.
+std::string additional_public_libraries() {
+  if (debuggable()) {
+    const char* val = getenv("ANDROID_ADDITIONAL_PUBLIC_LIBRARIES");
+    return val ? val : "";
+  }
+  return "";
+}
+
 void InsertVndkVersionStr(std::string* file_name) {
   CHECK(file_name != nullptr);
   size_t insert_pos = file_name->find_last_of(".");
@@ -171,130 +181,119 @@
   }
 }
 
-}  // namespace
+static std::string InitDefaultPublicLibraries() {
+  std::string config_file = root_dir() + kDefaultPublicLibrariesFile;
+  std::vector<std::string> sonames;
+  std::string error_msg;
+  LOG_ALWAYS_FATAL_IF(!ReadConfig(config_file, &sonames, always_true, &error_msg),
+                      "Error reading public native library list from \"%s\": %s",
+                      config_file.c_str(), error_msg.c_str());
 
-const std::string& default_public_libraries() {
-  static bool cached = false;
-  static std::string list;
-  if (!cached) {
-    std::string config_file = root_dir() + kDefaultPublicLibrariesFile;
-    std::vector<std::string> sonames;
-    std::string error_msg;
-    LOG_ALWAYS_FATAL_IF(!ReadConfig(config_file, &sonames, always_true, &error_msg),
-                        "Error reading public native library list from \"%s\": %s",
-                        config_file.c_str(), error_msg.c_str());
+  std::string additional_libs = additional_public_libraries();
+  if (!additional_libs.empty()) {
+    auto vec = base::Split(additional_libs, ":");
+    std::copy(vec.begin(), vec.end(), std::back_inserter(sonames));
+  }
 
-    // For debuggable platform builds use ANDROID_ADDITIONAL_PUBLIC_LIBRARIES environment
-    // variable to add libraries to the list. This is intended for platform tests only.
-    if (debuggable()) {
-      const char* additional_libs = getenv("ANDROID_ADDITIONAL_PUBLIC_LIBRARIES");
-      if (additional_libs != nullptr && additional_libs[0] != '\0') {
-        std::vector<std::string> additional_libs_vector = base::Split(additional_libs, ":");
-        std::copy(additional_libs_vector.begin(), additional_libs_vector.end(),
-                  std::back_inserter(sonames));
-      }
+  // Remove the public libs in the runtime namespace.
+  // These libs are listed in public.android.txt, but we don't want the rest of android
+  // in default namespace to dlopen the libs.
+  // For example, libicuuc.so is exposed to classloader namespace from runtime namespace.
+  // Unfortunately, it does not have stable C symbols, and default namespace should only use
+  // stable symbols in libandroidicu.so. http://b/120786417
+  for (const std::string& lib_name : kRuntimePublicLibraries) {
+    std::string path(kRuntimeApexLibPath);
+    path.append("/").append(lib_name);
+
+    struct stat s;
+    // Do nothing if the path in /apex does not exist.
+    // Runtime APEX must be mounted since libnativeloader is in the same APEX
+    if (stat(path.c_str(), &s) != 0) {
+      continue;
     }
 
-    // Remove the public libs in the runtime namespace.
-    // These libs are listed in public.android.txt, but we don't want the rest of android
-    // in default namespace to dlopen the libs.
-    // For example, libicuuc.so is exposed to classloader namespace from runtime namespace.
-    // Unfortunately, it does not have stable C symbols, and default namespace should only use
-    // stable symbols in libandroidicu.so. http://b/120786417
-    for (const std::string& lib_name : kRuntimePublicLibraries) {
-      std::string path(kRuntimeApexLibPath);
-      path.append("/").append(lib_name);
-
-      struct stat s;
-      // Do nothing if the path in /apex does not exist.
-      // Runtime APEX must be mounted since libnativeloader is in the same APEX
-      if (stat(path.c_str(), &s) != 0) {
-        continue;
-      }
-
-      auto it = std::find(sonames.begin(), sonames.end(), lib_name);
-      if (it != sonames.end()) {
-        sonames.erase(it);
-      }
+    auto it = std::find(sonames.begin(), sonames.end(), lib_name);
+    if (it != sonames.end()) {
+      sonames.erase(it);
     }
-    list = android::base::Join(sonames, ':');
-    cached = true;
+  }
+  return android::base::Join(sonames, ':');
+}
+
+static std::string InitRuntimePublicLibraries() {
+  CHECK(sizeof(kRuntimePublicLibraries) > 0);
+  std::string list = android::base::Join(kRuntimePublicLibraries, ":");
+
+  std::string additional_libs = additional_public_libraries();
+  if (!additional_libs.empty()) {
+    list = list + ':' + additional_libs;
   }
   return list;
 }
 
-const std::string& runtime_public_libraries() {
-  static bool cached = false;
-  static std::string list;
-  if (!cached) {
-    list = android::base::Join(kRuntimePublicLibraries, ":");
-    // For debuggable platform builds use ANDROID_ADDITIONAL_PUBLIC_LIBRARIES environment
-    // variable to add libraries to the list. This is intended for platform tests only.
-    if (debuggable()) {
-      const char* additional_libs = getenv("ANDROID_ADDITIONAL_PUBLIC_LIBRARIES");
-      if (additional_libs != nullptr && additional_libs[0] != '\0') {
-        list = list + ':' + additional_libs;
-      }
-    }
-  }
-  return list;
-}
-
-const std::string& vendor_public_libraries() {
-  static bool cached = false;
-  static std::string list;
-  if (!cached) {
-    // This file is optional, quietly ignore if the file does not exist.
-    std::vector<std::string> sonames;
-    ReadConfig(kVendorPublicLibrariesFile, &sonames, always_true, nullptr);
-    list = android::base::Join(sonames, ':');
-    cached = true;
-  }
-  return list;
+static std::string InitVendorPublicLibraries() {
+  // This file is optional, quietly ignore if the file does not exist.
+  std::vector<std::string> sonames;
+  ReadConfig(kVendorPublicLibrariesFile, &sonames, always_true, nullptr);
+  return android::base::Join(sonames, ':');
 }
 
 // read /system/etc/public.libraries-<companyname>.txt and
 // /product/etc/public.libraries-<companyname>.txt which contain partner defined
 // system libs that are exposed to apps. The libs in the txt files must be
 // named as lib<name>.<companyname>.so.
+static std::string InitExtendedPublicLibraries() {
+  std::vector<std::string> sonames;
+  ReadExtensionLibraries("/system/etc", &sonames);
+  ReadExtensionLibraries("/product/etc", &sonames);
+  return android::base::Join(sonames, ':');
+}
+
+static std::string InitLlndkLibraries() {
+  std::string config_file = kLlndkLibrariesFile;
+  InsertVndkVersionStr(&config_file);
+  std::vector<std::string> sonames;
+  ReadConfig(config_file, &sonames, always_true, nullptr);
+  return android::base::Join(sonames, ':');
+}
+
+static std::string InitVndkspLibraries() {
+  std::string config_file = kVndkLibrariesFile;
+  InsertVndkVersionStr(&config_file);
+  std::vector<std::string> sonames;
+  ReadConfig(config_file, &sonames, always_true, nullptr);
+  return android::base::Join(sonames, ':');
+}
+
+}  // namespace
+
+const std::string& default_public_libraries() {
+  static std::string list = InitDefaultPublicLibraries();
+  return list;
+}
+
+const std::string& runtime_public_libraries() {
+  static std::string list = InitRuntimePublicLibraries();
+  return list;
+}
+
+const std::string& vendor_public_libraries() {
+  static std::string list = InitVendorPublicLibraries();
+  return list;
+}
+
 const std::string& extended_public_libraries() {
-  static bool cached = false;
-  static std::string list;
-  if (!cached) {
-    std::vector<std::string> sonames;
-    ReadExtensionLibraries("/system/etc", &sonames);
-    ReadExtensionLibraries("/product/etc", &sonames);
-    list = android::base::Join(sonames, ':');
-    cached = true;
-  }
+  static std::string list = InitExtendedPublicLibraries();
   return list;
 }
 
 const std::string& llndk_libraries() {
-  static bool cached = false;
-  static std::string list;
-  if (!cached) {
-    std::string config_file = kLlndkLibrariesFile;
-    InsertVndkVersionStr(&config_file);
-    std::vector<std::string> sonames;
-    ReadConfig(config_file, &sonames, always_true, nullptr);
-    list = android::base::Join(sonames, ':');
-    cached = true;
-  }
+  static std::string list = InitLlndkLibraries();
   return list;
 }
 
 const std::string& vndksp_libraries() {
-  static bool cached = false;
-  static std::string list;
-  if (!cached) {
-    std::string config_file = kVndkLibrariesFile;
-    InsertVndkVersionStr(&config_file);
-    std::vector<std::string> sonames;
-    ReadConfig(config_file, &sonames, always_true, nullptr);
-    list = android::base::Join(sonames, ':');
-    cached = true;
-  }
+  static std::string list = InitVndkspLibraries();
   return list;
 }
 
diff --git a/libprocessgroup/Android.bp b/libprocessgroup/Android.bp
index 78a02e5..0207a75 100644
--- a/libprocessgroup/Android.bp
+++ b/libprocessgroup/Android.bp
@@ -32,6 +32,8 @@
     shared_libs: [
         "libbase",
         "libcgrouprc",
+    ],
+    static_libs: [
         "libjsoncpp",
     ],
     // for cutils/android_filesystem_config.h
diff --git a/libziparchive/include/ziparchive/zip_archive.h b/libziparchive/include/ziparchive/zip_archive.h
index 6e837a4..7eead7e 100644
--- a/libziparchive/include/ziparchive/zip_archive.h
+++ b/libziparchive/include/ziparchive/zip_archive.h
@@ -177,7 +177,10 @@
  *
  * Returns 0 on success and negative values on failure.
  */
-// TODO: switch these ZipStrings to std::string_view.
+int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
+                       const std::string_view optional_prefix = "",
+                       const std::string_view optional_suffix = "");
+// TODO: remove this.
 int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
                        const ZipString* optional_prefix, const ZipString* optional_suffix);
 
diff --git a/libziparchive/unzip.cpp b/libziparchive/unzip.cpp
index c6def73..3a3a694 100644
--- a/libziparchive/unzip.cpp
+++ b/libziparchive/unzip.cpp
@@ -249,7 +249,7 @@
   // libziparchive iteration order doesn't match the central directory.
   // We could sort, but that would cost extra and wouldn't match either.
   void* cookie;
-  int err = StartIteration(zah, &cookie, nullptr, nullptr);
+  int err = StartIteration(zah, &cookie);
   if (err != 0) {
     error(1, 0, "couldn't iterate %s: %s", archive_name, ErrorCodeString(err));
   }
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 2bd8fb9..ac3e236 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -689,54 +689,59 @@
 }
 
 struct IterationHandle {
-  uint32_t position;
-  // TODO: switch these to std::string now that Windows uses libc++ too.
-  ZipString prefix;
-  ZipString suffix;
   ZipArchive* archive;
 
-  IterationHandle(const ZipString* in_prefix, const ZipString* in_suffix) {
-    if (in_prefix) {
-      uint8_t* name_copy = new uint8_t[in_prefix->name_length];
-      memcpy(name_copy, in_prefix->name, in_prefix->name_length);
-      prefix.name = name_copy;
-      prefix.name_length = in_prefix->name_length;
-    } else {
-      prefix.name = NULL;
-      prefix.name_length = 0;
-    }
-    if (in_suffix) {
-      uint8_t* name_copy = new uint8_t[in_suffix->name_length];
-      memcpy(name_copy, in_suffix->name, in_suffix->name_length);
-      suffix.name = name_copy;
-      suffix.name_length = in_suffix->name_length;
-    } else {
-      suffix.name = NULL;
-      suffix.name_length = 0;
-    }
-  }
+  std::string prefix_holder;
+  ZipString prefix;
 
-  ~IterationHandle() {
-    delete[] prefix.name;
-    delete[] suffix.name;
-  }
+  std::string suffix_holder;
+  ZipString suffix;
+
+  uint32_t position = 0;
+
+  IterationHandle(ZipArchive* archive, const std::string_view in_prefix,
+                  const std::string_view in_suffix)
+      : archive(archive),
+        prefix_holder(in_prefix),
+        prefix(prefix_holder),
+        suffix_holder(in_suffix),
+        suffix(suffix_holder) {}
 };
 
 int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
-                       const ZipString* optional_prefix, const ZipString* optional_suffix) {
+                       const std::string_view optional_prefix,
+                       const std::string_view optional_suffix) {
   if (archive == NULL || archive->hash_table == NULL) {
     ALOGW("Zip: Invalid ZipArchiveHandle");
     return kInvalidHandle;
   }
 
-  IterationHandle* cookie = new IterationHandle(optional_prefix, optional_suffix);
-  cookie->position = 0;
-  cookie->archive = archive;
+  if (optional_prefix.size() > static_cast<size_t>(UINT16_MAX) ||
+      optional_suffix.size() > static_cast<size_t>(UINT16_MAX)) {
+    ALOGW("Zip: prefix/suffix too long");
+    return kInvalidEntryName;
+  }
 
-  *cookie_ptr = cookie;
+  *cookie_ptr = new IterationHandle(archive, optional_prefix, optional_suffix);
   return 0;
 }
 
+// TODO: remove this.
+int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
+                       const ZipString* optional_prefix, const ZipString* optional_suffix) {
+  std::string prefix;
+  if (optional_prefix) {
+    prefix = std::string(reinterpret_cast<const char*>(optional_prefix->name),
+                         optional_prefix->name_length);
+  }
+  std::string suffix;
+  if (optional_suffix) {
+    suffix = std::string(reinterpret_cast<const char*>(optional_suffix->name),
+                         optional_suffix->name_length);
+  }
+  return StartIteration(archive, cookie_ptr, prefix.c_str(), suffix.c_str());
+}
+
 void EndIteration(void* cookie) {
   delete reinterpret_cast<IterationHandle*>(cookie);
 }
diff --git a/libziparchive/zip_archive_benchmark.cpp b/libziparchive/zip_archive_benchmark.cpp
index 52166a4..434f2e1 100644
--- a/libziparchive/zip_archive_benchmark.cpp
+++ b/libziparchive/zip_archive_benchmark.cpp
@@ -75,7 +75,7 @@
 
   while (state.KeepRunning()) {
     OpenArchive(temp_file->path, &handle);
-    StartIteration(handle, &iteration_cookie, nullptr, nullptr);
+    StartIteration(handle, &iteration_cookie);
     while (Next(iteration_cookie, &data, &name) == 0) {
     }
     EndIteration(iteration_cookie);
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index cfbce1c..993c975 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -107,7 +107,7 @@
   close(fd);
 }
 
-static void AssertIterationOrder(const ZipString* prefix, const ZipString* suffix,
+static void AssertIterationOrder(const std::string_view prefix, const std::string_view suffix,
                                  const std::vector<std::string>& expected_names_sorted) {
   ZipArchiveHandle handle;
   ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
@@ -137,30 +137,26 @@
   static const std::vector<std::string> kExpectedMatchesSorted = {"a.txt", "b.txt", "b/", "b/c.txt",
                                                                   "b/d.txt"};
 
-  AssertIterationOrder(nullptr, nullptr, kExpectedMatchesSorted);
+  AssertIterationOrder("", "", kExpectedMatchesSorted);
 }
 
 TEST(ziparchive, IterationWithPrefix) {
-  ZipString prefix("b/");
   static const std::vector<std::string> kExpectedMatchesSorted = {"b/", "b/c.txt", "b/d.txt"};
 
-  AssertIterationOrder(&prefix, nullptr, kExpectedMatchesSorted);
+  AssertIterationOrder("b/", "", kExpectedMatchesSorted);
 }
 
 TEST(ziparchive, IterationWithSuffix) {
-  ZipString suffix(".txt");
   static const std::vector<std::string> kExpectedMatchesSorted = {"a.txt", "b.txt", "b/c.txt",
                                                                   "b/d.txt"};
 
-  AssertIterationOrder(nullptr, &suffix, kExpectedMatchesSorted);
+  AssertIterationOrder("", ".txt", kExpectedMatchesSorted);
 }
 
 TEST(ziparchive, IterationWithPrefixAndSuffix) {
-  ZipString prefix("b");
-  ZipString suffix(".txt");
   static const std::vector<std::string> kExpectedMatchesSorted = {"b.txt", "b/c.txt", "b/d.txt"};
 
-  AssertIterationOrder(&prefix, &suffix, kExpectedMatchesSorted);
+  AssertIterationOrder("b", ".txt", kExpectedMatchesSorted);
 }
 
 TEST(ziparchive, IterationWithBadPrefixAndSuffix) {
@@ -168,9 +164,7 @@
   ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
 
   void* iteration_cookie;
-  ZipString prefix("x");
-  ZipString suffix("y");
-  ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, &prefix, &suffix));
+  ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, "x", "y"));
 
   ZipEntry data;
   ZipString name;
@@ -228,7 +222,7 @@
   ASSERT_EQ(0, OpenArchiveWrapper("declaredlength.zip", &handle));
 
   void* iteration_cookie;
-  ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, nullptr, nullptr));
+  ASSERT_EQ(0, StartIteration(handle, &iteration_cookie));
 
   ZipString name;
   ZipEntry data;