Merge "Use new LOOP_CONFIGURE ioctl for configuring loop devices."
diff --git a/apexd/apex_database.cpp b/apexd/apex_database.cpp
index dd0e40e..13a5472 100644
--- a/apexd/apex_database.cpp
+++ b/apexd/apex_database.cpp
@@ -35,6 +35,7 @@
 #include <utility>
 
 using android::base::ConsumeSuffix;
+using android::base::EndsWith;
 using android::base::ParseInt;
 using android::base::ReadFileToString;
 using android::base::Result;
@@ -190,6 +191,7 @@
 
 Result<MountedApexData> resolveMountInfo(const BlockDevice& block,
                                          const std::string& mountPoint) {
+  bool temp_mount = EndsWith(mountPoint, ".tmp");
   // Now, see if it is dm-verity or loop mounted
   switch (block.GetType()) {
     case LoopDevice: {
@@ -199,7 +201,8 @@
       }
       auto result = MountedApexData(block.DevPath(), *backingFile, mountPoint,
                                     /* device_name= */ "",
-                                    /* hashtree_loop_name= */ "");
+                                    /* hashtree_loop_name= */ "",
+                                    /* is_temp_mount */ temp_mount);
       NormalizeIfDeleted(&result);
       return result;
     }
@@ -211,6 +214,7 @@
       MountedApexData result;
       result.mount_point = mountPoint;
       result.device_name = *name;
+      result.is_temp_mount = temp_mount;
       if (auto status = PopulateLoopInfo(block, &result); !status.ok()) {
         return status.error();
       }
diff --git a/apexd/apex_database.h b/apexd/apex_database.h
index af757f3..291defc 100644
--- a/apexd/apex_database.h
+++ b/apexd/apex_database.h
@@ -22,6 +22,10 @@
 #include <unordered_set>
 
 #include <android-base/logging.h>
