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

Commit ba15db8f authored by Felipe Leme's avatar Felipe Leme
Browse files

Use session id to uniquely identidy autofill ids for multi-session.

This change is need when integrating CustomDescription artifacts (like
CharSequenceTransformation) with SaveInfo.FLAG_DELAY_SAVE, as different
views might have the same autofill id on different activities.

Test: atest CtsAutoFillServiceTestCases:MultiScreenLoginTest
Test: atest CtsAutoFillServiceTestCases # to make sure it didn't break anything

Fixes: 113593220

Change-Id: I7db1df7a56dec7180a2172bb2022b042f115c7b8
parent 91a6b8bf
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1461,7 +1461,7 @@ public class Activity extends ContextThemeWrapper
     */
    @Override
    public AutofillId autofillClientGetNextAutofillId() {
        return new AutofillId(getNextAutofillId());
        return new AutofillId(getAutofillManager(), getNextAutofillId());
    }

    /**
+13 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.view.ViewStructure.HtmlInfo.Builder;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;

import com.android.internal.util.Preconditions;
@@ -72,6 +73,8 @@ public class AssistStructure implements Parcelable {
    boolean mHaveData;

    ComponentName mActivityComponent;
    // Not written to parcel, only used to set session id on virtual node children
    private final int mAutofillSessionId;
    private boolean mIsHomeActivity;
    private int mFlags;

@@ -1846,11 +1849,13 @@ public class AssistStructure implements Parcelable {
        @Override
        public void setAutofillId(@NonNull AutofillId id) {
            mNode.mAutofillId = id;
            mNode.mAutofillId.setSessionId(mAssist.mAutofillSessionId);
        }

        @Override
        public void setAutofillId(@NonNull AutofillId parentId, int virtualId) {
            mNode.mAutofillId = new AutofillId(parentId, virtualId);
            mNode.mAutofillId.setSessionId(mAssist.mAutofillSessionId);
        }

        @Override
@@ -2040,6 +2045,8 @@ public class AssistStructure implements Parcelable {
    public AssistStructure(Activity activity, boolean forAutoFill, int flags) {
        mHaveData = true;
        mActivityComponent = activity.getComponentName();
        final AutofillManager afm = activity.getSystemService(AutofillManager.class);
        mAutofillSessionId = afm == null ? AutofillManager.NO_SESSION : afm.getSessionId();
        mFlags = flags;
        ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
                activity.getActivityToken());
@@ -2056,6 +2063,7 @@ public class AssistStructure implements Parcelable {
    public AssistStructure() {
        mHaveData = true;
        mActivityComponent = null;
        mAutofillSessionId = AutofillManager.NO_SESSION;
        mFlags = 0;
    }

@@ -2063,6 +2071,7 @@ public class AssistStructure implements Parcelable {
    public AssistStructure(Parcel in) {
        mIsHomeActivity = in.readInt() == 1;
        mReceiveChannel = in.readStrongBinder();
        mAutofillSessionId = AutofillManager.NO_SESSION;
    }

    /**
@@ -2082,6 +2091,10 @@ public class AssistStructure implements Parcelable {
            ensureData();
        }
        Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString());
        if (mAutofillSessionId != AutofillManager.NO_SESSION) {
            Log.i(TAG, "Autofill Session ID: " + mAutofillSessionId);
        }

        Log.i(TAG, "Sanitize on write: " + mSanitizeOnWrite);
        Log.i(TAG, "Flags: " + mFlags);
        final int N = getWindowNodeCount();
+11 −4
Original line number Diff line number Diff line
@@ -8251,7 +8251,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (mAutofillId == null) {
            // The autofill id needs to be unique, but its value doesn't matter,
            // so it's better to reuse the accessibility id to save space.
            mAutofillId = new AutofillId(getAutofillViewId());
            mAutofillId = new AutofillId(getAutofillManager(), getAutofillViewId());
        }
        return mAutofillId;
    }
@@ -8313,11 +8313,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            // Ignore reset because it was never explicitly set before.
            return;
        }
        mAutofillId = id;
        if (id != null) {
            // Must create a new id so the session id is preserved.
            final int oldSessionId = mAutofillId.getSessionId();
            mAutofillViewId = id.getViewId();
            mAutofillId = new AutofillId(mAutofillViewId);
            mAutofillId.setSessionId(oldSessionId);
            mPrivateFlags3 |= PFLAG3_AUTOFILLID_EXPLICITLY_SET;
        } else {
            mAutofillId = null;
            mAutofillViewId = NO_ID;
            mPrivateFlags3 &= ~PFLAG3_AUTOFILLID_EXPLICITLY_SET;
        }
@@ -8607,8 +8611,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            structure.setContextClickable(true);
        }
        if (forAutofill) {
            structure.setAutofillId(new AutofillId(getAutofillId(),
                    AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId())));
            final AutofillId autofillId = new AutofillId(getAutofillId(),
                    AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()));
            final AutofillManager afm = getAutofillManager();
            autofillId.setSessionId(afm == null ? AutofillManager.NO_SESSION : afm.getSessionId());
            structure.setAutofillId(autofillId);
        }
        CharSequence cname = info.getClassName();
        structure.setClassName(cname != null ? cname.toString() : null);
+32 −2
Original line number Diff line number Diff line
@@ -15,6 +15,10 @@
 */
