diff options
author | 2022-03-09 17:04:38 +0000 | |
---|---|---|
committer | 2022-03-23 16:26:47 +0000 | |
commit | 0430279b743fb5f44a78083b1d0d6316b9f153a8 (patch) | |
tree | 513b8f3f39c8b2fb4078ed1dcac50669c80093db | |
parent | 70f72fa3d5927034d24c2752b450a4adc6996927 (diff) |
Make ReconcileSdkData more flexible
Instead of passing sdk package names and list of random strings to
installd, the client will pass the sub-directory name directly. The
client will be responsible for ensuring they don't create multiple
sub-directories for same sdk with different random suffixes.
Also, since "shared" sub-directory is just another type of sdk data
sub-directory, we no longer create it during sdk package path creation.
This directory should get created using ReconcileSdkData api by the
client.
Also cleaned up the tests and added SdkSandboxStorageHostTest in
TEST_MAPPING.
Bug: 211763739
Test: atest installd_service_test
Ignore-AOSP-First: Some of the cls are missing in AOSP. Will cherry-pick
this with rest of them together next week.
Change-Id: Ie9cdc2c41bcec64028008a79654f2d38c017b6d1
Merged-In: Ie9cdc2c41bcec64028008a79654f2d38c017b6d1
(cherry picked from commit 5288b055c114f0d765c284e50b9e0b3898305c80)
-rw-r--r-- | cmds/installd/InstalldNativeService.cpp | 109 | ||||
-rw-r--r-- | cmds/installd/InstalldNativeService.h | 6 | ||||
-rw-r--r-- | cmds/installd/TEST_MAPPING | 3 | ||||
-rw-r--r-- | cmds/installd/binder/android/os/ReconcileSdkDataArgs.aidl | 3 | ||||
-rw-r--r-- | cmds/installd/tests/installd_service_test.cpp | 248 | ||||
-rw-r--r-- | cmds/installd/tests/installd_utils_test.cpp | 13 | ||||
-rw-r--r-- | cmds/installd/utils.cpp | 27 | ||||
-rw-r--r-- | cmds/installd/utils.h | 4 |
8 files changed, 123 insertions, 290 deletions
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index a92de4efc0..955d812b23 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -752,8 +752,7 @@ binder::Status InstalldNativeService::createAppDataLocked( if (flags & FLAG_STORAGE_SDK) { // Safe to ignore status since we can retry creating this by calling reconcileSdkData - auto ignore = createSdkSandboxDataPackageDirectory(uuid, packageName, userId, appId, - previousAppId, seInfo, flags); + auto ignore = createSdkSandboxDataPackageDirectory(uuid, packageName, userId, appId, flags); if (!ignore.isOk()) { PLOG(WARNING) << "Failed to create sdk data package directory for " << packageName; } @@ -772,7 +771,7 @@ binder::Status InstalldNativeService::createAppDataLocked( */ binder::Status InstalldNativeService::createSdkSandboxDataPackageDirectory( const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, - int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t flags) { + int32_t appId, int32_t flags) { int32_t sdkSandboxUid = multiuser_get_sdk_sandbox_uid(userId, appId); if (sdkSandboxUid == -1) { // There no valid sdk sandbox process for this app. Skip creation of data directory @@ -791,7 +790,7 @@ binder::Status InstalldNativeService::createSdkSandboxDataPackageDirectory( // /data/misc_{ce,de}/<user-id>/sdksandbox directory gets created by vold // during user creation - // Prepare the app directory + // Prepare the package directory auto packagePath = create_data_misc_sdk_sandbox_package_path(uuid_, isCeData, userId, packageName.c_str()); #if SDK_DEBUG @@ -801,27 +800,6 @@ binder::Status InstalldNativeService::createSdkSandboxDataPackageDirectory( if (prepare_app_dir(packagePath, 0751, AID_SYSTEM, AID_SYSTEM, 0)) { return error("Failed to prepare " + packagePath); } - - // Now prepare the shared directory which will be accessible by all codes - auto sharedPath = create_data_misc_sdk_sandbox_shared_path(uuid_, isCeData, userId, - packageName.c_str()); - - int32_t previousSdkSandboxUid = multiuser_get_sdk_sandbox_uid(userId, previousAppId); - int32_t cacheGid = multiuser_get_cache_gid(userId, appId); - if (cacheGid == -1) { - return exception(binder::Status::EX_ILLEGAL_STATE, - StringPrintf("cacheGid cannot be -1 for sdksandbox data")); - } - auto status = createAppDataDirs(sharedPath, sdkSandboxUid, AID_NOBODY, - &previousSdkSandboxUid, cacheGid, seInfo, 0700 | S_ISGID); - if (!status.isOk()) { - return status; - } - - // TODO(b/211763739): We also need to handle art profile creations - - // TODO(b/211763739): And return the CE inode of the sdksandbox root directory and - // app directory under it so we can clear contents while CE storage is locked } return ok(); @@ -874,8 +852,8 @@ binder::Status InstalldNativeService::reconcileSdkData( const android::os::ReconcileSdkDataArgs& args) { // Locking is performed depeer in the callstack. - return reconcileSdkData(args.uuid, args.packageName, args.sdkPackageNames, args.randomSuffixes, - args.userId, args.appId, args.previousAppId, args.seInfo, args.flags); + return reconcileSdkData(args.uuid, args.packageName, args.subDirNames, args.userId, args.appId, + args.previousAppId, args.seInfo, args.flags); } /** @@ -889,17 +867,14 @@ binder::Status InstalldNativeService::reconcileSdkData( * is to avoid having same per-sdk directory with different suffix. * - If a sdk level directory exist which is absent from sdkPackageNames, we remove it. */ -binder::Status InstalldNativeService::reconcileSdkData( - const std::optional<std::string>& uuid, const std::string& packageName, - const std::vector<std::string>& sdkPackageNames, - const std::vector<std::string>& randomSuffixes, int userId, int appId, int previousAppId, - const std::string& seInfo, int flags) { +binder::Status InstalldNativeService::reconcileSdkData(const std::optional<std::string>& uuid, + const std::string& packageName, + const std::vector<std::string>& subDirNames, + int userId, int appId, int previousAppId, + const std::string& seInfo, int flags) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); - for (const auto& sdkPackageName : sdkPackageNames) { - CHECK_ARGUMENT_PACKAGE_NAME(sdkPackageName); - } LOCK_PACKAGE_USER(); #if SDK_DEBUG @@ -908,16 +883,9 @@ binder::Status InstalldNativeService::reconcileSdkData( const char* uuid_ = uuid ? uuid->c_str() : nullptr; - // Validate we have enough randomSuffixStrings - if (randomSuffixes.size() != sdkPackageNames.size()) { - return exception(binder::Status::EX_ILLEGAL_ARGUMENT, - StringPrintf("Not enough random suffix. Required %d, received %d.", - (int)sdkPackageNames.size(), (int)randomSuffixes.size())); - } - // Prepare the sdk package directory in case it's missing - const auto status = createSdkSandboxDataPackageDirectory(uuid, packageName, userId, appId, - previousAppId, seInfo, flags); + const auto status = + createSdkSandboxDataPackageDirectory(uuid, packageName, userId, appId, flags); if (!status.isOk()) { return status; } @@ -931,37 +899,22 @@ binder::Status InstalldNativeService::reconcileSdkData( } const bool isCeData = (currentFlag == FLAG_STORAGE_CE); - // Since random suffix provided will be random every time, we need to ensure we don't end up - // creating multuple directories for same sdk package with different suffixes. This - // is ensured by fetching all the existing sub directories and storing them so that we can - // check for existence later. We also remove unconsumed sdk directories in this check. const auto packagePath = create_data_misc_sdk_sandbox_package_path(uuid_, isCeData, userId, packageName.c_str()); - const std::unordered_set<std::string> expectedSdkNames(sdkPackageNames.begin(), - sdkPackageNames.end()); - // Store paths of per-sdk directory for sdk that already exists - std::unordered_map<std::string, std::string> sdkNamesThatExist; - - const auto subDirHandler = [&packagePath, &expectedSdkNames, &sdkNamesThatExist, - &res](const std::string& filename) { - auto filepath = packagePath + "/" + filename; - auto tokens = Split(filename, "@"); - if (tokens.size() != 2) { - // Not a per-sdk directory with random suffix - return; - } - auto sdkName = tokens[0]; + // Remove existing sub-directories not referred in subDirNames + const std::unordered_set<std::string> expectedSubDirNames(subDirNames.begin(), + subDirNames.end()); + const auto subDirHandler = [&packagePath, &expectedSubDirNames, + &res](const std::string& subDirName) { // Remove the per-sdk directory if it is not referred in - // expectedSdkNames - if (expectedSdkNames.find(sdkName) == expectedSdkNames.end()) { - if (delete_dir_contents_and_dir(filepath) != 0) { - res = error("Failed to delete " + filepath); + // expectedSubDirNames + if (expectedSubDirNames.find(subDirName) == expectedSubDirNames.end()) { + auto path = packagePath + "/" + subDirName; + if (delete_dir_contents_and_dir(path) != 0) { + res = error("Failed to delete " + path); return; } - } else { - // Otherwise, store it as existing sdk level directory - sdkNamesThatExist[sdkName] = filepath; } }; const int ec = foreach_subdir(packagePath, subDirHandler); @@ -970,19 +923,11 @@ binder::Status InstalldNativeService::reconcileSdkData( continue; } - // Create sdksandbox data directory for each sdksandbox package - for (int i = 0, size = sdkPackageNames.size(); i < size; i++) { - const std::string& sdkName = sdkPackageNames[i]; - const std::string& randomSuffix = randomSuffixes[i]; - std::string path; - if (const auto& it = sdkNamesThatExist.find(sdkName); it != sdkNamesThatExist.end()) { - // Already exists. Use existing path instead of creating a new one - path = it->second; - } else { - path = create_data_misc_sdk_sandbox_sdk_path(uuid_, isCeData, userId, - packageName.c_str(), sdkName.c_str(), - randomSuffix.c_str()); - } + // Now create the subDirNames + for (const auto& subDirName : subDirNames) { + const std::string path = + create_data_misc_sdk_sandbox_sdk_path(uuid_, isCeData, userId, + packageName.c_str(), subDirName.c_str()); // Create the directory along with cache and code_cache const int32_t cacheGid = multiuser_get_cache_gid(userId, appId); diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h index f0fd867f7c..95ac51692d 100644 --- a/cmds/installd/InstalldNativeService.h +++ b/cmds/installd/InstalldNativeService.h @@ -211,8 +211,7 @@ private: binder::Status createSdkSandboxDataPackageDirectory(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t appId, - int32_t previousAppId, - const std::string& seInfo, int32_t flags); + int32_t flags); binder::Status clearSdkSandboxDataPackageDirectory(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags); @@ -221,8 +220,7 @@ private: int32_t userId, int32_t flags); binder::Status reconcileSdkData(const std::optional<std::string>& uuid, const std::string& packageName, - const std::vector<std::string>& sdkPackageNames, - const std::vector<std::string>& randomSuffixes, int32_t userId, + const std::vector<std::string>& subDirNames, int32_t userId, int32_t appId, int32_t previousAppId, const std::string& seInfo, int flags); binder::Status restoreconSdkDataLocked(const std::optional<std::string>& uuid, diff --git a/cmds/installd/TEST_MAPPING b/cmds/installd/TEST_MAPPING index 3f0fb6d2ba..8ccab4cc2d 100644 --- a/cmds/installd/TEST_MAPPING +++ b/cmds/installd/TEST_MAPPING @@ -30,6 +30,9 @@ }, { "name": "CtsCompilationTestCases" + }, + { + "name": "SdkSandboxStorageHostTest" } ] } diff --git a/cmds/installd/binder/android/os/ReconcileSdkDataArgs.aidl b/cmds/installd/binder/android/os/ReconcileSdkDataArgs.aidl index 2f794b16cc..583a36d580 100644 --- a/cmds/installd/binder/android/os/ReconcileSdkDataArgs.aidl +++ b/cmds/installd/binder/android/os/ReconcileSdkDataArgs.aidl @@ -20,8 +20,7 @@ package android.os; parcelable ReconcileSdkDataArgs { @nullable @utf8InCpp String uuid; @utf8InCpp String packageName; - @utf8InCpp List<String> sdkPackageNames; - @utf8InCpp List<String> randomSuffixes; + @utf8InCpp List<String> subDirNames; int userId; int appId; int previousAppId; diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp index 65edc802b9..cf88856028 100644 --- a/cmds/installd/tests/installd_service_test.cpp +++ b/cmds/installd/tests/installd_service_test.cpp @@ -45,7 +45,7 @@ #include "utils.h" using android::base::StringPrintf; -namespace fs = std::filesystem; +using std::filesystem::is_empty; namespace android { std::string get_package_name(uid_t uid) { @@ -79,12 +79,15 @@ std::string get_package_name(uid_t uid) { namespace installd { static constexpr const char* kTestUuid = "TEST"; -static constexpr const char* kTestPath = "/data/local/tmp"; +static const std::string kTestPath = "/data/local/tmp"; static constexpr const uid_t kNobodyUid = 9999; static constexpr const uid_t kSystemUid = 1000; static constexpr const int32_t kTestUserId = 0; static constexpr const uid_t kTestAppId = 19999; static constexpr const int FLAG_STORAGE_SDK = InstalldNativeService::FLAG_STORAGE_SDK; +static constexpr const int FLAG_CLEAR_CACHE_ONLY = InstalldNativeService::FLAG_CLEAR_CACHE_ONLY; +static constexpr const int FLAG_CLEAR_CODE_CACHE_ONLY = + InstalldNativeService::FLAG_CLEAR_CODE_CACHE_ONLY; const gid_t kTestAppUid = multiuser_get_uid(kTestUserId, kTestAppId); const gid_t kTestCacheGid = multiuser_get_cache_gid(kTestUserId, kTestAppId); @@ -111,7 +114,7 @@ bool create_cache_path(char path[PKG_PATH_MAX], const char *src, const char *ins } static std::string get_full_path(const std::string& path) { - return StringPrintf("%s/%s", kTestPath, path.c_str()); + return StringPrintf("%s/%s", kTestPath.c_str(), path.c_str()); } static void mkdir(const std::string& path, uid_t owner, gid_t group, mode_t mode) { @@ -169,10 +172,9 @@ static bool find_file(const char* path, Pred&& pred) { } static bool exists_renamed_deleted_dir(const std::string& rootDirectory) { - return find_file((std::string(kTestPath) + rootDirectory).c_str(), - [](const std::string& name, bool is_dir) { - return is_dir && is_renamed_deleted_dir(name); - }); + return find_file((kTestPath + rootDirectory).c_str(), [](const std::string& name, bool is_dir) { + return is_dir && is_renamed_deleted_dir(name); + }); } class ServiceTest : public testing::Test { @@ -1067,16 +1069,12 @@ public: } android::os::ReconcileSdkDataArgs reconcileSdkDataArgs( - std::string packageName, std::vector<std::string> codeNames, - std::vector<std::string> randomSuffixes) { + const std::string& packageName, const std::vector<std::string>& subDirNames) { android::os::ReconcileSdkDataArgs args; args.uuid = kTestUuid; args.packageName = packageName; - for (const auto& codeName : codeNames) { - args.sdkPackageNames.push_back(codeName); - } - for (const auto& randomSuffix : randomSuffixes) { - args.randomSuffixes.push_back(randomSuffix); + for (const auto& subDirName : subDirNames) { + args.subDirNames.push_back(subDirName); } args.userId = kTestUserId; args.appId = kTestAppId; @@ -1126,24 +1124,12 @@ TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkPackageData) { const std::string fooCePath = "misc_ce/0/sdksandbox/com.foo"; CheckFileAccess(fooCePath, kSystemUid, kSystemUid, S_IFDIR | 0751); - CheckFileAccess(fooCePath + "/shared", kTestSdkSandboxUid, kNobodyUid, - S_IFDIR | S_ISGID | 0700); - CheckFileAccess(fooCePath + "/shared/cache", kTestSdkSandboxUid, kTestCacheGid, - S_IFDIR | S_ISGID | 0771); - CheckFileAccess(fooCePath + "/shared/code_cache", kTestSdkSandboxUid, kTestCacheGid, - S_IFDIR | S_ISGID | 0771); const std::string fooDePath = "misc_de/0/sdksandbox/com.foo"; CheckFileAccess(fooDePath, kSystemUid, kSystemUid, S_IFDIR | 0751); - CheckFileAccess(fooDePath + "/shared", kTestSdkSandboxUid, kNobodyUid, - S_IFDIR | S_ISGID | 0700); - CheckFileAccess(fooDePath + "/shared/cache", kTestSdkSandboxUid, kTestCacheGid, - S_IFDIR | S_ISGID | 0771); - CheckFileAccess(fooDePath + "/shared/code_cache", kTestSdkSandboxUid, kTestCacheGid, - S_IFDIR | S_ISGID | 0771); } -TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkAppLevelData_WithoutSdkFlag) { +TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkPackageData_WithoutSdkFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; @@ -1155,7 +1141,7 @@ TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkAppLevelData_WithoutSdkFlag) ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/sdksandbox/com.foo")); } -TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkAppLevelData_WithoutSdkFlagDeletesExisting) { +TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkPackageData_WithoutSdkFlagDeletesExisting) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); // Create the app user data. @@ -1169,7 +1155,7 @@ TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkAppLevelData_WithoutSdkFlagDe ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/sdksandbox/com.foo")); } -TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkAppLevelData_WithoutDeFlag) { +TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkPackageData_WithoutDeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_SDK; @@ -1184,7 +1170,7 @@ TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkAppLevelData_WithoutDeFlag) { ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/sdksandbox/com.foo")); } -TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkAppLevelData_WithoutCeFlag) { +TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkPackageData_WithoutCeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.flags = FLAG_STORAGE_DE | FLAG_STORAGE_SDK; @@ -1201,7 +1187,7 @@ TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkAppLevelData_WithoutCeFlag) { TEST_F(SdkSandboxDataTest, ReconcileSdkData) { android::os::ReconcileSdkDataArgs args = - reconcileSdkDataArgs("com.foo", {"bar", "baz"}, {"random1", "random2"}); + reconcileSdkDataArgs("com.foo", {"bar@random1", "baz@random2"}); // Create the sdk data. ASSERT_BINDER_SUCCESS(service->reconcileSdkData(args)); @@ -1235,59 +1221,15 @@ TEST_F(SdkSandboxDataTest, ReconcileSdkData) { S_IFDIR | S_ISGID | 0771); } -TEST_F(SdkSandboxDataTest, ReconcileSdkData_PackageNameCannotUseRandomSuffixSeparator) { - android::os::ReconcileSdkDataArgs args = - reconcileSdkDataArgs("com.foo", {"bar@illegal"}, {"random1"}); - - // Create the sdksandbox data. - auto status = service->reconcileSdkData(args); - ASSERT_EQ(status.exceptionCode(), binder::Status::EX_ILLEGAL_ARGUMENT); - ASSERT_EQ(status.exceptionMessage(), "Package name bar@illegal is malformed"); -} - -TEST_F(SdkSandboxDataTest, ReconcileSdkData_NotEnoughRandomSuffix) { - android::os::ReconcileSdkDataArgs args = - reconcileSdkDataArgs("com.foo", {"bar", "baz"}, {"random1"}); - - // Create the sdksandbox data. - auto status = service->reconcileSdkData(args); - ASSERT_EQ(status.exceptionCode(), binder::Status::EX_ILLEGAL_ARGUMENT); - ASSERT_EQ(status.exceptionMessage(), "Not enough random suffix. Required 2, received 1."); -} - -TEST_F(SdkSandboxDataTest, ReconcileSdkData_DirectoryNotCreatedIfAlreadyExistsIgnoringSuffix) { - android::os::ReconcileSdkDataArgs args = - reconcileSdkDataArgs("com.foo", {"bar", "baz"}, {"random1", "random2"}); - - // Create the sdksandbox data. - ASSERT_BINDER_SUCCESS(service->reconcileSdkData(args)); - - // Retry with different random suffix - args.randomSuffixes[0] = "r10"; - args.randomSuffixes[1] = "r20"; - - // Create the sdksandbox data again - ASSERT_BINDER_SUCCESS(service->reconcileSdkData(args)); - - // Previous directories from first attempt should exist - CheckFileAccess("misc_ce/0/sdksandbox/com.foo/bar@random1", kTestSdkSandboxUid, kNobodyUid, - S_IFDIR | S_ISGID | 0700); - CheckFileAccess("misc_ce/0/sdksandbox/com.foo/baz@random2", kTestSdkSandboxUid, kNobodyUid, - S_IFDIR | S_ISGID | 0700); - // No new directories should be created on second attempt - ASSERT_FALSE(exists("/data/local/tmp/misc_ce/0/sdksandbox/com.foo/bar@r10")); - ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/sdksandbox/com.foo/bar@r20")); -} - TEST_F(SdkSandboxDataTest, ReconcileSdkData_ExtraCodeDirectoriesAreDeleted) { android::os::ReconcileSdkDataArgs args = - reconcileSdkDataArgs("com.foo", {"bar", "baz"}, {"random1", "random2"}); + reconcileSdkDataArgs("com.foo", {"bar@random1", "baz@random2"}); // Create the sdksandbox data. ASSERT_BINDER_SUCCESS(service->reconcileSdkData(args)); // Retry with different package name - args.sdkPackageNames[0] = "bar.diff"; + args.subDirNames[0] = "bar.diff@random1"; // Create the sdksandbox data again ASSERT_BINDER_SUCCESS(service->reconcileSdkData(args)); @@ -1347,130 +1289,90 @@ public: void createTestSdkData(const std::string& packageName, std::vector<std::string> sdkNames) { const auto& cePackagePath = "/data/local/tmp/misc_ce/0/sdksandbox/" + packageName; const auto& dePackagePath = "/data/local/tmp/misc_de/0/sdksandbox/" + packageName; - ASSERT_TRUE(mkdirs(cePackagePath + "/shared/cache", 0700)); - ASSERT_TRUE(mkdirs(cePackagePath + "shared/code_cache", 0700)); - ASSERT_TRUE(mkdirs(dePackagePath + "/shared/cache", 0700)); - ASSERT_TRUE(mkdirs(dePackagePath + "/shared/code_cache", 0700)); - std::ofstream{cePackagePath + "/shared/cache/cachedTestData.txt"}; - for (auto sdkName : sdkNames) { - ASSERT_TRUE(mkdirs(cePackagePath + "/" + sdkName + "/cache", 0700)); - ASSERT_TRUE(mkdirs(dePackagePath + "/" + sdkName + "/cache", 0700)); - ASSERT_TRUE(mkdirs(cePackagePath + "/" + sdkName + "/code_cache", 0700)); - ASSERT_TRUE(mkdirs(dePackagePath + "/" + sdkName + "/code_cache", 0700)); - std::ofstream{cePackagePath + "/" + sdkName + "/cache/cachedTestData.txt"}; - std::ofstream{cePackagePath + "/" + sdkName + "/code_cache/cachedTestData.txt"}; - std::ofstream{dePackagePath + "/" + sdkName + "/cache/cachedTestData.txt"}; - std::ofstream{dePackagePath + "/" + sdkName + "/code_cache/cachedTestData.txt"}; + ASSERT_TRUE(mkdirs(cePackagePath, 0700)); + ASSERT_TRUE(mkdirs(dePackagePath, 0700)); + const std::vector<std::string> packagePaths = {cePackagePath, dePackagePath}; + for (const auto& packagePath : packagePaths) { + for (auto sdkName : sdkNames) { + ASSERT_TRUE(mkdirs(packagePath + "/" + sdkName + "/cache", 0700)); + ASSERT_TRUE(mkdirs(packagePath + "/" + sdkName + "/code_cache", 0700)); + std::ofstream{packagePath + "/" + sdkName + "/cache/cachedTestData.txt"}; + std::ofstream{packagePath + "/" + sdkName + "/code_cache/cachedTestData.txt"}; + } } } }; TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithCeAndClearCacheFlag) { - android::os::CreateAppDataResult result; - android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); - args.packageName = "com.foo"; - // Create the app user data. - ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); - createTestSdkData("com.foo", {"sdk1", "sdk2"}); + createTestSdkData("com.foo", {"shared", "sdk1", "sdk2"}); // Clear the app user data. - ASSERT_BINDER_SUCCESS( - service->clearAppData(args.uuid, args.packageName, args.userId, - FLAG_STORAGE_CE | (InstalldNativeService::FLAG_CLEAR_CACHE_ONLY), - result.ceDataInode)); - ASSERT_TRUE( - fs::is_empty(fs::path("/data/local/tmp/misc_ce/0/sdksandbox/com.foo/shared/cache"))); - ASSERT_TRUE(fs::is_empty(fs::path("/data/local/tmp/misc_ce/0/sdksandbox/com.foo/sdk1/cache"))); - ASSERT_TRUE(fs::is_empty(fs::path("/data/local/tmp/misc_ce/0/sdksandbox/com.foo/sdk2/cache"))); + ASSERT_BINDER_SUCCESS(service->clearAppData(kTestUuid, "com.foo", 0, + FLAG_STORAGE_CE | FLAG_CLEAR_CACHE_ONLY, -1)); + + const std::string packagePath = kTestPath + "/misc_ce/0/sdksandbox/com.foo"; + ASSERT_TRUE(is_empty(packagePath + "/shared/cache")); + ASSERT_TRUE(is_empty(packagePath + "/sdk1/cache")); + ASSERT_TRUE(is_empty(packagePath + "/sdk2/cache")); } TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithCeAndClearCodeCacheFlag) { - android::os::CreateAppDataResult result; - android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); - args.packageName = "com.foo"; - // Create the app user data. - ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); - createTestSdkData("com.foo", {"sdk1", "sdk2"}); + createTestSdkData("com.foo", {"shared", "sdk1", "sdk2"}); // Clear the app user data. - ASSERT_BINDER_SUCCESS( - service->clearAppData(args.uuid, args.packageName, args.userId, - FLAG_STORAGE_CE | - (InstalldNativeService::FLAG_CLEAR_CODE_CACHE_ONLY), - result.ceDataInode)); - ASSERT_TRUE(fs::is_empty( - fs::path("/data/local/tmp/misc_ce/0/sdksandbox/com.foo/shared/code_cache"))); - ASSERT_TRUE( - fs::is_empty(fs::path("/data/local/tmp/misc_ce/0/sdksandbox/com.foo/sdk1/code_cache"))); - ASSERT_TRUE( - fs::is_empty(fs::path("/data/local/tmp/misc_ce/0/sdksandbox/com.foo/sdk2/code_cache"))); + ASSERT_BINDER_SUCCESS(service->clearAppData(kTestUuid, "com.foo", 0, + FLAG_STORAGE_CE | FLAG_CLEAR_CODE_CACHE_ONLY, -1)); + + const std::string packagePath = kTestPath + "/misc_ce/0/sdksandbox/com.foo"; + ASSERT_TRUE(is_empty(packagePath + "/shared/code_cache")); + ASSERT_TRUE(is_empty(packagePath + "/sdk1/code_cache")); + ASSERT_TRUE(is_empty(packagePath + "/sdk2/code_cache")); } TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndClearCacheFlag) { - android::os::CreateAppDataResult result; - android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); - args.packageName = "com.foo"; - // Create the app user data. - ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); - createTestSdkData("com.foo", {"sdk1", "sdk2"}); + createTestSdkData("com.foo", {"shared", "sdk1", "sdk2"}); // Clear the app user data ASSERT_BINDER_SUCCESS( - service->clearAppData(args.uuid, args.packageName, args.userId, + service->clearAppData(kTestUuid, "com.foo", 0, FLAG_STORAGE_DE | (InstalldNativeService::FLAG_CLEAR_CACHE_ONLY), - result.ceDataInode)); - ASSERT_TRUE( - fs::is_empty(fs::path("/data/local/tmp/misc_de/0/sdksandbox/com.foo/shared/cache"))); - ASSERT_TRUE(fs::is_empty(fs::path("/data/local/tmp/misc_de/0/sdksandbox/com.foo/sdk1/cache"))); - ASSERT_TRUE(fs::is_empty(fs::path("/data/local/tmp/misc_de/0/sdksandbox/com.foo/sdk2/cache"))); + -1)); + + const std::string packagePath = kTestPath + "/misc_de/0/sdksandbox/com.foo"; + ASSERT_TRUE(is_empty(packagePath + "/shared/cache")); + ASSERT_TRUE(is_empty(packagePath + "/sdk1/cache")); + ASSERT_TRUE(is_empty(packagePath + "/sdk2/cache")); } TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndClearCodeCacheFlag) { - android::os::CreateAppDataResult result; - android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); - args.packageName = "com.foo"; - // Create the app user data. - ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); - createTestSdkData("com.foo", {"sdk1", "sdk2"}); + createTestSdkData("com.foo", {"shared", "sdk1", "sdk2"}); // Clear the app user data. - ASSERT_BINDER_SUCCESS( - service->clearAppData(args.uuid, args.packageName, args.userId, - FLAG_STORAGE_DE | - (InstalldNativeService::FLAG_CLEAR_CODE_CACHE_ONLY), - result.ceDataInode)); - ASSERT_TRUE(fs::is_empty( - fs::path("/data/local/tmp/misc_de/0/sdksandbox/com.foo/shared/code_cache"))); - ASSERT_TRUE( - fs::is_empty(fs::path("/data/local/tmp/misc_de/0/sdksandbox/com.foo/sdk1/code_cache"))); - ASSERT_TRUE( - fs::is_empty(fs::path("/data/local/tmp/misc_de/0/sdksandbox/com.foo/sdk2/code_cache"))); + ASSERT_BINDER_SUCCESS(service->clearAppData(kTestUuid, "com.foo", 0, + FLAG_STORAGE_DE | FLAG_CLEAR_CODE_CACHE_ONLY, -1)); + + const std::string packagePath = kTestPath + "/misc_de/0/sdksandbox/com.foo"; + ASSERT_TRUE(is_empty(packagePath + "/shared/code_cache")); + ASSERT_TRUE(is_empty(packagePath + "/sdk1/code_cache")); + ASSERT_TRUE(is_empty(packagePath + "/sdk2/code_cache")); } TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithCeAndWithoutAnyCacheFlag) { - android::os::CreateAppDataResult result; - android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); - args.packageName = "com.foo"; - // Create the app user data. - ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); - createTestSdkData("com.foo", {"sdk1", "sdk2"}); + createTestSdkData("com.foo", {"shared", "sdk1", "sdk2"}); // Clear the app user data. - ASSERT_BINDER_SUCCESS(service->clearAppData(args.uuid, args.packageName, args.userId, - FLAG_STORAGE_CE, result.ceDataInode)); - ASSERT_TRUE(fs::is_empty(fs::path("/data/local/tmp/misc_ce/0/sdksandbox/com.foo/shared"))); - ASSERT_TRUE(fs::is_empty(fs::path("/data/local/tmp/misc_ce/0/sdksandbox/com.foo/sdk1"))); - ASSERT_TRUE(fs::is_empty(fs::path("/data/local/tmp/misc_ce/0/sdksandbox/com.foo/sdk2"))); + ASSERT_BINDER_SUCCESS(service->clearAppData(kTestUuid, "com.foo", 0, FLAG_STORAGE_CE, -1)); + + const std::string packagePath = kTestPath + "/misc_ce/0/sdksandbox/com.foo"; + ASSERT_TRUE(is_empty(packagePath + "/shared")); + ASSERT_TRUE(is_empty(packagePath + "/sdk1")); + ASSERT_TRUE(is_empty(packagePath + "/sdk2")); } TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndWithoutAnyCacheFlag) { - android::os::CreateAppDataResult result; - android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); - args.packageName = "com.foo"; - // Create the app user data. - ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); - createTestSdkData("com.foo", {"sdk1", "sdk2"}); + createTestSdkData("com.foo", {"shared", "sdk1", "sdk2"}); // Clear the app user data. - ASSERT_BINDER_SUCCESS(service->clearAppData(args.uuid, args.packageName, args.userId, - FLAG_STORAGE_DE, result.ceDataInode)); - ASSERT_TRUE(fs::is_empty(fs::path("/data/local/tmp/misc_de/0/sdksandbox/com.foo/shared"))); - ASSERT_TRUE(fs::is_empty(fs::path("/data/local/tmp/misc_de/0/sdksandbox/com.foo/sdk1"))); - ASSERT_TRUE(fs::is_empty(fs::path("/data/local/tmp/misc_de/0/sdksandbox/com.foo/sdk2"))); + ASSERT_BINDER_SUCCESS(service->clearAppData(kTestUuid, "com.foo", 0, FLAG_STORAGE_DE, -1)); + + const std::string packagePath = kTestPath + "/misc_de/0/sdksandbox/com.foo"; + ASSERT_TRUE(is_empty(packagePath + "/shared")); + ASSERT_TRUE(is_empty(packagePath + "/sdk1")); + ASSERT_TRUE(is_empty(packagePath + "/sdk2")); } class DestroyUserDataTest : public SdkSandboxDataTest {}; diff --git a/cmds/installd/tests/installd_utils_test.cpp b/cmds/installd/tests/installd_utils_test.cpp index 38c1c05c53..910cd630f3 100644 --- a/cmds/installd/tests/installd_utils_test.cpp +++ b/cmds/installd/tests/installd_utils_test.cpp @@ -690,11 +690,11 @@ TEST_F(UtilsTest, TestSdkSandboxDataPaths) { create_data_misc_sdk_sandbox_package_path(nullptr, true, 10, "com.foo")); EXPECT_EQ("/data/misc_ce/0/sdksandbox/com.foo/shared", - create_data_misc_sdk_sandbox_shared_path(nullptr, true, 0, "com.foo")); + create_data_misc_sdk_sandbox_sdk_path(nullptr, true, 0, "com.foo", "shared")); EXPECT_EQ("/data/misc_ce/10/sdksandbox/com.foo/shared", - create_data_misc_sdk_sandbox_shared_path(nullptr, true, 10, "com.foo")); + create_data_misc_sdk_sandbox_sdk_path(nullptr, true, 10, "com.foo", "shared")); EXPECT_EQ("/data/misc_ce/10/sdksandbox/com.foo/bar@random", - create_data_misc_sdk_sandbox_sdk_path(nullptr, true, 10, "com.foo", "bar", "random")); + create_data_misc_sdk_sandbox_sdk_path(nullptr, true, 10, "com.foo", "bar@random")); // De data paths EXPECT_EQ("/data/misc_de/0/sdksandbox", @@ -707,12 +707,11 @@ TEST_F(UtilsTest, TestSdkSandboxDataPaths) { create_data_misc_sdk_sandbox_package_path(nullptr, false, 10, "com.foo")); EXPECT_EQ("/data/misc_de/0/sdksandbox/com.foo/shared", - create_data_misc_sdk_sandbox_shared_path(nullptr, false, 0, "com.foo")); + create_data_misc_sdk_sandbox_sdk_path(nullptr, false, 0, "com.foo", "shared")); EXPECT_EQ("/data/misc_de/10/sdksandbox/com.foo/shared", - create_data_misc_sdk_sandbox_shared_path(nullptr, false, 10, "com.foo")); + create_data_misc_sdk_sandbox_sdk_path(nullptr, false, 10, "com.foo", "shared")); EXPECT_EQ("/data/misc_de/10/sdksandbox/com.foo/bar@random", - create_data_misc_sdk_sandbox_sdk_path(nullptr, false, 10, "com.foo", "bar", - "random")); + create_data_misc_sdk_sandbox_sdk_path(nullptr, false, 10, "com.foo", "bar@random")); } TEST_F(UtilsTest, WaitChild) { diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp index fd4d7bd360..2ed971da0e 100644 --- a/cmds/installd/utils.cpp +++ b/cmds/installd/utils.cpp @@ -224,28 +224,17 @@ std::string create_data_misc_sdk_sandbox_package_path(const char* volume_uuid, b } /** - * Create the path name where shared code data for a particular app will be stored. - * E.g. /data/misc_ce/0/sdksandbox/<package-name>/shared - */ -std::string create_data_misc_sdk_sandbox_shared_path(const char* volume_uuid, bool isCeData, - userid_t user, const char* package_name) { - return StringPrintf("%s/shared", - create_data_misc_sdk_sandbox_package_path(volume_uuid, isCeData, user, - package_name) - .c_str()); -} - -/** - * Create the path name where per-code level data for a particular app will be stored. - * E.g. /data/misc_ce/0/sdksandbox/<package-name>/<sdk-name>-<random-suffix> + * Create the path name where sdk data for a particular sdk will be stored. + * E.g. /data/misc_ce/0/sdksandbox/<package-name>/com.foo@randomstrings */ std::string create_data_misc_sdk_sandbox_sdk_path(const char* volume_uuid, bool isCeData, userid_t user, const char* package_name, - const char* sdk_name, const char* randomSuffix) { - check_package_name(sdk_name); - auto package_path = - create_data_misc_sdk_sandbox_package_path(volume_uuid, isCeData, user, package_name); - return StringPrintf("%s/%s@%s", package_path.c_str(), sdk_name, randomSuffix); + const char* sub_dir_name) { + return StringPrintf("%s/%s", + create_data_misc_sdk_sandbox_package_path(volume_uuid, isCeData, user, + package_name) + .c_str(), + sub_dir_name); } std::string create_data_misc_ce_rollback_base_path(const char* volume_uuid, userid_t user) { diff --git a/cmds/installd/utils.h b/cmds/installd/utils.h index dfc0bd50d4..ecea1d2b1c 100644 --- a/cmds/installd/utils.h +++ b/cmds/installd/utils.h @@ -65,11 +65,9 @@ std::string create_data_misc_sdk_sandbox_path(const char* volume_uuid, bool isCe userid_t userid); std::string create_data_misc_sdk_sandbox_package_path(const char* volume_uuid, bool isCeData, userid_t userid, const char* package_name); -std::string create_data_misc_sdk_sandbox_shared_path(const char* volume_uuid, bool isCeData, - userid_t userid, const char* package_name); std::string create_data_misc_sdk_sandbox_sdk_path(const char* volume_uuid, bool isCeData, userid_t userid, const char* package_name, - const char* sdk_name, const char* randomSuffix); + const char* sub_dir_name); std::string create_data_misc_ce_rollback_base_path(const char* volume_uuid, userid_t user); std::string create_data_misc_de_rollback_base_path(const char* volume_uuid, userid_t user); |