Android6.0 按键流程 InputDispatcher分发输入消息(三)

来源:互联网 发布:scilab 矩阵 编辑:程序博客网 时间:2024/05/11 18:45


一、InputDispatcher的notifyKey函数

接上一篇我们我们分析到InputDispatcher的notifyKey函数:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {  
  2.     if (!validateKeyEvent(args->action)) {  
  3.         return;  
  4.     }  
  5.   
  6.     uint32_t policyFlags = args->policyFlags;  
  7.     int32_t flags = args->flags;  
  8.     int32_t metaState = args->metaState;  
  9.     if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {  
  10.         policyFlags |= POLICY_FLAG_VIRTUAL;  
  11.         flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;  
  12.     }  
  13.     if (policyFlags & POLICY_FLAG_FUNCTION) {  
  14.         metaState |= AMETA_FUNCTION_ON;  
  15.     }  
  16.   
  17.     policyFlags |= POLICY_FLAG_TRUSTED;  
  18.   
  19.     int32_t keyCode = args->keyCode;  
  20.     if (metaState & AMETA_META_ON && args->action == AKEY_EVENT_ACTION_DOWN) {  
  21.         int32_t newKeyCode = AKEYCODE_UNKNOWN;  
  22.         if (keyCode == AKEYCODE_DEL) {  
  23.             newKeyCode = AKEYCODE_BACK;  
  24.         } else if (keyCode == AKEYCODE_ENTER) {  
  25.             newKeyCode = AKEYCODE_HOME;  
  26.         }  
  27.         if (newKeyCode != AKEYCODE_UNKNOWN) {  
  28.             AutoMutex _l(mLock);  
  29.             struct KeyReplacement replacement = {keyCode, args->deviceId};  
  30.             mReplacedKeys.add(replacement, newKeyCode);  
  31.             keyCode = newKeyCode;  
  32.             metaState &= ~AMETA_META_ON;  
  33.         }  
  34.     } else if (args->action == AKEY_EVENT_ACTION_UP) {  
  35.         // In order to maintain a consistent stream of up and down events, check to see if the key  
  36.         // going up is one we've replaced in a down event and haven't yet replaced in an up event,  
  37.         // even if the modifier was released between the down and the up events.  
  38.         AutoMutex _l(mLock);  
  39.         struct KeyReplacement replacement = {keyCode, args->deviceId};  
  40.         ssize_t index = mReplacedKeys.indexOfKey(replacement);  
  41.         if (index >= 0) {  
  42.             keyCode = mReplacedKeys.valueAt(index);  
  43.             mReplacedKeys.removeItemsAt(index);  
  44.             metaState &= ~AMETA_META_ON;  
  45.         }  
  46.     }  
  47.   
  48.     KeyEvent event;  
  49.     event.initialize(args->deviceId, args->source, args->action,  
  50.             flags, keyCode, args->scanCode, metaState, 0,  
  51.             args->downTime, args->eventTime);  
  52.   
  53.     mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);//这个函数是调用了java的PhoneWindowManager  
  54.   
  55.     bool needWake;  
  56.     { // acquire lock  
  57.         mLock.lock();  
  58.   
  59.         if (shouldSendKeyToInputFilterLocked(args)) {  
  60.             mLock.unlock();  
  61.   
  62.             policyFlags |= POLICY_FLAG_FILTERED;  
  63.             if (!mPolicy->filterInputEvent(&event, policyFlags)) {  
  64.                 return// event was consumed by the filter  
  65.             }  
  66.   
  67.             mLock.lock();  
  68.         }  
  69.   
  70.         int32_t repeatCount = 0;  
  71.         KeyEntry* newEntry = new KeyEntry(args->eventTime,  
  72.                 args->deviceId, args->source, policyFlags,  
  73.                 args->action, flags, keyCode, args->scanCode,  
  74.                 metaState, repeatCount, args->downTime);  
  75.   
  76.         needWake = enqueueInboundEventLocked(newEntry);//将KeyEntry放入到队列中  
  77.         mLock.unlock();  
  78.     } // release lock  
  79.   
  80.     if (needWake) {  
  81.         mLooper->wake();//唤醒进程  
  82.     }  
  83. }  

