diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 74614cc8a7036..d814ddcc7f27d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -4919,18 +4919,27 @@ public final class ActivityThread { } 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. Take the diff of the old ApplicationInfo and the new + // to see if anything needs to change. synchronized (mResourcesManager) { // Update all affected loaded packages with new package information WeakReference ref = mPackages.get(ai.packageName); LoadedApk apk = ref != null ? ref.get() : null; if (apk != null) { - apk.updateApplicationInfo(ai, null); + final ArrayList oldPaths = new ArrayList<>(); + LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths, null /*outLibPaths*/); + apk.updateApplicationInfo(ai, oldPaths); } ref = mResourcePackages.get(ai.packageName); apk = ref != null ? ref.get() : null; if (apk != null) { - apk.updateApplicationInfo(ai, null); + final ArrayList oldPaths = new ArrayList<>(); + LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths, null /*outLibPaths*/); + apk.updateApplicationInfo(ai, oldPaths); } // Update all affected Resources objects to use new ResourcesImpl diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index db1162a3cbb3a..4ab07432ad1f0 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -16,6 +16,8 @@ package android.app; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -262,7 +264,15 @@ public final class LoadedApk { return ai.sharedLibraryFiles; } - public void updateApplicationInfo(ApplicationInfo aInfo, List oldPaths) { + /** + * Update the ApplicationInfo for an app. If oldPaths is null, all the paths are considered + * new. + * @param aInfo The new ApplicationInfo to use for this LoadedApk + * @param oldPaths The code paths for the old ApplicationInfo object. null means no paths can + * be reused. + */ + public void updateApplicationInfo(@NonNull ApplicationInfo aInfo, + @Nullable List oldPaths) { setApplicationInfo(aInfo); final List newPaths = new ArrayList<>();