diff options
| -rw-r--r-- | services/inputflinger/InputDispatcher.cpp | 22 | ||||
| -rw-r--r-- | services/inputflinger/InputDispatcher.h | 4 |
2 files changed, 26 insertions, 0 deletions
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp index 49aac72e28..93a8ac0fff 100644 --- a/services/inputflinger/InputDispatcher.cpp +++ b/services/inputflinger/InputDispatcher.cpp @@ -3126,6 +3126,11 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& input #endif mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle; } + + if (mFocusedDisplayId == displayId) { + onFocusChangedLocked(newFocusedWindowHandle); + } + } ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId); @@ -3241,6 +3246,8 @@ void InputDispatcher::setFocusedDisplay(int32_t displayId) { // Sanity check sp<InputWindowHandle> newFocusedWindowHandle = getValueByKey(mFocusedWindowHandlesByDisplay, displayId); + onFocusChangedLocked(newFocusedWindowHandle); + if (newFocusedWindowHandle == nullptr) { ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId); if (!mFocusedWindowHandlesByDisplay.empty()) { @@ -3799,6 +3806,13 @@ void InputDispatcher::onDispatchCycleBrokenLocked( commandEntry->connection = connection; } +void InputDispatcher::onFocusChangedLocked(const sp<InputWindowHandle>& newFocus) { + sp<IBinder> token = newFocus != nullptr ? newFocus->getToken() : nullptr; + CommandEntry* commandEntry = postCommandLocked( + & InputDispatcher::doNotifyFocusChangedLockedInterruptible); + commandEntry->token = token; +} + void InputDispatcher::onANRLocked( nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle, const sp<InputWindowHandle>& windowHandle, @@ -3856,6 +3870,14 @@ void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible( } } +void InputDispatcher::doNotifyFocusChangedLockedInterruptible( + CommandEntry* commandEntry) { + sp<IBinder> token = commandEntry->token; + mLock.unlock(); + mPolicy->notifyFocusChanged(token); + mLock.lock(); +} + void InputDispatcher::doNotifyANRLockedInterruptible( CommandEntry* commandEntry) { mLock.unlock(); diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h index 9ecabdbf08..11df5d91d9 100644 --- a/services/inputflinger/InputDispatcher.h +++ b/services/inputflinger/InputDispatcher.h @@ -214,6 +214,7 @@ public: /* Notifies the system that an input channel is unrecoverably broken. */ virtual void notifyInputChannelBroken(const sp<IBinder>& token) = 0; + virtual void notifyFocusChanged(const sp<IBinder>& token) = 0; /* Gets the input dispatcher configuration. */ virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) = 0; @@ -623,6 +624,7 @@ private: uint32_t seq; bool handled; sp<InputChannel> inputChannel; + sp<IBinder> token; }; // Generic queue implementation. @@ -1152,6 +1154,7 @@ private: nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled); void onDispatchCycleBrokenLocked( nsecs_t currentTime, const sp<Connection>& connection); + void onFocusChangedLocked(const sp<InputWindowHandle>& newFocus); void onANRLocked( nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle, const sp<InputWindowHandle>& windowHandle, @@ -1160,6 +1163,7 @@ private: // Outbound policy interactions. void doNotifyConfigurationChangedInterruptible(CommandEntry* commandEntry); void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry); + void doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry); void doNotifyANRLockedInterruptible(CommandEntry* commandEntry); void doInterceptKeyBeforeDispatchingLockedInterruptible(CommandEntry* commandEntry); void doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry); |