Link:
Android Input (1) -- InputManagerService启动
Android Input (2) -- inputReader
Android Input (3) -- inputDispatcher
Android Input (4) -- inputDispatcher到ViewRootImpl
Android Input (5) -- ViewRootImpl 的事件分发(Activity ViewGroup View )
Android Input (6) -- PhoneWindowManager中Power,BACK等按键处理流程
Android Input (7) -- 模块的锁检测
Android Input (8) -- ANR input event原理
这篇文章讲解InputReader线程,从threadloop开始,经过从eventhub获取事件getevent,然后processEventsLocked处理事件,完成事件的映射map,最后通过flush把事件给mInboundQueue中,这里会先使用interceptKeyBeforeQueueing处理部分事件,然后判断过滤事件filterInputEvent,最后通过enqueueInboundEventLocked方法 放入mInboundQueue
Input系统—InputReader线程:通过EventHub从/dev/input节点获取事件,转换成EventEntry事件加入到InputDispatcher的mInboundQueue。
Input系统—InputDispatcher线程:从mInboundQueue队列取出事件,转换成DispatchEntry事件加入到connection的outboundQueue队列。再然后开始处理分发事件,取出outbound队列,放入waitQueue.
Input系统—UI线程:创建socket pair,分别位于”InputDispatcher”线程和focused窗口所在进程的UI主线程,可相互通信。
UI主线程:通过setFdEvents(), 监听socket客户端,收到消息后回调NativeInputEventReceiver();
“InputDispatcher”线程: 通过IMS.registerInputChannel(),监听socket服务端,收到消息后回调handleReceiveCallback;
目录
1.1 InputReaderThread 线程 threadLoop()
2.1 获取事件mEventHub->getEvents
2.2 处理事件 processEventsLocked
2.2.1 processEventsLocked
2.2.2 InputDevice::process()
2.2.3 KeyboardInputMapper::process()
2.2.4 EventHub::mapKey()
2.2.5 getListener()->notifyKey
2.3 mQueuedListener->flush()
2.3.1 args->notify
2.3.2 InputDispatcher::notifyKey拦截事件并放入队列
2.3.2.1 interceptKeyBeforeQueueing
2.3.2.2 filterInputEvent
2.3.2.3 enqueueInboundEventLocked放入mInboundQueue
2.3.2.4 mLooper::wake
@frameworks/native/services/inputflinger/InputReader.cpp
bool InputReaderThread::threadLoop() {
mReader->loopOnce();
return true; //return true会一直执行
}
void InputReader::loopOnce() {
...
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE); // 2.1 EVENT_BUFFER_SIZE = 256; RawEvent mEventBuffer[EVENT_BUFFER_SIZE];
{ // acquire lock
AutoMutex _l(mLock);
mReaderIsAliveCondition.broadcast();
if (count) {
processEventsLocked(mEventBuffer, count); //2.2 处理事件
}
...
if (oldGeneration != mGeneration) {
inputDevicesChanged = true;
getInputDevicesLocked(inputDevices);
}
} // release lock
// Send out a message that the describes the changed input devices.
if (inputDevicesChanged) {
mPolicy->notifyInputDevicesChanged(inputDevices); // 输入设备发生改变
}
mQueuedListener->flush(); //2.3 发送事件到nputDispatcher
}
//构建为RawEvent
//mEventBuffer
RawEvent mEventBuffer[EVENT_BUFFER_SIZE];
struct RawEvent {
nsecs_t when;
int32_t deviceId;
int32_t type;
int32_t code;
int32_t value;
};
struct input_event {
struct timeval time; //事件发生的时间点
__u16 type;
__u16 code;
__s32 value;
};
主要就是获取kernel的event, 这里事件不仅包括input,还包括输入设备的add/remove等相关事件。
加入的输入设备在没有事件的时候,会block在EventHub中的epoll处,当有事件产生后,epoll_wait就会返回,然后针对变化的事件进行处理。
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
...
for (;;) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
if (mNeedToScanDevices) {
mNeedToScanDevices = false;
scanDevicesLocked(); //扫描设备
mNeedToSendFinishedDeviceScan = true;
}
while (mOpeningDevices != NULL) {
Device* device = mOpeningDevices;
ALOGV("Reporting device opened: id=%d, name=%s\n",
device->id, device->path.string());
mOpeningDevices = device->next;
event->when = now;
event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
event->type = DEVICE_ADDED; //添加设备的事件
event += 1;
}
...
Device* device = mDevices.valueAt(deviceIndex);
if (eventItem.events & EPOLLIN) {
//从设备不断读取事件,放入到readBuffer
int32_t readSize = read(device->fd, readBuffer,
sizeof(struct input_event) * capacity);
int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
size_t count = size_t(readSize) / sizeof(struct input_event);
for (size_t i = 0; i < count; i++) {
struct input_event& iev = readBuffer[i]; //读取事件
...
//将input_event信息, 封装成RawEvent
event->deviceId = deviceId;
event->type = iev.type;
event->code = iev.code;
event->value = iev.value;
event += 1;
capacity -= 1;
}
}
...
}
mLock.unlock(); // release lock before poll, must be before release_wake_lock
release_wake_lock(WAKE_LOCK_ID);
//poll之前先释放锁 等待input事件的到来
int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis);
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
} else {
// Some events occurred.
mPendingEventCount = size_t(pollResult);
}
}
// All done, return the number of events we read.
return event - buffer;
}
EventHub采用INotify + epoll机制实现监听目录/dev/input下的设备节点,经过EventHub将input_event结构体 + deviceId 转换成RawEvent结构体,如下:
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count;) {
int32_t type = rawEvent->type;
size_t batchSize = 1;
if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
int32_t deviceId = rawEvent->deviceId;
while (batchSize < count) {
if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
|| rawEvent[batchSize].deviceId != deviceId) {
break;
}
batchSize += 1;
}
processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
} else {
switch (rawEvent->type) {
case EventHubInterface::DEVICE_ADDED: //设备添加
addDeviceLocked(rawEvent->when, rawEvent->deviceId);
break;
case EventHubInterface::DEVICE_REMOVED: //remove
removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
break;
case EventHubInterface::FINISHED_DEVICE_SCAN: //scan device
handleConfigurationChangedLocked(rawEvent->when);
break;
default:
ALOG_ASSERT(false); // can't happen
break;
}
}
count -= batchSize;
rawEvent += batchSize;
}
}
//处理事件
void InputReader::processEventsForDeviceLocked(int32_t deviceId,
const RawEvent* rawEvents, size_t count) {
ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
if (deviceIndex < 0) {
ALOGW("Discarding event for unknown deviceId %d.", deviceId);
return;
}
InputDevice* device = mDevices.valueAt(deviceIndex);
if (device->isIgnored()) {
//ALOGD("Discarding event for ignored deviceId %d.", deviceId);
return;
}
device->process(rawEvents, count);
}
@frameworks/native/libs/input/InputDevice.cpp
void InputDevice::process(const RawEvent* rawEvents, size_t count) {
size_t numMappers = mMappers.size();
for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
if (mDropUntilNextSync) {
} else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
} else {
for (size_t i = 0; i < numMappers; i++) {
InputMapper* mapper = mMappers[i];
mapper->process(rawEvent); //调用各个InputMapper对象来映射mapper
}
}
}
}
//frameworks/native/services/inputflinger/InputReader.h
class SwitchInputMapper : public InputMapper {
class VibratorInputMapper : public InputMapper {
class KeyboardInputMapper : public InputMapper {
class CursorInputMapper : public InputMapper {
class RotaryEncoderInputMapper : public InputMapper {
class TouchInputMapper : public InputMapper {
class ExternalStylusInputMapper : public InputMapper {
class JoystickInputMapper : public InputMapper {
createDeviceLocked创建设备并添加InputMapper,提到会有多种InputMapper。 这里以 KeyboardInputMapper (按键事件)为例来展开说明
@frameworks/native/services/inputflinger/InputReader.cpp
void KeyboardInputMapper::process(const RawEvent* rawEvent) {
switch (rawEvent->type) {
case EV_KEY: {
int32_t scanCode = rawEvent->code;
int32_t usageCode = mCurrentHidUsage;
mCurrentHidUsage = 0;
if (isKeyboardOrGamepadKey(scanCode)) {
processKey(rawEvent->when, rawEvent->value != 0, scanCode, usageCode);
}
break;
}
case EV_MSC: {
case EV_SYN: {
...
}
}
void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t scanCode,
int32_t usageCode) {
int32_t keyCode;
int32_t keyMetaState;
uint32_t policyFlags;
if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, mMetaState, //将事件的扫描码(scanCode)转换成键盘码(Keycode)
&keyCode, &keyMetaState, &policyFlags)) {
keyCode = AKEYCODE_UNKNOWN;
keyMetaState = mMetaState;
policyFlags = 0;
}
if (down) {
...
mDownTime = when;
} else {
...
}
//创建NotifyKeyArgs对象, when记录eventTime, downTime记录按下时间
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime);
getListener()->notifyKey(&args); //通知key事件
}
@EventHub.cpp
status_t EventHub::mapKey(int32_t deviceId,
int32_t scanCode, int32_t usageCode, int32_t metaState,
int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const {
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
status_t status = NAME_NOT_FOUND;
if (device) {
// Check the key character map first.
sp kcm = device->getKeyCharacterMap();
if (kcm != NULL) {
if (!kcm->mapKey(scanCode, usageCode, outKeycode)) {
*outFlags = 0;
status = NO_ERROR;
}
}
// Check the key layout next.
if (status != NO_ERROR && device->keyMap.haveKeyLayout()) {
if (!device->keyMap.keyLayoutMap->mapKey(
scanCode, usageCode, outKeycode, outFlags)) {
status = NO_ERROR;
}
}
...
}
return status;
}
mKeyDowns记录着所有按下的键;
mDownTime记录按下时间点;
此处KeyboardInputMapper的mContext指向InputReader,getListener()获取的便是mQueuedListener。 接下来调用该对象的notifyKey.
[-> InputListener.cpp]
void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
mArgsQueue.push(new NotifyKeyArgs(*args));
}
//把值取出来,上面notifyKey push
@frameworks/native/services/inputflinger/InputListener.cpp
void QueuedInputListener::flush() {
size_t count = mArgsQueue.size();
for (size_t i = 0; i < count; i++) {
NotifyArgs* args = mArgsQueue[i];
args->notify(mInnerListener);
delete args;
}
mArgsQueue.clear();
}
遍历整个mArgsQueue数组, 在input架构中NotifyArgs的实现子类主要有以下几类:
@frameworks/native/services/inputflinger/InputListener.h
struct NotifyConfigurationChangedArgs : public NotifyArgs {
struct NotifyKeyArgs : public NotifyArgs {
struct NotifyMotionArgs : public NotifyArgs {
struct NotifySwitchArgs : public NotifyArgs {
struct NotifyDeviceResetArgs : public NotifyArgs {
void NotifyKeyArgs::notify(const sp& listener) const {
listener->notifyKey(this);
}
//listener是inputDispatcher
@frameworks/native/services/inputflinger/InputDispatcher.cpp
void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
int32_t keyCode = args->keyCode;
KeyEvent event;
event.initialize(args->deviceId, args->source, args->action,
flags, keyCode, args->scanCode, metaState, 0,
args->downTime, args->eventTime);
//mPolicy是指NativeInputManager对象
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags); //2.3.2.1 interceptKeyBeforeQueueing
bool needWake;
{ // acquire lock
mLock.lock();
if (shouldSendKeyToInputFilterLocked(args)) {
mLock.unlock();
policyFlags |= POLICY_FLAG_FILTERED;
if (!mPolicy->filterInputEvent(&event, policyFlags)) { //2.3.2.2 当inputEventObj不为空, 则事件被filter所拦截
return; // event was consumed by the filter
}
mLock.lock();
}
int32_t repeatCount = 0;
KeyEntry* newEntry = new KeyEntry(args->eventTime, //KeyEntry
args->deviceId, args->source, policyFlags,
args->action, flags, keyCode, args->scanCode,
metaState, repeatCount, args->downTime);
needWake = enqueueInboundEventLocked(newEntry); //2.3.2.3 放入mInboundQueue
mLock.unlock();
} // release lock
if (needWake) {
mLooper->wake(); //2.3.2.4 唤醒 InputDispatcher
}
}
调用NativeInputManager.interceptKeyBeforeQueueing,加入队列前执行拦截动作,但并不改变流程,调用链:
IMS.interceptKeyBeforeQueueing
InputMonitor.interceptKeyBeforeQueueing (继承IMS.WindowManagerCallbacks)
PhoneWindowManager.interceptKeyBeforeQueueing (继承WindowManagerPolicy)
当mInputFilterEnabled=true(该值默认为false,可通过setInputFilterEnabled设置),则调用NativeInputManager.filterInputEvent过滤输入事件;
当返回值为false则过滤该事件,不再往下分发;
生成KeyEvent,并调用enqueueInboundEventLocked,将该事件加入到InputDispatcherd的成员变量mInboundQueue。
//mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags); mpolicy是InputDispatcherPolicyInterface
sp mPolicy;
class InputDispatcherPolicyInterface : public virtual RefBase {
public:
virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) = 0;
* This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
* should be dispatched to applications.
*/
virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) = 0;
//NativeInputManager 初始化InputManager传入的this,就是InputManager中的dispatcherPolicy
NativeInputManager::NativeInputManager(jobject contextObj,
jobject serviceObj, const sp& looper) :
mLooper(looper), mInteractive(true) {
JNIEnv* env = jniEnv();
mContextObj = env->NewGlobalRef(contextObj);
mServiceObj = env->NewGlobalRef(serviceObj);
...
sp eventHub = new EventHub(); //create EventHub
mInputManager = new InputManager(eventHub, this, this);
}
@frameworks/native/services/inputflinger/InputManager.cpp
InputManager::InputManager(
const sp& eventHub,
const sp& readerPolicy,
const sp& dispatcherPolicy) {
mDispatcher = new InputDispatcher(dispatcherPolicy); //初始化InputDispatcher
mReader = new InputReader(eventHub, readerPolicy, mDispatcher); //初始化InputReader
initialize();
}
//InputDispatcher初始化就赋值 policy 为mPolicy
InputDispatcher::InputDispatcher(const sp& policy) :
mPolicy(policy), //赋值
...
policy->getDispatcherConfiguration(&mConfig);
}
@frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
uint32_t& policyFlags) {
bool interactive = mInteractive.load();
if (interactive) {
policyFlags |= POLICY_FLAG_INTERACTIVE;
}
if ((policyFlags & POLICY_FLAG_TRUSTED)) {
nsecs_t when = keyEvent->getEventTime();
JNIEnv* env = jniEnv();
jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
jint wmActions;
if (keyEventObj) {
wmActions = env->CallIntMethod(mServiceObj,
gServiceClassInfo.interceptKeyBeforeQueueing,
keyEventObj, policyFlags);
if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
wmActions = 0;
}
android_view_KeyEvent_recycle(env, keyEventObj);
env->DeleteLocalRef(keyEventObj);
} else {
}
handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
} else {
if (interactive) {
policyFlags |= POLICY_FLAG_PASS_TO_USER;
}
}
}
//calss InputManagerService method:interceptKeyBeforeQueueing
int register_android_server_InputManager(JNIEnv* env) {
int res = jniRegisterNativeMethods(env, "com/android/server/input/InputManagerService",
gInputManagerMethods, NELEM(gInputManagerMethods));
jclass clazz;
FIND_CLASS(clazz, "com/android/server/input/InputManagerService");
GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz,
"filterInputEvent", "(Landroid/view/InputEvent;I)Z");
GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeQueueing, clazz,
"interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;I)I");
InputManagerService中的WindowManagerCallbacks是接口 implements InputManagerService.WindowManagerCallbacks
@frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
// Native callback.
private int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
return mWindowManagerCallbacks.interceptKeyBeforeQueueing(event, policyFlags);
}
public interface WindowManagerCallbacks {
...
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags);
public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags);
public long interceptKeyBeforeDispatching(InputWindowHandle focus,
}
public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) {
mWindowManagerCallbacks = callbacks;
}
startOtherServices初始化传入的InputMonitor
private void startOtherServices() {
inputManager = new InputManagerService(context); //初始化InputManagerService
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
ServiceManager.addService(Context.INPUT_SERVICE, inputManager); //可以通过IInputManager来binder调用InputManagerService方法
inputManager.setWindowManagerCallbacks(wm.getInputMonitor()); //setWindowManagerCallbacks
inputManager.start(); //start inputmanager
}
得到的就是wms的mInputMonitor
@frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public InputMonitor getInputMonitor() {
return mInputMonitor;
}
//使用WindowManagerPolicy的interceptKeyBeforeQueueing
@frameworks/base/services/core/java/com/android/server/wm/InputMonitor.java
//使用WindowManagerPolicy的interceptKeyBeforeQueueing
final class InputMonitor implements InputManagerService.WindowManagerCallbacks { //implements WindowManagerCallbacks
@Override
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags);
}
}
看谁使用的WindowManagerPolicy接口
private final WindowManagerService mService;
final WindowManagerPolicy mPolicy;
@frameworks/base/core/java/android/view/WindowManagerPolicy.java
public interface WindowManagerPolicy {
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags);
}
PhoneWindowManager是接口WindowManagerPolicy
事件处理和拦截主要在这里,包括POWER灭屏,声音,语言助手,camera,BACK键之类的处理
public class PhoneWindowManager implements WindowManagerPolicy {
//可以看下policyFlags这个参数
@Override
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0;
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final boolean canceled = event.isCanceled();
final int keyCode = event.getKeyCode();
boolean useHapticFeedback = down
&& (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0
&& event.getRepeatCount() == 0;
// Handle special keys.
switch (keyCode) {
case KeyEvent.KEYCODE_BACK: { //返回键
if (down) {
interceptBackKeyDown();
} else {
boolean handled = interceptBackKeyUp(event);
// Don't pass back press to app if we've already handled it via long press
if (handled) {
result &= ~ACTION_PASS_TO_USER;
}
}
break;
}
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
break;
}
case KeyEvent.KEYCODE_POWER: { //POWER键行为控制
// Any activity on the power button stops the accessibility shortcut
cancelPendingAccessibilityShortcutAction();
result &= ~ACTION_PASS_TO_USER; //看起来~ACTION_PASS_TO_USER是表示拦截事件
isWakeKey = false; // wake-up will be handled separately
if (down) {
interceptPowerKeyDown(event, interactive);
} else {
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
//看起来像是导航栏上的事件
case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN:
// fall through
case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP:
// fall through
case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT:
// fall through
case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT: {
result &= ~ACTION_PASS_TO_USER;
interceptSystemNavigationKey(event);
break;
}
case KeyEvent.KEYCODE_SLEEP: {
break;
}
case KeyEvent.KEYCODE_MEDIA_PLAY:
case KeyEvent.KEYCODE_MEDIA_PAUSE:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MUTE:
case KeyEvent.KEYCODE_MEDIA_STOP:
case KeyEvent.KEYCODE_MEDIA_NEXT:
...
case KeyEvent.KEYCODE_CALL: {
break;
}
case KeyEvent.KEYCODE_VOICE_ASSIST: { //看起来是唤醒语音助手
Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK,
keyguardActive ? 1 : 0, 0);
break;
}
if (useHapticFeedback) { //震动反馈
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
}
if (isWakeKey) {
wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
}
return result;
}
//经过一系列判断后,调用vibrate实现振动
public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) {
mVibrator.vibrate(owningUid, owningPackage, effect, VIBRATION_ATTRIBUTES);
return true;
}
}
//return false才会拦截事件,return true正常分发事件
bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
ATRACE_CALL();
jobject inputEventObj;
JNIEnv* env = jniEnv();
switch (inputEvent->getType()) {
case AINPUT_EVENT_TYPE_KEY:
inputEventObj = android_view_KeyEvent_fromNative(env,
static_cast(inputEvent));
break;
case AINPUT_EVENT_TYPE_MOTION:
inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
static_cast(inputEvent));
break;
default:
return true; // dispatch the event normally
}
if (!inputEventObj) {
ALOGE("Failed to obtain input event object for filterInputEvent.");
return true; // dispatch the event normally
}
// The callee is responsible for recycling the event.
jboolean pass = env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent,
inputEventObj, policyFlags);
if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
pass = true;
}
env->DeleteLocalRef(inputEventObj);
return pass;
}
@frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
/ Native callback.
final boolean filterInputEvent(InputEvent event, int policyFlags) {
synchronized (mInputFilterLock) {
if (mInputFilter != null) { //mInputFilter != null拦截
try {
mInputFilter.filterInputEvent(event, policyFlags);
} catch (RemoteException e) {
/* ignore */
}
return false; //拦截
}
}
event.recycle();
return true;
}
final public void filterInputEvent(InputEvent event, int policyFlags) {
mH.obtainMessage(MSG_INPUT_EVENT, policyFlags, 0, event).sendToTarget();
}
3处理逻辑如下, 把event放入到mInboundQueue后,mLooper->wake()唤醒dispatcher线程
KeyEntry* newEntry = new KeyEntry(args->eventTime, //KeyEntry
args->deviceId, args->source, policyFlags,
args->action, flags, keyCode, args->scanCode,
metaState, repeatCount, args->downTime);
needWake = enqueueInboundEventLocked(newEntry); //放入mInboundQueue
//唤醒InputDispatcher线程
if (needWake) {
mLooper->wake();
}
enqueueInboundEventLocked把事件放入InboundQueue中
@frameworks/native/services/inputflinger/InputDispatcher.cpp
bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
bool needWake = mInboundQueue.isEmpty();
mInboundQueue.enqueueAtTail(entry); //入queue
traceInboundQueueLengthLocked();
switch (entry->type) {
case EventEntry::TYPE_KEY: {
// Optimize app switch latency.
// If the application takes too long to catch up then we drop all events preceding
// the app switch key.
KeyEntry* keyEntry = static_cast(entry);
if (isAppSwitchKeyEventLocked(keyEntry)) {
if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
mAppSwitchSawKeyDown = true;
} else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
if (mAppSwitchSawKeyDown) {
mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
mAppSwitchSawKeyDown = false;
needWake = true;
}
}
}
break;
}
case EventEntry::TYPE_MOTION: {
}
return needWake;
}