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

Commit 3662ca14 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Trigger Augmented Autofill when the standard service is not set."

parents 59352523 df30f270
Loading
Loading
Loading
Loading
+28 −9
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package android.view.autofill;

import static android.service.autofill.FillRequest.FLAG_AUGMENTED_AUTOFILL_REQUEST;
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
import static android.view.autofill.Helper.sDebug;
import static android.view.autofill.Helper.sVerbose;
@@ -228,6 +227,7 @@ public final class AutofillManager {
    /** @hide */ public static final int FLAG_ADD_CLIENT_ENABLED = 0x1;
    /** @hide */ public static final int FLAG_ADD_CLIENT_DEBUG = 0x2;
    /** @hide */ public static final int FLAG_ADD_CLIENT_VERBOSE = 0x4;
    /** @hide */ public static final int FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY = 0x8;

    /** @hide */ public static final int FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY = 0x1;

@@ -520,6 +520,13 @@ public final class AutofillManager {
    @GuardedBy("mLock")
    private boolean mForAugmentedAutofillOnly;

    /**
     * When set, standard autofill is enabled, but sessions can still be created for augmented
     * autofill only.
     */
    @GuardedBy("mLock")
    private boolean mEnabledForAugmentedAutofillOnly;

    /** @hide */
    public interface AutofillClient {
        /**
@@ -946,7 +953,7 @@ public final class AutofillManager {

        ensureServiceClientAddedIfNeededLocked();

        if (!mEnabled) {
        if (!mEnabled && !mEnabledForAugmentedAutofillOnly) {
            if (sVerbose) Log.v(TAG, "ignoring notifyViewEntered(" + id + "): disabled");

            if (mCallback != null) {
@@ -988,7 +995,7 @@ public final class AutofillManager {
    void notifyViewExitedLocked(@NonNull View view) {
        ensureServiceClientAddedIfNeededLocked();

        if (mEnabled && isActiveLocked()) {
        if ((mEnabled || mEnabledForAugmentedAutofillOnly) && isActiveLocked()) {
            // dont notify exited when Activity is already in background
            if (!isClientDisablingEnterExitEvent()) {
                final AutofillId id = view.getAutofillId();
@@ -1104,7 +1111,7 @@ public final class AutofillManager {

        ensureServiceClientAddedIfNeededLocked();

        if (!mEnabled) {
        if (!mEnabled && !mEnabledForAugmentedAutofillOnly) {
            if (sVerbose) {
                Log.v(TAG, "ignoring notifyViewEntered(" + id + "): disabled");
            }
@@ -1155,7 +1162,7 @@ public final class AutofillManager {
    private void notifyViewExitedLocked(@NonNull View view, int virtualId) {
        ensureServiceClientAddedIfNeededLocked();

        if (mEnabled && isActiveLocked()) {
        if ((mEnabled || mEnabledForAugmentedAutofillOnly) && isActiveLocked()) {
            // don't notify exited when Activity is already in background
            if (!isClientDisablingEnterExitEvent()) {
                final AutofillId id = getAutofillId(view, virtualId);
@@ -1674,14 +1681,17 @@ public final class AutofillManager {
    private void startSessionLocked(@NonNull AutofillId id, @NonNull Rect bounds,
            @NonNull AutofillValue value, int flags) {
        if (mEnteredForAugmentedAutofillIds != null
                && mEnteredForAugmentedAutofillIds.contains(id)) {
                && mEnteredForAugmentedAutofillIds.contains(id)
                || mEnabledForAugmentedAutofillOnly) {
            if (sVerbose) Log.v(TAG, "Starting session for augmented autofill on " + id);
            flags |= FLAG_AUGMENTED_AUTOFILL_REQUEST;
            flags |= FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY;
        }
        if (sVerbose) {
            Log.v(TAG, "startSessionLocked(): id=" + id + ", bounds=" + bounds + ", value=" + value
                    + ", flags=" + flags + ", state=" + getStateAsStringLocked()
                    + ", compatMode=" + isCompatibilityModeEnabledLocked()
                    + ", augmentedOnly=" + mForAugmentedAutofillOnly
                    + ", enabledAugmentedOnly=" + mEnabledForAugmentedAutofillOnly
                    + ", enteredIds=" + mEnteredIds);
        }
        if (mState != STATE_UNKNOWN && !isFinishedLocked() && (flags & FLAG_MANUAL_REQUEST) == 0) {
@@ -1776,7 +1786,8 @@ public final class AutofillManager {

    @GuardedBy("mLock")
    private void ensureServiceClientAddedIfNeededLocked() {
        if (getClient() == null) {
        final AutofillClient client = getClient();
        if (client == null) {
            return;
        }

@@ -1785,11 +1796,18 @@ public final class AutofillManager {
            try {
                final int userId = mContext.getUserId();
                final SyncResultReceiver receiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
                mService.addClient(mServiceClient, userId, receiver);
                mService.addClient(mServiceClient, client.autofillClientGetComponentName(),
                        userId, receiver);
                final int flags = receiver.getIntResult();
                mEnabled = (flags & FLAG_ADD_CLIENT_ENABLED) != 0;
                sDebug = (flags & FLAG_ADD_CLIENT_DEBUG) != 0;
                sVerbose = (flags & FLAG_ADD_CLIENT_VERBOSE) != 0;
                mEnabledForAugmentedAutofillOnly = (flags
                        & FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY) != 0;
                if (sVerbose) {
                    Log.v(TAG, "receiver results: flags=" + flags + " enabled=" + mEnabled
                            + ", enabledForAugmentedOnly: " + mEnabledForAugmentedAutofillOnly);
                }
                final IAutoFillManager service = mService;
                final IAutoFillManagerClient serviceClient = mServiceClient;
                mServiceClientCleaner = Cleaner.create(this, () -> {
@@ -2406,6 +2424,7 @@ public final class AutofillManager {
            pw.print(" ("); pw.print(client.autofillClientGetActivityToken()); pw.println(')');
        }
        pw.print(pfx); pw.print("enabled: "); pw.println(mEnabled);
        pw.print(pfx); pw.print("enabledAugmentedOnly: "); pw.println(mForAugmentedAutofillOnly);
        pw.print(pfx); pw.print("hasService: "); pw.println(mService != null);
        pw.print(pfx); pw.print("hasCallback: "); pw.println(mCallback != null);
        pw.print(pfx); pw.print("onInvisibleCalled "); pw.println(mOnInvisibleCalled);
+2 −1
Original line number Diff line number Diff line
@@ -37,7 +37,8 @@ import com.android.internal.os.IResultReceiver;
 */
oneway interface IAutoFillManager {
    // Returns flags: FLAG_ADD_CLIENT_ENABLED | FLAG_ADD_CLIENT_DEBUG | FLAG_ADD_CLIENT_VERBOSE
    void addClient(in IAutoFillManagerClient client, int userId, in IResultReceiver result);
    void addClient(in IAutoFillManagerClient client, in ComponentName componentName, int userId,
        in IResultReceiver result);
    void removeClient(in IAutoFillManagerClient client, int userId);
    void startSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId,
        in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags,
+6 −4
Original line number Diff line number Diff line
@@ -942,12 +942,14 @@ public final class AutofillManagerService

    final class AutoFillManagerServiceStub extends IAutoFillManager.Stub {
        @Override
        public void addClient(IAutoFillManagerClient client, int userId,
                @NonNull IResultReceiver receiver) {
        public void addClient(IAutoFillManagerClient client, ComponentName componentName,
                int userId, IResultReceiver receiver) {
            int flags = 0;
            synchronized (mLock) {
                if (getServiceForUserLocked(userId).addClientLocked(client)) {
                    flags |= AutofillManager.FLAG_ADD_CLIENT_ENABLED;
                final int enabledFlags = getServiceForUserLocked(userId).addClientLocked(client,
                        componentName);
                if (enabledFlags != 0) {
                    flags |= enabledFlags;
                }
                if (sDebug) {
                    flags |= AutofillManager.FLAG_ADD_CLIENT_DEBUG;
+39 −17
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.server.autofill;

import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
import static android.view.autofill.AutofillManager.ACTION_START_SESSION;
import static android.view.autofill.AutofillManager.FLAG_ADD_CLIENT_ENABLED;
import static android.view.autofill.AutofillManager.FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY;
import static android.view.autofill.AutofillManager.FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY;
import static android.view.autofill.AutofillManager.NO_SESSION;

@@ -54,7 +56,6 @@ import android.service.autofill.FieldClassification;
import android.service.autofill.FieldClassification.Match;
import android.service.autofill.FillEventHistory;
import android.service.autofill.FillEventHistory.Event;
import android.service.autofill.FillRequest;
import android.service.autofill.FillResponse;
import android.service.autofill.IAutoFillService;
import android.service.autofill.UserData;
@@ -242,13 +243,28 @@ final class AutofillManagerServiceImpl
        return mAutofillCompatState.getUrlBarResourceIds(packageName, mUserId);
    }

    /**
     * Adds the client and return the proper flags
     *
     * @return {@code 0} if disabled, {@code FLAG_ADD_CLIENT_ENABLED} if enabled (it might be
     * OR'ed with {@code FLAG_AUGMENTED_AUTOFILL_REQUEST}).
     */
    @GuardedBy("mLock")
    boolean addClientLocked(IAutoFillManagerClient client) {
    int addClientLocked(IAutoFillManagerClient client, ComponentName componentName) {
        if (mClients == null) {
            mClients = new RemoteCallbackList<>();
        }
        mClients.register(client);
        return isEnabledLocked();

        if (isEnabledLocked()) return FLAG_ADD_CLIENT_ENABLED;

        // Check if it's enabled for augmented autofill
        if (isSetupCompletedLocked() && isWhitelistedForAugmentedAutofillLocked(componentName)) {
            return FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY;
        }

        // No flags / disabled
        return 0;
    }

    @GuardedBy("mLock")
@@ -286,7 +302,7 @@ final class AutofillManagerServiceImpl
     *
     * @return {@code long} whose right-most 32 bits represent the session id (which is always
     * non-negative), and the left-most contains extra flags (currently either {@code 0} or
     * {@link FillRequest#FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY}).
     * {@link AutofillManager#FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY}).
     */
    @GuardedBy("mLock")
    long startSessionLocked(@NonNull IBinder activityToken, int taskId, int uid,
@@ -294,26 +310,27 @@ final class AutofillManagerServiceImpl
            @NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback,
            @NonNull ComponentName componentName, boolean compatMode,
            boolean bindInstantServiceAllowed, int flags) {
        if (!isEnabledLocked()) {
        // FLAG_AUGMENTED_AUTOFILL_REQUEST is set in the flags when standard autofill is disabled
        // but the package is whitelisted for augmented autofill
        boolean forAugmentedAutofillOnly = (flags
                & FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY) != 0;
        if (!isEnabledLocked() && !forAugmentedAutofillOnly) {
            return 0;
        }

        final String shortComponentName = componentName.toShortString();
        boolean forAugmentedAutofillOnly = false;

        if (isAutofillDisabledLocked(componentName)) {
            // Service disabled autofill; that means no session, unless the activity is whitelisted
            // for augmented autofill
        if (!forAugmentedAutofillOnly && isAutofillDisabledLocked(componentName)) {
            // Standard autofill is enabled, but service disabled autofill for this activity; that
            // means no session, unless the activity is whitelisted for augmented autofill
            if (isWhitelistedForAugmentedAutofillLocked(componentName)) {
                if (sDebug) {
                    Slog.d(TAG, "startSession(" + shortComponentName + "): disabled by service but "
                    Slog.d(TAG, "startSession(" + componentName + "): disabled by service but "
                            + "whitelisted for augmented autofill");
                }
                forAugmentedAutofillOnly = true;

            } else {
                if (sDebug) {
                    Slog.d(TAG, "startSession(" + shortComponentName + "): ignored because "
                    Slog.d(TAG, "startSession(" + componentName + "): ignored because "
                            + "disabled by service and not whitelisted for augmented autofill");
                }
                final IAutoFillManagerClient client = IAutoFillManagerClient.Stub
@@ -323,7 +340,7 @@ final class AutofillManagerServiceImpl
                            /* autofillableIds= */ null);
                } catch (RemoteException e) {
                    Slog.w(TAG,
                            "Could not notify " + shortComponentName + " that it's disabled: " + e);
                            "Could not notify " + componentName + " that it's disabled: " + e);
                }

                return NO_SESSION;
@@ -345,9 +362,11 @@ final class AutofillManagerServiceImpl
            return NO_SESSION;
        }

        // Service can be null when it's only for augmented autofill
        String servicePackageName = mInfo == null ? null : mInfo.getServiceInfo().packageName;
        final String historyItem =
                "id=" + newSession.id + " uid=" + uid + " a=" + shortComponentName
                + " s=" + mInfo.getServiceInfo().packageName
                "id=" + newSession.id + " uid=" + uid + " a=" + componentName.toShortString()
                + " s=" + servicePackageName
                + " u=" + mUserId + " i=" + autofillId + " b=" + virtualBounds
                + " hc=" + hasCallback + " f=" + flags + " aa=" + forAugmentedAutofillOnly;
        mMaster.logRequestLocked(historyItem);
@@ -485,9 +504,12 @@ final class AutofillManagerServiceImpl

        assertCallerLocked(componentName, compatMode);

        // It's null when the session is just for augmented autofill
        final ComponentName serviceComponentName = mInfo == null ? null
                : mInfo.getServiceInfo().getComponentName();
        final Session newSession = new Session(this, mUi, getContext(), mHandler, mUserId, mLock,
                sessionId, taskId, uid, activityToken, appCallbackToken, hasCallback,
                mUiLatencyHistory, mWtfHistory, mInfo.getServiceInfo().getComponentName(),
                mUiLatencyHistory, mWtfHistory, serviceComponentName,
                componentName, compatMode, bindInstantServiceAllowed, forAugmentedAutofillOnly,
                flags);
        mSessions.put(newSession.id, newSession);
+28 −4
Original line number Diff line number Diff line
@@ -185,6 +185,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
    @GuardedBy("mLock")
    private DeathRecipient mClientVulture;

    /**
     * Reference to the remote service.
     *
     * <p>Only {@code null} when the session is for augmented autofill only.
     */
    @Nullable
    private final RemoteFillService mRemoteFillService;

    @GuardedBy("mLock")
@@ -293,6 +299,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
    private final IAssistDataReceiver mAssistReceiver = new IAssistDataReceiver.Stub() {
        @Override
        public void onHandleAssistData(Bundle resultData) throws RemoteException {
            if (mRemoteFillService == null) {
                wtf(null, "onHandleAssistData() called without a remote service. "
                        + "mForAugmentedAutofillOnly: %s", mForAugmentedAutofillOnly);
                return;
            }
            final AssistStructure structure = resultData.getParcelable(ASSIST_KEY_STRUCTURE);
            if (structure == null) {
                Slog.e(TAG, "No assist structure - app might have crashed providing it");
@@ -527,6 +538,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
     */
    @GuardedBy("mLock")
    private void cancelCurrentRequestLocked() {
        if (mRemoteFillService == null) {
            wtf(null, "cancelCurrentRequestLocked() called without a remote service. "
                    + "mForAugmentedAutofillOnly: %s", mForAugmentedAutofillOnly);
            return;
        }
        final int canceledRequest = mRemoteFillService.cancelCurrentRequest();

        // Remove the FillContext as there will never be a response for the service
@@ -608,7 +624,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
            @NonNull Context context, @NonNull Handler handler, int userId, @NonNull Object lock,
            int sessionId, int taskId, int uid, @NonNull IBinder activityToken,
            @NonNull IBinder client, boolean hasCallback, @NonNull LocalLog uiLatencyHistory,
            @NonNull LocalLog wtfHistory, @NonNull ComponentName serviceComponentName,
            @NonNull LocalLog wtfHistory, @Nullable ComponentName serviceComponentName,
            @NonNull ComponentName componentName, boolean compatMode,
            boolean bindInstantServiceAllowed, boolean forAugmentedAutofillOnly, int flags) {
        if (sessionId < 0) {
@@ -623,7 +639,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
        mLock = lock;
        mUi = ui;
        mHandler = handler;
        mRemoteFillService = new RemoteFillService(context, serviceComponentName, userId, this,
        mRemoteFillService = serviceComponentName == null ? null
                : new RemoteFillService(context, serviceComponentName, userId, this,
                        bindInstantServiceAllowed);
        mActivityToken = activityToken;
        mHasCallback = hasCallback;
@@ -2035,6 +2052,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                    + id + " destroyed");
            return;
        }
        if (mRemoteFillService == null) {
            wtf(null, "callSaveLocked() called without a remote service. "
                    + "mForAugmentedAutofillOnly: %s", mForAugmentedAutofillOnly);
            return;
        }

        if (sVerbose) Slog.v(TAG, "callSaveLocked(): mViewStates=" + mViewStates);

@@ -3045,8 +3067,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
            pw.print(prefix); pw.print("mAugmentedAutofillableIds: ");
            pw.println(mAugmentedAutofillableIds);
        }
        if (mRemoteFillService != null) {
            mRemoteFillService.dump(prefix, pw);
        }
    }

    private static void dumpRequestLog(@NonNull PrintWriter pw, @NonNull LogMaker log) {
        pw.print("CAT="); pw.print(log.getCategory());