summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Paul Hobbs <phobbs@google.com> 2021-06-29 20:36:15 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-06-29 20:36:15 +0000
commit8d440c0566910525b6bd92ebc1ccaec392df6f40 (patch)
tree4799fbecbe34101426fb09368c7f91b2a887f440
parent4e395b98212bea2458cfeab6d863508db23c9ca5 (diff)
parentcb5a80ea57b51fcde117dea253c546dbba9f27f1 (diff)
Merge changes from topic "revert-15058002-SNQUARIDWJ" into sc-dev
* changes: Revert^2 "Deprecate Context#createApplicationContext" Revert "Version LoadedApk cache using base code path" Revert "Apply overlay changes with config change"
-rw-r--r--core/java/android/app/ActivityThread.java533
-rw-r--r--core/java/android/app/ContextImpl.java12
-rw-r--r--core/java/android/app/Notification.java7
-rw-r--r--core/java/android/app/ResourcesManager.java43
-rw-r--r--core/java/android/appwidget/AppWidgetHostView.java8
-rw-r--r--core/java/android/content/Context.java26
-rw-r--r--core/java/android/content/ContextWrapper.java8
-rw-r--r--core/java/android/service/notification/StatusBarNotification.java7
-rw-r--r--core/java/android/webkit/WebViewFactory.java10
-rw-r--r--core/java/android/widget/RemoteViews.java5
-rw-r--r--core/tests/coretests/Android.bp2
-rw-r--r--core/tests/coretests/apks/res_upgrade/Android.bp22
-rw-r--r--core/tests/coretests/apks/res_upgrade/AndroidManifest.xml20
-rw-r--r--core/tests/coretests/apks/res_upgrade/res_after/values/values.xml22
-rw-r--r--core/tests/coretests/apks/res_upgrade/res_before/values/values.xml22
-rw-r--r--core/tests/coretests/src/android/content/ContextTest.java146
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java2
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java5
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java12
19 files changed, 319 insertions, 593 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4182ac3e572d..034ad8e83fd3 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -36,6 +36,7 @@ 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;
@@ -61,6 +62,7 @@ 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;
@@ -71,6 +73,7 @@ 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;
@@ -218,8 +221,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 +231,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 +419,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")
@@ -1182,7 +1172,6 @@ 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);
}
@@ -2385,281 +2374,72 @@ 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);
- }
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+ public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
+ @CreatePackageOptions int flags) {
+ return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
}
- 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;
+ public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
+ @CreatePackageOptions int flags, @UserIdInt int userId) {
+ return getPackageInfo(packageName, compatInfo, flags, userId, 0 /* packageFlags */);
}
- /**
- * 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) {
+ public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
+ @CreatePackageOptions int flags, @UserIdInt int userId,
+ @ApplicationInfoFlags int packageFlags) {
+ final boolean differentUser = (UserHandle.myUserId() != userId);
+ ApplicationInfo ai = PackageManager.getApplicationInfoAsUserCached(
+ packageName,
+ packageFlags | PackageManager.GET_SHARED_LIBRARY_FILES
+ | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
+ (userId < 0) ? UserHandle.myUserId() : userId);
synchronized (mResourcesManager) {
WeakReference<LoadedApk> ref;
- if (includeCode) {
- return ((ref = mPackages.get(packageName)) != null) ? ref.get() : null;
+ if (differentUser) {
+ // Caching not supported across users
+ ref = null;
+ } else if ((flags & Context.CONTEXT_INCLUDE_CODE) != 0) {
+ ref = mPackages.get(packageName);
} 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;
+ ref = mResourcePackages.get(packageName);
}
- // 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;
- }
+ 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);
}
- }
-
- 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));
+ 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;
}
- }
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
- int flags) {
- return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
- }
- public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
- int flags, int userId) {
- final 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);
- }
-
- 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);
- }
- return packageInfo;
+ return getPackageInfo(ai, compatInfo, flags);
}
- return ai == null ? null : getPackageInfo(ai, compatInfo, flags, false);
+ 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) {
+ @CreatePackageOptions int flags) {
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))
@@ -2669,47 +2449,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
@@ -3671,7 +3511,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();
@@ -6154,10 +5994,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);
+ }
}
/**
@@ -6334,7 +6204,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:
@@ -6342,19 +6234,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;
}
}
@@ -6913,7 +6854,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,
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index d24196813387..16b6ea5bcf42 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -48,6 +48,7 @@ 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;
@@ -2461,7 +2462,7 @@ class ContextImpl extends Context {
public Context createApplicationContext(ApplicationInfo application, int flags)
throws NameNotFoundException {
LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(),
- flags | CONTEXT_REGISTER_PACKAGE, false);
+ flags | CONTEXT_REGISTER_PACKAGE);
if (pi != null) {
ContextImpl c = new ContextImpl(this, mMainThread, pi, ContextParams.EMPTY,
mAttributionSource.getAttributionTag(),
@@ -2493,6 +2494,13 @@ 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.
@@ -2503,7 +2511,7 @@ class ContextImpl extends Context {
}
LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
- flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
+ flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier(), packageFlags);
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 6454d2027f58..506dfe09f3fa 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6344,10 +6344,11 @@ public class Notification implements Parcelable
ApplicationInfo applicationInfo = n.extras.getParcelable(
EXTRA_BUILDER_APPLICATION_INFO);
Context builderContext;
- if (applicationInfo != null) {
+ if (applicationInfo != null && applicationInfo.packageName != null) {
try {
- builderContext = context.createApplicationContext(applicationInfo,
- Context.CONTEXT_RESTRICTED);
+ builderContext = context.createPackageContextAsUser(applicationInfo.packageName,
+ Context.CONTEXT_RESTRICTED,
+ UserHandle.getUserHandleForUid(applicationInfo.uid));
} 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 dfd1e2b61fae..e469b1fde2e5 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -98,12 +98,6 @@ 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.
*/
@@ -994,7 +988,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 #applyConfigurationToResources(Configuration, CompatibilityInfo)}
+ * {@link #applyConfigurationToResourcesLocked(Configuration, CompatibilityInfo)}
* is called.
*/
@Nullable
@@ -1121,8 +1115,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[], String[], Integer, Configuration, CompatibilityInfo, ClassLoader, List)} is still
- * valid and will have the updated configuration.
+ * 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.
@@ -1273,22 +1267,6 @@ 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 */);
@@ -1302,18 +1280,7 @@ public class ResourcesManager {
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
"ResourcesManager#applyConfigurationToResources");
- 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 (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
if (DEBUG || DEBUG_CONFIGURATION) {
Slog.v(TAG, "Skipping new config: curSeq="
+ mResConfiguration.seq + ", newSeq=" + config.seq);
@@ -1353,7 +1320,7 @@ public class ResourcesManager {
}
}
- return assetsUpdated || changes != 0;
+ return 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 ba3fc1e55c54..3b11a19f9acc 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -37,6 +37,7 @@ 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;
@@ -718,9 +719,10 @@ public class AppWidgetHostView extends FrameLayout {
protected Context getRemoteContext() {
try {
// Return if cloned successfully, otherwise default
- Context newContext = mContext.createApplicationContext(
- mInfo.providerInfo.applicationInfo,
- Context.CONTEXT_RESTRICTED);
+ final ApplicationInfo info = mInfo.providerInfo.applicationInfo;
+ Context newContext = mContext.createPackageContextAsUser(info.packageName,
+ Context.CONTEXT_RESTRICTED,
+ UserHandle.getUserHandleForUid(info.uid));
if (mColorResources != null) {
mColorResources.apply(newContext);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c02dcfd3d681..9c60f431b06e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -46,6 +46,7 @@ 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;
@@ -6268,6 +6269,23 @@ 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.
@@ -6286,10 +6304,18 @@ 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 6324d0ecb0e0..cf0dc8c92ea1 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -1009,6 +1009,14 @@ 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 8e4a68e52697..863d71f6f793 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -434,11 +434,8 @@ public class StatusBarNotification implements Parcelable {
public Context getPackageContext(Context context) {
if (mContext == null) {
try {
- ApplicationInfo ai = context.getPackageManager()
- .getApplicationInfoAsUser(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES,
- getUserId());
- mContext = context.createApplicationContext(ai,
- Context.CONTEXT_RESTRICTED);
+ mContext = context.createPackageContextAsUser(pkg, Context.CONTEXT_RESTRICTED, user,
+ PackageManager.MATCH_UNINSTALLED_PACKAGES);
} catch (PackageManager.NameNotFoundException e) {
mContext = null;
}
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index cf6807e41e8a..8d27cded6338 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -33,6 +33,7 @@ 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;
@@ -467,9 +468,12 @@ 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.createApplicationContext(
- ai,
- Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+ 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);
sPackageInfo = newPackageInfo;
return webViewContext;
} finally {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index e827f0a31bfd..8a044fd06dd5 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -5831,8 +5831,9 @@ public class RemoteViews implements Parcelable, Filter {
return context;
}
try {
- return context.createApplicationContext(mApplication,
- Context.CONTEXT_RESTRICTED);
+ return context.createPackageContextAsUser(mApplication.packageName,
+ Context.CONTEXT_RESTRICTED,
+ UserHandle.getUserHandleForUid(mApplication.uid));
} catch (NameNotFoundException e) {
Log.e(LOG_TAG, "Package name " + mApplication.packageName + " not found");
}
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 8fae80d602d9..93e4a294a2cb 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -121,8 +121,6 @@ java_genrule {
":FrameworksCoreTests_keyset_splat_api",
":FrameworksCoreTests_locales",
":FrameworksCoreTests_overlay_config",
- ":FrameworksCoreTests_res_version_after",
- ":FrameworksCoreTests_res_version_before",
":FrameworksCoreTests_version_1",
":FrameworksCoreTests_version_1_diff",
":FrameworksCoreTests_version_1_nosys",
diff --git a/core/tests/coretests/apks/res_upgrade/Android.bp b/core/tests/coretests/apks/res_upgrade/Android.bp
deleted file mode 100644
index c58614f2c946..000000000000
--- a/core/tests/coretests/apks/res_upgrade/Android.bp
+++ /dev/null
@@ -1,22 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test_helper_app {
- name: "FrameworksCoreTests_res_version_before",
- defaults: ["FrameworksCoreTests_apks_defaults"],
- resource_dirs: ["res_before"],
- certificate: ":FrameworksCoreTests_unit_test_cert",
-}
-
-android_test_helper_app {
- name: "FrameworksCoreTests_res_version_after",
- defaults: ["FrameworksCoreTests_apks_defaults"],
- resource_dirs: ["res_after"],
- certificate: ":FrameworksCoreTests_unit_test_cert",
-}
diff --git a/core/tests/coretests/apks/res_upgrade/AndroidManifest.xml b/core/tests/coretests/apks/res_upgrade/AndroidManifest.xml
deleted file mode 100644
index 1c607c9fd249..000000000000
--- a/core/tests/coretests/apks/res_upgrade/AndroidManifest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2021 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.frameworks.coretests.res_version">
- <application android:hasCode="false"/>
-</manifest>
diff --git a/core/tests/coretests/apks/res_upgrade/res_after/values/values.xml b/core/tests/coretests/apks/res_upgrade/res_after/values/values.xml
deleted file mode 100644
index db4fd54c7aee..000000000000
--- a/core/tests/coretests/apks/res_upgrade/res_after/values/values.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- ~ Copyright (C) 2021 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<resources>
- <string name="version">after</string>
- <public type="string" name="version" id="0x7f010000"/>
-</resources>
diff --git a/core/tests/coretests/apks/res_upgrade/res_before/values/values.xml b/core/tests/coretests/apks/res_upgrade/res_before/values/values.xml
deleted file mode 100644
index 63fc79020e3f..000000000000
--- a/core/tests/coretests/apks/res_upgrade/res_before/values/values.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- ~ Copyright (C) 2021 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<resources>
- <string name="version">before</string>
- <public type="string" name="version" id="0x7f010000"/>
-</resources>
diff --git a/core/tests/coretests/src/android/content/ContextTest.java b/core/tests/coretests/src/android/content/ContextTest.java
index 8488a84dbe01..d1776fb7e5c1 100644
--- a/core/tests/coretests/src/android/content/ContextTest.java
+++ b/core/tests/coretests/src/android/content/ContextTest.java
@@ -25,23 +25,15 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.app.ActivityThread;
-import android.app.PendingIntent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageManager;
import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.inputmethodservice.InputMethodService;
import android.media.ImageReader;
-import android.os.FileUtils;
import android.os.UserHandle;
import android.view.Display;
@@ -50,20 +42,12 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
-import com.android.compatibility.common.util.ShellIdentityUtils;
-import com.android.frameworks.coretests.R;
-
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
/**
- * Build/Install/Run:
- * atest FrameworksCoreTests:ContextTest
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:ContextTest
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -232,132 +216,6 @@ public class ContextTest {
assertFalse(context.isUiContext());
}
- private static class TestReceiver extends BroadcastReceiver implements AutoCloseable {
- private static final String INTENT_ACTION = "com.android.server.pm.test.test_app.action";
- private final ArrayBlockingQueue<Intent> mResults = new ArrayBlockingQueue<>(1);
-
- public IntentSender makeIntentSender() {
- return PendingIntent.getBroadcast(getContext(), 0, new Intent(INTENT_ACTION),
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED)
- .getIntentSender();
- }
-
- public void waitForIntent() throws InterruptedException {
- assertNotNull(mResults.poll(30, TimeUnit.SECONDS));
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- mResults.add(intent);
- }
-
- public void register() {
- getContext().registerReceiver(this, new IntentFilter(INTENT_ACTION));
- }
-
- @Override
- public void close() throws Exception {
- getContext().unregisterReceiver(this);
- }
-
- private Context getContext() {
- return InstrumentationRegistry.getInstrumentation().getContext();
- }
- }
-
- @Test
- public void applicationContextBeforeAndAfterUpgrade() throws Exception {
- final Context context = InstrumentationRegistry.getInstrumentation().getContext();
- final String testPackageName = "com.android.frameworks.coretests.res_version";
- try {
- final PackageManager pm = context.getPackageManager();
- final int versionRes = 0x7f010000;
-
- final Context appContext = ApplicationProvider.getApplicationContext();
- installApk(appContext, R.raw.res_version_before);
-
- ApplicationInfo info = pm.getApplicationInfo(testPackageName, 0);
- final Context beforeContext = appContext.createApplicationContext(info, 0);
- assertEquals("before", beforeContext.getResources().getString(versionRes));
-
- installApk(appContext, R.raw.res_version_after);
-
- info = pm.getApplicationInfo(testPackageName, 0);
- final Context afterContext = appContext.createApplicationContext(info, 0);
- assertEquals("before", beforeContext.createConfigurationContext(Configuration.EMPTY)
- .getResources().getString(versionRes));
- assertEquals("after", afterContext.createConfigurationContext(Configuration.EMPTY)
- .getResources().getString(versionRes));
- assertNotEquals(beforeContext.getPackageResourcePath(),
- afterContext.getPackageResourcePath());
- } finally {
- uninstallPackage(context, testPackageName);
- }
- }
-
- @Test
- public void packageContextBeforeAndAfterUpgrade() throws Exception {
- final Context context = InstrumentationRegistry.getInstrumentation().getContext();
- final String testPackageName = "com.android.frameworks.coretests.res_version";
- try {
- final int versionRes = 0x7f010000;
- final Context appContext = ApplicationProvider.getApplicationContext();
- installApk(appContext, R.raw.res_version_before);
-
- final Context beforeContext = appContext.createPackageContext(testPackageName, 0);
- assertEquals("before", beforeContext.getResources().getString(versionRes));
-
- installApk(appContext, R.raw.res_version_after);
-
- final Context afterContext = appContext.createPackageContext(testPackageName, 0);
- assertEquals("before", beforeContext.createConfigurationContext(Configuration.EMPTY)
- .getResources().getString(versionRes));
- assertEquals("after", afterContext.createConfigurationContext(Configuration.EMPTY)
- .getResources().getString(versionRes));
- assertNotEquals(beforeContext.getPackageResourcePath(),
- afterContext.getPackageResourcePath());
- } finally {
- uninstallPackage(context, testPackageName);
- }
- }
-
- private void installApk(Context context, int rawApkResId) throws Exception {
- final PackageManager pm = context.getPackageManager();
- final PackageInstaller pi = pm.getPackageInstaller();
- final PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
- PackageInstaller.SessionParams.MODE_FULL_INSTALL);
- final int sessionId = pi.createSession(params);
-
- try (PackageInstaller.Session session = pi.openSession(sessionId)) {
- // Copy the apk to the install session.
- final Resources resources = context.getResources();
- try (InputStream is = resources.openRawResource(rawApkResId);
- OutputStream sessionOs = session.openWrite("base", 0, -1)) {
- FileUtils.copy(is, sessionOs);
- }
-
- // Wait for the installation to finish
- try (TestReceiver receiver = new TestReceiver()) {
- receiver.register();
- ShellIdentityUtils.invokeMethodWithShellPermissions(session,
- (s) -> {
- s.commit(receiver.makeIntentSender());
- return true;
- });
- receiver.waitForIntent();
- }
- }
- }
-
- private void uninstallPackage(Context context, String packageName) throws Exception {
- try (TestReceiver receiver = new TestReceiver()) {
- receiver.register();
- final PackageInstaller pi = context.getPackageManager().getPackageInstaller();
- pi.uninstall(packageName, receiver.makeIntentSender());
- receiver.waitForIntent();
- }
- }
-
private Context createUiContext() {
final Context appContext = ApplicationProvider.getApplicationContext();
final DisplayManager displayManager = appContext.getSystemService(DisplayManager.class);
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 2b35bcd9a3ea..c90833c5b8f2 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.createApplicationContext(info, 0), classLoader);
+ mContext.createPackageContext(pkg, 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 fd9a53695e6c..7c5d09c3c5ce 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,7 +4705,8 @@ public final class ProcessList {
});
}
- mService.mActivityTaskManager.updateAssetConfiguration(targetProcesses, updateFrameworkRes);
+ mService.mActivityTaskManager.updateAssetConfiguration(
+ updateFrameworkRes ? null : targetProcesses);
}
@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 569c11be01e7..2bf78e9b1a2c 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -4158,21 +4158,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
+ * @param processes the processes that needs to update the asset configuration, if none
+ * updates the global configuration for all processes.
*/
- public void updateAssetConfiguration(List<WindowProcessController> processes,
- boolean updateFrameworkRes) {
+ public void updateAssetConfiguration(List<WindowProcessController> processes) {
synchronized (mGlobalLock) {
final int assetSeq = increaseAssetConfigurationSeq();
- if (updateFrameworkRes) {
+ // Update the global configuration if the no target processes
+ if (processes == null) {
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);