am 070e1ecf: am a137cf2a: am 4b18ced6: Merge "Fix 2578016." into froyo

This commit is contained in:
Suchi Amalapurapu
2010-04-07 16:40:45 -07:00
committed by Android Git Automerger
42 changed files with 373 additions and 114 deletions

View File

@@ -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)

View File

@@ -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>

View File

@@ -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>

View File

@@ -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)

View File

@@ -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>

View File

@@ -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>

View File

@@ -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)

View File

@@ -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>

View File

@@ -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>

View File

@@ -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)

View File

@@ -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>

View File

@@ -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>

Binary file not shown.

View File

@@ -24,6 +24,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageParser; import android.content.pm.PackageParser;
@@ -1218,8 +1219,15 @@ public class PackageManagerTests extends AndroidTestCase {
private class PackageMoveObserver extends IPackageMoveObserver.Stub { private class PackageMoveObserver extends IPackageMoveObserver.Stub {
public int returnCode; public int returnCode;
private boolean doneFlag = false; private boolean doneFlag = false;
public String packageName;
public PackageMoveObserver(String pkgName) {
packageName = pkgName;
}
public void packageMoved(String packageName, int returnCode) { public void packageMoved(String packageName, int returnCode) {
Log.i("DEBUG_MOVE::", "pkg = " + packageName + ", " + "ret = " + returnCode);
if (!packageName.equals(this.packageName)) {
return;
}
synchronized(this) { synchronized(this) {
this.returnCode = returnCode; this.returnCode = returnCode;
doneFlag = true; doneFlag = true;
@@ -1234,7 +1242,7 @@ public class PackageManagerTests extends AndroidTestCase {
public boolean invokeMovePackage(String pkgName, int flags, public boolean invokeMovePackage(String pkgName, int flags,
GenericReceiver receiver) throws Exception { GenericReceiver receiver) throws Exception {
PackageMoveObserver observer = new PackageMoveObserver(); PackageMoveObserver observer = new PackageMoveObserver(pkgName);
final boolean received = false; final boolean received = false;
mContext.registerReceiver(receiver, receiver.filter); mContext.registerReceiver(receiver, receiver.filter);
try { try {
@@ -1269,6 +1277,26 @@ public class PackageManagerTests extends AndroidTestCase {
mContext.unregisterReceiver(receiver); 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() { private int getInstallLoc() {
boolean userSetting = false; boolean userSetting = false;
@@ -1285,31 +1313,37 @@ public class PackageManagerTests extends AndroidTestCase {
Settings.System.putInt(mContext.getContentResolver(), Settings.System.putInt(mContext.getContentResolver(),
Settings.System.DEFAULT_INSTALL_LOCATION, loc); 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 * Utility function that reads a apk bundled as a raw resource
* copies it into own data directory and invokes * copies it into own data directory and invokes
* PackageManager api to install first and then replace it * PackageManager api to install first and then replace it
* again. * 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(); int origDefaultLoc = getInstallLoc();
setInstallLoc(PackageHelper.APP_INSTALL_AUTO); InstallParams ip = null;
// Install first
InstallParams ip = sampleInstallFromRawResource(installFlags, false);
ApplicationInfo oldAppInfo = null;
try { try {
oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0); setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
} catch (NameNotFoundException e) { // Install first
failStr("Pkg hasnt been installed correctly"); ip = installFromRawResource("install.apk", rawResId, installFlags, false,
} false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
ApplicationInfo oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0);
// Create receiver based on expRetCode if (fail) {
MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName); assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
try { ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags, assertNotNull(info);
receiver); assertEquals(oldAppInfo.flags, info.flags);
if (expRetCode == PackageManager.MOVE_SUCCEEDED) { } else {
// Create receiver based on expRetCode
MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName);
boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags,
receiver);
assertTrue(retCode); assertTrue(retCode);
ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0); ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
assertNotNull(info); assertNotNull(info);
@@ -1318,40 +1352,91 @@ public class PackageManagerTests extends AndroidTestCase {
} else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0){ } else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0){
assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 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) { } catch (Exception e) {
failStr("Failed with exception : " + e); failStr("Failed with exception : " + e);
} finally { } finally {
cleanUpInstall(ip); if (ip != null) {
cleanUpInstall(ip);
}
// Restore default install location // Restore default install location
setInstallLoc(origDefaultLoc); 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() { public void testMoveAppInternalToExternal() {
moveFromRawResource(0, PackageManager.MOVE_EXTERNAL_MEDIA, int installFlags = PackageManager.INSTALL_INTERNAL;
PackageManager.MOVE_SUCCEEDED); int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
boolean fail = false;
int result = PackageManager.MOVE_SUCCEEDED;
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
} }
public void testMoveAppInternalToInternal() { public void testMoveAppInternalToInternal() {
moveFromRawResource(0, PackageManager.MOVE_INTERNAL, int installFlags = PackageManager.INSTALL_INTERNAL;
PackageManager.MOVE_FAILED_INVALID_LOCATION); int moveFlags = PackageManager.MOVE_INTERNAL;
boolean fail = true;
int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
} }
public void testMoveAppExternalToExternal() { public void testMoveAppExternalToExternal() {
moveFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.MOVE_EXTERNAL_MEDIA, int installFlags = PackageManager.INSTALL_EXTERNAL;
PackageManager.MOVE_FAILED_INVALID_LOCATION); int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
boolean fail = true;
int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
} }
public void testMoveAppExternalToInternal() { public void testMoveAppExternalToInternal() {
moveFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.MOVE_INTERNAL, int installFlags = PackageManager.INSTALL_EXTERNAL;
PackageManager.MOVE_SUCCEEDED); 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 * Test that an install error code is returned when media is unmounted
* and package installed on sdcard via package manager flag. * and package installed on sdcard via package manager flag.
@@ -1799,7 +1884,7 @@ public class PackageManagerTests extends AndroidTestCase {
rFlags, rFlags,
true, true,
false, -1, false, -1,
PackageInfo.INSTALL_LOCATION_AUTO); PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
} }
/* /*
* The following set of tests check install location for existing * The following set of tests check install location for existing

View File

@@ -9699,9 +9699,6 @@ class PackageManagerService extends IPackageManager.Stub {
public void movePackage(final String packageName, public void movePackage(final String packageName,
final IPackageMoveObserver observer, final int flags) { final IPackageMoveObserver observer, final int flags) {
if (packageName == null) {
return;
}
mContext.enforceCallingOrSelfPermission( mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.MOVE_PACKAGE, null); android.Manifest.permission.MOVE_PACKAGE, null);
int returnCode = PackageManager.MOVE_SUCCEEDED; int returnCode = PackageManager.MOVE_SUCCEEDED;
@@ -9711,30 +9708,31 @@ class PackageManagerService extends IPackageManager.Stub {
PackageParser.Package pkg = mPackages.get(packageName); PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) { if (pkg == null) {
returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 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 { } else {
// Find install location first // Disable moving fwd locked apps and system packages
if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 && if (pkg.applicationInfo != null &&
(flags & PackageManager.MOVE_INTERNAL) != 0) { (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
Slog.w(TAG, "Ambigous flags specified for move location."); Slog.w(TAG, "Cannot move system application");
returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; 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 { } else {
newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? // Find install location first
PackageManager.INSTALL_EXTERNAL : 0; if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 &&
currFlags = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 ? (flags & PackageManager.MOVE_INTERNAL) != 0) {
PackageManager.INSTALL_EXTERNAL : 0; Slog.w(TAG, "Ambigous flags specified for move location.");
if (newFlags == currFlags) {
Slog.w(TAG, "No move required. Trying to move to same location");
returnCode = PackageManager.MOVE_FAILED_INVALID_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() { public void run() {
mHandler.removeCallbacks(this); mHandler.removeCallbacks(this);
int returnCode = currentStatus; int returnCode = currentStatus;
boolean moveSucceeded = (returnCode == PackageManager.MOVE_SUCCEEDED); if (currentStatus == PackageManager.MOVE_SUCCEEDED) {
if (moveSucceeded) { int uidArr[] = null;
int uid = -1; ArrayList<String> pkgList = null;
synchronized (mPackages) { synchronized (mPackages) {
uid = mPackages.get(mp.packageName).applicationInfo.uid; PackageParser.Package pkg = mPackages.get(mp.packageName);
} if (pkg == null ) {
ArrayList<String> pkgList = new ArrayList<String>(); Slog.w(TAG, " Package " + mp.packageName +
pkgList.add(mp.packageName); " doesn't exist. Aborting move");
int uidArr[] = new int[] { uid }; returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
// Send resources unavailable broadcast } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
sendResourcesChangedBroadcast(false, pkgList, uidArr); Slog.w(TAG, "Package " + mp.packageName + " code path changed from " +
mp.srcArgs.getCodePath() + " to " + pkg.applicationInfo.sourceDir +
// Update package code and resource paths " Aborting move and returning error");
synchronized (mInstallLock) { returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
synchronized (mPackages) { } else {
PackageParser.Package pkg = mPackages.get(mp.packageName); uidArr = new int[] { pkg.applicationInfo.uid };
if (pkg != null) { pkgList = new ArrayList<String>();
String oldCodePath = pkg.mPath; pkgList.add(mp.packageName);
String newCodePath = mp.targetArgs.getCodePath(); }
String newResPath = mp.targetArgs.getResourcePath(); }
pkg.mPath = newCodePath; if (returnCode == PackageManager.MOVE_SUCCEEDED) {
// Move dex files around // Send resources unavailable broadcast
if (moveDexFilesLI(pkg) sendResourcesChangedBroadcast(false, pkgList, uidArr);
!= PackageManager.INSTALL_SUCCEEDED) { // Update package code and resource paths
// Moving of dex files failed. Set synchronized (mInstallLock) {
// error code and abort move. synchronized (mPackages) {
pkg.mPath = pkg.mScanPath; PackageParser.Package pkg = mPackages.get(mp.packageName);
returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; // Recheck for package again.
moveSucceeded = false; if (pkg == null ) {
} else { Slog.w(TAG, " Package " + mp.packageName +
pkg.mScanPath = newCodePath; " doesn't exist. Aborting move");
pkg.applicationInfo.sourceDir = newCodePath; returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
pkg.applicationInfo.publicSourceDir = newResPath; } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
PackageSetting ps = (PackageSetting) pkg.mExtras; Slog.w(TAG, "Package " + mp.packageName + " code path changed from " +
ps.codePath = new File(pkg.applicationInfo.sourceDir); mp.srcArgs.getCodePath() + " to " + pkg.applicationInfo.sourceDir +
ps.codePathString = ps.codePath.getPath(); " Aborting move and returning error");
ps.resourcePath = new File(pkg.applicationInfo.publicSourceDir); returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
ps.resourcePathString = ps.resourcePath.getPath(); } else {
// Set the application info flag correctly. String oldCodePath = pkg.mPath;
if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) { String newCodePath = mp.targetArgs.getCodePath();
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE; String newResPath = mp.targetArgs.getResourcePath();
} else { pkg.mPath = newCodePath;
pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE; // Move dex files around
} if (moveDexFilesLI(pkg)
ps.setFlags(pkg.applicationInfo.flags); != PackageManager.INSTALL_SUCCEEDED) {
mAppDirs.remove(oldCodePath); // Moving of dex files failed. Set
mAppDirs.put(newCodePath, pkg); // error code and abort move.
// Persist settings pkg.mPath = pkg.mScanPath;
mSettings.writeLP(); 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 // Clean up failed installation
if (mp.targetArgs != null) { if (mp.targetArgs != null) {
mp.targetArgs.doPostInstall( mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR);
returnCode);
} }
} else { } else {
// Force a gc to clear things up. // Force a gc to clear things up.
@@ -9840,3 +9858,4 @@ class PackageManagerService extends IPackageManager.Stub {
}); });
} }
} }