Merge "Turn on executable bit on system_ext/bin"
diff --git a/base/README.md b/base/README.md
new file mode 100644
index 0000000..2ef5c10
--- /dev/null
+++ b/base/README.md
@@ -0,0 +1,42 @@
+# libbase
+
+## Who is this library for?
+
+This library is a collection of convenience functions to make common tasks
+easier and less error-prone.
+
+In this context, "error-prone" covers both "hard to do correctly" and
+"hard to do with good performance", but as a general purpose library,
+libbase's primary focus is on making it easier to do things easily and
+correctly when a compromise has to be made between "simplest API" on the
+one hand and "fastest implementation" on the other. Though obviously
+the ideal is to have both.
+
+## Should my routine be added?
+
+The intention is to cover the 80% use cases, not be all things to all users.
+
+If you have a routine that's really useful in your project,
+congratulations. But that doesn't mean it should be here rather than
+just in your project.
+
+The question for libbase is "should everyone be doing this?"/"does this
+make everyone's code cleaner/safer?". Historically we've considered the
+bar for inclusion to be "are there at least three *unrelated* projects
+that would be cleaned up by doing so".
+
+If your routine is actually something from a future C++ standard (that
+isn't yet in libc++), or it's widely used in another library, that helps
+show that there's precedent. Being able to say "so-and-so has used this
+API for n years" is a good way to reduce concerns about API choices.
+
+## Any other restrictions?
+
+Unlike most Android code, code in libbase has to build for Mac and
+Windows too.
+
+Code here is also expected to have good test coverage.
+
+By its nature, it's difficult to change libbase API. It's often best
+to start using your routine just in your project, and let it "graduate"
+after you're certain that the API is solid.
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index a8059b7..75ebd94 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1407,9 +1407,8 @@
             return -1;
         }
     } else {
-        // TODO(b/135984674): support remounting for ext4.
-        LERROR << "Remounting in checkpointing mode is not yet supported for ext4";
-        return -1;
+        // STOPSHIP(b/143970043): support remounting for ext4.
+        LWARNING << "Remounting into checkpointing is not supported for ex4. Proceed with caution";
     }
     return 0;
 }
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 9e168e9..e80f368 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -73,12 +73,25 @@
     return std::nullopt;
 }
 
+static void initHealthInfo(HealthInfo_2_1* health_info_2_1) {
+    *health_info_2_1 = HealthInfo_2_1{};
+
+    // HIDL enum values are zero initialized, so they need to be initialized
+    // properly.
+    health_info_2_1->batteryCapacityLevel = BatteryCapacityLevel::UNKNOWN;
+    auto* props = &health_info_2_1->legacy.legacy;
+    props->batteryStatus = BatteryStatus::UNKNOWN;
+    props->batteryHealth = BatteryHealth::UNKNOWN;
+}
+
 BatteryMonitor::BatteryMonitor()
     : mHealthdConfig(nullptr),
       mBatteryDevicePresent(false),
       mBatteryFixedCapacity(0),
       mBatteryFixedTemperature(0),
-      mHealthInfo(std::make_unique<HealthInfo_2_1>()) {}
+      mHealthInfo(std::make_unique<HealthInfo_2_1>()) {
+    initHealthInfo(mHealthInfo.get());
+}
 
 BatteryMonitor::~BatteryMonitor() {}
 
@@ -198,7 +211,7 @@
 }
 
 void BatteryMonitor::updateValues(void) {
-    *mHealthInfo = HealthInfo_2_1{};
+    initHealthInfo(mHealthInfo.get());
 
     HealthInfo_1_0& props = mHealthInfo->legacy.legacy;
 
diff --git a/init/reboot.cpp b/init/reboot.cpp
index fc18ecb..4a16969 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -57,6 +57,7 @@
 #include "action_manager.h"
 #include "builtin_arguments.h"
 #include "init.h"
+#include "mount_namespace.h"
 #include "property_service.h"
 #include "reboot_utils.h"
 #include "service.h"
@@ -713,6 +714,18 @@
     SendStartSendingMessagesMessage();
 }
 
