Fix 2578016.
Add some checks before moving package.
Checkin test code.
Regenerate test apks
Change-Id: I769ece128fefd3429ce93208a77d887c7759d2e1
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index b1b4028..95dbf3c 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -9663,9 +9663,6 @@
public void movePackage(final String packageName,
final IPackageMoveObserver observer, final int flags) {
- if (packageName == null) {
- return;
- }
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.MOVE_PACKAGE, null);
int returnCode = PackageManager.MOVE_SUCCEEDED;
@@ -9675,30 +9672,31 @@
PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) {
returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
- }
- // Disable moving fwd locked apps and system packages
- if (pkg.applicationInfo != null &&
- (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- Slog.w(TAG, "Cannot move system application");
- returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
- } else if (pkg.applicationInfo != null &&
- (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0) {
- Slog.w(TAG, "Cannot move forward locked app.");
- returnCode = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
} else {
- // Find install location first
- if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 &&
- (flags & PackageManager.MOVE_INTERNAL) != 0) {
- Slog.w(TAG, "Ambigous flags specified for move location.");
- returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
+ // Disable moving fwd locked apps and system packages
+ if (pkg.applicationInfo != null &&
+ (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ Slog.w(TAG, "Cannot move system application");
+ returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
+ } else if (pkg.applicationInfo != null &&
+ (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0) {
+ Slog.w(TAG, "Cannot move forward locked app.");
+ returnCode = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
} else {
- newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ?
- PackageManager.INSTALL_EXTERNAL : 0;
- currFlags = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 ?
- PackageManager.INSTALL_EXTERNAL : 0;
- if (newFlags == currFlags) {
- Slog.w(TAG, "No move required. Trying to move to same location");
+ // Find install location first
+ if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 &&
+ (flags & PackageManager.MOVE_INTERNAL) != 0) {
+ Slog.w(TAG, "Ambigous flags specified for move location.");
returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
+ } else {
+ newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ?
+ PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
+ currFlags = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 ?
+ PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
+ if (newFlags == currFlags) {
+ Slog.w(TAG, "No move required. Trying to move to same location");
+ returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
+ }
}
}
}
@@ -9722,67 +9720,87 @@
public void run() {
mHandler.removeCallbacks(this);
int returnCode = currentStatus;
- boolean moveSucceeded = (returnCode == PackageManager.MOVE_SUCCEEDED);
- if (moveSucceeded) {
- int uid = -1;
+ if (currentStatus == PackageManager.MOVE_SUCCEEDED) {
+ int uidArr[] = null;
+ ArrayList<String> pkgList = null;
synchronized (mPackages) {
- uid = mPackages.get(mp.packageName).applicationInfo.uid;
- }
- ArrayList<String> pkgList = new ArrayList<String>();
- pkgList.add(mp.packageName);
- int uidArr[] = new int[] { uid };
- // Send resources unavailable broadcast
- sendResourcesChangedBroadcast(false, pkgList, uidArr);
-
- // Update package code and resource paths
- synchronized (mInstallLock) {
- synchronized (mPackages) {
- PackageParser.Package pkg = mPackages.get(mp.packageName);
- if (pkg != null) {
- String oldCodePath = pkg.mPath;
- String newCodePath = mp.targetArgs.getCodePath();
- String newResPath = mp.targetArgs.getResourcePath();
- pkg.mPath = newCodePath;
- // Move dex files around
- if (moveDexFilesLI(pkg)
- != PackageManager.INSTALL_SUCCEEDED) {
- // Moving of dex files failed. Set
- // error code and abort move.
- pkg.mPath = pkg.mScanPath;
- returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
- moveSucceeded = false;
- } else {
- pkg.mScanPath = newCodePath;
- pkg.applicationInfo.sourceDir = newCodePath;
- pkg.applicationInfo.publicSourceDir = newResPath;
- PackageSetting ps = (PackageSetting) pkg.mExtras;
- ps.codePath = new File(pkg.applicationInfo.sourceDir);
- ps.codePathString = ps.codePath.getPath();
- ps.resourcePath = new File(pkg.applicationInfo.publicSourceDir);
- ps.resourcePathString = ps.resourcePath.getPath();
- // Set the application info flag correctly.
- if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
- pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
- } else {
- pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
- }
- ps.setFlags(pkg.applicationInfo.flags);
- mAppDirs.remove(oldCodePath);
- mAppDirs.put(newCodePath, pkg);
- // Persist settings
- mSettings.writeLP();
- }
- }
+ PackageParser.Package pkg = mPackages.get(mp.packageName);
+ if (pkg == null ) {
+ Slog.w(TAG, " Package " + mp.packageName +
+ " doesn't exist. Aborting move");
+ returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
+ } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
+ Slog.w(TAG, "Package " + mp.packageName + " code path changed from " +
+ mp.srcArgs.getCodePath() + " to " + pkg.applicationInfo.sourceDir +
+ " Aborting move and returning error");
+ returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
+ } else {
+ uidArr = new int[] { pkg.applicationInfo.uid };
+ pkgList = new ArrayList<String>();
+ pkgList.add(mp.packageName);
}
}
- // Send resources available broadcast
- sendResourcesChangedBroadcast(true, pkgList, uidArr);
+ if (returnCode == PackageManager.MOVE_SUCCEEDED) {
+ // Send resources unavailable broadcast
+ sendResourcesChangedBroadcast(false, pkgList, uidArr);
+ // Update package code and resource paths
+ synchronized (mInstallLock) {
+ synchronized (mPackages) {
+ PackageParser.Package pkg = mPackages.get(mp.packageName);
+ // Recheck for package again.
+ if (pkg == null ) {
+ Slog.w(TAG, " Package " + mp.packageName +
+ " doesn't exist. Aborting move");
+ returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
+ } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
+ Slog.w(TAG, "Package " + mp.packageName + " code path changed from " +
+ mp.srcArgs.getCodePath() + " to " + pkg.applicationInfo.sourceDir +
+ " Aborting move and returning error");
+ returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
+ } else {
+ String oldCodePath = pkg.mPath;
+ String newCodePath = mp.targetArgs.getCodePath();
+ String newResPath = mp.targetArgs.getResourcePath();
+ pkg.mPath = newCodePath;
+ // Move dex files around
+ if (moveDexFilesLI(pkg)
+ != PackageManager.INSTALL_SUCCEEDED) {
+ // Moving of dex files failed. Set
+ // error code and abort move.
+ pkg.mPath = pkg.mScanPath;
+ returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+ } else {
+ pkg.mScanPath = newCodePath;
+ pkg.applicationInfo.sourceDir = newCodePath;
+ pkg.applicationInfo.publicSourceDir = newResPath;
+ PackageSetting ps = (PackageSetting) pkg.mExtras;
+ ps.codePath = new File(pkg.applicationInfo.sourceDir);
+ ps.codePathString = ps.codePath.getPath();
+ ps.resourcePath = new File(pkg.applicationInfo.publicSourceDir);
+ ps.resourcePathString = ps.resourcePath.getPath();
+ // Set the application info flag correctly.
+ if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
+ pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
+ } else {
+ pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
+ }
+ ps.setFlags(pkg.applicationInfo.flags);
+ mAppDirs.remove(oldCodePath);
+ mAppDirs.put(newCodePath, pkg);
+ // Persist settings
+ mSettings.writeLP();
+ }
+ }
+ }
+ // Send resources available broadcast
+ sendResourcesChangedBroadcast(true, pkgList, uidArr);
+ }
+ }
}
- if (!moveSucceeded){
+ if (returnCode != PackageManager.MOVE_SUCCEEDED){
// Clean up failed installation
if (mp.targetArgs != null) {
- mp.targetArgs.doPostInstall(
- returnCode);
+ mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR);
}
} else {
// Force a gc to clear things up.
@@ -9804,3 +9822,4 @@
});
}
}
+