Let InputDispatcher handle its own thread
We move the threading logic from InputManger to InputDispatcher by
removing dispatchOnce() method from InputDispatcherInterface and adding
a start() and stop() method in its place.
Bug: 130819454
Test: atest inputflinger_tests
Test: Touch input works on crosshatch
Change-Id: I1d06be2330a2f8b9261fd5c5323a486d6aa544e8
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index b9bec44..dcb3ebc 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -240,6 +240,24 @@
return removed;
}
+// --- InputDispatcherThread ---
+
+class InputDispatcher::InputDispatcherThread : public Thread {
+public:
+ explicit InputDispatcherThread(InputDispatcher* dispatcher)
+ : Thread(/* canCallJava */ true), mDispatcher(dispatcher) {}
+
+ ~InputDispatcherThread() {}
+
+private:
+ InputDispatcher* mDispatcher;
+
+ virtual bool threadLoop() override {
+ mDispatcher->dispatchOnce();
+ return true;
+ }
+};
+
// --- InputDispatcher ---
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
@@ -264,6 +282,8 @@
mKeyRepeatState.lastKeyEntry = nullptr;
policy->getDispatcherConfiguration(&mConfig);
+
+ mThread = new InputDispatcherThread(this);
}
InputDispatcher::~InputDispatcher() {
@@ -281,6 +301,28 @@
}
}
+status_t InputDispatcher::start() {
+ if (mThread->isRunning()) {
+ return ALREADY_EXISTS;
+ }
+ return mThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
+}
+
+status_t InputDispatcher::stop() {
+ if (!mThread->isRunning()) {
+ return OK;
+ }
+ if (gettid() == mThread->getTid()) {
+ ALOGE("InputDispatcher can only be stopped from outside of the InputDispatcherThread!");
+ return INVALID_OPERATION;
+ }
+ // Directly calling requestExitAndWait() causes the thread to not exit
+ // if mLooper is waiting for a long timeout.
+ mThread->requestExit();
+ mLooper->wake();
+ return mThread->requestExitAndWait();
+}
+
void InputDispatcher::dispatchOnce() {
nsecs_t nextWakeupTime = LONG_LONG_MAX;
{ // acquire lock