diff --git a/core/tests/coretests/apks/install_loc_auto/Android.mk b/core/tests/coretests/apks/install_loc_auto/Android.mk new file mode 100644 index 0000000000000..2deb978262bd3 --- /dev/null +++ b/core/tests/coretests/apks/install_loc_auto/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_loc_auto + +include $(BUILD_PACKAGE) + diff --git a/core/tests/coretests/apks/install_loc_auto/AndroidManifest.xml b/core/tests/coretests/apks/install_loc_auto/AndroidManifest.xml new file mode 100644 index 0000000000000..5a903e2903d38 --- /dev/null +++ b/core/tests/coretests/apks/install_loc_auto/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/core/tests/coretests/apks/install_loc_auto/res/values/strings.xml b/core/tests/coretests/apks/install_loc_auto/res/values/strings.xml new file mode 100644 index 0000000000000..3b8b3b1af9b5e --- /dev/null +++ b/core/tests/coretests/apks/install_loc_auto/res/values/strings.xml @@ -0,0 +1,6 @@ + + + + + dummy + diff --git a/core/tests/coretests/apks/install_loc_internal/Android.mk b/core/tests/coretests/apks/install_loc_internal/Android.mk new file mode 100644 index 0000000000000..784bf0a014632 --- /dev/null +++ b/core/tests/coretests/apks/install_loc_internal/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_loc_internal + +include $(BUILD_PACKAGE) + diff --git a/core/tests/coretests/apks/install_loc_internal/AndroidManifest.xml b/core/tests/coretests/apks/install_loc_internal/AndroidManifest.xml new file mode 100644 index 0000000000000..2568f37295237 --- /dev/null +++ b/core/tests/coretests/apks/install_loc_internal/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/core/tests/coretests/apks/install_loc_internal/res/values/strings.xml b/core/tests/coretests/apks/install_loc_internal/res/values/strings.xml new file mode 100644 index 0000000000000..3b8b3b1af9b5e --- /dev/null +++ b/core/tests/coretests/apks/install_loc_internal/res/values/strings.xml @@ -0,0 +1,6 @@ + + + + + dummy + diff --git a/core/tests/coretests/apks/install_loc_sdcard/Android.mk b/core/tests/coretests/apks/install_loc_sdcard/Android.mk new file mode 100644 index 0000000000000..4eea32256b8df --- /dev/null +++ b/core/tests/coretests/apks/install_loc_sdcard/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_loc_sdcard + +include $(BUILD_PACKAGE) + diff --git a/core/tests/coretests/apks/install_loc_sdcard/AndroidManifest.xml b/core/tests/coretests/apks/install_loc_sdcard/AndroidManifest.xml new file mode 100644 index 0000000000000..647f4e5f60ff6 --- /dev/null +++ b/core/tests/coretests/apks/install_loc_sdcard/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml b/core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml new file mode 100644 index 0000000000000..3b8b3b1af9b5e --- /dev/null +++ b/core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml @@ -0,0 +1,6 @@ + + + + + dummy + diff --git a/core/tests/coretests/apks/install_loc_unspecified/Android.mk b/core/tests/coretests/apks/install_loc_unspecified/Android.mk new file mode 100644 index 0000000000000..206c99fe0076e --- /dev/null +++ b/core/tests/coretests/apks/install_loc_unspecified/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_loc_unspecified + +include $(BUILD_PACKAGE) + diff --git a/core/tests/coretests/apks/install_loc_unspecified/AndroidManifest.xml b/core/tests/coretests/apks/install_loc_unspecified/AndroidManifest.xml new file mode 100644 index 0000000000000..07b1eb3105e39 --- /dev/null +++ b/core/tests/coretests/apks/install_loc_unspecified/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml b/core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml new file mode 100644 index 0000000000000..3b8b3b1af9b5e --- /dev/null +++ b/core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml @@ -0,0 +1,6 @@ + + + + + dummy + diff --git a/core/tests/coretests/res/raw/install b/core/tests/coretests/res/raw/install index 2ee1f3cffa443..06981f41270bf 100644 Binary files a/core/tests/coretests/res/raw/install and b/core/tests/coretests/res/raw/install differ diff --git a/core/tests/coretests/res/raw/install_app1_cert1 b/core/tests/coretests/res/raw/install_app1_cert1 index 67eb2de645d37..f880c0b1126b9 100644 Binary files a/core/tests/coretests/res/raw/install_app1_cert1 and b/core/tests/coretests/res/raw/install_app1_cert1 differ diff --git a/core/tests/coretests/res/raw/install_app1_cert1_cert2 b/core/tests/coretests/res/raw/install_app1_cert1_cert2 index dbafdc509181a..ed89fbb2eb353 100644 Binary files a/core/tests/coretests/res/raw/install_app1_cert1_cert2 and b/core/tests/coretests/res/raw/install_app1_cert1_cert2 differ diff --git a/core/tests/coretests/res/raw/install_app1_cert2 b/core/tests/coretests/res/raw/install_app1_cert2 index e26c2eb20f8db..5551c7ebff07c 100644 Binary files a/core/tests/coretests/res/raw/install_app1_cert2 and b/core/tests/coretests/res/raw/install_app1_cert2 differ diff --git a/core/tests/coretests/res/raw/install_app1_cert3 b/core/tests/coretests/res/raw/install_app1_cert3 index fa10be760022a..0d1a4dcce8542 100644 Binary files a/core/tests/coretests/res/raw/install_app1_cert3 and b/core/tests/coretests/res/raw/install_app1_cert3 differ diff --git a/core/tests/coretests/res/raw/install_app1_cert3_cert4 b/core/tests/coretests/res/raw/install_app1_cert3_cert4 index c2f6c81a63072..29ff3b6c59714 100644 Binary files a/core/tests/coretests/res/raw/install_app1_cert3_cert4 and b/core/tests/coretests/res/raw/install_app1_cert3_cert4 differ diff --git a/core/tests/coretests/res/raw/install_app1_unsigned b/core/tests/coretests/res/raw/install_app1_unsigned index 18be5f856bfcb..01b39e28866f8 100644 Binary files a/core/tests/coretests/res/raw/install_app1_unsigned and b/core/tests/coretests/res/raw/install_app1_unsigned differ diff --git a/core/tests/coretests/res/raw/install_app2_cert1 b/core/tests/coretests/res/raw/install_app2_cert1 index b34573202f661..12bfc6f5aa5d7 100644 Binary files a/core/tests/coretests/res/raw/install_app2_cert1 and b/core/tests/coretests/res/raw/install_app2_cert1 differ diff --git a/core/tests/coretests/res/raw/install_app2_cert1_cert2 b/core/tests/coretests/res/raw/install_app2_cert1_cert2 index 1faa257b451aa..39095ba7faa22 100644 Binary files a/core/tests/coretests/res/raw/install_app2_cert1_cert2 and b/core/tests/coretests/res/raw/install_app2_cert1_cert2 differ diff --git a/core/tests/coretests/res/raw/install_app2_cert2 b/core/tests/coretests/res/raw/install_app2_cert2 index c3d597904a8cc..f6d965be6f374 100644 Binary files a/core/tests/coretests/res/raw/install_app2_cert2 and b/core/tests/coretests/res/raw/install_app2_cert2 differ diff --git a/core/tests/coretests/res/raw/install_app2_cert3 b/core/tests/coretests/res/raw/install_app2_cert3 index ac0d9da2067da..3d8b6f17f397d 100644 Binary files a/core/tests/coretests/res/raw/install_app2_cert3 and b/core/tests/coretests/res/raw/install_app2_cert3 differ diff --git a/core/tests/coretests/res/raw/install_app2_unsigned b/core/tests/coretests/res/raw/install_app2_unsigned index 8d24e888127cf..b69d9fe5c6f93 100644 Binary files a/core/tests/coretests/res/raw/install_app2_unsigned and b/core/tests/coretests/res/raw/install_app2_unsigned differ diff --git a/core/tests/coretests/res/raw/install_decl_perm b/core/tests/coretests/res/raw/install_decl_perm index 6f223213e2416..af05d81fbedf4 100644 Binary files a/core/tests/coretests/res/raw/install_decl_perm and b/core/tests/coretests/res/raw/install_decl_perm differ diff --git a/core/tests/coretests/res/raw/install_loc_auto b/core/tests/coretests/res/raw/install_loc_auto index d5d2739f927e2..63bf35c3adb75 100644 Binary files a/core/tests/coretests/res/raw/install_loc_auto and b/core/tests/coretests/res/raw/install_loc_auto differ diff --git a/core/tests/coretests/res/raw/install_loc_internal b/core/tests/coretests/res/raw/install_loc_internal index eb6279a475dfe..5178803080139 100644 Binary files a/core/tests/coretests/res/raw/install_loc_internal and b/core/tests/coretests/res/raw/install_loc_internal differ diff --git a/core/tests/coretests/res/raw/install_loc_sdcard b/core/tests/coretests/res/raw/install_loc_sdcard index c7749891dead4..013a4146f8214 100644 Binary files a/core/tests/coretests/res/raw/install_loc_sdcard and b/core/tests/coretests/res/raw/install_loc_sdcard differ diff --git a/core/tests/coretests/res/raw/install_loc_unspecified b/core/tests/coretests/res/raw/install_loc_unspecified index ab226c6d73e6c..06981f41270bf 100644 Binary files a/core/tests/coretests/res/raw/install_loc_unspecified and b/core/tests/coretests/res/raw/install_loc_unspecified differ diff --git a/core/tests/coretests/res/raw/install_shared1_cert1 b/core/tests/coretests/res/raw/install_shared1_cert1 index d702dabbb6766..714f9fffde4e0 100644 Binary files a/core/tests/coretests/res/raw/install_shared1_cert1 and b/core/tests/coretests/res/raw/install_shared1_cert1 differ diff --git a/core/tests/coretests/res/raw/install_shared1_cert12 b/core/tests/coretests/res/raw/install_shared1_cert12 deleted file mode 100644 index b580b60a5feef..0000000000000 Binary files a/core/tests/coretests/res/raw/install_shared1_cert12 and /dev/null differ diff --git a/core/tests/coretests/res/raw/install_shared1_cert1_cert2 b/core/tests/coretests/res/raw/install_shared1_cert1_cert2 index b580b60a5feef..83725e0d2b263 100644 Binary files a/core/tests/coretests/res/raw/install_shared1_cert1_cert2 and b/core/tests/coretests/res/raw/install_shared1_cert1_cert2 differ diff --git a/core/tests/coretests/res/raw/install_shared1_cert2 b/core/tests/coretests/res/raw/install_shared1_cert2 index a2de801249ad7..6a3157e1196c7 100644 Binary files a/core/tests/coretests/res/raw/install_shared1_cert2 and b/core/tests/coretests/res/raw/install_shared1_cert2 differ diff --git a/core/tests/coretests/res/raw/install_shared1_unsigned b/core/tests/coretests/res/raw/install_shared1_unsigned index 35680be1697e1..2a2e5f5fdad8d 100644 Binary files a/core/tests/coretests/res/raw/install_shared1_unsigned and b/core/tests/coretests/res/raw/install_shared1_unsigned differ diff --git a/core/tests/coretests/res/raw/install_shared2_cert1 b/core/tests/coretests/res/raw/install_shared2_cert1 index 9064de7840b08..7006edcc67b25 100644 Binary files a/core/tests/coretests/res/raw/install_shared2_cert1 and b/core/tests/coretests/res/raw/install_shared2_cert1 differ diff --git a/core/tests/coretests/res/raw/install_shared2_cert12 b/core/tests/coretests/res/raw/install_shared2_cert12 deleted file mode 100644 index 26a250d5d7f03..0000000000000 Binary files a/core/tests/coretests/res/raw/install_shared2_cert12 and /dev/null differ diff --git a/core/tests/coretests/res/raw/install_shared2_cert1_cert2 b/core/tests/coretests/res/raw/install_shared2_cert1_cert2 index 26a250d5d7f03..b7b084c0a7798 100644 Binary files a/core/tests/coretests/res/raw/install_shared2_cert1_cert2 and b/core/tests/coretests/res/raw/install_shared2_cert1_cert2 differ diff --git a/core/tests/coretests/res/raw/install_shared2_cert2 b/core/tests/coretests/res/raw/install_shared2_cert2 index 79813087c142f..0f04388c371e3 100644 Binary files a/core/tests/coretests/res/raw/install_shared2_cert2 and b/core/tests/coretests/res/raw/install_shared2_cert2 differ diff --git a/core/tests/coretests/res/raw/install_shared2_unsigned b/core/tests/coretests/res/raw/install_shared2_unsigned index ad909fd6c9d0a..2794282512dea 100644 Binary files a/core/tests/coretests/res/raw/install_shared2_unsigned and b/core/tests/coretests/res/raw/install_shared2_unsigned differ diff --git a/core/tests/coretests/res/raw/install_use_perm_good b/core/tests/coretests/res/raw/install_use_perm_good index d5216f89a47a0..a7eb32fb55816 100644 Binary files a/core/tests/coretests/res/raw/install_use_perm_good and b/core/tests/coretests/res/raw/install_use_perm_good differ diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java index c699c10215bf6..152f02e57ebb9 100755 --- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java +++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java @@ -24,6 +24,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageMoveObserver; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageParser; @@ -1218,8 +1219,15 @@ public class PackageManagerTests extends AndroidTestCase { private class PackageMoveObserver extends IPackageMoveObserver.Stub { public int returnCode; private boolean doneFlag = false; - + public String packageName; + public PackageMoveObserver(String pkgName) { + packageName = pkgName; + } public void packageMoved(String packageName, int returnCode) { + Log.i("DEBUG_MOVE::", "pkg = " + packageName + ", " + "ret = " + returnCode); + if (!packageName.equals(this.packageName)) { + return; + } synchronized(this) { this.returnCode = returnCode; doneFlag = true; @@ -1234,7 +1242,7 @@ public class PackageManagerTests extends AndroidTestCase { public boolean invokeMovePackage(String pkgName, int flags, GenericReceiver receiver) throws Exception { - PackageMoveObserver observer = new PackageMoveObserver(); + PackageMoveObserver observer = new PackageMoveObserver(pkgName); final boolean received = false; mContext.registerReceiver(receiver, receiver.filter); try { @@ -1269,6 +1277,26 @@ public class PackageManagerTests extends AndroidTestCase { mContext.unregisterReceiver(receiver); } } + private boolean invokeMovePackageFail(String pkgName, int flags, int errCode) throws Exception { + PackageMoveObserver observer = new PackageMoveObserver(pkgName); + try { + // Wait on observer + synchronized(observer) { + getPm().movePackage(pkgName, observer, flags); + long waitTime = 0; + while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) { + observer.wait(WAIT_TIME_INCR); + waitTime += WAIT_TIME_INCR; + } + if(!observer.isDone()) { + throw new Exception("Timed out waiting for pkgmove callback"); + } + assertEquals(errCode, observer.returnCode); + } + } finally { + } + return true; + } private int getInstallLoc() { boolean userSetting = false; @@ -1285,31 +1313,37 @@ public class PackageManagerTests extends AndroidTestCase { Settings.System.putInt(mContext.getContentResolver(), Settings.System.DEFAULT_INSTALL_LOCATION, loc); } + /* + * Tests for moving apps between internal and external storage + */ /* * Utility function that reads a apk bundled as a raw resource * copies it into own data directory and invokes * PackageManager api to install first and then replace it * again. */ - public void moveFromRawResource(int installFlags, int moveFlags, - int expRetCode) { + + private void moveFromRawResource(String outFileName, + int rawResId, int installFlags, int moveFlags, boolean cleanUp, + boolean fail, int result) { int origDefaultLoc = getInstallLoc(); - setInstallLoc(PackageHelper.APP_INSTALL_AUTO); - // Install first - InstallParams ip = sampleInstallFromRawResource(installFlags, false); - ApplicationInfo oldAppInfo = null; + InstallParams ip = null; try { - oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0); - } catch (NameNotFoundException e) { - failStr("Pkg hasnt been installed correctly"); - } - - // Create receiver based on expRetCode - MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName); - try { - boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags, - receiver); - if (expRetCode == PackageManager.MOVE_SUCCEEDED) { + setInstallLoc(PackageHelper.APP_INSTALL_AUTO); + // Install first + ip = installFromRawResource("install.apk", rawResId, installFlags, false, + false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); + ApplicationInfo oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0); + if (fail) { + assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result)); + ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0); + assertNotNull(info); + assertEquals(oldAppInfo.flags, info.flags); + } else { + // Create receiver based on expRetCode + MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName); + boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags, + receiver); assertTrue(retCode); ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0); assertNotNull(info); @@ -1318,40 +1352,91 @@ public class PackageManagerTests extends AndroidTestCase { } else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0){ assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); } - } else { - assertFalse(retCode); - ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0); - assertNotNull(info); - assertEquals(oldAppInfo.flags, info.flags); } + } catch (NameNotFoundException e) { + failStr("Pkg hasnt been installed correctly"); } catch (Exception e) { failStr("Failed with exception : " + e); } finally { - cleanUpInstall(ip); + if (ip != null) { + cleanUpInstall(ip); + } // Restore default install location setInstallLoc(origDefaultLoc); } } + private void sampleMoveFromRawResource(int installFlags, int moveFlags, boolean fail, + int result) { + moveFromRawResource("install.apk", + R.raw.install, installFlags, moveFlags, true, + fail, result); + } public void testMoveAppInternalToExternal() { - moveFromRawResource(0, PackageManager.MOVE_EXTERNAL_MEDIA, - PackageManager.MOVE_SUCCEEDED); + int installFlags = PackageManager.INSTALL_INTERNAL; + int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; + boolean fail = false; + int result = PackageManager.MOVE_SUCCEEDED; + sampleMoveFromRawResource(installFlags, moveFlags, fail, result); } public void testMoveAppInternalToInternal() { - moveFromRawResource(0, PackageManager.MOVE_INTERNAL, - PackageManager.MOVE_FAILED_INVALID_LOCATION); + int installFlags = PackageManager.INSTALL_INTERNAL; + int moveFlags = PackageManager.MOVE_INTERNAL; + boolean fail = true; + int result = PackageManager.MOVE_FAILED_INVALID_LOCATION; + sampleMoveFromRawResource(installFlags, moveFlags, fail, result); } public void testMoveAppExternalToExternal() { - moveFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.MOVE_EXTERNAL_MEDIA, - PackageManager.MOVE_FAILED_INVALID_LOCATION); + int installFlags = PackageManager.INSTALL_EXTERNAL; + int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; + boolean fail = true; + int result = PackageManager.MOVE_FAILED_INVALID_LOCATION; + sampleMoveFromRawResource(installFlags, moveFlags, fail, result); } public void testMoveAppExternalToInternal() { - moveFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.MOVE_INTERNAL, - PackageManager.MOVE_SUCCEEDED); + int installFlags = PackageManager.INSTALL_EXTERNAL; + int moveFlags = PackageManager.MOVE_INTERNAL; + boolean fail = false; + int result = PackageManager.MOVE_SUCCEEDED; + sampleMoveFromRawResource(installFlags, moveFlags, fail, result); + } + public void testMoveAppForwardLocked() { + int installFlags = PackageManager.INSTALL_FORWARD_LOCK; + int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; + boolean fail = true; + int result = PackageManager.MOVE_FAILED_FORWARD_LOCKED; + sampleMoveFromRawResource(installFlags, moveFlags, fail, result); + } + public void testMoveAppFailInternalToExternalDelete() { + int installFlags = 0; + int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; + boolean fail = true; + final int result = PackageManager.MOVE_FAILED_DOESNT_EXIST; + + int rawResId = R.raw.install; + int origDefaultLoc = getInstallLoc(); + InstallParams ip = null; + try { + PackageManager pm = getPm(); + setInstallLoc(PackageHelper.APP_INSTALL_AUTO); + // Install first + ip = installFromRawResource("install.apk", R.raw.install, installFlags, false, + false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED); + // Delete the package now retaining data. + pm.deletePackage(ip.pkg.packageName, null, PackageManager.DONT_DELETE_DATA); + assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result)); + } catch (Exception e) { + failStr(e); + } finally { + if (ip != null) { + cleanUpInstall(ip); + } + // Restore default install location + setInstallLoc(origDefaultLoc); + } } - /* * Test that an install error code is returned when media is unmounted * and package installed on sdcard via package manager flag. @@ -1799,7 +1884,7 @@ public class PackageManagerTests extends AndroidTestCase { rFlags, true, false, -1, - PackageInfo.INSTALL_LOCATION_AUTO); + PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); } /* * The following set of tests check install location for existing diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index 38aec67aecb14..0df09e47c14f6 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -9699,9 +9699,6 @@ class PackageManagerService extends IPackageManager.Stub { 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; @@ -9711,30 +9708,31 @@ class PackageManagerService extends IPackageManager.Stub { 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; + } } } } @@ -9758,67 +9756,87 @@ class PackageManagerService extends IPackageManager.Stub { 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 pkgList = null; synchronized (mPackages) { - uid = mPackages.get(mp.packageName).applicationInfo.uid; - } - ArrayList pkgList = new ArrayList(); - 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(); + pkgList.add(mp.packageName); + } + } + 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); } } - // 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. @@ -9840,3 +9858,4 @@ class PackageManagerService extends IPackageManager.Stub { }); } } +