总结一下,Android按键事件发布流程
1
2
3
4
5
6
7
8
9
10
|
//InputReader.cpp
void
InputReader::loopOnce() {
...
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
if
(count) {
processEventsLocked(mEventBuffer, count);
}
...
}
|
1
2
3
4
5
6
7
|
//InputReader.cpp
void
InputReader::processEventsLocked(
const
RawEvent* rawEvents, size_t count) {
...
processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
...
}
|
1
2
3
4
5
6
7
|
//InputReader.cpp
void
InputReader::processEventsForDeviceLocked(int32_t deviceId,
const
RawEvent* rawEvents, size_t count) {
...
device->process(rawEvents, count);
...
}
|
1
2
3
4
5
6
|
//InputReader.cpp
void
InputDevice::process(
const
RawEvent* rawEvents, size_t count) {
...
mapper->process(rawEvent);
...
}
|
每个设备可能有多种mapper,比如既有按键又有触摸板,把事件发给相应的mapper
1
2
3
4
5
6
7
|
//InputReader.cpp
void
KeyboardInputMapper::process(
const
RawEvent* rawEvent) {
...
processKey(rawEvent->when, rawEvent->value !=
0
, keyCode, scanCode, flags);
...
}
|
键盘mapper处理事件
1
2
3
4
5
6
7
8
|
//InputReader.cpp
void
KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
int32_t scanCode, uint32_t policyFlags) {
...
getListener()->notifyKey(&args);
...
}
|
1
2
3
4
5
6
7
8
|
//InputDispatcher.cpp
void
InputDispatcher::notifyKey(
const
NotifyKeyArgs* args) {
....
needWake = enqueueInboundEventLocked(newEntry);
if
(needWake){
mLooper->wake();
}
}
|
1
2
3
4
5
6
7
|
//InputDispatcher.cpp
bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
bool needWake = mInboundQueue.isEmpty();
mInboundQueue.enqueueAtTail(entry);
....
return
needWake;
}
|
1
2
3
4
5
6
7
|
//InputDispatcher.cpp
void
InputDispatcher::dispatchOnce(){
...
dispatchOnceInnerLocked(&nextWakeupTime);
...
mLooper->pollOnce(timeoutMillis);
}
|
1
2
3
4
5
6
|
//InputDispatcher.cpp
void
InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
...
dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
...
}
|
如果有事件发生,则发布。
1
2
3
4
5
6
7
8
9
10
11
12
|
//InputDispatcher.cpp
bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
DropReason* dropReason, nsecs_t* nextWakeupTime) {
...
int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
entry, inputTargets, nextWakeupTime);
dispatchEventLocked(currentTime, entry, inputTargets);
...
}
|
首先寻找获得焦点的窗口,并将事件发送给它
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//InputDispatcher.cpp
void
InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
EventEntry* eventEntry,
const
Vector<inputtarget>& inputTargets) {
...
for
(size_t i =
0
; i < inputTargets.size(); i++) {
const
InputTarget& inputTarget = inputTargets.itemAt(i);
ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
if
(connectionIndex >=
0
) {
sp<connection> connection = mConnectionsByFd.valueAt(connectionIndex);
prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
}
...
}
}
</connection></inputtarget>
|
1
2
3
4
5
6
7
8
|
//InputDispatcher.cpp
void
InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
const
sp<connection>& connection, EventEntry* eventEntry,
const
InputTarget* inputTarget){
...
enqueueDispatchEntriesLocked(currentTime, connection,
splitMotionEntry, inputTarget);
...
}</connection>
|
1
2
3
4
5
6
7
8
9
|
//InputDispathcer.cpp
void
InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
const
sp<connection>& connection, EventEntry* eventEntry,
const
InputTarget* inputTarget) {
...
startDispatchCycleLocked(currentTime, connection);
...
}
</connection>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
//InputDispatcher.cpp
void
InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
const
sp<connection>& connection){
...
status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
keyEntry->deviceId, keyEntry->source,
dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
keyEntry->keyCode, keyEntry->scanCode,
keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
keyEntry->eventTime);
...
}</connection>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//InputTransport.cpp
status_t InputPublisher::publishKeyEvent(
uint32_t seq,
int32_t deviceId,
int32_t source,
int32_t action,
int32_t flags,
int32_t keyCode,
int32_t scanCode,
int32_t metaState,
int32_t repeatCount,
nsecs_t downTime,
nsecs_t eventTime) {
...
return
mChannel->sendMessage(&msg);
}
|
1
2
3
4
5
6
7
8
|
//InputTransport.cpp
status_t InputChannel::sendMessage(
const
InputMessage* msg) {
size_t msgLength = msg->size();
ssize_t nWrite;
do
{
nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
...
}
|
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
|
//Looper.cpp
int
Looper::pollInner(
int
timeoutMillis) {
struct epoll_event eventItems[EPOLL_MAX_EVENTS];
//等待消息
int
eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
…
Done:
for
(size_t i =
0
; i < mResponses.size(); i++) {
Response& response = mResponses.editItemAt(i);
if
(response.request.ident == ALOOPER_POLL_CALLBACK) {
int
fd = response.request.fd;
int
events = response.events;
void
* data = response.request.data;
// callback--------NativeInputEventRecieverd
int
callbackResult = response.request.callback->handleEvent(fd, events, data);
if
(callbackResult ==
0
) {
removeFd(fd);
}
response.request.callback.clear();
result = ALOOPER_POLL_CALLBACK;
}
}
return
result;
}
|
1
2
3
4
5
6
7
|
//android_view_InputEventReceiver.cpp
int
NativeInputEventReceiver::handleEvent(
int
receiveFd,
int
events,
void
* data) {
...
status_t status = consumeEvents(env,
false
/*consumeBatches*/
, -
1
, NULL);
...
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
//android_view_InputEventReceiver.cpp
status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
....
status_t status = mInputConsumer.consume(&mInputEventFactory,
consumeBatches, frameTime, &seq, &inputEvent);
...
env->CallVoidMethod(receiverObj.get(),
gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);
...
}
|
1
|
|
1
2
3
4
5
6
7
|
//InputTransport.cpp
status_t InputConsumer::consume(InputEventFactoryInterface* factory,
bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
...
status_t result = mChannel->receiveMessage(&mMsg);
...
}
|
1
2
3
4
5
6
7
|
//InputEventReceiver.java
// Called from native code.
@SuppressWarnings
(
"unused"
)
private
void
dispatchInputEvent(
int
seq, InputEvent event) {
mSeqMap.put(event.getSequenceNumber(), seq);
onInputEvent(event);
}
|
1
2
3
4
5
6
7
8
9
10
|
//ViewRootImpl.java
final
class
WindowInputEventReceiver
extends
InputEventReceiver {
public
WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
super
(inputChannel, looper);
}
@Override
public
void
onInputEvent(InputEvent event) {
enqueueInputEvent(event,
this
,
0
,
true
);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
//ViewRootImpl.java
void
enqueueInputEvent(InputEvent event,
InputEventReceiver receiver,
int
flags,
boolean
processImmediately) {
QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);
...
if
(processImmediately) {
doProcessInputEvents();
}
else
{
scheduleProcessInputEvents();
}
}
|
U kernel/include/linux/input.h
U frameworks/native/include/android/keycodes.h
U frameworks/base/core/jni/android_os_SystemProperties.cpp
U frameworks/base/core/java/android/os/Build.java
U frameworks/base/core/java/android/view/KeyEvent.java
U frameworks/base/core/res/res/values/attrs.xml
U frameworks/base/include/androidfw/KeycodeLabels.h
U frameworks/base/libs/androidfw/Input.cpp
U frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
U mediatek/platform/mt6589/kernel/drivers/keypad/kpd.c
U mediatek/config/smarttimes89_wet_jb2/mtk-kpd.kl
A mediatek/config/mt6589/navi.xml
U mediatek/config/mt6589/AndroidBoard.mk
A mediatek/config/mt6589/baidu.sh
U mediatek/config/mt6589/init.rc
U mediatek/custom/st8988/kernel/dct/dct/codegen.dws