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

Commit 4952dfd1 authored by Jeff Brown's avatar Jeff Brown
Browse files

Ensure input events are processed in-order in the application.

As it turns out, it used to be possible for there to be multiple
input events simultaneously in flight in an application.  Although
it worked, it made it hard to reason about what was going on.
The problem was somewhat exacerbated by the introduction of a
queue of "InputEventMessage" objects as part of an earlier latency
optimization.

This change restores order from chaos and greatly simplifies the
invariants related to input event dispatch within the application.

Change-Id: I6de5fe61c1fe2ac3dd33edf770d949044df8a019
parent 95db2b20
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package android.service.wallpaper;

import com.android.internal.os.HandlerCaller;
import com.android.internal.view.BaseIWindow;
import com.android.internal.view.BaseInputHandler;
import com.android.internal.view.BaseSurfaceHolder;

import android.annotation.SdkConstant;
@@ -45,6 +44,7 @@ import android.view.Gravity;
import android.view.IWindowSession;
import android.view.InputChannel;
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.InputHandler;
import android.view.InputQueue;
import android.view.MotionEvent;
@@ -229,15 +229,15 @@ public abstract class WallpaperService extends Service {
            
        };
        
        final InputHandler mInputHandler = new BaseInputHandler() {
        final InputHandler mInputHandler = new InputHandler() {
            @Override
            public void handleMotion(MotionEvent event,
            public void handleInputEvent(InputEvent event,
                    InputQueue.FinishedCallback finishedCallback) {
                boolean handled = false;
                try {
                    int source = event.getSource();
                    if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
                        dispatchPointer(event);
                    if (event instanceof MotionEvent
                            && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
                        dispatchPointer((MotionEvent)event);
                        handled = true;
                    }
                } finally {
+6 −14
Original line number Diff line number Diff line
@@ -20,24 +20,16 @@ package android.view;
 * Handles input messages that arrive on an input channel.
 * @hide
 */
public interface InputHandler {
public class InputHandler {
    /**
     * Handle a key event.
     * Handle an input event.
     * It is the responsibility of the callee to ensure that the finished callback is
     * eventually invoked when the event processing is finished and the input system
     * can send the next event.
     * @param event The key event data.
     * @param event The input event.
     * @param finishedCallback The callback to invoke when event processing is finished.
     */
    public void handleKey(KeyEvent event, InputQueue.FinishedCallback finishedCallback);
    
    /**
     * Handle a motion event.
     * It is the responsibility of the callee to ensure that the finished callback is
     * eventually invoked when the event processing is finished and the input system
     * can send the next event.
     * @param event The motion event data.
     * @param finishedCallback The callback to invoke when event processing is finished.
     */
    public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback);
    public void handleInputEvent(InputEvent event, InputQueue.FinishedCallback finishedCallback) {
        finishedCallback.finished(false);
    }
}
+3 −10
Original line number Diff line number Diff line
@@ -114,17 +114,10 @@ public final class InputQueue {
    }
    
    @SuppressWarnings("unused")
    private static void dispatchKeyEvent(InputHandler inputHandler,
            KeyEvent event, long finishedToken) {
    private static void dispatchInputEvent(InputHandler inputHandler,
            InputEvent event, long finishedToken) {
        FinishedCallback finishedCallback = FinishedCallback.obtain(finishedToken);
        inputHandler.handleKey(event, finishedCallback);
    }

    @SuppressWarnings("unused")
    private static void dispatchMotionEvent(InputHandler inputHandler,
            MotionEvent event, long finishedToken) {
        FinishedCallback finishedCallback = FinishedCallback.obtain(finishedToken);
        inputHandler.handleMotion(event, finishedCallback);
        inputHandler.handleInputEvent(event, finishedCallback);
    }

    /**
+278 −347

File changed.

Preview size limit exceeded, changes collapsed.

+0 −36
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.view;

import android.view.InputHandler;
import android.view.InputQueue;
import android.view.KeyEvent;
import android.view.MotionEvent;

/**
 * Base do-nothing implementation of an input handler.
 * @hide
 */
public abstract class BaseInputHandler implements InputHandler {
    public void handleKey(KeyEvent event, InputQueue.FinishedCallback finishedCallback) {
        finishedCallback.finished(false);
    }
    
    public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
        finishedCallback.finished(false);
    }
}
Loading