package android.view.autofill;

import static android.view.autofill.Helper.sDebug;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -28,6 +32,7 @@ public final class AutofillId implements Parcelable {
    private final int mViewId;
    private final boolean mVirtual;
    private final int mVirtualId;
    private int mSessionId = AutofillManager.NO_SESSION;

    /** @hide */
    @TestApi
@@ -38,18 +43,26 @@ public final class AutofillId implements Parcelable {
    }

    /** @hide */
    // NOTE: caller must set sessionId
    @TestApi
    public AutofillId(AutofillId parent, int virtualChildId) {
    public AutofillId(@NonNull AutofillId parent, int virtualChildId) {
        mVirtual = true;
        mViewId = parent.mViewId;
        mVirtualId = virtualChildId;
    }

    /** @hide */
    public AutofillId(int parentId, int virtualChildId) {
    public AutofillId(int sessionId, int parentId, int virtualChildId) {
        mVirtual = true;
        mViewId = parentId;
        mVirtualId = virtualChildId;
        mSessionId = sessionId;
    }

    /** @hide */
    public AutofillId(@Nullable AutofillManager afm, int id) {
        this(id);
        mSessionId = afm == null ? AutofillManager.NO_SESSION : afm.getSessionId();
    }

    /** @hide */
@@ -67,6 +80,16 @@ public final class AutofillId implements Parcelable {
        return mVirtual;
    }

    /** @hide */
    public int getSessionId() {
        return mSessionId;
    }

    /** @hide */
    public void setSessionId(int sessionId) {
        this.mSessionId = sessionId;
    }

    /////////////////////////////////
    //  Object "contract" methods. //
    /////////////////////////////////
@@ -77,6 +100,7 @@ public final class AutofillId implements Parcelable {
        int result = 1;
        result = prime * result + mViewId;
        result = prime * result + mVirtualId;
        result = prime * result + mSessionId;
        return result;
    }

@@ -88,6 +112,7 @@ public final class AutofillId implements Parcelable {
        final AutofillId other = (AutofillId) obj;
        if (mViewId != other.mViewId) return false;
        if (mVirtualId != other.mVirtualId) return false;
        if (mSessionId != other.mSessionId) return false;
        return true;
    }

@@ -97,6 +122,9 @@ public final class AutofillId implements Parcelable {
        if (mVirtual) {
            builder.append(':').append(mVirtualId);
        }
        if (mSessionId != AutofillManager.NO_SESSION && sDebug) {
            builder.append('<').append(mSessionId).append('>');
        }
        return builder.toString();
    }

@@ -110,12 +138,14 @@ public final class AutofillId implements Parcelable {
        parcel.writeInt(mViewId);
        parcel.writeInt(mVirtual ? 1 : 0);
        parcel.writeInt(mVirtualId);
        parcel.writeInt(mSessionId);
    }

    private AutofillId(Parcel parcel) {
        mViewId = parcel.readInt();
        mVirtual = parcel.readInt() == 1;
        mVirtualId = parcel.readInt();
        mSessionId = parcel.readInt();
    }

    public static final Parcelable.Creator<AutofillId> CREATOR =
+21 −7
Original line number Diff line number Diff line
@@ -916,7 +916,7 @@ public final class AutofillManager {
            boolean isVisible, boolean virtual) {
        synchronized (mLock) {
            if (mEnabled && isActiveLocked()) {
                final AutofillId id = virtual ? getAutofillId(view, virtualId)
                final AutofillId id = virtual ? getAutofillIdLocked(view, virtualId)
                        : view.getAutofillId();
                if (sVerbose) Log.v(TAG, "visibility changed for " + id + ": " + isVisible);
                if (!isVisible && mFillableIds != null) {
@@ -976,7 +976,7 @@ public final class AutofillManager {
    @GuardedBy("mLock")
    private AutofillCallback notifyViewEnteredLocked(View view, int virtualId, Rect bounds,
                                                     int flags) {
        final AutofillId id = getAutofillId(view, virtualId);
        final AutofillId id = getAutofillIdLocked(view, virtualId);
        AutofillCallback callback = null;
        if (shouldIgnoreViewEnteredLocked(id, flags)) return callback;

@@ -1033,7 +1033,7 @@ public final class AutofillManager {
        if (mEnabled && isActiveLocked()) {
            // don't notify exited when Activity is already in background
            if (!isClientDisablingEnterExitEvent()) {
                final AutofillId id = getAutofillId(view, virtualId);
                final AutofillId id = getAutofillIdLocked(view, virtualId);

                // Update focus on existing session.
                updateSessionLocked(id, null, null, ACTION_VIEW_EXITED, 0);
@@ -1116,7 +1116,7 @@ public final class AutofillManager {
                return;
            }

            final AutofillId id = getAutofillId(view, virtualId);
            final AutofillId id = getAutofillIdLocked(view, virtualId);
            updateSessionLocked(id, null, value, ACTION_VALUE_CHANGED, 0);
        }
    }
@@ -1137,7 +1137,11 @@ public final class AutofillManager {
     * @param virtualId id identifying the virtual child inside the parent view.
     */
    public void notifyViewClicked(@NonNull View view, int virtualId) {
        notifyViewClicked(getAutofillId(view, virtualId));
        final AutofillId id;
        synchronized (mLock) {
            id = getAutofillIdLocked(view, virtualId);
        }
        notifyViewClicked(id);
    }

    private void notifyViewClicked(AutofillId id) {
@@ -1534,8 +1538,9 @@ public final class AutofillManager {
        return id;
    }

    private static AutofillId getAutofillId(View parent, int virtualId) {
        return new AutofillId(parent.getAutofillViewId(), virtualId);
    @GuardedBy("mLock")
    private AutofillId getAutofillIdLocked(View parent, int virtualId) {
        return new AutofillId(mSessionId, parent.getAutofillViewId(), virtualId);
    }

    @GuardedBy("mLock")
@@ -1566,6 +1571,8 @@ public final class AutofillManager {
            mSessionId = receiver.getIntResult();
            if (mSessionId != NO_SESSION) {
                mState = STATE_ACTIVE;
                // Need to update the view's autofill id with the session
                id.setSessionId(mSessionId);
            }
            client.autofillClientResetableStateAvailable();
        } catch (RemoteException e) {
@@ -2210,6 +2217,13 @@ public final class AutofillManager {
        return getStateAsString(mState);
    }

    /** @hide */
    public int getSessionId() {
        synchronized (mLock) {
            return mSessionId;
        }
    }

    @NonNull
    private static String getStateAsString(int state) {
        switch (state) {
Loading