/*
 * 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.
 */

#define LOG_TAG "InputManager-JNI"

//#define LOG_NDEBUG 0

// Log debug messages about InputReaderPolicy
#define DEBUG_INPUT_READER_POLICY 0

// Log debug messages about InputDispatcherPolicy
#define DEBUG_INPUT_DISPATCHER_POLICY 0

// Log debug messages about input focus tracking
#define DEBUG_FOCUS 0

#include "JNIHelp.h"
#include "jni.h"
#include <limits.h>
#include <android_runtime/AndroidRuntime.h>
#include <ui/InputReader.h>
#include <ui/InputDispatcher.h>
#include <ui/InputManager.h>
#include <ui/InputTransport.h>
#include <utils/Log.h>
#include <utils/threads.h>
#include "../../core/jni/android_view_KeyEvent.h"
#include "../../core/jni/android_view_MotionEvent.h"
#include "../../core/jni/android_view_InputChannel.h"
#include "com_android_server_PowerManagerService.h"

namespace android {

// Window flags from WindowManager.LayoutParams
enum {
    FLAG_ALLOW_LOCK_WHILE_SCREEN_ON     = 0x00000001,
    FLAG_DIM_BEHIND        = 0x00000002,
    FLAG_BLUR_BEHIND        = 0x00000004,
    FLAG_NOT_FOCUSABLE      = 0x00000008,
    FLAG_NOT_TOUCHABLE      = 0x00000010,
    FLAG_NOT_TOUCH_MODAL    = 0x00000020,
    FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040,
    FLAG_KEEP_SCREEN_ON     = 0x00000080,
    FLAG_LAYOUT_IN_SCREEN   = 0x00000100,
    FLAG_LAYOUT_NO_LIMITS   = 0x00000200,
    FLAG_FULLSCREEN      = 0x00000400,
    FLAG_FORCE_NOT_FULLSCREEN   = 0x00000800,
    FLAG_DITHER             = 0x00001000,
    FLAG_SECURE             = 0x00002000,
    FLAG_SCALED             = 0x00004000,
    FLAG_IGNORE_CHEEK_PRESSES    = 0x00008000,
    FLAG_LAYOUT_INSET_DECOR = 0x00010000,
    FLAG_ALT_FOCUSABLE_IM = 0x00020000,
    FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000,
    FLAG_SHOW_WHEN_LOCKED = 0x00080000,
    FLAG_SHOW_WALLPAPER = 0x00100000,
    FLAG_TURN_SCREEN_ON = 0x00200000,
    FLAG_DISMISS_KEYGUARD = 0x00400000,
    FLAG_IMMERSIVE = 0x00800000,
    FLAG_KEEP_SURFACE_WHILE_ANIMATING = 0x10000000,
    FLAG_COMPATIBLE_WINDOW = 0x20000000,
    FLAG_SYSTEM_ERROR = 0x40000000,
};

// Window types from WindowManager.LayoutParams
enum {
    FIRST_APPLICATION_WINDOW = 1,
    TYPE_BASE_APPLICATION   = 1,
    TYPE_APPLICATION        = 2,
    TYPE_APPLICATION_STARTING = 3,
    LAST_APPLICATION_WINDOW = 99,
    FIRST_SUB_WINDOW        = 1000,
    TYPE_APPLICATION_PANEL  = FIRST_SUB_WINDOW,
    TYPE_APPLICATION_MEDIA  = FIRST_SUB_WINDOW+1,
    TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW+2,
    TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3,
    TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW+4,
    LAST_SUB_WINDOW         = 1999,
    FIRST_SYSTEM_WINDOW     = 2000,
    TYPE_STATUS_BAR         = FIRST_SYSTEM_WINDOW,
    TYPE_SEARCH_BAR         = FIRST_SYSTEM_WINDOW+1,
    TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2,
    TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3,
    TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4,
    TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5,
    TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6,
    TYPE_PRIORITY_PHONE     = FIRST_SYSTEM_WINDOW+7,
    TYPE_SYSTEM_DIALOG      = FIRST_SYSTEM_WINDOW+8,
    TYPE_KEYGUARD_DIALOG    = FIRST_SYSTEM_WINDOW+9,
    TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10,
    TYPE_INPUT_METHOD       = FIRST_SYSTEM_WINDOW+11,
    TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12,
    TYPE_WALLPAPER          = FIRST_SYSTEM_WINDOW+13,
    TYPE_STATUS_BAR_PANEL   = FIRST_SYSTEM_WINDOW+14,
    LAST_SYSTEM_WINDOW      = 2999,
};

// Delay between reporting long touch events to the power manager.
const nsecs_t EVENT_IGNORE_DURATION = 300 * 1000000LL; // 300 ms

// Default input dispatching timeout if there is no focused application or paused window
// from which to determine an appropriate dispatching timeout.
const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec

// Minimum amount of time to provide to the input dispatcher for delivery of an event
// regardless of how long the application window was paused.
const nsecs_t MIN_INPUT_DISPATCHING_TIMEOUT = 1000 * 1000000LL; // 1 sec

// ----------------------------------------------------------------------------

static struct {
    jclass clazz;

    jmethodID notifyConfigurationChanged;
    jmethodID notifyLidSwitchChanged;
    jmethodID notifyInputChannelBroken;
    jmethodID notifyInputChannelANR;
    jmethodID notifyInputChannelRecoveredFromANR;
    jmethodID notifyANR;
    jmethodID virtualKeyDownFeedback;
    jmethodID interceptKeyBeforeQueueing;
    jmethodID interceptKeyBeforeDispatching;
    jmethodID checkInjectEventsPermission;
    jmethodID notifyAppSwitchComing;
    jmethodID filterTouchEvents;
    jmethodID filterJumpyTouchEvents;
    jmethodID getVirtualKeyDefinitions;
    jmethodID getExcludedDeviceNames;
    jmethodID getMaxEventsPerSecond;
} gCallbacksClassInfo;

static struct {
    jclass clazz;

    jfieldID scanCode;
    jfieldID centerX;
    jfieldID centerY;
    jfieldID width;
    jfieldID height;
} gVirtualKeyDefinitionClassInfo;

static struct {
    jclass clazz;

    jfieldID inputChannel;
    jfieldID layoutParamsFlags;
    jfieldID layoutParamsType;
    jfieldID dispatchingTimeoutNanos;
    jfieldID frameLeft;
    jfieldID frameTop;
    jfieldID touchableAreaLeft;
    jfieldID touchableAreaTop;
    jfieldID touchableAreaRight;
    jfieldID touchableAreaBottom;
    jfieldID visible;
    jfieldID hasFocus;
    jfieldID hasWallpaper;
    jfieldID paused;
    jfieldID ownerPid;
    jfieldID ownerUid;
} gInputWindowClassInfo;

static struct {
    jclass clazz;

    jfieldID name;
    jfieldID dispatchingTimeoutNanos;
    jfieldID token;
} gInputApplicationClassInfo;

static struct {
    jclass clazz;
} gKeyEventClassInfo;

static struct {
    jclass clazz;
} gMotionEventClassInfo;

// ----------------------------------------------------------------------------

static inline nsecs_t now() {
    return systemTime(SYSTEM_TIME_MONOTONIC);
}

// ----------------------------------------------------------------------------

class NativeInputManager : public virtual RefBase,
    public virtual InputReaderPolicyInterface,
    public virtual InputDispatcherPolicyInterface {
protected:
    virtual ~NativeInputManager();

public:
    NativeInputManager(jobject callbacksObj);

    inline sp<InputManager> getInputManager() const { return mInputManager; }

    String8 dump();

    void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
    void setDisplayOrientation(int32_t displayId, int32_t orientation);

    status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
            jweak inputChannelObjWeak, bool monitor);
    status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);

    void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
    void setFocusedApplication(JNIEnv* env, jobject applicationObj);
    void setInputDispatchMode(bool enabled, bool frozen);
    void preemptInputDispatch();

    /* --- InputReaderPolicyInterface implementation --- */

    virtual bool getDisplayInfo(int32_t displayId,
            int32_t* width, int32_t* height, int32_t* orientation);
    virtual void virtualKeyDownFeedback();
    virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
            bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags);
    virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
            uint32_t& policyFlags);
    virtual int32_t interceptGeneric(nsecs_t when, uint32_t& policyFlags);
    virtual bool filterTouchEvents();
    virtual bool filterJumpyTouchEvents();
    virtual void getVirtualKeyDefinitions(const String8& deviceName,
            Vector<InputReaderPolicyInterface::VirtualKeyDefinition>& outVirtualKeyDefinitions);
    virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);

    /* --- InputDispatcherPolicyInterface implementation --- */

    virtual void notifyConfigurationChanged(nsecs_t when);
    virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel);
    virtual bool notifyInputChannelANR(const sp<InputChannel>& inputChannel,
            nsecs_t& outNewTimeout);
    virtual void notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel);
    virtual nsecs_t getKeyRepeatTimeout();
    virtual int32_t waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
            int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets);
    virtual int32_t waitForMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
            int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets);
    virtual int32_t getMaxEventsPerSecond();

