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 {
-}