diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2019-05-05 13:57:25 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2019-05-05 13:57:25 +0000 |
commit | e2e44ba3e7ee7458a1c82ca52baa1b1c1c2ac152 (patch) | |
tree | 6cfa10165509ab1abb9f2df45aeec3aa792a2f7c | |
parent | e9f7e3eaae4d6a7a0ca8bbcc270c05867ef8873e (diff) | |
parent | 6b3fd567d6462ce4d405d6e1650e86a96bc5bd58 (diff) | |
download | platform_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.bp | 3 | ||||
-rw-r--r-- | apexd/aidl/android/apex/ApexInfo.aidl | 1 | ||||
-rw-r--r-- | apexd/apex_database.cpp | 2 | ||||
-rw-r--r-- | apexd/apexd.cpp | 66 | ||||
-rw-r--r-- | apexd/apexd.h | 1 | ||||
-rw-r--r-- | apexd/apexd_checkpoint.h | 1 | ||||
-rw-r--r-- | apexd/apexd_checkpoint_vold.cpp | 11 | ||||
-rw-r--r-- | apexd/apexd_checkpoint_vold.h | 3 | ||||
-rw-r--r-- | apexd/apexd_loop.cpp | 23 | ||||
-rw-r--r-- | apexd/apexd_loop.h | 2 | ||||
-rw-r--r-- | apexd/apexd_utils.h | 48 | ||||
-rw-r--r-- | apexd/apexservice.cpp | 3 | ||||
-rw-r--r-- | apexer/apexer.py | 2 | ||||
-rw-r--r-- | proto/apex_manifest.proto | 3 | ||||
-rw-r--r-- | tests/Android.bp | 18 | ||||
-rw-r--r-- | tests/TEST_MAPPING | 8 | ||||
-rw-r--r-- | tests/apex-e2e-tests.xml | 26 | ||||
-rw-r--r-- | tests/src/com/android/tests/apex/ApexPackageStageActivateUninstallHostTest.java | 54 | ||||
-rw-r--r-- | tests/src/com/android/tests/apex/MediaSwCodecHostTest.java | 3 |
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() { |