summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/inputflinger/InputDispatcher.cpp22
-rw-r--r--services/inputflinger/InputDispatcher.h4
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);