Merge "fs_mgr: overlayfs: export fs_mgr_overlayfs_candidate_list"
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 4a53a33..76c5ade 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -115,19 +115,14 @@
         "libbase",
         "libdebuggerd",
         "libunwindstack",
-        "libdexfile",  // libunwindstack dependency
-        "libdexfile_external",  // libunwindstack dependency
-        "libdexfile_support",  // libunwindstack dependency
+        "libdexfile_support_static",  // libunwindstack dependency
         "liblzma",
         "libcutils",
     ],
     target: {
         recovery: {
             exclude_static_libs: [
-                "libartbase",
-                "libdexfile",
-                "libdexfile_external",
-                "libdexfile_support",
+                "libdexfile_support_static",
             ],
         },
     },
@@ -174,8 +169,7 @@
     include_dirs: ["bionic/libc"],
 
     static_libs: [
-        "libdexfile_external",  // libunwindstack dependency
-        "libdexfile_support",  // libunwindstack dependency
+        "libdexfile_support_static",  // libunwindstack dependency
         "libunwindstack",
         "liblzma",
         "libbase",
@@ -185,8 +179,7 @@
     target: {
         recovery: {
             exclude_static_libs: [
-                "libdexfile_external",
-                "libdexfile_support",
+                "libdexfile_support_static",
             ],
         },
     },
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 1b077bc..898e28e 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -47,6 +47,7 @@
 using android::base::Split;
 using android::base::Timer;
 using android::fs_mgr::AvbHandle;
+using android::fs_mgr::AvbHandleStatus;
 using android::fs_mgr::AvbHashtreeResult;
 using android::fs_mgr::AvbUniquePtr;
 using android::fs_mgr::BuildGsiSystemFstabEntry;
@@ -737,8 +738,17 @@
         hashtree_result =
                 avb_handle_->SetUpAvbHashtree(fstab_entry, false /* wait_for_verity_dev */);
     } else if (!fstab_entry->avb_key.empty()) {
-        hashtree_result =
-                AvbHandle::SetUpStandaloneAvbHashtree(fstab_entry, false /* wait_for_verity_dev */);
+        if (!InitAvbHandle()) return false;
+        // Checks if hashtree should be disabled from the top-level /vbmeta.
+        if (avb_handle_->status() == AvbHandleStatus::kHashtreeDisabled ||
+            avb_handle_->status() == AvbHandleStatus::kVerificationDisabled) {
+            LOG(ERROR) << "Top-level vbmeta is disabled, skip Hashtree setup for "
+                       << fstab_entry->mount_point;
+            return true;  // Returns true to mount the partition directly.
+        } else {
+            hashtree_result = AvbHandle::SetUpStandaloneAvbHashtree(
+                    fstab_entry, false /* wait_for_verity_dev */);
+        }
     } else {
         return true;  // No need AVB, returns true to mount the partition directly.
     }
@@ -754,8 +764,6 @@
         default:
             return false;
     }
-
-    return true;  // Returns true to mount the partition.
 }
 
 bool FirstStageMountVBootV2::InitAvbHandle() {
diff --git a/libasyncio/Android.bp b/libasyncio/Android.bp
index 4ab439d..0fd2a3a 100644
--- a/libasyncio/Android.bp
+++ b/libasyncio/Android.bp
@@ -27,6 +27,7 @@
     name: "libasyncio",
     defaults: ["libasyncio_defaults"],
     vendor_available: true,
+    double_loadable: true,
     recovery_available: true,
     host_supported: true,
     srcs: [
diff --git a/libmeminfo/libdmabufinfo/tools/Android.bp b/libmeminfo/libdmabufinfo/tools/Android.bp
index 0af3c48..224b68e 100644
--- a/libmeminfo/libdmabufinfo/tools/Android.bp
+++ b/libmeminfo/libdmabufinfo/tools/Android.bp
@@ -26,5 +26,5 @@
     static_libs: [
         "libdmabufinfo",
     ],
-    soc_specific: true,
+    product_specific: true,
 }
\ No newline at end of file
diff --git a/libmemtrack/Android.bp b/libmemtrack/Android.bp
index 4e4554a..320b851 100644
--- a/libmemtrack/Android.bp
+++ b/libmemtrack/Android.bp
@@ -6,6 +6,7 @@
     vndk: {
         enabled: true,
     },
+    double_loadable: true,
     srcs: ["memtrack.cpp"],
     export_include_dirs: ["include"],
     local_include_dirs: ["include"],
diff --git a/libnativebridge/OWNERS b/libnativebridge/OWNERS
index 6f0824b..daf87f4 100644
--- a/libnativebridge/OWNERS
+++ b/libnativebridge/OWNERS
@@ -1,2 +1,4 @@
 dimitry@google.com
 eaeltsin@google.com
+ngeoffray@google.com
+oth@google.com
diff --git a/libprocessgroup/cgroup_map.cpp b/libprocessgroup/cgroup_map.cpp
index cd8ef94..d094811 100644
--- a/libprocessgroup/cgroup_map.cpp
+++ b/libprocessgroup/cgroup_map.cpp
@@ -126,22 +126,26 @@
         return false;
     }
 