private:
    struct InputWindow {
        sp<InputChannel> inputChannel;
        int32_t layoutParamsFlags;
        int32_t layoutParamsType;
        nsecs_t dispatchingTimeout;
        int32_t frameLeft;
        int32_t frameTop;
        int32_t touchableAreaLeft;
        int32_t touchableAreaTop;
        int32_t touchableAreaRight;
        int32_t touchableAreaBottom;
        bool visible;
        bool hasFocus;
        bool hasWallpaper;
        bool paused;
        int32_t ownerPid;
        int32_t ownerUid;

        inline bool touchableAreaContainsPoint(int32_t x, int32_t y) {
            return x >= touchableAreaLeft && x <= touchableAreaRight
                    && y >= touchableAreaTop && y <= touchableAreaBottom;
        }
    };

    struct InputApplication {
        String8 name;
        nsecs_t dispatchingTimeout;
        jweak tokenObjWeak;
    };

    class ANRTimer {
        enum Budget {
            SYSTEM = 0,
            APPLICATION = 1
        };

        Budget mBudget;
        nsecs_t mStartTime;
        bool mFrozen;
        InputWindow* mPausedWindow;

    public:
        ANRTimer();

        void dispatchFrozenBySystem();
        void dispatchPausedByApplication(InputWindow* pausedWindow);
        bool waitForDispatchStateChangeLd(NativeInputManager* inputManager);

        nsecs_t getTimeSpentWaitingForApplication() const;
    };

    sp<InputManager> mInputManager;

    jobject mCallbacksObj;

    // Cached filtering policies.
    int32_t mFilterTouchEvents;
    int32_t mFilterJumpyTouchEvents;

    // Cached throttling policy.
    int32_t mMaxEventsPerSecond;

    // Cached display state.  (lock mDisplayLock)
    Mutex mDisplayLock;
    int32_t mDisplayWidth, mDisplayHeight;
    int32_t mDisplayOrientation;

    // Power manager interactions.
    bool isScreenOn();
    bool isScreenBright();

    // Weak references to all currently registered input channels by connection pointer.
    Mutex mInputChannelRegistryLock;
    KeyedVector<InputChannel*, jweak> mInputChannelObjWeakTable;

    jobject getInputChannelObjLocal(JNIEnv* env, const sp<InputChannel>& inputChannel);

    // Input target and focus tracking.  (lock mDispatchLock)
    Mutex mDispatchLock;
    Condition mDispatchStateChanged;

    bool mDispatchEnabled;
    bool mDispatchFrozen;
    bool mWindowsReady;
    Vector<InputWindow> mWindows;
    Vector<InputWindow*> mWallpaperWindows;
    Vector<sp<InputChannel> > mMonitoringChannels;

    // Focus tracking for keys, trackball, etc.
    InputWindow* mFocusedWindow;

    // Focus tracking for touch.
    bool mTouchDown;
    InputWindow* mTouchedWindow;                   // primary target for current down
    Vector<InputWindow*> mTouchedWallpaperWindows; // wallpaper targets

    Vector<InputWindow*> mTempTouchedOutsideWindows; // temporary outside touch targets
    Vector<sp<InputChannel> > mTempTouchedWallpaperChannels; // temporary wallpaper targets

    // Focused application.
    InputApplication* mFocusedApplication;
    InputApplication mFocusedApplicationStorage; // preallocated storage for mFocusedApplication

    void dumpDeviceInfo(String8& dump);
    void dumpDispatchStateLd(String8& dump);
    void logDispatchStateLd();

    bool notifyANR(jobject tokenObj, nsecs_t& outNewTimeout);
    void releaseFocusedApplicationLd(JNIEnv* env);

    int32_t waitForFocusedWindowLd(uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid,
            Vector<InputTarget>& outTargets, InputWindow*& outFocusedWindow);
    int32_t waitForTouchedWindowLd(MotionEvent* motionEvent, uint32_t policyFlags,
            int32_t injectorPid, int32_t injectorUid,
            Vector<InputTarget>& outTargets, InputWindow*& outTouchedWindow);

    void releaseTouchedWindowLd();

    int32_t waitForNonTouchEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
            int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets);
    int32_t waitForTouchEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
            int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets);

    bool interceptKeyBeforeDispatching(const InputTarget& target,
            const KeyEvent* keyEvent, uint32_t policyFlags);

    void pokeUserActivityIfNeeded(int32_t windowType, int32_t eventType);
    void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
    bool checkInjectionPermission(const InputWindow* window,
            int32_t injectorPid, int32_t injectorUid);

    static bool populateWindow(JNIEnv* env, jobject windowObj, InputWindow& outWindow);
    static void addTarget(const InputWindow* window, int32_t targetFlags,
            nsecs_t timeSpentWaitingForApplication, Vector<InputTarget>& outTargets);

    void registerMonitoringChannel(const sp<InputChannel>& inputChannel);
    void unregisterMonitoringChannel(const sp<InputChannel>& inputChannel);
    void addMonitoringTargetsLd(Vector<InputTarget>& outTargets);

    static inline JNIEnv* jniEnv() {
        return AndroidRuntime::getJNIEnv();
    }

    static bool isAppSwitchKey(int32_t keyCode);
    static bool isPolicyKey(int32_t keyCode, bool isScreenOn);
    static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
};

// ----------------------------------------------------------------------------

NativeInputManager::NativeInputManager(jobject callbacksObj) :
    mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
    mMaxEventsPerSecond(-1),
    mDisplayWidth(-1), mDisplayHeight(-1), mDisplayOrientation(ROTATION_0),
    mDispatchEnabled(true), mDispatchFrozen(false), mWindowsReady(true),
    mFocusedWindow(NULL), mTouchDown(false), mTouchedWindow(NULL),
    mFocusedApplication(NULL) {
    JNIEnv* env = jniEnv();

    mCallbacksObj = env->NewGlobalRef(callbacksObj);

    sp<EventHub> eventHub = new EventHub();
    mInputManager = new InputManager(eventHub, this, this);
}

NativeInputManager::~NativeInputManager() {
    JNIEnv* env = jniEnv();

    env->DeleteGlobalRef(mCallbacksObj);

    releaseFocusedApplicationLd(env);
}

String8 NativeInputManager::dump() {
    String8 dump;
    { // acquire lock
        AutoMutex _l(mDisplayLock);
        dump.append("Native Input Dispatcher State:\n");
        dumpDispatchStateLd(dump);
        dump.append("\n");
    } // release lock

    dump.append("Input Devices:\n");
    dumpDeviceInfo(dump);

    return dump;
}

bool NativeInputManager::isAppSwitchKey(int32_t keyCode) {
    return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
}

bool NativeInputManager::isPolicyKey(int32_t keyCode, bool isScreenOn) {
    // Special keys that the WindowManagerPolicy might care about.
    switch (keyCode) {
    case AKEYCODE_VOLUME_UP:
    case AKEYCODE_VOLUME_DOWN:
    case AKEYCODE_ENDCALL:
    case AKEYCODE_POWER:
    case AKEYCODE_CALL:
    case AKEYCODE_HOME:
    case AKEYCODE_MENU:
    case AKEYCODE_SEARCH:
        // media keys
    case AKEYCODE_HEADSETHOOK:
    case AKEYCODE_MEDIA_PLAY_PAUSE:
    case AKEYCODE_MEDIA_STOP:
    case AKEYCODE_MEDIA_NEXT:
    case AKEYCODE_MEDIA_PREVIOUS:
    case AKEYCODE_MEDIA_REWIND:
    case AKEYCODE_MEDIA_FAST_FORWARD:
        return true;
    default:
        // We need to pass all keys to the policy in the following cases:
        // - screen is off
        // - keyguard is visible
        // - policy is performing key chording
        //return ! isScreenOn || keyguardVisible || chording;
        return true; // XXX stubbed out for now
    }
}

bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
    if (env->ExceptionCheck()) {
        LOGE("An exception was thrown by callback '%s'.", methodName);
        LOGE_EX(env);
        env->ExceptionClear();
        return true;
    }
    return false;
}

void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
    if (displayId == 0) {
        AutoMutex _l(mDisplayLock);

        mDisplayWidth = width;
        mDisplayHeight = height;
    }
}

void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
    if (displayId == 0) {
        AutoMutex _l(mDisplayLock);

        mDisplayOrientation = orientation;
    }
}

status_t NativeInputManager::registerInputChannel(JNIEnv* env,
        const sp<InputChannel>& inputChannel, jobject inputChannelObj, bool monitor) {
    jweak inputChannelObjWeak = env->NewWeakGlobalRef(inputChannelObj);
    if (! inputChannelObjWeak) {
        LOGE("Could not create weak reference for input channel.");
        LOGE_EX(env);
        return NO_MEMORY;
    }

    status_t status;
    {
        AutoMutex _l(mInputChannelRegistryLock);

        ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
        if (index >= 0) {
            LOGE("Input channel object '%s' has already been registered",
                    inputChannel->getName().string());
            status = INVALID_OPERATION;
            goto DeleteWeakRef;
        }

        mInputChannelObjWeakTable.add(inputChannel.get(), inputChannelObjWeak);
    }

    status = mInputManager->registerInputChannel(inputChannel);
    if (! status) {
        // Success.
        if (monitor) {
            registerMonitoringChannel(inputChannel);
        }
        return OK;
    }

    // Failed!
    {
        AutoMutex _l(mInputChannelRegistryLock);
        mInputChannelObjWeakTable.removeItem(inputChannel.get());
    }

DeleteWeakRef:
    env->DeleteWeakGlobalRef(inputChannelObjWeak);
    return status;
}

status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
        const sp<InputChannel>& inputChannel) {
    jweak inputChannelObjWeak;
    {
        AutoMutex _l(mInputChannelRegistryLock);

        ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
        if (index < 0) {
            LOGE("Input channel object '%s' is not currently registered",
                    inputChannel->getName().string());
            return INVALID_OPERATION;
        }

        inputChannelObjWeak = mInputChannelObjWeakTable.valueAt(index);
        mInputChannelObjWeakTable.removeItemsAt(index);
    }

    env->DeleteWeakGlobalRef(inputChannelObjWeak);

    unregisterMonitoringChannel(inputChannel);

    return mInputManager->unregisterInputChannel(inputChannel);
}

jobject NativeInputManager::getInputChannelObjLocal(JNIEnv* env,
        const sp<InputChannel>& inputChannel) {
    {
        AutoMutex _l(mInputChannelRegistryLock);

        ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
        if (index < 0) {
            return NULL;
        }

        jweak inputChannelObjWeak = mInputChannelObjWeakTable.valueAt(index);
        return env->NewLocalRef(inputChannelObjWeak);
    }
}

bool NativeInputManager::getDisplayInfo(int32_t displayId,
        int32_t* width, int32_t* height, int32_t* orientation) {
    bool result = false;
    if (displayId == 0) {
        AutoMutex _l(mDisplayLock);

        if (mDisplayWidth > 0) {
            if (width) {
                *width = mDisplayWidth;
            }
            if (height) {
                *height = mDisplayHeight;
            }
            if (orientation) {
                *orientation = mDisplayOrientation;
            }
            result = true;
        }
    }
    return result;
}

