Merge "libziparchive: start moving to a non-ZipString StartIteration API."
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 558e6c4..c091ff7 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -1183,6 +1183,7 @@
   boot_event_store.AddBootEventWithValue(boot_complete_prefix, uptime_s.count());
 
   RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init");
+  RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init.first_stage");
   RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init.selinux");
   RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init.cold_boot_wait");
 
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/README.md b/init/README.md
index 79c6237..c4505fe 100644
--- a/init/README.md
+++ b/init/README.md
@@ -695,8 +695,11 @@
 > Time after boot in ns (via the CLOCK\_BOOTTIME clock) at which the first
   stage of init started.
 
+`ro.boottime.init.first_stage`
+> How long in ns it took to run first stage.
+
 `ro.boottime.init.selinux`
-> How long it took the first stage to initialize SELinux.
+> How long in ns it took to run SELinux stage.
 
 `ro.boottime.init.cold_boot_wait`
 > How long init waited for ueventd's coldboot phase to end.
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index 8b95e38..7dd3ad4 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -235,9 +235,8 @@
 
     SetInitAvbVersionInRecovery();
 
-    static constexpr uint32_t kNanosecondsPerMillisecond = 1e6;
-    uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond;
-    setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1);
+    setenv(kEnvFirstStageStartedAt, std::to_string(start_time.time_since_epoch().count()).c_str(),
+           1);
 
     const char* path = "/system/bin/init";
     const char* args[] = {path, "selinux_setup", nullptr};
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 c79e459..1f3c2fc 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -35,6 +35,7 @@
 #include <android-base/chrono_utils.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/parseint.h>
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
@@ -55,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"
@@ -627,11 +629,38 @@
     }
 }
 
+static void RecordStageBoottimes(const boot_clock::time_point& second_stage_start_time) {
+    int64_t first_stage_start_time_ns = -1;
+    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(kEnvFirstStageStartedAt);
+
+    int64_t selinux_start_time_ns = -1;
+    if (auto selinux_start_time_str = getenv(kEnvSelinuxStartedAt); selinux_start_time_str) {
+        android::base::ParseInt(selinux_start_time_str, &selinux_start_time_ns);
+    }
+    unsetenv(kEnvSelinuxStartedAt);
+
+    if (selinux_start_time_ns == -1) return;
+    if (first_stage_start_time_ns == -1) return;
+
+    property_set("ro.boottime.init.first_stage",
+                 std::to_string(selinux_start_time_ns - first_stage_start_time_ns));
+    property_set("ro.boottime.init.selinux",
+                 std::to_string(second_stage_start_time.time_since_epoch().count() -
+                                selinux_start_time_ns));
+}
+
 int SecondStageMain(int argc, char** argv) {
     if (REBOOT_BOOTLOADER_ON_PANIC) {
         InstallRebootSignalHandlers();
     }
 
+    boot_clock::time_point start_time = boot_clock::now();
+
     // We need to set up stdin/stdout/stderr again now that we're running in init's context.
     InitKernelLogging(argv, InitAborter);
     LOG(INFO) << "init second stage started!";
@@ -663,9 +692,8 @@
     // used by init as well as the current required properties.
     export_kernel_boot_props();
 
-    // Make the time that init started available for bootstat to log.
-    property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));
-    property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK"));
+    // Make the time that init stages started available for bootstat to log.
+    RecordStageBoottimes(start_time);
 
     // Set libavb version for Framework-only OTA match in Treble build.
     const char* avb_version = getenv("INIT_AVB_VERSION");
@@ -678,8 +706,6 @@
     }
 
     // Clean up our environment.
-    unsetenv("INIT_STARTED_AT");
-    unsetenv("INIT_SELINUX_TOOK");
     unsetenv("INIT_AVB_VERSION");
     unsetenv("INIT_FORCE_DEBUGGABLE");
 
diff --git a/init/selinux.cpp b/init/selinux.cpp
index c49dc9f..8a63363 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -431,8 +431,6 @@
 }
 
 void SelinuxInitialize() {
-    Timer t;
-
     LOG(INFO) << "Loading SELinux policy";
     if (!LoadPolicy()) {
         LOG(FATAL) << "Unable to load SELinux policy";
@@ -449,9 +447,6 @@
     if (auto result = WriteFile("/sys/fs/selinux/checkreqprot", "0"); !result) {
         LOG(FATAL) << "Unable to write to /sys/fs/selinux/checkreqprot: " << result.error();
     }
-
-    // init's first stage can't set properties, so pass the time to the second stage.
-    setenv("INIT_SELINUX_TOOK", std::to_string(t.duration().count()).c_str(), 1);
 }
 
 }  // namespace
@@ -535,6 +530,8 @@
         InstallRebootSignalHandlers();
     }
 
+    boot_clock::time_point start_time = boot_clock::now();
+
     // Set up SELinux, loading the SELinux policy.
     SelinuxSetupKernelLogging();
     SelinuxInitialize();
@@ -547,6 +544,8 @@
         PLOG(FATAL) << "restorecon failed of /system/bin/init failed";
     }
 
+    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};
     execv(path, const_cast<char**>(args));
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/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
index f484550..33da1f1 100644
--- a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
+++ b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
@@ -585,6 +585,7 @@
       {"ro.boottime.imsdatadaemon", "u:object_r:boottime_prop:s0"},
       {"ro.boottime.imsqmidaemon", "u:object_r:boottime_prop:s0"},
       {"ro.boottime.init", "u:object_r:boottime_prop:s0"},
+      {"ro.boottime.init.first_stage", "u:object_r:boottime_prop:s0"},
       {"ro.boottime.init.cold_boot_wait", "u:object_r:boottime_prop:s0"},
       {"ro.boottime.init.mount_all.default", "u:object_r:boottime_prop:s0"},
       {"ro.boottime.init.selinux", "u:object_r:boottime_prop:s0"},