diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2021-10-25 12:26:27 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-10-25 12:26:27 +0000 |
| commit | cff5e32516f04b69e135bc49e98164e240da696f (patch) | |
| tree | 1fa331c3a5c3deff0d2ed3e25e7983b77ed2a1c0 /core/java/android | |
| parent | defbe2ff4a694780e9982215c95a3f644ff698b2 (diff) | |
| parent | acfcc90ebd40be13b5058529d2b77dd57cbe2c8f (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.java | 34 | ||||
| -rw-r--r-- | core/java/android/appwidget/AppWidgetHostView.java | 11 | ||||
| -rw-r--r-- | core/java/android/widget/RemoteViews.java | 7 | ||||
| -rw-r--r-- | core/java/android/widget/RemoteViewsAdapter.java | 2 |
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; } |