-    Json::Value cgroups = root["Cgroups"];
-    for (Json::Value::ArrayIndex i = 0; i < cgroups.size(); ++i) {
-        std::string name = cgroups[i]["Controller"].asString();
-        descriptors->emplace(std::make_pair(
-                name,
-                CgroupDescriptor(1, name, cgroups[i]["Path"].asString(),
-                                 std::strtoul(cgroups[i]["Mode"].asString().c_str(), 0, 8),
-                                 cgroups[i]["UID"].asString(), cgroups[i]["GID"].asString())));
+    if (root.isMember("Cgroups")) {
+        const Json::Value& cgroups = root["Cgroups"];
+        for (Json::Value::ArrayIndex i = 0; i < cgroups.size(); ++i) {
+            std::string name = cgroups[i]["Controller"].asString();
+            descriptors->emplace(std::make_pair(
+                    name,
+                    CgroupDescriptor(1, name, cgroups[i]["Path"].asString(),
+                                     std::strtoul(cgroups[i]["Mode"].asString().c_str(), 0, 8),
+                                     cgroups[i]["UID"].asString(), cgroups[i]["GID"].asString())));
+        }
     }
 
-    Json::Value cgroups2 = root["Cgroups2"];
-    descriptors->emplace(std::make_pair(
-            CGROUPV2_CONTROLLER_NAME,
-            CgroupDescriptor(2, CGROUPV2_CONTROLLER_NAME, cgroups2["Path"].asString(),
-                             std::strtoul(cgroups2["Mode"].asString().c_str(), 0, 8),
-                             cgroups2["UID"].asString(), cgroups2["GID"].asString())));
+    if (root.isMember("Cgroups2")) {
+        const Json::Value& cgroups2 = root["Cgroups2"];
+        descriptors->emplace(std::make_pair(
+                CGROUPV2_CONTROLLER_NAME,
+                CgroupDescriptor(2, CGROUPV2_CONTROLLER_NAME, cgroups2["Path"].asString(),
+                                 std::strtoul(cgroups2["Mode"].asString().c_str(), 0, 8),
+                                 cgroups2["UID"].asString(), cgroups2["GID"].asString())));
+    }
 
     return true;
 }
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 447852d..b69103c 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -90,6 +90,10 @@
     if (sys_supports_timerslack) {
         auto file = StringPrintf("/proc/%d/timerslack_ns", tid);
         if (!WriteStringToFile(std::to_string(slack_), file)) {
+            if (errno == ENOENT) {
+                // This happens when process is already dead
+                return true;
+            }
             PLOG(ERROR) << "set_timerslack_ns write failed";
         }
     }
diff --git a/libprocinfo/Android.bp b/libprocinfo/Android.bp
index 15f03d0..27cda93 100644
--- a/libprocinfo/Android.bp
+++ b/libprocinfo/Android.bp
@@ -31,6 +31,7 @@
     vndk: {
         enabled: true,
     },
