Merge "Update visibility according to the change AVF directories layout" into main
diff --git a/fs_mgr/TEST_MAPPING b/fs_mgr/TEST_MAPPING
index 32e8b88..192232d 100644
--- a/fs_mgr/TEST_MAPPING
+++ b/fs_mgr/TEST_MAPPING
@@ -34,6 +34,9 @@
   ],
   "kernel-presubmit": [
     {
+      "name": "adb-remount-sh"
+    },
+    {
       "name": "libdm_test"
     },
     {
diff --git a/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h b/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h
index 90813fe..0afd8bd 100644
--- a/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h
+++ b/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h
@@ -30,6 +30,8 @@
 #include <storage_literals/storage_literals.h>
 #include <update_engine/update_metadata.pb.h>
 
+#include "utility.h"
+
 namespace android {
 namespace snapshot {
 
@@ -234,5 +236,21 @@
 
 #define RETURN_IF_NON_VIRTUAL_AB() RETURN_IF_NON_VIRTUAL_AB_MSG("")
 
+#define SKIP_IF_VENDOR_ON_ANDROID_S()                                        \
+    do {                                                                     \
+        if (IsVendorFromAndroid12())                                         \
+            GTEST_SKIP() << "Skip test as Vendor partition is on Android S"; \
+    } while (0)
+
+#define RETURN_IF_VENDOR_ON_ANDROID_S_MSG(msg) \
+    do {                                       \
+        if (IsVendorFromAndroid12()) {         \
+            std::cerr << (msg);                \
+            return;                            \
+        }                                      \
+    } while (0)
+
+#define RETURN_IF_VENDOR_ON_ANDROID_S() RETURN_IF_VENDOR_ON_ANDROID_S_MSG("")
+
 }  // namespace snapshot
 }  // namespace android
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 6674378..11aa3f9 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -20,6 +20,7 @@
 #include <sys/file.h>
 #include <sys/types.h>
 #include <sys/unistd.h>
+#include <sys/xattr.h>
 
 #include <chrono>
 #include <filesystem>
@@ -91,6 +92,8 @@
 static constexpr char kRollbackIndicatorPath[] = "/metadata/ota/rollback-indicator";
 static constexpr char kSnapuserdFromSystem[] = "/metadata/ota/snapuserd-from-system";
 static constexpr auto kUpdateStateCheckInterval = 2s;
+static constexpr char kOtaFileContext[] = "u:object_r:ota_metadata_file:s0";
+
 /*
  * The readahead size is set to 32kb so that
  * there is no significant memory pressure (/proc/pressure/memory) during boot.
@@ -2135,6 +2138,24 @@
         PLOG(ERROR) << "Unable to write to vendor update path: " << path;
         return false;
     }
+
+    unique_fd fd(open(path.c_str(), O_PATH));
+    if (fd < 0) {
+        PLOG(ERROR) << "Failed to open file: " << path;
+        return false;
+    }
+
+    /*
+     * This function is invoked by first stage init and hence we need to
+     * explicitly set the correct selinux label for this file as update_engine
+     * will try to remove this file later on once the snapshot merge is
+     * complete.
+     */
+    if (fsetxattr(fd.get(), XATTR_NAME_SELINUX, kOtaFileContext, strlen(kOtaFileContext) + 1, 0) <
+        0) {
+        PLOG(ERROR) << "fsetxattr for the path: " << path << " failed";
+    }
+
     return true;
 }
 
@@ -2185,18 +2206,24 @@
  *
  */
 bool SnapshotManager::IsLegacySnapuserdPostReboot() {
-    if (is_legacy_snapuserd_.has_value() && is_legacy_snapuserd_.value() == true) {
-        auto slot = GetCurrentSlot();
-        if (slot == Slot::Target) {
-            // If this marker is present, then daemon can handle userspace
-            // snapshots; also, it indicates that the vendor partition was
-            // updated from Android 12.
-            if (access(GetSnapuserdFromSystemPath().c_str(), F_OK) == 0) {
-                return false;
-            }
+    auto slot = GetCurrentSlot();
+    if (slot == Slot::Target) {
+        /*
+            If this marker is present, the daemon can handle userspace snapshots.
+            During post-OTA reboot, this implies that the vendor partition is
+            Android 13 or higher. If the snapshots were created on an
+            Android 12 vendor, this means the vendor partition has been updated.
+        */
+        if (access(GetSnapuserdFromSystemPath().c_str(), F_OK) == 0) {
+            is_snapshot_userspace_ = true;
+            return false;
+        }
+        // If the marker isn't present and if the vendor is still in Android 12
+        if (is_legacy_snapuserd_.has_value() && is_legacy_snapuserd_.value() == true) {
             return true;
         }
     }
+
     return false;
 }
 
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index 1435b12..07f1301 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -122,6 +122,7 @@
         LOG(INFO) << "Starting test: " << test_name_;
 
         SKIP_IF_NON_VIRTUAL_AB();
+        SKIP_IF_VENDOR_ON_ANDROID_S();
 
         SetupProperties();
         if (!DeviceSupportsMode()) {
@@ -168,6 +169,7 @@
 
     void TearDown() override {
         RETURN_IF_NON_VIRTUAL_AB();
+        RETURN_IF_VENDOR_ON_ANDROID_S();
 
         LOG(INFO) << "Tearing down SnapshotTest test: " << test_name_;
 
@@ -1015,6 +1017,7 @@
   public:
     void SetUp() override {
         SKIP_IF_NON_VIRTUAL_AB();
+        SKIP_IF_VENDOR_ON_ANDROID_S();
 
         SnapshotTest::SetUp();
         if (!image_manager_) {
@@ -1097,6 +1100,7 @@
     }
     void TearDown() override {
         RETURN_IF_NON_VIRTUAL_AB();
+        RETURN_IF_VENDOR_ON_ANDROID_S();
 
         LOG(INFO) << "Tearing down SnapshotUpdateTest test: " << test_name_;
 
@@ -2833,6 +2837,7 @@
     // that is fixed, don't call GTEST_SKIP here, but instead call GTEST_SKIP in individual test
     // suites.
     RETURN_IF_NON_VIRTUAL_AB_MSG("Virtual A/B is not enabled, skipping global setup.\n");
+    RETURN_IF_VENDOR_ON_ANDROID_S_MSG("Test not enabled for Vendor on Android S.\n");
 
     std::vector<std::string> paths = {
             // clang-format off
@@ -2887,6 +2892,8 @@
 
 void SnapshotTestEnvironment::TearDown() {
     RETURN_IF_NON_VIRTUAL_AB();
+    RETURN_IF_VENDOR_ON_ANDROID_S();
+
     if (super_images_ != nullptr) {
         DeleteBackingImage(super_images_.get(), "fake-super");
     }
diff --git a/init/README.md b/init/README.md
index 11c4e1c..0bb26e8 100644
--- a/init/README.md
+++ b/init/README.md
@@ -499,9 +499,11 @@
    4. `late-fs` - Mount partitions marked as latemounted.
    5. `post-fs-data` - Mount and configure `/data`; set up encryption. `/metadata` is
       reformatted here if it couldn't mount in first-stage init.
-   6. `zygote-start` - Start the zygote.
-   7. `early-boot` - After zygote has started.
-   8. `boot` - After `early-boot` actions have completed.
+   6. `post-fs-data-checkpointed` - Triggered when vold has completed committing a checkpoint
+      after an OTA update. Not triggered if checkpointing is not needed or supported.
+   7. `zygote-start` - Start the zygote.
+   8. `early-boot` - After zygote has started.
+   9. `boot` - After `early-boot` actions have completed.
 
 Commands
 --------
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 2443b7c..b804c1b 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -1087,6 +1087,9 @@
     # Update dm-verity state and set partition.*.verified properties.
     verity_update_state
 
+on property:vold.checkpoint_committed=1
+    trigger post-fs-data-checkpointed
+
 # It is recommended to put unnecessary data/ initialization from post-fs-data
 # to start-zygote in device's init.rc to unblock zygote start.
 on zygote-start