diff options
13 files changed, 70 insertions, 93 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 034ad8e83fd3..00ba55c4cb1c 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -36,7 +36,6 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UserIdInt; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.backup.BackupAgent; @@ -62,7 +61,6 @@ import android.content.ContentCaptureOptions; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; -import android.content.Context.CreatePackageOptions; import android.content.IContentProvider; import android.content.IIntentReceiver; import android.content.Intent; @@ -73,7 +71,6 @@ import android.content.pm.IPackageManager; import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManager.ApplicationInfoFlags; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionInfo; @@ -1172,6 +1169,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); } @@ -2376,22 +2374,16 @@ public final class ActivityThread extends ClientTransactionHandler @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, - @CreatePackageOptions int flags) { + int flags) { return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId()); } public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, - @CreatePackageOptions int flags, @UserIdInt int userId) { - return getPackageInfo(packageName, compatInfo, flags, userId, 0 /* packageFlags */); - } - - public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, - @CreatePackageOptions int flags, @UserIdInt int userId, - @ApplicationInfoFlags int packageFlags) { + int flags, int userId) { final boolean differentUser = (UserHandle.myUserId() != userId); ApplicationInfo ai = PackageManager.getApplicationInfoAsUserCached( packageName, - packageFlags | PackageManager.GET_SHARED_LIBRARY_FILES + PackageManager.GET_SHARED_LIBRARY_FILES | PackageManager.MATCH_DEBUG_TRIAGED_MISSING, (userId < 0) ? UserHandle.myUserId() : userId); synchronized (mResourcesManager) { @@ -2434,7 +2426,7 @@ public final class ActivityThread extends ClientTransactionHandler @UnsupportedAppUsage(trackingBug = 171933273) public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo, - @CreatePackageOptions int flags) { + int flags) { boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0; boolean securityViolation = includeCode && ai.uid != 0 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 16b6ea5bcf42..5e99c79a7497 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -26,7 +26,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UiContext; import android.compat.annotation.UnsupportedAppUsage; -import android.content.AttributionSource; import android.content.AutofillOptions; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -48,7 +47,6 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; -import android.content.pm.PackageManager.ApplicationInfoFlags; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.AssetManager; import android.content.res.CompatResources; @@ -62,6 +60,7 @@ import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.content.AttributionSource; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -2494,13 +2493,6 @@ class ContextImpl extends Context { @Override public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) throws NameNotFoundException { - return createPackageContextAsUser(packageName, flags, user, 0 /* packageFlags */); - } - - @Override - public Context createPackageContextAsUser( - @NonNull String packageName, @CreatePackageOptions int flags, @NonNull UserHandle user, - @ApplicationInfoFlags int packageFlags) throws PackageManager.NameNotFoundException { if (packageName.equals("system") || packageName.equals("android")) { // The system resources are loaded in every application, so we can safely copy // the context without reloading Resources. @@ -2511,7 +2503,7 @@ class ContextImpl extends Context { } LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), - flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier(), packageFlags); + flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier()); if (pi != null) { ContextImpl c = new ContextImpl(this, mMainThread, pi, mParams, mAttributionSource.getAttributionTag(), diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 506dfe09f3fa..6454d2027f58 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -6344,11 +6344,10 @@ public class Notification implements Parcelable ApplicationInfo applicationInfo = n.extras.getParcelable( EXTRA_BUILDER_APPLICATION_INFO); Context builderContext; - if (applicationInfo != null && applicationInfo.packageName != null) { + if (applicationInfo != null) { try { - builderContext = context.createPackageContextAsUser(applicationInfo.packageName, - Context.CONTEXT_RESTRICTED, - UserHandle.getUserHandleForUid(applicationInfo.uid)); + builderContext = context.createApplicationContext(applicationInfo, + Context.CONTEXT_RESTRICTED); } catch (NameNotFoundException e) { Log.e(TAG, "ApplicationInfo " + applicationInfo + " not found"); builderContext = context; // try with our context diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index e469b1fde2e5..dfd1e2b61fae 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -98,6 +98,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. */ @@ -988,7 +994,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 @@ -1115,8 +1121,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. @@ -1267,6 +1273,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 */); @@ -1280,7 +1302,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); @@ -1320,7 +1353,7 @@ public class ResourcesManager { } } - return changes != 0; + return assetsUpdated || changes != 0; } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 3b11a19f9acc..ba3fc1e55c54 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -37,7 +37,6 @@ import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Parcelable; -import android.os.UserHandle; import android.util.AttributeSet; import android.util.Log; import android.util.Pair; @@ -719,10 +718,9 @@ public class AppWidgetHostView extends FrameLayout { protected Context getRemoteContext() { try { // Return if cloned successfully, otherwise default - final ApplicationInfo info = mInfo.providerInfo.applicationInfo; - Context newContext = mContext.createPackageContextAsUser(info.packageName, - Context.CONTEXT_RESTRICTED, - UserHandle.getUserHandleForUid(info.uid)); + Context newContext = mContext.createApplicationContext( + mInfo.providerInfo.applicationInfo, + Context.CONTEXT_RESTRICTED); if (mColorResources != null) { mColorResources.apply(newContext); } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 9c60f431b06e..c02dcfd3d681 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -46,7 +46,6 @@ import android.app.time.TimeManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManager.ApplicationInfoFlags; import android.content.res.AssetManager; import android.content.res.ColorStateList; import android.content.res.Configuration; @@ -6269,23 +6268,6 @@ public abstract class Context { } /** - * Similar to {@link #createPackageContextAsUser(String, int, UserHandle)}, but also allows - * specifying the flags used to retrieve the {@link ApplicationInfo} of the package. - * - * @hide - */ - @NonNull - public Context createPackageContextAsUser( - @NonNull String packageName, @CreatePackageOptions int flags, @NonNull UserHandle user, - @ApplicationInfoFlags int packageFlags) - throws PackageManager.NameNotFoundException { - if (Build.IS_ENG) { - throw new IllegalStateException("createPackageContextAsUser not overridden!"); - } - return this; - } - - /** * Similar to {@link #createPackageContext(String, int)}, but for the own package with a * different {@link UserHandle}. For example, {@link #getContentResolver()} * will open any {@link Uri} as the given user. @@ -6304,18 +6286,10 @@ public abstract class Context { /** * Creates a context given an {@link android.content.pm.ApplicationInfo}. * - * @deprecated use {@link #createPackageContextAsUser(String, int, UserHandle, int)} - * If an application caches an ApplicationInfo and uses it to call this method, - * the app will not get the most recent version of Runtime Resource Overlays for - * that application. To make things worse, the LoadedApk stored in - * {@code ActivityThread#mResourcePackages} is updated using the old ApplicationInfo - * causing further uses of the cached LoadedApk to return outdated information. - * * @hide */ @SuppressWarnings("HiddenAbstractMethod") @UnsupportedAppUsage - @Deprecated public abstract Context createApplicationContext(ApplicationInfo application, @CreatePackageOptions int flags) throws PackageManager.NameNotFoundException; diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index cf0dc8c92ea1..6324d0ecb0e0 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -1009,14 +1009,6 @@ public class ContextWrapper extends Context { /** @hide */ @Override - public Context createPackageContextAsUser(String packageName, int flags, UserHandle user, - int packageFlags) - throws PackageManager.NameNotFoundException { - return mBase.createPackageContextAsUser(packageName, flags, user, packageFlags); - } - - /** @hide */ - @Override public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) { return mBase.createContextAsUser(user, flags); } diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index 863d71f6f793..8e4a68e52697 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -434,8 +434,11 @@ public class StatusBarNotification implements Parcelable { public Context getPackageContext(Context context) { if (mContext == null) { try { - mContext = context.createPackageContextAsUser(pkg, Context.CONTEXT_RESTRICTED, user, - PackageManager.MATCH_UNINSTALLED_PACKAGES); + ApplicationInfo ai = context.getPackageManager() + .getApplicationInfoAsUser(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES, + getUserId()); + mContext = context.createApplicationContext(ai, + Context.CONTEXT_RESTRICTED); } catch (PackageManager.NameNotFoundException e) { mContext = null; } diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 8d27cded6338..cf6807e41e8a 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -33,7 +33,6 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.Trace; -import android.os.UserHandle; import android.util.AndroidRuntimeException; import android.util.ArraySet; import android.util.Log; @@ -468,12 +467,9 @@ public final class WebViewFactory { sTimestamps.mCreateContextStart = SystemClock.uptimeMillis(); try { // Construct an app context to load the Java code into the current app. - Context webViewContext = initialApplication.createPackageContextAsUser( - ai.packageName, - Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY, - UserHandle.getUserHandleForUid(ai.uid), - PackageManager.MATCH_UNINSTALLED_PACKAGES - | PackageManager.MATCH_DEBUG_TRIAGED_MISSING); + Context webViewContext = initialApplication.createApplicationContext( + ai, + Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY); sPackageInfo = newPackageInfo; return webViewContext; } finally { diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 8a044fd06dd5..e827f0a31bfd 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -5831,9 +5831,8 @@ public class RemoteViews implements Parcelable, Filter { return context; } try { - return context.createPackageContextAsUser(mApplication.packageName, - Context.CONTEXT_RESTRICTED, - UserHandle.getUserHandleForUid(mApplication.uid)); + return context.createApplicationContext(mApplication, + Context.CONTEXT_RESTRICTED); } catch (NameNotFoundException e) { Log.e(LOG_TAG, "Package name " + mApplication.packageName + " not found"); } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java index c90833c5b8f2..2b35bcd9a3ea 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java @@ -345,7 +345,7 @@ public class PluginInstanceManager<T extends Plugin> { // Create our own ClassLoader so we can use our own code as the parent. ClassLoader classLoader = mManager.getClassLoader(info); Context pluginContext = new PluginContextWrapper( - mContext.createPackageContext(pkg, 0), classLoader); + mContext.createApplicationContext(info, 0), classLoader); Class<?> pluginClass = Class.forName(cls, true, classLoader); // TODO: Only create the plugin before version check if we need it for // legacy version check. diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 7c5d09c3c5ce..fd9a53695e6c 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -4691,10 +4691,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) { @@ -4705,8 +4705,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 899266d1f686..680937b37eac 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -4159,21 +4159,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); |