一个是InputReader,一个是InputDispatcher。方法是dispatchTouch。
入口点是InputReader 的loopOnce方法.
InputReader里面有个线程叫做InputReaderThread,threadLoop
[code="java"]InputReaderThread::InputReaderThread(const sp& reader) :
        Thread(/*canCallJava*/ true), mReader(reader) {
}
InputReaderThread::~InputReaderThread() {
}
bool InputReaderThread::threadLoop() {
    mReader->loopOnce();
    return true;
}
Java代码 
 ![]()
class="star" src="/Upload/Images/2014101410/40B102E0EF997EA6.png" alt="收藏代码" />
- void InputDispatcher::dispatchOnce() {  
-     nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();  
-     nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();  
-   
-     nsecs_t nextWakeupTime = LONG_LONG_MAX;  
-     { 
-         AutoMutex _l(mLock);  
-         dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);  
-   
-         if (runCommandsLockedInterruptible()) {  
-             nextWakeupTime = LONG_LONG_MIN;  
-         }  
-     } 
-   
-     
-     nsecs_t currentTime = now();  
-     int32_t timeoutMillis;  
-     if (nextWakeupTime > currentTime) {  
-         uint64_t timeout = uint64_t(nextWakeupTime - currentTime);  
-         timeout = (timeout + 999999LL) / 1000000LL;  
-         timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);  
-     } else {  
-         timeoutMillis = 0;  
-     }  
-   
-     mLooper->pollOnce(timeoutMillis);  
- }  
 
Java代码 
  
- case EventEntry::TYPE_MOTION: {  
-     MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);  
-     if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {  
-         dropReason = DROP_REASON_APP_SWITCH;  
-     }  
-     done = dispatchMotionLocked(currentTime, typedEntry,  
-             &dropReason, nextWakeupTime);  
-     break;  
 
Java代码 
  
- bool InputDispatcher::dispatchMotionLocked(  
-         nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {  
-     
-     if (! entry->dispatchInProgress) {  
-         entry->dispatchInProgress = true;  
-         resetTargetsLocked();  
-   
-         logOutboundMotionDetailsLocked("dispatchMotion - ", entry);  
-     }  
-   
-     
-     if (*dropReason != DROP_REASON_NOT_DROPPED) {  
-         resetTargetsLocked();  
-         setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY  
-                 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);  
-         return true;  
-     }  
-   
-     bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;  
-   
-     
-     if (! mCurrentInputTargetsValid) {  
-         int32_t injectionResult;  
-         if (isPointerEvent) {  
-             
-             injectionResult = findTouchedWindowTargetsLocked(currentTime,  
-                     entry, nextWakeupTime);  
-         } else {  
-             
-             injectionResult = findFocusedWindowTargetsLocked(currentTime,  
-                     entry, nextWakeupTime);  
-         }  
-         if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {  
-             return false;  
-         }  
-   
-         setInjectionResultLocked(entry, injectionResult);  
-         if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {  
-             return true;  
-         }  
-   
-         addMonitoringTargetsLocked();  
-         commitTargetsLocked();  
-     }  
-   
-     
-     dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);  
-     return true;  
- }  
 
Java代码 
  
- startDispatchCycleLocked 中的方法  
-  status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,  
-                 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,  
-                 xOffset, yOffset,  
-                 motionEntry->xPrecision, motionEntry->yPrecision,  
-                 motionEntry->downTime, firstMotionSample->eventTime,  
-                 motionEntry->pointerCount, motionEntry->pointerIds,  
-                 firstMotionSample->pointerCoords);  
 
Java代码 
  
- ViewRoot有个InputHandler  
 
Java代码 
  
- private final InputHandler mInputHandler = new InputHandler() {  
-     public void handleKey(KeyEvent event, Runnable finishedCallback) {  
-         startInputEvent(finishedCallback);  
-         dispatchKey(event, true);  
-     }  
-   
-     public void handleMotion(MotionEvent event, Runnable finishedCallback) {  
-         startInputEvent(finishedCallback);  
-         dispatchMotion(event, true);  
-     }  
- };  
 InputHandler注册给了系统
 
Java代码 
  
- InputQueue.registerInputChannel(mInputChannel, mInputHandler,  
-                            Looper.myQueue());  
 
Java代码 
  