+static Result<void> UnmountAllApexes() {
+    const char* args[] = {"/system/bin/apexd", "--unmount-all"};
+    int status;
+    if (logwrap_fork_execvp(arraysize(args), args, &status, false, LOG_KLOG, true, nullptr) != 0) {
+        return ErrnoError() << "Failed to call '/system/bin/apexd --unmount-all'";
+    }
+    if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+        return {};
+    }
+    return Error() << "'/system/bin/apexd --unmount-all' failed : " << status;
+}
+
 static Result<void> DoUserspaceReboot() {
     LOG(INFO) << "Userspace reboot initiated";
     auto guard = android::base::make_scope_guard([] {
@@ -746,30 +759,20 @@
         // TODO(b/135984674): store information about offending services for debugging.
         return Error() << r << " post-data services are still running";
     }
-    // We only really need to restart vold if userdata is ext4 filesystem.
-    // TODO(b/135984674): get userdata fs type here, and do nothing in case of f2fs.
-    // First shutdown volumes managed by vold. They will be recreated by
-    // system_server.
-    Service* vold_service = ServiceList::GetInstance().FindService("vold");
-    if (vold_service != nullptr && vold_service->IsRunning()) {
-        if (auto result = ShutdownVold(); !result) {
-            return result;
-        }
-        LOG(INFO) << "Restarting vold";
-        vold_service->Restart();
-    }
-    // Again, we only need to kill zram backing device in case of ext4 userdata.
-    // TODO(b/135984674): get userdata fs type here, and do nothing in case of f2fs.
-    if (auto result = KillZramBackingDevice(); !result) {
-        return result;
-    }
+    // TODO(b/143970043): in case of ext4 we probably we will need to restart vold and kill zram
+    //  backing device.
     if (int r = StopServicesAndLogViolations(GetDebuggingServices(true /* only_post_data */), 5s,
                                              false /* SIGKILL */);
         r > 0) {
         // TODO(b/135984674): store information about offending services for debugging.
         return Error() << r << " debugging services are still running";
     }
-    // TODO(b/135984674): deactivate APEX modules and switch back to bootstrap namespace.
+    if (auto result = UnmountAllApexes(); !result) {
+        return result;
+    }
+    if (!SwitchToBootstrapMountNamespaceIfNeeded()) {
+        return Error() << "Failed to switch to bootstrap namespace";
+    }
     // Re-enable services
     for (const auto& s : were_enabled) {
         LOG(INFO) << "Re-enabling service '" << s->name() << "'";
diff --git a/init/selinux.cpp b/init/selinux.cpp
index a15d136..a9cd290 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -514,9 +514,6 @@
 
 }  // namespace
 
-// The files and directories that were created before initial sepolicy load or
-// files on ramdisk need to have their security context restored to the proper
-// value. This must happen before /dev is populated by ueventd.
 void SelinuxRestoreContext() {
     LOG(INFO) << "Running restorecon...";
     selinux_android_restorecon("/dev", 0);
@@ -560,15 +557,12 @@
     return 0;
 }
 
-// This function sets up SELinux logging to be written to kmsg, to match init's logging.
 void SelinuxSetupKernelLogging() {
     selinux_callback cb;
     cb.func_log = SelinuxKlogCallback;
     selinux_set_callback(SELINUX_CB_LOG, cb);
 }
 
-// This function returns the Android version with which the vendor SEPolicy was compiled.
-// It is used for version checks such as whether or not vendor_init should be used
 int SelinuxGetVendorAndroidVersion() {
     static int vendor_android_version = [] {
         if (!IsSplitPolicyDevice()) {
@@ -594,7 +588,6 @@
     return vendor_android_version;
 }
 
-// This function initializes SELinux then execs init to run in the init SELinux context.
 int SetupSelinux(char** argv) {
     SetStdioToDevNull(argv);
     InitKernelLogging(argv);
diff --git a/init/selinux.h b/init/selinux.h
index 63ad470..1a41bfd 100644
--- a/init/selinux.h
+++ b/init/selinux.h
@@ -19,10 +19,19 @@
 namespace android {
 namespace init {
 
+// Initialize SELinux, then exec init to run in the init SELinux context.
 int SetupSelinux(char** argv);
+
+// Restore the proper security context to files and directories on ramdisk, and
+// those that were created before initial sepolicy load.
+// This must happen before /dev is populated by ueventd.
 void SelinuxRestoreContext();
 
+// Set up SELinux logging to be written to kmsg, to match init's logging.
 void SelinuxSetupKernelLogging();
+
+// Return the Android API level with which the vendor SEPolicy was compiled.
+// Used for version checks such as whether or not vendor_init should be used.
 int SelinuxGetVendorAndroidVersion();
 
 static constexpr char kEnvSelinuxStartedAt[] = "SELINUX_STARTED_AT";
diff --git a/libcutils/fs_config_test.cpp b/libcutils/fs_config_test.cpp
index 9627152..c6684b4 100644
--- a/libcutils/fs_config_test.cpp
+++ b/libcutils/fs_config_test.cpp
@@ -46,7 +46,7 @@
         // clang-format off
     { true,  "system/lib",             "system/lib/hw",           true  },
     { true,  "vendor/lib",             "system/vendor/lib/hw",    true  },
-    { true,  "system/vendor/lib",      "vendor/lib/hw",           true  },
+    { true,  "system/vendor/lib",      "vendor/lib/hw",           false },
     { true,  "system/vendor/lib",      "system/vendor/lib/hw",    true  },
     { true,  "foo/*/bar/*",            "foo/1/bar/2",             true  },
     { true,  "foo/*/bar/*",            "foo/1/bar",               true  },
@@ -56,13 +56,14 @@
     { false, "vendor/bin/wifi",        "system/vendor/bin/wifi",  true  },
     { false, "vendor/bin/wifi",        "system/vendor/bin/wifi2", false },
     { false, "system/vendor/bin/wifi", "system/vendor/bin/wifi",  true, },
-    { false, "odm/bin/wifi",           "system/odm/bin/wifi",     true  },
-    { false, "oem/bin/wifi",           "system/oem/bin/wifi",     true  },
+    { false, "odm/bin/wifi",           "system/odm/bin/wifi",     false },
+    { false, "odm/bin/wifi",           "vendor/odm/bin/wifi",     true  },
+    { false, "oem/bin/wifi",           "system/oem/bin/wifi",     false },
     { false, "data/bin/wifi",          "system/data/bin/wifi",    false },
     { false, "system/bin/*",           "system/bin/wifi",         true  },
     { false, "vendor/bin/*",           "system/vendor/bin/wifi",  true  },
     { false, "system/bin/*",           "system/bin",              false },
-    { false, "system/vendor/bin/*",    "vendor/bin/wifi",         true  },
+    { false, "system/vendor/bin/*",    "vendor/bin/wifi",         false },
     { false, "foo/*/bar/*",            "foo/1/bar/2",             true  },
     { false, "foo/*/bar/*",            "foo/1/bar",               false },
     { false, "foo/*/bar/*",            "foo/1/bar/2/3",           true  },
diff --git a/libutils/include/utils/Trace.h b/libutils/include/utils/Trace.h
index fec0ffa..9986bf5 100644
--- a/libutils/include/utils/Trace.h
+++ b/libutils/include/utils/Trace.h
@@ -33,7 +33,7 @@
 // ATRACE_NAME traces from its location until the end of its enclosing scope.
 #define _PASTE(x, y) x ## y
 #define PASTE(x, y) _PASTE(x,y)
-#define ATRACE_NAME(name) android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG, name)
+#define ATRACE_NAME(name) ::android::ScopedTrace PASTE(___tracer, __LINE__)(ATRACE_TAG, name)
 
 // ATRACE_CALL is an ATRACE_NAME that uses the current function name.
 #define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 66d60fa..a8e0f5f 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -924,7 +924,7 @@
   setprop sys.init.userspace_reboot_in_progress 1
   setprop sys.boot_completed 0
   setprop sys.init.updatable_crashing 0
-  setprop apexd.status 0
+  setprop apexd.status ""
 
 on userspace-reboot-fs-remount
   # Make sure that vold is running.