bool NativeInputManager::isScreenOn() {
    return android_server_PowerManagerService_isScreenOn();
}

bool NativeInputManager::isScreenBright() {
    return android_server_PowerManagerService_isScreenBright();
}

void NativeInputManager::virtualKeyDownFeedback() {
#if DEBUG_INPUT_READER_POLICY
    LOGD("virtualKeyDownFeedback");
#endif

    JNIEnv* env = jniEnv();

    env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyDownFeedback);
    checkAndClearExceptionFromCallback(env, "virtualKeyDownFeedback");
}

int32_t NativeInputManager::interceptKey(nsecs_t when,
        int32_t deviceId, bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
#if DEBUG_INPUT_READER_POLICY
    LOGD("interceptKey - when=%lld, deviceId=%d, down=%d, keyCode=%d, scanCode=%d, "
            "policyFlags=0x%x",
            when, deviceId, down, keyCode, scanCode, policyFlags);
#endif

    const int32_t WM_ACTION_PASS_TO_USER = 1;
    const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
    const int32_t WM_ACTION_GO_TO_SLEEP = 4;

    bool isScreenOn = this->isScreenOn();
    bool isScreenBright = this->isScreenBright();

    jint wmActions = 0;
    if (isPolicyKey(keyCode, isScreenOn)) {
        JNIEnv* env = jniEnv();

        wmActions = env->CallIntMethod(mCallbacksObj,
                gCallbacksClassInfo.interceptKeyBeforeQueueing,
                when, keyCode, down, policyFlags, isScreenOn);
        if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
            wmActions = 0;
        }
    } else {
        wmActions = WM_ACTION_PASS_TO_USER;
    }

    int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
    if (! isScreenOn) {
        // Key presses and releases wake the device.
        policyFlags |= POLICY_FLAG_WOKE_HERE;
    }

    if (! isScreenBright) {
        // Key presses and releases brighten the screen if dimmed.
        policyFlags |= POLICY_FLAG_BRIGHT_HERE;
    }

    if (wmActions & WM_ACTION_GO_TO_SLEEP) {
        android_server_PowerManagerService_goToSleep(when);
    }

    if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
        pokeUserActivity(when, POWER_MANAGER_BUTTON_EVENT);
    }

    if (wmActions & WM_ACTION_PASS_TO_USER) {
        actions |= InputReaderPolicyInterface::ACTION_DISPATCH;

        if (down && isAppSwitchKey(keyCode)) {
            JNIEnv* env = jniEnv();

            env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyAppSwitchComing);
            checkAndClearExceptionFromCallback(env, "notifyAppSwitchComing");

            actions |= InputReaderPolicyInterface::ACTION_APP_SWITCH_COMING;
        }
    }

    return actions;
}

int32_t NativeInputManager::interceptGeneric(nsecs_t when, uint32_t& policyFlags) {
#if DEBUG_INPUT_READER_POLICY
    LOGD("interceptGeneric - when=%lld, policyFlags=0x%x", when, policyFlags);
#endif

    int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
    if (isScreenOn()) {
        // Only dispatch events when the device is awake.
        // Do not wake the device.
        actions |= InputReaderPolicyInterface::ACTION_DISPATCH;

        if (! isScreenBright()) {
            // Brighten the screen if dimmed.
            policyFlags |= POLICY_FLAG_BRIGHT_HERE;
        }
    }

    return actions;
}

int32_t NativeInputManager::interceptSwitch(nsecs_t when, int32_t switchCode,
        int32_t switchValue, uint32_t& policyFlags) {
#if DEBUG_INPUT_READER_POLICY
    LOGD("interceptSwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
            when, switchCode, switchValue, policyFlags);
#endif

    JNIEnv* env = jniEnv();

    switch (switchCode) {
    case SW_LID:
        env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
                when, switchValue == 0);
        checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
        break;
    }

    return InputReaderPolicyInterface::ACTION_NONE;
}

bool NativeInputManager::filterTouchEvents() {
    if (mFilterTouchEvents < 0) {
        JNIEnv* env = jniEnv();

        jboolean result = env->CallBooleanMethod(mCallbacksObj,
                gCallbacksClassInfo.filterTouchEvents);
        if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
            result = false;
        }

        mFilterTouchEvents = result ? 1 : 0;
    }
    return mFilterTouchEvents;
}

bool NativeInputManager::filterJumpyTouchEvents() {
    if (mFilterJumpyTouchEvents < 0) {
        JNIEnv* env = jniEnv();

        jboolean result = env->CallBooleanMethod(mCallbacksObj,
                gCallbacksClassInfo.filterJumpyTouchEvents);
        if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
            result = false;
        }

        mFilterJumpyTouchEvents = result ? 1 : 0;
    }
    return mFilterJumpyTouchEvents;
}

void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
        Vector<InputReaderPolicyInterface::VirtualKeyDefinition>& outVirtualKeyDefinitions) {
    JNIEnv* env = jniEnv();

    jstring deviceNameStr = env->NewStringUTF(deviceName.string());
    if (! checkAndClearExceptionFromCallback(env, "getVirtualKeyDefinitions")) {
        jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
                gCallbacksClassInfo.getVirtualKeyDefinitions, deviceNameStr));
        if (! checkAndClearExceptionFromCallback(env, "getVirtualKeyDefinitions") && result) {
            jsize length = env->GetArrayLength(result);
            for (jsize i = 0; i < length; i++) {
                jobject item = env->GetObjectArrayElement(result, i);

                outVirtualKeyDefinitions.add();
                outVirtualKeyDefinitions.editTop().scanCode =
                        int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.scanCode));
                outVirtualKeyDefinitions.editTop().centerX =
                        int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerX));
                outVirtualKeyDefinitions.editTop().centerY =
                        int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerY));
                outVirtualKeyDefinitions.editTop().width =
                        int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.width));
                outVirtualKeyDefinitions.editTop().height =
                        int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.height));

                env->DeleteLocalRef(item);
            }
            env->DeleteLocalRef(result);
        }
        env->DeleteLocalRef(deviceNameStr);
    }
}

void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
    JNIEnv* env = jniEnv();

    jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
            gCallbacksClassInfo.getExcludedDeviceNames));
    if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
        jsize length = env->GetArrayLength(result);
        for (jsize i = 0; i < length; i++) {
            jstring item = jstring(env->GetObjectArrayElement(result, i));

            const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
            outExcludedDeviceNames.add(String8(deviceNameChars));
            env->ReleaseStringUTFChars(item, deviceNameChars);

            env->DeleteLocalRef(item);
        }
        env->DeleteLocalRef(result);
    }
}

void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
#if DEBUG_INPUT_DISPATCHER_POLICY
    LOGD("notifyConfigurationChanged - when=%lld", when);
#endif

    JNIEnv* env = jniEnv();

    InputConfiguration config;
    mInputManager->getInputConfiguration(& config);

    env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged,
            when, config.touchScreen, config.keyboard, config.navigation);
    checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
}

void NativeInputManager::notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
#if DEBUG_INPUT_DISPATCHER_POLICY
    LOGD("notifyInputChannelBroken - inputChannel='%s'", inputChannel->getName().string());
#endif

    JNIEnv* env = jniEnv();

    jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
    if (inputChannelObjLocal) {
        env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
                inputChannelObjLocal);
        checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");

        env->DeleteLocalRef(inputChannelObjLocal);
    }

    unregisterMonitoringChannel(inputChannel);
}

bool NativeInputManager::notifyInputChannelANR(const sp<InputChannel>& inputChannel,
        nsecs_t& outNewTimeout) {
#if DEBUG_INPUT_DISPATCHER_POLICY
    LOGD("notifyInputChannelANR - inputChannel='%s'",
            inputChannel->getName().string());
#endif

    JNIEnv* env = jniEnv();

    jlong newTimeout;
    jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
    if (inputChannelObjLocal) {
        newTimeout = env->CallLongMethod(mCallbacksObj,
                gCallbacksClassInfo.notifyInputChannelANR, inputChannelObjLocal);
        if (checkAndClearExceptionFromCallback(env, "notifyInputChannelANR")) {
            newTimeout = -2;
        }

        env->DeleteLocalRef(inputChannelObjLocal);
    } else {
        newTimeout = -2;
    }

    if (newTimeout == -2) {
        return false; // abort
    }

    outNewTimeout = newTimeout;
    return true; // resume
}

void NativeInputManager::notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel) {
#if DEBUG_INPUT_DISPATCHER_POLICY
    LOGD("notifyInputChannelRecoveredFromANR - inputChannel='%s'",
            inputChannel->getName().string());
#endif

    JNIEnv* env = jniEnv();

    jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
    if (inputChannelObjLocal) {
        env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelRecoveredFromANR,
                inputChannelObjLocal);
        checkAndClearExceptionFromCallback(env, "notifyInputChannelRecoveredFromANR");

        env->DeleteLocalRef(inputChannelObjLocal);
    }
}

bool NativeInputManager::notifyANR(jobject tokenObj, nsecs_t& outNewTimeout) {
#if DEBUG_INPUT_DISPATCHER_POLICY
    LOGD("notifyANR");
#endif

    JNIEnv* env = jniEnv();

    jlong newTimeout = env->CallLongMethod(mCallbacksObj,
            gCallbacksClassInfo.notifyANR, tokenObj);
    if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
        newTimeout = -2;
    }

    if (newTimeout == -2) {
        return false; // abort
    }

    outNewTimeout = newTimeout;
    return true; // resume
}

nsecs_t NativeInputManager::getKeyRepeatTimeout() {
    if (! isScreenOn()) {
        // Disable key repeat when the screen is off.
        return -1;
    } else {
        // TODO use ViewConfiguration.getLongPressTimeout()
        return milliseconds_to_nanoseconds(500);
    }
}

int32_t NativeInputManager::getMaxEventsPerSecond() {
    if (mMaxEventsPerSecond < 0) {
        JNIEnv* env = jniEnv();

        jint result = env->CallIntMethod(mCallbacksObj,
                gCallbacksClassInfo.getMaxEventsPerSecond);
        if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
            result = 60;
        }

        mMaxEventsPerSecond = result;
    }
    return mMaxEventsPerSecond;
}

