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

Commit 3b8e872e authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Move focus dispatch to input (2/2)

Input now tells the app when it has focus.

Touch mode information will now also be sent to the apps through input.

When a key targeting a non-focused display is processed, run the
'moveDisplayToTop' synchronously to ensure that setInputWindows with the
correct window focus information is completed. This would ensure that
the focus event is enqueued before the key event.

Bug: 70668286
Test: atest WindowFocusTests
Change-Id: Iff0b88a05441b29834741aa3dfae31d55871ddd6
parent 0df35373
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -127,6 +127,19 @@ public abstract class InputEventReceiver {
        finishInputEvent(event, false);
    }

    /**
     * Called when a focus event is received.
     *
     * @param hasFocus if true, the window associated with this input channel has just received
     *                 focus
     *                 if false, the window associated with this input channel has just lost focus
     * @param inTouchMode if true, the device is in touch mode
     *                    if false, the device is not in touch mode
     */
    // Called from native code.
    public void onFocusEvent(boolean hasFocus, boolean inTouchMode) {
    }

    /**
     * Called when a batched input event is pending.
     *
@@ -213,8 +226,13 @@ public abstract class InputEventReceiver {
        onBatchedInputEventPending();
    }

    public static interface Factory {
        public InputEventReceiver createInputEventReceiver(
                InputChannel inputChannel, Looper looper);
    /**
     * Factory for InputEventReceiver
     */
    public interface Factory {
        /**
         * Create a new InputReceiver for a given inputChannel
         */
        InputEventReceiver createInputEventReceiver(InputChannel inputChannel, Looper looper);
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -8039,6 +8039,11 @@ public final class ViewRootImpl implements ViewParent,
            }
        }

        @Override
        public void onFocusEvent(boolean hasFocus, boolean inTouchMode) {
            windowFocusChanged(hasFocus, inTouchMode);
        }

        @Override
        public void dispose() {
            unscheduleConsumeBatchedInput();
+22 −2
Original line number Diff line number Diff line
@@ -40,10 +40,15 @@ namespace android {

static const bool kDebugDispatchCycle = false;

static const char* toString(bool value) {
    return value ? "true" : "false";
}

static struct {
    jclass clazz;

    jmethodID dispatchInputEvent;
    jmethodID onFocusEvent;
    jmethodID dispatchBatchedInputEventPending;
} gInputEventReceiverClassInfo;

@@ -219,8 +224,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
        bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
    if (kDebugDispatchCycle) {
        ALOGD("channel '%s' ~ Consuming input events, consumeBatches=%s, frameTime=%" PRId64,
                getInputChannelName().c_str(),
                consumeBatches ? "true" : "false", frameTime);
              getInputChannelName().c_str(), toString(consumeBatches), frameTime);
    }

    if (consumeBatches) {
@@ -235,6 +239,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
    for (;;) {
        uint32_t seq;
        InputEvent* inputEvent;

        status_t status = mInputConsumer.consume(&mInputEventFactory,
                consumeBatches, frameTime, &seq, &inputEvent);
        if (status) {
@@ -302,6 +307,19 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
                inputEventObj = android_view_MotionEvent_obtainAsCopy(env, motionEvent);
                break;
            }
            case AINPUT_EVENT_TYPE_FOCUS: {
                FocusEvent* focusEvent = static_cast<FocusEvent*>(inputEvent);
                if (kDebugDispatchCycle) {
                    ALOGD("channel '%s' ~ Received focus event: hasFocus=%s, inTouchMode=%s.",
                          getInputChannelName().c_str(), toString(focusEvent->getHasFocus()),
                          toString(focusEvent->getInTouchMode()));
                }
                env->CallVoidMethod(receiverObj.get(), gInputEventReceiverClassInfo.onFocusEvent,
                                    jboolean(focusEvent->getHasFocus()),
                                    jboolean(focusEvent->getInTouchMode()));
                finishInputEvent(seq, true /* handled */);
                return OK;
            }

            default:
                assert(false); // InputConsumer should prevent this from ever happening
@@ -421,6 +439,8 @@ int register_android_view_InputEventReceiver(JNIEnv* env) {
    gInputEventReceiverClassInfo.dispatchInputEvent = GetMethodIDOrDie(env,
            gInputEventReceiverClassInfo.clazz,
            "dispatchInputEvent", "(ILandroid/view/InputEvent;)V");
    gInputEventReceiverClassInfo.onFocusEvent =
            GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onFocusEvent", "(ZZ)V");
    gInputEventReceiverClassInfo.dispatchBatchedInputEventPending = GetMethodIDOrDie(env,
            gInputEventReceiverClassInfo.clazz, "dispatchBatchedInputEventPending", "()V");

+3 −3
Original line number Diff line number Diff line
@@ -4602,13 +4602,13 @@ public class WindowManagerService extends IWindowManager.Stub

                    if (newFocus != null) {
                        ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Gaining focus: %s", newFocus);
                        newFocus.reportFocusChangedSerialized(true, mInTouchMode);
                        newFocus.reportFocusChangedSerialized(true);
                        notifyFocusChanged();
                    }

                    if (lastFocus != null) {
                        ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Losing focus: %s", lastFocus);
                        lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
                        lastFocus.reportFocusChangedSerialized(false);
                    }
                    break;
                }
@@ -4626,7 +4626,7 @@ public class WindowManagerService extends IWindowManager.Stub
                    for (int i = 0; i < N; i++) {
                        ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Losing delayed focus: %s",
                                losers.get(i));
                        losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
                        losers.get(i).reportFocusChangedSerialized(false);
                    }
                    break;
                }
+1 −5
Original line number Diff line number Diff line
@@ -3339,11 +3339,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
     * Report a focus change.  Must be called with no locks held, and consistently
     * from the same serialized thread (such as dispatched from a handler).
     */
    void reportFocusChangedSerialized(boolean focused, boolean inTouchMode) {
        try {
            mClient.windowFocusChanged(focused, inTouchMode);
        } catch (RemoteException e) {
        }
    void reportFocusChangedSerialized(boolean focused) {
        if (mFocusCallbacks != null) {
            final int N = mFocusCallbacks.beginBroadcast();
            for (int i=0; i<N; i++) {