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

Commit 09571f89 authored by Dake Gu's avatar Dake Gu Committed by Android (Google) Code Review
Browse files

Merge "autofill: pass keyevent from fillui to app"

parents f09c8c16 6a20a194
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -7622,6 +7622,19 @@ public class Activity extends ContextThemeWrapper
        return !wasShowing && mAutofillPopupWindow.isShowing();
    }

    /** @hide */
    @Override
    public final void autofillClientDispatchUnhandledKey(@NonNull View anchor,
            @NonNull KeyEvent keyEvent) {
        ViewRootImpl rootImpl = anchor.getViewRootImpl();
        if (rootImpl != null) {
            // dont care if anchorView is current focus, for example a custom view may only receive
            // touchEvent, not focusable but can still trigger autofill window. The Key handling
            // might be inside parent of the custom view.
            rootImpl.dispatchKeyFromAutofill(keyEvent);
        }
    }

    /** @hide */
    @Override
    public final boolean autofillClientRequestHideFillUi() {
+21 −1
Original line number Diff line number Diff line
@@ -3925,6 +3925,7 @@ public final class ViewRootImpl implements ViewParent,
    private final static int MSG_DISPATCH_APP_VISIBILITY = 8;
    private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9;
    private final static int MSG_DISPATCH_KEY_FROM_IME = 11;
    private final static int MSG_DISPATCH_KEY_FROM_AUTOFILL = 12;
    private final static int MSG_CHECK_FOCUS = 13;
    private final static int MSG_CLOSE_SYSTEM_DIALOGS = 14;
    private final static int MSG_DISPATCH_DRAG_EVENT = 15;
@@ -3966,6 +3967,8 @@ public final class ViewRootImpl implements ViewParent,
                    return "MSG_DISPATCH_GET_NEW_SURFACE";
                case MSG_DISPATCH_KEY_FROM_IME:
                    return "MSG_DISPATCH_KEY_FROM_IME";
                case MSG_DISPATCH_KEY_FROM_AUTOFILL:
                    return "MSG_DISPATCH_KEY_FROM_AUTOFILL";
                case MSG_CHECK_FOCUS:
                    return "MSG_CHECK_FOCUS";
                case MSG_CLOSE_SYSTEM_DIALOGS:
@@ -4143,6 +4146,15 @@ public final class ViewRootImpl implements ViewParent,
                    }
                    enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME, true);
                } break;
                case MSG_DISPATCH_KEY_FROM_AUTOFILL: {
                    if (LOCAL_LOGV) {
                        Log.v(TAG, "Dispatching key " + msg.obj + " from Autofill to " + mView);
                    }
                    KeyEvent event = (KeyEvent) msg.obj;
                    // send InputEvent to pre IME, set FLAG_FROM_AUTOFILL so the InputEvent
                    // wont be dropped as app window is not focus.
                    enqueueInputEvent(event, null, QueuedInputEvent.FLAG_FROM_AUTOFILL, true);
                } break;
                case MSG_CHECK_FOCUS: {
                    InputMethodManager imm = InputMethodManager.peekInstance();
                    if (imm != null) {
@@ -4433,7 +4445,8 @@ public final class ViewRootImpl implements ViewParent,
                Slog.w(mTag, "Dropping event due to root view being removed: " + q.mEvent);
                return true;
            } else if ((!mAttachInfo.mHasWindowFocus
                    && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) || mStopped
                    && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)
                    && (q.mFlags & QueuedInputEvent.FLAG_FROM_AUTOFILL) == 0) || mStopped
                    || (mIsAmbientMode && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_BUTTON))
                    || (mPausedForTransition && !isBack(q.mEvent))) {
                // This is a focus event and the window doesn't currently have input focus or
@@ -6805,6 +6818,7 @@ public final class ViewRootImpl implements ViewParent,
        public static final int FLAG_FINISHED_HANDLED = 1 << 3;
        public static final int FLAG_RESYNTHESIZED = 1 << 4;
        public static final int FLAG_UNHANDLED = 1 << 5;
        public static final int FLAG_FROM_AUTOFILL = 1 << 6;

        public QueuedInputEvent mNext;

@@ -7262,6 +7276,12 @@ public final class ViewRootImpl implements ViewParent,
        mHandler.sendMessage(msg);
    }

    public void dispatchKeyFromAutofill(KeyEvent event) {
        Message msg = mHandler.obtainMessage(MSG_DISPATCH_KEY_FROM_AUTOFILL, event);
        msg.setAsynchronous(true);
        mHandler.sendMessage(msg);
    }

    /**
     * Reinject unhandled {@link InputEvent}s in order to synthesize fallbacks events.
     *
+34 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.SparseArray;
import android.view.Choreographer;
import android.view.KeyEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -410,6 +411,13 @@ public final class AutofillManager {
        boolean autofillClientRequestShowFillUi(@NonNull View anchor, int width, int height,
                @Nullable Rect virtualBounds, IAutofillWindowPresenter presenter);

        /**
         * Dispatch unhandled keyevent from Autofill window
         * @param anchor The real view the UI needs to anchor to.
         * @param keyEvent Unhandled KeyEvent from autofill window.
         */
        void autofillClientDispatchUnhandledKey(@NonNull View anchor, @NonNull KeyEvent keyEvent);

        /**
         * Request hiding the autofill UI.
         *
@@ -1668,6 +1676,24 @@ public final class AutofillManager {
        }
    }

    private void dispatchUnhandledKey(int sessionId, AutofillId id, KeyEvent keyEvent) {
        final View anchor = findView(id);
        if (anchor == null) {
            return;
        }

        AutofillCallback callback = null;
        synchronized (mLock) {
            if (mSessionId == sessionId) {
                AutofillClient client = getClient();

                if (client != null) {
                    client.autofillClientDispatchUnhandledKey(anchor, keyEvent);
                }
            }
        }
    }

    /** @hide */
    public static final int SET_STATE_FLAG_ENABLED = 0x01;
    /** @hide */
