summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorSam Mortimer <sam@mortimer.me.uk>2015-12-27 00:57:08 -0800
committerGerrit Code Review <gerrit@cyanogenmod.org>2016-08-18 06:53:43 -0700
commit5422685df7dd34a859512d1bee5f53d0a9ac696c (patch)
treea0a04565de77f83363eaf7a5a49d2a4c33daeb32 /services
parentd119bd8d5d6964a326c948b49895ea9488f93a9e (diff)
downloadframeworks_base-5422685df7dd34a859512d1bee5f53d0a9ac696c.zip
frameworks_base-5422685df7dd34a859512d1bee5f53d0a9ac696c.tar.gz
frameworks_base-5422685df7dd34a859512d1bee5f53d0a9ac696c.tar.bz2
Ensure packages on adopted media do not move when updated
Packages not installed with PackageInstaller.Session that are moved to adopted storage via android storage settings will get moved back to private internal storage when the package is later updated. This causes the app to lose it's data (and leaves the data dir dangling on the original adopted location). play market installs do not have this problem (because they use an installer session) but pretty much every other app install route does. eg adb install and other app stores. Change-Id: I0f606b230460f32310921c75e58ccb5b610268e4
Diffstat (limited to 'services')
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java32
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;
}