diff options
-rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 687ca5b..920a850 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -11505,7 +11505,7 @@ public class PackageManagerService extends IPackageManager.Stub { final IPackageInstallObserver2 observer; int installFlags; final String installerPackageName; - final String volumeUuid; + String volumeUuid; final VerificationParams verificationParams; private InstallArgs mArgs; private int mRet; @@ -11710,6 +11710,28 @@ public class PackageManagerService extends IPackageManager.Stub { } } + // Check whether we're replacing an existing package that's + // installed on adopted storage. If yes, override the new + // package location to match. + if (move == null && (installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { + synchronized (mPackages) { + PackageParser.Package pkg = mPackages.get(pkgLite.packageName); + if (pkg != null && isExternalAdopted(pkg)) { + // Check whether anything will actually change + // so that we log only when a fixup was needed + if (!((installFlags & PackageManager.INSTALL_INTERNAL) != 0 + && (installFlags & PackageManager.INSTALL_EXTERNAL) == 0 + && Objects.equals(volumeUuid, pkg.volumeUuid))) { + installFlags |= PackageManager.INSTALL_INTERNAL; + installFlags &= ~PackageManager.INSTALL_EXTERNAL; + volumeUuid = pkg.volumeUuid; + Slog.w(TAG, "Replacing package on adopted storage, updating " + +"new package destination to volumeUuid "+volumeUuid); + } + } + } + } + final InstallArgs args = createInstallArgs(this); mArgs = args; @@ -13661,6 +13683,14 @@ public class PackageManagerService extends IPackageManager.Stub { return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; } + // Package is assumed to be on adopted storage if: + // FLAG_EXTERNAL_STORAGE is set + // volumeUuid is neither private internal (null) nor primary physical + private static boolean isExternalAdopted(PackageParser.Package pkg) { + return isExternal(pkg) && !TextUtils.isEmpty(pkg.volumeUuid) + && !Objects.equals(pkg.volumeUuid, StorageManager.UUID_PRIMARY_PHYSICAL); + } + private static boolean isSystemApp(PackageParser.Package pkg) { return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } |