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

Commit b88102f5 authored by Jeff Brown's avatar Jeff Brown
Browse files

Input dispatcher ANR handling enhancements.

This change is essentially a rewrite of the main input dispatcher loop
with the target identification folded in.  Since the input dispatcher now
has all of the window state, it can make better decisions about
when to ANR.

Added a .5 second deadline for processing app switch keys.  This behavior
predates Gingerbread but had not previously been ported.

Fixed some timing inaccuracies in the ANR accounting that could cause
applications to ANR sooner than they should have.

Added a mechanism for tracking key and motion events that have been
dispatched to a window so that appropriate cancelation events can be
synthesized when recovering from ANR.  This change helps to keep
applications in sync so they don't end up with stuck buttons upon
recovery from ANRs.

Added more comments to describe the tricky parts of PollLoop.

Change-Id: I13dffca27acb436fc383980db536abc4d8b9e6f1
parent 11fe181e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -224,8 +224,8 @@ public class MessageQueue {
                msg.next = prev.next;
                prev.next = msg;
            }
            nativeWake();
        }
        nativeWake();
        return true;
    }

+431 −76

File changed.

Preview size limit exceeded, changes collapsed.

+7 −64
Original line number Diff line number Diff line
@@ -72,51 +72,11 @@ public:
    /* Stops the input manager threads and waits for them to exit. */
    virtual status_t stop() = 0;

    /* Registers an input channel prior to using it as the target of an event. */
    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
    /* Gets the input reader. */
    virtual sp<InputReaderInterface> getReader() = 0;

    /* Unregisters an input channel. */
    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;

    /* Injects an input event and optionally waits for sync.
     * The synchronization mode determines whether the method blocks while waiting for
     * input injection to proceed.
     * Returns one of the INPUT_EVENT_INJECTION_XXX constants.
     */
    virtual int32_t injectInputEvent(const InputEvent* event,
            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0;

    /* Preempts input dispatch in progress by making pending synchronous
     * dispatches asynchronous instead.  This method is generally called during a focus
     * transition from one application to the next so as to enable the new application
     * to start receiving input as soon as possible without having to wait for the
     * old application to finish up.
     */
    virtual void preemptInputDispatch() = 0;

    /* Gets input device configuration. */
    virtual void getInputConfiguration(InputConfiguration* outConfiguration) = 0;

    /* Gets information about the specified input device.
     * Returns OK if the device information was obtained or NAME_NOT_FOUND if there
     * was no such device.
     */
    virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) = 0;

    /* Gets the list of all registered device ids. */
    virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds) = 0;

    /* Queries current input state. */
    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
            int32_t scanCode) = 0;
    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
            int32_t keyCode) = 0;
    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
            int32_t sw) = 0;

    /* Determines whether physical keys exist for the given framework-domain key codes. */
    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
            size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
    /* Gets the input dispatcher. */
    virtual sp<InputDispatcherInterface> getDispatcher() = 0;
};

class InputManager : public InputManagerInterface {
@@ -137,25 +97,8 @@ public:
    virtual status_t start();
    virtual status_t stop();

    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);

    virtual int32_t injectInputEvent(const InputEvent* event,
            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);

    virtual void preemptInputDispatch();

    virtual void getInputConfiguration(InputConfiguration* outConfiguration);
    virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo);
    virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds);
    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
            int32_t scanCode);
    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
            int32_t keyCode);
    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
            int32_t sw);
    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
            size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
    virtual sp<InputReaderInterface> getReader();
    virtual sp<InputDispatcherInterface> getDispatcher();

private:
    sp<InputReaderInterface> mReader;
+12 −4
Original line number Diff line number Diff line
@@ -95,10 +95,6 @@ public:

        // The input dispatcher should dispatch the input to the application.
        ACTION_DISPATCH = 0x00000001,

        // The input dispatcher should perform special filtering in preparation for
        // a pending app switch.
        ACTION_APP_SWITCH_COMING = 0x00000002,
    };

    /* Gets information about the display with the specified id.
@@ -168,6 +164,11 @@ protected:
    virtual ~InputReaderInterface() { }

public:
    /* Dumps the state of the input reader.
     *
     * This method may be called on any thread (usually by the input manager). */
    virtual void dump(String8& dump) = 0;

    /* Runs a single iteration of the processing loop.
     * Nominally reads and processes one incoming message from the EventHub.
     *
@@ -240,6 +241,8 @@ public:
            const sp<InputDispatcherInterface>& dispatcher);
    virtual ~InputReader();

    virtual void dump(String8& dump);

    virtual void loopOnce();

    virtual void getInputConfiguration(InputConfiguration* outConfiguration);
@@ -305,6 +308,9 @@ private:
            GetStateFunc getStateFunc);
    bool markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
            const int32_t* keyCodes, uint8_t* outFlags);

    // dump state
    void dumpDeviceInfo(String8& dump);
};


@@ -759,9 +765,11 @@ protected:
    } mLocked;

    virtual void configureParameters();
    virtual void logParameters();
    virtual void configureRawAxes();
    virtual void logRawAxes();
    virtual bool configureSurfaceLocked();
    virtual void logMotionRangesLocked();
    virtual void configureVirtualKeysLocked();
    virtual void parseCalibration();
    virtual void resolveCalibration();
+37 −0
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.
 */

#ifndef _UI_POWER_MANAGER_H
#define _UI_POWER_MANAGER_H


namespace android {

enum {
    POWER_MANAGER_OTHER_EVENT = 0,
    POWER_MANAGER_CHEEK_EVENT = 1,
    POWER_MANAGER_TOUCH_EVENT = 2, // touch events are TOUCH for 300ms, and then either
                                   // up events or LONG_TOUCH events.
    POWER_MANAGER_LONG_TOUCH_EVENT = 3,
    POWER_MANAGER_TOUCH_UP_EVENT = 4,
    POWER_MANAGER_BUTTON_EVENT = 5, // Button and trackball events.

    POWER_MANAGER_LAST_EVENT = POWER_MANAGER_BUTTON_EVENT, // Last valid event code.
};

} // namespace android

#endif // _UI_POWER_MANAGER_H
Loading