Merge "Support oem_#### users/groups for host_init_verifier"
diff --git a/bootstat/Android.bp b/bootstat/Android.bp
index dd9ba88..8fc2171 100644
--- a/bootstat/Android.bp
+++ b/bootstat/Android.bp
@@ -63,7 +63,6 @@
     name: "bootstat",
     defaults: ["bootstat_defaults"],
     static_libs: ["libbootstat"],
-    shared_libs: ["liblogcat"],
     init_rc: ["bootstat.rc"],
     product_variables: {
         pdk: {
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 9fe25fd..7ec57ec 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -43,7 +43,6 @@
 #include <android/log.h>
 #include <cutils/android_reboot.h>
 #include <cutils/properties.h>
-#include <log/logcat.h>
 #include <metricslogger/metrics_logger.h>
 
 #include "boot_event_record_store.h"
@@ -870,86 +869,7 @@
       }
     }
 
-    // The following battery test should migrate to a default system health HAL
-
-    // Let us not worry if the reboot command was issued, for the cases of
-    // reboot -p, reboot <no reason>, reboot cold, reboot warm and reboot hard.
-    // Same for bootloader and ro.boot.bootreasons of this set, but a dead
-    // battery could conceivably lead to these, so worthy of override.
-    if (isBluntRebootReason(ret)) {
-      // Heuristic to determine if shutdown possibly because of a dead battery?
-      // Really a hail-mary pass to find it in last klog content ...
-      static const int battery_dead_threshold = 2;  // percent
-      static const char battery[] = "healthd: battery l=";
-      const pstoreConsole console(content);
-      size_t pos = console.rfind(battery);  // last one
-      std::string digits;
-      if (pos != std::string::npos) {
-        digits = content.substr(pos + strlen(battery), strlen("100 "));
-        // correct common errors
-        correctForBitError(digits, "100 ");
-        if (digits[0] == '!') digits[0] = '1';
-        if (digits[1] == '!') digits[1] = '1';
-      }
-      const char* endptr = digits.c_str();
-      unsigned level = 0;
-      while (::isdigit(*endptr)) {
-        level *= 10;
-        level += *endptr++ - '0';
-        // make sure no leading zeros, except zero itself, and range check.
-        if ((level == 0) || (level > 100)) break;
-      }
-      // example bit error rate issues for 10%
-      //   'l=10 ' no bits in error
-      //   'l=00 ' single bit error (fails above)
-      //   'l=1  ' single bit error
-      //   'l=0  ' double bit error
-      // There are others, not typically critical because of 2%
-      // battery_dead_threshold. KISS check, make sure second
-      // character after digit sequence is not a space.
-      if ((level <= 100) && (endptr != digits.c_str()) && (endptr[0] == ' ') && (endptr[1] != ' ')) {
-        LOG(INFO) << "Battery level at shutdown " << level << "%";
-        if (level <= battery_dead_threshold) {
-          ret = "shutdown,battery";
-        }
-      } else {        // Most likely
-        digits = "";  // reset digits
-
-        // Content buffer no longer will have console data. Beware if more
-        // checks added below, that depend on parsing console content.
-        content = "";
-
-        LOG(DEBUG) << "Can not find last low battery in last console messages";
-        android_logcat_context ctx = create_android_logcat();
-        FILE* fp = android_logcat_popen(&ctx, "logcat -b kernel -v brief -d");
-        if (fp != nullptr) {
-          android::base::ReadFdToString(fileno(fp), &content);
-        }
-        android_logcat_pclose(&ctx, fp);
-        static const char logcat_battery[] = "W/healthd (    0): battery l=";
-
-        pos = content.find(logcat_battery);  // The first one it finds.
-        if (pos != std::string::npos) {
-          digits = content.substr(pos + strlen(logcat_battery), strlen("100 "));
-        }
-        endptr = digits.c_str();
-        level = 0;
-        while (::isdigit(*endptr)) {
-          level *= 10;
-          level += *endptr++ - '0';
-          // make sure no leading zeros, except zero itself, and range check.
-          if ((level == 0) || (level > 100)) break;
-        }
-        if ((level <= 100) && (endptr != digits.c_str()) && (*endptr == ' ')) {
-          LOG(INFO) << "Battery level at startup " << level << "%";
-          if (level <= battery_dead_threshold) {
-            ret = "shutdown,battery";
-          }
-        } else {
-          LOG(DEBUG) << "Can not find first battery level in dmesg or logcat";
-        }
-      }
-    }
+    // TODO: use the HAL to get battery level (http://b/77725702).
 
     // Is there a controlled shutdown hint in last_reboot_reason_property?
     if (isBluntRebootReason(ret)) {
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index b016e23..360ea95 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -20,6 +20,7 @@
 #include <string.h>
 
 #include <limits>
+#include <string_view>
 #include <thread>
 
 #include <android-base/file.h>
@@ -33,9 +34,10 @@
 using android::base::unique_fd;
 
 static void usage(int exit_code) {
-  fprintf(stderr, "usage: debuggerd [-b] PID\n");
+  fprintf(stderr, "usage: debuggerd [-bj] PID\n");
   fprintf(stderr, "\n");
   fprintf(stderr, "-b, --backtrace    just a backtrace rather than a full tombstone\n");
+  fprintf(stderr, "-j                 collect java traces\n");
   _exit(exit_code);
 }
 
@@ -58,8 +60,19 @@
 int main(int argc, char* argv[]) {
   if (argc <= 1) usage(0);
   if (argc > 3) usage(1);
-  if (argc == 3 && strcmp(argv[1], "-b") != 0 && strcmp(argv[1], "--backtrace") != 0) usage(1);
-  bool backtrace_only = argc == 3;
+
+  DebuggerdDumpType dump_type = kDebuggerdTombstone;
+
+  if (argc == 3) {
+    std::string_view flag = argv[1];
+    if (flag == "-b" || flag == "--backtrace") {
+      dump_type = kDebuggerdNativeBacktrace;
+    } else if (flag == "-j") {
+      dump_type = kDebuggerdJavaBacktrace;
+    } else {
+      usage(1);
+    }
+  }
 
   pid_t pid;
   if (!android::base::ParseInt(argv[argc - 1], &pid, 1, std::numeric_limits<pid_t>::max())) {
@@ -90,8 +103,7 @@
   }
 
   std::thread redirect_thread = spawn_redirect_thread(std::move(piperead));
-  if (!debuggerd_trigger_dump(pid, backtrace_only ? kDebuggerdNativeBacktrace : kDebuggerdTombstone,
-                              0, std::move(pipewrite))) {
+  if (!debuggerd_trigger_dump(pid, dump_type, 0, std::move(pipewrite))) {
     redirect_thread.join();
     errx(1, "failed to dump process %d", pid);
   }
diff --git a/init/host_import_parser.cpp b/init/host_import_parser.cpp
index faf6fc1..93e363f 100644
--- a/init/host_import_parser.cpp
+++ b/init/host_import_parser.cpp
@@ -23,22 +23,17 @@
 namespace android {
 namespace init {
 
-Result<Success> HostImportParser::ParseSection(std::vector<std::string>&& args,
-                                               const std::string& filename, int line) {
+Result<Success> HostImportParser::ParseSection(std::vector<std::string>&& args, const std::string&,
+                                               int) {
     if (args.size() != 2) {
         return Error() << "single argument needed for import\n";
     }
 
-    auto import_path = args[1];
+    return Success();
+}
 
-    if (StartsWith(import_path, "/system") || StartsWith(import_path, "/product") ||
-        StartsWith(import_path, "/odm") || StartsWith(import_path, "/vendor")) {
-        import_path = out_dir_ + "/" + import_path;
-    } else {
-        import_path = out_dir_ + "/root/" + import_path;
-    }
-
-    return ImportParser::ParseSection({"import", import_path}, filename, line);
+Result<Success> HostImportParser::ParseLineSection(std::vector<std::string>&&, int) {
+    return Error() << "Unexpected line found after import statement";
 }
 
 }  // namespace init
diff --git a/init/host_import_parser.h b/init/host_import_parser.h
index e2980b2..52b8891 100644
--- a/init/host_import_parser.h
+++ b/init/host_import_parser.h
@@ -19,21 +19,16 @@
 #include <string>
 #include <vector>
 
-#include "import_parser.h"
 #include "parser.h"
 
 namespace android {
 namespace init {
 
-class HostImportParser : public ImportParser {
+class HostImportParser : public SectionParser {
   public:
-    HostImportParser(const std::string& out_dir, Parser* parser)
-        : ImportParser(parser), out_dir_(out_dir) {}
-    Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename,
-                                 int line) override;
-
-  private:
-    std::string out_dir_;
+    HostImportParser() {}
+    Result<Success> ParseSection(std::vector<std::string>&& args, const std::string&, int) override;
+    Result<Success> ParseLineSection(std::vector<std::string>&&, int) override;
 };
 
 }  // namespace init
diff --git a/init/host_init_verifier.cpp b/init/host_init_verifier.cpp
index ba8ebfb..7e93b44 100644
--- a/init/host_init_verifier.cpp
+++ b/init/host_init_verifier.cpp
@@ -17,6 +17,7 @@
 #include <errno.h>
 #include <pwd.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 #include <iostream>
 #include <string>
@@ -45,11 +46,11 @@
 using android::base::ReadFileToString;
 using android::base::Split;
 
-static std::string out_dir;
+static std::string passwd_file;
 
 static std::vector<std::pair<std::string, int>> GetVendorPasswd() {
     std::string passwd;
-    if (!ReadFileToString(out_dir + "/vendor/etc/passwd", &passwd)) {
+    if (!ReadFileToString(passwd_file, &passwd)) {
         return {};
     }
 
@@ -126,20 +127,14 @@
 int main(int argc, char** argv) {
     android::base::InitLogging(argv, &android::base::StdioLogger);
     android::base::SetMinimumLogSeverity(android::base::ERROR);
-    if (argc != 3) {
-        LOG(ERROR) << "Usage: " << argv[0] << " <out directory> <properties>";
-        return -1;
+
+    if (argc != 2 && argc != 3) {
+        LOG(ERROR) << "Usage: " << argv[0] << " <init rc file> [passwd file]";
+        return EXIT_FAILURE;
     }
 
-    out_dir = argv[1];
-
-    auto properties = Split(argv[2], ",");
-    for (const auto& property : properties) {
-        auto split_property = Split(property, "=");
-        if (split_property.size() != 2) {
-            continue;
-        }
-        property_set(split_property[0], split_property[1]);
+    if (argc == 3) {
+        passwd_file = argv[2];
     }
 
     const BuiltinFunctionMap function_map;
@@ -149,22 +144,23 @@
     Parser parser;
     parser.AddSectionParser("service", std::make_unique<ServiceParser>(&sl, nullptr));
     parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, nullptr));
-    parser.AddSectionParser("import", std::make_unique<HostImportParser>(out_dir, &parser));
+    parser.AddSectionParser("import", std::make_unique<HostImportParser>());
 
-    if (!parser.ParseConfig(argv[1] + "/root/init.rc"s)) {
-        LOG(ERROR) << "Failed to find root init.rc script";
-        return -1;
+    if (!parser.ParseConfig(argv[1])) {
+        LOG(ERROR) << "Failed to open init rc script '" << argv[1] << "'";
+        return EXIT_FAILURE;
     }
     if (parser.parse_error_count() > 0) {
-        LOG(ERROR) << "Init script parsing failed with " << parser.parse_error_count() << " errors";
-        return -1;
+        LOG(ERROR) << "Failed to parse init script '" << argv[1] << "' with "
+                   << parser.parse_error_count() << " errors";
+        return EXIT_FAILURE;
     }
-    return 0;
+    return EXIT_SUCCESS;
 }
 
 }  // namespace init
 }  // namespace android
 
 int main(int argc, char** argv) {
-    android::init::main(argc, argv);
+    return android::init::main(argc, argv);
 }
diff --git a/libsync/include/ndk/sync.h b/libsync/include/ndk/sync.h
index a786d3e..49f01e1 100644
--- a/libsync/include/ndk/sync.h
+++ b/libsync/include/ndk/sync.h
@@ -32,8 +32,6 @@
 
 __BEGIN_DECLS
 
-#if __ANDROID_API__ >= __ANDROID_API_O__
-
 /* Fences indicate the status of an asynchronous task. They are initially
  * in unsignaled state (0), and make a one-time transition to either signaled
  * (1) or error (< 0) state. A sync file is a collection of one or more fences;
@@ -63,14 +61,14 @@
  * The original fences remain valid, and the caller is responsible for closing
  * them.
  */
-int32_t sync_merge(const char *name, int32_t fd1, int32_t fd2);
+int32_t sync_merge(const char* name, int32_t fd1, int32_t fd2) __INTRODUCED_IN(26);
 
 /**
  * Retrieve detailed information about a sync file and its fences.
  *
  * The returned sync_file_info must be freed by calling sync_file_info_free().
  */
-struct sync_file_info *sync_file_info(int32_t fd);
+struct sync_file_info* sync_file_info(int32_t fd) __INTRODUCED_IN(26);
 
 /**
  * Get the array of fence infos from the sync file's info.
@@ -88,9 +86,7 @@
 }
 
 /** Free a struct sync_file_info structure */
-void sync_file_info_free(struct sync_file_info *info);
-
-#endif // __ANDROID_API__ >= __ANDROID_API_O__
+void sync_file_info_free(struct sync_file_info* info) __INTRODUCED_IN(26);
 
 __END_DECLS
 
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index a0b1996..eebad2b 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -52,6 +52,7 @@
 namespace.default.permitted.paths += /system/${LIB}/extractors
 namespace.default.permitted.paths += /system/${LIB}/hw
 namespace.default.permitted.paths += /product/${LIB}
+namespace.default.permitted.paths += /system/product/${LIB}
 # These are where odex files are located. libart has to be able to dlopen the files
 namespace.default.permitted.paths += /system/framework
 namespace.default.permitted.paths += /system/app
@@ -66,6 +67,9 @@
 namespace.default.permitted.paths += /product/framework
 namespace.default.permitted.paths += /product/app
 namespace.default.permitted.paths += /product/priv-app
+namespace.default.permitted.paths += /system/product/framework
+namespace.default.permitted.paths += /system/product/app
+namespace.default.permitted.paths += /system/product/priv-app
 namespace.default.permitted.paths += /data
 namespace.default.permitted.paths += /mnt/expand
 
@@ -92,6 +96,10 @@
 namespace.default.asan.permitted.paths += /product/framework
 namespace.default.asan.permitted.paths += /product/app
 namespace.default.asan.permitted.paths += /product/priv-app
+namespace.default.asan.permitted.paths += /system/product/${LIB}
+namespace.default.asan.permitted.paths += /system/product/framework
+namespace.default.asan.permitted.paths += /system/product/app
+namespace.default.asan.permitted.paths += /system/product/priv-app
 namespace.default.asan.permitted.paths += /mnt/expand
 
 ###############################################################################