+    double_loadable: true,
     host_supported: true,
     srcs: [
         "process.cpp",
diff --git a/libusbhost/Android.bp b/libusbhost/Android.bp
index fc6f305..39bf3a5 100644
--- a/libusbhost/Android.bp
+++ b/libusbhost/Android.bp
@@ -20,6 +20,7 @@
     vndk: {
         enabled: true,
     },
+    double_loadable: true,
     host_supported: true,
     srcs: ["usbhost.c"],
     cflags: ["-Werror"],
diff --git a/libvndksupport/include/vndksupport/linker.h b/libvndksupport/include/vndksupport/linker.h
index f509564..5f48c39 100644
--- a/libvndksupport/include/vndksupport/linker.h
+++ b/libvndksupport/include/vndksupport/linker.h
@@ -20,6 +20,16 @@
 extern "C" {
 #endif
 
+/*
+ * Returns whether the current process is a vendor process.
+ *
+ * Note that this is only checking what process is running and has nothing to
+ * do with what namespace the caller is loaded at.  For example, a VNDK-SP
+ * library loaded by SP-HAL calling this function may still get a 'false',
+ * because it is running in a system process.
+ */
+int android_is_in_vendor_process();
+
 void* android_load_sphal_library(const char* name, int flag);
 
 int android_unload_sphal_library(void* handle);
diff --git a/libvndksupport/libvndksupport.map.txt b/libvndksupport/libvndksupport.map.txt
index d3db10f..ac9a99c 100644
--- a/libvndksupport/libvndksupport.map.txt
+++ b/libvndksupport/libvndksupport.map.txt
@@ -1,5 +1,6 @@
 LIBVNDKSUPPORT {
   global:
+    android_is_in_vendor_process; # vndk apex
     android_load_sphal_library; # vndk apex
     android_unload_sphal_library; # vndk apex
   local:
diff --git a/libvndksupport/linker.c b/libvndksupport/linker.c
index bc5620b..821940a 100644
--- a/libvndksupport/linker.c
+++ b/libvndksupport/linker.c
@@ -45,6 +45,17 @@
     return vendor_namespace;
 }
 
+int android_is_in_vendor_process() {
+    if (android_get_exported_namespace == NULL) {
+        ALOGD("android_get_exported_namespace() not available. Assuming system process.");
+        return 0;
+    }
+
+    // In vendor process, 'vndk' namespace is not visible, whereas in system
+    // process, it is.
+    return android_get_exported_namespace("vndk") == NULL;
+}
+
 void* android_load_sphal_library(const char* name, int flag) {
     struct android_namespace_t* vendor_namespace = get_vendor_namespace();
     if (vendor_namespace != NULL) {
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index cbbc710..b5e5a71 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -42,6 +42,23 @@
 LOCAL_POST_INSTALL_CMD = mkdir -p $(TARGET_OUT)/usr && rm -rf $(TARGET_OUT)/usr/icu
 LOCAL_POST_INSTALL_CMD += ; ln -sf /apex/com.android.runtime/etc/icu $(TARGET_OUT)/usr/icu
 
+# TODO(b/124106384): Clean up compat symlinks for ART binaries.
+ART_BINARIES= \
+  dalvikvm32 \
+  dalvikvm64 \
+  dex2oat \
+  dexdiag \
+  dexdump \
+  dexlist \
+  dexoptanalyzer \
+  oatdump \
+  profman \
+
+$(foreach b,$(ART_BINARIES), \
+  $(eval LOCAL_POST_INSTALL_CMD += \
+    ; ln -sf /apex/com.android.runtime/bin/$(b) $(TARGET_OUT)/bin/$(b)) \
+)
+
 # End of runtime APEX compatibilty.
 
 include $(BUILD_PREBUILT)
@@ -58,6 +75,16 @@
 include $(BUILD_PREBUILT)
 
 #######################################
+# cgroups.json for recovery
+include $(CLEAR_VARS)
+LOCAL_MODULE := cgroups.recovery.json
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/etc
+LOCAL_MODULE_STEM := cgroups.json
+include $(BUILD_PREBUILT)
+
+#######################################
 # task_profiles.json
 include $(CLEAR_VARS)
 
diff --git a/rootdir/cgroups.recovery.json b/rootdir/cgroups.recovery.json
new file mode 100644
index 0000000..f0bf5fd
--- /dev/null
+++ b/rootdir/cgroups.recovery.json
@@ -0,0 +1,9 @@
+{
+  "Cgroups": [
+    {
+      "Controller": "cpuacct",
+      "Path": "/acct",
+      "Mode": "0555"
+    }
+  ]
+}
diff --git a/rootdir/etc/TEST_MAPPING b/rootdir/etc/TEST_MAPPING
new file mode 100644
index 0000000..af2ec0f
--- /dev/null
+++ b/rootdir/etc/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "bionic-unit-tests"
+    }
+  ]
+}