Loading core/java/android/view/InputEvent.java +9 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,15 @@ public abstract class InputEvent implements Parcelable { */ public abstract void setSource(int source); /** * Recycles the event. * This method should only be used by the system since applications do not * expect {@link KeyEvent} objects to be recycled, although {@link MotionEvent} * objects are fine. See {@link KeyEvent#recycle()} for details. * @hide */ public abstract void recycle(); public int describeContents() { return 0; } Loading core/java/android/view/WindowManagerPolicy.java +2 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,8 @@ public interface WindowManagerPolicy { public final static int FLAG_INJECTED = 0x01000000; public final static int FLAG_TRUSTED = 0x02000000; public final static int FLAG_FILTERED = 0x04000000; public final static int FLAG_DISABLE_KEY_REPEAT = 0x08000000; public final static int FLAG_WOKE_HERE = 0x10000000; public final static int FLAG_BRIGHT_HERE = 0x20000000; Loading include/ui/Input.h +6 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,12 @@ enum { // input device or an application with system-wide event injection permission. POLICY_FLAG_TRUSTED = 0x02000000, // Indicates that the input event has passed through an input filter. POLICY_FLAG_FILTERED = 0x04000000, // Disables automatic key repeating behavior. POLICY_FLAG_DISABLE_KEY_REPEAT = 0x08000000, /* These flags are set by the input reader policy as it intercepts each event. */ // Indicates that the screen was off when the event was received and the event Loading services/input/InputDispatcher.cpp +69 −12 Original line number Diff line number Diff line Loading @@ -186,7 +186,7 @@ InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& polic mPolicy(policy), mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX), mNextUnblockedEvent(NULL), mDispatchEnabled(true), mDispatchFrozen(false), mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false), mFocusedWindow(NULL), mFocusedApplication(NULL), mCurrentInputTargetsValid(false), Loading Loading @@ -725,7 +725,7 @@ bool InputDispatcher::dispatchKeyLocked( if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN && (entry->policyFlags & POLICY_FLAG_TRUSTED) && !entry->isInjected()) { && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) { if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) { // We have seen two identical key downs in a row which indicates that the device Loading Loading @@ -2402,7 +2402,18 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t so bool needWake; { // acquire lock AutoMutex _l(mLock); mLock.lock(); if (mInputFilterEnabled) { mLock.unlock(); policyFlags |= POLICY_FLAG_FILTERED; if (!mPolicy->filterInputEvent(&event, policyFlags)) { return; // event was consumed by the filter } mLock.lock(); } int32_t repeatCount = 0; KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime, Loading @@ -2410,6 +2421,7 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t so metaState, repeatCount, downTime); needWake = enqueueInboundEventLocked(newEntry); mLock.unlock(); } // release lock if (needWake) { Loading Loading @@ -2452,7 +2464,23 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t bool needWake; { // acquire lock AutoMutex _l(mLock); mLock.lock(); if (mInputFilterEnabled) { mLock.unlock(); MotionEvent event; event.initialize(deviceId, source, action, flags, edgeFlags, metaState, 0, 0, xPrecision, yPrecision, downTime, eventTime, pointerCount, pointerIds, pointerCoords); policyFlags |= POLICY_FLAG_FILTERED; if (!mPolicy->filterInputEvent(&event, policyFlags)) { return; // event was consumed by the filter } mLock.lock(); } // Attempt batching and streaming of move events. if (action == AMOTION_EVENT_ACTION_MOVE Loading Loading @@ -2491,6 +2519,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t LOGD("Appended motion sample onto batch for most recent " "motion event for this device in the inbound queue."); #endif mLock.unlock(); return; // done! } Loading Loading @@ -2579,6 +2608,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t true /*resumeWithAppendedMotionSample*/); runCommandsLockedInterruptible(); mLock.unlock(); return; // done! } } Loading @@ -2593,6 +2623,7 @@ NoBatchingOrStreaming:; pointerCount, pointerIds, pointerCoords); needWake = enqueueInboundEventLocked(newEntry); mLock.unlock(); } // release lock if (needWake) { Loading @@ -2612,16 +2643,17 @@ void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t swi } int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) { int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags) { #if DEBUG_INBOUND_EVENT_DETAILS LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, " "syncMode=%d, timeoutMillis=%d", event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis); "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x", event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags); #endif nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis); uint32_t policyFlags = POLICY_FLAG_INJECTED; policyFlags |= POLICY_FLAG_INJECTED; if (hasInjectionPermission(injectorPid, injectorUid)) { policyFlags |= POLICY_FLAG_TRUSTED; } Loading @@ -2640,7 +2672,9 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, policyFlags |= POLICY_FLAG_VIRTUAL; } if (!(policyFlags & POLICY_FLAG_FILTERED)) { mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags); } if (policyFlags & POLICY_FLAG_WOKE_HERE) { flags |= AKEY_EVENT_FLAG_WOKE_HERE; Loading @@ -2664,8 +2698,10 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, return INPUT_EVENT_INJECTION_FAILED; } if (!(policyFlags & POLICY_FLAG_FILTERED)) { nsecs_t eventTime = motionEvent->getEventTime(); mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags); } mLock.lock(); const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes(); Loading Loading @@ -2780,7 +2816,8 @@ void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t inject injectionResult, injectionState->injectorPid, injectionState->injectorUid); #endif if (injectionState->injectionIsAsync) { if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) { // Log the outcome since the injector did not wait for the injection result. switch (injectionResult) { case INPUT_EVENT_INJECTION_SUCCEEDED: Loading Loading @@ -2982,6 +3019,26 @@ void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) { } } void InputDispatcher::setInputFilterEnabled(bool enabled) { #if DEBUG_FOCUS LOGD("setInputFilterEnabled: enabled=%d", enabled); #endif { // acquire lock AutoMutex _l(mLock); if (mInputFilterEnabled == enabled) { return; } mInputFilterEnabled = enabled; resetAndDropEverythingLocked("input filter is being enabled or disabled"); } // release lock // Wake up poll loop since there might be work to do to drop everything. mLooper->wake(); } bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel, const sp<InputChannel>& toChannel) { #if DEBUG_FOCUS Loading services/input/InputDispatcher.h +21 −2 Original line number Diff line number Diff line Loading @@ -176,6 +176,13 @@ public: */ virtual int32_t getMaxEventsPerSecond() = 0; /* Filters an input event. * Return true to dispatch the event unmodified, false to consume the event. * A filter can also transform and inject events later by passing POLICY_FLAG_FILTERED * to injectInputEvent. */ virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) = 0; /* Intercepts a key event immediately before queueing it. * The policy can use this method as an opportunity to perform power management functions * and early event preprocessing such as updating policy flags. Loading Loading @@ -266,7 +273,8 @@ public: * This method may be called on any thread (usually by the input manager). */ virtual int32_t injectInputEvent(const InputEvent* event, int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0; int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags) = 0; /* Sets the list of input windows. * Loading @@ -286,6 +294,14 @@ public: */ virtual void setInputDispatchMode(bool enabled, bool frozen) = 0; /* Sets whether input event filtering is enabled. * When enabled, incoming input events are sent to the policy's filterInputEvent * method instead of being dispatched. The filter is expected to use * injectInputEvent to inject the events it would like to have dispatched. * It should include POLICY_FLAG_FILTERED in the policy flags during injection. */ virtual void setInputFilterEnabled(bool enabled) = 0; /* Transfers touch focus from the window associated with one channel to the * window associated with the other channel. * Loading Loading @@ -345,11 +361,13 @@ public: int32_t switchCode, int32_t switchValue, uint32_t policyFlags) ; virtual int32_t injectInputEvent(const InputEvent* event, int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis); int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags); virtual void setInputWindows(const Vector<InputWindow>& inputWindows); virtual void setFocusedApplication(const InputApplication* inputApplication); virtual void setInputDispatchMode(bool enabled, bool frozen); virtual void setInputFilterEnabled(bool enabled); virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel, const sp<InputChannel>& toChannel); Loading Loading @@ -863,6 +881,7 @@ private: // Dispatch state. bool mDispatchEnabled; bool mDispatchFrozen; bool mInputFilterEnabled; Vector<InputWindow> mWindows; Loading Loading
core/java/android/view/InputEvent.java +9 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,15 @@ public abstract class InputEvent implements Parcelable { */ public abstract void setSource(int source); /** * Recycles the event. * This method should only be used by the system since applications do not * expect {@link KeyEvent} objects to be recycled, although {@link MotionEvent} * objects are fine. See {@link KeyEvent#recycle()} for details. * @hide */ public abstract void recycle(); public int describeContents() { return 0; } Loading
core/java/android/view/WindowManagerPolicy.java +2 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,8 @@ public interface WindowManagerPolicy { public final static int FLAG_INJECTED = 0x01000000; public final static int FLAG_TRUSTED = 0x02000000; public final static int FLAG_FILTERED = 0x04000000; public final static int FLAG_DISABLE_KEY_REPEAT = 0x08000000; public final static int FLAG_WOKE_HERE = 0x10000000; public final static int FLAG_BRIGHT_HERE = 0x20000000; Loading
include/ui/Input.h +6 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,12 @@ enum { // input device or an application with system-wide event injection permission. POLICY_FLAG_TRUSTED = 0x02000000, // Indicates that the input event has passed through an input filter. POLICY_FLAG_FILTERED = 0x04000000, // Disables automatic key repeating behavior. POLICY_FLAG_DISABLE_KEY_REPEAT = 0x08000000, /* These flags are set by the input reader policy as it intercepts each event. */ // Indicates that the screen was off when the event was received and the event Loading
services/input/InputDispatcher.cpp +69 −12 Original line number Diff line number Diff line Loading @@ -186,7 +186,7 @@ InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& polic mPolicy(policy), mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX), mNextUnblockedEvent(NULL), mDispatchEnabled(true), mDispatchFrozen(false), mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false), mFocusedWindow(NULL), mFocusedApplication(NULL), mCurrentInputTargetsValid(false), Loading Loading @@ -725,7 +725,7 @@ bool InputDispatcher::dispatchKeyLocked( if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN && (entry->policyFlags & POLICY_FLAG_TRUSTED) && !entry->isInjected()) { && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) { if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) { // We have seen two identical key downs in a row which indicates that the device Loading Loading @@ -2402,7 +2402,18 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t so bool needWake; { // acquire lock AutoMutex _l(mLock); mLock.lock(); if (mInputFilterEnabled) { mLock.unlock(); policyFlags |= POLICY_FLAG_FILTERED; if (!mPolicy->filterInputEvent(&event, policyFlags)) { return; // event was consumed by the filter } mLock.lock(); } int32_t repeatCount = 0; KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime, Loading @@ -2410,6 +2421,7 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t so metaState, repeatCount, downTime); needWake = enqueueInboundEventLocked(newEntry); mLock.unlock(); } // release lock if (needWake) { Loading Loading @@ -2452,7 +2464,23 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t bool needWake; { // acquire lock AutoMutex _l(mLock); mLock.lock(); if (mInputFilterEnabled) { mLock.unlock(); MotionEvent event; event.initialize(deviceId, source, action, flags, edgeFlags, metaState, 0, 0, xPrecision, yPrecision, downTime, eventTime, pointerCount, pointerIds, pointerCoords); policyFlags |= POLICY_FLAG_FILTERED; if (!mPolicy->filterInputEvent(&event, policyFlags)) { return; // event was consumed by the filter } mLock.lock(); } // Attempt batching and streaming of move events. if (action == AMOTION_EVENT_ACTION_MOVE Loading Loading @@ -2491,6 +2519,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t LOGD("Appended motion sample onto batch for most recent " "motion event for this device in the inbound queue."); #endif mLock.unlock(); return; // done! } Loading Loading @@ -2579,6 +2608,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t true /*resumeWithAppendedMotionSample*/); runCommandsLockedInterruptible(); mLock.unlock(); return; // done! } } Loading @@ -2593,6 +2623,7 @@ NoBatchingOrStreaming:; pointerCount, pointerIds, pointerCoords); needWake = enqueueInboundEventLocked(newEntry); mLock.unlock(); } // release lock if (needWake) { Loading @@ -2612,16 +2643,17 @@ void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t swi } int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) { int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags) { #if DEBUG_INBOUND_EVENT_DETAILS LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, " "syncMode=%d, timeoutMillis=%d", event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis); "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x", event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags); #endif nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis); uint32_t policyFlags = POLICY_FLAG_INJECTED; policyFlags |= POLICY_FLAG_INJECTED; if (hasInjectionPermission(injectorPid, injectorUid)) { policyFlags |= POLICY_FLAG_TRUSTED; } Loading @@ -2640,7 +2672,9 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, policyFlags |= POLICY_FLAG_VIRTUAL; } if (!(policyFlags & POLICY_FLAG_FILTERED)) { mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags); } if (policyFlags & POLICY_FLAG_WOKE_HERE) { flags |= AKEY_EVENT_FLAG_WOKE_HERE; Loading @@ -2664,8 +2698,10 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, return INPUT_EVENT_INJECTION_FAILED; } if (!(policyFlags & POLICY_FLAG_FILTERED)) { nsecs_t eventTime = motionEvent->getEventTime(); mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags); } mLock.lock(); const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes(); Loading Loading @@ -2780,7 +2816,8 @@ void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t inject injectionResult, injectionState->injectorPid, injectionState->injectorUid); #endif if (injectionState->injectionIsAsync) { if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) { // Log the outcome since the injector did not wait for the injection result. switch (injectionResult) { case INPUT_EVENT_INJECTION_SUCCEEDED: Loading Loading @@ -2982,6 +3019,26 @@ void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) { } } void InputDispatcher::setInputFilterEnabled(bool enabled) { #if DEBUG_FOCUS LOGD("setInputFilterEnabled: enabled=%d", enabled); #endif { // acquire lock AutoMutex _l(mLock); if (mInputFilterEnabled == enabled) { return; } mInputFilterEnabled = enabled; resetAndDropEverythingLocked("input filter is being enabled or disabled"); } // release lock // Wake up poll loop since there might be work to do to drop everything. mLooper->wake(); } bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel, const sp<InputChannel>& toChannel) { #if DEBUG_FOCUS Loading
services/input/InputDispatcher.h +21 −2 Original line number Diff line number Diff line Loading @@ -176,6 +176,13 @@ public: */ virtual int32_t getMaxEventsPerSecond() = 0; /* Filters an input event. * Return true to dispatch the event unmodified, false to consume the event. * A filter can also transform and inject events later by passing POLICY_FLAG_FILTERED * to injectInputEvent. */ virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) = 0; /* Intercepts a key event immediately before queueing it. * The policy can use this method as an opportunity to perform power management functions * and early event preprocessing such as updating policy flags. Loading Loading @@ -266,7 +273,8 @@ public: * This method may be called on any thread (usually by the input manager). */ virtual int32_t injectInputEvent(const InputEvent* event, int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0; int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags) = 0; /* Sets the list of input windows. * Loading @@ -286,6 +294,14 @@ public: */ virtual void setInputDispatchMode(bool enabled, bool frozen) = 0; /* Sets whether input event filtering is enabled. * When enabled, incoming input events are sent to the policy's filterInputEvent * method instead of being dispatched. The filter is expected to use * injectInputEvent to inject the events it would like to have dispatched. * It should include POLICY_FLAG_FILTERED in the policy flags during injection. */ virtual void setInputFilterEnabled(bool enabled) = 0; /* Transfers touch focus from the window associated with one channel to the * window associated with the other channel. * Loading Loading @@ -345,11 +361,13 @@ public: int32_t switchCode, int32_t switchValue, uint32_t policyFlags) ; virtual int32_t injectInputEvent(const InputEvent* event, int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis); int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags); virtual void setInputWindows(const Vector<InputWindow>& inputWindows); virtual void setFocusedApplication(const InputApplication* inputApplication); virtual void setInputDispatchMode(bool enabled, bool frozen); virtual void setInputFilterEnabled(bool enabled); virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel, const sp<InputChannel>& toChannel); Loading Loading @@ -863,6 +881,7 @@ private: // Dispatch state. bool mDispatchEnabled; bool mDispatchFrozen; bool mInputFilterEnabled; Vector<InputWindow> mWindows; Loading