summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2021-10-25 12:26:27 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2021-10-25 12:26:27 +0000
commitcff5e32516f04b69e135bc49e98164e240da696f (patch)
tree1fa331c3a5c3deff0d2ed3e25e7983b77ed2a1c0 /core/java/android
parentdefbe2ff4a694780e9982215c95a3f644ff698b2 (diff)
parentacfcc90ebd40be13b5058529d2b77dd57cbe2c8f (diff)
Merge "Check if APK paths are valid right before creating the context." into sc-v2-dev
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/LoadedApk.java34
-rw-r--r--core/java/android/appwidget/AppWidgetHostView.java11
-rw-r--r--core/java/android/widget/RemoteViews.java7
-rw-r--r--core/java/android/widget/RemoteViewsAdapter.java2
4 files changed, 47 insertions, 7 deletions
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index a2c9795204ad..74208c3a4aff 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -2134,4 +2134,38 @@ public final class LoadedApk {
final IBinder mService;
}
}
+
+ /**
+ * Check if the Apk paths in the cache are correct, and update them if they are not.
+ * @hide
+ */
+ public static void checkAndUpdateApkPaths(ApplicationInfo expectedAppInfo) {
+ // Get the LoadedApk from the cache
+ ActivityThread activityThread = ActivityThread.currentActivityThread();
+ if (activityThread == null) {
+ Log.e(TAG, "Cannot find activity thread");
+ return;
+ }
+ checkAndUpdateApkPaths(activityThread, expectedAppInfo, /* cacheWithCode */ true);
+ checkAndUpdateApkPaths(activityThread, expectedAppInfo, /* cacheWithCode */ false);
+ }
+
+ private static void checkAndUpdateApkPaths(ActivityThread activityThread,
+ ApplicationInfo expectedAppInfo, boolean cacheWithCode) {
+ String expectedCodePath = expectedAppInfo.getCodePath();
+ LoadedApk loadedApk = activityThread.peekPackageInfo(
+ expectedAppInfo.packageName, /* includeCode= */ cacheWithCode);
+ // If there is load apk cached, or if the cache is valid, don't do anything.
+ if (loadedApk == null || loadedApk.getApplicationInfo() == null
+ || loadedApk.getApplicationInfo().getCodePath().equals(expectedCodePath)) {
+ return;
+ }
+ // Duplicate framework logic
+ List<String> oldPaths = new ArrayList<>();
+ LoadedApk.makePaths(activityThread, expectedAppInfo, oldPaths);
+
+ // Force update the LoadedApk instance, which should update the reference in the cache
+ loadedApk.updateApplicationInfo(expectedAppInfo, oldPaths);
+ }
+
}
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index dd147cc26e59..eb10f097f37f 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityOptions;
+import android.app.LoadedApk;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
@@ -554,7 +555,7 @@ public class AppWidgetHostView extends FrameLayout {
}
// Prepare a local reference to the remote Context so we're ready to
// inflate any requested LayoutParams.
- mRemoteContext = getRemoteContext();
+ mRemoteContext = getRemoteContextEnsuringCorrectCachedApkPath();
int layoutId = rvToApply.getLayoutId();
if (rvToApply.canRecycleView(mView)) {
@@ -616,7 +617,7 @@ public class AppWidgetHostView extends FrameLayout {
private void inflateAsync(@NonNull RemoteViews remoteViews) {
// Prepare a local reference to the remote Context so we're ready to
// inflate any requested LayoutParams.
- mRemoteContext = getRemoteContext();
+ mRemoteContext = getRemoteContextEnsuringCorrectCachedApkPath();
int layoutId = remoteViews.getLayoutId();
if (mLastExecutionSignal != null) {
@@ -718,8 +719,10 @@ public class AppWidgetHostView extends FrameLayout {
* purposes of reading remote resources.
* @hide
*/
- protected Context getRemoteContext() {
+ protected Context getRemoteContextEnsuringCorrectCachedApkPath() {
try {
+ ApplicationInfo expectedAppInfo = mInfo.providerInfo.applicationInfo;
+ LoadedApk.checkAndUpdateApkPaths(expectedAppInfo);
// Return if cloned successfully, otherwise default
Context newContext = mContext.createApplicationContext(
mInfo.providerInfo.applicationInfo,
@@ -765,7 +768,7 @@ public class AppWidgetHostView extends FrameLayout {
try {
if (mInfo != null) {
- Context theirContext = getRemoteContext();
+ Context theirContext = getRemoteContextEnsuringCorrectCachedApkPath();
mRemoteContext = theirContext;
LayoutInflater inflater = (LayoutInflater)
theirContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index fe5eb085dc5c..0f309f10c2b7 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -34,6 +34,7 @@ import android.app.Activity;
import android.app.ActivityOptions;
import android.app.ActivityThread;
import android.app.Application;
+import android.app.LoadedApk;
import android.app.PendingIntent;
import android.app.RemoteInput;
import android.appwidget.AppWidgetHostView;
@@ -5475,7 +5476,8 @@ public class RemoteViews implements Parcelable, Filter {
// user. So build a context that loads resources from that user but
// still returns the current users userId so settings like data / time formats
// are loaded without requiring cross user persmissions.
- final Context contextForResources = getContextForResources(context);
+ final Context contextForResources =
+ getContextForResourcesEnsuringCorrectCachedApkPaths(context);
if (colorResources != null) {
colorResources.apply(contextForResources);
}
@@ -5853,13 +5855,14 @@ public class RemoteViews implements Parcelable, Filter {
}
}
- private Context getContextForResources(Context context) {
+ private Context getContextForResourcesEnsuringCorrectCachedApkPaths(Context context) {
if (mApplication != null) {
if (context.getUserId() == UserHandle.getUserId(mApplication.uid)
&& context.getPackageName().equals(mApplication.packageName)) {
return context;
}
try {
+ LoadedApk.checkAndUpdateApkPaths(mApplication);
return context.createApplicationContext(mApplication,
Context.CONTEXT_RESTRICTED);
} catch (NameNotFoundException e) {
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 6b33428d7fe4..8e293f4b356d 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -408,7 +408,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
}
@Override
- protected Context getRemoteContext() {
+ protected Context getRemoteContextEnsuringCorrectCachedApkPath() {
return null;
}