void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
#if DEBUG_FOCUS
    LOGD("setInputWindows");
#endif
    { // acquire lock
        AutoMutex _l(mDispatchLock);

        sp<InputChannel> touchedWindowChannel;
        if (mTouchedWindow) {
            touchedWindowChannel = mTouchedWindow->inputChannel;
            mTouchedWindow = NULL;
        }
        size_t numTouchedWallpapers = mTouchedWallpaperWindows.size();
        if (numTouchedWallpapers != 0) {
            for (size_t i = 0; i < numTouchedWallpapers; i++) {
                mTempTouchedWallpaperChannels.push(mTouchedWallpaperWindows[i]->inputChannel);
            }
            mTouchedWallpaperWindows.clear();
        }

        bool hadFocusedWindow = mFocusedWindow != NULL;

        mWindows.clear();
        mFocusedWindow = NULL;
        mWallpaperWindows.clear();

        if (windowObjArray) {
            mWindowsReady = true;

            jsize length = env->GetArrayLength(windowObjArray);
            for (jsize i = 0; i < length; i++) {
                jobject inputTargetObj = env->GetObjectArrayElement(windowObjArray, i);
                if (! inputTargetObj) {
                    break; // found null element indicating end of used portion of the array
                }

                mWindows.push();
                InputWindow& window = mWindows.editTop();
                bool valid = populateWindow(env, inputTargetObj, window);
                if (! valid) {
                    mWindows.pop();
                }

                env->DeleteLocalRef(inputTargetObj);
            }

            size_t numWindows = mWindows.size();
            for (size_t i = 0; i < numWindows; i++) {
                InputWindow* window = & mWindows.editItemAt(i);
                if (window->hasFocus) {
                    mFocusedWindow = window;
                }

                if (window->layoutParamsType == TYPE_WALLPAPER) {
                    mWallpaperWindows.push(window);

                    for (size_t j = 0; j < numTouchedWallpapers; j++) {
                        if (window->inputChannel == mTempTouchedWallpaperChannels[i]) {
                            mTouchedWallpaperWindows.push(window);
                        }
                    }
                }

                if (window->inputChannel == touchedWindowChannel) {
                    mTouchedWindow = window;
                }
            }
        } else {
            mWindowsReady = false;
        }

        mTempTouchedWallpaperChannels.clear();

        if ((hadFocusedWindow && ! mFocusedWindow)
                || (mFocusedWindow && ! mFocusedWindow->visible)) {
            preemptInputDispatch();
        }

        mDispatchStateChanged.broadcast();

#if DEBUG_FOCUS
        logDispatchStateLd();
#endif
    } // release lock
}

bool NativeInputManager::populateWindow(JNIEnv* env, jobject windowObj,
        InputWindow& outWindow) {
    bool valid = false;

    jobject inputChannelObj = env->GetObjectField(windowObj,
            gInputWindowClassInfo.inputChannel);
    if (inputChannelObj) {
        sp<InputChannel> inputChannel =
                android_view_InputChannel_getInputChannel(env, inputChannelObj);
        if (inputChannel != NULL) {
            jint layoutParamsFlags = env->GetIntField(windowObj,
                    gInputWindowClassInfo.layoutParamsFlags);
            jint layoutParamsType = env->GetIntField(windowObj,
                    gInputWindowClassInfo.layoutParamsType);
            jlong dispatchingTimeoutNanos = env->GetLongField(windowObj,
                    gInputWindowClassInfo.dispatchingTimeoutNanos);
            jint frameLeft = env->GetIntField(windowObj,
                    gInputWindowClassInfo.frameLeft);
            jint frameTop = env->GetIntField(windowObj,
                    gInputWindowClassInfo.frameTop);
            jint touchableAreaLeft = env->GetIntField(windowObj,
                    gInputWindowClassInfo.touchableAreaLeft);
            jint touchableAreaTop = env->GetIntField(windowObj,
                    gInputWindowClassInfo.touchableAreaTop);
            jint touchableAreaRight = env->GetIntField(windowObj,
                    gInputWindowClassInfo.touchableAreaRight);
            jint touchableAreaBottom = env->GetIntField(windowObj,
                    gInputWindowClassInfo.touchableAreaBottom);
            jboolean visible = env->GetBooleanField(windowObj,
                    gInputWindowClassInfo.visible);
            jboolean hasFocus = env->GetBooleanField(windowObj,
                    gInputWindowClassInfo.hasFocus);
            jboolean hasWallpaper = env->GetBooleanField(windowObj,
                    gInputWindowClassInfo.hasWallpaper);
            jboolean paused = env->GetBooleanField(windowObj,
                    gInputWindowClassInfo.paused);
            jint ownerPid = env->GetIntField(windowObj,
                    gInputWindowClassInfo.ownerPid);
            jint ownerUid = env->GetIntField(windowObj,
                    gInputWindowClassInfo.ownerUid);

            outWindow.inputChannel = inputChannel;
            outWindow.layoutParamsFlags = layoutParamsFlags;
            outWindow.layoutParamsType = layoutParamsType;
            outWindow.dispatchingTimeout = dispatchingTimeoutNanos;
            outWindow.frameLeft = frameLeft;
            outWindow.frameTop = frameTop;
            outWindow.touchableAreaLeft = touchableAreaLeft;
            outWindow.touchableAreaTop = touchableAreaTop;
            outWindow.touchableAreaRight = touchableAreaRight;
            outWindow.touchableAreaBottom = touchableAreaBottom;
            outWindow.visible = visible;
            outWindow.hasFocus = hasFocus;
            outWindow.hasWallpaper = hasWallpaper;
            outWindow.paused = paused;
            outWindow.ownerPid = ownerPid;
            outWindow.ownerUid = ownerUid;
            valid = true;
        } else {
            LOGW("Dropping input target because its input channel is not initialized.");
        }

        env->DeleteLocalRef(inputChannelObj);
    } else {
        LOGW("Dropping input target because the input channel object was null.");
    }
    return valid;
}

void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
#if DEBUG_FOCUS
    LOGD("setFocusedApplication");
#endif
    { // acquire lock
        AutoMutex _l(mDispatchLock);

        releaseFocusedApplicationLd(env);

        if (applicationObj) {
            jstring nameObj = jstring(env->GetObjectField(applicationObj,
                    gInputApplicationClassInfo.name));
            jlong dispatchingTimeoutNanos = env->GetLongField(applicationObj,
                    gInputApplicationClassInfo.dispatchingTimeoutNanos);
            jobject tokenObj = env->GetObjectField(applicationObj,
                    gInputApplicationClassInfo.token);
            jweak tokenObjWeak = env->NewWeakGlobalRef(tokenObj);
            if (! tokenObjWeak) {
                LOGE("Could not create weak reference for application token.");
                LOGE_EX(env);
                env->ExceptionClear();
            }
            env->DeleteLocalRef(tokenObj);

            mFocusedApplication = & mFocusedApplicationStorage;

            if (nameObj) {
                const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
                mFocusedApplication->name.setTo(nameStr);
                env->ReleaseStringUTFChars(nameObj, nameStr);
                env->DeleteLocalRef(nameObj);
            } else {
                LOGE("InputApplication.name should not be null.");
                mFocusedApplication->name.setTo("unknown");
            }

            mFocusedApplication->dispatchingTimeout = dispatchingTimeoutNanos;
            mFocusedApplication->tokenObjWeak = tokenObjWeak;
        }

        mDispatchStateChanged.broadcast();

#if DEBUG_FOCUS
        logDispatchStateLd();
#endif
    } // release lock
}

void NativeInputManager::releaseFocusedApplicationLd(JNIEnv* env) {
    if (mFocusedApplication) {
        env->DeleteWeakGlobalRef(mFocusedApplication->tokenObjWeak);
        mFocusedApplication = NULL;
    }
}

void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
#if DEBUG_FOCUS
    LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
#endif

    { // acquire lock
        AutoMutex _l(mDispatchLock);

        if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
            mDispatchEnabled = enabled;
            mDispatchFrozen = frozen;

            mDispatchStateChanged.broadcast();
        }

#if DEBUG_FOCUS
        logDispatchStateLd();
#endif
    } // release lock
}

void NativeInputManager::preemptInputDispatch() {
#if DEBUG_FOCUS
    LOGD("preemptInputDispatch");
#endif

    mInputManager->preemptInputDispatch();
}

int32_t NativeInputManager::waitForFocusedWindowLd(uint32_t policyFlags,
        int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets,
        InputWindow*& outFocusedWindow) {

    int32_t injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
    bool firstIteration = true;
    ANRTimer anrTimer;
    for (;;) {
        if (firstIteration) {
            firstIteration = false;
        } else {
            if (! anrTimer.waitForDispatchStateChangeLd(this)) {
                LOGW("Dropping event because the dispatcher timed out waiting to identify "
                        "the window that should receive it.");
                injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
                break;
            }
        }

        // If dispatch is not enabled then fail.
        if (! mDispatchEnabled) {
            LOGI("Dropping event because input dispatch is disabled.");
            injectionResult = INPUT_EVENT_INJECTION_FAILED;
            break;
        }

        // If dispatch is frozen or we don't have valid window data yet then wait.
        if (mDispatchFrozen || ! mWindowsReady) {
#if DEBUG_FOCUS
            LOGD("Waiting because dispatch is frozen or windows are not ready.");
#endif
            anrTimer.dispatchFrozenBySystem();
            continue;
        }

        // If there is no currently focused window and no focused application
        // then drop the event.
        if (! mFocusedWindow) {
            if (mFocusedApplication) {
#if DEBUG_FOCUS
                LOGD("Waiting because there is no focused window but there is a "
                        "focused application that may yet introduce a new target: '%s'.",
                        mFocusedApplication->name.string());
#endif
                continue;
            }

            LOGI("Dropping event because there is no focused window or focused application.");
            injectionResult = INPUT_EVENT_INJECTION_FAILED;
            break;
        }

        // Check permissions.
        if (! checkInjectionPermission(mFocusedWindow, injectorPid, injectorUid)) {
            injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
            break;
        }

        // If the currently focused window is paused then keep waiting.
        if (mFocusedWindow->paused) {
#if DEBUG_FOCUS
            LOGD("Waiting because focused window is paused.");
#endif
            anrTimer.dispatchPausedByApplication(mFocusedWindow);
            continue;
        }

        // Success!
        break; // done waiting, exit loop
    }

    // Output targets.
    if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED) {
        addTarget(mFocusedWindow, InputTarget::FLAG_SYNC,
                anrTimer.getTimeSpentWaitingForApplication(), outTargets);

        outFocusedWindow = mFocusedWindow;
    } else {
        outFocusedWindow = NULL;
    }

#if DEBUG_FOCUS
    LOGD("waitForFocusedWindow finished: injectionResult=%d",
            injectionResult);
    logDispatchStateLd();
#endif
    return injectionResult;
}

enum InjectionPermission {
    INJECTION_PERMISSION_UNKNOWN,
    INJECTION_PERMISSION_GRANTED,
    INJECTION_PERMISSION_DENIED
};

int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uint32_t policyFlags,
        int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets,
        InputWindow*& outTouchedWindow) {
    nsecs_t startTime = now();

    // For security reasons, we defer updating the touch state until we are sure that
    // event injection will be allowed.
    //
    // FIXME In the original code, screenWasOff could never be set to true.
    //       The reason is that the POLICY_FLAG_WOKE_HERE
    //       and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
    //       EV_KEY, EV_REL and EV_ABS events.  As it happens, the touch event was
    //       actually enqueued using the policyFlags that appeared in the final EV_SYN
    //       events upon which no preprocessing took place.  So policyFlags was always 0.
    //       In the new native input dispatcher we're a bit more careful about event
    //       preprocessing so the touches we receive can actually have non-zero policyFlags.
    //       Unfortunately we obtain undesirable behavior.
    //
    //       Here's what happens:
    //
    //       When the device dims in anticipation of going to sleep, touches
    //       in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
    //       the device to brighten and reset the user activity timer.
    //       Touches on other windows (such as the launcher window)
    //       are dropped.  Then after a moment, the device goes to sleep.  Oops.
    //
    //       Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
    //       instead of POLICY_FLAG_WOKE_HERE...
    //
    bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;

    int32_t action = motionEvent->getAction();

    bool firstIteration = true;
    ANRTimer anrTimer;
    int32_t injectionResult;
    InjectionPermission injectionPermission;
    for (;;) {
        if (firstIteration) {
            firstIteration = false;
        } else {
            if (! anrTimer.waitForDispatchStateChangeLd(this)) {
                LOGW("Dropping event because the dispatcher timed out waiting to identify "
                        "the window that should receive it.");
                injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
                injectionPermission = INJECTION_PERMISSION_UNKNOWN;
                break; // timed out, exit wait loop
            }
        }

        // If dispatch is not enabled then fail.
        if (! mDispatchEnabled) {
            LOGI("Dropping event because input dispatch is disabled.");
            injectionResult = INPUT_EVENT_INJECTION_FAILED;
            injectionPermission = INJECTION_PERMISSION_UNKNOWN;
            break; // failed, exit wait loop
        }

        // If dispatch is frozen or we don't have valid window data yet then wait.
        if (mDispatchFrozen || ! mWindowsReady) {
#if DEBUG_INPUT_DISPATCHER_POLICY
            LOGD("Waiting because dispatch is frozen or windows are not ready.");
#endif
            anrTimer.dispatchFrozenBySystem();
            continue;
        }

        // Update the touch state as needed based on the properties of the touch event.
        if (action == AMOTION_EVENT_ACTION_DOWN) {
            /* Case 1: ACTION_DOWN */

            InputWindow* newTouchedWindow = NULL;
            mTempTouchedOutsideWindows.clear();

            int32_t x = int32_t(motionEvent->getX(0));
            int32_t y = int32_t(motionEvent->getY(0));
            InputWindow* topErrorWindow = NULL;

            // Traverse windows from front to back to find touched window and outside targets.
            size_t numWindows = mWindows.size();
            for (size_t i = 0; i < numWindows; i++) {
                InputWindow* window = & mWindows.editItemAt(i);
                int32_t flags = window->layoutParamsFlags;

                if (flags & FLAG_SYSTEM_ERROR) {
                    if (! topErrorWindow) {
                        topErrorWindow = window;
                    }
                }

                if (window->visible) {
                    if (! (flags & FLAG_NOT_TOUCHABLE)) {
                        bool isTouchModal = (flags &
                                (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL)) == 0;
                        if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
                            if (! screenWasOff || flags & FLAG_TOUCHABLE_WHEN_WAKING) {
                                newTouchedWindow = window;
                            }
                            break; // found touched window, exit window loop
                        }
                    }

                    if (flags & FLAG_WATCH_OUTSIDE_TOUCH) {
                        mTempTouchedOutsideWindows.push(window);
                    }
                }
            }

            // If there is an error window but it is not taking focus (typically because
            // it is invisible) then wait for it.  Any other focused window may in
            // fact be in ANR state.
            if (topErrorWindow && newTouchedWindow != topErrorWindow) {
#if DEBUG_INPUT_DISPATCHER_POLICY
                LOGD("Waiting because system error window is pending.");
#endif
                anrTimer.dispatchFrozenBySystem();
                continue; // wait some more
            }

            // If we did not find a touched window then fail.
            if (! newTouchedWindow) {
                if (mFocusedApplication) {
#if DEBUG_FOCUS
                    LOGD("Waiting because there is no focused window but there is a "
                            "focused application that may yet introduce a new target: '%s'.",
                            mFocusedApplication->name.string());
#endif
                    continue;
                }

                LOGI("Dropping event because there is no touched window or focused application.");
                injectionResult = INPUT_EVENT_INJECTION_FAILED;
                injectionPermission = INJECTION_PERMISSION_UNKNOWN;
                break; // failed, exit wait loop
            }

            // Check permissions.
            if (! checkInjectionPermission(newTouchedWindow, injectorPid, injectorUid)) {
                injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
                injectionPermission = INJECTION_PERMISSION_DENIED;
                break; // failed, exit wait loop
            }

            // If the touched window is paused then keep waiting.
            if (newTouchedWindow->paused) {
#if DEBUG_INPUT_DISPATCHER_POLICY
                LOGD("Waiting because touched window is paused.");
#endif
                anrTimer.dispatchPausedByApplication(newTouchedWindow);
                continue; // wait some more
            }

            // Success!  Update the touch dispatch state for real.
            releaseTouchedWindowLd();

            mTouchedWindow = newTouchedWindow;

            if (newTouchedWindow->hasWallpaper) {
                mTouchedWallpaperWindows.appendVector(mWallpaperWindows);
            }

            injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
            injectionPermission = INJECTION_PERMISSION_GRANTED;
            break; // done
        } else {
            /* Case 2: Everything but ACTION_DOWN */

            // Check permissions.
            if (! checkInjectionPermission(mTouchedWindow, injectorPid, injectorUid)) {
                injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
                injectionPermission = INJECTION_PERMISSION_DENIED;
                break; // failed, exit wait loop
            }

            // If the pointer is not currently down, then ignore the event.
            if (! mTouchDown) {
                LOGI("Dropping event because the pointer is not down.");
                injectionResult = INPUT_EVENT_INJECTION_FAILED;
                injectionPermission = INJECTION_PERMISSION_GRANTED;
                break; // failed, exit wait loop
            }

            // If there is no currently touched window then fail.
            if (! mTouchedWindow) {
#if DEBUG_INPUT_DISPATCHER_POLICY
                LOGD("Dropping event because there is no touched window to receive it.");
#endif
                injectionResult = INPUT_EVENT_INJECTION_FAILED;
                injectionPermission = INJECTION_PERMISSION_GRANTED;
                break; // failed, exit wait loop
            }

            // If the touched window is paused then keep waiting.
            if (mTouchedWindow->paused) {
#if DEBUG_INPUT_DISPATCHER_POLICY
                LOGD("Waiting because touched window is paused.");
#endif
                anrTimer.dispatchPausedByApplication(mTouchedWindow);
                continue; // wait some more
            }

            // Success!
            injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
            injectionPermission = INJECTION_PERMISSION_GRANTED;
            break; // done
        }
    }

    // Output targets.
    if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED) {
        size_t numWallpaperWindows = mTouchedWallpaperWindows.size();
        for (size_t i = 0; i < numWallpaperWindows; i++) {
            addTarget(mTouchedWallpaperWindows[i], 0, 0, outTargets);
        }

        size_t numOutsideWindows = mTempTouchedOutsideWindows.size();
        for (size_t i = 0; i < numOutsideWindows; i++) {
            addTarget(mTempTouchedOutsideWindows[i], InputTarget::FLAG_OUTSIDE, 0, outTargets);
        }

        addTarget(mTouchedWindow, InputTarget::FLAG_SYNC,
                anrTimer.getTimeSpentWaitingForApplication(), outTargets);
        outTouchedWindow = mTouchedWindow;
    } else {
        outTouchedWindow = NULL;
    }
    mTempTouchedOutsideWindows.clear();

    // Check injection permission once and for all.
    if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
        if (checkInjectionPermission(action == AMOTION_EVENT_ACTION_DOWN ? NULL : mTouchedWindow,
                injectorPid, injectorUid)) {
            injectionPermission = INJECTION_PERMISSION_GRANTED;
        } else {
            injectionPermission = INJECTION_PERMISSION_DENIED;
        }
    }

    // Update final pieces of touch state if the injector had permission.
    if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
        if (action == AMOTION_EVENT_ACTION_DOWN) {
            if (mTouchDown) {
                // This is weird.  We got a down but we thought it was already down!
                LOGW("Pointer down received while already down.");
            } else {
                mTouchDown = true;
            }

            if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
                // Since we failed to identify a target for this touch down, we may still
                // be holding on to an earlier target from a previous touch down.  Release it.
                releaseTouchedWindowLd();
            }
        } else if (action == AMOTION_EVENT_ACTION_UP) {
            mTouchDown = false;
            releaseTouchedWindowLd();
        }
    } else {
        LOGW("Not updating touch focus because injection was denied.");
    }