- dispatchMotion(event, true);方法如下  
- rivate void dispatchMotion(MotionEvent event, boolean sendDone) {  
-        int source = event.getSource();  
-        if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {  
-            dispatchPointer(event, sendDone);  
-        } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {  
-            dispatchTrackball(event, sendDone);  
-        } else {  
-            
-            Log.v(TAG, "Dropping unsupported motion event (unimplemented): " + event);  
-            if (sendDone) {  
-                finishInputEvent();  
-            }  
-        }  
-    }   
 
调用了dispatchPointer
 ViewRoot本身就是Handler直接sendMessageAtTime
然后就进入了View的焦点系统。
 
下面就说一下Activity的焦点是怎么回事。
Java代码 
  
- InputDisapatcher.cpp中调用了如下方法  
-   
-  dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,  
-                             true 
 然后
Java代码 
  
- dispatchEventToCurrentInputTargetsLocked  
调用了如下方法
Java代码 
  
- int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,  
-         const EventEntry* entry, nsecs_t* nextWakeupTime) {  
-     mCurrentInputTargets.clear();  
-   
-     int32_t injectionResult;  
-   
-     
-     
-     if (! mFocusedWindow) {  
-         if (mFocusedApplication) {  
- #if DEBUG_FOCUS  
-             LOGD("Waiting because there is no focused window but there is a "  
-                     "focused application that may eventually add a window: %s.",  
-                     getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());  
- #endif  
-             injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
-                     mFocusedApplication, NULL, nextWakeupTime);  
-             goto Unresponsive;  
-         }  
-   
-         LOGI("Dropping event because there is no focused window or focused application.");  
-         injectionResult = INPUT_EVENT_INJECTION_FAILED;  
-         goto Failed;  
-     }  
-   
-     
-     if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {  
-         injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;  
-         goto Failed;  
-     }  
-   
-     
-     if (mFocusedWindow->paused) {  
- #if DEBUG_FOCUS  
-         LOGD("Waiting because focused window is paused.");  
- #endif  
-         injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
-                 mFocusedApplication, mFocusedWindow, nextWakeupTime);  
-         goto Unresponsive;  
-     }  
-   
-     
-     if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {  
- #if DEBUG_FOCUS  
-         LOGD("Waiting because focused window still processing previous input.");  
- #endif  
-         injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
-                 mFocusedApplication, mFocusedWindow, nextWakeupTime);  
-         goto Unresponsive;  
-     }  
-   
-     
-     injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;  
-     addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));  
-   
-     
- Failed:  
- Unresponsive:  
-     nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);  
-     updateDispatchStatisticsLocked(currentTime, entry,  
-             injectionResult, timeSpentWaitingForApplication);  
- #if DEBUG_FOCUS  
-     LOGD("findFocusedWindow finished: injectionResult=%d, "  
-             "timeSpendWaitingForApplication=%0.1fms",  
-             injectionResult, timeSpentWaitingForApplication / 1000000.0);  
- #endif  
-     return injectionResult;  
- }  
 
move事件的处理和Down事件的处理很不相同。
 
新建立的Window在处理焦点的时候,按下事件没有起来之前,保持了原来的焦点窗口。除非ACTION_UP事件收到以后
 
 
Java代码 
  