我们先来看看mPolicy是构造函数中传进来的,那么我们就要去看InputManager中

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :  
  2.     mPolicy(policy),  

InputManager的构造函数,还是在InputManager中传入的,那么我们就要跟到NativeInputManager了。

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. InputManager::InputManager(  
  2.         const sp<EventHubInterface>& eventHub,  
  3.         const sp<InputReaderPolicyInterface>& readerPolicy,  
  4.         const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {  
  5.     mDispatcher = new InputDispatcher(dispatcherPolicy);  
  6.     mReader = new InputReader(eventHub, readerPolicy, mDispatcher);  
NativeInputManager是把自己传进来了,
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. NativeInputManager::NativeInputManager(jobject contextObj,  
  2.         jobject serviceObj, const sp<Looper>& looper) :  
  3.         mLooper(looper), mInteractive(true) {  
  4.     JNIEnv* env = jniEnv();  
  5.   
  6.     mContextObj = env->NewGlobalRef(contextObj);  
  7.     mServiceObj = env->NewGlobalRef(serviceObj);  
  8.   
  9.     {  
  10.         AutoMutex _l(mLock);  
  11.         mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;  
  12.         mLocked.pointerSpeed = 0;  
  13.         mLocked.pointerGesturesEnabled = true;  
  14.         mLocked.showTouches = false;  
  15.     }  
  16.     mInteractive = true;  
  17.   
  18.     sp<EventHub> eventHub = new EventHub();  
  19.     mInputManager = new InputManager(eventHub, thisthis);  

因此在InputDispatcher中调用interceptKeyBeforeQueueing,是调用了NativeInputManager的interceptKeyBeforeQueueing函数

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,  
  2.         uint32_t& policyFlags) {  
  3.     // Policy:  
  4.     // - Ignore untrusted events and pass them along.  
  5.     // - Ask the window manager what to do with normal events and trusted injected events.  
  6.     // - For normal events wake and brighten the screen if currently off or dim.  
  7.     bool interactive = mInteractive.load();  
  8.     if (interactive) {  
  9.         policyFlags |= POLICY_FLAG_INTERACTIVE;  
  10.     }  
  11.     if ((policyFlags & POLICY_FLAG_TRUSTED)) {  
  12.         nsecs_t when = keyEvent->getEventTime();  
  13.         JNIEnv* env = jniEnv();  
  14.         jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);  
  15.         jint wmActions;  
  16.         if (keyEventObj) {  
  17.             wmActions = env->CallIntMethod(mServiceObj,//反调用PhoneWindowManager  
  18.                     gServiceClassInfo.interceptKeyBeforeQueueing,  
  19.                     keyEventObj, policyFlags);  
  20.             if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {  
  21.                 wmActions = 0;  
  22.             }  
  23.             android_view_KeyEvent_recycle(env, keyEventObj);  
  24.             env->DeleteLocalRef(keyEventObj);  
  25.         } else {  
  26.             ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");  
  27.             wmActions = 0;  
  28.         }  
  29.   
  30.         handleInterceptActions(wmActions, when, /*byref*/ policyFlags);  
  31.     } else {  
  32.         if (interactive) {  
  33.             policyFlags |= POLICY_FLAG_PASS_TO_USER;  
  34.         }  
  35.     }  
  36. }  

在这个函数中会反调到PhoneWindowManager中的interceptKeyBeforeQueueing函数,在上层的result返回result &= ~ACTION_PASS_TO_USER就不会发送到应用进程了。

返回结果保存在wmActions中,然后调用了handleInterceptActions函数:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,  
  2.         uint32_t& policyFlags) {  
  3.     if (wmActions & WM_ACTION_PASS_TO_USER) {  
  4.         policyFlags |= POLICY_FLAG_PASS_TO_USER;  
  5.     } else {  
  6.     }  
  7. }  
