Skip to content

Commit 85d384a

Browse files
TreeHugger RobotAndroid (Google) Code Review
authored andcommitted
Merge "Reland "Let InputReader handle its own thread""
2 parents e519536 + 28efc19 commit 85d384a

File tree

7 files changed

+118
-80
lines changed

7 files changed

+118
-80
lines changed

services/inputflinger/InputManager.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ InputManager::~InputManager() {
4646
}
4747

4848
void InputManager::initialize() {
49-
mReaderThread = new InputReaderThread(mReader);
5049
mDispatcherThread = new InputDispatcherThread(mDispatcher);
5150
}
5251

@@ -57,9 +56,9 @@ status_t InputManager::start() {
5756
return result;
5857
}
5958

60-
result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
59+
result = mReader->start();
6160
if (result) {
62-
ALOGE("Could not start InputReader thread due to error %d.", result);
61+
ALOGE("Could not start InputReader due to error %d.", result);
6362

6463
mDispatcherThread->requestExit();
6564
return result;
@@ -69,9 +68,9 @@ status_t InputManager::start() {
6968
}
7069

7170
status_t InputManager::stop() {
72-
status_t result = mReaderThread->requestExitAndWait();
71+
status_t result = mReader->stop();
7372
if (result) {
74-
ALOGW("Could not stop InputReader thread due to error %d.", result);
73+
ALOGW("Could not stop InputReader due to error %d.", result);
7574
}
7675

7776
result = mDispatcherThread->requestExitAndWait();

services/inputflinger/InputManager.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ class InputDispatcherThread;
4343
/*
4444
* The input manager is the core of the system event processing.
4545
*
46-
* The input manager uses two threads.
46+
* The input manager has two components.
4747
*
48-
* 1. The InputReaderThread (called "InputReader") reads and preprocesses raw input events,
49-
* applies policy, and posts messages to a queue managed by the DispatcherThread.
48+
* 1. The InputReader class starts a thread that reads and preprocesses raw input events, applies
49+
* policy, and posts messages to a queue managed by the InputDispatcherThread.
5050
* 2. The InputDispatcherThread (called "InputDispatcher") thread waits for new events on the
5151
* queue and asynchronously dispatches them to applications.
5252
*
53-
* By design, the InputReaderThread class and InputDispatcherThread class do not share any
54-
* internal state. Moreover, all communication is done one way from the InputReaderThread
53+
* By design, the InputReader class and InputDispatcherThread class do not share any
54+
* internal state. Moreover, all communication is done one way from the InputReader
5555
* into the InputDispatcherThread and never the reverse. Both classes may interact with the
5656
* InputDispatchPolicy, however.
5757
*
@@ -102,7 +102,6 @@ class InputManager : public InputManagerInterface, public BnInputFlinger {
102102

103103
private:
104104
sp<InputReaderInterface> mReader;
105-
sp<InputReaderThread> mReaderThread;
106105

107106
sp<InputClassifierInterface> mClassifier;
108107

services/inputflinger/InputReaderBase.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,6 @@ using android::base::StringPrintf;
3333

3434
namespace android {
3535

36-
// --- InputReaderThread ---
37-
38-
InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
39-
Thread(/*canCallJava*/ true), mReader(reader) {
40-
}
41-
42-
InputReaderThread::~InputReaderThread() {
43-
}
44-
45-
bool InputReaderThread::threadLoop() {
46-
mReader->loopOnce();
47-
return true;
48-
}
49-
5036
// --- InputReaderConfiguration ---
5137

5238
std::string InputReaderConfiguration::changesToString(uint32_t changes) {

services/inputflinger/include/InputReaderBase.h

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919

2020
#include "PointerControllerInterface.h"
2121

22+
#include <input/DisplayViewport.h>
2223
#include <input/Input.h>
2324
#include <input/InputDevice.h>
24-
#include <input/DisplayViewport.h>
2525
#include <input/VelocityControl.h>
2626
#include <input/VelocityTracker.h>
27-
#include <utils/Thread.h>
27+
#include <utils/Errors.h>
2828
#include <utils/RefBase.h>
2929

3030
#include <stddef.h>
@@ -44,7 +44,16 @@
4444

4545
namespace android {
4646

47-
/* Processes raw input events and sends cooked event data to an input listener. */
47+
// --- InputReaderInterface ---
48+
49+
/* The interface for the InputReader shared library.
50+
*
51+
* Manages one or more threads that process raw input events and sends cooked event data to an
52+
* input listener.
53+
*
54+
* The implementation must guarantee thread safety for this interface. However, since the input
55+
* listener is NOT thread safe, all calls to the listener must happen from the same thread.
56+
*/
4857
class InputReaderInterface : public virtual RefBase {
4958
protected:
5059
InputReaderInterface() { }
@@ -56,18 +65,17 @@ class InputReaderInterface : public virtual RefBase {
5665
* This method may be called on any thread (usually by the input manager). */
5766
virtual void dump(std::string& dump) = 0;
5867

59-
/* Called by the heatbeat to ensures that the reader has not deadlocked. */
68+
/* Called by the heartbeat to ensures that the reader has not deadlocked. */
6069
virtual void monitor() = 0;
6170

6271
/* Returns true if the input device is enabled. */
6372
virtual bool isInputDeviceEnabled(int32_t deviceId) = 0;
6473

65-
/* Runs a single iteration of the processing loop.
66-
* Nominally reads and processes one incoming message from the EventHub.
67-
*
68-
* This method should be called on the input reader thread.
69-
*/
70-
virtual void loopOnce() = 0;
74+
/* Makes the reader start processing events from the kernel. */
75+
virtual status_t start() = 0;
76+
77+
/* Makes the reader stop processing any more events. */
78+
virtual status_t stop() = 0;
7179

7280
/* Gets information about all input devices.
7381
*
@@ -104,17 +112,7 @@ class InputReaderInterface : public virtual RefBase {
104112
virtual bool canDispatchToDisplay(int32_t deviceId, int32_t displayId) = 0;
105113
};
106114

107-
/* Reads raw events from the event hub and processes them, endlessly. */
108-
class InputReaderThread : public Thread {
109-
public:
110-
explicit InputReaderThread(const sp<InputReaderInterface>& reader);
111-
virtual ~InputReaderThread();
112-
113-
private:
114-
sp<InputReaderInterface> mReader;
115-
116-
virtual bool threadLoop();
117-
};
115+
// --- InputReaderConfiguration ---
118116

119117
/*
120118
* Input reader configuration.
@@ -285,6 +283,8 @@ struct InputReaderConfiguration {
285283
std::vector<DisplayViewport> mDisplays;
286284
};
287285

286+
// --- TouchAffineTransformation ---
287+
288288
struct TouchAffineTransformation {
289289
float x_scale;
290290
float x_ymix;
@@ -307,6 +307,8 @@ struct TouchAffineTransformation {
307307
void applyTo(float& x, float& y) const;
308308
};
309309

310+
// --- InputReaderPolicyInterface ---
311+
310312
/*
311313
* Input reader policy interface.
312314
*
@@ -316,8 +318,8 @@ struct TouchAffineTransformation {
316318
* The actual implementation is partially supported by callbacks into the DVM
317319
* via JNI. This interface is also mocked in the unit tests.
318320
*
319-
* These methods must NOT re-enter the input reader since they may be called while
320-
* holding the input reader lock.
321+
* These methods will NOT re-enter the input reader interface, so they may be called from
322+
* any method in the input reader interface.
321323
*/
322324
class InputReaderPolicyInterface : public virtual RefBase {
323325
protected:

services/inputflinger/reader/InputReader.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,38 @@
3838
#include <unistd.h>
3939

4040
#include <log/log.h>
41+
#include <utils/Errors.h>
4142

4243
#include <android-base/stringprintf.h>
4344
#include <input/Keyboard.h>
4445
#include <input/VirtualKeyMap.h>
45-
46+
#include <utils/Thread.h>
4647

4748
using android::base::StringPrintf;
4849

4950
namespace android {
5051

52+
// --- InputReader::InputReaderThread ---
53+
54+
/* Thread that reads raw events from the event hub and processes them, endlessly. */
55+
class InputReader::InputReaderThread : public Thread {
56+
public:
57+
explicit InputReaderThread(InputReader* reader)
58+
: Thread(/* canCallJava */ true), mReader(reader) {}
59+
60+
~InputReaderThread() {}
61+
62+
private:
63+
InputReader* mReader;
64+
65+
bool threadLoop() override {
66+
mReader->loopOnce();
67+
return true;
68+
}
69+
};
70+
71+
// --- InputReader ---
72+
5173
InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
5274
const sp<InputReaderPolicyInterface>& policy,
5375
const sp<InputListenerInterface>& listener)
@@ -61,6 +83,7 @@ InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
6183
mNextTimeout(LLONG_MAX),
6284
mConfigurationChangesToRefresh(0) {
6385
mQueuedListener = new QueuedInputListener(listener);
86+
mThread = new InputReaderThread(this);
6487

6588
{ // acquire lock
6689
AutoMutex _l(mLock);
@@ -76,6 +99,28 @@ InputReader::~InputReader() {
7699
}
77100
}
78101

102+
status_t InputReader::start() {
103+
if (mThread->isRunning()) {
104+
return ALREADY_EXISTS;
105+
}
106+
return mThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
107+
}
108+
109+
status_t InputReader::stop() {
110+
if (!mThread->isRunning()) {
111+
return OK;
112+
}
113+
if (gettid() == mThread->getTid()) {
114+
ALOGE("InputReader can only be stopped from outside of the InputReaderThread!");
115+
return INVALID_OPERATION;
116+
}
117+
// Directly calling requestExitAndWait() causes the thread to not exit
118+
// if mEventHub is waiting for a long timeout.
119+
mThread->requestExit();
120+
mEventHub->wake();
121+
return mThread->requestExitAndWait();
122+
}
123+
79124
void InputReader::loopOnce() {
80125
int32_t oldGeneration;
81126
int32_t timeoutMillis;

services/inputflinger/reader/include/InputReader.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ struct StylusState;
3838
* that it sends to the input listener. Some functions of the input reader, such as early
3939
* event filtering in low power states, are controlled by a separate policy object.
4040
*
41-
* The InputReader owns a collection of InputMappers. Most of the work it does happens
42-
* on the input reader thread but the InputReader can receive queries from other system
41+
* The InputReader owns a collection of InputMappers. InputReader starts its own thread, where
42+
* most of the work happens, but the InputReader can receive queries from other system
4343
* components running on arbitrary threads. To keep things manageable, the InputReader
4444
* uses a single Mutex to guard its state. The Mutex may be held while calling into the
4545
* EventHub or the InputReaderPolicy but it is never held while calling into the
46-
* InputListener.
46+
* InputListener. All calls to InputListener must happen from InputReader's thread.
4747
*/
4848
class InputReader : public InputReaderInterface {
4949
public:
@@ -55,7 +55,8 @@ class InputReader : public InputReaderInterface {
5555
virtual void dump(std::string& dump) override;
5656
virtual void monitor() override;
5757

58-
virtual void loopOnce() override;
58+
virtual status_t start() override;
59+
virtual status_t stop() override;
5960

6061
virtual void getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) override;
6162

@@ -86,6 +87,10 @@ class InputReader : public InputReaderInterface {
8687
const InputDeviceIdentifier& identifier,
8788
uint32_t classes);
8889

90+
// With each iteration of the loop, InputReader reads and processes one incoming message from
91+
// the EventHub.
92+
void loopOnce();
93+
8994
class ContextImpl : public InputReaderContext {
9095
InputReader* mReader;
9196

@@ -111,6 +116,9 @@ class InputReader : public InputReaderInterface {
111116
friend class ContextImpl;
112117

113118
private:
119+
class InputReaderThread;
120+
sp<InputReaderThread> mThread;
121+
114122
Mutex mLock;
115123

116124
Condition mReaderIsAliveCondition;

0 commit comments

Comments
 (0)