summaryrefslogtreecommitdiffstats
path: root/services/core/java/com/android/server/pm/PackageManagerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/core/java/com/android/server/pm/PackageManagerService.java')
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java640
1 files changed, 290 insertions, 350 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 89bd1d4..aa49b27 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -48,11 +48,6 @@ import static android.os.Process.PACKAGE_INFO_GID;
import static android.os.Process.SYSTEM_UID;
import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDWR;
-import static android.system.OsConstants.S_IRGRP;
-import static android.system.OsConstants.S_IROTH;
-import static android.system.OsConstants.S_IRWXU;
-import static android.system.OsConstants.S_IXGRP;
-import static android.system.OsConstants.S_IXOTH;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
import static com.android.internal.util.ArrayUtils.appendInt;
@@ -70,7 +65,6 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.Preconditions;
import com.android.server.EventLogTags;
import com.android.server.IntentResolver;
import com.android.server.LocalServices;
@@ -107,12 +101,12 @@ import android.content.pm.IPackageInstaller;
import android.content.pm.IPackageManager;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
-import android.content.pm.InstallSessionParams;
import android.content.pm.InstrumentationInfo;
import android.content.pm.ManifestDigest;
import android.content.pm.PackageCleanItem;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfoLite;
+import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
import android.content.pm.PackageParser.ActivityIntentInfo;
@@ -140,6 +134,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Environment.UserEnvironment;
+import android.os.storage.StorageManager;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBinder;
@@ -211,6 +206,7 @@ import dalvik.system.StaleDexCacheError;
import dalvik.system.VMRuntime;
import libcore.io.IoUtils;
+import libcore.util.EmptyArray;
/**
* Keep track of all those .apks everywhere.
@@ -253,10 +249,6 @@ public class PackageManagerService extends IPackageManager.Stub {
// package apks to install directory.
private static final String INSTALL_PACKAGE_SUFFIX = "-";
- // Special value for {@code PackageParser.Package#cpuAbiOverride} to indicate
- // that the cpuAbiOverride must be clear.
- private static final String CLEAR_ABI_OVERRIDE = "-";
-
static final int SCAN_MONITOR = 1<<0;
static final int SCAN_NO_DEX = 1<<1;
static final int SCAN_FORCE_DEX = 1<<2;
@@ -311,8 +303,6 @@ public class PackageManagerService extends IPackageManager.Stub {
private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
- static final String mTempContainerPrefix = "smdl2tmp";
-
private static String sPreferredInstructionSet;
final ServiceThread mHandlerThread;
@@ -1394,16 +1384,27 @@ public class PackageManagerService extends IPackageManager.Stub {
* list of process files because dexopt will have been run
* if necessary during zygote startup.
*/
- String bootClassPath = System.getProperty("java.boot.class.path");
+ final String bootClassPath = System.getenv("BOOTCLASSPATH");
+ final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
+
if (bootClassPath != null) {
- String[] paths = splitString(bootClassPath, ':');
- for (int i=0; i<paths.length; i++) {
- alreadyDexOpted.add(paths[i]);
+ String[] bootClassPathElements = splitString(bootClassPath, ':');
+ for (String element : bootClassPathElements) {
+ alreadyDexOpted.add(element);
}
} else {
Slog.w(TAG, "No BOOTCLASSPATH found!");
}
+ if (systemServerClassPath != null) {
+ String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
+ for (String element : systemServerClassPathElements) {
+ alreadyDexOpted.add(element);
+ }
+ } else {
+ Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
+ }
+
boolean didDexOptLibraryOrTool = false;
final List<String> allInstructionSets = getAllInstructionSets();
@@ -2920,7 +2921,8 @@ public class PackageManagerService extends IPackageManager.Stub {
findPreferredActivity(intent, resolvedType,
flags, query, 0, false, true, false, userId);
// Add the new activity as the last chosen for this filter
- addPreferredActivityInternal(filter, match, null, activity, false, userId);
+ addPreferredActivityInternal(filter, match, null, activity, false, userId,
+ "Setting last chosen");
}
@Override
@@ -3192,24 +3194,22 @@ public class PackageManagerService extends IPackageManager.Stub {
if (matches.get(i).getTargetUserId() == targetUserId) return true;
}
}
-
ArrayList<String> packageNames = null;
SparseArray<ArrayList<String>> fromSource =
mSettings.mCrossProfilePackageInfo.get(sourceUserId);
if (fromSource != null) {
packageNames = fromSource.get(targetUserId);
- }
- if (packageNames != null && packageNames.contains(intent.getPackage())) {
- return true;
- }
- // We need the package name, so we try to resolve with the loosest flags possible
- List<ResolveInfo> resolveInfos = mActivities.queryIntent(
- intent, resolvedType, PackageManager.GET_UNINSTALLED_PACKAGES, targetUserId);
- int count = resolveInfos.size();
- for (int i = 0; i < count; i++) {
- ResolveInfo resolveInfo = resolveInfos.get(i);
- if (packageNames.contains(resolveInfo.activityInfo.packageName)) {
- return true;
+ if (packageNames != null) {
+ // We need the package name, so we try to resolve with the loosest flags possible
+ List<ResolveInfo> resolveInfos = mActivities.queryIntent(intent, resolvedType,
+ PackageManager.GET_UNINSTALLED_PACKAGES, targetUserId);
+ int count = resolveInfos.size();
+ for (int i = 0; i < count; i++) {
+ ResolveInfo resolveInfo = resolveInfos.get(i);
+ if (packageNames.contains(resolveInfo.activityInfo.packageName)) {
+ return true;
+ }
+ }
}
}
return false;
@@ -3282,6 +3282,7 @@ public class PackageManagerService extends IPackageManager.Stub {
intent, resolvedType, flags, userId);
if (resolveInfo != null) {
result.add(resolveInfo);
+ Collections.sort(result, mResolvePrioritySorter);
}
return result;
}
@@ -4091,21 +4092,24 @@ public class PackageManagerService extends IPackageManager.Stub {
for (File file : files) {
final boolean isPackage = (isApkFile(file) || file.isDirectory())
- && !PackageInstallerService.isStageFile(file);
+ && !PackageInstallerService.isStageName(file.getName());
if (!isPackage) {
- // Ignore entries which are not apk's
+ // Ignore entries which are not packages
continue;
}
try {
- scanPackageLI(file, flags | PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);
+ scanPackageLI(file, flags | PackageParser.PARSE_MUST_BE_APK,
+ scanMode, currentTime, null);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
- // Don't mess around with apps in system partition.
+ // Delete invalid userdata apps
if ((flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
- // Delete the apk
- Slog.w(TAG, "Cleaning up failed install of " + file);
+ Slog.w(TAG, "Deleting invalid package at " + file);
+ if (file.isDirectory()) {
+ FileUtils.deleteContents(file);
+ }
file.delete();
}
}
@@ -5008,7 +5012,7 @@ public class PackageManagerService extends IPackageManager.Stub {
private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
String cpuAbiOverride = null;
- if (CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
+ if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
cpuAbiOverride = null;
} else if (abiOverride != null) {
cpuAbiOverride = abiOverride;
@@ -5512,7 +5516,8 @@ public class PackageManagerService extends IPackageManager.Stub {
// Warn if we've set an abiOverride for multi-lib packages..
// By definition, we need to copy both 32 and 64 bit libraries for
// such packages.
- if (pkg.cpuAbiOverride != null && !CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
+ if (pkg.cpuAbiOverride != null
+ && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
}
@@ -5522,7 +5527,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (isAsec) {
abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
} else {
- abi32 = copyNativeLibrariesForInternalApp(handle,
+ abi32 = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, useIsaSpecificSubdirs);
}
}
@@ -5534,7 +5539,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (isAsec) {
abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
} else {
- abi64 = copyNativeLibrariesForInternalApp(handle,
+ abi64 = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, useIsaSpecificSubdirs);
}
}
@@ -5573,8 +5578,8 @@ public class PackageManagerService extends IPackageManager.Stub {
if (isAsec) {
copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
} else {
- copyRet = copyNativeLibrariesForInternalApp(handle, nativeLibraryRoot, abiList,
- useIsaSpecificSubdirs);
+ copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle,
+ nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
}
if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
@@ -6457,58 +6462,6 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
- private static void createNativeLibrarySubdir(File path) throws IOException {
- if (!path.isDirectory()) {
- path.delete();
-
- if (!path.mkdir()) {
- throw new IOException("Cannot create " + path.getPath());
- }
-
- try {
- Os.chmod(path.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
- } catch (ErrnoException e) {
- throw new IOException("Cannot chmod native library directory "
- + path.getPath(), e);
- }
- } else if (!SELinux.restorecon(path)) {
- throw new IOException("Cannot set SELinux context for " + path.getPath());
- }
- }
-
- private static int copyNativeLibrariesForInternalApp(NativeLibraryHelper.Handle handle,
- final File nativeLibraryRoot, String[] abiList, boolean useIsaSubdir) throws IOException {
- createNativeLibrarySubdir(nativeLibraryRoot);
-
- /*
- * If this is an internal application or our nativeLibraryPath points to
- * the app-lib directory, unpack the libraries if necessary.
- */
- int abi = NativeLibraryHelper.findSupportedAbi(handle, abiList);
- if (abi >= 0) {
- /*
- * If we have a matching instruction set, construct a subdir under the native
- * library root that corresponds to this instruction set.
- */
- final String instructionSet = VMRuntime.getInstructionSet(abiList[abi]);
- final File subDir;
- if (useIsaSubdir) {
- final File isaSubdir = new File(nativeLibraryRoot, instructionSet);
- createNativeLibrarySubdir(isaSubdir);
- subDir = isaSubdir;
- } else {
- subDir = nativeLibraryRoot;
- }
-
- int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, subDir, abiList[abi]);
- if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
- return copyRet;
- }
- }
-
- return abi;
- }
-
private void killApplication(String pkgName, int appId, String reason) {
// Request the ActivityManager to kill the process(only for existing packages)
// so that we do not end up in a confused state while the user is still using the older
@@ -7829,19 +7782,19 @@ public class PackageManagerService extends IPackageManager.Stub {
verificationParams.setInstallerUid(uid);
final Message msg = mHandler.obtainMessage(INIT_COPY);
- msg.obj = new InstallParams(originFile, false, observer, filteredFlags,
+ msg.obj = new InstallParams(originFile, null, false, observer, filteredFlags,
installerPackageName, verificationParams, user, packageAbiOverride);
mHandler.sendMessage(msg);
}
- void installStage(String packageName, File stageDir, IPackageInstallObserver2 observer,
- InstallSessionParams params, String installerPackageName, int installerUid,
- UserHandle user) {
+ void installStage(String packageName, File stagedDir, String stagedCid,
+ IPackageInstallObserver2 observer, PackageInstaller.SessionParams params,
+ String installerPackageName, int installerUid, UserHandle user) {
final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
params.referrerUri, installerUid, null);
final Message msg = mHandler.obtainMessage(INIT_COPY);
- msg.obj = new InstallParams(stageDir, true, observer, params.installFlags,
+ msg.obj = new InstallParams(stagedDir, stagedCid, true, observer, params.installFlags,
installerPackageName, verifParams, user, params.abiOverride);
mHandler.sendMessage(msg);
}
@@ -8541,10 +8494,12 @@ public class PackageManagerService extends IPackageManager.Stub {
* file, or a cluster directory. This location may be untrusted.
*/
final File originFile;
+ final String originCid;
/**
- * Flag indicating that {@link #originFile} has already been staged,
- * meaning downstream users don't need to defensively copy the contents.
+ * Flag indicating that {@link #originFile} or {@link #originCid} has
+ * already been staged, meaning downstream users don't need to
+ * defensively copy the contents.
*/
boolean originStaged;
@@ -8557,11 +8512,12 @@ public class PackageManagerService extends IPackageManager.Stub {
final String packageAbiOverride;
boolean multiArch;
- InstallParams(File originFile, boolean originStaged, IPackageInstallObserver2 observer,
- int flags, String installerPackageName, VerificationParams verificationParams,
- UserHandle user, String packageAbiOverride) {
+ InstallParams(File originFile, String originCid, boolean originStaged,
+ IPackageInstallObserver2 observer, int flags, String installerPackageName,
+ VerificationParams verificationParams, UserHandle user, String packageAbiOverride) {
super(user);
- this.originFile = Preconditions.checkNotNull(originFile);
+ this.originFile = originFile;
+ this.originCid = originCid;
this.originStaged = originStaged;
this.observer = observer;
this.flags = flags;
@@ -8572,9 +8528,8 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public String toString() {
- return "InstallParams{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + originFile + "}";
+ return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
+ + " file=" + originFile + " cid=" + originCid + "}";
}
public ManifestDigest getManifestDigest() {
@@ -8643,15 +8598,6 @@ public class PackageManagerService extends IPackageManager.Stub {
return pkgLite.recommendedInstallLocation;
}
- private long getMemoryLowThreshold() {
- final DeviceStorageMonitorInternal
- dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
- if (dsm == null) {
- return 0L;
- }
- return dsm.getMemoryLowThreshold();
- }
-
/*
* Invoke remote method to get package information and install
* location values. Override install location based on default
@@ -8660,6 +8606,20 @@ public class PackageManagerService extends IPackageManager.Stub {
*/
public void handleStartCopy() throws RemoteException {
int ret = PackageManager.INSTALL_SUCCEEDED;
+
+ // If we're already staged, we've firmly committed to an install location
+ if (originStaged) {
+ if (originFile != null) {
+ flags |= PackageManager.INSTALL_INTERNAL;
+ flags &= ~PackageManager.INSTALL_EXTERNAL;
+ } else if (originCid != null) {
+ flags |= PackageManager.INSTALL_EXTERNAL;
+ flags &= ~PackageManager.INSTALL_INTERNAL;
+ } else {
+ throw new IllegalStateException("Invalid stage location");
+ }
+ }
+
final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0;
PackageInfoLite pkgLite = null;
@@ -8669,14 +8629,9 @@ public class PackageManagerService extends IPackageManager.Stub {
Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
} else {
- final long lowThreshold = getMemoryLowThreshold();
- if (lowThreshold == 0L) {
- Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
- }
-
// Remote call to find out default install location
final String originPath = originFile.getAbsolutePath();
- pkgLite = mContainerService.getMinimalPackageInfo(originPath, flags, lowThreshold,
+ pkgLite = mContainerService.getMinimalPackageInfo(originPath, flags,
packageAbiOverride);
// Keep track of whether this package is a multiArch package until
// we perform a full scan of it. We need to do this because we might
@@ -8688,14 +8643,21 @@ public class PackageManagerService extends IPackageManager.Stub {
* If we have too little free space, try to free cache
* before giving up.
*/
- if (pkgLite.recommendedInstallLocation
+ if (!originStaged && pkgLite.recommendedInstallLocation
== PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
- final long size = mContainerService.calculateInstalledSize(
+ // TODO: focus freeing disk space on the target device
+ final StorageManager storage = StorageManager.from(mContext);
+ final long lowThreshold = storage.getStorageLowBytes(
+ Environment.getDataDirectory());
+
+ final long sizeBytes = mContainerService.calculateInstalledSize(
originPath, isForwardLocked(), packageAbiOverride);
- if (mInstaller.freeCache(size + lowThreshold) >= 0) {
+
+ if (mInstaller.freeCache(sizeBytes + lowThreshold) >= 0) {
pkgLite = mContainerService.getMinimalPackageInfo(originPath, flags,
- lowThreshold, packageAbiOverride);
+ packageAbiOverride);
}
+
/*
* The cache free must have deleted the file we
* downloaded to install.
@@ -9225,24 +9187,11 @@ public class PackageManagerService extends IPackageManager.Stub {
}
boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
- final long lowThreshold;
+ final long sizeBytes = imcs.calculateInstalledSize(originFile.getAbsolutePath(),
+ isFwdLocked(), abiOverride);
- final DeviceStorageMonitorInternal
- dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
- if (dsm == null) {
- Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
- lowThreshold = 0L;
- } else {
- if (dsm.isMemoryLow()) {
- Log.w(TAG, "Memory is reported as being too low; aborting package install");
- return false;
- }
-
- lowThreshold = dsm.getMemoryLowThreshold();
- }
-
- return imcs.checkInternalFreeStorage(originFile.getAbsolutePath(), isFwdLocked(),
- lowThreshold);
+ final StorageManager storage = StorageManager.from(mContext);
+ return (sizeBytes <= storage.getStorageBytesUntilLow(Environment.getDataDirectory()));
}
int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
@@ -9254,7 +9203,7 @@ public class PackageManagerService extends IPackageManager.Stub {
resourceFile = originFile;
} else {
try {
- final File tempDir = mInstallerService.allocateSessionDir();
+ final File tempDir = mInstallerService.allocateInternalStageDirLegacy();
codeFile = tempDir;
resourceFile = tempDir;
} catch (IOException e) {
@@ -9291,49 +9240,11 @@ public class PackageManagerService extends IPackageManager.Stub {
NativeLibraryHelper.Handle handle = null;
try {
handle = NativeLibraryHelper.Handle.create(codeFile);
- if (multiArch) {
- // Warn if we've set an abiOverride for multi-lib packages..
- // By definition, we need to copy both 32 and 64 bit libraries for
- // such packages.
- if (abiOverride != null && !CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
- Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
- }
-
- int copyRet = PackageManager.NO_NATIVE_LIBRARIES;
- if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
- copyRet = copyNativeLibrariesForInternalApp(handle, libraryRoot,
- Build.SUPPORTED_32_BIT_ABIS, true /* use isa specific subdirs */);
- maybeThrowExceptionForMultiArchCopy("Failure copying 32 bit native libraries", copyRet);
- }
-
- if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
- copyRet = copyNativeLibrariesForInternalApp(handle, libraryRoot,
- Build.SUPPORTED_64_BIT_ABIS, true /* use isa specific subdirs */);
- maybeThrowExceptionForMultiArchCopy("Failure copying 64 bit native libraries", copyRet);
- }
- } else {
- final String cpuAbiOverride = deriveAbiOverride(this.abiOverride, null /* package setting */);
- String[] abiList = (cpuAbiOverride != null) ?
- new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
-
- if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
- NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
- abiList = Build.SUPPORTED_32_BIT_ABIS;
- }
-
- int copyRet = copyNativeLibrariesForInternalApp(handle, libraryRoot, abiList,
- true /* use isa specific subdirs */);
- if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
- Slog.w(TAG, "Failure copying native libraries [errorCode=" + copyRet + "]");
- return copyRet;
- }
- }
+ ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, libraryRoot,
+ abiOverride, multiArch);
} catch (IOException e) {
Slog.e(TAG, "Copying native libraries failed", e);
ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
- } catch (PackageManagerException pme) {
- Slog.e(TAG, "Copying native libraries failed", pme);
- ret = pme.error;
} finally {
IoUtils.closeQuietly(handle);
}
@@ -9508,8 +9419,6 @@ public class PackageManagerService extends IPackageManager.Stub {
* renaming logic.
*/
class AsecInstallArgs extends InstallArgs {
- // TODO: teach about handling cluster directories
-
static final String RES_FILE_NAME = "pkg.apk";
static final String PUBLIC_RES_FILE_NAME = "res.zip";
@@ -9532,12 +9441,17 @@ public class PackageManagerService extends IPackageManager.Stub {
super(null, false, null, (isExternal ? INSTALL_EXTERNAL : 0)
| (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
instructionSets, null, isMultiArch);
+ // Hackily pretend we're still looking at a full code path
+ if (!fullCodePath.endsWith(RES_FILE_NAME)) {
+ fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
+ }
+
// Extract cid from fullCodePath
int eidx = fullCodePath.lastIndexOf("/");
String subStr1 = fullCodePath.substring(0, eidx);
int sidx = subStr1.lastIndexOf("/");
cid = subStr1.substring(sidx+1, eidx);
- setCachePath(subStr1);
+ setMountPath(subStr1);
}
AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked,
@@ -9546,7 +9460,7 @@ public class PackageManagerService extends IPackageManager.Stub {
| (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
instructionSets, null, isMultiArch);
this.cid = cid;
- setCachePath(PackageHelper.getSdDir(cid));
+ setMountPath(PackageHelper.getSdDir(cid));
}
/** New install from existing */
@@ -9559,12 +9473,22 @@ public class PackageManagerService extends IPackageManager.Stub {
}
void createCopyFile() {
- cid = getTempContainerId();
+ cid = mInstallerService.allocateExternalStageCidLegacy();
}
boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
- return imcs.checkExternalFreeStorage(originFile.getAbsolutePath(), isFwdLocked(),
+ final long sizeBytes = imcs.calculateInstalledSize(packagePath, isFwdLocked(),
abiOverride);
+
+ final File target;
+ if (isExternal()) {
+ target = new UserEnvironment(UserHandle.USER_OWNER).getExternalStorageDirectory();
+ } else {
+ target = Environment.getDataDirectory();
+ }
+
+ final StorageManager storage = StorageManager.from(mContext);
+ return (sizeBytes <= storage.getStorageBytesUntilLow(target));
}
private final boolean isExternal() {
@@ -9572,6 +9496,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
+ // TODO: if already staged, we only need to extract native code
if (temp) {
createCopyFile();
} else {
@@ -9582,12 +9507,12 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageHelper.destroySdDir(cid);
}
- final String newCachePath = imcs.copyPackageToContainer(
+ final String newMountPath = imcs.copyPackageToContainer(
originFile.getAbsolutePath(), cid, getEncryptKey(), isExternal(),
isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
- if (newCachePath != null) {
- setCachePath(newCachePath);
+ if (newMountPath != null) {
+ setMountPath(newMountPath);
return PackageManager.INSTALL_SUCCEEDED;
} else {
return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
@@ -9616,10 +9541,10 @@ public class PackageManagerService extends IPackageManager.Stub {
} else {
boolean mounted = PackageHelper.isContainerMounted(cid);
if (!mounted) {
- String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(),
+ String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
Process.SYSTEM_UID);
- if (newCachePath != null) {
- setCachePath(newCachePath);
+ if (newMountPath != null) {
+ setMountPath(newMountPath);
} else {
return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
}
@@ -9630,7 +9555,7 @@ public class PackageManagerService extends IPackageManager.Stub {
boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
- String newCachePath = null;
+ String newMountPath = null;
if (PackageHelper.isContainerMounted(cid)) {
// Unmount the container
if (!PackageHelper.unMountSdDir(cid)) {
@@ -9655,46 +9580,59 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (!PackageHelper.isContainerMounted(newCacheId)) {
Slog.w(TAG, "Mounting container " + newCacheId);
- newCachePath = PackageHelper.mountSdDir(newCacheId,
+ newMountPath = PackageHelper.mountSdDir(newCacheId,
getEncryptKey(), Process.SYSTEM_UID);
} else {
- newCachePath = PackageHelper.getSdDir(newCacheId);
+ newMountPath = PackageHelper.getSdDir(newCacheId);
}
- if (newCachePath == null) {
+ if (newMountPath == null) {
Slog.w(TAG, "Failed to get cache path for " + newCacheId);
return false;
}
Log.i(TAG, "Succesfully renamed " + cid +
" to " + newCacheId +
- " at new path: " + newCachePath);
+ " at new path: " + newMountPath);
cid = newCacheId;
- setCachePath(newCachePath);
- // TODO: extend to support split APKs
- pkg.codePath = getCodePath();
- pkg.baseCodePath = getCodePath();
- pkg.splitCodePaths = null;
-
- pkg.applicationInfo.setCodePath(getCodePath());
- pkg.applicationInfo.setBaseCodePath(getCodePath());
- pkg.applicationInfo.setSplitCodePaths(null);
- pkg.applicationInfo.setResourcePath(getResourcePath());
- pkg.applicationInfo.setBaseResourcePath(getResourcePath());
- pkg.applicationInfo.setSplitResourcePaths(null);
+ final File beforeCodeFile = new File(packagePath);
+ setMountPath(newMountPath);
+ final File afterCodeFile = new File(packagePath);
+
+ // Reflect the rename in scanned details
+ pkg.codePath = afterCodeFile.getAbsolutePath();
+ pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
+ pkg.baseCodePath);
+ pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
+ pkg.splitCodePaths);
+
+ // Reflect the rename in app info
+ pkg.applicationInfo.setCodePath(pkg.codePath);
+ pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
+ pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
+ pkg.applicationInfo.setResourcePath(pkg.codePath);
+ pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
+ pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
return true;
}
- private void setCachePath(String newCachePath) {
- File cachePath = new File(newCachePath);
- legacyNativeLibraryDir = new File(cachePath, LIB_DIR_NAME).getPath();
- packagePath = new File(cachePath, RES_FILE_NAME).getPath();
+ private void setMountPath(String mountPath) {
+ final File mountFile = new File(mountPath);
- if (isFwdLocked()) {
- resourcePath = new File(cachePath, PUBLIC_RES_FILE_NAME).getPath();
+ final File monolithicFile = new File(mountFile, RES_FILE_NAME);
+ if (monolithicFile.exists()) {
+ packagePath = monolithicFile.getAbsolutePath();
+ if (isFwdLocked()) {
+ resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
+ } else {
+ resourcePath = packagePath;
+ }
} else {
+ packagePath = mountFile.getAbsolutePath();
resourcePath = packagePath;
}
+
+ legacyNativeLibraryDir = new File(mountFile, LIB_DIR_NAME).getAbsolutePath();
}
int doPostInstall(int status, int uid) {
@@ -9733,23 +9671,43 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageHelper.destroySdDir(cid);
}
- void cleanUpResourcesLI() {
- String sourceFile = getCodePath();
- // Remove dex file
- if (instructionSets == null) {
- throw new IllegalStateException("instructionSet == null");
- }
- String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
- for (String dexCodeInstructionSet : dexCodeInstructionSets) {
- int retCode = mInstaller.rmdex(sourceFile, dexCodeInstructionSet);
- if (retCode < 0) {
- Slog.w(TAG, "Couldn't remove dex file for package: "
- + " at location "
- + sourceFile.toString() + ", retcode=" + retCode);
- // we don't consider this to be a failure of the core package deletion
+ private List<String> getAllCodePaths() {
+ final File codeFile = new File(getCodePath());
+ if (codeFile != null && codeFile.exists()) {
+ try {
+ final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
+ return pkg.getAllCodePaths();
+ } catch (PackageParserException e) {
+ // Ignored; we tried our best
}
}
+ return Collections.EMPTY_LIST;
+ }
+
+ void cleanUpResourcesLI() {
+ // Enumerate all code paths before deleting
+ cleanUpResourcesLI(getAllCodePaths());
+ }
+
+ private void cleanUpResourcesLI(List<String> allCodePaths) {
cleanUp();
+
+ if (!allCodePaths.isEmpty()) {
+ if (instructionSets == null) {
+ throw new IllegalStateException("instructionSet == null");
+ }
+ String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
+ for (String codePath : allCodePaths) {
+ for (String dexCodeInstructionSet : dexCodeInstructionSets) {
+ int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
+ if (retCode < 0) {
+ Slog.w(TAG, "Couldn't remove dex file for package: "
+ + " at location " + codePath + ", retcode=" + retCode);
+ // we don't consider this to be a failure of the core package deletion
+ }
+ }
+ }
+ }
}
boolean matchContainer(String app) {
@@ -9764,16 +9722,19 @@ public class PackageManagerService extends IPackageManager.Stub {
}
boolean doPostDeleteLI(boolean delete) {
- boolean ret = false;
+ if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
+ final List<String> allCodePaths = getAllCodePaths();
boolean mounted = PackageHelper.isContainerMounted(cid);
if (mounted) {
// Unmount first
- ret = PackageHelper.unMountSdDir(cid);
+ if (PackageHelper.unMountSdDir(cid)) {
+ mounted = false;
+ }
}
- if (ret && delete) {
- cleanUpResourcesLI();
+ if (!mounted && delete) {
+ cleanUpResourcesLI(allCodePaths);
}
- return ret;
+ return !mounted;
}
@Override
@@ -10960,6 +10921,7 @@ public class PackageManagerService extends IPackageManager.Stub {
outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
getAppDexInstructionSets(ps), isMultiArch(ps));
+ if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
}
return true;
}
@@ -11462,11 +11424,13 @@ public class PackageManagerService extends IPackageManager.Stub {
@Override
public void addPreferredActivity(IntentFilter filter, int match,
ComponentName[] set, ComponentName activity, int userId) {
- addPreferredActivityInternal(filter, match, set, activity, true, userId);
+ addPreferredActivityInternal(filter, match, set, activity, true, userId,
+ "Adding preferred");
}
private void addPreferredActivityInternal(IntentFilter filter, int match,
- ComponentName[] set, ComponentName activity, boolean always, int userId) {
+ ComponentName[] set, ComponentName activity, boolean always, int userId,
+ String opname) {
// writer
int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId, true, "add preferred activity");
@@ -11488,10 +11452,11 @@ public class PackageManagerService extends IPackageManager.Stub {
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
}
- Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :");
+ PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
+ Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
+ + userId + ":");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
- mSettings.editPreferredActivitiesLPw(userId).addFilter(
- new PreferredActivity(filter, match, set, activity, always));
+ pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
mSettings.writePackageRestrictionsLPr(userId);
}
}
@@ -11514,7 +11479,6 @@ public class PackageManagerService extends IPackageManager.Stub {
final int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId, true, "replace preferred activity");
- final int callingUserId = UserHandle.getUserId(callingUid);
synchronized (mPackages) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
@@ -11529,30 +11493,63 @@ public class PackageManagerService extends IPackageManager.Stub {
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
}
- PreferredIntentResolver pir = mSettings.mPreferredActivities.get(callingUserId);
+ PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
if (pir != null) {
- Intent intent = new Intent(filter.getAction(0)).addCategory(filter.getCategory(0));
- if (filter.countDataSchemes() == 1) {
- Uri.Builder builder = new Uri.Builder();
- builder.scheme(filter.getDataScheme(0));
- intent.setData(builder.build());
- }
- List<PreferredActivity> matches = pir.queryIntent(
- intent, null, true, callingUserId);
- if (DEBUG_PREFERRED) {
- Slog.i(TAG, matches.size() + " preferred matches for " + intent);
- }
- for (int i = 0; i < matches.size(); i++) {
- PreferredActivity pa = matches.get(i);
+ // Get all of the existing entries that exactly match this filter.
+ ArrayList<PreferredActivity> existing = pir.findFilters(filter);
+ if (existing != null && existing.size() == 1) {
+ PreferredActivity cur = existing.get(0);
if (DEBUG_PREFERRED) {
- Slog.i(TAG, "Removing preferred activity "
- + pa.mPref.mComponent + ":");
+ Slog.i(TAG, "Checking replace of preferred:");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
+ if (!cur.mPref.mAlways) {
+ Slog.i(TAG, " -- CUR; not mAlways!");
+ } else {
+ Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch);
+ Slog.i(TAG, " -- CUR: mSet="
+ + Arrays.toString(cur.mPref.mSetComponents));
+ Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent);
+ Slog.i(TAG, " -- NEW: mMatch="
+ + (match&IntentFilter.MATCH_CATEGORY_MASK));
+ Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set));
+ Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString());
+ }
+ }
+ if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
+ && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
+ && cur.mPref.sameSet(set)) {
+ if (DEBUG_PREFERRED) {
+ Slog.i(TAG, "Replacing with same preferred activity "
+ + cur.mPref.mShortComponent + " for user "
+ + userId + ":");
+ filter.dump(new LogPrinter(Log.INFO, TAG), " ");
+ } else {
+ Slog.i(TAG, "Replacing with same preferred activity "
+ + cur.mPref.mShortComponent + " for user "
+ + userId);
+ }
+ return;
+ }
+ }
+
+ if (existing != null) {
+ if (DEBUG_PREFERRED) {
+ Slog.i(TAG, existing.size() + " existing preferred matches for:");
+ filter.dump(new LogPrinter(Log.INFO, TAG), " ");
+ }
+ for (int i = 0; i < existing.size(); i++) {
+ PreferredActivity pa = existing.get(i);
+ if (DEBUG_PREFERRED) {
+ Slog.i(TAG, "Removing existing preferred activity "
+ + pa.mPref.mComponent + ":");
+ pa.dump(new LogPrinter(Log.INFO, TAG), " ");
+ }
+ pir.removeFilter(pa);
}
- pir.removeFilter(pa);
}
}
- addPreferredActivityInternal(filter, match, set, activity, true, callingUserId);
+ addPreferredActivityInternal(filter, match, set, activity, true, userId,
+ "Replacing preferred");
}
}
@@ -12610,7 +12607,7 @@ public class PackageManagerService extends IPackageManager.Stub {
private boolean mMediaMounted = false;
- private String getEncryptKey() {
+ static String getEncryptKey() {
try {
String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
SD_ENCRYPTION_KEYSTORE_NAME);
@@ -12630,30 +12627,6 @@ public class PackageManagerService extends IPackageManager.Stub {
Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
return null;
}
-
- }
-
- /* package */static String getTempContainerId() {
- int tmpIdx = 1;
- String list[] = PackageHelper.getSecureContainerList();
- if (list != null) {
- for (final String name : list) {
- // Ignore null and non-temporary container entries
- if (name == null || !name.startsWith(mTempContainerPrefix)) {
- continue;
- }
-
- String subStr = name.substring(mTempContainerPrefix.length());
- try {
- int cid = Integer.parseInt(subStr);
- if (cid >= tmpIdx) {
- tmpIdx = cid + 1;
- }
- } catch (NumberFormatException e) {
- }
- }
- }
- return mTempContainerPrefix + tmpIdx;
}
/*
@@ -12711,31 +12684,27 @@ public class PackageManagerService extends IPackageManager.Stub {
*/
private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
boolean externalStorage) {
- // Collection of uids
- int uidArr[] = null;
- // Collection of stale containers
- HashSet<String> removeCids = new HashSet<String>();
- // Collection of packages on external media with valid containers.
- HashMap<AsecInstallArgs, String> processCids = new HashMap<AsecInstallArgs, String>();
- // Get list of secure containers.
- final String list[] = PackageHelper.getSecureContainerList();
- if (list == null || list.length == 0) {
- Log.i(TAG, "No secure containers on sdcard");
+ ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
+ int[] uidArr = EmptyArray.INT;
+
+ final String[] list = PackageHelper.getSecureContainerList();
+ if (ArrayUtils.isEmpty(list)) {
+ Log.i(TAG, "No secure containers found");
} else {
// Process list of secure containers and categorize them
// as active or stale based on their package internal state.
- int uidList[] = new int[list.length];
- int num = 0;
+
// reader
synchronized (mPackages) {
for (String cid : list) {
+ // Leave stages untouched for now; installer service owns them
+ if (PackageInstallerService.isStageName(cid)) continue;
+
if (DEBUG_SD_INSTALL)
Log.i(TAG, "Processing container " + cid);
String pkgName = getAsecPackageName(cid);
if (pkgName == null) {
- if (DEBUG_SD_INSTALL)
- Log.i(TAG, "Container : " + cid + " stale");
- removeCids.add(cid);
+ Slog.i(TAG, "Found stale container " + cid + " with no package name");
continue;
}
if (DEBUG_SD_INSTALL)
@@ -12743,8 +12712,7 @@ public class PackageManagerService extends IPackageManager.Stub {
final PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps == null) {
- Log.i(TAG, "Deleting container with no matching settings " + cid);
- removeCids.add(cid);
+ Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
continue;
}
@@ -12760,7 +12728,8 @@ public class PackageManagerService extends IPackageManager.Stub {
getAppDexInstructionSets(ps), isForwardLocked(ps), isMultiArch(ps));
// The package status is changed only if the code path
// matches between settings and the container id.
- if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) {
+ if (ps.codePathString != null
+ && ps.codePathString.startsWith(args.getCodePath())) {
if (DEBUG_SD_INSTALL) {
Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
+ " at code path: " + ps.codePathString);
@@ -12770,35 +12739,25 @@ public class PackageManagerService extends IPackageManager.Stub {
processCids.put(args, ps.codePathString);
final int uid = ps.appId;
if (uid != -1) {
- uidList[num++] = uid;
+ uidArr = ArrayUtils.appendInt(uidArr, uid);
}
} else {
- Log.i(TAG, "Deleting stale container for " + cid);
- removeCids.add(cid);
+ Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
+ + ps.codePathString);
}
}
}
- if (num > 0) {
- // Sort uid list
- Arrays.sort(uidList, 0, num);
- // Throw away duplicates
- uidArr = new int[num];
- uidArr[0] = uidList[0];
- int di = 0;
- for (int i = 1; i < num; i++) {
- if (uidList[i - 1] != uidList[i]) {
- uidArr[di++] = uidList[i];
- }
- }
- }
+ Arrays.sort(uidArr);
}
+
// Process packages with valid entries.
if (isMounted) {
if (DEBUG_SD_INSTALL)
Log.i(TAG, "Loading packages");
- loadMediaPackages(processCids, uidArr, removeCids);
+ loadMediaPackages(processCids, uidArr);
startCleaningPackages();
+ mInstallerService.onSecureContainersAvailable();
} else {
if (DEBUG_SD_INSTALL)
Log.i(TAG, "Unloading packages");
@@ -12806,8 +12765,8 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
- private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
- ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
+ private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
+ ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
int size = pkgList.size();
if (size > 0) {
// Send broadcasts here
@@ -12832,11 +12791,10 @@ public class PackageManagerService extends IPackageManager.Stub {
* the cid is added to list of removeCids. We currently don't delete stale
* containers.
*/
- private void loadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[],
- HashSet<String> removeCids) {
+ private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) {
ArrayList<String> pkgList = new ArrayList<String>();
Set<AsecInstallArgs> keys = processCids.keySet();
- boolean doGc = false;
+
for (AsecInstallArgs args : keys) {
String codePath = processCids.get(args);
if (DEBUG_SD_INSTALL)
@@ -12850,7 +12808,7 @@ public class PackageManagerService extends IPackageManager.Stub {
continue;
}
// Check code path here.
- if (codePath == null || !codePath.equals(args.getCodePath())) {
+ if (codePath == null || !codePath.startsWith(args.getCodePath())) {
Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
+ " does not match one in settings " + codePath);
continue;
@@ -12864,7 +12822,6 @@ public class PackageManagerService extends IPackageManager.Stub {
parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
}
- doGc = true;
synchronized (mInstallLock) {
PackageParser.Package pkg = null;
try {
@@ -12894,9 +12851,7 @@ public class PackageManagerService extends IPackageManager.Stub {
} finally {
if (retCode != PackageManager.INSTALL_SUCCEEDED) {
- // Don't destroy container here. Wait till gc clears things
- // up.
- removeCids.add(args.cid);
+ Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
}
}
}
@@ -12931,21 +12886,6 @@ public class PackageManagerService extends IPackageManager.Stub {
if (pkgList.size() > 0) {
sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
}
- // Force gc to avoid any stale parser references that we might have.
- if (doGc) {
- Runtime.getRuntime().gc();
- }
- // List stale containers and destroy stale temporary containers.
- if (removeCids != null) {
- for (String cid : removeCids) {
- if (cid.startsWith(mTempContainerPrefix)) {
- Log.i(TAG, "Destroying stale temporary container " + cid);
- PackageHelper.destroySdDir(cid);
- } else {
- Log.w(TAG, "Container " + cid + " is stale");
- }
- }
- }
}
/*
@@ -12969,7 +12909,7 @@ public class PackageManagerService extends IPackageManager.Stub {
* that we always have to post this message if status has been requested no
* matter what.
*/
- private void unloadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[],
+ private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
final boolean reportStatus) {
if (DEBUG_SD_INSTALL)
Log.i(TAG, "unloading media packages");