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

Commit 55d8ed1e authored by Tim Yu's avatar Tim Yu Committed by Markus S
Browse files

[BACKPORT] Fix Autofill Inflating as User 0

Autofill will inflate views as the current foreground user instead of
the system_server user (0).

Bug: 327137311
Test: atest CtsAutoFillServiceTestCases --user-type secondary_user
Flag: EXEMPT security bug fix
Cherrypick-From: https://googleplex-android-review.googlesource.com/q/commit:1cdf83b61b533b8174b4fae5b1bd15039751ed42
Merged-In: I8a2c96259976e61d297dec914d10d86e585a6d6f
Change-Id: I8a2c96259976e61d297dec914d10d86e585a6d6f
parent 6777c2de
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -16,14 +16,24 @@

package com.android.server.autofill;

import static android.Manifest.permission.INTERACT_ACROSS_USERS;

import static com.android.server.autofill.Helper.sDebug;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.Icon;
import android.metrics.LogMaker;
import android.os.UserHandle;
import android.os.UserManager;
import android.service.autofill.Dataset;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -33,6 +43,7 @@ import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
import android.widget.RemoteViews;


import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.ArrayUtils;

@@ -97,6 +108,32 @@ public final class Helper {
        return permissionsOk.get();
    }

    /**
     * Creates the context as the foreground user
     *
     * <p>Returns the current context as the current foreground user
     */
    @RequiresPermission(INTERACT_ACROSS_USERS)
    public static Context getUserContext(Context context) {
        int userId = ActivityManager.getCurrentUser();
        String packageName = context.getPackageName();
        try {
            Context c = context.createPackageContextAsUser(packageName, 0, UserHandle.of(userId));
            if (sDebug) {
                Slog.d(
                        TAG,
                        "Current User: "
                                + userId
                                + ", context created as: "
                                + c.getContentResolver().getUserId());
            }
            return c;
        } catch (PackageManager.NameNotFoundException e) {
            Slog.e(TAG, "Create context as " + userId + " failed", e);
            return context;
        }
    }

    /**
     * Checks the URI permissions of the remote view,
     * to see if the current userId is able to access it.
+11 −4
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ final class FillUi {
            new AutofillWindowPresenter();

    private final @NonNull Context mContext;
    private final @NonNull Context mUserContext;

    private final @NonNull AnchoredWindow mWindow;

@@ -128,6 +129,8 @@ final class FillUi {
        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
    }

    // System has all permissions, see b/228957088
    @SuppressWarnings("AndroidFrameworkRequiresPermission")
    FillUi(@NonNull Context context, @NonNull FillResponse response,
           @NonNull AutofillId focusedViewId, @NonNull @Nullable String filterText,
           @NonNull OverlayControl overlayControl, @NonNull CharSequence serviceLabel,
@@ -135,6 +138,8 @@ final class FillUi {
        mCallback = callback;
        mFullScreen = isFullScreen(context);
        mContext = new ContextThemeWrapper(context, THEME_ID);
        mUserContext = Helper.getUserContext(mContext);

        final LayoutInflater inflater = LayoutInflater.from(mContext);

        final RemoteViews headerPresentation = Helper.sanitizeRemoteView(response.getHeader());
@@ -224,7 +229,7 @@ final class FillUi {
                    throw new RuntimeException("Permission error accessing RemoteView");
                }
                response.getPresentation().setApplyTheme(THEME_ID);
                content = response.getPresentation().apply(mContext, decor, interceptionHandler);
                content = response.getPresentation().apply(mUserContext, decor, interceptionHandler);
                container.addView(content);
            } catch (RuntimeException e) {
                callback.onCanceled();
@@ -265,7 +270,7 @@ final class FillUi {
            if (headerPresentation != null) {
                clickBlocker = newClickBlocker();
                headerPresentation.setApplyTheme(THEME_ID);
                mHeader = headerPresentation.apply(mContext, null, clickBlocker);
                mHeader = headerPresentation.apply(mUserContext, null, clickBlocker);
                final LinearLayout headerContainer =
                        decor.findViewById(R.id.autofill_dataset_header);
                if (sVerbose) Slog.v(TAG, "adding header");
@@ -283,7 +288,7 @@ final class FillUi {
                        clickBlocker = newClickBlocker();
                    }
                    footerPresentation.setApplyTheme(THEME_ID);
                    mFooter = footerPresentation.apply(mContext, null, clickBlocker);
                    mFooter = footerPresentation.apply(mUserContext, null, clickBlocker);
                    // Footer not supported on some platform e.g. TV
                    if (sVerbose) Slog.v(TAG, "adding footer");
                    footerContainer.addView(mFooter);
@@ -311,7 +316,7 @@ final class FillUi {
                    try {
                        if (sVerbose) Slog.v(TAG, "setting remote view for " + focusedViewId);
                        presentation.setApplyTheme(THEME_ID);
                        view = presentation.apply(mContext, null, interceptionHandler);
                        view = presentation.apply(mUserContext, null, interceptionHandler);
                    } catch (RuntimeException e) {
                        Slog.e(TAG, "Error inflating remote views", e);
                        continue;
@@ -740,6 +745,8 @@ final class FillUi {
        pw.print(prefix); pw.print("mContentWidth: "); pw.println(mContentWidth);
        pw.print(prefix); pw.print("mContentHeight: "); pw.println(mContentHeight);
        pw.print(prefix); pw.print("mDestroyed: "); pw.println(mDestroyed);
        pw.print(prefix); pw.print("mContext: "); pw.println(mContext);
        pw.print(prefix); pw.print("mUserContext: "); pw.println(mUserContext);
        if (mWindow != null) {
            pw.print(prefix); pw.print("mWindow: ");
            final String prefix2 = prefix + "  ";
+3 −1
Original line number Diff line number Diff line
@@ -144,6 +144,8 @@ final class SaveUi {

    private boolean mDestroyed;

    // System has all permissions, see b/228957088
    @SuppressWarnings("AndroidFrameworkRequiresPermission")
    SaveUi(@NonNull Context context, @NonNull PendingUi pendingUi,
           @NonNull CharSequence serviceLabel, @NonNull Drawable serviceIcon,
           @Nullable String servicePackageName, @NonNull ComponentName componentName,
@@ -157,7 +159,7 @@ final class SaveUi {
        mComponentName = componentName;
        mCompatMode = compatMode;

        context = new ContextThemeWrapper(context, THEME_ID);
        context = new ContextThemeWrapper(Helper.getUserContext(context), THEME_ID);
        final LayoutInflater inflater = LayoutInflater.from(context);
        final View view = inflater.inflate(R.layout.autofill_save, null);