snapuserd_test: skip test if dm-user kernel driver is absent

Bug: 357487459
Test: snapuserd_test
Change-Id: I8458f223fc35fcfa042588e67a30c5bb273b0277
Signed-off-by: Akilesh Kailash <akailash@google.com>
diff --git a/fs_mgr/libsnapshot/snapuserd/Android.bp b/fs_mgr/libsnapshot/snapuserd/Android.bp
index b3a7e8c..efbcb5a 100644
--- a/fs_mgr/libsnapshot/snapuserd/Android.bp
+++ b/fs_mgr/libsnapshot/snapuserd/Android.bp
@@ -267,6 +267,10 @@
     test_suites: [
         "vts",
     ],
+    test_options: {
+        // VABC mandatory in Android T per VSR.
+        min_shipping_api_level: 32,
+    },
 }
 
 cc_binary_host {
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_test.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_test.cpp
index 9042f2b..4dfb9bf 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_test.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_test.cpp
@@ -1530,6 +1530,14 @@
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
 
+#ifdef __ANDROID__
+    if (!android::snapshot::CanUseUserspaceSnapshots() ||
+        android::snapshot::IsVendorFromAndroid12()) {
+        std::cerr << "snapuserd_test not supported on this device\n";
+        return 0;
+    }
+#endif
+
     gflags::ParseCommandLineFlags(&argc, &argv, false);
 
     return RUN_ALL_TESTS();
diff --git a/fs_mgr/libsnapshot/snapuserd/utility.cpp b/fs_mgr/libsnapshot/snapuserd/utility.cpp
index 684ca3d..b44f5ab 100644
--- a/fs_mgr/libsnapshot/snapuserd/utility.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/utility.cpp
@@ -14,11 +14,14 @@
 
 #include "utility.h"
 
+#include <android-base/properties.h>
 #include <sys/resource.h>
 #include <sys/utsname.h>
 #include <unistd.h>
 
 #include <android-base/file.h>
+#include <android-base/logging.h>
+#include <libdm/dm.h>
 #include <processgroup/processgroup.h>
 
 #include <private/android_filesystem_config.h>
@@ -27,6 +30,7 @@
 namespace snapshot {
 
 using android::base::unique_fd;
+using android::dm::DeviceMapper;
 
 bool SetThreadPriority([[maybe_unused]] int priority) {
 #ifdef __ANDROID__
@@ -61,5 +65,38 @@
     return major > 5 || (major == 5 && minor >= 6);
 }
 
+bool GetUserspaceSnapshotsEnabledProperty() {
+    return android::base::GetBoolProperty("ro.virtual_ab.userspace.snapshots.enabled", false);
+}
+
+bool KernelSupportsCompressedSnapshots() {
+    auto& dm = DeviceMapper::Instance();
+    return dm.GetTargetByName("user", nullptr);
+}
+
+bool IsVendorFromAndroid12() {
+    const std::string UNKNOWN = "unknown";
+    const std::string vendor_release =
+            android::base::GetProperty("ro.vendor.build.version.release_or_codename", UNKNOWN);
+
+    if (vendor_release.find("12") != std::string::npos) {
+        return true;
+    }
+    return false;
+}
+
+bool CanUseUserspaceSnapshots() {
+    if (!GetUserspaceSnapshotsEnabledProperty()) {
+        LOG(INFO) << "Virtual A/B - Userspace snapshots disabled";
+        return false;
+    }
+
+    if (!KernelSupportsCompressedSnapshots()) {
+        LOG(ERROR) << "Userspace snapshots requested, but no kernel support is available.";
+        return false;
+    }
+    return true;
+}
+
 }  // namespace snapshot
 }  // namespace android
diff --git a/fs_mgr/libsnapshot/snapuserd/utility.h b/fs_mgr/libsnapshot/snapuserd/utility.h
index c3c3cba..50be418 100644
--- a/fs_mgr/libsnapshot/snapuserd/utility.h
+++ b/fs_mgr/libsnapshot/snapuserd/utility.h
@@ -24,5 +24,10 @@
 bool SetProfiles(std::initializer_list<std::string_view> profiles);
 bool KernelSupportsIoUring();
 
+bool GetUserspaceSnapshotsEnabledProperty();
+bool KernelSupportsCompressedSnapshots();
+bool CanUseUserspaceSnapshots();
+bool IsVendorFromAndroid12();
+
 }  // namespace snapshot
 }  // namespace android