summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/pm/Settings.java6
-rw-r--r--services/core/java/com/android/server/pm/dex/ArtManagerService.java13
-rw-r--r--services/core/java/com/android/server/pm/dex/ViewCompiler.java7
-rw-r--r--services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java31
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java3
5 files changed, 46 insertions, 14 deletions
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 307867c4e272..d2adfddb4be3 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4893,8 +4893,6 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
pw.print("]");
}
pw.println();
- File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId());
- pw.print(prefix); pw.print(" dataDir="); pw.println(dataDir.getAbsolutePath());
if (pkg != null) {
pw.print(prefix); pw.print(" versionName="); pw.println(pkg.getVersionName());
pw.print(prefix); pw.print(" usesNonSdkApi="); pw.println(pkg.isNonSdkApiRequested());
@@ -5195,6 +5193,10 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
pw.print(" installReason=");
pw.println(userState.getInstallReason());
+ final File dataDir = PackageInfoUtils.getDataDir(ps, user.id);
+ pw.print(" dataDir=");
+ pw.println(dataDir == null ? "null" : dataDir.getAbsolutePath());
+
final PackageUserStateInternal pus = ps.readUserState(user.id);
pw.print(" firstInstallTime=");
date.setTime(pus.getFirstInstallTimeMillis());
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index 31856f1630bb..f4f03f4c9c4e 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -544,11 +544,6 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
*/
public boolean compileLayouts(@NonNull PackageStateInternal ps, @NonNull AndroidPackage pkg) {
try {
- final String packageName = pkg.getPackageName();
- final String apkPath = pkg.getSplits().get(0).getPath();
- // TODO(b/143971007): Use a cross-user directory
- File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId());
- final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex";
if (ps.isPrivileged() || pkg.isUseEmbeddedDex()
|| pkg.isDefaultToDeviceProtectedStorage()) {
// Privileged apps prefer to load trusted code so they don't use compiled views.
@@ -558,6 +553,14 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
// selinux permissions required for writing to user_de.
return false;
}
+ final String packageName = pkg.getPackageName();
+ final String apkPath = pkg.getSplits().get(0).getPath();
+ final File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId());
+ if (dataDir == null) {
+ // The app is not installed on the target user and doesn't have a data dir
+ return false;
+ }
+ final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex";
Log.i("PackageManager", "Compiling layouts in " + packageName + " (" + apkPath +
") to " + outDexFile);
final long callingId = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/pm/dex/ViewCompiler.java b/services/core/java/com/android/server/pm/dex/ViewCompiler.java
index 6405ea5667d3..c5b65a3641c1 100644
--- a/services/core/java/com/android/server/pm/dex/ViewCompiler.java
+++ b/services/core/java/com/android/server/pm/dex/ViewCompiler.java
@@ -40,8 +40,11 @@ public class ViewCompiler {
public boolean compileLayouts(PackageStateInternal ps, String apkPath) {
try {
final String packageName = ps.getPackageName();
- // TODO(b/143971007): Use a cross-user directory
- File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId());
+ final File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId());
+ if (dataDir == null) {
+ // The app is not installed on the target user and doesn't have a data dir
+ return false;
+ }
final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex";
Log.i("PackageManager", "Compiling layouts in " + packageName + " (" + apkPath +
") to " + outDexFile);
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index 27812dffd215..fc079093c9e3 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -443,7 +443,7 @@ public class PackageInfoUtils {
updateApplicationInfo(info, flags, state);
- initForUser(info, pkg, userId);
+ initForUser(info, pkg, userId, state);
// TODO(b/135203078): Remove PackageParser1/toAppInfoWithoutState and clean all this up
PackageStateUnserialized pkgState = pkgSetting.getTransientState();
@@ -689,7 +689,7 @@ public class PackageInfoUtils {
info.splitDependencies = pkg.getSplitDependencies().size() == 0
? null : pkg.getSplitDependencies();
- initForUser(info, pkg, userId);
+ initForUser(info, pkg, userId, state);
info.primaryCpuAbi = pkgSetting.getPrimaryCpuAbi();
info.secondaryCpuAbi = pkgSetting.getSecondaryCpuAbi();
@@ -1001,7 +1001,7 @@ public class PackageInfoUtils {
}
private static void initForUser(ApplicationInfo output, AndroidPackage input,
- @UserIdInt int userId) {
+ @UserIdInt int userId, PackageUserStateInternal state) {
PackageImpl pkg = ((PackageImpl) input);
String packageName = input.getPackageName();
output.uid = UserHandle.getUid(userId, UserHandle.getAppId(input.getUid()));
@@ -1011,6 +1011,12 @@ public class PackageInfoUtils {
return;
}
+ if (!pkg.isSystem() && state.getCeDataInode() <= 0) {
+ // The data dir has been deleted
+ output.dataDir = null;
+ return;
+ }
+
// For performance reasons, all these paths are built as strings
if (userId == UserHandle.USER_SYSTEM) {
output.credentialProtectedDataDir =
@@ -1045,7 +1051,7 @@ public class PackageInfoUtils {
// This duplicates the ApplicationInfo variant because it uses field assignment and the classes
// don't inherit from each other, unfortunately. Consolidating logic would introduce overhead.
private static void initForUser(InstrumentationInfo output, AndroidPackage input,
- @UserIdInt int userId) {
+ @UserIdInt int userId, PackageUserStateInternal state) {
PackageImpl pkg = ((PackageImpl) input);
String packageName = input.getPackageName();
if ("android".equals(packageName)) {
@@ -1053,6 +1059,12 @@ public class PackageInfoUtils {
return;
}
+ if (!pkg.isSystem() && state.getCeDataInode() <= 0) {
+ // The data dir has been deleted
+ output.dataDir = null;
+ return;
+ }
+
// For performance reasons, all these paths are built as strings
if (userId == UserHandle.USER_SYSTEM) {
output.credentialProtectedDataDir =
@@ -1084,12 +1096,21 @@ public class PackageInfoUtils {
}
}
- @NonNull
+ /**
+ * Returns the data dir of the app for the target user. Return null if the app isn't installed
+ * on the target user and doesn't have a data dir on the target user.
+ */
+ @Nullable
public static File getDataDir(PackageStateInternal ps, int userId) {
if ("android".equals(ps.getPackageName())) {
return Environment.getDataSystemDirectory();
}
+ if (!ps.isSystem() && ps.getUserStateOrDefault(userId).getCeDataInode() <= 0) {
+ // The data dir has been deleted
+ return null;
+ }
+
if (ps.isDefaultToDeviceProtectedStorage()
&& PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
return Environment.getDataUserDePackageDirectory(ps.getVolumeUuid(), userId,
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java
index e2939c1aff3b..98c6c424e223 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java
@@ -612,6 +612,9 @@ public class ScanTests {
final PackageSetting pkgSetting = scanResult.mPkgSetting;
assertBasicPackageSetting(scanResult, packageName, isInstant, pkgSetting);
+ // pretend that the data dir has been set up already, so that the generated applicationInfo
+ // includes the expected data dir string
+ pkgSetting.setCeDataInode(/* ceDataInode= */100, /* userId= */0);
final ApplicationInfo applicationInfo = PackageInfoUtils.generateApplicationInfo(
pkgSetting.getPkg(), 0, pkgSetting.getUserStateOrDefault(0), 0, pkgSetting);