Only restore apex backups on non-checkpointing devices.

Backup and restore of /data/apex/active is only intended to occur on
devices that do not have FS-checkpointing support. This change
ensures that backups are not restored on devices that do support
checkpointing.

Cherry-pick of aosp/1767767

Bug: 192102594
Bug: 193932765
Test: atest ApexServiceRevertTest
Change-Id: Ia07633c0da71f167098b15958e519ebb0bc90b6b
Merged-In: Ia07633c0da71f167098b15958e519ebb0bc90b6b
(cherry picked from commit 85642155eecda9c895283e3050fdb376d92271ae)
diff --git a/apexd/apexd.cpp b/apexd/apexd.cpp
index 0010c42..80e075a 100644
--- a/apexd/apexd.cpp
+++ b/apexd/apexd.cpp
@@ -52,6 +52,7 @@
 #include <dirent.h>
 #include <fcntl.h>
 #include <linux/loop.h>
+#include <log/log.h>
 #include <stdlib.h>
 #include <sys/inotify.h>
 #include <sys/ioctl.h>
@@ -1256,7 +1257,7 @@
     }
   } else if (session.IsRollback()) {
     for (const auto& apex_name : session.GetApexNames()) {
-      if (!gInFsCheckpointMode) {
+      if (!gSupportsFsCheckpoints) {
         // Snapshot before restore so this rollback can be reverted.
         snapshotDataDirectory(base_dir, session.GetRollbackId(), apex_name,
                               true /* pre_restore */);
@@ -1737,6 +1738,11 @@
   }
 
   if (!gInFsCheckpointMode) {
+    // SafetyNet logging for b/19393765
+    android_errorWriteLog(0x534e4554, "193932765");
+  }
+
+  if (!gSupportsFsCheckpoints) {
     auto restoreStatus = RestoreActivePackages();
     if (!restoreStatus.ok()) {
       for (auto& session : activeSessions) {
@@ -1754,7 +1760,7 @@
   }
 
   for (auto& session : activeSessions) {
-    if (!gInFsCheckpointMode && session.IsRollback()) {
+    if (!gSupportsFsCheckpoints && session.IsRollback()) {
       // If snapshots have already been restored, undo that by restoring the
       // pre-restore snapshot.
       restoreDePreRestoreSnapshotsIfPresent(session);
@@ -2070,7 +2076,7 @@
       return Error() << "Failed to mark session " << *session
                      << " as successful : " << cleanup_status.error();
     }
-    if (session->IsRollback() && !gInFsCheckpointMode) {
+    if (session->IsRollback() && !gSupportsFsCheckpoints) {
       deleteDePreRestoreSnapshots(*session);
     }
     return session->UpdateStateAndCommit(SessionState::SUCCESS);
diff --git a/apexd/apexservice_test.cpp b/apexd/apexservice_test.cpp
index 4c054f1..7f78610 100644
--- a/apexd/apexservice_test.cpp
+++ b/apexd/apexservice_test.cpp
@@ -2187,7 +2187,7 @@
     }
   }
 
-  void CheckRevertWasPerformed(const std::vector<std::string>& expected_pkgs) {
+  void CheckActiveApexContents(const std::vector<std::string>& expected_pkgs) {
     // First check that /data/apex/active exists and has correct permissions.
     struct stat sd;
     ASSERT_EQ(0, stat(kActiveApexPackagesDataDir, &sd));
@@ -2225,7 +2225,38 @@
   auto pkg = StringPrintf("%s/com.android.apex.test_package@1.apex",
                           kActiveApexPackagesDataDir);
   SCOPED_TRACE("");
-  CheckRevertWasPerformed({pkg});
+  CheckActiveApexContents({pkg});
+}
+
+// Calling revertActiveSessions should not restore backup on checkpointing
+// devices
+TEST_F(ApexServiceRevertTest,
+       RevertActiveSessionsDoesNotRestoreBackupIfCheckpointingSupported) {
+  if (!supports_fs_checkpointing_) {
+    GTEST_SKIP() << "Can't run if filesystem checkpointing is not supported";
+  }
+
+  PrepareTestApexForInstall installer(GetTestFile("apex.apexd_test_v2.apex"));
+  if (!installer.Prepare()) {
+    return;
+  }
+
+  auto session = ApexSession::CreateSession(1543);
+  ASSERT_TRUE(IsOk(session));
+  ASSERT_TRUE(IsOk(session->UpdateStateAndCommit(SessionState::ACTIVATED)));
+
+  // Make sure /data/apex/active is non-empty.
+  ASSERT_TRUE(IsOk(service_->stagePackages({installer.test_file})));
+
+  PrepareBackup({GetTestFile("apex.apexd_test.apex")});
+
+  ASSERT_TRUE(IsOk(service_->revertActiveSessions()));
+
+  // Check that active apexes were not reverted.
+  auto pkg = StringPrintf("%s/com.android.apex.test_package@2.apex",
+                          kActiveApexPackagesDataDir);
+  SCOPED_TRACE("");
+  CheckActiveApexContents({pkg});
 }
 
 // Should fail to revert active sessions when there are none
@@ -2296,7 +2327,7 @@
   auto pkg2 = StringPrintf("%s/com.android.apex.test_package_2@1.apex",
                            kActiveApexPackagesDataDir);
   SCOPED_TRACE("");
-  CheckRevertWasPerformed({pkg1, pkg2});
+  CheckActiveApexContents({pkg1, pkg2});
 
   std::vector<ApexSessionInfo> sessions;
   ASSERT_TRUE(IsOk(service_->getSessions(&sessions)));