Fix 2578016.

Add some checks before moving package.
Checkin test code.
Regenerate test apks

Change-Id: I769ece128fefd3429ce93208a77d887c7759d2e1
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 0000000..2deb978
--- /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 0000000..5a903e29
--- /dev/null
+++ b/core/tests/coretests/apks/install_loc_auto/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        android:installLocation="auto"
+        package="com.android.frameworks.coretests.install_loc">
+
+    <application android:hasCode="false">
+    </application>
+</manifest>
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 0000000..3b8b3b1
--- /dev/null
+++ b/core/tests/coretests/apks/install_loc_auto/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Just need this dummy file to have something to build. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string name="dummy">dummy</string>
+</resources>
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 0000000..784bf0a
--- /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 0000000..2568f37
--- /dev/null
+++ b/core/tests/coretests/apks/install_loc_internal/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        android:installLocation="internalOnly"
+        package="com.android.frameworks.coretests.install_loc">
+
+    <application android:hasCode="false">
+    </application>
+</manifest>
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 0000000..3b8b3b1
--- /dev/null
+++ b/core/tests/coretests/apks/install_loc_internal/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Just need this dummy file to have something to build. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string name="dummy">dummy</string>
+</resources>
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 0000000..4eea322
--- /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 0000000..647f4e5
--- /dev/null
+++ b/core/tests/coretests/apks/install_loc_sdcard/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        android:installLocation="preferExternal"
+        package="com.android.frameworks.coretests.install_loc">
+
+    <application android:hasCode="false">
+    </application>
+</manifest>
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 0000000..3b8b3b1
--- /dev/null
+++ b/core/tests/coretests/apks/install_loc_sdcard/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Just need this dummy file to have something to build. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string name="dummy">dummy</string>
+</resources>
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 0000000..206c99f
--- /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 0000000..07b1eb3
--- /dev/null
+++ b/core/tests/coretests/apks/install_loc_unspecified/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.frameworks.coretests.install_loc">
+
+    <application android:hasCode="false">
+    </application>
+</manifest>
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 0000000..3b8b3b1
--- /dev/null
+++ b/core/tests/coretests/apks/install_loc_unspecified/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Just need this dummy file to have something to build. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string name="dummy">dummy</string>
+</resources>
diff --git a/core/tests/coretests/res/raw/install b/core/tests/coretests/res/raw/install
index 2ee1f3c..06981f4 100644
--- a/core/tests/coretests/res/raw/install
+++ b/core/tests/coretests/res/raw/install
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app1_cert1 b/core/tests/coretests/res/raw/install_app1_cert1
index 67eb2de..f880c0b 100644
--- a/core/tests/coretests/res/raw/install_app1_cert1
+++ b/core/tests/coretests/res/raw/install_app1_cert1
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app1_cert1_cert2 b/core/tests/coretests/res/raw/install_app1_cert1_cert2
index dbafdc5..ed89fbb 100644
--- a/core/tests/coretests/res/raw/install_app1_cert1_cert2
+++ b/core/tests/coretests/res/raw/install_app1_cert1_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app1_cert2 b/core/tests/coretests/res/raw/install_app1_cert2
index e26c2eb..5551c7e 100644
--- a/core/tests/coretests/res/raw/install_app1_cert2
+++ b/core/tests/coretests/res/raw/install_app1_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app1_cert3 b/core/tests/coretests/res/raw/install_app1_cert3
index fa10be7..0d1a4dc 100644
--- a/core/tests/coretests/res/raw/install_app1_cert3
+++ b/core/tests/coretests/res/raw/install_app1_cert3
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app1_cert3_cert4 b/core/tests/coretests/res/raw/install_app1_cert3_cert4
index c2f6c81..29ff3b6 100644
--- a/core/tests/coretests/res/raw/install_app1_cert3_cert4
+++ b/core/tests/coretests/res/raw/install_app1_cert3_cert4
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app1_unsigned b/core/tests/coretests/res/raw/install_app1_unsigned
index 18be5f8..01b39e2 100644
--- a/core/tests/coretests/res/raw/install_app1_unsigned
+++ b/core/tests/coretests/res/raw/install_app1_unsigned
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app2_cert1 b/core/tests/coretests/res/raw/install_app2_cert1
index b345732..12bfc6f 100644
--- a/core/tests/coretests/res/raw/install_app2_cert1
+++ b/core/tests/coretests/res/raw/install_app2_cert1
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app2_cert1_cert2 b/core/tests/coretests/res/raw/install_app2_cert1_cert2
index 1faa257..39095ba 100644
--- a/core/tests/coretests/res/raw/install_app2_cert1_cert2
+++ b/core/tests/coretests/res/raw/install_app2_cert1_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app2_cert2 b/core/tests/coretests/res/raw/install_app2_cert2
index c3d5979..f6d965b 100644
--- a/core/tests/coretests/res/raw/install_app2_cert2
+++ b/core/tests/coretests/res/raw/install_app2_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app2_cert3 b/core/tests/coretests/res/raw/install_app2_cert3
index ac0d9da..3d8b6f1 100644
--- a/core/tests/coretests/res/raw/install_app2_cert3
+++ b/core/tests/coretests/res/raw/install_app2_cert3
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app2_unsigned b/core/tests/coretests/res/raw/install_app2_unsigned
index 8d24e88..b69d9fe 100644
--- a/core/tests/coretests/res/raw/install_app2_unsigned
+++ b/core/tests/coretests/res/raw/install_app2_unsigned
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_decl_perm b/core/tests/coretests/res/raw/install_decl_perm
index 6f22321..af05d81 100644
--- a/core/tests/coretests/res/raw/install_decl_perm
+++ b/core/tests/coretests/res/raw/install_decl_perm
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_loc_auto b/core/tests/coretests/res/raw/install_loc_auto
index d5d2739..63bf35c 100644
--- a/core/tests/coretests/res/raw/install_loc_auto
+++ b/core/tests/coretests/res/raw/install_loc_auto
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_loc_internal b/core/tests/coretests/res/raw/install_loc_internal
index eb6279a..5178803 100644
--- a/core/tests/coretests/res/raw/install_loc_internal
+++ b/core/tests/coretests/res/raw/install_loc_internal
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_loc_sdcard b/core/tests/coretests/res/raw/install_loc_sdcard
index c774989..013a414 100644
--- a/core/tests/coretests/res/raw/install_loc_sdcard
+++ b/core/tests/coretests/res/raw/install_loc_sdcard
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_loc_unspecified b/core/tests/coretests/res/raw/install_loc_unspecified
index ab226c6..06981f4 100644
--- a/core/tests/coretests/res/raw/install_loc_unspecified
+++ b/core/tests/coretests/res/raw/install_loc_unspecified
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared1_cert1 b/core/tests/coretests/res/raw/install_shared1_cert1
index d702dab..714f9ff 100644
--- a/core/tests/coretests/res/raw/install_shared1_cert1
+++ b/core/tests/coretests/res/raw/install_shared1_cert1
Binary files 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 b580b60..0000000
--- a/core/tests/coretests/res/raw/install_shared1_cert12
+++ /dev/null
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared1_cert1_cert2 b/core/tests/coretests/res/raw/install_shared1_cert1_cert2
index b580b60..83725e0 100644
--- a/core/tests/coretests/res/raw/install_shared1_cert1_cert2
+++ b/core/tests/coretests/res/raw/install_shared1_cert1_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared1_cert2 b/core/tests/coretests/res/raw/install_shared1_cert2
index a2de801..6a3157e 100644
--- a/core/tests/coretests/res/raw/install_shared1_cert2
+++ b/core/tests/coretests/res/raw/install_shared1_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared1_unsigned b/core/tests/coretests/res/raw/install_shared1_unsigned
index 35680be..2a2e5f5 100644
--- a/core/tests/coretests/res/raw/install_shared1_unsigned
+++ b/core/tests/coretests/res/raw/install_shared1_unsigned
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared2_cert1 b/core/tests/coretests/res/raw/install_shared2_cert1
index 9064de7..7006edc 100644
--- a/core/tests/coretests/res/raw/install_shared2_cert1
+++ b/core/tests/coretests/res/raw/install_shared2_cert1
Binary files 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 26a250d..0000000
--- a/core/tests/coretests/res/raw/install_shared2_cert12
+++ /dev/null
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared2_cert1_cert2 b/core/tests/coretests/res/raw/install_shared2_cert1_cert2
index 26a250d..b7b084c 100644
--- a/core/tests/coretests/res/raw/install_shared2_cert1_cert2
+++ b/core/tests/coretests/res/raw/install_shared2_cert1_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared2_cert2 b/core/tests/coretests/res/raw/install_shared2_cert2
index 7981308..0f04388 100644
--- a/core/tests/coretests/res/raw/install_shared2_cert2
+++ b/core/tests/coretests/res/raw/install_shared2_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared2_unsigned b/core/tests/coretests/res/raw/install_shared2_unsigned
index ad909fd..2794282 100644
--- a/core/tests/coretests/res/raw/install_shared2_unsigned
+++ b/core/tests/coretests/res/raw/install_shared2_unsigned
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_use_perm_good b/core/tests/coretests/res/raw/install_use_perm_good
index d5216f8..a7eb32f 100644
--- a/core/tests/coretests/res/raw/install_use_perm_good
+++ b/core/tests/coretests/res/raw/install_use_perm_good
Binary files differ
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index c699c10..152f02e 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.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 @@
     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 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 @@
             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;
@@ -1286,30 +1314,36 @@
                 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 @@
                 } 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 @@
                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 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 @@
        });
    }
 }
+