am 4b18ced6: Merge "Fix 2578016." into froyo

Merge commit '4b18ced6b5409bb9dd4013c06b9562b76a062939' into froyo-plus-aosp

* commit '4b18ced6b5409bb9dd4013c06b9562b76a062939':
  Fix 2578016.
This commit is contained in:
Suchi Amalapurapu
2010-04-07 16:32:26 -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.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

View File

@@ -9663,9 +9663,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;
@@ -9675,30 +9672,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;
}
}
}
}
@@ -9722,67 +9720,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<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);
}
}
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.
@@ -9804,3 +9822,4 @@ class PackageManagerService extends IPackageManager.Stub {
});
}
}