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

Commit 342b98fc authored by Simranjit Kohli's avatar Simranjit Kohli Committed by Android (Google) Code Review
Browse files

Merge changes Iae0f5ec1,I7d72740b into main

* changes:
  [Relayout] Part 3: Introduce more functionality[Relayout]
  [Relayout] Part 2: Plug in Activity
parents daa08602 6dd83238
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2214,6 +2214,9 @@ public class Activity extends ContextThemeWrapper
        notifyVoiceInteractionManagerServiceActivityEvent(
                VoiceInteractionSession.VOICE_INTERACTION_ACTIVITY_EVENT_RESUME);

        // Notify autofill
        getAutofillClientController().onActivityPostResumed();

        mCalled = true;
    }

+24 −0
Original line number Diff line number Diff line
@@ -11004,6 +11004,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            ? afm.isAutofillable(this) : false;
    }
    /**
     * Returns whether the view is autofillable.
     *
     * @return whether the view is autofillable, and should send out autofill request to provider.
     */
    private boolean isAutofillable() {
        if (DBG) {
            Log.d(VIEW_LOG_TAG, "isAutofillable() entered.");
@@ -27631,6 +27636,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        return null;
    }
    /**
     * Performs the traversal to find views that are autofillable.
     * Autofillable views are added to the provided list.
     *
     * <strong>Note:</strong>This method does not stop at the root namespace
     * boundary.
     *
     * @param autofillableViews The output list of autofillable Views.
     * @hide
     */
    public void findAutofillableViewsByTraversal(@NonNull List<View> autofillableViews) {
        if (isAutofillable()) {
            autofillableViews.add(this);
        }
    }
    /**
     * Look for a child view with the given tag.  If this view has the given
     * tag, return this view.
@@ -30597,6 +30619,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
    // Note that if the function returns true, it indicates aapt did not generate this id.
    // However false value does not indicate that aapt did generated this id.
    private static boolean isViewIdGenerated(int id) {
        return (id & 0xFF000000) == 0 && (id & 0x00FFFFFF) != 0;
    }
+13 −0
Original line number Diff line number Diff line
@@ -1500,6 +1500,19 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        return null;
    }

    /** @hide */
    @Override
    public void findAutofillableViewsByTraversal(@NonNull List<View> autofillableViews) {
        super.findAutofillableViewsByTraversal(autofillableViews);

        final int childrenCount = mChildrenCount;
        final View[] children = mChildren;
        for (int i = 0; i < childrenCount; i++) {
            View child = children[i];
            child.findAutofillableViewsByTraversal(autofillableViews);
        }
    }

    @Override
    public void dispatchWindowFocusChanged(boolean hasFocus) {
        super.dispatchWindowFocusChanged(hasFocus);
+87 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.view.WindowManagerGlobal;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * A controller to manage the autofill requests for the {@link Activity}.
@@ -71,6 +72,7 @@ public final class AutofillClientController implements AutofillManager.AutofillC
    private AutofillPopupWindow mAutofillPopupWindow;
    private boolean mAutoFillResetNeeded;
    private boolean mAutoFillIgnoreFirstResumePause;
    private Boolean mRelayoutFix;

    /**
     * AutofillClientController constructor.
@@ -86,6 +88,18 @@ public final class AutofillClientController implements AutofillManager.AutofillC
        return mAutofillManager;
    }

    /**
     * Whether to apply relayout fixes.
     *
     * @hide
     */
    public boolean isRelayoutFixEnabled() {
        if (mRelayoutFix == null) {
            mRelayoutFix = getAutofillManager().isRelayoutFixEnabled();
        }
        return mRelayoutFix;
    }

    // ------------------ Called for Activity events ------------------

    /**
@@ -119,7 +133,54 @@ public final class AutofillClientController implements AutofillManager.AutofillC
     * Called when the {@link Activity#onResume()} is called.
     */
    public void onActivityResumed() {
        if (Helper.sVerbose) {
            Log.v(TAG, "onActivityResumed()");
        }
        if (isRelayoutFixEnabled()) {
            // Do nothing here. We'll handle it in onActivityPostResumed()
            return;
        }
        if (Helper.sVerbose) {
            Log.v(TAG, "onActivityResumed(): Relayout fix not enabled");
        }
        forResume();
    }

    /**
     * Called when the {@link Activity#onPostResume()} is called.
     */
    public void onActivityPostResumed() {
        if (Helper.sVerbose) {
            Log.v(TAG, "onActivityPostResumed()");
        }
        if (!isRelayoutFixEnabled()) {
            return;
        }
        if (Helper.sVerbose) {
            Log.v(TAG, "onActivityPostResumed(): Relayout fix enabled");
        }
        forResume();
    }

    /**
     * Code to execute when an app has resumed (or is about to resume)
     */
    private void forResume() {
        enableAutofillCompatibilityIfNeeded();
        boolean relayoutFix = isRelayoutFixEnabled();
        if (relayoutFix) {
            if (getAutofillManager().shouldRetryFill()) {
                if (Helper.sVerbose) {
                    Log.v(TAG, "forResume(): Autofill potential relayout. Retrying fill.");
                }
                getAutofillManager().attemptRefill();
            } else {
                if (Helper.sVerbose) {
                    Log.v(TAG, "forResume(): Not attempting refill.");
                }
            }
        }

        if (mAutoFillResetNeeded) {
            if (!mAutoFillIgnoreFirstResumePause) {
                View focus = mActivity.getCurrentFocus();
@@ -131,11 +192,20 @@ public final class AutofillClientController implements AutofillManager.AutofillC
                    // ViewRootImpl.performTraversals() changes window visibility to VISIBLE.
                    // So we cannot call View.notifyEnterOrExited() which will do nothing
                    // when View.isVisibleToUser() is false.
                    if (relayoutFix && getAutofillManager().isAuthenticationPending()) {
                        if (Helper.sVerbose) {
                            Log.v(TAG, "forResume(): ignoring focus due to auth pending");
                        }
                    } else {
                        if (Helper.sVerbose) {
                            Log.v(TAG, "forResume(): notifyViewEntered");
                        }
                        getAutofillManager().notifyViewEntered(focus);
                    }
                }
            }
        }
    }

    /**
     * Called when the Activity is performing resume.
@@ -426,6 +496,22 @@ public final class AutofillClientController implements AutofillManager.AutofillC
        return views;
    }

    @Override
    public List<View> autofillClientFindAutofillableViewsByTraversal() {
        final ArrayList<View> views = new ArrayList<>();
        final ArrayList<ViewRootImpl> roots =
                WindowManagerGlobal.getInstance().getRootViews(mActivity.getActivityToken());

        for (int rootNum = 0; rootNum < roots.size(); rootNum++) {
            final View rootView = roots.get(rootNum).getView();

            if (rootView != null) {
                rootView.findAutofillableViewsByTraversal(views);
            }
        }
        return views;
    }

    @Override
    public boolean autofillClientIsFillUiShowing() {
        return mAutofillPopupWindow != null && mAutofillPopupWindow.isShowing();
+38 −0
Original line number Diff line number Diff line
@@ -873,6 +873,13 @@ public final class AutofillManager {
         */
        @Nullable View autofillClientFindViewByAccessibilityIdTraversal(int viewId, int windowId);

        /**
         * Finds all the autofillable views on the screen.
         *
         * @return The list of views that are autofillable.
         */
        List<View> autofillClientFindAutofillableViewsByTraversal();

        /**
         * Runs the specified action on the UI thread.
         */
@@ -1497,6 +1504,37 @@ public final class AutofillManager {
        notifyViewEntered(view, virtualId, absBounds, flags);
    }

    /**
     * Called to know whether authentication was pending.
     * @hide
     */
    public boolean isAuthenticationPending() {
        return mState == STATE_PENDING_AUTHENTICATION;
    }

    /**
     * Called to check if we should retry fill.
     * Useful for knowing whether to attempt refill after relayout.
     *
     * @hide
     */
    public boolean shouldRetryFill() {
        // TODO: Implement in follow-up cl
        return false;
    }

    /**
     * Called when a potential relayout may have occurred.
     *
     * @return whether refill was done. True if refill was done partially or fully.
     * @hide
     */
    public boolean attemptRefill() {
        Log.i(TAG, "Attempting refill");
        // TODO: Implement in follow-up cl
        return false;
    }

    /**
     * Called when a {@link View} that supports autofill is entered.
     *
Loading