#if DEBUG_FOCUS
    LOGD("waitForTouchedWindow finished: injectionResult=%d",
            injectionResult);
    logDispatchStateLd();
#endif
    return injectionResult;
}

void NativeInputManager::releaseTouchedWindowLd() {
    mTouchedWindow = NULL;
    mTouchedWallpaperWindows.clear();
}

void NativeInputManager::addTarget(const InputWindow* window, int32_t targetFlags,
        nsecs_t timeSpentWaitingForApplication, Vector<InputTarget>& outTargets) {
    nsecs_t timeout = window->dispatchingTimeout - timeSpentWaitingForApplication;
    if (timeout < MIN_INPUT_DISPATCHING_TIMEOUT) {
        timeout = MIN_INPUT_DISPATCHING_TIMEOUT;
    }

    outTargets.push();

    InputTarget& target = outTargets.editTop();
    target.inputChannel = window->inputChannel;
    target.flags = targetFlags;
    target.timeout = timeout;
    target.xOffset = - window->frameLeft;
    target.yOffset = - window->frameTop;
}

bool NativeInputManager::checkInjectionPermission(const InputWindow* window,
        int32_t injectorPid, int32_t injectorUid) {
    if (injectorUid > 0 && (window == NULL || window->ownerUid != injectorUid)) {
        JNIEnv* env = jniEnv();
        jboolean result = env->CallBooleanMethod(mCallbacksObj,
                gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
        checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission");

        if (! result) {
            if (window) {
                LOGW("Permission denied: injecting event from pid %d uid %d to window "
                        "with input channel %s owned by uid %d",
                        injectorPid, injectorUid, window->inputChannel->getName().string(),
                        window->ownerUid);
            } else {
                LOGW("Permission denied: injecting event from pid %d uid %d",
                        injectorPid, injectorUid);
            }
            return false;
        }
    }

    return true;
}

int32_t NativeInputManager::waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
        int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets) {
#if DEBUG_INPUT_DISPATCHER_POLICY
    LOGD("waitForKeyEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d",
            policyFlags, injectorPid, injectorUid);
#endif

    int32_t windowType;
    { // acquire lock
        AutoMutex _l(mDispatchLock);

        InputWindow* focusedWindow;
        int32_t injectionResult = waitForFocusedWindowLd(policyFlags,
                injectorPid, injectorUid, outTargets, /*out*/ focusedWindow);
        if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
            return injectionResult;
        }

        windowType = focusedWindow->layoutParamsType;
    } // release lock

    if (isPolicyKey(keyEvent->getKeyCode(), isScreenOn())) {
        const InputTarget& target = outTargets.top();
        bool consumed = interceptKeyBeforeDispatching(target, keyEvent, policyFlags);
        if (consumed) {
            outTargets.clear();
            return INPUT_EVENT_INJECTION_SUCCEEDED;
        }

        addMonitoringTargetsLd(outTargets);
    }

    pokeUserActivityIfNeeded(windowType, POWER_MANAGER_BUTTON_EVENT);
    return INPUT_EVENT_INJECTION_SUCCEEDED;
}

int32_t NativeInputManager::waitForMotionEventTargets(MotionEvent* motionEvent,
        uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid,
        Vector<InputTarget>& outTargets) {
#if DEBUG_INPUT_DISPATCHER_POLICY
    LOGD("waitForMotionEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d",
            policyFlags, injectorPid, injectorUid);
#endif

    int32_t source = motionEvent->getSource();
    if (source & AINPUT_SOURCE_CLASS_POINTER) {
        return waitForTouchEventTargets(motionEvent, policyFlags, injectorPid, injectorUid,
                outTargets);
    } else {
        return waitForNonTouchEventTargets(motionEvent, policyFlags, injectorPid, injectorUid,
                outTargets);
    }
}

int32_t NativeInputManager::waitForNonTouchEventTargets(MotionEvent* motionEvent,
        uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid,
        Vector<InputTarget>& outTargets) {
#if DEBUG_INPUT_DISPATCHER_POLICY
    LOGD("waitForNonTouchEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d",
            policyFlags, injectorPid, injectorUid);
#endif

    int32_t windowType;
    { // acquire lock
        AutoMutex _l(mDispatchLock);

        InputWindow* focusedWindow;
        int32_t injectionResult = waitForFocusedWindowLd(policyFlags,
                injectorPid, injectorUid, outTargets, /*out*/ focusedWindow);
        if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
            return injectionResult;
        }

        windowType = focusedWindow->layoutParamsType;

        addMonitoringTargetsLd(outTargets);
    } // release lock

    pokeUserActivityIfNeeded(windowType, POWER_MANAGER_BUTTON_EVENT);
    return INPUT_EVENT_INJECTION_SUCCEEDED;
}

int32_t NativeInputManager::waitForTouchEventTargets(MotionEvent* motionEvent,
        uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid,
        Vector<InputTarget>& outTargets) {
#if DEBUG_INPUT_DISPATCHER_POLICY
    LOGD("waitForTouchEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d",
            policyFlags, injectorPid, injectorUid);
#endif

    int32_t windowType;
    { // acquire lock
        AutoMutex _l(mDispatchLock);

        InputWindow* touchedWindow;
        int32_t injectionResult = waitForTouchedWindowLd(motionEvent, policyFlags,
                injectorPid, injectorUid, outTargets, /*out*/ touchedWindow);
        if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
            return injectionResult;
        }

        windowType = touchedWindow->layoutParamsType;

        addMonitoringTargetsLd(outTargets);
    } // release lock

    int32_t eventType;
    switch (motionEvent->getAction()) {
    case AMOTION_EVENT_ACTION_DOWN:
        eventType = POWER_MANAGER_TOUCH_EVENT;
        break;
    case AMOTION_EVENT_ACTION_UP:
        eventType = POWER_MANAGER_TOUCH_UP_EVENT;
        break;
    default:
        if (motionEvent->getEventTime() - motionEvent->getDownTime()
                >= EVENT_IGNORE_DURATION) {
            eventType = POWER_MANAGER_TOUCH_EVENT;
        } else {
            eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
        }
        break;
    }
    pokeUserActivityIfNeeded(windowType, eventType);
    return INPUT_EVENT_INJECTION_SUCCEEDED;
}

bool NativeInputManager::interceptKeyBeforeDispatching(const InputTarget& target,
        const KeyEvent* keyEvent, uint32_t policyFlags) {
    JNIEnv* env = jniEnv();

    jobject inputChannelObj = getInputChannelObjLocal(env, target.inputChannel);
    if (inputChannelObj) {
        jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
                gCallbacksClassInfo.interceptKeyBeforeDispatching,
                inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
                keyEvent->getKeyCode(), keyEvent->getMetaState(),
                keyEvent->getRepeatCount(), policyFlags);
        bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");

        env->DeleteLocalRef(inputChannelObj);

        return consumed && ! error;
    } else {
        LOGW("Could not apply key dispatch policy because input channel '%s' is "
                "no longer valid.", target.inputChannel->getName().string());
        return false;
    }
}

void NativeInputManager::pokeUserActivityIfNeeded(int32_t windowType, int32_t eventType) {
    if (windowType != TYPE_KEYGUARD) {
        nsecs_t eventTime = now();
        pokeUserActivity(eventTime, eventType);
    }
}

void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
    android_server_PowerManagerService_userActivity(eventTime, eventType);
}

void NativeInputManager::registerMonitoringChannel(const sp<InputChannel>& inputChannel) {
    { // acquire lock
         AutoMutex _l(mDispatchLock);
         mMonitoringChannels.push(inputChannel);
    } // release lock
}

void NativeInputManager::unregisterMonitoringChannel(const sp<InputChannel>& inputChannel) {
    { // acquire lock
         AutoMutex _l(mDispatchLock);

         for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
             if (mMonitoringChannels[i] == inputChannel) {
                 mMonitoringChannels.removeAt(i);
                 break;
             }
         }
    } // release lock
}

void NativeInputManager::addMonitoringTargetsLd(Vector<InputTarget>& outTargets) {
    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
        outTargets.push();

        InputTarget& target = outTargets.editTop();
        target.inputChannel = mMonitoringChannels[i];
        target.flags = 0;
        target.timeout = -1;
        target.xOffset = 0;
        target.yOffset = 0;
    }
}

static void dumpMotionRange(String8& dump,
        const char* name, const InputDeviceInfo::MotionRange* range) {
    if (range) {
        dump.appendFormat("      %s = { min: %0.3f, max: %0.3f, flat: %0.3f, fuzz: %0.3f }\n",
                name, range->min, range->max, range->flat, range->fuzz);
    }
}