-        public void updateInputWindowsLw() {  
-            
-            
-            
-            
-            
-            final ArrayList<WindowState> windows = mWindows;  
-            final int N = windows.size();  
-            for (int i = N - 1; i >= 0; i--) {  
-                final WindowState child = windows.get(i);  
-                if (child.mInputChannel == null || child.mRemoved) {  
-                    
-                    continue;  
-                }  
-                  
-                final int flags = child.mAttrs.flags;  
-                final int type = child.mAttrs.type;  
-                  
-                final boolean hasFocus = (child == mInputFocus);  
-                final boolean isVisible = child.isVisibleLw();  
-                final boolean hasWallpaper = (child == mWallpaperTarget)  
-                        && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);  
-                  
-                
-                final InputWindow inputWindow = mTempInputWindows.add();  
-                inputWindow.inputChannel = child.mInputChannel;  
-                inputWindow.name = child.toString();  
-                inputWindow.layoutParamsFlags = flags;  
-                inputWindow.layoutParamsType = type;  
-                inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();  
-                inputWindow.visible = isVisible;  
-                inputWindow.canReceiveKeys = child.canReceiveKeys();  
-                inputWindow.hasFocus = hasFocus;  
-                inputWindow.hasWallpaper = hasWallpaper;  
-                inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;  
-                inputWindow.layer = child.mLayer;  
-                inputWindow.ownerPid = child.mSession.mPid;  
-                inputWindow.ownerUid = child.mSession.mUid;  
-                  
-                final Rect frame = child.mFrame;  
-                inputWindow.frameLeft = frame.left;  
-                inputWindow.frameTop = frame.top;  
-                inputWindow.frameRight = frame.right;  
-                inputWindow.frameBottom = frame.bottom;  
-                  
-                final Rect visibleFrame = child.mVisibleFrame;  
-                inputWindow.visibleFrameLeft = visibleFrame.left;  
-                inputWindow.visibleFrameTop = visibleFrame.top;  
-                inputWindow.visibleFrameRight = visibleFrame.right;  
-                inputWindow.visibleFrameBottom = visibleFrame.bottom;  
-                  
-                switch (child.mTouchableInsets) {  
-                    default:  
-                    case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:  
-                        inputWindow.touchableAreaLeft = frame.left;  
-                        inputWindow.touchableAreaTop = frame.top;  
-                        inputWindow.touchableAreaRight = frame.right;  
-                        inputWindow.touchableAreaBottom = frame.bottom;  
-                        break;  
-                          
-                    case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {  
-                        Rect inset = child.mGivenContentInsets;  
-                        inputWindow.touchableAreaLeft = frame.left + inset.left;  
-                        inputWindow.touchableAreaTop = frame.top + inset.top;  
-                        inputWindow.touchableAreaRight = frame.right - inset.right;  
-                        inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;  
-                        break;  
-                    }  
-                          
-                    case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {  
-                        Rect inset = child.mGivenVisibleInsets;  
-                        inputWindow.touchableAreaLeft = frame.left + inset.left;  
-                        inputWindow.touchableAreaTop = frame.top + inset.top;  
-                        inputWindow.touchableAreaRight = frame.right - inset.right;  
-                        inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;  
-                        break;  
-                    }  
-                }  
-            }  
-   
-            
-            mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());  
-              
-            
-            
-            mTempInputWindows.clear();  
-        }  
  真正的Input的控制是通过以下方式
      /**
     * Z-ordered (bottom-most first) list of all Window objects.
     */
    final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();
Java代码 
  
- final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();  
 
另外的touch的target并不是通过input focus 获得的。而是通过visible来获得
 
Java代码 
  
