3. InputReader
在frameworks/base/services/input/InputReader.cpp中InputReader类成员函数loopOnce将调用EventHub类成员函数getEvents。
1
2
3
4
5
6
7
8
9
|
void
InputReader::loopOnce() {
...
size_t
count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
...
if
(count) {
processEventsLocked(mEventBuffer, count);
}
...
}
|
processEventsLocked进一步调用processEventsForDeviceLocked,而processEventsForDeviceLocked调用InputDevice类成员函数process来处理获得的输入事件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
void
InputReader::processEventsForDeviceLocked(int32_t deviceId,
const
RawEvent* rawEvents,
size_t
count) {
ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
if
(deviceIndex < 0) {
LOGW(
"Discarding event for unknown deviceId %d."
, deviceId);
return
;
}
InputDevice* device = mDevices.valueAt(deviceIndex);
if
(device->isIgnored()) {
//LOGD("Discarding event for ignored deviceId %d.", deviceId);
return
;
}
device->process(rawEvents, count);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
void
InputDevice::process(
const
RawEvent* rawEvents,
size_t
count) {
// Process all of the events in order for each mapper.
// We cannot simply ask each mapper to process them in bulk because mappers may
// have side-effects that must be interleaved. For example, joystick movement events and
// gamepad button presses are handled by different mappers but they should be dispatched
// in the order received.
size_t
numMappers = mMappers.size();
for
(
const
RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
if
(mDropUntilNextSync) {
if
(rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) {
mDropUntilNextSync =
false
;
}
}
else
if
(rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_DROPPED) {
LOGI(
"Detected input event buffer overrun for device %s."
, mName.string());
mDropUntilNextSync =
true
;
reset(rawEvent->when);
}
else
{
for
(
size_t
i = 0; i < numMappers; i++) {
InputMapper* mapper = mMappers[i];
mapper->process(rawEvent);
}
}
}
}
|
4. InputMapper
从InputReader.h中的定义可知,InputMapper是一个抽象类。事实上,每个InputDevice在创建时(InputReader::createDeviceLocked)都会为此设备增加一个或多个Mapper,每个Mappr会根据设备类别的不同来分配一个相对应的InputMapper继承类对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
InputDevice* InputReader::createDeviceLocked(int32_t deviceId,
const
String8& name, uint32_t classes) {
InputDevice* device =
new
InputDevice(&mContext, deviceId, name, classes);
// External devices.
if
(classes & INPUT_DEVICE_CLASS_EXTERNAL) {
device->setExternal(
true
);
}
// Switch-like devices.
if
(classes & INPUT_DEVICE_CLASS_SWITCH) {
device->addMapper(
new
SwitchInputMapper(device));
}
....
if
(keyboardSource != 0) {
device->addMapper(
new
KeyboardInputMapper(device, keyboardSource, keyboardType));
}
// Cursor-like devices.
if
(classes & INPUT_DEVICE_CLASS_CURSOR) {
device->addMapper(
new
CursorInputMapper(device));
}
// Touchscreens and touchpad devices.
if
(classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
device->addMapper(
new
MultiTouchInputMapper(device));
}
else
if
(classes & INPUT_DEVICE_CLASS_TOUCH) {
device->addMapper(
new
SingleTouchInputMapper(device));
}
// Joystick-like devices.
if
(classes & INPUT_DEVICE_CLASS_JOYSTICK) {
device->addMapper(
new
JoystickInputMapper(device));
}
return
device;
}
|
以单点触摸类别设备为例,其Mapper对输入事件的处理为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
void
SingleTouchInputMapper::process(
const
RawEvent* rawEvent) {
TouchInputMapper::process(rawEvent);
mSingleTouchMotionAccumulator.process(rawEvent);
}
void
TouchInputMapper::process(
const
RawEvent* rawEvent) {
mCursorButtonAccumulator.process(rawEvent);
mCursorScrollAccumulator.process(rawEvent);
mTouchButtonAccumulator.process(rawEvent);
if
(rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) {
sync(rawEvent->when);
}
}
|
其中,以下语句均是将输入事件信息转存至类成员变量中。
- mCursorButtonAccumulator.process(rawEvent);
- mCursorScrollAccumulator.process(rawEvent);
- mTouchButtonAccumulator.process(rawEvent);
- mSingleTouchMotionAccumulator.process(rawEvent);
看来输入事件的处理关键在TouchInputMapper::sync。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
void
TouchInputMapper::sync(nsecs_t when) {
...
if
(mDeviceMode == DEVICE_MODE_DISABLED) {
// Drop all input if the device is disabled.
mCurrentRawPointerData.clear();
mCurrentButtonState = 0;
}
else
{
...
// Cook pointer data. This call populates the mCurrentCookedPointerData structure
// with cooked pointer data that has the same ids and indices as the raw data.
// The following code can use either the raw or cooked data, as needed.
cookPointerData();
// Dispatch the touches either directly or by translation through a pointer on screen.
if
(mDeviceMode == DEVICE_MODE_POINTER) {
...
dispatchPointerUsage(when, policyFlags, pointerUsage);
}
else
{
...
dispatchHoverExit(when, policyFlags);
dispatchTouches(when, policyFlags);
dispatchHoverEnterAndMove(when, policyFlags);
}
...
}
...
}
|
cookPointerData将原始的输入事件(坐标)转变为屏幕坐标,而以dispatch开头的这几个函数最终将输入事件分发出去,下面以dispatchPointerUsage为例加以说明。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
void
TouchInputMapper::dispatchPointerUsage(nsecs_t when, uint32_t policyFlags,
PointerUsage pointerUsage) {
if
(pointerUsage != mPointerUsage) {
abortPointerUsage(when, policyFlags);
mPointerUsage = pointerUsage;
}
switch
(mPointerUsage) {
case
POINTER_USAGE_GESTURES:
dispatchPointerGestures(when, policyFlags,
false
/*isTimeout*/
);
break
;
case
POINTER_USAGE_STYLUS:
dispatchPointerStylus(when, policyFlags);
break
;
case
POINTER_USAGE_MOUSE:
dispatchPointerMouse(when, policyFlags);
break
;
default
:
break
;
}
}
|
1
2
3
4
|
void
TouchInputMapper::dispatchPointerStylus(nsecs_t when, uint32_t policyFlags) {
...
dispatchPointerSimple(when, policyFlags, down, hovering);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
void
TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
bool
down,
bool
hovering) {
...
if
(mPointerSimple.down && !down) {
mPointerSimple.down =
false
;
// Send up.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_UP, 0, metaState, mLastButtonState, 0,
1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
getListener()->notifyMotion(&args);
}
if
(mPointerSimple.hovering && !hovering) {
mPointerSimple.hovering =
false
;
// Send hover exit.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
getListener()->notifyMotion(&args);
}
if
(down) {
if
(!mPointerSimple.down) {
mPointerSimple.down =
true
;
mPointerSimple.downTime = when;
// Send down.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_DOWN, 0, metaState, mCurrentButtonState, 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
getListener()->notifyMotion(&args);
}
// Send move.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, metaState, mCurrentButtonState, 0,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
getListener()->notifyMotion(&args);
}
...
}
|
很明显,调用getListener()->notifyMotion来分发事件。下面来跟踪下getListener()返回的具体对象。
1
2
3
4
5
6
7
8
9
10
|
class
InputMapper {
public
:
...
inline
InputListenerInterface* getListener() {
return
mContext->getListener(); }
...
protected
:
InputReaderContext* mContext;
...
}
|
1
2
3
|
InputMapper::InputMapper(InputDevice* device) :
mDevice(device), mContext(device->getContext()) {
}
|
getListener在InputMapper基类中定义,其返回的对象为mContext->getListener()。由其构造函数可知,InputMapper.mContext即InputDevice.mContext ( InputDevice::getContext函数返回)。InputDevice.mContext在其构造函数中初始化。
1
2
3
4
5
|
InputDevice::InputDevice(InputReaderContext* context, int32_t id,
const
String8& name,
uint32_t classes) :
mContext(context), mId(id), mName(name), mClasses(classes),
mSources(0), mIsExternal(
false
), mDropUntilNextSync(
false
) {
}
|
在InputReader::createDeviceLocked函数中,分配InputDevice时传给InputDevice构造函数的context参数为InputReader.mContext的引用。这样,InputMapper::getListener返回的其实为InputReader的ContextImpl类成员变量mContext。
1
2
3
|
InputListenerInterface* InputReader::ContextImpl::getListener() {
return
mReader->mQueuedListener.get();
}
|
mQueuedInputListener的定义为: sp
QueuedInputListener::notifyMotion (InputReader.mQueuedInputListener->notifyMotion )。
QueuedInputListener类在InputListener.h和InputListener.cpp中定义和实现,其notify系列成员函数只是将传入的参数复制一份并存入数组成员变量mArgsQueue中。