#define DUMP_MOTION_RANGE(range) \
    dumpMotionRange(dump, #range, deviceInfo.getMotionRange(AINPUT_MOTION_RANGE_##range));

void NativeInputManager::dumpDeviceInfo(String8& dump) {
    Vector<int32_t> deviceIds;
    mInputManager->getInputDeviceIds(deviceIds);

    InputDeviceInfo deviceInfo;
    for (size_t i = 0; i < deviceIds.size(); i++) {
        int32_t deviceId = deviceIds[i];

        status_t result = mInputManager->getInputDeviceInfo(deviceId, & deviceInfo);
        if (result == NAME_NOT_FOUND) {
            continue;
        } else if (result != OK) {
            dump.appendFormat("  ** Unexpected error %d getting information about input devices.\n",
                    result);
            continue;
        }

        dump.appendFormat("  Device %d: '%s'\n",
                deviceInfo.getId(), deviceInfo.getName().string());
        dump.appendFormat("    sources = 0x%08x\n",
                deviceInfo.getSources());
        dump.appendFormat("    keyboardType = %d\n",
                deviceInfo.getKeyboardType());

        dump.append("    motion ranges:\n");
        DUMP_MOTION_RANGE(X);
        DUMP_MOTION_RANGE(Y);
        DUMP_MOTION_RANGE(PRESSURE);
        DUMP_MOTION_RANGE(SIZE);
        DUMP_MOTION_RANGE(TOUCH_MAJOR);
        DUMP_MOTION_RANGE(TOUCH_MINOR);
        DUMP_MOTION_RANGE(TOOL_MAJOR);
        DUMP_MOTION_RANGE(TOOL_MINOR);
        DUMP_MOTION_RANGE(ORIENTATION);
    }
}

#undef DUMP_MOTION_RANGE

void NativeInputManager::logDispatchStateLd() {
    String8 dump;
    dumpDispatchStateLd(dump);
    LOGD("%s", dump.string());
}

void NativeInputManager::dumpDispatchStateLd(String8& dump) {
    dump.appendFormat("  dispatchEnabled: %d\n", mDispatchEnabled);
    dump.appendFormat("  dispatchFrozen: %d\n", mDispatchFrozen);
    dump.appendFormat("  windowsReady: %d\n", mWindowsReady);

    if (mFocusedApplication) {
        dump.appendFormat("  focusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
                mFocusedApplication->name.string(),
                mFocusedApplication->dispatchingTimeout / 1000000.0);
    } else {
        dump.append("  focusedApplication: <null>\n");
    }
    dump.appendFormat("  focusedWindow: '%s'\n",
            mFocusedWindow != NULL ? mFocusedWindow->inputChannel->getName().string() : "<null>");
    dump.appendFormat("  touchedWindow: '%s', touchDown=%d\n",
            mTouchedWindow != NULL ? mTouchedWindow->inputChannel->getName().string() : "<null>",
            mTouchDown);
    for (size_t i = 0; i < mTouchedWallpaperWindows.size(); i++) {
        dump.appendFormat("  touchedWallpaperWindows[%d]: '%s'\n",
                i, mTouchedWallpaperWindows[i]->inputChannel->getName().string());
    }
    for (size_t i = 0; i < mWindows.size(); i++) {
        dump.appendFormat("  windows[%d]: '%s', paused=%d, hasFocus=%d, hasWallpaper=%d, "
                "visible=%d, flags=0x%08x, type=0x%08x, "
                "frame=[%d,%d], touchableArea=[%d,%d][%d,%d], "
                "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
                i, mWindows[i].inputChannel->getName().string(),
                mWindows[i].paused, mWindows[i].hasFocus, mWindows[i].hasWallpaper,
                mWindows[i].visible, mWindows[i].layoutParamsFlags, mWindows[i].layoutParamsType,
                mWindows[i].frameLeft, mWindows[i].frameTop,
                mWindows[i].touchableAreaLeft, mWindows[i].touchableAreaTop,
                mWindows[i].touchableAreaRight, mWindows[i].touchableAreaBottom,
                mWindows[i].ownerPid, mWindows[i].ownerUid,
                mWindows[i].dispatchingTimeout / 1000000.0);
    }

    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
        dump.appendFormat("  monitoringChannel[%d]: '%s'\n",
                i, mMonitoringChannels[i]->getName().string());
    }
}

// ----------------------------------------------------------------------------

NativeInputManager::ANRTimer::ANRTimer() :
        mBudget(APPLICATION), mStartTime(now()), mFrozen(false), mPausedWindow(NULL) {
}

void NativeInputManager::ANRTimer::dispatchFrozenBySystem() {
    mFrozen = true;
}

void NativeInputManager::ANRTimer::dispatchPausedByApplication(InputWindow* pausedWindow) {
    mPausedWindow = pausedWindow;
}

bool NativeInputManager::ANRTimer::waitForDispatchStateChangeLd(NativeInputManager* inputManager) {
    nsecs_t currentTime = now();

    Budget newBudget;
    nsecs_t dispatchingTimeout;
    sp<InputChannel> pausedChannel = NULL;
    jobject tokenObj = NULL;
    if (mFrozen) {
        newBudget = SYSTEM;
        dispatchingTimeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
        mFrozen = false;
    } else if (mPausedWindow) {
        newBudget = APPLICATION;
        dispatchingTimeout = mPausedWindow->dispatchingTimeout;
        pausedChannel = mPausedWindow->inputChannel;
        mPausedWindow = NULL;
    } else if (inputManager->mFocusedApplication) {
        newBudget = APPLICATION;
        dispatchingTimeout = inputManager->mFocusedApplication->dispatchingTimeout;
        tokenObj = jniEnv()->NewLocalRef(inputManager->mFocusedApplication->tokenObjWeak);
    } else {
        newBudget = APPLICATION;
        dispatchingTimeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
    }

    if (mBudget != newBudget) {
        mBudget = newBudget;
        mStartTime = currentTime;
    }

    bool result = false;
    nsecs_t timeoutRemaining = mStartTime + dispatchingTimeout - currentTime;
    if (timeoutRemaining > 0
            && inputManager->mDispatchStateChanged.waitRelative(inputManager->mDispatchLock,
                    timeoutRemaining) == OK) {
        result = true;
    } else {
        if (pausedChannel != NULL || tokenObj != NULL) {
            bool resumed;
            nsecs_t newTimeout = 0;

            inputManager->mDispatchLock.unlock(); // release lock
            if (pausedChannel != NULL) {
                resumed = inputManager->notifyInputChannelANR(pausedChannel, /*out*/ newTimeout);
            } else {
                resumed = inputManager->notifyANR(tokenObj, /*out*/ newTimeout);
            }
            inputManager->mDispatchLock.lock(); // re-acquire lock

            if (resumed) {
                mStartTime = now() - dispatchingTimeout + newTimeout;
                result = true;
            }
        }
    }

    if (tokenObj) {
        jniEnv()->DeleteLocalRef(tokenObj);
    }

    return result;
}

nsecs_t NativeInputManager::ANRTimer::getTimeSpentWaitingForApplication() const {
    return mBudget == APPLICATION ? now() - mStartTime : 0;
}

// ----------------------------------------------------------------------------

static sp<NativeInputManager> gNativeInputManager;

static bool checkInputManagerUnitialized(JNIEnv* env) {
    if (gNativeInputManager == NULL) {
        LOGE("Input manager not initialized.");
        jniThrowRuntimeException(env, "Input manager not initialized.");
        return true;
    }
    return false;
}

static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
        jobject callbacks) {
    if (gNativeInputManager == NULL) {
        gNativeInputManager = new NativeInputManager(callbacks);
    } else {
        LOGE("Input manager already initialized.");
        jniThrowRuntimeException(env, "Input manager already initialized.");
    }
}

static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
    if (checkInputManagerUnitialized(env)) {
        return;
    }

    status_t result = gNativeInputManager->getInputManager()->start();
    if (result) {
        jniThrowRuntimeException(env, "Input manager could not be started.");
    }
}

static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
        jint displayId, jint width, jint height) {
    if (checkInputManagerUnitialized(env)) {
        return;
    }

    // XXX we could get this from the SurfaceFlinger directly instead of requiring it
    // to be passed in like this, not sure which is better but leaving it like this
    // keeps the window manager in direct control of when display transitions propagate down
    // to the input dispatcher
    gNativeInputManager->setDisplaySize(displayId, width, height);
}

static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
        jint displayId, jint orientation) {
    if (checkInputManagerUnitialized(env)) {
        return;
    }

    gNativeInputManager->setDisplayOrientation(displayId, orientation);
}

static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
        jint deviceId, jint sourceMask, jint scanCode) {
    if (checkInputManagerUnitialized(env)) {
        return AKEY_STATE_UNKNOWN;
    }

    return gNativeInputManager->getInputManager()->getScanCodeState(
            deviceId, uint32_t(sourceMask), scanCode);
}

static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
        jint deviceId, jint sourceMask, jint keyCode) {
    if (checkInputManagerUnitialized(env)) {
        return AKEY_STATE_UNKNOWN;
    }

    return gNativeInputManager->getInputManager()->getKeyCodeState(
            deviceId, uint32_t(sourceMask), keyCode);
}

static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
        jint deviceId, jint sourceMask, jint sw) {
    if (checkInputManagerUnitialized(env)) {
        return AKEY_STATE_UNKNOWN;
    }

    return gNativeInputManager->getInputManager()->getSwitchState(
            deviceId, uint32_t(sourceMask), sw);
}

static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
        jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
    if (checkInputManagerUnitialized(env)) {
        return JNI_FALSE;
    }

    int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
    uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
    jsize numCodes = env->GetArrayLength(keyCodes);
    jboolean result;
    if (numCodes == env->GetArrayLength(keyCodes)) {
        result = gNativeInputManager->getInputManager()->hasKeys(
                deviceId, uint32_t(sourceMask), numCodes, codes, flags);
    } else {
        result = JNI_FALSE;
    }

    env->ReleaseBooleanArrayElements(outFlags, flags, 0);
    env->ReleaseIntArrayElements(keyCodes, codes, 0);
    return result;
}

static void throwInputChannelNotInitialized(JNIEnv* env) {
    jniThrowException(env, "java/lang/IllegalStateException",
             "inputChannel is not initialized");
}

static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
        jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
    LOGW("Input channel object '%s' was disposed without first being unregistered with "
            "the input manager!", inputChannel->getName().string());

    if (gNativeInputManager != NULL) {
        gNativeInputManager->unregisterInputChannel(env, inputChannel);
    }
}

static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
        jobject inputChannelObj, jboolean monitor) {
    if (checkInputManagerUnitialized(env)) {
        return;
    }

    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
            inputChannelObj);
    if (inputChannel == NULL) {
        throwInputChannelNotInitialized(env);
        return;
    }


    status_t status = gNativeInputManager->registerInputChannel(
            env, inputChannel, inputChannelObj, monitor);
    if (status) {
        jniThrowRuntimeException(env, "Failed to register input channel.  "
                "Check logs for details.");
        return;
    }

    if (! monitor) {
        android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
                android_server_InputManager_handleInputChannelDisposed, NULL);
    }
}

static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
        jobject inputChannelObj) {
    if (checkInputManagerUnitialized(env)) {
        return;
    }

    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
            inputChannelObj);
    if (inputChannel == NULL) {
        throwInputChannelNotInitialized(env);
        return;
    }

    android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);

    status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
    if (status) {
        jniThrowRuntimeException(env, "Failed to unregister input channel.  "
                "Check logs for details.");
    }
}