+#include <android-base/result.h>
+
+using android::base::Error;
+using android::base::Result;
 
 namespace android {
 namespace apex {
@@ -40,17 +44,21 @@
     std::string hashtree_loop_name;
     // Whenever apex file specified in full_path was deleted.
     bool deleted;
+    // Whether the mount is a temp mount or not.
+    bool is_temp_mount;
 
     MountedApexData() {}
     MountedApexData(const std::string& loop_name, const std::string& full_path,
                     const std::string& mount_point,
                     const std::string& device_name,
-                    const std::string& hashtree_loop_name)
+                    const std::string& hashtree_loop_name,
+                    bool is_temp_mount = false)
         : loop_name(loop_name),
           full_path(full_path),
           mount_point(mount_point),
           device_name(device_name),
-          hashtree_loop_name(hashtree_loop_name) {}
+          hashtree_loop_name(hashtree_loop_name),
+          is_temp_mount(is_temp_mount) {}
 
     inline bool operator<(const MountedApexData& rhs) const {
       int compare_val = loop_name.compare(rhs.loop_name);
@@ -134,7 +142,8 @@
   }
 
   inline void RemoveMountedApex(const std::string& package,
-                                const std::string& full_path) {
+                                const std::string& full_path,
+                                bool match_temp_mounts = false) {
     auto it = mounted_apexes_.find(package);
     if (it == mounted_apexes_.end()) {
       return;
@@ -143,7 +152,8 @@
     auto& pkg_map = it->second;
 
     for (auto pkg_it = pkg_map.begin(); pkg_it != pkg_map.end(); ++pkg_it) {
-      if (pkg_it->first.full_path == full_path) {
+      if (pkg_it->first.full_path == full_path &&
+          pkg_it->first.is_temp_mount == match_temp_mounts) {
         pkg_map.erase(pkg_it);
         return;
       }
@@ -184,22 +194,27 @@
   }
 
   template <typename T>
-  inline void ForallMountedApexes(const std::string& package,
-                                  const T& handler) const {
+  inline void ForallMountedApexes(const std::string& package, const T& handler,
+                                  bool match_temp_mounts = false) const {
     auto it = mounted_apexes_.find(package);
     if (it == mounted_apexes_.end()) {
       return;
     }
     for (auto& pair : it->second) {
-      handler(pair.first, pair.second);
+      if (pair.first.is_temp_mount == match_temp_mounts) {
+        handler(pair.first, pair.second);
+      }
     }
   }
 
   template <typename T>
-  inline void ForallMountedApexes(const T& handler) const {
+  inline void ForallMountedApexes(const T& handler,
+                                  bool match_temp_mounts = false) const {
     for (const auto& pkg : mounted_apexes_) {
       for (const auto& pair : pkg.second) {
-        handler(pkg.first, pair.first, pair.second);
+        if (pair.first.is_temp_mount == match_temp_mounts) {
+          handler(pkg.first, pair.first, pair.second);
+        }
       }
     }
   }
diff --git a/apexd/apexd.cpp b/apexd/apexd.cpp
index 5de713c..a32a99b 100644
--- a/apexd/apexd.cpp
+++ b/apexd/apexd.cpp
@@ -361,7 +361,8 @@
                                          const std::string& mountPoint,
                                          const std::string& device_name,
                                          const std::string& hashtree_file,
-                                         bool verifyImage) {
+                                         bool verifyImage,
+                                         bool tempMount = false) {
   LOG(VERBOSE) << "Creating mount point: " << mountPoint;
   // Note: the mount point could exist in case when the APEX was activated
   // during the bootstrap phase (e.g., the runtime or tzdata APEX).
@@ -413,7 +414,8 @@
   std::string blockDevice = loopbackDevice.name;
   MountedApexData apex_data(loopbackDevice.name, apex.GetPath(), mountPoint,
                             /* device_name = */ "",
-                            /* hashtree_loop_name = */ "");
+                            /* hashtree_loop_name = */ "",
+                            /* is_temp_mount */ tempMount);
 
   // for APEXes in immutable partitions, we don't need to mount them on
   // dm-verity because they are already in the dm-verity protected partition;
@@ -512,13 +514,16 @@
       return ErrnoError() << "Failed to unlink " << hashtree_file;
     }
   }
-  auto ret = MountPackageImpl(apex, mount_point, temp_device_name,
-                              hashtree_file, /* verifyImage = */ true);
+  auto ret =
+      MountPackageImpl(apex, mount_point, temp_device_name, hashtree_file,
+                       /* verifyImage = */ true, /* tempMount = */ true);
   if (!ret.ok()) {
     LOG(DEBUG) << "Cleaning up " << hashtree_file;
     if (TEMP_FAILURE_RETRY(unlink(hashtree_file.c_str())) != 0) {
       PLOG(ERROR) << "Failed to unlink " << hashtree_file;
     }
+  } else {
+    gMountedApexes.AddMountedApex(apex.GetManifest().name(), false, *ret);
   }
   return ret;
 }
@@ -561,7 +566,8 @@
 
 template <typename VerifyFn>
 Result<void> RunVerifyFnInsideTempMount(const ApexFile& apex,
-                                        const VerifyFn& verify_fn) {
+                                        const VerifyFn& verify_fn,
+                                        bool unmount_during_cleanup) {
   // Temp mount image of this apex to validate it was properly signed;
   // this will also read the entire block device through dm-verity, so
   // we can be sure there is no corruption.
@@ -576,11 +582,15 @@
     return mount_status.error();
   }
   auto cleaner = [&]() {
-    LOG(DEBUG) << "Unmounting " << temp_mount_point;
-    Result<void> result = Unmount(*mount_status);
-    if (!result.ok()) {
-      LOG(WARNING) << "Failed to unmount " << temp_mount_point << " : "
-                   << result.error();
+    if (unmount_during_cleanup) {
+      LOG(DEBUG) << "Unmounting " << temp_mount_point;
+      Result<void> result = Unmount(*mount_status);
+      if (!result.ok()) {
+        LOG(WARNING) << "Failed to unmount " << temp_mount_point << " : "
+                     << result.error();
+      }
+      gMountedApexes.RemoveMountedApex(apex.GetManifest().name(),
+                                       apex.GetPath(), true);
     }
   };
   auto scope_guard = android::base::make_scope_guard(cleaner);
@@ -590,6 +600,11 @@
 template <typename HookFn, typename HookCall>
 Result<void> PrePostinstallPackages(const std::vector<ApexFile>& apexes,
                                     HookFn fn, HookCall call) {
+  auto scope_guard = android::base::make_scope_guard([&]() {
+    for (const ApexFile& apex_file : apexes) {
+      apexd_private::UnmountTempMount(apex_file);
+    }
+  });
   if (apexes.empty()) {
     return Errorf("Empty set of inputs");
   }
@@ -624,20 +639,23 @@
                                 &StagePostInstall);
 }
 
-template <typename RetType, typename Fn>
-RetType HandlePackages(const std::vector<std::string>& paths, Fn fn) {
-  // 1) Open all APEXes.
-  std::vector<ApexFile> apex_files;
+// Converts a list of apex file paths into a list of ApexFile objects
+//
+// Returns error when trying to open empty set of inputs.
+Result<std::vector<ApexFile>> OpenApexFiles(
+    const std::vector<std::string>& paths) {
+  if (paths.empty()) {
+    return Errorf("Empty set of inputs");
+  }
+  std::vector<ApexFile> ret;
   for (const std::string& path : paths) {
     Result<ApexFile> apex_file = ApexFile::Open(path);
     if (!apex_file.ok()) {
       return apex_file.error();
     }
-    apex_files.emplace_back(std::move(*apex_file));
+    ret.emplace_back(std::move(*apex_file));
   }
-
-  // 2) Dispatch.
-  return fn(apex_files);
+  return ret;
 }
 
 Result<void> ValidateStagingShimApex(const ApexFile& to) {
@@ -650,7 +668,7 @@
   auto verify_fn = [&](const std::string& system_apex_path) {
     return shim::ValidateUpdate(system_apex_path, to.GetPath());
   };
-  return RunVerifyFnInsideTempMount(*system_shim, verify_fn);
+  return RunVerifyFnInsideTempMount(*system_shim, verify_fn, true);
 }
 
 // A version of apex verification that happens during boot.
@@ -688,27 +706,26 @@
   constexpr const auto kSuccessFn = [](const std::string& /*mount_point*/) {
     return Result<void>{};
   };
-  return RunVerifyFnInsideTempMount(apex_file, kSuccessFn);
+  return RunVerifyFnInsideTempMount(apex_file, kSuccessFn, false);
 }
 
 template <typename VerifyApexFn>
 Result<std::vector<ApexFile>> verifyPackages(
     const std::vector<std::string>& paths, const VerifyApexFn& verify_apex_fn) {
-  if (paths.empty()) {
-    return Errorf("Empty set of inputs");
+  Result<std::vector<ApexFile>> apex_files = OpenApexFiles(paths);
+  if (!apex_files.ok()) {
+    return apex_files.error();
   }
+
   LOG(DEBUG) << "verifyPackages() for " << Join(paths, ',');
 
-  auto verify_fn = [&](std::vector<ApexFile>& apexes) {
-    for (const ApexFile& apex_file : apexes) {
-      Result<void> result = verify_apex_fn(apex_file);
-      if (!result.ok()) {
-        return Result<std::vector<ApexFile>>(result.error());
-      }
+  for (const ApexFile& apex_file : *apex_files) {
+    Result<void> result = verify_apex_fn(apex_file);
+    if (!result.ok()) {
+      return result.error();
     }
-    return Result<std::vector<ApexFile>>(std::move(apexes));
-  };
-  return HandlePackages<Result<std::vector<ApexFile>>>(paths, verify_fn);
+  }
+  return std::move(*apex_files);
 }
 
 Result<ApexFile> verifySessionDir(const int session_id) {
@@ -909,6 +926,43 @@
   return android::apex::VerifyAndTempMountPackage(apex, mount_point);
 }
 
+Result<void> UnmountTempMount(const ApexFile& apex) {
+  const ApexManifest& manifest = apex.GetManifest();
+  LOG(VERBOSE) << "Unmounting all temp mounts for package " << manifest.name();
+
+  bool finished_unmounting = false;
+  // If multiple temp mounts exist, ensure that all are unmounted.
+  while (!finished_unmounting) {
+    Result<MountedApexData> data =
+        apexd_private::getTempMountedApexData(manifest.name());
+    if (!data.ok()) {
+      finished_unmounting = true;
+    } else {
+      gMountedApexes.RemoveMountedApex(manifest.name(), data->full_path, true);
+      Unmount(*data);
+    }
+  }
+  return {};
+}
+
+Result<MountedApexData> getTempMountedApexData(const std::string& package) {
+  bool found = false;
+  Result<MountedApexData> mount_data;
+  gMountedApexes.ForallMountedApexes(
+      package,
+      [&](const MountedApexData& data, [[maybe_unused]] bool latest) {
+        if (!found) {
+          mount_data = data;
+          found = true;
+        }
+      },
+      true);
+  if (found) {
+    return mount_data;
+  }
+  return Error() << "No temp mount data found for " << package;
+}
+
 Result<void> Unmount(const MountedApexData& data) {
   // TODO(b/139041058): consolidate these two methods.
   return android::apex::Unmount(data);
@@ -1656,19 +1710,21 @@
 }
 
 Result<void> preinstallPackages(const std::vector<std::string>& paths) {
-  if (paths.empty()) {
-    return Errorf("Empty set of inputs");
+  Result<std::vector<ApexFile>> apex_files = OpenApexFiles(paths);
+  if (!apex_files.ok()) {
+    return apex_files.error();
   }
   LOG(DEBUG) << "preinstallPackages() for " << Join(paths, ',');
-  return HandlePackages<Result<void>>(paths, PreinstallPackages);
+  return PreinstallPackages(*apex_files);
 }
 
 Result<void> postinstallPackages(const std::vector<std::string>& paths) {
-  if (paths.empty()) {
-    return Errorf("Empty set of inputs");
+  Result<std::vector<ApexFile>> apex_files = OpenApexFiles(paths);
+  if (!apex_files.ok()) {
+    return apex_files.error();
   }
   LOG(DEBUG) << "postinstallPackages() for " << Join(paths, ',');
-  return HandlePackages<Result<void>>(paths, PostinstallPackages);
+  return PostinstallPackages(*apex_files);
 }
 
 namespace {
@@ -2239,6 +2295,7 @@
 void bootCompletedCleanup() {
   UnmountDanglingMounts();
   RemoveOrphanedApexes();
+  ApexSession::DeleteFinalizedSessions();
 }
 
 int unmountAll() {
diff --git a/apexd/apexd.h b/apexd/apexd.h
index 36f72be..2399b73 100644
--- a/apexd/apexd.h
+++ b/apexd/apexd.h
@@ -24,6 +24,7 @@
 #include <android-base/result.h>
 
 #include "apex_constants.h"
+#include "apex_database.h"
 #include "apex_file.h"
 
 namespace android {
@@ -116,6 +117,9 @@
 
 int unmountAll();
 
+android::base::Result<MountedApexDatabase::MountedApexData>
+getTempMountedApexData(const std::string& package);
+
 // Optimistically tries to remount as many APEX packages as possible.
 // For more documentation see corresponding binder call in IApexService.aidl.
 android::base::Result<void> remountPackages();
diff --git a/apexd/apexd_prepostinstall.cpp b/apexd/apexd_prepostinstall.cpp
index 1051ecb..9a58aa6 100644
--- a/apexd/apexd_prepostinstall.cpp
+++ b/apexd/apexd_prepostinstall.cpp
@@ -35,6 +35,7 @@
 
 #include "apex_database.h"
 #include "apex_file.h"
+#include "apex_manifest.h"
 #include "apexd.h"
 #include "apexd_private.h"
 #include "apexd_utils.h"
@@ -82,14 +83,6 @@
   std::vector<MountedApexData> mounted_apexes;
   std::vector<std::string> activation_dirs;
   auto preinstall_guard = android::base::make_scope_guard([&]() {
-    for (const auto& mount : mounted_apexes) {
-      Result<void> st = apexd_private::Unmount(mount);
-      if (!st.ok()) {
-        LOG(ERROR) << "Failed to unmount " << mount.full_path << " from "
-                   << mount.mount_point << " after " << name << ": "
-                   << st.error();
-      }
-    }
     for (const std::string& active_point : activation_dirs) {
       if (0 != rmdir(active_point.c_str())) {
         PLOG(ERROR) << "Could not delete temporary active point "
@@ -99,13 +92,17 @@
   });
 
   for (const ApexFile& apex : apexes) {
-    // 1) Mount the package.
-    std::string mount_point =
-        apexd_private::GetPackageTempMountPoint(apex.GetManifest());
-
-    auto mount_data = apexd_private::TempMountPackage(apex, mount_point);
+    // 1) Retrieve the mount data if the apex is already temp mounted, temp
+    // mount it otherwise.
+    Result<MountedApexData> mount_data =
+        apexd_private::getTempMountedApexData(apex.GetManifest().name());
     if (!mount_data.ok()) {
-      return mount_data.error();
+      std::string mount_point =
+          apexd_private::GetPackageTempMountPoint(apex.GetManifest());
+      mount_data = apexd_private::TempMountPackage(apex, mount_point);
+      if (!mount_data.ok()) {
+        return mount_data.error();
+      }
     }
     mounted_apexes.push_back(std::move(*mount_data));
 
diff --git a/apexd/apexd_private.h b/apexd/apexd_private.h
index 1706e08..25b2789 100644
--- a/apexd/apexd_private.h
+++ b/apexd/apexd_private.h
@@ -21,6 +21,7 @@
 
 #include <android-base/result.h>
 #include "apex_database.h"
+#include "apex_file.h"
 #include "apex_manifest.h"
 
 namespace android {
@@ -38,10 +39,13 @@
 
 android::base::Result<void> BindMount(const std::string& target,
                                       const std::string& source);
+android::base::Result<MountedApexDatabase::MountedApexData>
+getTempMountedApexData(const std::string& package);
 android::base::Result<MountedApexDatabase::MountedApexData> TempMountPackage(
     const ApexFile& apex, const std::string& mount_point);
 android::base::Result<void> Unmount(
     const MountedApexDatabase::MountedApexData& data);
+android::base::Result<void> UnmountTempMount(const ApexFile& apex);
 
 }  // namespace apexd_private
 }  // namespace apex
diff --git a/apexd/apexd_session.cpp b/apexd/apexd_session.cpp
index 3d916c4..8ca5fa8 100644
--- a/apexd/apexd_session.cpp
+++ b/apexd/apexd_session.cpp
@@ -259,5 +259,18 @@
              << "]";
 }
 
+void ApexSession::DeleteFinalizedSessions() {
+  auto sessions = GetSessions();
+  for (const ApexSession& session : sessions) {
+    if (!session.IsFinalized()) {
+      continue;
+    }
+    auto result = session.DeleteSession();
+    if (!result.ok()) {
+      LOG(WARNING) << "Failed to delete finalized session: " << session.GetId();
+    }
+  }
+}
+
 }  // namespace apex
 }  // namespace android
diff --git a/apexd/apexd_session.h b/apexd/apexd_session.h
index e0cea91..ed045a7 100644
--- a/apexd/apexd_session.h
+++ b/apexd/apexd_session.h
@@ -64,6 +64,7 @@
       const ::apex::proto::SessionState::State& state);
 
   android::base::Result<void> DeleteSession() const;
+  static void DeleteFinalizedSessions();
 
  private:
   ApexSession(::apex::proto::SessionState state);
diff --git a/apexd/apexservice_test.cpp b/apexd/apexservice_test.cpp
index 5dc2161..1e09aaf 100644
--- a/apexd/apexservice_test.cpp
+++ b/apexd/apexservice_test.cpp
@@ -1983,6 +1983,42 @@
                                              SessionInfoEq(expected2)));
 }
 
+// Only finalized sessions should be deleted on DeleteFinalizedSessions()
+TEST_F(ApexServiceTest, DeleteFinalizedSessions) {
+  // Fetch list of all session state
+  std::vector<SessionState::State> states;
+  for (int i = SessionState::State_MIN; i < SessionState::State_MAX; i++) {
+    if (!SessionState::State_IsValid(i)) {
+      continue;
+    }
+    states.push_back(SessionState::State(i));
+  }
+
+  // For every session state, create a new session. This is to verify we only
+  // delete sessions in final state.
+  auto nonFinalSessions = 0u;
+  for (auto i = 0u; i < states.size(); i++) {
+    auto session = ApexSession::CreateSession(230 + i);
+    SessionState::State state = states[i];
+    ASSERT_TRUE(IsOk(session->UpdateStateAndCommit(state)));
+    if (!session->IsFinalized()) {
+      nonFinalSessions++;
+    }
+  }
+  std::vector<ApexSession> sessions = ApexSession::GetSessions();
+  ASSERT_EQ(states.size(), sessions.size());
+
+  // Now try cleaning up all finalized sessions
+  ApexSession::DeleteFinalizedSessions();
+  sessions = ApexSession::GetSessions();
+  ASSERT_EQ(nonFinalSessions, sessions.size());
+
+  // Verify only finalized sessions have been deleted
+  for (auto& session : sessions) {
+    ASSERT_FALSE(session.IsFinalized());
+  }
+}
+
 TEST_F(ApexServiceTest, BackupActivePackages) {
   if (supports_fs_checkpointing_) {
     GTEST_SKIP() << "Can't run if filesystem checkpointing is enabled";
diff --git a/tests/Android.bp b/tests/Android.bp
index b5cd3d2..45ea5cd 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -24,17 +24,6 @@
 }
 
 java_test_host {
-    name: "adbd_e2e_tests",
-    srcs:  ["src/**/AdbdHostTest.java"],
-    defaults: ["apex_e2e_test_defaults"],
-    data: [
-        ":test_com.android.adbd",
-    ],
-    test_config: "adbd-e2e-tests.xml",
-    test_suites: ["device-tests"],
-}
-
-java_test_host {
     name: "timezone_data_e2e_tests",
     srcs:  ["src/**/TimezoneDataHostTest.java"],
     defaults: ["apex_e2e_test_defaults"],
@@ -71,39 +60,6 @@
 }
 
 java_test_host {
-    name: "conscrypt_e2e_tests",
-    srcs:  ["src/**/ConscryptHostTest.java"],
-    defaults: ["apex_e2e_test_defaults"],
-    data: [
-        ":test_com.android.conscrypt",
-    ],
-    test_config: "conscrypt-e2e-tests.xml",
-    test_suites: ["device-tests"],
-}
-
-java_test_host {
-    name: "neuralnetworks_e2e_tests",
-    srcs:  ["src/**/NeuralNetworksHostTest.java"],
-    defaults: ["apex_e2e_test_defaults"],
-    data: [
-        ":test_com.android.neuralnetworks",
-    ],
-    test_config: "neuralnetworks-e2e-tests.xml",
-    test_suites: ["device-tests"],
-}
-
-java_test_host {
-    name: "ipsec_e2e_tests",
-    srcs:  ["src/**/IpSecHostTest.java"],
-    defaults: ["apex_e2e_test_defaults"],
-    data: [
-        ":test_com.android.ipsec",
-    ],
-    test_config: "ipsec-e2e-tests.xml",
-    test_suites: ["device-tests"],
-}
-
-java_test_host {
     name: "apex_targetprep_tests",
     libs: ["tradefed"],
     srcs:  ["src/**/ApexTargetPrepTest.java"],
diff --git a/tests/adbd-e2e-tests.xml b/tests/adbd-e2e-tests.xml
deleted file mode 100644
index a144d83..0000000
--- a/tests/adbd-e2e-tests.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<configuration description="Configuration for adbd module e2e tests">
-    <option name="test-suite-tag" value="adbd_e2e_tests" />
-    <option name="test-suite-tag" value="apct" />
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-    <test class="com.android.tradefed.testtype.HostTest" >
-        <option name="jar" value="adbd_e2e_tests.jar" />
-        <option name="set-option" value="apex_file_name:test_com.android.adbd.apex" />
-    </test>
-</configuration>
diff --git a/tests/conscrypt-e2e-tests.xml b/tests/conscrypt-e2e-tests.xml
deleted file mode 100644
index 77f781a..0000000
--- a/tests/conscrypt-e2e-tests.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<configuration description="Config for Conscrypt module e2e test cases">
-    <option name="test-suite-tag" value="conscrypt_e2e_tests" />
-    <option name="test-suite-tag" value="apct" />
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-    <test class="com.android.tradefed.testtype.HostTest" >
-        <option name="jar" value="conscrypt_e2e_tests.jar" />
-        <option name="set-option" value="apex_file_name:test_com.android.conscrypt.apex" />
-    </test>
-</configuration>
-
diff --git a/tests/ipsec-e2e-tests.xml b/tests/ipsec-e2e-tests.xml
deleted file mode 100644
index 0030bd3..0000000
--- a/tests/ipsec-e2e-tests.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<configuration description="Config for ipsec module e2e testing">
-    <option name="test-suite-tag" value="ipsec_e2e_test" />
-    <option name="test-suite-tag" value="apct" />
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
-    <test class="com.android.tradefed.testtype.HostTest" >
-        <option name="jar" value="ipsec_e2e_tests.jar" />
-        <option name="set-option" value="apex_file_name:test_com.android.ipsec.apex" />
-    </test>
-</configuration>
-
diff --git a/tests/neuralnetworks-e2e-tests.xml b/tests/neuralnetworks-e2e-tests.xml
deleted file mode 100644
index 63c38a6..0000000
--- a/tests/neuralnetworks-e2e-tests.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<configuration description="Config for neuralnetworks module e2e test cases">
-    <option name="test-suite-tag" value="neuralnetworks_e2e_tests" />
-    <option name="test-suite-tag" value="apct" />
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-    <test class="com.android.tradefed.testtype.HostTest" >
-        <option name="jar" value="neuralnetworks_e2e_tests.jar" />
-        <option name="set-option" value="apex_file_name:test_com.android.neuralnetworks.apex" />
-    </test>
-</configuration>
-
diff --git a/tests/sdkextensions/Android.bp b/tests/sdkextensions/Android.bp
deleted file mode 100644
index e156d6b..0000000
--- a/tests/sdkextensions/Android.bp
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_test_host {
-    name: "sdkextensions_e2e_tests",
-    srcs:  ["test-src/**/*.java"],
-    libs: ["tradefed"],
-    static_libs: ["apex_e2e_base_test"],
-    data: [
-        ":sdkextensions_e2e_test_app",
-        ":test_com.android.media",
-        ":test_com.android.sdkext",
-    ],
-    test_config: "sdkextensions-e2e-tests.xml",
-    test_suites: ["device-tests"],
-}
-
-android_app {
-    name: "sdkextensions_e2e_test_app",
-    srcs: ["app-src/**/*.java"],
-    libs: ["test_framework-sdkextensions-stubs"],
-    sdk_version: "system_current",
-}
diff --git a/tests/sdkextensions/AndroidManifest.xml b/tests/sdkextensions/AndroidManifest.xml
deleted file mode 100644
index 0e4f8d1..0000000
--- a/tests/sdkextensions/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.tests.apex.sdkextensions"
-        android:versionName="1"
-        android:versionCode="1">
-    <uses-sdk android:minSdkVersion="30" android:targetSdkVersion="30" />
-
-    <application android:label="SDK Extensions verifier">
-        <receiver android:name=".Receiver">
-            <intent-filter>
-                <action android:name="com.android.tests.apex.sdkextensions.MAKE_CALLS_0" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="com.android.tests.apex.sdkextensions.MAKE_CALLS_45" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="com.android.tests.apex.sdkextensions.GET_SDK_VERSION" />
-            </intent-filter>
-        </receiver>
-
-    </application>
-</manifest>
diff --git a/tests/sdkextensions/app-src/com/android/tests/apex/sdkextensions/Receiver.java b/tests/sdkextensions/app-src/com/android/tests/apex/sdkextensions/Receiver.java
deleted file mode 100644
index 0332c1e..0000000
--- a/tests/sdkextensions/app-src/com/android/tests/apex/sdkextensions/Receiver.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tests.apex.sdkextensions;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Build;
-import android.os.ext.SdkExtensions;
-import android.os.ext.test.Test;
-import android.util.Log;
-
-public class Receiver extends BroadcastReceiver {
-
-    private static final String ACTION_GET_SDK_VERSION =
-            "com.android.tests.apex.sdkextensions.GET_SDK_VERSION";
-    private static final String ACTION_MAKE_CALLS_0 =
-            "com.android.tests.apex.sdkextensions.MAKE_CALLS_0";
-    private static final String ACTION_MAKE_CALLS_45 =
-            "com.android.tests.apex.sdkextensions.MAKE_CALLS_45";
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        try {
-            switch (intent.getAction()) {
-                case ACTION_GET_SDK_VERSION:
-                    int sdkVersion = SdkExtensions.getExtensionVersion(Build.VERSION_CODES.R);
-                    setResultData(String.valueOf(sdkVersion));
-                    break;
-                case ACTION_MAKE_CALLS_0:
-                    makeCallsVersion0();
-                    setResultData("true");
-                    break;
-                case ACTION_MAKE_CALLS_45:
-                    makeCallsVersion45();
-                    setResultData("true");
-                    break;
-            }
-        } catch (Throwable e) {
-            Log.e("SdkExtensionsE2E", "Unexpected error/exception", e);
-            setResultData("Unexpected error or exception in test app, see log for details");
-        }
-    }
-
-    private static void makeCallsVersion0() {
-        try {
-            Test test = new Test();
-            throw new IllegalStateException("Instantiated test class, but shouldn't be able to");
-        } catch (NoClassDefFoundError t) {
-            // Expected
-        }
-    }
-
-    private static void makeCallsVersion45() {
-        Test test = new Test();
-        test.publicMethod();
-        test.systemApiMethod();
-        try {
-            test.moduleLibsApiMethod();
-            throw new IllegalStateException("Called module-libs method, but shouldn't be able to");
-        } catch (NoSuchMethodError t) {
-            // Expected
-        }
-        try {
-            test.testApiMethod();
-            throw new IllegalStateException("Called testapi method, but shouldn't be able to");
-        } catch (NoSuchMethodError t) {
-            // Expected
-        }
-        try {
-            test.hiddenMethod();
-            throw new IllegalStateException("Called hidden method, but shouldn't be able to");
-        } catch (NoSuchMethodError t) {
-            // Expected
-        }
-    }
-}
diff --git a/tests/sdkextensions/sdkextensions-e2e-tests.xml b/tests/sdkextensions/sdkextensions-e2e-tests.xml
deleted file mode 100644
index 7787773..0000000
--- a/tests/sdkextensions/sdkextensions-e2e-tests.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<configuration description="Config for sdkextensions module e2e test cases">
-    <option name="test-suite-tag" value="sdkextensions_e2e_tests" />
-    <option name="test-suite-tag" value="apct" />
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-    <test class="com.android.tradefed.testtype.HostTest" >
-        <option name="jar" value="sdkextensions_e2e_tests.jar" />
-        <option name="set-option" value="apex_file_name:test_com.android.sdkext.apex" />
-    </test>
-</configuration>
diff --git a/tests/sdkextensions/test-src/com/android/tests/apex/sdkextensions/SdkExtensionsHostTest.java b/tests/sdkextensions/test-src/com/android/tests/apex/sdkextensions/SdkExtensionsHostTest.java
deleted file mode 100644
index 3ee8913..0000000
--- a/tests/sdkextensions/test-src/com/android/tests/apex/sdkextensions/SdkExtensionsHostTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tests.apex.sdkextensions;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import com.android.tests.apex.ApexE2EBaseHostTest;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.util.CommandResult;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class SdkExtensionsHostTest extends ApexE2EBaseHostTest {
-
-    private static final String APP_FILENAME = "sdkextensions_e2e_test_app.apk";
-    private static final String APP_PACKAGE = "com.android.tests.apex.sdkextensions";
-    private static final String MEDIA_FILENAME = "test_com.android.media.apex";
-    private static final String SDKEXTENSIONS_FILENAME = "test_com.android.sdkext.apex";
-
-    @Before
-    public void installTestApp() throws Exception {
-        File testAppFile = mUtils.getTestFile(APP_FILENAME);
-        String installResult = getDevice().installPackage(testAppFile, true);
-        assertNull(installResult);
-    }
-
-    @After
-    public void uninstallTestApp() throws Exception {
-        String uninstallResult = getDevice().uninstallPackage(APP_PACKAGE);
-        assertNull(uninstallResult);
-    }
-
-    @Override
-    protected List<String> getAllApexFilenames() {
-        return List.of(SDKEXTENSIONS_FILENAME, MEDIA_FILENAME);
-    }
-
-    @Test
-    public void testDefault() throws Exception {
-        assertVersion0();
-    }
-
-    @Test
-    public void upgradeOneApex() throws Exception {
-        // On the system image, sdkextensions is the only apex with sdkinfo, and it's version 0.
-        // This test verifies that installing media with sdk version 45 doesn't bump the version.
-        assertVersion0();
-        installApex(MEDIA_FILENAME);
-        reboot(false);
-        assertVersion0();
-    }
-
-    @Test
-    public void upgradeTwoApexes() throws Exception {
-        // On the system image, sdkextensions is the only apex with sdkinfo, and it's version 0.
-        // This test verifies that installing media with sdk version 45 *and* a new sdkext does bump
-        // the version.
-        assertVersion0();
-        installApexes(MEDIA_FILENAME, SDKEXTENSIONS_FILENAME);
-        reboot(false);
-        assertVersion45();
-    }
-
-    @Override
-    public void additionalCheck() throws Exception {
-        // This method is run after the default test in the base class, which just installs sdkext.
-        assertVersion45();
-    }
-
-    private int getExtensionVersionR() throws Exception {
-        int appValue = Integer.parseInt(broadcast("GET_SDK_VERSION"));
-        int syspropValue = getExtensionVersionRFromSysprop();
-        assertEquals(appValue, syspropValue);
-        return appValue;
-    }
-
-    private int getExtensionVersionRFromSysprop() throws Exception {
-        CommandResult res = getDevice().executeShellV2Command("getprop build.version.extensions.r");
-        assertEquals(0, (int) res.getExitCode());
-        String syspropString = res.getStdout().replace("\n", "");
-        return Integer.parseInt(syspropString);
-    }
-
-    private String broadcast(String action) throws Exception {
-        String command = getBroadcastCommand(action);
-        CommandResult res = getDevice().executeShellV2Command(command);
-        assertEquals(0, (int) res.getExitCode());
-        Matcher matcher = Pattern.compile("data=\"([^\"]+)\"").matcher(res.getStdout());
-        assertTrue("Unexpected output from am broadcast: " + res.getStdout(), matcher.find());
-        return matcher.group(1);
-    }
-
-    private void assertVersion0() throws Exception {
-        assertEquals(0, getExtensionVersionR());
-        assertEquals("true", broadcast("MAKE_CALLS_0"));
-    }
-
-    private void assertVersion45() throws Exception {
-        assertEquals(45, getExtensionVersionR());
-        assertEquals("true", broadcast("MAKE_CALLS_45"));
-    }
-
-    private static String getBroadcastCommand(String action) {
-        String cmd = "am broadcast";
-        cmd += " -a com.android.tests.apex.sdkextensions." + action;
-        cmd += " -n com.android.tests.apex.sdkextensions/.Receiver";
-        return cmd;
-    }
-}
diff --git a/tests/src/com/android/tests/apex/AdbdHostTest.java b/tests/src/com/android/tests/apex/AdbdHostTest.java
deleted file mode 100644
index 445ca88..0000000
--- a/tests/src/com/android/tests/apex/AdbdHostTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tests.apex;
-
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
-import org.junit.Ignore;
-import org.junit.runner.RunWith;
-
-/**
- * Test to check if Apex can be staged, activated and uninstalled successfully.
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-@Ignore // TODO(b/148759193): remove when test is fixed
-public class AdbdHostTest extends ApexE2EBaseHostTest {
-}
diff --git a/tests/src/com/android/tests/apex/ConscryptHostTest.java b/tests/src/com/android/tests/apex/ConscryptHostTest.java
deleted file mode 100644
index 01cb840..0000000
--- a/tests/src/com/android/tests/apex/ConscryptHostTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tests.apex;
-
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
-import org.junit.runner.RunWith;
-
-/**
- * Test to check if Apex can be staged, activated and uninstalled successfully.
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class ConscryptHostTest extends ApexE2EBaseHostTest {
-}
diff --git a/tests/src/com/android/tests/apex/IpSecHostTest.java b/tests/src/com/android/tests/apex/IpSecHostTest.java
deleted file mode 100644
index 765f435..0000000
--- a/tests/src/com/android/tests/apex/IpSecHostTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tests.apex;
-
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
-import org.junit.runner.RunWith;
-
-/** Test to check if Apex can be staged, activated and uninstalled successfully. */
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class IpSecHostTest extends ApexE2EBaseHostTest {
-}
diff --git a/tests/src/com/android/tests/apex/NeuralNetworksHostTest.java b/tests/src/com/android/tests/apex/NeuralNetworksHostTest.java
deleted file mode 100644
index 1effbe2..0000000
--- a/tests/src/com/android/tests/apex/NeuralNetworksHostTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tests.apex;
-
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
-import org.junit.runner.RunWith;
-
-/**
- * Test to check if Apex can be staged, activated and uninstalled successfully.
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class NeuralNetworksHostTest extends ApexE2EBaseHostTest {
-}