diff options
4 files changed, 47 insertions, 14 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index f71e9fd033da..4182ac3e572d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1182,6 +1182,7 @@ public final class ActivityThread extends ClientTransactionHandler } public void scheduleApplicationInfoChanged(ApplicationInfo ai) { + mResourcesManager.updatePendingAppInfoUpdates(ai); mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai); sendMessage(H.APPLICATION_INFO_CHANGED, ai); } diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index f28c760d54d9..4984577ac153 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -99,6 +99,12 @@ public class ResourcesManager { private int mResDisplayId = DEFAULT_DISPLAY; /** + * ApplicationInfo changes that need to be applied to Resources when the next configuration + * change occurs. + */ + private ArrayList<ApplicationInfo> mPendingAppInfoUpdates; + + /** * A mapping of ResourceImpls and their configurations. These are heavy weight objects * which should be reused as much as possible. */ @@ -1032,7 +1038,7 @@ public class ResourcesManager { * @param classLoader The classloader to use for the Resources object. * If null, {@link ClassLoader#getSystemClassLoader()} is used. * @return A Resources object that gets updated when - * {@link #applyConfigurationToResourcesLocked(Configuration, CompatibilityInfo)} + * {@link #applyConfigurationToResources(Configuration, CompatibilityInfo)} * is called. */ @Nullable @@ -1159,8 +1165,8 @@ public class ResourcesManager { /** * Updates an Activity's Resources object with overrideConfig. The Resources object * that was previously returned by {@link #getResources(IBinder, String, String[], String[], - * String[], Integer, Configuration, CompatibilityInfo, ClassLoader, List)} is still valid and - * will have the updated configuration. + * String[], String[], Integer, Configuration, CompatibilityInfo, ClassLoader, List)} is still + * valid and will have the updated configuration. * * @param activityToken The Activity token. * @param overrideConfig The configuration override to update. @@ -1311,6 +1317,22 @@ public class ResourcesManager { return newKey; } + public void updatePendingAppInfoUpdates(@NonNull ApplicationInfo appInfo) { + synchronized (mLock) { + if (mPendingAppInfoUpdates == null) { + mPendingAppInfoUpdates = new ArrayList<>(); + } + // Clear previous app info changes for the package to prevent multiple ResourcesImpl + // recreations when only the last recreation will be used. + for (int i = mPendingAppInfoUpdates.size() - 1; i >= 0; i--) { + if (appInfo.sourceDir.equals(mPendingAppInfoUpdates.get(i).sourceDir)) { + mPendingAppInfoUpdates.remove(i); + } + } + mPendingAppInfoUpdates.add(appInfo); + } + } + public final boolean applyConfigurationToResources(@NonNull Configuration config, @Nullable CompatibilityInfo compat) { return applyConfigurationToResources(config, compat, null /* adjustments */); @@ -1324,7 +1346,18 @@ public class ResourcesManager { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#applyConfigurationToResources"); - if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) { + final boolean assetsUpdated = mPendingAppInfoUpdates != null + && config.assetsSeq > mResConfiguration.assetsSeq; + if (assetsUpdated) { + for (int i = 0, n = mPendingAppInfoUpdates.size(); i < n; i++) { + final ApplicationInfo appInfo = mPendingAppInfoUpdates.get(i); + applyNewResourceDirs(appInfo, new String[]{appInfo.sourceDir}); + } + mPendingAppInfoUpdates = null; + } + + if (!assetsUpdated && !mResConfiguration.isOtherSeqNewer(config) + && compat == null) { if (DEBUG || DEBUG_CONFIGURATION) { Slog.v(TAG, "Skipping new config: curSeq=" + mResConfiguration.seq + ", newSeq=" + config.seq); @@ -1367,7 +1400,7 @@ public class ResourcesManager { } } - return changes != 0; + return assetsUpdated || changes != 0; } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 8ebc987a59f4..1b67679b56d6 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -4698,10 +4698,10 @@ public final class ProcessList { final ApplicationInfo ai = AppGlobals.getPackageManager() .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId); if (ai != null) { - app.getThread().scheduleApplicationInfoChanged(ai); if (ai.packageName.equals(app.info.packageName)) { app.info = ai; } + app.getThread().scheduleApplicationInfoChanged(ai); targetProcesses.add(app.getWindowProcessController()); } } catch (RemoteException e) { @@ -4712,8 +4712,7 @@ public final class ProcessList { }); } - mService.mActivityTaskManager.updateAssetConfiguration( - updateFrameworkRes ? null : targetProcesses); + mService.mActivityTaskManager.updateAssetConfiguration(targetProcesses, updateFrameworkRes); } @GuardedBy("mService") diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 5e75cebc322d..8078c78dfdc8 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -4146,21 +4146,21 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** * Update the asset configuration and increase the assets sequence number. - * @param processes the processes that needs to update the asset configuration, if none - * updates the global configuration for all processes. + * @param processes the processes that needs to update the asset configuration */ - public void updateAssetConfiguration(List<WindowProcessController> processes) { + public void updateAssetConfiguration(List<WindowProcessController> processes, + boolean updateFrameworkRes) { synchronized (mGlobalLock) { final int assetSeq = increaseAssetConfigurationSeq(); - // Update the global configuration if the no target processes - if (processes == null) { + if (updateFrameworkRes) { Configuration newConfig = new Configuration(); newConfig.assetsSeq = assetSeq; updateConfiguration(newConfig); - return; } + // Always update the override of every process so the asset sequence of the process is + // always greater than or equal to the global configuration. for (int i = processes.size() - 1; i >= 0; i--) { final WindowProcessController wpc = processes.get(i); wpc.updateAssetConfiguration(assetSeq); |