static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
        jobject inputEventObj, jint injectorPid, jint injectorUid,
        jint syncMode, jint timeoutMillis) {
    if (checkInputManagerUnitialized(env)) {
        return INPUT_EVENT_INJECTION_FAILED;
    }

    if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
        KeyEvent keyEvent;
        android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);

        return gNativeInputManager->getInputManager()->injectInputEvent(& keyEvent,
                injectorPid, injectorUid, syncMode, timeoutMillis);
    } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
        MotionEvent motionEvent;
        android_view_MotionEvent_toNative(env, inputEventObj, & motionEvent);

        return gNativeInputManager->getInputManager()->injectInputEvent(& motionEvent,
                injectorPid, injectorUid, syncMode, timeoutMillis);
    } else {
        jniThrowRuntimeException(env, "Invalid input event type.");
        return INPUT_EVENT_INJECTION_FAILED;
    }
}

static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
        jobjectArray windowObjArray) {
    if (checkInputManagerUnitialized(env)) {
        return;
    }

    gNativeInputManager->setInputWindows(env, windowObjArray);
}

static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
        jobject applicationObj) {
    if (checkInputManagerUnitialized(env)) {
        return;
    }

    gNativeInputManager->setFocusedApplication(env, applicationObj);
}

static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
        jclass clazz, jboolean enabled, jboolean frozen) {
    if (checkInputManagerUnitialized(env)) {
        return;
    }

    gNativeInputManager->setInputDispatchMode(enabled, frozen);
}

static void android_server_InputManager_nativePreemptInputDispatch(JNIEnv* env,
        jclass clazz) {
    if (checkInputManagerUnitialized(env)) {
        return;
    }

    gNativeInputManager->preemptInputDispatch();
}

static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
    if (checkInputManagerUnitialized(env)) {
        return NULL;
    }

    String8 dump(gNativeInputManager->dump());
    return env->NewStringUTF(dump.string());
}

// ----------------------------------------------------------------------------

static JNINativeMethod gInputManagerMethods[] = {
    /* name, signature, funcPtr */
    { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V",
            (void*) android_server_InputManager_nativeInit },
    { "nativeStart", "()V",
            (void*) android_server_InputManager_nativeStart },
    { "nativeSetDisplaySize", "(III)V",
            (void*) android_server_InputManager_nativeSetDisplaySize },
    { "nativeSetDisplayOrientation", "(II)V",
            (void*) android_server_InputManager_nativeSetDisplayOrientation },
    { "nativeGetScanCodeState", "(III)I",
            (void*) android_server_InputManager_nativeGetScanCodeState },
    { "nativeGetKeyCodeState", "(III)I",
            (void*) android_server_InputManager_nativeGetKeyCodeState },
    { "nativeGetSwitchState", "(III)I",
            (void*) android_server_InputManager_nativeGetSwitchState },
    { "nativeHasKeys", "(II[I[Z)Z",
            (void*) android_server_InputManager_nativeHasKeys },
    { "nativeRegisterInputChannel", "(Landroid/view/InputChannel;Z)V",
            (void*) android_server_InputManager_nativeRegisterInputChannel },
    { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
            (void*) android_server_InputManager_nativeUnregisterInputChannel },
    { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
            (void*) android_server_InputManager_nativeInjectInputEvent },
    { "nativeSetInputWindows", "([Lcom/android/server/InputWindow;)V",
            (void*) android_server_InputManager_nativeSetInputWindows },
    { "nativeSetFocusedApplication", "(Lcom/android/server/InputApplication;)V",
            (void*) android_server_InputManager_nativeSetFocusedApplication },
    { "nativeSetInputDispatchMode", "(ZZ)V",
            (void*) android_server_InputManager_nativeSetInputDispatchMode },
    { "nativePreemptInputDispatch", "()V",
            (void*) android_server_InputManager_nativePreemptInputDispatch },
    { "nativeDump", "()Ljava/lang/String;",
            (void*) android_server_InputManager_nativeDump },
};

#define FIND_CLASS(var, className) \
        var = env->FindClass(className); \
        LOG_FATAL_IF(! var, "Unable to find class " className); \
        var = jclass(env->NewGlobalRef(var));

#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
        LOG_FATAL_IF(! var, "Unable to find method " methodName);

#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
        LOG_FATAL_IF(! var, "Unable to find field " fieldName);

int register_android_server_InputManager(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "com/android/server/InputManager",
            gInputManagerMethods, NELEM(gInputManagerMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");

    // Callbacks

    FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");

    GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
            "notifyConfigurationChanged", "(JIII)V");

    GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
            "notifyLidSwitchChanged", "(JZ)V");

    GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
            "notifyInputChannelBroken", "(Landroid/view/InputChannel;)V");

    GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelANR, gCallbacksClassInfo.clazz,
            "notifyInputChannelANR", "(Landroid/view/InputChannel;)J");

    GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelRecoveredFromANR, gCallbacksClassInfo.clazz,
            "notifyInputChannelRecoveredFromANR", "(Landroid/view/InputChannel;)V");

    GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
            "notifyANR", "(Ljava/lang/Object;)J");

    GET_METHOD_ID(gCallbacksClassInfo.virtualKeyDownFeedback, gCallbacksClassInfo.clazz,
            "virtualKeyDownFeedback", "()V");

    GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
            "interceptKeyBeforeQueueing", "(JIZIZ)I");

    GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
            "interceptKeyBeforeDispatching", "(Landroid/view/InputChannel;IIIIII)Z");

    GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
            "checkInjectEventsPermission", "(II)Z");

    GET_METHOD_ID(gCallbacksClassInfo.notifyAppSwitchComing, gCallbacksClassInfo.clazz,
            "notifyAppSwitchComing", "()V");

    GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
            "filterTouchEvents", "()Z");

    GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
            "filterJumpyTouchEvents", "()Z");

    GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyDefinitions, gCallbacksClassInfo.clazz,
            "getVirtualKeyDefinitions",
            "(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;");

    GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
            "getExcludedDeviceNames", "()[Ljava/lang/String;");

    GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
            "getMaxEventsPerSecond", "()I");

    // VirtualKeyDefinition

    FIND_CLASS(gVirtualKeyDefinitionClassInfo.clazz,
            "com/android/server/InputManager$VirtualKeyDefinition");

    GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.scanCode, gVirtualKeyDefinitionClassInfo.clazz,
            "scanCode", "I");

    GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerX, gVirtualKeyDefinitionClassInfo.clazz,
            "centerX", "I");

    GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerY, gVirtualKeyDefinitionClassInfo.clazz,
            "centerY", "I");

    GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.width, gVirtualKeyDefinitionClassInfo.clazz,
            "width", "I");

    GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.height, gVirtualKeyDefinitionClassInfo.clazz,
            "height", "I");

    // InputWindow

    FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");

    GET_FIELD_ID(gInputWindowClassInfo.inputChannel, gInputWindowClassInfo.clazz,
            "inputChannel", "Landroid/view/InputChannel;");

    GET_FIELD_ID(gInputWindowClassInfo.layoutParamsFlags, gInputWindowClassInfo.clazz,
            "layoutParamsFlags", "I");

    GET_FIELD_ID(gInputWindowClassInfo.layoutParamsType, gInputWindowClassInfo.clazz,
            "layoutParamsType", "I");

    GET_FIELD_ID(gInputWindowClassInfo.dispatchingTimeoutNanos, gInputWindowClassInfo.clazz,
            "dispatchingTimeoutNanos", "J");

    GET_FIELD_ID(gInputWindowClassInfo.frameLeft, gInputWindowClassInfo.clazz,
            "frameLeft", "I");

    GET_FIELD_ID(gInputWindowClassInfo.frameTop, gInputWindowClassInfo.clazz,
            "frameTop", "I");

    GET_FIELD_ID(gInputWindowClassInfo.touchableAreaLeft, gInputWindowClassInfo.clazz,
            "touchableAreaLeft", "I");

    GET_FIELD_ID(gInputWindowClassInfo.touchableAreaTop, gInputWindowClassInfo.clazz,
            "touchableAreaTop", "I");

    GET_FIELD_ID(gInputWindowClassInfo.touchableAreaRight, gInputWindowClassInfo.clazz,
            "touchableAreaRight", "I");

    GET_FIELD_ID(gInputWindowClassInfo.touchableAreaBottom, gInputWindowClassInfo.clazz,
            "touchableAreaBottom", "I");

    GET_FIELD_ID(gInputWindowClassInfo.visible, gInputWindowClassInfo.clazz,
            "visible", "Z");

    GET_FIELD_ID(gInputWindowClassInfo.hasFocus, gInputWindowClassInfo.clazz,
            "hasFocus", "Z");

    GET_FIELD_ID(gInputWindowClassInfo.hasWallpaper, gInputWindowClassInfo.clazz,
            "hasWallpaper", "Z");

    GET_FIELD_ID(gInputWindowClassInfo.paused, gInputWindowClassInfo.clazz,
            "paused", "Z");

    GET_FIELD_ID(gInputWindowClassInfo.ownerPid, gInputWindowClassInfo.clazz,
            "ownerPid", "I");

    GET_FIELD_ID(gInputWindowClassInfo.ownerUid, gInputWindowClassInfo.clazz,
            "ownerUid", "I");

    // InputApplication

    FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/InputApplication");

    GET_FIELD_ID(gInputApplicationClassInfo.name, gInputApplicationClassInfo.clazz,
            "name", "Ljava/lang/String;");

    GET_FIELD_ID(gInputApplicationClassInfo.dispatchingTimeoutNanos,
            gInputApplicationClassInfo.clazz,
            "dispatchingTimeoutNanos", "J");

    GET_FIELD_ID(gInputApplicationClassInfo.token, gInputApplicationClassInfo.clazz,
            "token", "Ljava/lang/Object;");

    // KeyEvent

    FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");

    // MotionEVent

    FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");

    return 0;
}

} /* namespace android */
