Skip to content

Commit 5422685

Browse files
sam3000Gerrit Code Review
authored andcommitted
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
1 parent d119bd8 commit 5422685

1 file changed

Lines changed: 31 additions & 1 deletion

File tree

services/core/java/com/android/server/pm/PackageManagerService.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11505,7 +11505,7 @@ class InstallParams extends HandlerParams {
1150511505
final IPackageInstallObserver2 observer;
1150611506
int installFlags;
1150711507
final String installerPackageName;
11508-
final String volumeUuid;
11508+
String volumeUuid;
1150911509
final VerificationParams verificationParams;
1151011510
private InstallArgs mArgs;
1151111511
private int mRet;
@@ -11710,6 +11710,28 @@ public void handleStartCopy() throws RemoteException {
1171011710
}
1171111711
}
1171211712

11713+
// Check whether we're replacing an existing package that's
11714+
// installed on adopted storage. If yes, override the new
11715+
// package location to match.
11716+
if (move == null && (installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
11717+
synchronized (mPackages) {
11718+
PackageParser.Package pkg = mPackages.get(pkgLite.packageName);
11719+
if (pkg != null && isExternalAdopted(pkg)) {
11720+
// Check whether anything will actually change
11721+
// so that we log only when a fixup was needed
11722+
if (!((installFlags & PackageManager.INSTALL_INTERNAL) != 0
11723+
&& (installFlags & PackageManager.INSTALL_EXTERNAL) == 0
11724+
&& Objects.equals(volumeUuid, pkg.volumeUuid))) {
11725+
installFlags |= PackageManager.INSTALL_INTERNAL;
11726+
installFlags &= ~PackageManager.INSTALL_EXTERNAL;
11727+
volumeUuid = pkg.volumeUuid;
11728+
Slog.w(TAG, "Replacing package on adopted storage, updating "
11729+
+"new package destination to volumeUuid "+volumeUuid);
11730+
}
11731+
}
11732+
}
11733+
}
11734+
1171311735
final InstallArgs args = createInstallArgs(this);
1171411736
mArgs = args;
1171511737

@@ -13661,6 +13683,14 @@ private static boolean isExternal(ApplicationInfo info) {
1366113683
return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
1366213684
}
1366313685

13686+
// Package is assumed to be on adopted storage if:
13687+
// FLAG_EXTERNAL_STORAGE is set
13688+
// volumeUuid is neither private internal (null) nor primary physical
13689+
private static boolean isExternalAdopted(PackageParser.Package pkg) {
13690+
return isExternal(pkg) && !TextUtils.isEmpty(pkg.volumeUuid)
13691+
&& !Objects.equals(pkg.volumeUuid, StorageManager.UUID_PRIMARY_PHYSICAL);
13692+
}
13693+
1366413694
private static boolean isSystemApp(PackageParser.Package pkg) {
1366513695
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
1366613696
}

0 commit comments

Comments
 (0)