Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59e5fa40 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Check if APK paths are valid right before creating the context." into...

Merge "Check if APK paths are valid right before creating the context." into sc-v2-dev am: cff5e325 am: fc3b9c48

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16004854

Change-Id: I2a81b2cee43744e32a3546f93498377d1367a090
parents 2be31ef8 fc3b9c48
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -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);
    }

}
+7 −4
Original line number Diff line number Diff line
@@ -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);
+5 −2
Original line number Diff line number Diff line
@@ -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) {
+1 −1
Original line number Diff line number Diff line
@@ -408,7 +408,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
        }

        @Override
        protected Context getRemoteContext() {
        protected Context getRemoteContextEnsuringCorrectCachedApkPath() {
            return null;
        }