admin管理员组

文章数量:1576265

在前面的文章:Android输入事件从读取到分发三:InputDispatcherThread线程分发事件的过程 一文中已经提过事件在分发前要做拦截的事情,只不过当时没有展开来分析,因此这篇文章的主要目的就是分析事件在分发前的拦截过程。(注:Android源码版本为6.0)
在Android输入事件从读取到分发三:InputDispatcherThread线程分发事件的过程 一文中我们分析到InputDispatcher类的notifyKey方法中,第一次尝试拦截事件,可以在看看这个方法:

void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
...
    KeyEvent event;
    event.initialize(args->deviceId, args->source, args->action,
            flags, keyCode, args->scanCode, metaState, 0,
            args->downTime, args->eventTime);

    mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
...
}

这里是事件进入队列前的拦截,这里将其称为第一次拦截吧。
除此之外,在事件分发之前还要做一次拦截,也就是事件进入到InputDispatcherThread线程后,在发送事件之前,做一次拦截,调用流程如下:
dispatchOnce
->dispatchOnceInnerLocked
->dispatchKeyLocked
->doInterceptKeyBeforeDispatchingLockedInterruptible
->mPolicy->interceptKeyBeforeDispatching
这个过程这里将其称为二次拦截吧。

有了上面知识的铺垫,下面,我们逐一分析两次拦截过程。

第一次事件拦截

首先看下时序图:

接下来,跟着时序图,我们分析下事件拦截的源码:
当我们在InputDispatcher::notifyKey调用mPolicy->interceptKeyBeforeQueueing方法后,就进入到NativeInputManager::interceptKeyBeforeQueueing方法了:

void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
        uint32_t& policyFlags) {
    // Policy:
    // - Ignore untrusted events and pass them along.
    // - Ask the window manager what to do with normal events and trusted injected events.
    // - For normal events wake and brighten the screen if currently off or dim.
    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

本文标签: 事件过程android