- int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,  
-         const MotionEntry* entry, nsecs_t* nextWakeupTime) {  
-     enum InjectionPermission {  
-         INJECTION_PERMISSION_UNKNOWN,  
-         INJECTION_PERMISSION_GRANTED,  
-         INJECTION_PERMISSION_DENIED  
-     };  
-   
-     mCurrentInputTargets.clear();  
-   
-     nsecs_t startTime = now();  
-   
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     
-     bool screenWasOff = false; 
-   
-     int32_t action = entry->action;  
-     int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;  
-   
-     
-     int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;  
-     InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;  
-     if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {  
-         mTempTouchState.reset();  
-         mTempTouchState.down = true;  
-     } else {  
-         mTempTouchState.copyFrom(mTouchState);  
-     }  
-   
-     bool isSplit = mTempTouchState.split && mTempTouchState.down;  
-     if (maskedAction == AMOTION_EVENT_ACTION_DOWN  
-             || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {  
-         
-   
-         int32_t pointerIndex = getMotionEventActionPointerIndex(action);  
-         int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);  
-         int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);  
-         const InputWindow* newTouchedWindow = NULL;  
-         const InputWindow* topErrorWindow = NULL;  
-   
-         
-         size_t numWindows = mWindows.size();  
-         for (size_t i = 0; i < numWindows; i++) {  
-             const InputWindow* window = & mWindows.editItemAt(i);  
-             int32_t flags = window->layoutParamsFlags;  
-   
-             if (flags & InputWindow::FLAG_SYSTEM_ERROR) {  
-                 if (! topErrorWindow) {  
-                     topErrorWindow = window;  
-                 }  
-             }  
-   
-             if (window->visible) {  
-                 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {  
-                     bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE  
-                             | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;  
-                     if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {  
-                         if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {  
-                             newTouchedWindow = window;  
-                         }  
-                         break; 
-                     }  
-                 }  
-   
-                 if (maskedAction == AMOTION_EVENT_ACTION_DOWN  
-                         && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {  
-                     int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;  
-                     if (isWindowObscuredAtPointLocked(window, x, y)) {  
-                         outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;  
-                     }  
-   
-                     mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));  
-                 }  
-             }  
-         }  
-   
-         
-         
-         
-         if (topErrorWindow && newTouchedWindow != topErrorWindow) {  
- #if DEBUG_FOCUS  
-             LOGD("Waiting because system error window is pending.");  
- #endif  
-             injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
-                     NULL, NULL, nextWakeupTime);  
-             injectionPermission = INJECTION_PERMISSION_UNKNOWN;  
-             goto Unresponsive;  
-         }  
-   
-         
-         if (newTouchedWindow  
-                 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {  
-             
-             isSplit = true;  
-         } else if (isSplit) {  
-             
-             
-             
-             newTouchedWindow = mTempTouchState.getFirstForegroundWindow();  
-         }  
-   
-         
-         if (! newTouchedWindow) {  
-             if (mFocusedApplication) {  
- #if DEBUG_FOCUS  
-                 LOGD("Waiting because there is no touched window but there is a "  
-                         "focused application that may eventually add a new window: %s.",  
-                         getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());  
- #endif  
-                 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
-                         mFocusedApplication, NULL, nextWakeupTime);  
-                 goto Unresponsive;  
-             }  
-   
-             LOGI("Dropping event because there is no touched window or focused application.");  
-             injectionResult = INPUT_EVENT_INJECTION_FAILED;  
-             goto Failed;  
-         }  
-   
-         
-         int32_t targetFlags = InputTarget::FLAG_FOREGROUND;  
-         if (isSplit) {  
-             targetFlags |= InputTarget::FLAG_SPLIT;  
-         }  
-         if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {  
-             targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;  
-         }  
-   
-         
-         BitSet32 pointerIds;  
-         if (isSplit) {  
-             uint32_t pointerId = entry->pointerIds[pointerIndex];  
-             pointerIds.markBit(pointerId);  
-         }  
-         mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);  
-     } else {  
-         
-   
-         
-         if (! mTempTouchState.down) {  
-             LOGI("Dropping event because the pointer is not down.");  
-             injectionResult = INPUT_EVENT_INJECTION_FAILED;  
-             goto Failed;  
-         }  
-     }  
-   
-     
-     
-     {  
-         bool haveForegroundWindow = false;  
-         for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {  
-             const TouchedWindow& touchedWindow = mTempTouchState.windows[i];  
-             if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {  
-                 haveForegroundWindow = true;  
-                 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {  
-                     injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;  
-                     injectionPermission = INJECTION_PERMISSION_DENIED;  
-                     goto Failed;  
-                 }  
-             }  
-         }  
-         if (! haveForegroundWindow) {  
- #if DEBUG_INPUT_DISPATCHER_POLICY  
-             LOGD("Dropping event because there is no touched foreground window to receive it.");  
- #endif  
-             injectionResult = INPUT_EVENT_INJECTION_FAILED;  
-             goto Failed;  
-         }  
-   
-         
-         injectionPermission = INJECTION_PERMISSION_GRANTED;  
-     }  
-   
-     
-     for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {  
-         const TouchedWindow& touchedWindow = mTempTouchState.windows[i];  
-         if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {  
-             
-             if (touchedWindow.window->paused) {  
- #if DEBUG_INPUT_DISPATCHER_POLICY  
-                 LOGD("Waiting because touched window is paused.");  
- #endif  
-                 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
-                         NULL, touchedWindow.window, nextWakeupTime);  
-                 goto Unresponsive;  
-             }  
-   
-             
-             if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {  
- #if DEBUG_FOCUS  
-                 LOGD("Waiting because touched window still processing previous input.");  
- #endif  
-                 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
-                         NULL, touchedWindow.window, nextWakeupTime);  
-                 goto Unresponsive;  
-             }  
-         }  
-     }  
-   
-     
-     
-     
-     if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {  
-         const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();  
-         if (foregroundWindow->hasWallpaper) {  
-             for (size_t i = 0; i < mWindows.size(); i++) {  
-                 const InputWindow* window = & mWindows[i];  
-                 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {  
-                     mTempTouchState.addOrUpdateWindow(window,  
-                             InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));  
-                 }  
-             }  
-         }  
-     }  
-   
-     
-     injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;  
-   
-     for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {  
-         const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);  
-         addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,  
-                 touchedWindow.pointerIds);  
-     }  
-   
-     
-     mTempTouchState.removeOutsideTouchWindows();  
-   
- Failed:  
-     
-     if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {  
-         if (checkInjectionPermission(NULL, entry->injectionState)) {  
-             injectionPermission = INJECTION_PERMISSION_GRANTED;  
-         } else {  
-             injectionPermission = INJECTION_PERMISSION_DENIED;  
-         }  
-     }  
-   
-     
-     if (injectionPermission == INJECTION_PERMISSION_GRANTED) {  
-         if (maskedAction == AMOTION_EVENT_ACTION_UP  
-                 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {  
-             
-             mTempTouchState.reset();  
-         } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {  
-             
-             if (mTouchState.down) {  
- #if DEBUG_FOCUS  
-                 LOGD("Pointer down received while already down.");  
- #endif  
-             }  
-         } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {  
-             
-             if (isSplit) {  
-                 int32_t pointerIndex = getMotionEventActionPointerIndex(action);  
-                 uint32_t pointerId = entry->pointerIds[pointerIndex];  
-   
-                 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {  
-                     TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);  
-                     if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {  
-                         touchedWindow.pointerIds.clearBit(pointerId);  
-                         if (touchedWindow.pointerIds.isEmpty()) {  
-                             mTempTouchState.windows.removeAt(i);  
-                             continue;  
-                         }  
-                     }  
-                     i += 1;  
-                 }  
-             }  
-         }  
-   
-         
-         mTouchState.copyFrom(mTempTouchState);  
-     } else {  
- #if DEBUG_FOCUS  
-         LOGD("Not updating touch focus because injection was denied.");  
- #endif  
-     }  
-   
- Unresponsive:  
-     
-     mTempTouchState.reset();  
-   
-     nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);  
-     updateDispatchStatisticsLocked(currentTime, entry,  
-             injectionResult, timeSpentWaitingForApplication);  
- #if DEBUG_FOCUS  
-     LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "  
-             "timeSpentWaitingForApplication=%0.1fms",  
-             injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);  
- #endif  
-     return injectionResult;  
- }  
  最关键的几行代码,说明了Windows是如何找到触屏的输入焦点的:
 