如果PhoneWindowManager返回的是result &= ~ACTION_PASS_TO_USER,policyFlags |= POLICY_FLAG_PASS_TO_USER就没有了。

继续分析InputDispatcher::notifyKey函数,调用完interceptKeyBeforeQueueing,然后 新建了一个KeyEntry对象后,调用enqueueInboundEventLocked函数。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {  
  2.     bool needWake = mInboundQueue.isEmpty();  
  3.     mInboundQueue.enqueueAtTail(entry);//放入队列尾  
  4.     traceInboundQueueLengthLocked();  
  5.   
  6.     switch (entry->type) {  
  7.     case EventEntry::TYPE_KEY: {//各个不同类型  
  8.         // Optimize app switch latency.  
  9.         // If the application takes too long to catch up then we drop all events preceding  
  10.         // the app switch key.  
  11.         KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);  
  12.         if (isAppSwitchKeyEventLocked(keyEntry)) {  
  13.             if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {  
  14.                 mAppSwitchSawKeyDown = true;  
  15.             } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {  
  16.                 if (mAppSwitchSawKeyDown) {  
  17. #if DEBUG_APP_SWITCH  
  18.                     ALOGD("App switch is pending!");  
  19. #endif  
  20.                     mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;  
  21.                     mAppSwitchSawKeyDown = false;  
  22.                     needWake = true;  
  23.                 }  
  24.             }  
  25.         }  
  26.         break;  
  27.     }  
继续分析InputDispatcher::notifyKey函数,最后会调用mLooper的wake函数唤醒线程,这个我们就不详细分析了。之前分析过。


二、InputDispatcher分发

notifyKey我们分析完了,接下来我们分析之前的InputDispatcherThread,线程不断的循环调用了InputDispatcher的dispatchOnce函数,下面我们来看下:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. void InputDispatcher::dispatchOnce() {  
  2.     nsecs_t nextWakeupTime = LONG_LONG_MAX;  
  3.     { // acquire lock  
  4.         AutoMutex _l(mLock);  
  5.         mDispatcherIsAliveCondition.broadcast();  
  6.   
  7.         // Run a dispatch loop if there are no pending commands.  
  8.         // The dispatch loop might enqueue commands to run afterwards.  
  9.         if (!haveCommandsLocked()) {  
  10.             dispatchOnceInnerLocked(&nextWakeupTime);//分发消息  
  11.         }  
  12.   
  13.         // Run all pending commands if there are any.  
  14.         // If any commands were run then force the next poll to wake up immediately.  
  15.         if (runCommandsLockedInterruptible()) {  
  16.             nextWakeupTime = LONG_LONG_MIN;  
  17.         }  
  18.     } // release lock  
  19.   
  20.     // Wait for callback or timeout or wake.  (make sure we round up, not down)  
  21.     nsecs_t currentTime = now();  
  22.     int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);  
  23.     mLooper->pollOnce(timeoutMillis);//进入epoll  
  24. }  

