Merge "SurfaceFlinger: remove DdmConnection"
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index 65743d9..9d3a234 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -229,16 +229,16 @@
 }
 
 // OTA slot script
-cc_prebuilt_binary {
+sh_binary {
     name: "otapreopt_slot",
-    srcs: ["otapreopt_slot.sh"],
+    src: "otapreopt_slot.sh",
     init_rc: ["otapreopt.rc"],
 }
 
 // OTA postinstall script
-cc_prebuilt_binary {
+sh_binary {
     name: "otapreopt_script",
-    srcs: ["otapreopt_script.sh"],
+    src: "otapreopt_script.sh",
     // Let this depend on otapreopt, the chroot tool and the slot script,
     // so we just have to mention one in a configuration.
     required: [
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 1c99663..609ddaf 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -41,6 +41,23 @@
 namespace android {
 namespace installd {
 
+// Configuration for bind-mounted Bionic artifacts.
+
+static constexpr const char* kLinkerMountPoint = "/bionic/bin/linker";
+static constexpr const char* kRuntimeLinkerPath = "/apex/com.android.runtime/bin/linker";
+
+static constexpr const char* kBionicLibsMountPointDir = "/bionic/lib/";
+static constexpr const char* kRuntimeBionicLibsDir = "/apex/com.android.runtime/lib/bionic/";
+
+static constexpr const char* kLinkerMountPoint64 = "/bionic/bin/linker64";
+static constexpr const char* kRuntimeLinkerPath64 = "/apex/com.android.runtime/bin/linker64";
+
+static constexpr const char* kBionicLibsMountPointDir64 = "/bionic/lib64/";
+static constexpr const char* kRuntimeBionicLibsDir64 = "/apex/com.android.runtime/lib64/bionic/";
+
+static const std::vector<std::string> kBionicLibFileNames = {"libc.so", "libm.so", "libdl.so"};
+
+
 static void CloseDescriptor(int fd) {
     if (fd >= 0) {
         int result = close(fd);
@@ -79,6 +96,43 @@
     }
 }
 
+// Copied from system/core/init/mount_namespace.cpp.
+static bool BindMount(const std::string& source, const std::string& mount_point,
+                      bool recursive = false) {
+    unsigned long mountflags = MS_BIND;
+    if (recursive) {
+        mountflags |= MS_REC;
+    }
+    if (mount(source.c_str(), mount_point.c_str(), nullptr, mountflags, nullptr) == -1) {
+        PLOG(ERROR) << "Could not bind-mount " << source << " to " << mount_point;
+        return false;
+    }
+    return true;
+}
+
+// Copied from system/core/init/mount_namespace.cpp and and adjusted (bind
+// mounts are not made private, as the /postinstall is already private (see
+// `android::installd::otapreopt_chroot`).
+static bool BindMountBionic(const std::string& linker_source, const std::string& lib_dir_source,
+                            const std::string& linker_mount_point,
+                            const std::string& lib_mount_dir) {
+    if (access(linker_source.c_str(), F_OK) != 0) {
+        PLOG(INFO) << linker_source << " does not exist. Skipping mounting Bionic there.";
+        return true;
+    }
+    if (!BindMount(linker_source, linker_mount_point)) {
+        return false;
+    }
+    for (const auto& libname : kBionicLibFileNames) {
+        std::string mount_point = lib_mount_dir + libname;
+        std::string source = lib_dir_source + libname;
+        if (!BindMount(source, mount_point)) {
+            return false;
+        }
+    }
+    return true;
+}
+
 // Entry for otapreopt_chroot. Expected parameters are:
 //   [cmd] [status-fd] [target-slot] "dexopt" [dexopt-params]
 // The file descriptor denoted by status-fd will be closed. The rest of the parameters will
@@ -222,6 +276,23 @@
     // the Android Runtime APEX, as it is required by otapreopt to run dex2oat.
     std::vector<apex::ApexFile> active_packages = ActivateApexPackages();
 
+    // Bind-mount Bionic artifacts from the Runtime APEX.
+    // This logic is copied and adapted from system/core/init/mount_namespace.cpp.
+    if (!BindMountBionic(kRuntimeLinkerPath, kRuntimeBionicLibsDir, kLinkerMountPoint,
+                         kBionicLibsMountPointDir)) {
+        LOG(ERROR) << "Failed to mount 32-bit Bionic artifacts from the Runtime APEX.";
+        // Clean up and exit.
+        DeactivateApexPackages(active_packages);
+        exit(215);
+    }
+    if (!BindMountBionic(kRuntimeLinkerPath64, kRuntimeBionicLibsDir64, kLinkerMountPoint64,
+                         kBionicLibsMountPointDir64)) {
+        LOG(ERROR) << "Failed to mount 64-bit Bionic artifacts from the Runtime APEX.";
+        // Clean up and exit.
+        DeactivateApexPackages(active_packages);
+        exit(216);
+    }
+
     // Now go on and run otapreopt.
 
     // Incoming:  cmd + status-fd + target-slot + cmd...      | Incoming | = argc
diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp
index cf7f1eb..7327710 100644
--- a/cmds/installd/tests/installd_service_test.cpp
+++ b/cmds/installd/tests/installd_service_test.cpp
@@ -451,12 +451,12 @@
 TEST_F(ServiceTest, CreateAppDataSnapshot_ClearsCache) {
   auto fake_package_ce_path = create_data_user_ce_package_path("TEST", 0, "com.foo");
   auto fake_package_de_path = create_data_user_de_package_path("TEST", 0, "com.foo");
-  auto fake_package_ce_cache_path = read_path_inode(fake_package_ce_path,
-      "cache", kXattrInodeCache);
-  auto fake_package_ce_code_cache_path = read_path_inode(fake_package_ce_path,
-      "code_cache", kXattrInodeCache);
+  auto fake_package_ce_cache_path = fake_package_ce_path + "/cache";
+  auto fake_package_ce_code_cache_path = fake_package_ce_path + "/code_cache";
   auto fake_package_de_cache_path = fake_package_de_path + "/cache";
   auto fake_package_de_code_cache_path = fake_package_de_path + "/code_cache";
+  auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0);
+  auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0);
 
   ASSERT_TRUE(mkdirs(fake_package_ce_path, 700));
   ASSERT_TRUE(mkdirs(fake_package_de_path, 700));
@@ -464,20 +464,15 @@
   ASSERT_TRUE(mkdirs(fake_package_ce_code_cache_path, 700));
   ASSERT_TRUE(mkdirs(fake_package_de_cache_path, 700));
   ASSERT_TRUE(mkdirs(fake_package_de_code_cache_path, 700));
+  ASSERT_TRUE(mkdirs(rollback_ce_dir, 700));
+  ASSERT_TRUE(mkdirs(rollback_de_dir, 700));
 
   auto deleter = [&fake_package_ce_path, &fake_package_de_path,
-          &fake_package_ce_cache_path, &fake_package_ce_code_cache_path,
-          &fake_package_de_cache_path, &fake_package_de_code_cache_path]() {
+          &rollback_ce_dir, &rollback_de_dir]() {
       delete_dir_contents(fake_package_ce_path, true);
       delete_dir_contents(fake_package_de_path, true);
-      delete_dir_contents(fake_package_ce_cache_path, true);
-      delete_dir_contents(fake_package_ce_code_cache_path, true);
-      delete_dir_contents(fake_package_de_cache_path, true);
-      delete_dir_contents(fake_package_de_code_cache_path, true);
-      rmdir(fake_package_ce_cache_path.c_str());
-      rmdir(fake_package_ce_code_cache_path.c_str());
-      rmdir(fake_package_de_cache_path.c_str());
-      rmdir(fake_package_de_code_cache_path.c_str());
+      delete_dir_contents_and_dir(rollback_ce_dir, true);
+      delete_dir_contents_and_dir(rollback_de_dir, true);
   };
   auto scope_guard = android::base::make_scope_guard(deleter);
 
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index b2db945..0423264 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -181,7 +181,10 @@
                 if ((outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
                     int size = ashmem_get_size_region(obj.handle);
                     if (size > 0) {
-                        *outAshmemSize -= size;
+                        // ashmem size might have changed since last time it was accounted for, e.g.
+                        // in acquire_object(). Value of *outAshmemSize is not critical since we are
+                        // releasing the object anyway. Check for integer overflow condition.
+                        *outAshmemSize -= std::min(*outAshmemSize, static_cast<size_t>(size));
                     }
                 }