Merge "Fix 2578016." into froyo

This commit is contained in:
Suchi Amalapurapu
2010-04-07 15:25:51 -07:00
committed by Android (Google) Code Review
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();
InstallParams ip = null;
try {
setInstallLoc(PackageHelper.APP_INSTALL_AUTO); setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
// Install first // Install first
InstallParams ip = sampleInstallFromRawResource(installFlags, false); ip = installFromRawResource("install.apk", rawResId, installFlags, false,
ApplicationInfo oldAppInfo = null; false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
try { ApplicationInfo oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0);
oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0); if (fail) {
} catch (NameNotFoundException e) { assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
failStr("Pkg hasnt been installed correctly"); ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
} assertNotNull(info);
assertEquals(oldAppInfo.flags, info.flags);
} else {
// Create receiver based on expRetCode // Create receiver based on expRetCode
MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName); MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName);
try {
boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags, boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags,
receiver); receiver);
if (expRetCode == PackageManager.MOVE_SUCCEEDED) {
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 {
if (ip != null) {
cleanUpInstall(ip); 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

@@ -9663,9 +9663,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;
@@ -9675,7 +9672,7 @@ 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;
} } else {
// Disable moving fwd locked apps and system packages // Disable moving fwd locked apps and system packages
if (pkg.applicationInfo != null && if (pkg.applicationInfo != null &&
(pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
@@ -9693,15 +9690,16 @@ class PackageManagerService extends IPackageManager.Stub {
returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
} else { } else {
newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ?
PackageManager.INSTALL_EXTERNAL : 0; PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
currFlags = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 ? currFlags = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 ?
PackageManager.INSTALL_EXTERNAL : 0; PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
if (newFlags == currFlags) { if (newFlags == currFlags) {
Slog.w(TAG, "No move required. Trying to move to same location"); Slog.w(TAG, "No move required. Trying to move to same location");
returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
} }
} }
} }
}
if (returnCode != PackageManager.MOVE_SUCCEEDED) { if (returnCode != PackageManager.MOVE_SUCCEEDED) {
processPendingMove(new MoveParams(null, observer, 0, null), returnCode); processPendingMove(new MoveParams(null, observer, 0, null), returnCode);
} else { } else {
@@ -9722,23 +9720,44 @@ 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 +
" 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); pkgList.add(mp.packageName);
int uidArr[] = new int[] { uid }; }
}
if (returnCode == PackageManager.MOVE_SUCCEEDED) {
// Send resources unavailable broadcast // Send resources unavailable broadcast
sendResourcesChangedBroadcast(false, pkgList, uidArr); sendResourcesChangedBroadcast(false, pkgList, uidArr);
// Update package code and resource paths // Update package code and resource paths
synchronized (mInstallLock) { synchronized (mInstallLock) {
synchronized (mPackages) { synchronized (mPackages) {
PackageParser.Package pkg = mPackages.get(mp.packageName); PackageParser.Package pkg = mPackages.get(mp.packageName);
if (pkg != null) { // 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 oldCodePath = pkg.mPath;
String newCodePath = mp.targetArgs.getCodePath(); String newCodePath = mp.targetArgs.getCodePath();
String newResPath = mp.targetArgs.getResourcePath(); String newResPath = mp.targetArgs.getResourcePath();
@@ -9750,7 +9769,6 @@ class PackageManagerService extends IPackageManager.Stub {
// error code and abort move. // error code and abort move.
pkg.mPath = pkg.mScanPath; pkg.mPath = pkg.mScanPath;
returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
moveSucceeded = false;
} else { } else {
pkg.mScanPath = newCodePath; pkg.mScanPath = newCodePath;
pkg.applicationInfo.sourceDir = newCodePath; pkg.applicationInfo.sourceDir = newCodePath;
@@ -9774,15 +9792,15 @@ class PackageManagerService extends IPackageManager.Stub {
} }
} }
} }
}
// Send resources available broadcast // Send resources available broadcast
sendResourcesChangedBroadcast(true, pkgList, uidArr); 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.
@@ -9804,3 +9822,4 @@ class PackageManagerService extends IPackageManager.Stub {
}); });
} }
} }