继续分析dispatchOnceInnerLocked函数

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {  
  2.     ........  
  3.   
  4.     switch (mPendingEvent->type) {//根据类型不同  
  5.     case EventEntry::TYPE_CONFIGURATION_CHANGED: {  
  6.         ConfigurationChangedEntry* typedEntry =  
  7.                 static_cast<ConfigurationChangedEntry*>(mPendingEvent);  
  8.         done = dispatchConfigurationChangedLocked(currentTime, typedEntry);  
  9.         dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped  
  10.         break;  
  11.     }  
  12.   
  13.     case EventEntry::TYPE_DEVICE_RESET: {  
  14.         DeviceResetEntry* typedEntry =  
  15.                 static_cast<DeviceResetEntry*>(mPendingEvent);  
  16.         done = dispatchDeviceResetLocked(currentTime, typedEntry);  
  17.         dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped  
  18.         break;  
  19.     }  
  20.   
  21.     case EventEntry::TYPE_KEY: {  
  22.         KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);  
  23.         if (isAppSwitchDue) {  
  24.             if (isAppSwitchKeyEventLocked(typedEntry)) {  
  25.                 resetPendingAppSwitchLocked(true);  
  26.                 isAppSwitchDue = false;  
  27.             } else if (dropReason == DROP_REASON_NOT_DROPPED) {  
  28.                 dropReason = DROP_REASON_APP_SWITCH;  
  29.             }  
  30.         }  
  31.         if (dropReason == DROP_REASON_NOT_DROPPED  
  32.                 && isStaleEventLocked(currentTime, typedEntry)) {  
  33.             dropReason = DROP_REASON_STALE;  
  34.         }  
  35.         if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {  
  36.             dropReason = DROP_REASON_BLOCKED;  
  37.         }  
  38.         done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);  
  39.         break;  
  40.     }  
  41.   
  42.     case EventEntry::TYPE_MOTION: {  
  43.         MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);  
  44.         if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {  
  45.             dropReason = DROP_REASON_APP_SWITCH;  
  46.         }  
  47.         if (dropReason == DROP_REASON_NOT_DROPPED  
  48.                 && isStaleEventLocked(currentTime, typedEntry)) {  
  49.             dropReason = DROP_REASON_STALE;  
  50.         }  
  51.         if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {  
  52.             dropReason = DROP_REASON_BLOCKED;  
  53.         }  
  54.         done = dispatchMotionLocked(currentTime, typedEntry,  
  55.                 &dropReason, nextWakeupTime);  
  56.         break;  
  57.     }  
  58.   
  59.     default:  
  60.         ALOG_ASSERT(false);  
  61.         break;  
  62.     }  
  63.   
  64.     if (done) {  
  65.         if (dropReason != DROP_REASON_NOT_DROPPED) {  
  66.             dropInboundEventLocked(mPendingEvent, dropReason);  
  67.         }  
  68.         mLastDropReason = dropReason;  
  69.   
  70.         releasePendingEventLocked();  
  71.         *nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately  
  72.     }  
  73. }  

这个函数中,最后会根据类型不同调用不同的方法,我们是TYPE_KEY,调用了dispatchKeyLocked方法,一路跟下去有很多函数,我们就直接到最后的函数startDispatchCycleLocked函数:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,  
  2.         const sp<Connection>& connection) {  
  3.   
  4.     while (connection->status == Connection::STATUS_NORMAL  
  5.             && !connection->outboundQueue.isEmpty()) {  
  6.         DispatchEntry* dispatchEntry = connection->outboundQueue.head;  
  7.         dispatchEntry->deliveryTime = currentTime;  
  8.   
  9.         // Publish the event.  
  10.         status_t status;  
  11.         EventEntry* eventEntry = dispatchEntry->eventEntry;  
  12.         switch (eventEntry->type) {  
  13.         case EventEntry::TYPE_KEY: {  
  14.             KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);  
  15.   
  16.             // Publish the key event.  
  17.             status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,  
  18.                     keyEntry->deviceId, keyEntry->source,  
  19.                     dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,  
  20.                     keyEntry->keyCode, keyEntry->scanCode,  
  21.                     keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,  
  22.                     keyEntry->eventTime);  
  23.             break;  
  24.         }  

这个函数会根据Event类型来分别处理,最后调用了connection对象的inputPublisher的publishKeyEvent函数。

下篇博客我们来继续分析下connection这个对象从何而来?


转载地址

http://blog.csdn.net/kc58236582/article/details/50611208

0 0
原创粉丝点击