@@ -2609,6 +2635,14 @@ public final class AutofillManager {
            }
        }

        @Override
        public void dispatchUnhandledKey(int sessionId, AutofillId id, KeyEvent fullScreen) {
            final AutofillManager afm = mAfm.get();
            if (afm != null) {
                afm.post(() -> afm.dispatchUnhandledKey(sessionId, id, fullScreen));
            }
        }

        @Override
        public void startIntentSender(IntentSender intentSender, Intent intent) {
            final AutofillManager afm = mAfm.get();
+8 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.os.IBinder;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
import android.view.autofill.IAutofillWindowPresenter;
import android.view.KeyEvent;

/**
 * Object running in the application process and responsible for autofilling it.
@@ -73,6 +74,13 @@ oneway interface IAutoFillManagerClient {
     */
    void notifyNoFillUi(int sessionId, in AutofillId id, int sessionFinishedState);

    /**
     * Dispatches unhandled keyevent from autofill ui. Autofill ui handles DPAD and ENTER events,
     * other unhandled keyevents are dispatched to app's window to filter autofill result.
     * Note this method is not called when autofill ui is in fullscreen mode (TV only).
     */
    void dispatchUnhandledKey(int sessionId, in AutofillId id, in KeyEvent keyEvent);

    /**
     * Starts the provided intent sender.
     */
+3 −2
Original line number Diff line number Diff line
@@ -14,7 +14,8 @@
     limitations under the License.
-->

<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
<view  xmlns:android="http://schemas.android.com/apk/res/android"
    class="com.android.server.autofill.ui.FillUi$AutofillFrameLayout"
    android:id="@+id/autofill_dataset_picker"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
@@ -30,4 +31,4 @@
        android:visibility="gone">
    </ListView>

</FrameLayout>
</view>
Loading