[installd] Support creating oat dir hierarchy for inherit install.
This is to support the Package Manager change in
commit 767b1214ba6e5640380827d2f32ddb85271d938c. Details can be found
there.
Bug: 258223472
Test: -
1. Install a base APK using `adb install`.
2. Check the files in the oat dir and their inodes.
3. Install a split APK using `adb install -p` (inherit install).
4. Verify that the existing files are there in the oat dir at the
destination and their inodes are unchanged.
Flag: android.content.pm.alternative_for_dexopt_cleanup
Change-Id: I97f8e2be418a9375b84e2b872dc17d5bee0406d9
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 051c999..b4ad289 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -3291,7 +3291,7 @@
const char* oat_dir = getCStr(outputPath);
const char* instruction_set = instructionSet.c_str();
- if (oat_dir != nullptr && !createOatDir(packageName, oat_dir, instruction_set).isOk()) {
+ if (oat_dir != nullptr && !createOatDirs(packageName, oat_dir, {instruction_set}).isOk()) {
// Can't create oat dir - let dexopt use cache dir.
oat_dir = nullptr;
}
@@ -3499,17 +3499,15 @@
return res;
}
-binder::Status InstalldNativeService::createOatDir(const std::string& packageName,
- const std::string& oatDir,
- const std::string& instructionSet) {
+binder::Status InstalldNativeService::createOatDirs(const std::string& packageName,
+ const std::string& oatDir,
+ const std::vector<std::string>& oatSubDirs) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
CHECK_ARGUMENT_PATH(oatDir);
LOCK_PACKAGE();
const char* oat_dir = oatDir.c_str();
- const char* instruction_set = instructionSet.c_str();
- char oat_instr_dir[PKG_PATH_MAX];
if (validate_apk_path(oat_dir)) {
return error("Invalid path " + oatDir);
@@ -3520,9 +3518,22 @@
if (selinux_android_restorecon(oat_dir, 0)) {
return error("Failed to restorecon " + oatDir);
}
- snprintf(oat_instr_dir, PKG_PATH_MAX, "%s/%s", oat_dir, instruction_set);
- if (fs_prepare_dir(oat_instr_dir, S_IRWXU | S_IRWXG | S_IXOTH, AID_SYSTEM, AID_INSTALL)) {
- return error(StringPrintf("Failed to prepare %s", oat_instr_dir));
+ for (const std::string& sub_dir : oatSubDirs) {
+ // Create the given sub-directory as well as any nonexistent parent directories.
+ std::filesystem::path current_path(oat_dir);
+ std::filesystem::path sub_path(sub_dir);
+ if (sub_path.is_absolute()) {
+ return error("Invalid oat sub directory " + sub_dir);
+ }
+ for (const std::filesystem::path& component : sub_path) {
+ current_path /= component;
+ std::string path_str = current_path.string();
+ CHECK_ARGUMENT_PATH(path_str);
+ if (fs_prepare_dir(path_str.c_str(), S_IRWXU | S_IRWXG | S_IXOTH, AID_SYSTEM,
+ AID_INSTALL)) {
+ return error(StringPrintf("Failed to prepare %s", path_str.c_str()));
+ }
+ }
}
return ok();
}
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index b13d6d7..5c140fe 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -170,8 +170,8 @@
int32_t flags);
binder::Status linkNativeLibraryDirectory(const std::optional<std::string>& uuid,
const std::string& packageName, const std::string& nativeLibPath32, int32_t userId);
- binder::Status createOatDir(const std::string& packageName, const std::string& oatDir,
- const std::string& instructionSet);
+ binder::Status createOatDirs(const std::string& packageName, const std::string& oatDir,
+ const std::vector<std::string>& oatSubDirs);
binder::Status linkFile(const std::string& packageName, const std::string& relativePath,
const std::string& fromBase, const std::string& toBase);
binder::Status moveAb(const std::string& packageName, const std::string& apkPath,
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 8a2f113..64f662d 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -90,8 +90,8 @@
void freeCache(@nullable @utf8InCpp String uuid, long targetFreeBytes, int flags);
void linkNativeLibraryDirectory(@nullable @utf8InCpp String uuid,
@utf8InCpp String packageName, @utf8InCpp String nativeLibPath32, int userId);
- void createOatDir(@utf8InCpp String packageName, @utf8InCpp String oatDir,
- @utf8InCpp String instructionSet);
+ void createOatDirs(@utf8InCpp String packageName, @utf8InCpp String oatDir,
+ in @utf8InCpp List<String> oatSubDirs);
void linkFile(@utf8InCpp String packageName, @utf8InCpp String relativePath,
@utf8InCpp String fromBase, @utf8InCpp String toBase);
void moveAb(@utf8InCpp String packageName, @utf8InCpp String apkPath,
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index e89543e..5b1d8b1 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -775,7 +775,7 @@
TEST_F(DexoptTest, DexoptPrimaryPublicCreateOatDir) {
LOG(INFO) << "DexoptPrimaryPublic";
- ASSERT_BINDER_SUCCESS(service_->createOatDir(package_name_, app_oat_dir_, kRuntimeIsa));
+ ASSERT_BINDER_SUCCESS(service_->createOatDirs(package_name_, app_oat_dir_, {kRuntimeIsa}));
CompilePrimaryDexOk("verify",
DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
app_oat_dir_.c_str(),