Cpp代码 
  
- if (window->visible) {    
-               if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {    
-                   bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE    
-                           | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;    
-                   if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {    
-                       if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {    
-                           newTouchedWindow = window;    
-                       }    
-                       break; 
-                   }    
-               }    
-   
-               if (maskedAction == AMOTION_EVENT_ACTION_DOWN    
-                       && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {    
-                   int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;    
-                   if (isWindowObscuredAtPointLocked(window, x, y)) {    
-                       outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;    
-                   }    
-   
-                   mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));    
-               }    
-           }    
 
 
Java代码 
  
-  
-     struct TouchedWindow {  
-         const InputWindow* window;  
-         int32_t targetFlags;  
-         BitSet32 pointerIds;  
-         sp<InputChannel> channel;  
-     };  
-     struct TouchState {  
-         bool down;  
-         bool split;  
-         Vector<TouchedWindow> windows;  
-   
-         TouchState();  
-         ~TouchState();  
-         void reset();  
-         void copyFrom(const TouchState& other);  
-         void addOrUpdateWindow(const InputWindow* window, int32_t targetFlags, BitSet32 pointerIds);  
-         void removeOutsideTouchWindows();  
-         const InputWindow* getFirstForegroundWindow();  
-     };  
-   
-   
-   
- 另外如何定义按键和其他触屏焦点的:  
-   
-   
-         
-         public void updateInputWindowsLw() {  
-             
-             
-             
-             
-             
-             final ArrayList<WindowState> windows = mWindows;  
-             final int N = windows.size();  
-             for (int i = N - 1; i >= 0; i--) {  
-                 final WindowState child = windows.get(i);  
-                 if (child.mInputChannel == null || child.mRemoved) {  
-                     
-                     continue;  
-                 }  
-                   
-                 final int flags = child.mAttrs.flags;  
-                 final int type = child.mAttrs.type;  
-                   
-                <span style="color: #ff6600;"> final boolean hasFocus = (child == mInputFocus);</span>  
-                 final boolean isVisible = child.isVisibleLw();  
-                 final boolean hasWallpaper = (child == mWallpaperTarget)  
-                         && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);