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

Commit 938ad012 authored by Tim Yu's avatar Tim Yu Committed by Evelyn Torres
Browse files

[RESTRICT AUTOMERGE] 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 c15f90b5
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -16,8 +16,13 @@

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;
@@ -26,8 +31,11 @@ import android.app.assist.AssistStructure.WindowNode;
import android.app.slice.Slice;
import android.app.slice.SliceItem;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.drawable.Icon;
import android.metrics.LogMaker;
import android.os.UserHandle;
import android.os.UserManager;
import android.service.autofill.Dataset;
import android.service.autofill.InternalSanitizer;
import android.service.autofill.SaveInfo;
@@ -41,6 +49,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;

@@ -95,6 +104,26 @@ 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();
        Context c = context.createContextAsUser(UserHandle.of(userId), /* flags= */ 0);
        if (sDebug) {
            Slog.d(
                    TAG,
                    "Current User: "
                            + userId
                            + ", context created as: "
                            + c.getContentResolver().getUserId());
        }
        return c;
    }

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

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

    private final @NonNull AnchoredWindow mWindow;

@@ -129,6 +130,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, @Nullable String filterText,
            @NonNull OverlayControl overlayControl, @NonNull CharSequence serviceLabel,
@@ -138,6 +141,7 @@ final class FillUi {
        mCallback = callback;
        mFullScreen = isFullScreen(context);
        mContext = new ContextThemeWrapper(context, mThemeId);
        mUserContext = Helper.getUserContext(mContext);

        final LayoutInflater inflater = LayoutInflater.from(mContext);

@@ -225,7 +229,7 @@ final class FillUi {
                    throw new RuntimeException("Permission error accessing RemoteView");
                }
                content = response.getPresentation().applyWithTheme(
                        mContext, decor, interceptionHandler, mThemeId);
                        mUserContext, decor, interceptionHandler, mThemeId);
                container.addView(content);
            } catch (RuntimeException e) {
                callback.onCanceled();
@@ -266,7 +270,7 @@ final class FillUi {
            if (headerPresentation != null) {
                interactionBlocker = newInteractionBlocker();
                mHeader = headerPresentation.applyWithTheme(
                        mContext, null, interactionBlocker, mThemeId);
                        mUserContext, null, interactionBlocker, mThemeId);
                final LinearLayout headerContainer =
                        decor.findViewById(R.id.autofill_dataset_header);
                applyCancelAction(mHeader, response.getCancelIds());
@@ -285,7 +289,7 @@ final class FillUi {
                        interactionBlocker = newInteractionBlocker();
                    }
                    mFooter = footerPresentation.applyWithTheme(
                            mContext, null, interactionBlocker, mThemeId);
                            mUserContext, null, interactionBlocker, mThemeId);
                    applyCancelAction(mFooter, response.getCancelIds());
                    // Footer not supported on some platform e.g. TV
                    if (sVerbose) Slog.v(TAG, "adding footer");
@@ -314,7 +318,7 @@ final class FillUi {
                    try {
                        if (sVerbose) Slog.v(TAG, "setting remote view for " + focusedViewId);
                        view = presentation.applyWithTheme(
                                mContext, null, interceptionHandler, mThemeId);
                                mUserContext, null, interceptionHandler, mThemeId);
                    } catch (RuntimeException e) {
                        Slog.e(TAG, "Error inflating remote views", e);
                        continue;
@@ -775,6 +779,8 @@ final class FillUi {
        pw.print(prefix); pw.print("mContentHeight: "); pw.println(mContentHeight);
        pw.print(prefix); pw.print("mDestroyed: "); pw.println(mDestroyed);
        pw.print(prefix); pw.print("theme id: "); pw.print(mThemeId);
        pw.print(prefix); pw.print("mContext: "); pw.println(mContext);
        pw.print(prefix); pw.print("mUserContext: "); pw.println(mUserContext);
        switch (mThemeId) {
            case THEME_ID_DARK:
                pw.println(" (dark)");
+4 −1
Original line number Diff line number Diff line
@@ -172,6 +172,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,
@@ -187,7 +189,7 @@ final class SaveUi {
        mComponentName = componentName;
        mCompatMode = compatMode;

        context = new ContextThemeWrapper(context, mThemeId) {
        context = new ContextThemeWrapper(Helper.getUserContext(context), mThemeId) {
            @Override
            public void startActivity(Intent intent) {
                if (resolveActivity(intent) == null) {
@@ -224,6 +226,7 @@ final class SaveUi {
                return null;
            }
        };

        final LayoutInflater inflater = LayoutInflater.from(context);
        final View view = inflater.inflate(R.layout.autofill_save, null);