diff options
author | 2019-10-31 18:40:33 -0700 | |
---|---|---|
committer | 2020-01-23 17:40:30 -0800 | |
commit | 5a57cff6f380f62841f671890e38a33aab129928 (patch) | |
tree | 8d9d22ddf144f82cecfac8dcf5ca05d36313a7dd | |
parent | 3afee20deaf91c96427d327e1554aa5c7fb5a212 (diff) |
Create InputThread to manage inputflinger threads
InputReader and InputDispatcher both manage their own threads. To help
manage input processing threads that have elevated priority/nice values,
we create the InputThread class.
Creating an InputThread starts the thread immediately, and loops the
loop function until the InputThread object is destructed.
Bug: 130819454
Test: atest inputflinger_tests
Test: Touch input works on crosshatch
Change-Id: I2cb56250fc62300e195c5b2474d32c2db3fa4711
-rw-r--r-- | services/inputflinger/Android.bp | 1 | ||||
-rw-r--r-- | services/inputflinger/InputThread.cpp | 60 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 40 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.h | 4 | ||||
-rw-r--r-- | services/inputflinger/include/InputThread.h | 46 | ||||
-rw-r--r-- | services/inputflinger/reader/InputReader.cpp | 40 | ||||
-rw-r--r-- | services/inputflinger/reader/include/InputReader.h | 4 |
7 files changed, 127 insertions, 68 deletions
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp index f6b5935bcf..308e93aa48 100644 --- a/services/inputflinger/Android.bp +++ b/services/inputflinger/Android.bp @@ -83,6 +83,7 @@ cc_library_shared { srcs: [ "InputListener.cpp", "InputReaderBase.cpp", + "InputThread.cpp", ], shared_libs: [ diff --git a/services/inputflinger/InputThread.cpp b/services/inputflinger/InputThread.cpp new file mode 100644 index 0000000000..b87f7a1243 --- /dev/null +++ b/services/inputflinger/InputThread.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020 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. + */ + +#include "InputThread.h" + +namespace android { + +namespace { + +// Implementation of Thread from libutils. +class InputThreadImpl : public Thread { +public: + explicit InputThreadImpl(std::function<void()> loop) + : Thread(/* canCallJava */ true), mThreadLoop(loop) {} + + ~InputThreadImpl() {} + +private: + std::function<void()> mThreadLoop; + + bool threadLoop() override { + mThreadLoop(); + return true; + } +}; + +} // namespace + +InputThread::InputThread(std::string name, std::function<void()> loop, std::function<void()> wake) + : mName(name), mThreadWake(wake) { + mThread = new InputThreadImpl(loop); + mThread->run(mName.c_str(), ANDROID_PRIORITY_URGENT_DISPLAY); +} + +InputThread::~InputThread() { + mThread->requestExit(); + if (mThreadWake) { + mThreadWake(); + } + mThread->requestExitAndWait(); +} + +bool InputThread::isCallingThread() { + return gettid() == mThread->getTid(); +} + +} // namespace android
\ No newline at end of file diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 30fdf906fc..6a56d38298 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -325,24 +325,6 @@ static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inp return dispatchEntry; } -// --- 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) @@ -367,8 +349,6 @@ InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& polic mKeyRepeatState.lastKeyEntry = nullptr; policy->getDispatcherConfiguration(&mConfig); - - mThread = new InputDispatcherThread(this); } InputDispatcher::~InputDispatcher() { @@ -387,25 +367,21 @@ InputDispatcher::~InputDispatcher() { } status_t InputDispatcher::start() { - if (mThread->isRunning()) { + if (mThread) { return ALREADY_EXISTS; } - return mThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY); + mThread = std::make_unique<InputThread>( + "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); }); + return OK; } status_t InputDispatcher::stop() { - if (!mThread->isRunning()) { - return OK; - } - if (gettid() == mThread->getTid()) { - ALOGE("InputDispatcher can only be stopped from outside of the InputDispatcherThread!"); + if (mThread && mThread->isCallingThread()) { + ALOGE("InputDispatcher cannot be stopped from its own thread!"); 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(); + mThread.reset(); + return OK; } void InputDispatcher::dispatchOnce() { diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index a4ba0dec6a..93de18d02f 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -25,6 +25,7 @@ #include "InputDispatcherPolicyInterface.h" #include "InputState.h" #include "InputTarget.h" +#include "InputThread.h" #include "Monitor.h" #include "TouchState.h" #include "TouchedWindow.h" @@ -124,8 +125,7 @@ private: STALE, }; - class InputDispatcherThread; - sp<InputDispatcherThread> mThread; + std::unique_ptr<InputThread> mThread; sp<InputDispatcherPolicyInterface> mPolicy; android::InputDispatcherConfiguration mConfig; diff --git a/services/inputflinger/include/InputThread.h b/services/inputflinger/include/InputThread.h new file mode 100644 index 0000000000..407365a269 --- /dev/null +++ b/services/inputflinger/include/InputThread.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 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. + */ + +#ifndef _UI_INPUT_THREAD_H +#define _UI_INPUT_THREAD_H + +#include <utils/Thread.h> + +namespace android { + +/* A thread that loops continuously until destructed to process input events. + * + * Creating the InputThread starts it immediately. The thread begins looping the loop + * function until the InputThread is destroyed. The wake function is used to wake anything + * that sleeps in the loop when it is time for the thread to be destroyed. + */ +class InputThread { +public: + explicit InputThread(std::string name, std::function<void()> loop, + std::function<void()> wake = nullptr); + virtual ~InputThread(); + + bool isCallingThread(); + +private: + std::string mName; + std::function<void()> mThreadWake; + sp<Thread> mThread; +}; + +} // namespace android + +#endif // _UI_INPUT_THREAD_H
\ No newline at end of file diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp index 05f0db1329..2023c6e8da 100644 --- a/services/inputflinger/reader/InputReader.cpp +++ b/services/inputflinger/reader/InputReader.cpp @@ -49,25 +49,6 @@ using android::base::StringPrintf; namespace android { -// --- InputReader::InputReaderThread --- - -/* Thread that reads raw events from the event hub and processes them, endlessly. */ -class InputReader::InputReaderThread : public Thread { -public: - explicit InputReaderThread(InputReader* reader) - : Thread(/* canCallJava */ true), mReader(reader) {} - - ~InputReaderThread() {} - -private: - InputReader* mReader; - - bool threadLoop() override { - mReader->loopOnce(); - return true; - } -}; - // --- InputReader --- InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub, @@ -83,7 +64,6 @@ InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub, mNextTimeout(LLONG_MAX), mConfigurationChangesToRefresh(0) { mQueuedListener = new QueuedInputListener(listener); - mThread = new InputReaderThread(this); { // acquire lock AutoMutex _l(mLock); @@ -100,25 +80,21 @@ InputReader::~InputReader() { } status_t InputReader::start() { - if (mThread->isRunning()) { + if (mThread) { return ALREADY_EXISTS; } - return mThread->run("InputReader", PRIORITY_URGENT_DISPLAY); + mThread = std::make_unique<InputThread>( + "InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); }); + return OK; } status_t InputReader::stop() { - if (!mThread->isRunning()) { - return OK; - } - if (gettid() == mThread->getTid()) { - ALOGE("InputReader can only be stopped from outside of the InputReaderThread!"); + if (mThread && mThread->isCallingThread()) { + ALOGE("InputReader cannot be stopped from its own thread!"); return INVALID_OPERATION; } - // Directly calling requestExitAndWait() causes the thread to not exit - // if mEventHub is waiting for a long timeout. - mThread->requestExit(); - mEventHub->wake(); - return mThread->requestExitAndWait(); + mThread.reset(); + return OK; } void InputReader::loopOnce() { diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h index 502490601e..02957cd6ee 100644 --- a/services/inputflinger/reader/include/InputReader.h +++ b/services/inputflinger/reader/include/InputReader.h @@ -21,6 +21,7 @@ #include "InputListener.h" #include "InputReaderBase.h" #include "InputReaderContext.h" +#include "InputThread.h" #include <utils/Condition.h> #include <utils/Mutex.h> @@ -116,8 +117,7 @@ protected: friend class ContextImpl; private: - class InputReaderThread; - sp<InputReaderThread> mThread; + std::unique_ptr<InputThread> mThread; Mutex mLock; |