summaryrefslogtreecommitdiff
path: root/core/java/android/app/ActivityThread.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/app/ActivityThread.java')
-rw-r--r--core/java/android/app/ActivityThread.java525
1 files changed, 229 insertions, 296 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f71e9fd033da..46233d7a0688 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -218,8 +218,6 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.net.InetAddress;
@@ -230,7 +228,6 @@ import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -419,16 +416,6 @@ public final class ActivityThread extends ClientTransactionHandler
@GuardedBy("mResourcesManager")
@UnsupportedAppUsage
final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages = new ArrayMap<>();
-
- @GuardedBy("mResourcesManager")
- private final ArrayMap<List<String>, WeakReference<LoadedApk>> mPackageNonAMS =
- new ArrayMap<>();
- @GuardedBy("mResourcesManager")
- private final ArrayMap<List<String>, WeakReference<LoadedApk>> mResourcePackagesNonAMS =
- new ArrayMap<>();
- @GuardedBy("mResourcesManager")
- private final ReferenceQueue<LoadedApk> mPackageRefQueue = new ReferenceQueue<>();
-
@GuardedBy("mResourcesManager")
final ArrayList<ActivityClientRecord> mRelaunchingActivities = new ArrayList<>();
@GuardedBy("mResourcesManager")
@@ -2384,229 +2371,6 @@ public final class ActivityThread extends ClientTransactionHandler
return mH;
}
- /**
- * If {@code retainReferences} is false, prunes all {@link LoadedApk} representing any of the
- * specified packages from the package caches.
- *
- * @return whether the cache contains a loaded apk representing any of the specified packages
- */
- private boolean clearCachedApks() {
- synchronized (mResourcesManager) {
- Reference<? extends LoadedApk> enqueuedRef = mPackageRefQueue.poll();
- if (enqueuedRef == null) {
- return false;
- }
-
- final HashSet<Reference<? extends LoadedApk>> deadReferences = new HashSet<>();
- for (; enqueuedRef != null; enqueuedRef = mPackageRefQueue.poll()) {
- deadReferences.add(enqueuedRef);
- }
-
- return cleanWeakMapValues(mPackages, deadReferences)
- || cleanWeakMapValues(mResourcePackages, deadReferences)
- || cleanWeakMapValues(mPackageNonAMS, deadReferences)
- || cleanWeakMapValues(mResourcePackages, deadReferences);
- }
- }
-
- private static <K> boolean cleanWeakMapValues(ArrayMap<K, WeakReference<LoadedApk>> map,
- HashSet<Reference<? extends LoadedApk>> deadReferences) {
- boolean hasPkgInfo = false;
- for (int i = map.size() - 1; i >= 0; i--) {
- if (deadReferences.contains(map.valueAt(i))) {
- map.removeAt(i);
- hasPkgInfo = true;
- }
- }
- return hasPkgInfo;
- }
-
- /**
- * Retrieves the previously cached {@link LoadedApk} that was created/updated with the most
- * recent {@link ApplicationInfo} sent from the activity manager service.
- */
- @Nullable
- private LoadedApk peekLatestCachedApkFromAMS(@NonNull String packageName, boolean includeCode) {
- synchronized (mResourcesManager) {
- WeakReference<LoadedApk> ref;
- if (includeCode) {
- return ((ref = mPackages.get(packageName)) != null) ? ref.get() : null;
- } else {
- return ((ref = mResourcePackages.get(packageName)) != null) ? ref.get() : null;
- }
- }
- }
-
- /**
- * Updates the previously cached {@link LoadedApk} that was created/updated using an
- * {@link ApplicationInfo} sent from activity manager service.
- *
- * If {@code appInfo} is null, the most up-to-date {@link ApplicationInfo} will be fetched and
- * used to update the cached package; otherwise, the specified app info will be used.
- */
- private boolean updateLatestCachedApkFromAMS(@NonNull String packageName,
- @Nullable ApplicationInfo appInfo, boolean updateActivityRecords) {
- final LoadedApk[] loadedPackages = new LoadedApk[]{
- peekLatestCachedApkFromAMS(packageName, true),
- peekLatestCachedApkFromAMS(packageName, false)
- };
-
- try {
- if (appInfo == null) {
- appInfo = sPackageManager.getApplicationInfo(
- packageName, PackageManager.GET_SHARED_LIBRARY_FILES,
- UserHandle.myUserId());
- }
- } catch (RemoteException e) {
- Slog.v(TAG, "Failed to get most recent app info for '" + packageName + "'", e);
- return false;
- }
-
- boolean hasPackage = false;
- final String[] oldResDirs = new String[loadedPackages.length];
- for (int i = loadedPackages.length - 1; i >= 0; i--) {
- final LoadedApk loadedPackage = loadedPackages[i];
- if (loadedPackage == null) {
- continue;
- }
-
- // If the package is being updated, yet it still has a valid LoadedApk object, the
- // package was updated with PACKAGE_REMOVED_DONT_KILL. Adjust it's internal references
- // to the application info and resources.
- hasPackage = true;
- if (updateActivityRecords && mActivities.size() > 0) {
- for (ActivityClientRecord ar : mActivities.values()) {
- if (ar.activityInfo.applicationInfo.packageName.equals(packageName)) {
- ar.activityInfo.applicationInfo = appInfo;
- ar.packageInfo = loadedPackage;
- }
- }
- }
-
- updateLoadedApk(loadedPackage, appInfo);
- oldResDirs[i] = loadedPackage.getResDir();
- }
- if (hasPackage) {
- synchronized (mResourcesManager) {
- mResourcesManager.applyNewResourceDirs(appInfo, oldResDirs);
- }
- }
- return hasPackage;
- }
-
- private static List<String> makeNonAMSKey(@NonNull ApplicationInfo appInfo) {
- final List<String> paths = new ArrayList<>();
- paths.add(appInfo.sourceDir);
- if (appInfo.resourceDirs != null) {
- for (String path : appInfo.resourceDirs) {
- paths.add(path);
- }
- }
- return paths;
- }
-
- /**
- * Retrieves the previously cached {@link LoadedApk}.
- *
- * If {@code isAppInfoFromAMS} is true, then {@code appInfo} will be used to update the paths
- * of the previously cached {@link LoadedApk} that was created/updated using an
- * {@link ApplicationInfo} sent from activity manager service.
- */
- @Nullable
- private LoadedApk retrieveCachedApk(@NonNull ApplicationInfo appInfo, boolean includeCode,
- boolean isAppInfoFromAMS) {
- if (UserHandle.myUserId() != UserHandle.getUserId(appInfo.uid)) {
- // Caching not supported across users.
- return null;
- }
-
- if (isAppInfoFromAMS) {
- LoadedApk loadedPackage = peekLatestCachedApkFromAMS(appInfo.packageName, includeCode);
- if (loadedPackage != null) {
- updateLoadedApk(loadedPackage, appInfo);
- }
- return loadedPackage;
- }
-
- synchronized (mResourcesManager) {
- WeakReference<LoadedApk> ref;
- if (includeCode) {
- return ((ref = mPackageNonAMS.get(makeNonAMSKey(appInfo))) != null)
- ? ref.get() : null;
- } else {
- return ((ref = mResourcePackagesNonAMS.get(makeNonAMSKey(appInfo))) != null)
- ? ref.get() : null;
- }
- }
- }
-
- private static boolean isLoadedApkResourceDirsUpToDate(LoadedApk loadedApk,
- ApplicationInfo appInfo) {
- boolean baseDirsUpToDate = loadedApk.getResDir().equals(appInfo.sourceDir);
- boolean resourceDirsUpToDate = Arrays.equals(
- ArrayUtils.defeatNullable(appInfo.resourceDirs),
- ArrayUtils.defeatNullable(loadedApk.getOverlayDirs()));
- boolean overlayPathsUpToDate = Arrays.equals(
- ArrayUtils.defeatNullable(appInfo.overlayPaths),
- ArrayUtils.defeatNullable(loadedApk.getOverlayPaths()));
-
- return (loadedApk.mResources == null || loadedApk.mResources.getAssets().isUpToDate())
- && baseDirsUpToDate && resourceDirsUpToDate && overlayPathsUpToDate;
- }
-
- private void updateLoadedApk(@NonNull LoadedApk loadedPackage,
- @NonNull ApplicationInfo appInfo) {
- if (isLoadedApkResourceDirsUpToDate(loadedPackage, appInfo)) {
- return;
- }
-
- final List<String> oldPaths = new ArrayList<>();
- LoadedApk.makePaths(this, appInfo, oldPaths);
- loadedPackage.updateApplicationInfo(appInfo, oldPaths);
- }
-
- @Nullable
- private LoadedApk createLoadedPackage(@NonNull ApplicationInfo appInfo,
- @Nullable CompatibilityInfo compatInfo, @Nullable ClassLoader baseLoader,
- boolean securityViolation, boolean includeCode, boolean registerPackage,
- boolean isAppInfoFromAMS) {
- final LoadedApk packageInfo =
- new LoadedApk(this, appInfo, compatInfo, baseLoader,
- securityViolation, includeCode
- && (appInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
-
- if (mSystemThread && "android".equals(appInfo.packageName)) {
- packageInfo.installSystemApplicationInfo(appInfo,
- getSystemContext().mPackageInfo.getClassLoader());
- }
-
- if (UserHandle.myUserId() != UserHandle.getUserId(appInfo.uid)) {
- // Caching not supported across users
- return packageInfo;
- }
-
- synchronized (mResourcesManager) {
- if (includeCode) {
- if (isAppInfoFromAMS) {
- mPackages.put(appInfo.packageName,
- new WeakReference<>(packageInfo, mPackageRefQueue));
- } else {
- mPackageNonAMS.put(makeNonAMSKey(appInfo),
- new WeakReference<>(packageInfo, mPackageRefQueue));
- }
- } else {
- if (isAppInfoFromAMS) {
- mResourcePackages.put(appInfo.packageName,
- new WeakReference<>(packageInfo, mPackageRefQueue));
- } else {
- mResourcePackagesNonAMS.put(makeNonAMSKey(appInfo),
- new WeakReference<>(packageInfo, mPackageRefQueue));
- }
- }
- return packageInfo;
- }
- }
-
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
int flags) {
@@ -2615,50 +2379,58 @@ public final class ActivityThread extends ClientTransactionHandler
public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
int flags, int userId) {
- final ApplicationInfo ai = PackageManager.getApplicationInfoAsUserCached(
+ final boolean differentUser = (UserHandle.myUserId() != userId);
+ ApplicationInfo ai = PackageManager.getApplicationInfoAsUserCached(
packageName,
PackageManager.GET_SHARED_LIBRARY_FILES
| PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
(userId < 0) ? UserHandle.myUserId() : userId);
- LoadedApk packageInfo = null;
- if (ai != null) {
- packageInfo = retrieveCachedApk(ai,
- (flags & Context.CONTEXT_INCLUDE_CODE) != 0,
- false);
- }
+ synchronized (mResourcesManager) {
+ WeakReference<LoadedApk> ref;
+ if (differentUser) {
+ // Caching not supported across users
+ ref = null;
+ } else if ((flags & Context.CONTEXT_INCLUDE_CODE) != 0) {
+ ref = mPackages.get(packageName);
+ } else {
+ ref = mResourcePackages.get(packageName);
+ }
- if (packageInfo != null) {
- if (packageInfo.isSecurityViolation()
- && (flags & Context.CONTEXT_IGNORE_SECURITY) == 0) {
- throw new SecurityException(
- "Requesting code from " + packageName
- + " to be run in process "
- + mBoundApplication.processName
- + "/" + mBoundApplication.appInfo.uid);
+ LoadedApk packageInfo = ref != null ? ref.get() : null;
+ if (ai != null && packageInfo != null) {
+ if (!isLoadedApkResourceDirsUpToDate(packageInfo, ai)) {
+ List<String> oldPaths = new ArrayList<>();
+ LoadedApk.makePaths(this, ai, oldPaths);
+ packageInfo.updateApplicationInfo(ai, oldPaths);
+ }
+
+ if (packageInfo.isSecurityViolation()
+ && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
+ throw new SecurityException(
+ "Requesting code from " + packageName
+ + " to be run in process "
+ + mBoundApplication.processName
+ + "/" + mBoundApplication.appInfo.uid);
+ }
+ return packageInfo;
}
- return packageInfo;
}
- return ai == null ? null : getPackageInfo(ai, compatInfo, flags, false);
+ if (ai != null) {
+ return getPackageInfo(ai, compatInfo, flags);
+ }
+
+ return null;
}
- /**
- * @deprecated Use {@link #getPackageInfo(ApplicationInfo, CompatibilityInfo, int, boolean)}
- * instead.
- */
- @Deprecated
@UnsupportedAppUsage(trackingBug = 171933273)
public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
int flags) {
- return getPackageInfo(ai, compatInfo, flags, true);
- }
-
- public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
- @Context.CreatePackageOptions int flags, boolean isAppInfoFromAMS) {
boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
boolean securityViolation = includeCode && ai.uid != 0
- && ai.uid != Process.SYSTEM_UID && (mBoundApplication == null
- || !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid));
+ && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
+ ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
+ : true);
boolean registerPackage = includeCode && (flags&Context.CONTEXT_REGISTER_PACKAGE) != 0;
if ((flags&(Context.CONTEXT_INCLUDE_CODE
|Context.CONTEXT_IGNORE_SECURITY))
@@ -2668,47 +2440,107 @@ public final class ActivityThread extends ClientTransactionHandler
+ " (with uid " + ai.uid + ")";
if (mBoundApplication != null) {
msg = msg + " to be run in process "
- + mBoundApplication.processName + " (with uid "
- + mBoundApplication.appInfo.uid + ")";
+ + mBoundApplication.processName + " (with uid "
+ + mBoundApplication.appInfo.uid + ")";
}
throw new SecurityException(msg);
}
}
return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode,
- registerPackage, isAppInfoFromAMS);
+ registerPackage);
}
@Override
@UnsupportedAppUsage
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
CompatibilityInfo compatInfo) {
- return getPackageInfo(ai, compatInfo, null, false, true, false, true);
+ return getPackageInfo(ai, compatInfo, null, false, true, false);
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
synchronized (mResourcesManager) {
- return peekLatestCachedApkFromAMS(packageName, includeCode);
+ WeakReference<LoadedApk> ref;
+ if (includeCode) {
+ ref = mPackages.get(packageName);
+ } else {
+ ref = mResourcePackages.get(packageName);
+ }
+ return ref != null ? ref.get() : null;
}
}
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
- boolean registerPackage, boolean isAppInfoFromAMS) {
- LoadedApk packageInfo = retrieveCachedApk(aInfo, includeCode,
- isAppInfoFromAMS);
- if (packageInfo != null) {
+ boolean registerPackage) {
+ final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
+ synchronized (mResourcesManager) {
+ WeakReference<LoadedApk> ref;
+ if (differentUser) {
+ // Caching not supported across users
+ ref = null;
+ } else if (includeCode) {
+ ref = mPackages.get(aInfo.packageName);
+ } else {
+ ref = mResourcePackages.get(aInfo.packageName);
+ }
+
+ LoadedApk packageInfo = ref != null ? ref.get() : null;
+
+ if (packageInfo != null) {
+ if (!isLoadedApkResourceDirsUpToDate(packageInfo, aInfo)) {
+ List<String> oldPaths = new ArrayList<>();
+ LoadedApk.makePaths(this, aInfo, oldPaths);
+ packageInfo.updateApplicationInfo(aInfo, oldPaths);
+ }
+
+ return packageInfo;
+ }
+
+ if (localLOGV) {
+ Slog.v(TAG, (includeCode ? "Loading code package "
+ : "Loading resource-only package ") + aInfo.packageName
+ + " (in " + (mBoundApplication != null
+ ? mBoundApplication.processName : null)
+ + ")");
+ }
+
+ packageInfo =
+ new LoadedApk(this, aInfo, compatInfo, baseLoader,
+ securityViolation, includeCode
+ && (aInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
+
+ if (mSystemThread && "android".equals(aInfo.packageName)) {
+ packageInfo.installSystemApplicationInfo(aInfo,
+ getSystemContext().mPackageInfo.getClassLoader());
+ }
+
+ if (differentUser) {
+ // Caching not supported across users
+ } else if (includeCode) {
+ mPackages.put(aInfo.packageName,
+ new WeakReference<LoadedApk>(packageInfo));
+ } else {
+ mResourcePackages.put(aInfo.packageName,
+ new WeakReference<LoadedApk>(packageInfo));
+ }
+
return packageInfo;
}
- if (localLOGV) {
- Slog.v(TAG, (includeCode ? "Loading code package "
- : "Loading resource-only package ") + aInfo.packageName
- + " (in " + (mBoundApplication != null
- ? mBoundApplication.processName : null)
- + ")");
- }
- return createLoadedPackage(aInfo, compatInfo, baseLoader,
- securityViolation, includeCode, registerPackage, isAppInfoFromAMS);
+ }
+
+ private static boolean isLoadedApkResourceDirsUpToDate(LoadedApk loadedApk,
+ ApplicationInfo appInfo) {
+ Resources packageResources = loadedApk.mResources;
+ boolean resourceDirsUpToDate = Arrays.equals(
+ ArrayUtils.defeatNullable(appInfo.resourceDirs),
+ ArrayUtils.defeatNullable(loadedApk.getOverlayDirs()));
+ boolean overlayPathsUpToDate = Arrays.equals(
+ ArrayUtils.defeatNullable(appInfo.overlayPaths),
+ ArrayUtils.defeatNullable(loadedApk.getOverlayPaths()));
+
+ return (packageResources == null || packageResources.getAssets().isUpToDate())
+ && resourceDirsUpToDate && overlayPathsUpToDate;
}
@UnsupportedAppUsage
@@ -3670,7 +3502,7 @@ public final class ActivityThread extends ClientTransactionHandler
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
- Context.CONTEXT_INCLUDE_CODE, true);
+ Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
@@ -6153,10 +5985,40 @@ public final class ActivityThread extends ClientTransactionHandler
@VisibleForTesting(visibility = PACKAGE)
public void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) {
- // Updates triggered by package installation go through a package update receiver. Here we
- // try to capture ApplicationInfo changes that are caused by other sources, such as
- // overlays. That means we want to be as conservative about code changes as possible.
- updateLatestCachedApkFromAMS(ai.packageName, ai, false);
+ // Updates triggered by package installation go through a package update
+ // receiver. Here we try to capture ApplicationInfo changes that are
+ // caused by other sources, such as overlays. That means we want to be as conservative
+ // about code changes as possible. Take the diff of the old ApplicationInfo and the new
+ // to see if anything needs to change.
+ LoadedApk apk;
+ LoadedApk resApk;
+ // Update all affected loaded packages with new package information
+ synchronized (mResourcesManager) {
+ WeakReference<LoadedApk> ref = mPackages.get(ai.packageName);
+ apk = ref != null ? ref.get() : null;
+ ref = mResourcePackages.get(ai.packageName);
+ resApk = ref != null ? ref.get() : null;
+ }
+
+ final String[] oldResDirs = new String[2];
+
+ if (apk != null) {
+ oldResDirs[0] = apk.getResDir();
+ final ArrayList<String> oldPaths = new ArrayList<>();
+ LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths);
+ apk.updateApplicationInfo(ai, oldPaths);
+ }
+ if (resApk != null) {
+ oldResDirs[1] = resApk.getResDir();
+ final ArrayList<String> oldPaths = new ArrayList<>();
+ LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths);
+ resApk.updateApplicationInfo(ai, oldPaths);
+ }
+
+ synchronized (mResourcesManager) {
+ // Update all affected Resources objects to use new ResourcesImpl
+ mResourcesManager.applyNewResourceDirs(ai, oldResDirs);
+ }
}
/**
@@ -6333,7 +6195,29 @@ public final class ActivityThread extends ClientTransactionHandler
case ApplicationThreadConstants.PACKAGE_REMOVED:
case ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL:
{
- hasPkgInfo = clearCachedApks();
+ final boolean killApp = cmd == ApplicationThreadConstants.PACKAGE_REMOVED;
+ if (packages == null) {
+ break;
+ }
+ synchronized (mResourcesManager) {
+ for (int i = packages.length - 1; i >= 0; i--) {
+ if (!hasPkgInfo) {
+ WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
+ if (ref != null && ref.get() != null) {
+ hasPkgInfo = true;
+ } else {
+ ref = mResourcePackages.get(packages[i]);
+ if (ref != null && ref.get() != null) {
+ hasPkgInfo = true;
+ }
+ }
+ }
+ if (killApp) {
+ mPackages.remove(packages[i]);
+ mResourcePackages.remove(packages[i]);
+ }
+ }
+ }
break;
}
case ApplicationThreadConstants.PACKAGE_REPLACED:
@@ -6341,19 +6225,68 @@ public final class ActivityThread extends ClientTransactionHandler
if (packages == null) {
break;
}
- final List<String> packagesHandled = new ArrayList<>();
- for (int i = packages.length - 1; i >= 0; i--) {
- final String packageName = packages[i];
- if (updateLatestCachedApkFromAMS(packageName, null, true)) {
- hasPkgInfo = true;
- packagesHandled.add(packageName);
+
+ List<String> packagesHandled = new ArrayList<>();
+
+ synchronized (mResourcesManager) {
+ for (int i = packages.length - 1; i >= 0; i--) {
+ String packageName = packages[i];
+ WeakReference<LoadedApk> ref = mPackages.get(packageName);
+ LoadedApk pkgInfo = ref != null ? ref.get() : null;
+ if (pkgInfo != null) {
+ hasPkgInfo = true;
+ } else {
+ ref = mResourcePackages.get(packageName);
+ pkgInfo = ref != null ? ref.get() : null;
+ if (pkgInfo != null) {
+ hasPkgInfo = true;
+ }
+ }
+ // If the package is being replaced, yet it still has a valid
+ // LoadedApk object, the package was updated with _DONT_KILL.
+ // Adjust it's internal references to the application info and
+ // resources.
+ if (pkgInfo != null) {
+ packagesHandled.add(packageName);
+ try {
+ final ApplicationInfo aInfo =
+ sPackageManager.getApplicationInfo(
+ packageName,
+ PackageManager.GET_SHARED_LIBRARY_FILES,
+ UserHandle.myUserId());
+
+ if (mActivities.size() > 0) {
+ for (ActivityClientRecord ar : mActivities.values()) {
+ if (ar.activityInfo.applicationInfo.packageName
+ .equals(packageName)) {
+ ar.activityInfo.applicationInfo = aInfo;
+ ar.packageInfo = pkgInfo;
+ }
+ }
+ }
+
+ final String[] oldResDirs = { pkgInfo.getResDir() };
+
+ final ArrayList<String> oldPaths = new ArrayList<>();
+ LoadedApk.makePaths(this, pkgInfo.getApplicationInfo(), oldPaths);
+ pkgInfo.updateApplicationInfo(aInfo, oldPaths);
+
+ synchronized (mResourcesManager) {
+ // Update affected Resources objects to use new ResourcesImpl
+ mResourcesManager.applyNewResourceDirs(aInfo, oldResDirs);
+ }
+ } catch (RemoteException e) {
+ }
+ }
}
}
+
try {
getPackageManager().notifyPackagesReplacedReceived(
packagesHandled.toArray(new String[0]));
} catch (RemoteException ignored) {
}
+
break;
}
}
@@ -6912,7 +6845,7 @@ public final class ActivityThread extends ClientTransactionHandler
ii.copyTo(instrApp);
instrApp.initForUser(UserHandle.myUserId());
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
- appContext.getClassLoader(), false, true, false, true);
+ appContext.getClassLoader(), false, true, false);
// The test context's op package name == the target app's op package name, because
// the app ops manager checks the op package name against the real calling UID,