summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2019-05-05 13:57:25 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-05-05 13:57:25 +0000
commite2e44ba3e7ee7458a1c82ca52baa1b1c1c2ac152 (patch)
tree6cfa10165509ab1abb9f2df45aeec3aa792a2f7c
parente9f7e3eaae4d6a7a0ca8bbcc270c05867ef8873e (diff)
parent6b3fd567d6462ce4d405d6e1650e86a96bc5bd58 (diff)
downloadplatform_system_apex-e2e44ba3e7ee7458a1c82ca52baa1b1c1c2ac152.tar.gz
platform_system_apex-e2e44ba3e7ee7458a1c82ca52baa1b1c1c2ac152.tar.bz2
platform_system_apex-e2e44ba3e7ee7458a1c82ca52baa1b1c1c2ac152.zip
Snap for 5533315 from 6b3fd567d6462ce4d405d6e1650e86a96bc5bd58 to qt-aml-release
Change-Id: I61c47fd5d308db2ff28e9b8365576cf6006f3192
-rw-r--r--apexd/Android.bp3
-rw-r--r--apexd/aidl/android/apex/ApexInfo.aidl1
-rw-r--r--apexd/apex_database.cpp2
-rw-r--r--apexd/apexd.cpp66
-rw-r--r--apexd/apexd.h1
-rw-r--r--apexd/apexd_checkpoint.h1
-rw-r--r--apexd/apexd_checkpoint_vold.cpp11
-rw-r--r--apexd/apexd_checkpoint_vold.h3
-rw-r--r--apexd/apexd_loop.cpp23
-rw-r--r--apexd/apexd_loop.h2
-rw-r--r--apexd/apexd_utils.h48
-rw-r--r--apexd/apexservice.cpp3
-rw-r--r--apexer/apexer.py2
-rw-r--r--proto/apex_manifest.proto3
-rw-r--r--tests/Android.bp18
-rw-r--r--tests/TEST_MAPPING8
-rw-r--r--tests/apex-e2e-tests.xml26
-rw-r--r--tests/src/com/android/tests/apex/ApexPackageStageActivateUninstallHostTest.java54
-rw-r--r--tests/src/com/android/tests/apex/MediaSwCodecHostTest.java3
19 files changed, 63 insertions, 215 deletions
diff --git a/apexd/Android.bp b/apexd/Android.bp
index b22a1eae..6c6f75da 100644
--- a/apexd/Android.bp
+++ b/apexd/Android.bp
@@ -112,9 +112,6 @@ cc_binary {
ldflags: ["-Wl,--rpath,/system/${LIB}/bootstrap"],
},
},
- required: [
- "com.android.apex.cts.shim.v1_prebuilt",
- ],
}
cc_library_static {
diff --git a/apexd/aidl/android/apex/ApexInfo.aidl b/apexd/aidl/android/apex/ApexInfo.aidl
index 774a6ee6..42fa6a06 100644
--- a/apexd/aidl/android/apex/ApexInfo.aidl
+++ b/apexd/aidl/android/apex/ApexInfo.aidl
@@ -20,6 +20,7 @@ parcelable ApexInfo {
@utf8InCpp String packageName;
@utf8InCpp String packagePath;
long versionCode;
+ @utf8InCpp String versionName;
boolean isFactory;
boolean isActive;
}
diff --git a/apexd/apex_database.cpp b/apexd/apex_database.cpp
index 4539d5a2..c83c21f5 100644
--- a/apexd/apex_database.cpp
+++ b/apexd/apex_database.cpp
@@ -250,7 +250,7 @@ void MountedApexDatabase::PopulateFromMounts() {
while (std::getline(mounts, line)) {
auto [block, mountPoint] = parseMountInfo(line);
// TODO(jooyung): ignore tmp mount?
- if (fs::path(mountPoint).parent_path() == kApexRoot) {
+ if (fs::path(mountPoint).parent_path() != kApexRoot) {
continue;
}
if (isActiveMountPoint(mountPoint)) {
diff --git a/apexd/apexd.cpp b/apexd/apexd.cpp
index 70d4afc1..abb623dd 100644
--- a/apexd/apexd.cpp
+++ b/apexd/apexd.cpp
@@ -315,11 +315,6 @@ StatusOr<DmVerityDevice> createVerityDevice(const std::string& name,
return StatusOr<DmVerityDevice>(std::move(dev));
}
-template <char kTypeVal>
-bool DTypeFilter(unsigned char d_type, const char* d_name ATTRIBUTE_UNUSED) {
- return d_type == kTypeVal;
-}
-
Status RemovePreviouslyActiveApexFiles(
const std::unordered_set<std::string>& affected_packages,
const std::unordered_set<std::string>& files_to_keep) {
@@ -1301,50 +1296,6 @@ Status abortActiveSession() {
}
}
-void unmountAndDetachExistingImages() {
- // TODO: this procedure should probably not be needed anymore when apexd
- // becomes an actual daemon. Remove if that's the case.
- LOG(INFO) << "Scanning " << kApexRoot
- << " looking for packages already mounted.";
- // Find directories having apex manifest in it. This is to exclude
- // the empty directories (mount points) that were created by the bootstrap
- // apexd on the /apex tmpfs.
- StatusOr<std::vector<std::string>> folders_status =
- ReadDir(kApexRoot, [](const std::filesystem::directory_entry& entry) {
- std::error_code ec;
- return entry.is_directory(ec) &&
- ApexFile::Open(std::string(kApexRoot) + "/" +
- entry.path().filename().string())
- .Ok();
- });
- if (!folders_status.Ok()) {
- LOG(ERROR) << folders_status.ErrorMessage();
- return;
- }
-
- // Sort the folders. This way, the "latest" folder will appear before any
- // versioned folder, so we'll unmount the bind-mount first.
- std::vector<std::string>& folders = *folders_status;
- std::sort(folders.begin(), folders.end());
-
- for (const std::string& full_path : folders) {
- LOG(INFO) << "Unmounting " << full_path;
- // Lazily try to umount whatever is mounted.
- if (umount2(full_path.c_str(), UMOUNT_NOFOLLOW | MNT_DETACH) != 0 &&
- errno != EINVAL && errno != ENOENT) {
- PLOG(ERROR) << "Failed to unmount directory " << full_path;
- }
- // Attempt to delete the folder. If the folder is retained, other
- // data may be incorrect.
- // TODO: Fix this.
- if (rmdir(full_path.c_str()) != 0) {
- PLOG(ERROR) << "Failed to rmdir directory " << full_path;
- }
- }
-
- loop::destroyAllLoopDevices();
-}
-
Status scanPackagesDirAndActivate(const char* apex_package_dir) {
LOG(INFO) << "Scanning " << apex_package_dir << " looking for APEX packages.";
@@ -1793,12 +1744,27 @@ void onAllPackagesReady() {
StatusOr<std::vector<ApexFile>> submitStagedSession(
const int session_id, const std::vector<int>& child_session_ids) {
+ bool needsBackup = true;
Status cleanup_status = ClearSessions();
if (!cleanup_status.Ok()) {
return StatusOr<std::vector<ApexFile>>::MakeError(cleanup_status);
}
- if (!gSupportsFsCheckpoints) {
+ if (gSupportsFsCheckpoints) {
+ Status checkpoint_status =
+ gVoldService->StartCheckpoint(1 /* numRetries */);
+ if (!checkpoint_status.Ok()) {
+ // The device supports checkpointing, but we could not start it;
+ // log a warning, but do continue, since we can live without it.
+ LOG(WARNING) << "Failed to start filesystem checkpoint on device that "
+ "should support it: "
+ << checkpoint_status.ErrorMessage();
+ } else {
+ needsBackup = false;
+ }
+ }
+
+ if (needsBackup) {
Status backup_status = BackupActivePackages();
if (!backup_status.Ok()) {
return StatusOr<std::vector<ApexFile>>::MakeError(backup_status);
diff --git a/apexd/apexd.h b/apexd/apexd.h
index a3f34d93..0d8f284c 100644
--- a/apexd/apexd.h
+++ b/apexd/apexd.h
@@ -33,7 +33,6 @@ namespace apex {
class CheckpointInterface;
Status resumeRollbackIfNeeded();
-void unmountAndDetachExistingImages();
Status scanPackagesDirAndActivate(const char* apex_package_dir);
void scanStagedSessionsDirAndStage();
diff --git a/apexd/apexd_checkpoint.h b/apexd/apexd_checkpoint.h
index 7ef3c44f..19b4918e 100644
--- a/apexd/apexd_checkpoint.h
+++ b/apexd/apexd_checkpoint.h
@@ -32,6 +32,7 @@ class CheckpointInterface {
virtual StatusOr<bool> NeedsCheckpoint() = 0;
virtual StatusOr<bool> NeedsRollback() = 0;
+ virtual Status StartCheckpoint(int32_t numRetries) = 0;
virtual Status AbortChanges(const std::string& msg, bool retry) = 0;
};
diff --git a/apexd/apexd_checkpoint_vold.cpp b/apexd/apexd_checkpoint_vold.cpp
index c1fb3625..b9c38719 100644
--- a/apexd/apexd_checkpoint_vold.cpp
+++ b/apexd/apexd_checkpoint_vold.cpp
@@ -90,6 +90,17 @@ StatusOr<bool> VoldCheckpointInterface::NeedsRollback() {
return StatusOr<bool>(false);
}
+Status VoldCheckpointInterface::StartCheckpoint(int32_t numRetries) {
+ if (supports_fs_checkpoints_) {
+ android::binder::Status status = vold_service_->startCheckpoint(numRetries);
+ if (!status.isOk()) {
+ return Status::Fail(status.toString8().c_str());
+ }
+ return Status::Success();
+ }
+ return Status::Fail("Device does not support filesystem checkpointing");
+}
+
Status VoldCheckpointInterface::AbortChanges(const std::string& msg,
bool retry) {
vold_service_->abortChanges(msg, retry);
diff --git a/apexd/apexd_checkpoint_vold.h b/apexd/apexd_checkpoint_vold.h
index 356f2836..117911ba 100644
--- a/apexd/apexd_checkpoint_vold.h
+++ b/apexd/apexd_checkpoint_vold.h
@@ -40,8 +40,9 @@ class VoldCheckpointInterface : public CheckpointInterface {
StatusOr<bool> NeedsCheckpoint() override;
StatusOr<bool> NeedsRollback() override;
+ Status StartCheckpoint(int32_t retry) override;
- Status AbortChanges(const std::string& msg, bool retry) override;
+ Status AbortChanges(const std::string& msg, bool numRetries) override;
static StatusOr<VoldCheckpointInterface> Create();
diff --git a/apexd/apexd_loop.cpp b/apexd/apexd_loop.cpp
index 7a6e3c70..972e329b 100644
--- a/apexd/apexd_loop.cpp
+++ b/apexd/apexd_loop.cpp
@@ -246,29 +246,6 @@ void DestroyLoopDevice(const std::string& path, const DestroyLoopFn& extra) {
}
}
-void destroyAllLoopDevices() {
- std::string root = "/dev/block/";
- StatusOr<std::vector<std::string>> loop_files =
- ReadDir(root, [](const std::filesystem::directory_entry& entry) {
- return StartsWith(entry.path().filename().string(), "loop");
- });
-
- if (!loop_files.Ok()) {
- PLOG(ERROR) << "Failed to open /dev/block/, can't destroy loop devices.";
- return;
- }
-
- // Poke through all devices looking for loop devices.
- auto log_fn = [](const std::string& path, const std::string& id) {
- LOG(DEBUG) << "Tearing down stale loop device at " << path << " named "
- << id;
- };
-
- for (const std::string& full_path : *loop_files) {
- DestroyLoopDevice(full_path, log_fn);
- }
-}
-
} // namespace loop
} // namespace apex
} // namespace android
diff --git a/apexd/apexd_loop.h b/apexd/apexd_loop.h
index 53db772f..10eecc9b 100644
--- a/apexd/apexd_loop.h
+++ b/apexd/apexd_loop.h
@@ -68,8 +68,6 @@ using DestroyLoopFn =
std::function<void(const std::string&, const std::string&)>;
void DestroyLoopDevice(const std::string& path, const DestroyLoopFn& extra);
-void destroyAllLoopDevices();
-
} // namespace loop
} // namespace apex
} // namespace android
diff --git a/apexd/apexd_utils.h b/apexd/apexd_utils.h
index ff17dac4..3ce80541 100644
--- a/apexd/apexd_utils.h
+++ b/apexd/apexd_utils.h
@@ -86,34 +86,29 @@ template <typename FilterFn>
StatusOr<std::vector<std::string>> ReadDir(const std::string& path,
FilterFn fn) {
namespace fs = std::filesystem;
- fs::path file_path = path;
- std::error_code ec;
+ using Status = StatusOr<std::vector<std::string>>;
- if (!fs::is_directory(file_path, ec)) {
- return StatusOr<std::vector<std::string>>::MakeError(
- StringLog() << "Can't open " << path << " for reading : " << ec);
+ std::error_code ec;
+ if (!fs::is_directory(path, ec) || ec) {
+ return Status::Fail(StringLog() << "Can't open " << path
+ << " for reading : " << ec.message());
}
std::vector<std::string> ret;
- auto iter = fs::directory_iterator(file_path, ec);
- if (ec) {
- return StatusOr<std::vector<std::string>>::MakeError(
- StringLog() << "Can't open " << path << " for reading: " << ec);
- }
- while (iter != fs::end(iter)) {
- if (fn(*iter)) {
- ret.push_back(file_path.string() + "/" +
- iter->path().filename().string());
- }
- iter = iter.increment(ec);
- if (ec) {
- return StatusOr<std::vector<std::string>>::MakeError(
- StringLog() << "Failed to iterate " << path << ": " << ec);
+ auto it = fs::directory_iterator(path, ec);
+ auto end = fs::directory_iterator();
+ while (!ec && it != end) {
+ if (fn(*it)) {
+ ret.push_back(it->path());
}
+ it.increment(ec);
}
-
- return StatusOr<std::vector<std::string>>(std::move(ret));
-}
+ if (ec) {
+ return Status::Fail(StringLog() << "Can't open " << path
+ << " for reading : " << ec.message());
+ }
+ return Status(std::move(ret));
+} // namespace apex
inline bool IsEmptyDirectory(const std::string& path) {
auto res = ReadDir(path, [](auto _) { return true; });
@@ -162,17 +157,18 @@ inline Status DeleteDirContent(const std::string& path) {
inline StatusOr<bool> PathExists(const std::string& path) {
namespace fs = std::filesystem;
+ using Status = StatusOr<bool>;
std::error_code ec;
if (!fs::exists(fs::path(path), ec)) {
if (ec) {
- return StatusOr<bool>::MakeError(StringLog() << "Failed to access "
- << path << " : " << ec);
+ return Status::Fail(StringLog() << "Failed to access " << path << " : "
+ << ec.message());
} else {
- return StatusOr<bool>(false);
+ return Status(false);
}
}
- return StatusOr<bool>(true);
+ return Status(true);
}
inline void Reboot() {
diff --git a/apexd/apexservice.cpp b/apexd/apexservice.cpp
index 857f2e69..13d21139 100644
--- a/apexd/apexservice.cpp
+++ b/apexd/apexservice.cpp
@@ -261,6 +261,7 @@ static ApexInfo getApexInfo(const ApexFile& package) {
out.packageName = package.GetManifest().name();
out.packagePath = package.GetPath();
out.versionCode = package.GetManifest().version();
+ out.versionName = package.GetManifest().versionname();
return out;
}
@@ -268,6 +269,7 @@ static std::string toString(const ApexInfo& package) {
std::string msg = StringLog()
<< "Package: " << package.packageName
<< " Version: " << package.versionCode
+ << " VersionName: " << package.versionName
<< " Path: " << package.packagePath
<< " IsActive: " << std::boolalpha << package.isActive
<< " IsFactory: " << std::boolalpha << package.isFactory
@@ -380,6 +382,7 @@ BinderStatus ApexService::getActivePackage(const std::string& packageName,
aidl_return->packageName = apex->GetManifest().name();
aidl_return->packagePath = apex->GetPath();
aidl_return->versionCode = apex->GetManifest().version();
+ aidl_return->versionName = apex->GetManifest().versionname();
aidl_return->isActive = true;
aidl_return->isFactory =
::android::apex::isPathForBuiltinApexes(apex->GetPath());
diff --git a/apexer/apexer.py b/apexer/apexer.py
index 1869a291..35a3f8ef 100644
--- a/apexer/apexer.py
+++ b/apexer/apexer.py
@@ -356,6 +356,8 @@ def CreateApex(args, work_dir):
# This version from apex_manifest.json is used when versionCode isn't
# specified in AndroidManifest.xml
cmd.extend(['--version-code', str(manifest_apex.version)])
+ if manifest_apex.versionName:
+ cmd.extend(['--version-name', manifest_apex.versionName])
if args.target_sdk_version:
cmd.extend(['--target-sdk-version', args.target_sdk_version])
# Default value for minSdkVersion.
diff --git a/proto/apex_manifest.proto b/proto/apex_manifest.proto
index 32c6438c..8158c28a 100644
--- a/proto/apex_manifest.proto
+++ b/proto/apex_manifest.proto
@@ -31,4 +31,7 @@ message ApexManifest {
// Post Install Hook
string postInstallHook = 4;
+
+ // Version Name
+ string versionName = 5;
}
diff --git a/tests/Android.bp b/tests/Android.bp
index b34f056a..6f514728 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -13,24 +13,6 @@
// limitations under the License.
java_test_host {
- name: "apex_e2e_tests",
-
- srcs: ["src/**/ApexPackageStageActivateUninstallHostTest.java"],
-
- libs: ["tradefed"],
-
- static_libs: ["apex_e2e_base_test"],
-
- data: [
- ":apex.test",
- ],
-
- test_config: "apex-e2e-tests.xml",
-
- test_suites: ["general-tests"],
-}
-
-java_test_host {
name: "timezone_data_e2e_tests",
srcs: ["src/**/TimezoneDataHostTest.java"],
diff --git a/tests/TEST_MAPPING b/tests/TEST_MAPPING
index d7fecf71..8e7a3836 100644
--- a/tests/TEST_MAPPING
+++ b/tests/TEST_MAPPING
@@ -1,19 +1,13 @@
{
"presubmit": [
{
- "name": "apex_e2e_tests"
- },
- {
"name": "apex_targetprep_tests"
},
{
"name": "timezone_data_e2e_tests"
},
{
- "name": "media_e2e_tests"
- },
- {
- "name": "media_swcodec_e2e_tests"
+ "name": "CtsStagedInstallHostTestCases"
}
]
}
diff --git a/tests/apex-e2e-tests.xml b/tests/apex-e2e-tests.xml
deleted file mode 100644
index 348ea6ac..00000000
--- a/tests/apex-e2e-tests.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 apex install/uninstall test cases">
- <option name="test-suite-tag" value="apex_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="apex_e2e_tests.jar" />
- <option name="set-option" value="apex_file_name:apex.test.apex" />
- </test>
-</configuration>
-
diff --git a/tests/src/com/android/tests/apex/ApexPackageStageActivateUninstallHostTest.java b/tests/src/com/android/tests/apex/ApexPackageStageActivateUninstallHostTest.java
deleted file mode 100644
index 6489ec4f..00000000
--- a/tests/src/com/android/tests/apex/ApexPackageStageActivateUninstallHostTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2018 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.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.IOException;
-
-/**
- * Test to check if Apex can be staged, activated and uninstalled successfully.
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class ApexPackageStageActivateUninstallHostTest extends ApexE2EBaseHostTest {
-
- /**
- * Tests that if Apex package can be staged, activated and uninstalled successfully.
- */
- @Test
- public void testStageActivateUninstallApexPackage()
- throws DeviceNotAvailableException, IOException {
- doTestStageActivateUninstallApexPackage();
- }
-
- @Test
- public void testStageActivatUninstallTwice() throws Exception {
- doTestStageActivateUninstallApexPackage();
- CLog.i("Installing the same apex second time");
- doTestStageActivateUninstallApexPackage();
- }
-
- @Override
- public void additionalCheck() {
- // Nothing to do here.
- }
-}
diff --git a/tests/src/com/android/tests/apex/MediaSwCodecHostTest.java b/tests/src/com/android/tests/apex/MediaSwCodecHostTest.java
index e43a34f4..040fc28d 100644
--- a/tests/src/com/android/tests/apex/MediaSwCodecHostTest.java
+++ b/tests/src/com/android/tests/apex/MediaSwCodecHostTest.java
@@ -62,11 +62,8 @@ public class MediaSwCodecHostTest extends ApexE2EBaseHostTest {
@Override
public void additionalCheck() {
- /*
- * TODO(b/130138217) re-enable when this works on Cuttlefish
assertTrue(((IManagedTestDevice) getDevice()).getMonitor().waitForBootComplete(60000));
checkCodecs();
- */
}
private void checkCodecs() {