Loading core/java/android/app/ActivityThread.java +45 −4 Original line number Diff line number Diff line Loading @@ -359,6 +359,15 @@ public final class ActivityThread extends ClientTransactionHandler /** Maps from activity token to the pending override configuration. */ @GuardedBy("mPendingOverrideConfigs") private final ArrayMap<IBinder, Configuration> mPendingOverrideConfigs = new ArrayMap<>(); /** * A queue of pending ApplicationInfo updates. In case when we get a concurrent update * this queue allows us to only apply the latest object, and it can be applied on demand * instead of waiting for the handler thread to reach the scheduled callback. */ @GuardedBy("mResourcesManager") private final ArrayMap<String, ApplicationInfo> mPendingAppInfoUpdates = new ArrayMap<>(); /** The activities to be truly destroyed (not include relaunch). */ final Map<IBinder, ClientTransactionItem> mActivitiesToBeDestroyed = Collections.synchronizedMap(new ArrayMap<IBinder, ClientTransactionItem>()); Loading Loading @@ -1260,9 +1269,19 @@ public final class ActivityThread extends ClientTransactionHandler } public void scheduleApplicationInfoChanged(ApplicationInfo ai) { synchronized (mResourcesManager) { var oldAi = mPendingAppInfoUpdates.put(ai.packageName, ai); if (oldAi != null && oldAi.createTimestamp > ai.createTimestamp) { Slog.w(TAG, "Skipping application info changed for obsolete AI with TS " + ai.createTimestamp + " < already pending TS " + oldAi.createTimestamp); mPendingAppInfoUpdates.put(ai.packageName, oldAi); return; } } mResourcesManager.appendPendingAppInfoUpdate(new String[]{ai.sourceDir}, ai); mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai); sendMessage(H.APPLICATION_INFO_CHANGED, ai); mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai.packageName); sendMessage(H.APPLICATION_INFO_CHANGED, ai.packageName); } public void updateTimeZone() { Loading Loading @@ -2437,7 +2456,7 @@ public final class ActivityThread extends ClientTransactionHandler break; } case APPLICATION_INFO_CHANGED: handleApplicationInfoChanged((ApplicationInfo) msg.obj); applyPendingApplicationInfoChanges((String) msg.obj); break; case RUN_ISOLATED_ENTRY_POINT: handleRunIsolatedEntryPoint((String) ((SomeArgs) msg.obj).arg1, Loading Loading @@ -3922,7 +3941,8 @@ public final class ActivityThread extends ClientTransactionHandler mProfiler.startProfiling(); } // Make sure we are running with the most recent config. // Make sure we are running with the most recent config and resource paths. applyPendingApplicationInfoChanges(r.activityInfo.packageName); mConfigurationController.handleConfigurationChanged(null, null); updateDeviceIdForNonUIContexts(deviceId); Loading Loading @@ -6248,6 +6268,17 @@ public final class ActivityThread extends ClientTransactionHandler r.mLastReportedWindowingMode = newWindowingMode; } private void applyPendingApplicationInfoChanges(String packageName) { final ApplicationInfo ai; synchronized (mResourcesManager) { ai = mPendingAppInfoUpdates.remove(packageName); } if (ai == null) { return; } handleApplicationInfoChanged(ai); } /** * Updates the application info. * Loading @@ -6273,6 +6304,16 @@ public final class ActivityThread extends ClientTransactionHandler apk = ref != null ? ref.get() : null; ref = mResourcePackages.get(ai.packageName); resApk = ref != null ? ref.get() : null; for (ActivityClientRecord ar : mActivities.values()) { if (ar.activityInfo.applicationInfo.packageName.equals(ai.packageName)) { ar.activityInfo.applicationInfo = ai; if (apk != null || resApk != null) { ar.packageInfo = apk != null ? apk : resApk; } else { apk = ar.packageInfo; } } } } if (apk != null) { Loading core/java/android/app/LoadedApk.java +11 −2 Original line number Diff line number Diff line Loading @@ -343,7 +343,9 @@ public final class LoadedApk { */ public void updateApplicationInfo(@NonNull ApplicationInfo aInfo, @Nullable List<String> oldPaths) { setApplicationInfo(aInfo); if (!setApplicationInfo(aInfo)) { return; } final List<String> newPaths = new ArrayList<>(); makePaths(mActivityThread, aInfo, newPaths); Loading Loading @@ -388,7 +390,13 @@ public final class LoadedApk { mAppComponentFactory = createAppFactory(aInfo, mDefaultClassLoader); } private void setApplicationInfo(ApplicationInfo aInfo) { private boolean setApplicationInfo(ApplicationInfo aInfo) { if (mApplicationInfo != null && mApplicationInfo.createTimestamp > aInfo.createTimestamp) { Slog.w(TAG, "New application info for package " + aInfo.packageName + " is out of date with TS " + aInfo.createTimestamp + " < the current TS " + mApplicationInfo.createTimestamp); return false; } final int myUid = Process.myUid(); aInfo = adjustNativeLibraryPaths(aInfo); mApplicationInfo = aInfo; Loading @@ -411,6 +419,7 @@ public final class LoadedApk { if (aInfo.requestsIsolatedSplitLoading() && !ArrayUtils.isEmpty(mSplitNames)) { mSplitLoader = new SplitDependencyLoaderImpl(aInfo.splitDependencies); } return true; } void setSdkSandboxStorage(@Nullable String sdkSandboxClientAppVolumeUuid, Loading Loading
core/java/android/app/ActivityThread.java +45 −4 Original line number Diff line number Diff line Loading @@ -359,6 +359,15 @@ public final class ActivityThread extends ClientTransactionHandler /** Maps from activity token to the pending override configuration. */ @GuardedBy("mPendingOverrideConfigs") private final ArrayMap<IBinder, Configuration> mPendingOverrideConfigs = new ArrayMap<>(); /** * A queue of pending ApplicationInfo updates. In case when we get a concurrent update * this queue allows us to only apply the latest object, and it can be applied on demand * instead of waiting for the handler thread to reach the scheduled callback. */ @GuardedBy("mResourcesManager") private final ArrayMap<String, ApplicationInfo> mPendingAppInfoUpdates = new ArrayMap<>(); /** The activities to be truly destroyed (not include relaunch). */ final Map<IBinder, ClientTransactionItem> mActivitiesToBeDestroyed = Collections.synchronizedMap(new ArrayMap<IBinder, ClientTransactionItem>()); Loading Loading @@ -1260,9 +1269,19 @@ public final class ActivityThread extends ClientTransactionHandler } public void scheduleApplicationInfoChanged(ApplicationInfo ai) { synchronized (mResourcesManager) { var oldAi = mPendingAppInfoUpdates.put(ai.packageName, ai); if (oldAi != null && oldAi.createTimestamp > ai.createTimestamp) { Slog.w(TAG, "Skipping application info changed for obsolete AI with TS " + ai.createTimestamp + " < already pending TS " + oldAi.createTimestamp); mPendingAppInfoUpdates.put(ai.packageName, oldAi); return; } } mResourcesManager.appendPendingAppInfoUpdate(new String[]{ai.sourceDir}, ai); mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai); sendMessage(H.APPLICATION_INFO_CHANGED, ai); mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai.packageName); sendMessage(H.APPLICATION_INFO_CHANGED, ai.packageName); } public void updateTimeZone() { Loading Loading @@ -2437,7 +2456,7 @@ public final class ActivityThread extends ClientTransactionHandler break; } case APPLICATION_INFO_CHANGED: handleApplicationInfoChanged((ApplicationInfo) msg.obj); applyPendingApplicationInfoChanges((String) msg.obj); break; case RUN_ISOLATED_ENTRY_POINT: handleRunIsolatedEntryPoint((String) ((SomeArgs) msg.obj).arg1, Loading Loading @@ -3922,7 +3941,8 @@ public final class ActivityThread extends ClientTransactionHandler mProfiler.startProfiling(); } // Make sure we are running with the most recent config. // Make sure we are running with the most recent config and resource paths. applyPendingApplicationInfoChanges(r.activityInfo.packageName); mConfigurationController.handleConfigurationChanged(null, null); updateDeviceIdForNonUIContexts(deviceId); Loading Loading @@ -6248,6 +6268,17 @@ public final class ActivityThread extends ClientTransactionHandler r.mLastReportedWindowingMode = newWindowingMode; } private void applyPendingApplicationInfoChanges(String packageName) { final ApplicationInfo ai; synchronized (mResourcesManager) { ai = mPendingAppInfoUpdates.remove(packageName); } if (ai == null) { return; } handleApplicationInfoChanged(ai); } /** * Updates the application info. * Loading @@ -6273,6 +6304,16 @@ public final class ActivityThread extends ClientTransactionHandler apk = ref != null ? ref.get() : null; ref = mResourcePackages.get(ai.packageName); resApk = ref != null ? ref.get() : null; for (ActivityClientRecord ar : mActivities.values()) { if (ar.activityInfo.applicationInfo.packageName.equals(ai.packageName)) { ar.activityInfo.applicationInfo = ai; if (apk != null || resApk != null) { ar.packageInfo = apk != null ? apk : resApk; } else { apk = ar.packageInfo; } } } } if (apk != null) { Loading
core/java/android/app/LoadedApk.java +11 −2 Original line number Diff line number Diff line Loading @@ -343,7 +343,9 @@ public final class LoadedApk { */ public void updateApplicationInfo(@NonNull ApplicationInfo aInfo, @Nullable List<String> oldPaths) { setApplicationInfo(aInfo); if (!setApplicationInfo(aInfo)) { return; } final List<String> newPaths = new ArrayList<>(); makePaths(mActivityThread, aInfo, newPaths); Loading Loading @@ -388,7 +390,13 @@ public final class LoadedApk { mAppComponentFactory = createAppFactory(aInfo, mDefaultClassLoader); } private void setApplicationInfo(ApplicationInfo aInfo) { private boolean setApplicationInfo(ApplicationInfo aInfo) { if (mApplicationInfo != null && mApplicationInfo.createTimestamp > aInfo.createTimestamp) { Slog.w(TAG, "New application info for package " + aInfo.packageName + " is out of date with TS " + aInfo.createTimestamp + " < the current TS " + mApplicationInfo.createTimestamp); return false; } final int myUid = Process.myUid(); aInfo = adjustNativeLibraryPaths(aInfo); mApplicationInfo = aInfo; Loading @@ -411,6 +419,7 @@ public final class LoadedApk { if (aInfo.requestsIsolatedSplitLoading() && !ArrayUtils.isEmpty(mSplitNames)) { mSplitLoader = new SplitDependencyLoaderImpl(aInfo.splitDependencies); } return true; } void setSdkSandboxStorage(@Nullable String sdkSandboxClientAppVolumeUuid, Loading