Android输入输出系统之TouchEvent流程_移动开发_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > 移动开发 > Android输入输出系统之TouchEvent流程

Android输入输出系统之TouchEvent流程

 2014/10/14 10:44:18  xiaochao1234  程序员俱乐部  我要评论(0)
  • 摘要:一个是InputReader,一个是InputDispatcher。方法是dispatchTouch。入口点是InputReader的loopOnce方法.InputReader里面有个线程叫做InputReaderThread,threadLoop[code="java"]InputReaderThread::InputReaderThread(constsp&reader):Thread(/*canCallJava*/true)
  • 标签:android 输出 touch 流程

一个是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代码 javascripts/syntaxhighlighter/clipboard_new.swf" type="application/x-shockwave-flash">ways" /> class="star" src="/Upload/Images/2014101410/40B102E0EF997EA6.png" alt="收藏代码" />
  1. void InputDispatcher::dispatchOnce() {  
  2.     nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();  
  3.     nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();  
  4.   
  5.     nsecs_t nextWakeupTime = LONG_LONG_MAX;  
  6.     { // acquire lock  
  7.         AutoMutex _l(mLock);  
  8.         dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);  
  9.   
  10.         if (runCommandsLockedInterruptible()) {  
  11.             nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately  
  12.         }  
  13.     } // release lock  
  14.   
  15.     // Wait for callback or timeout or wake.  (make sure we round up, not down)  
  16.     nsecs_t currentTime = now();  
  17.     int32_t timeoutMillis;  
  18.     if (nextWakeupTime > currentTime) {  
  19.         uint64_t timeout = uint64_t(nextWakeupTime - currentTime);  
  20.         timeout = (timeout + 999999LL) / 1000000LL;  
  21.         timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);  
  22.     } else {  
  23.         timeoutMillis = 0;  
  24.     }  
  25.   
  26.     mLooper->pollOnce(timeoutMillis);  
  27. }  

 

Java代码 APP_SWITCH%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20done%20%3D%20dispatchMotionLocked(currentTime%2C%20typedEntry%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%26dropReason%2C%20nextWakeupTime)%3B%0A%20%20%20%20%20%20%20%20break%3B" /> 收藏代码
  1. case EventEntry::TYPE_MOTION: {  
  2.     MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);  
  3.     if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {  
  4.         dropReason = DROP_REASON_APP_SWITCH;  
  5.     }  
  6.     done = dispatchMotionLocked(currentTime, typedEntry,  
  7.             &dropReason, nextWakeupTime);  
  8.     break;  

 

Java代码 touchscreen)%0A%20%20%20%20%20%20%20%20%20%20%20%20injectionResult%20%3D%20findTouchedWindowTargetsLocked(currentTime%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entry%2C%20nextWakeupTime)%3B%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Non%20touch%20event.%20%20(eg.%20trackball)%0A%20%20%20%20%20%20%20%20%20%20%20%20injectionResult%20%3D%20findFocusedWindowTargetsLocked(currentTime%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entry%2C%20nextWakeupTime)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(injectionResult%20%3D%3D%20INPUT_EVENT_INJECTION_PENDING)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20setInjectionResultLocked(entry%2C%20injectionResult)%3B%0A%20%20%20%20%20%20%20%20if%20(injectionResult%20!%3D%20INPUT_EVENT_INJECTION_SUCCEEDED)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20true%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20addMonitoringTargetsLocked()%3B%0A%20%20%20%20%20%20%20%20commitTargetsLocked()%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Dispatch%20the%20motion.%0A%20%20%20%20dispatchEventToCurrentInputTargetsLocked(currentTime%2C%20entry%2C%20false)%3B%0A%20%20%20%20return%20true%3B%0A%7D%0A" /> 收藏代码
  1. bool InputDispatcher::dispatchMotionLocked(  
  2.         nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {  
  3.     // Preprocessing.  
  4.     if (! entry->dispatchInProgress) {  
  5.         entry->dispatchInProgress = true;  
  6.         resetTargetsLocked();  
  7.   
  8.         logOutboundMotionDetailsLocked("dispatchMotion - ", entry);  
  9.     }  
  10.   
  11.     // Clean up if dropping the event.  
  12.     if (*dropReason != DROP_REASON_NOT_DROPPED) {  
  13.         resetTargetsLocked();  
  14.         setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY  
  15.                 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);  
  16.         return true;  
  17.     }  
  18.   
  19.     bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;  
  20.   
  21.     // Identify targets.  
  22.     if (! mCurrentInputTargetsValid) {  
  23.         int32_t injectionResult;  
  24.         if (isPointerEvent) {  
  25.             // Pointer event.  (eg. touchscreen)  
  26.             injectionResult = findTouchedWindowTargetsLocked(currentTime,  
  27.                     entry, nextWakeupTime);  
  28.         } else {  
  29.             // Non touch event.  (eg. trackball)  
  30.             injectionResult = findFocusedWindowTargetsLocked(currentTime,  
  31.                     entry, nextWakeupTime);  
  32.         }  
  33.         if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {  
  34.             return false;  
  35.         }  
  36.   
  37.         setInjectionResultLocked(entry, injectionResult);  
  38.         if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {  
  39.             return true;  
  40.         }  
  41.   
  42.         addMonitoringTargetsLocked();  
  43.         commitTargetsLocked();  
  44.     }  
  45.   
  46.     // Dispatch the motion.  
  47.     dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);  
  48.     return true;  
  49. }  

 

Java代码  收藏代码
  1. startDispatchCycleLocked 中的方法  
  2.  status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,  
  3.                 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,  
  4.                 xOffset, yOffset,  
  5.                 motionEntry->xPrecision, motionEntry->yPrecision,  
  6.                 motionEntry->downTime, firstMotionSample->eventTime,  
  7.                 motionEntry->pointerCount, motionEntry->pointerIds,  
  8.                 firstMotionSample->pointerCoords);  

 

Java代码  收藏代码
  1. ViewRoot有个InputHandler  

 

Java代码 Runnable%20finishedCallback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20startInputEvent(finishedCallback)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20dispatchKey(event%2C%20true)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20public%20void%20handleMotion(MotionEvent%20event%2C%20Runnable%20finishedCallback)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20startInputEvent(finishedCallback)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20dispatchMotion(event%2C%20true)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%3B" /> 收藏代码
  1. private final InputHandler mInputHandler = new InputHandler() {  
  2.     public void handleKey(KeyEvent event, Runnable finishedCallback) {  
  3.         startInputEvent(finishedCallback);  
  4.         dispatchKey(event, true);  
  5.     }  
  6.   
  7.     public void handleMotion(MotionEvent event, Runnable finishedCallback) {  
  8.         startInputEvent(finishedCallback);  
  9.         dispatchMotion(event, true);  
  10.     }  
  11. };  

 InputHandler注册给了系统

 

Java代码  收藏代码
  1. InputQueue.registerInputChannel(mInputChannel, mInputHandler,  
  2.                            Looper.myQueue());  

 

Java代码 unimplemented)%3A%20%22%20%2B%20event)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(sendDone)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20finishInputEvent()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%20" /> 收藏代码
  1. dispatchMotion(event, true);方法如下  
  2. rivate void dispatchMotion(MotionEvent event, boolean sendDone) {  
  3.        int source = event.getSource();  
  4.        if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {  
  5.            dispatchPointer(event, sendDone);  
  6.        } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {  
  7.            dispatchTrackball(event, sendDone);  
  8.        } else {  
  9.            // TODO  
  10.            Log.v(TAG, "Dropping unsupported motion event (unimplemented): " + event);  
  11.            if (sendDone) {  
  12.                finishInputEvent();  
  13.            }  
  14.        }  
  15.    }   

 

调用了dispatchPointer

 ViewRoot本身就是Handler直接sendMessageAtTime

然后就进入了View的焦点系统。

 

下面就说一下Activity的焦点是怎么回事。

Java代码  收藏代码
  1. InputDisapatcher.cpp中调用了如下方法  
  2.   
  3.  dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,  
  4.                             true /*resumeWithAppendedMotionSample*/);  

 然后

Java代码  收藏代码
  1. dispatchEventToCurrentInputTargetsLocked  

调用了如下方法

Java代码  收藏代码
  1. int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,  
  2.         const EventEntry* entry, nsecs_t* nextWakeupTime) {  
  3.     mCurrentInputTargets.clear();  
  4.   
  5.     int32_t injectionResult;  
  6.   
  7.     // If there is no currently focused window and no focused application  
  8.     // then drop the event.  
  9.     if (! mFocusedWindow) {  
  10.         if (mFocusedApplication) {  
  11. #if DEBUG_FOCUS  
  12.             LOGD("Waiting because there is no focused window but there is a "  
  13.                     "focused application that may eventually add a window: %s.",  
  14.                     getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());  
  15. #endif  
  16.             injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
  17.                     mFocusedApplication, NULL, nextWakeupTime);  
  18.             goto Unresponsive;  
  19.         }  
  20.   
  21.         LOGI("Dropping event because there is no focused window or focused application.");  
  22.         injectionResult = INPUT_EVENT_INJECTION_FAILED;  
  23.         goto Failed;  
  24.     }  
  25.   
  26.     // Check permissions.  
  27.     if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {  
  28.         injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;  
  29.         goto Failed;  
  30.     }  
  31.   
  32.     // If the currently focused window is paused then keep waiting.  
  33.     if (mFocusedWindow->paused) {  
  34. #if DEBUG_FOCUS  
  35.         LOGD("Waiting because focused window is paused.");  
  36. #endif  
  37.         injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
  38.                 mFocusedApplication, mFocusedWindow, nextWakeupTime);  
  39.         goto Unresponsive;  
  40.     }  
  41.   
  42.     // If the currently focused window is still working on previous events then keep waiting.  
  43.     if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {  
  44. #if DEBUG_FOCUS  
  45.         LOGD("Waiting because focused window still processing previous input.");  
  46. #endif  
  47.         injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
  48.                 mFocusedApplication, mFocusedWindow, nextWakeupTime);  
  49.         goto Unresponsive;  
  50.     }  
  51.   
  52.     // Success!  Output targets.  
  53.     injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;  
  54.     addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));  
  55.   
  56.     // Done.  
  57. Failed:  
  58. Unresponsive:  
  59.     nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);  
  60.     updateDispatchStatisticsLocked(currentTime, entry,  
  61.             injectionResult, timeSpentWaitingForApplication);  
  62. #if DEBUG_FOCUS  
  63.     LOGD("findFocusedWindow finished: injectionResult=%d, "  
  64.             "timeSpendWaitingForApplication=%0.1fms",  
  65.             injectionResult, timeSpentWaitingForApplication / 1000000.0);  
  66. #endif  
  67.     return injectionResult;  
  68. }  

 

move事件的处理和Down事件的处理很不相同。

 

新建立的Window在处理焦点的时候,按下事件没有起来之前,保持了原来的焦点窗口。除非ACTION_UP事件收到以后

 

 

Java代码 has%20touch%20focus.%0A%20%20%20%20%20%20%20%20%20%20%20%20final%20ArrayList%3CWindowState%3E%20windows%20%3D%20mWindows%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20N%20%3D%20windows.size()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(int%20i%20%3D%20N%20-%201%3B%20i%20%3E%3D%200%3B%20i--)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20WindowState%20child%20%3D%20windows.get(i)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(child.mInputChannel%20%3D%3D%20null%20%7C%7C%20child.mRemoved)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Skip%20this%20window%20because%20it%20cannot%20possibly%20receive%20input.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20flags%20%3D%20child.mAttrs.flags%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20type%20%3D%20child.mAttrs.type%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20boolean%20hasFocus%20%3D%20(child%20%3D%3D%20mInputFocus)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20boolean%20isVisible%20%3D%20child.isVisibleLw()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20boolean%20hasWallpaper%20%3D%20(child%20%3D%3D%20mWallpaperTarget)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%26%26%20(type%20!%3D%20WindowManager.LayoutParams.TYPE_KEYGUARD)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Add%20a%20window%20to%20our%20list%20of%20input%20windows.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20InputWindow%20inputWindow%20%3D%20mTempInputWindows.add()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.inputChannel%20%3D%20child.mInputChannel%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.name%20%3D%20child.toString()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.layoutParamsFlags%20%3D%20flags%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.layoutParamsType%20%3D%20type%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.dispatchingTimeoutNanos%20%3D%20child.getInputDispatchingTimeoutNanos()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.visible%20%3D%20isVisible%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.canReceiveKeys%20%3D%20child.canReceiveKeys()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.hasFocus%20%3D%20hasFocus%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.hasWallpaper%20%3D%20hasWallpaper%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.paused%20%3D%20child.mAppToken%20!%3D%20null%20%3F%20child.mAppToken.paused%20%3A%20false%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.layer%20%3D%20child.mLayer%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.ownerPid%20%3D%20child.mSession.mPid%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.ownerUid%20%3D%20child.mSession.mUid%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20Rect%20frame%20%3D%20child.mFrame%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.frameLeft%20%3D%20frame.left%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.frameTop%20%3D%20frame.top%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.frameRight%20%3D%20frame.right%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.frameBottom%20%3D%20frame.bottom%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20Rect%20visibleFrame%20%3D%20child.mVisibleFrame%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.visibleFrameLeft%20%3D%20visibleFrame.left%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.visibleFrameTop%20%3D%20visibleFrame.top%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.visibleFrameRight%20%3D%20visibleFrame.right%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.visibleFrameBottom%20%3D%20visibleFrame.bottom%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20switch%20(child.mTouchableInsets)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20default%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.touchableAreaLeft%20%3D%20frame.left%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.touchableAreaTop%20%3D%20frame.top%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.touchableAreaRight%20%3D%20frame.right%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.touchableAreaBottom%20%3D%20frame.bottom%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Rect%20inset%20%3D%20child.mGivenContentInsets%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.touchableAreaLeft%20%3D%20frame.left%20%2B%20inset.left%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.touchableAreaTop%20%3D%20frame.top%20%2B%20inset.top%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.touchableAreaRight%20%3D%20frame.right%20-%20inset.right%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.touchableAreaBottom%20%3D%20frame.bottom%20-%20inset.bottom%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20case%20ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Rect%20inset%20%3D%20child.mGivenVisibleInsets%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.touchableAreaLeft%20%3D%20frame.left%20%2B%20inset.left%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.touchableAreaTop%20%3D%20frame.top%20%2B%20inset.top%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.touchableAreaRight%20%3D%20frame.right%20-%20inset.right%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputWindow.touchableAreaBottom%20%3D%20frame.bottom%20-%20inset.bottom%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Send%20windows%20to%20native%20code.%0A%20%20%20%20%20%20%20%20%20%20%20%20mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray())%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Clear%20the%20list%20in%20preparation%20for%20the%20next%20round.%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Also%20avoids%20keeping%20InputChannel%20objects%20referenced%20unnecessarily.%0A%20%20%20%20%20%20%20%20%20%20%20%20mTempInputWindows.clear()%3B%0A%20%20%20%20%20%20%20%20%7D" /> 收藏代码
  1. /* Updates the cached window information provided to the input dispatcher. */  
  2.        public void updateInputWindowsLw() {  
  3.            // Populate the input window list with information about all of the windows that  
  4.            // could potentially receive input.  
  5.            // As an optimization, we could try to prune the list of windows but this turns  
  6.            // out to be difficult because only the native code knows for sure which window  
  7.            // currently has touch focus.  
  8.            final ArrayList<WindowState> windows = mWindows;  
  9.            final int N = windows.size();  
  10.            for (int i = N - 1; i >= 0; i--) {  
  11.                final WindowState child = windows.get(i);  
  12.                if (child.mInputChannel == null || child.mRemoved) {  
  13.                    // Skip this window because it cannot possibly receive input.  
  14.                    continue;  
  15.                }  
  16.                  
  17.                final int flags = child.mAttrs.flags;  
  18.                final int type = child.mAttrs.type;  
  19.                  
  20.                final boolean hasFocus = (child == mInputFocus);  
  21.                final boolean isVisible = child.isVisibleLw();  
  22.                final boolean hasWallpaper = (child == mWallpaperTarget)  
  23.                        && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);  
  24.                  
  25.                // Add a window to our list of input windows.  
  26.                final InputWindow inputWindow = mTempInputWindows.add();  
  27.                inputWindow.inputChannel = child.mInputChannel;  
  28.                inputWindow.name = child.toString();  
  29.                inputWindow.layoutParamsFlags = flags;  
  30.                inputWindow.layoutParamsType = type;  
  31.                inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();  
  32.                inputWindow.visible = isVisible;  
  33.                inputWindow.canReceiveKeys = child.canReceiveKeys();  
  34.                inputWindow.hasFocus = hasFocus;  
  35.                inputWindow.hasWallpaper = hasWallpaper;  
  36.                inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;  
  37.                inputWindow.layer = child.mLayer;  
  38.                inputWindow.ownerPid = child.mSession.mPid;  
  39.                inputWindow.ownerUid = child.mSession.mUid;  
  40.                  
  41.                final Rect frame = child.mFrame;  
  42.                inputWindow.frameLeft = frame.left;  
  43.                inputWindow.frameTop = frame.top;  
  44.                inputWindow.frameRight = frame.right;  
  45.                inputWindow.frameBottom = frame.bottom;  
  46.                  
  47.                final Rect visibleFrame = child.mVisibleFrame;  
  48.                inputWindow.visibleFrameLeft = visibleFrame.left;  
  49.                inputWindow.visibleFrameTop = visibleFrame.top;  
  50.                inputWindow.visibleFrameRight = visibleFrame.right;  
  51.                inputWindow.visibleFrameBottom = visibleFrame.bottom;  
  52.                  
  53.                switch (child.mTouchableInsets) {  
  54.                    default:  
  55.                    case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:  
  56.                        inputWindow.touchableAreaLeft = frame.left;  
  57.                        inputWindow.touchableAreaTop = frame.top;  
  58.                        inputWindow.touchableAreaRight = frame.right;  
  59.                        inputWindow.touchableAreaBottom = frame.bottom;  
  60.                        break;  
  61.                          
  62.                    case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {  
  63.                        Rect inset = child.mGivenContentInsets;  
  64.                        inputWindow.touchableAreaLeft = frame.left + inset.left;  
  65.                        inputWindow.touchableAreaTop = frame.top + inset.top;  
  66.                        inputWindow.touchableAreaRight = frame.right - inset.right;  
  67.                        inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;  
  68.                        break;  
  69.                    }  
  70.                          
  71.                    case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {  
  72.                        Rect inset = child.mGivenVisibleInsets;  
  73.                        inputWindow.touchableAreaLeft = frame.left + inset.left;  
  74.                        inputWindow.touchableAreaTop = frame.top + inset.top;  
  75.                        inputWindow.touchableAreaRight = frame.right - inset.right;  
  76.                        inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;  
  77.                        break;  
  78.                    }  
  79.                }  
  80.            }  
  81.   
  82.            // Send windows to native code.  
  83.            mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());  
  84.              
  85.            // Clear the list in preparation for the next round.  
  86.            // Also avoids keeping InputChannel objects referenced unnecessarily.  
  87.            mTempInputWindows.clear();  
  88.        }  

  真正的Input的控制是通过以下方式

      /**
     * Z-ordered (bottom-most first) list of all Window objects.
     */
    final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();

Java代码  收藏代码
  1. /** 
  2.  * Z-ordered (bottom-most first) list of all Window objects. 
  3.  */  
  4. final ArrayList<WindowState> mWindows = new ArrayList<WindowState>();  

 

另外的touch的target并不是通过input focus 获得的。而是通过visible来获得

 

Java代码 original%20code%2C%20screenWasOff%20could%20never%20be%20set%20to%20true.%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20The%20reason%20is%20that%20the%20POLICY_FLAG_WOKE_HERE%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20and%20POLICY_FLAG_BRIGHT_HERE%20flags%20were%20set%20only%20when%20preprocessing%20raw%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20EV_KEY%2C%20EV_REL%20and%20EV_ABS%20events.%20%20As%20it%20happens%2C%20the%20touch%20event%20was%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20actually%20enqueued%20using%20the%20policyFlags%20that%20appeared%20in%20the%20final%20EV_SYN%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20events%20upon%20which%20no%20preprocessing%20took%20place.%20%20So%20policyFlags%20was%20always%200.%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20In%20the%20new%20native%20input%20dispatcher%20we're%20a%20bit%20more%20careful%20about%20event%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20preprocessing%20so%20the%20touches%20we%20receive%20can%20actually%20have%20non-zero%20policyFlags.%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20Unfortunately%20we%20obtain%20undesirable%20behavior.%0A%20%20%20%20%2F%2F%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20Here's%20what%20happens%3A%0A%20%20%20%20%2F%2F%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20When%20the%20device%20dims%20in%20anticipation%20of%20going%20to%20sleep%2C%20touches%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20in%20windows%20which%20have%20FLAG_TOUCHABLE_WHEN_WAKING%20cause%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20the%20device%20to%20brighten%20and%20reset%20the%20user%20activity%20timer.%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20Touches%20on%20other%20windows%20(such%20as%20the%20launcher%20window)%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20are%20dropped.%20%20Then%20after%20a%20moment%2C%20the%20device%20goes%20to%20sleep.%20%20Oops.%0A%20%20%20%20%2F%2F%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20Also%20notice%20how%20screenWasOff%20was%20being%20initialized%20using%20POLICY_FLAG_BRIGHT_HERE%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20instead%20of%20POLICY_FLAG_WOKE_HERE...%0A%20%20%20%20%2F%2F%0A%20%20%20%20bool%20screenWasOff%20%3D%20false%3B%20%2F%2F%20original%20policy%3A%20policyFlags%20%26%20POLICY_FLAG_BRIGHT_HERE%3B%0A%0A%20%20%20%20int32_t%20action%20%3D%20entry-%3Eaction%3B%0A%20%20%20%20int32_t%20maskedAction%20%3D%20action%20%26%20AMOTION_EVENT_ACTION_MASK%3B%0A%0A%20%20%20%20%2F%2F%20Update%20the%20touch%20state%20as%20needed%20based%20on%20the%20properties%20of%20the%20touch%20event.%0A%20%20%20%20int32_t%20injectionResult%20%3D%20INPUT_EVENT_INJECTION_PENDING%3B%0A%20%20%20%20InjectionPermission%20injectionPermission%20%3D%20INJECTION_PERMISSION_UNKNOWN%3B%0A%20%20%20%20if%20(maskedAction%20%3D%3D%20AMOTION_EVENT_ACTION_DOWN)%20%7B%0A%20%20%20%20%20%20%20%20mTempTouchState.reset()%3B%0A%20%20%20%20%20%20%20%20mTempTouchState.down%20%3D%20true%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20mTempTouchState.copyFrom(mTouchState)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20bool%20isSplit%20%3D%20mTempTouchState.split%20%26%26%20mTempTouchState.down%3B%0A%20%20%20%20if%20(maskedAction%20%3D%3D%20AMOTION_EVENT_ACTION_DOWN%0A%20%20%20%20%20%20%20%20%20%20%20%20%7C%7C%20(isSplit%20%26%26%20maskedAction%20%3D%3D%20AMOTION_EVENT_ACTION_POINTER_DOWN))%20%7B%0A%20%20%20%20%20%20%20%20%2F*%20Case%201%3A%20New%20splittable%20pointer%20going%20down.%20*%2F%0A%0A%20%20%20%20%20%20%20%20int32_t%20pointerIndex%20%3D%20getMotionEventActionPointerIndex(action)%3B%0A%20%20%20%20%20%20%20%20int32_t%20x%20%3D%20int32_t(entry-%3EfirstSample.pointerCoords%5BpointerIndex%5D.x)%3B%0A%20%20%20%20%20%20%20%20int32_t%20y%20%3D%20int32_t(entry-%3EfirstSample.pointerCoords%5BpointerIndex%5D.y)%3B%0A%20%20%20%20%20%20%20%20const%20InputWindow*%20newTouchedWindow%20%3D%20NULL%3B%0A%20%20%20%20%20%20%20%20const%20InputWindow*%20topErrorWindow%20%3D%20NULL%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Traverse%20windows%20from%20front%20to%20back%20to%20find%20touched%20window%20and%20outside%20targets.%0A%20%20%20%20%20%20%20%20size_t%20numWindows%20%3D%20mWindows.size()%3B%0A%20%20%20%20%20%20%20%20for%20(size_t%20i%20%3D%200%3B%20i%20%3C%20numWindows%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20InputWindow*%20window%20%3D%20%26%20mWindows.editItemAt(i)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20int32_t%20flags%20%3D%20window-%3ElayoutParamsFlags%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(flags%20%26%20InputWindow%3A%3AFLAG_SYSTEM_ERROR)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!%20topErrorWindow)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20topErrorWindow%20%3D%20window%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(window-%3Evisible)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!%20(flags%20%26%20InputWindow%3A%3AFLAG_NOT_TOUCHABLE))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bool%20isTouchModal%20%3D%20(flags%20%26%20(InputWindow%3A%3AFLAG_NOT_FOCUSABLE%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20InputWindow%3A%3AFLAG_NOT_TOUCH_MODAL))%20%3D%3D%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isTouchModal%20%7C%7C%20window-%3EtouchableAreaContainsPoint(x%2C%20y))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!%20screenWasOff%20%7C%7C%20flags%20%26%20InputWindow%3A%3AFLAG_TOUCHABLE_WHEN_WAKING)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newTouchedWindow%20%3D%20window%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%3B%20%2F%2F%20found%20touched%20window%2C%20exit%20window%20loop%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(maskedAction%20%3D%3D%20AMOTION_EVENT_ACTION_DOWN%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%26%26%20(flags%20%26%20InputWindow%3A%3AFLAG_WATCH_OUTSIDE_TOUCH))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20int32_t%20outsideTargetFlags%20%3D%20InputTarget%3A%3AFLAG_OUTSIDE%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(isWindowObscuredAtPointLocked(window%2C%20x%2C%20y))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20outsideTargetFlags%20%7C%3D%20InputTarget%3A%3AFLAG_WINDOW_IS_OBSCURED%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mTempTouchState.addOrUpdateWindow(window%2C%20outsideTargetFlags%2C%20BitSet32(0))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20If%20there%20is%20an%20error%20window%20but%20it%20is%20not%20taking%20focus%20(typically%20because%0A%20%20%20%20%20%20%20%20%2F%2F%20it%20is%20invisible)%20then%20wait%20for%20it.%20%20Any%20other%20focused%20window%20may%20in%0A%20%20%20%20%20%20%20%20%2F%2F%20fact%20be%20in%20ANR%20state.%0A%20%20%20%20%20%20%20%20if%20(topErrorWindow%20%26%26%20newTouchedWindow%20!%3D%20topErrorWindow)%20%7B%0A%23if%20DEBUG_FOCUS%0A%20%20%20%20%20%20%20%20%20%20%20%20LOGD(%22Waiting%20because%20system%20error%20window%20is%20pending.%22)%3B%0A%23endif%0A%20%20%20%20%20%20%20%20%20%20%20%20injectionResult%20%3D%20handleTargetsNotReadyLocked(currentTime%2C%20entry%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20NULL%2C%20NULL%2C%20nextWakeupTime)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20injectionPermission%20%3D%20INJECTION_PERMISSION_UNKNOWN%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20goto%20Unresponsive%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Figure%20out%20whether%20splitting%20will%20be%20allowed%20for%20this%20window.%0A%20%20%20%20%20%20%20%20if%20(newTouchedWindow%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%26%26%20(newTouchedWindow-%3ElayoutParamsFlags%20%26%20InputWindow%3A%3AFLAG_SPLIT_TOUCH))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20New%20window%20supports%20splitting.%0A%20%20%20%20%20%20%20%20%20%20%20%20isSplit%20%3D%20true%3B%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(isSplit)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20New%20window%20does%20not%20support%20splitting%20but%20we%20have%20already%20split%20events.%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Assign%20the%20pointer%20to%20the%20first%20foreground%20window%20we%20find.%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20(May%20be%20NULL%20which%20is%20why%20we%20put%20this%20code%20block%20before%20the%20next%20check.)%0A%20%20%20%20%20%20%20%20%20%20%20%20newTouchedWindow%20%3D%20mTempTouchState.getFirstForegroundWindow()%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20If%20we%20did%20not%20find%20a%20touched%20window%20then%20fail.%0A%20%20%20%20%20%20%20%20if%20(!%20newTouchedWindow)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(mFocusedApplication)%20%7B%0A%23if%20DEBUG_FOCUS%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20LOGD(%22Waiting%20because%20there%20is%20no%20touched%20window%20but%20there%20is%20a%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22focused%20application%20that%20may%20eventually%20add%20a%20new%20window%3A%20%25s.%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20getApplicationWindowLabelLocked(mFocusedApplication%2C%20NULL).string())%3B%0A%23endif%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20injectionResult%20%3D%20handleTargetsNotReadyLocked(currentTime%2C%20entry%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mFocusedApplication%2C%20NULL%2C%20nextWakeupTime)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20goto%20Unresponsive%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20LOGI(%22Dropping%20event%20because%20there%20is%20no%20touched%20window%20or%20focused%20application.%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20injectionResult%20%3D%20INPUT_EVENT_INJECTION_FAILED%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20goto%20Failed%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Set%20target%20flags.%0A%20%20%20%20%20%20%20%20int32_t%20targetFlags%20%3D%20InputTarget%3A%3AFLAG_FOREGROUND%3B%0A%20%20%20%20%20%20%20%20if%20(isSplit)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20targetFlags%20%7C%3D%20InputTarget%3A%3AFLAG_SPLIT%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(isWindowObscuredAtPointLocked(newTouchedWindow%2C%20x%2C%20y))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20targetFlags%20%7C%3D%20InputTarget%3A%3AFLAG_WINDOW_IS_OBSCURED%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Update%20the%20temporary%20touch%20state.%0A%20%20%20%20%20%20%20%20BitSet32%20pointerIds%3B%0A%20%20%20%20%20%20%20%20if%20(isSplit)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20uint32_t%20pointerId%20%3D%20entry-%3EpointerIds%5BpointerIndex%5D%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20pointerIds.markBit(pointerId)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20mTempTouchState.addOrUpdateWindow(newTouchedWindow%2C%20targetFlags%2C%20pointerIds)%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%2F*%20Case%202%3A%20Pointer%20move%2C%20up%2C%20cancel%20or%20non-splittable%20pointer%20down.%20*%2F%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20If%20the%20pointer%20is%20not%20currently%20down%2C%20then%20ignore%20the%20event.%0A%20%20%20%20%20%20%20%20if%20(!%20mTempTouchState.down)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20LOGI(%22Dropping%20event%20because%20the%20pointer%20is%20not%20down.%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20injectionResult%20%3D%20INPUT_EVENT_INJECTION_FAILED%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20goto%20Failed%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Check%20permission%20to%20inject%20into%20all%20touched%20foreground%20windows%20and%20ensure%20there%0A%20%20%20%20%2F%2F%20is%20at%20least%20one%20touched%20foreground%20window.%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20bool%20haveForegroundWindow%20%3D%20false%3B%0A%20%20%20%20%20%20%20%20for%20(size_t%20i%20%3D%200%3B%20i%20%3C%20mTempTouchState.windows.size()%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20TouchedWindow%26%20touchedWindow%20%3D%20mTempTouchState.windows%5Bi%5D%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(touchedWindow.targetFlags%20%26%20InputTarget%3A%3AFLAG_FOREGROUND)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20haveForegroundWindow%20%3D%20true%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!%20checkInjectionPermission(touchedWindow.window%2C%20entry-%3EinjectionState))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20injectionResult%20%3D%20INPUT_EVENT_INJECTION_PERMISSION_DENIED%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20injectionPermission%20%3D%20INJECTION_PERMISSION_DENIED%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20goto%20Failed%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20if%20(!%20haveForegroundWindow)%20%7B%0A%23if%20DEBUG_INPUT_DISPATCHER_POLICY%0A%20%20%20%20%20%20%20%20%20%20%20%20LOGD(%22Dropping%20event%20because%20there%20is%20no%20touched%20foreground%20window%20to%20receive%20it.%22)%3B%0A%23endif%0A%20%20%20%20%20%20%20%20%20%20%20%20injectionResult%20%3D%20INPUT_EVENT_INJECTION_FAILED%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20goto%20Failed%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Permission%20granted%20to%20injection%20into%20all%20touched%20foreground%20windows.%0A%20%20%20%20%20%20%20%20injectionPermission%20%3D%20INJECTION_PERMISSION_GRANTED%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Ensure%20all%20touched%20foreground%20windows%20are%20ready%20for%20new%20input.%0A%20%20%20%20for%20(size_t%20i%20%3D%200%3B%20i%20%3C%20mTempTouchState.windows.size()%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20const%20TouchedWindow%26%20touchedWindow%20%3D%20mTempTouchState.windows%5Bi%5D%3B%0A%20%20%20%20%20%20%20%20if%20(touchedWindow.targetFlags%20%26%20InputTarget%3A%3AFLAG_FOREGROUND)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20If%20the%20touched%20window%20is%20paused%20then%20keep%20waiting.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(touchedWindow.window-%3Epaused)%20%7B%0A%23if%20DEBUG_INPUT_DISPATCHER_POLICY%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20LOGD(%22Waiting%20because%20touched%20window%20is%20paused.%22)%3B%0A%23endif%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20injectionResult%20%3D%20handleTargetsNotReadyLocked(currentTime%2C%20entry%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20NULL%2C%20touchedWindow.window%2C%20nextWakeupTime)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20goto%20Unresponsive%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20If%20the%20touched%20window%20is%20still%20working%20on%20previous%20events%20then%20keep%20waiting.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!%20isWindowFinishedWithPreviousInputLocked(touchedWindow.window))%20%7B%0A%23if%20DEBUG_FOCUS%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20LOGD(%22Waiting%20because%20touched%20window%20still%20processing%20previous%20input.%22)%3B%0A%23endif%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20injectionResult%20%3D%20handleTargetsNotReadyLocked(currentTime%2C%20entry%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20NULL%2C%20touchedWindow.window%2C%20nextWakeupTime)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20goto%20Unresponsive%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20If%20this%20is%20the%20first%20pointer%20going%20down%20and%20the%20touched%20window%20has%20a%20wallpaper%0A%20%20%20%20%2F%2F%20then%20also%20add%20the%20touched%20wallpaper%20windows%20so%20they%20are%20locked%20in%20for%20the%20duration%0A%20%20%20%20%2F%2F%20of%20the%20touch%20gesture.%0A%20%20%20%20if%20(maskedAction%20%3D%3D%20AMOTION_EVENT_ACTION_DOWN)%20%7B%0A%20%20%20%20%20%20%20%20const%20InputWindow*%20foregroundWindow%20%3D%20mTempTouchState.getFirstForegroundWindow()%3B%0A%20%20%20%20%20%20%20%20if%20(foregroundWindow-%3EhasWallpaper)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(size_t%20i%20%3D%200%3B%20i%20%3C%20mWindows.size()%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20InputWindow*%20window%20%3D%20%26%20mWindows%5Bi%5D%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(window-%3ElayoutParamsType%20%3D%3D%20InputWindow%3A%3ATYPE_WALLPAPER)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mTempTouchState.addOrUpdateWindow(window%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20InputTarget%3A%3AFLAG_WINDOW_IS_OBSCURED%2C%20BitSet32(0))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Success!%20%20Output%20targets.%0A%20%20%20%20injectionResult%20%3D%20INPUT_EVENT_INJECTION_SUCCEEDED%3B%0A%0A%20%20%20%20for%20(size_t%20i%20%3D%200%3B%20i%20%3C%20mTempTouchState.windows.size()%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20const%20TouchedWindow%26%20touchedWindow%20%3D%20mTempTouchState.windows.itemAt(i)%3B%0A%20%20%20%20%20%20%20%20addWindowTargetLocked(touchedWindow.window%2C%20touchedWindow.targetFlags%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20touchedWindow.pointerIds)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Drop%20the%20outside%20touch%20window%20since%20we%20will%20not%20care%20about%20them%20in%20the%20next%20iteration.%0A%20%20%20%20mTempTouchState.removeOutsideTouchWindows()%3B%0A%0AFailed%3A%0A%20%20%20%20%2F%2F%20Check%20injection%20permission%20once%20and%20for%20all.%0A%20%20%20%20if%20(injectionPermission%20%3D%3D%20INJECTION_PERMISSION_UNKNOWN)%20%7B%0A%20%20%20%20%20%20%20%20if%20(checkInjectionPermission(NULL%2C%20entry-%3EinjectionState))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20injectionPermission%20%3D%20INJECTION_PERMISSION_GRANTED%3B%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20injectionPermission%20%3D%20INJECTION_PERMISSION_DENIED%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Update%20final%20pieces%20of%20touch%20state%20if%20the%20injector%20had%20permission.%0A%20%20%20%20if%20(injectionPermission%20%3D%3D%20INJECTION_PERMISSION_GRANTED)%20%7B%0A%20%20%20%20%20%20%20%20if%20(maskedAction%20%3D%3D%20AMOTION_EVENT_ACTION_UP%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%7C%20maskedAction%20%3D%3D%20AMOTION_EVENT_ACTION_CANCEL)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20All%20pointers%20up%20or%20canceled.%0A%20%20%20%20%20%20%20%20%20%20%20%20mTempTouchState.reset()%3B%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(maskedAction%20%3D%3D%20AMOTION_EVENT_ACTION_DOWN)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20First%20pointer%20went%20down.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(mTouchState.down)%20%7B%0A%23if%20DEBUG_FOCUS%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20LOGD(%22Pointer%20down%20received%20while%20already%20down.%22)%3B%0A%23endif%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%20else%20if%20(maskedAction%20%3D%3D%20AMOTION_EVENT_ACTION_POINTER_UP)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20One%20pointer%20went%20up.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(isSplit)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20int32_t%20pointerIndex%20%3D%20getMotionEventActionPointerIndex(action)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20uint32_t%20pointerId%20%3D%20entry-%3EpointerIds%5BpointerIndex%5D%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(size_t%20i%20%3D%200%3B%20i%20%3C%20mTempTouchState.windows.size()%3B%20)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20TouchedWindow%26%20touchedWindow%20%3D%20mTempTouchState.windows.editItemAt(i)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(touchedWindow.targetFlags%20%26%20InputTarget%3A%3AFLAG_SPLIT)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20touchedWindow.pointerIds.clearBit(pointerId)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(touchedWindow.pointerIds.isEmpty())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mTempTouchState.windows.removeAt(i)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i%20%2B%3D%201%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Save%20changes%20to%20touch%20state.%0A%20%20%20%20%20%20%20%20mTouchState.copyFrom(mTempTouchState)%3B%0A%20%20%20%20%7D%20else%20%7B%0A%23if%20DEBUG_FOCUS%0A%20%20%20%20%20%20%20%20LOGD(%22Not%20updating%20touch%20focus%20because%20injection%20was%20denied.%22)%3B%0A%23endif%0A%20%20%20%20%7D%0A%0AUnresponsive%3A%0A%20%20%20%20%2F%2F%20Reset%20temporary%20touch%20state%20to%20ensure%20we%20release%20unnecessary%20references%20to%20input%20channels.%0A%20%20%20%20mTempTouchState.reset()%3B%0A%0A%20%20%20%20nsecs_t%20timeSpentWaitingForApplication%20%3D%20getTimeSpentWaitingForApplicationLocked(currentTime)%3B%0A%20%20%20%20updateDispatchStatisticsLocked(currentTime%2C%20entry%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20injectionResult%2C%20timeSpentWaitingForApplication)%3B%0A%23if%20DEBUG_FOCUS%0A%20%20%20%20LOGD(%22findTouchedWindow%20finished%3A%20injectionResult%3D%25d%2C%20injectionPermission%3D%25d%2C%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%22timeSpentWaitingForApplication%3D%250.1fms%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20injectionResult%2C%20injectionPermission%2C%20timeSpentWaitingForApplication%20%2F%201000000.0)%3B%0A%23endif%0A%20%20%20%20return%20injectionResult%3B%0A%7D%0A" /> 收藏代码
  1. int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,  
  2.         const MotionEntry* entry, nsecs_t* nextWakeupTime) {  
  3.     enum InjectionPermission {  
  4.         INJECTION_PERMISSION_UNKNOWN,  
  5.         INJECTION_PERMISSION_GRANTED,  
  6.         INJECTION_PERMISSION_DENIED  
  7.     };  
  8.   
  9.     mCurrentInputTargets.clear();  
  10.   
  11.     nsecs_t startTime = now();  
  12.   
  13.     // For security reasons, we defer updating the touch state until we are sure that  
  14.     // event injection will be allowed.  
  15.     //  
  16.     // FIXME In the original code, screenWasOff could never be set to true.  
  17.     //       The reason is that the POLICY_FLAG_WOKE_HERE  
  18.     //       and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw  
  19.     //       EV_KEY, EV_REL and EV_ABS events.  As it happens, the touch event was  
  20.     //       actually enqueued using the policyFlags that appeared in the final EV_SYN  
  21.     //       events upon which no preprocessing took place.  So policyFlags was always 0.  
  22.     //       In the new native input dispatcher we're a bit more careful about event  
  23.     //       preprocessing so the touches we receive can actually have non-zero policyFlags.  
  24.     //       Unfortunately we obtain undesirable behavior.  
  25.     //  
  26.     //       Here's what happens:  
  27.     //  
  28.     //       When the device dims in anticipation of going to sleep, touches  
  29.     //       in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause  
  30.     //       the device to brighten and reset the user activity timer.  
  31.     //       Touches on other windows (such as the launcher window)  
  32.     //       are dropped.  Then after a moment, the device goes to sleep.  Oops.  
  33.     //  
  34.     //       Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE  
  35.     //       instead of POLICY_FLAG_WOKE_HERE...  
  36.     //  
  37.     bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;  
  38.   
  39.     int32_t action = entry->action;  
  40.     int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;  
  41.   
  42.     // Update the touch state as needed based on the properties of the touch event.  
  43.     int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;  
  44.     InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;  
  45.     if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {  
  46.         mTempTouchState.reset();  
  47.         mTempTouchState.down = true;  
  48.     } else {  
  49.         mTempTouchState.copyFrom(mTouchState);  
  50.     }  
  51.   
  52.     bool isSplit = mTempTouchState.split && mTempTouchState.down;  
  53.     if (maskedAction == AMOTION_EVENT_ACTION_DOWN  
  54.             || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {  
  55.         /* Case 1: New splittable pointer going down. */  
  56.   
  57.         int32_t pointerIndex = getMotionEventActionPointerIndex(action);  
  58.         int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);  
  59.         int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);  
  60.         const InputWindow* newTouchedWindow = NULL;  
  61.         const InputWindow* topErrorWindow = NULL;  
  62.   
  63.         // Traverse windows from front to back to find touched window and outside targets.  
  64.         size_t numWindows = mWindows.size();  
  65.         for (size_t i = 0; i < numWindows; i++) {  
  66.             const InputWindow* window = & mWindows.editItemAt(i);  
  67.             int32_t flags = window->layoutParamsFlags;  
  68.   
  69.             if (flags & InputWindow::FLAG_SYSTEM_ERROR) {  
  70.                 if (! topErrorWindow) {  
  71.                     topErrorWindow = window;  
  72.                 }  
  73.             }  
  74.   
  75.             if (window->visible) {  
  76.                 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {  
  77.                     bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE  
  78.                             | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;  
  79.                     if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {  
  80.                         if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {  
  81.                             newTouchedWindow = window;  
  82.                         }  
  83.                         break; // found touched window, exit window loop  
  84.                     }  
  85.                 }  
  86.   
  87.                 if (maskedAction == AMOTION_EVENT_ACTION_DOWN  
  88.                         && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {  
  89.                     int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;  
  90.                     if (isWindowObscuredAtPointLocked(window, x, y)) {  
  91.                         outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;  
  92.                     }  
  93.   
  94.                     mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));  
  95.                 }  
  96.             }  
  97.         }  
  98.   
  99.         // If there is an error window but it is not taking focus (typically because  
  100.         // it is invisible) then wait for it.  Any other focused window may in  
  101.         // fact be in ANR state.  
  102.         if (topErrorWindow && newTouchedWindow != topErrorWindow) {  
  103. #if DEBUG_FOCUS  
  104.             LOGD("Waiting because system error window is pending.");  
  105. #endif  
  106.             injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
  107.                     NULL, NULL, nextWakeupTime);  
  108.             injectionPermission = INJECTION_PERMISSION_UNKNOWN;  
  109.             goto Unresponsive;  
  110.         }  
  111.   
  112.         // Figure out whether splitting will be allowed for this window.  
  113.         if (newTouchedWindow  
  114.                 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {  
  115.             // New window supports splitting.  
  116.             isSplit = true;  
  117.         } else if (isSplit) {  
  118.             // New window does not support splitting but we have already split events.  
  119.             // Assign the pointer to the first foreground window we find.  
  120.             // (May be NULL which is why we put this code block before the next check.)  
  121.             newTouchedWindow = mTempTouchState.getFirstForegroundWindow();  
  122.         }  
  123.   
  124.         // If we did not find a touched window then fail.  
  125.         if (! newTouchedWindow) {  
  126.             if (mFocusedApplication) {  
  127. #if DEBUG_FOCUS  
  128.                 LOGD("Waiting because there is no touched window but there is a "  
  129.                         "focused application that may eventually add a new window: %s.",  
  130.                         getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());  
  131. #endif  
  132.                 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
  133.                         mFocusedApplication, NULL, nextWakeupTime);  
  134.                 goto Unresponsive;  
  135.             }  
  136.   
  137.             LOGI("Dropping event because there is no touched window or focused application.");  
  138.             injectionResult = INPUT_EVENT_INJECTION_FAILED;  
  139.             goto Failed;  
  140.         }  
  141.   
  142.         // Set target flags.  
  143.         int32_t targetFlags = InputTarget::FLAG_FOREGROUND;  
  144.         if (isSplit) {  
  145.             targetFlags |= InputTarget::FLAG_SPLIT;  
  146.         }  
  147.         if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {  
  148.             targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;  
  149.         }  
  150.   
  151.         // Update the temporary touch state.  
  152.         BitSet32 pointerIds;  
  153.         if (isSplit) {  
  154.             uint32_t pointerId = entry->pointerIds[pointerIndex];  
  155.             pointerIds.markBit(pointerId);  
  156.         }  
  157.         mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);  
  158.     } else {  
  159.         /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */  
  160.   
  161.         // If the pointer is not currently down, then ignore the event.  
  162.         if (! mTempTouchState.down) {  
  163.             LOGI("Dropping event because the pointer is not down.");  
  164.             injectionResult = INPUT_EVENT_INJECTION_FAILED;  
  165.             goto Failed;  
  166.         }  
  167.     }  
  168.   
  169.     // Check permission to inject into all touched foreground windows and ensure there  
  170.     // is at least one touched foreground window.  
  171.     {  
  172.         bool haveForegroundWindow = false;  
  173.         for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {  
  174.             const TouchedWindow& touchedWindow = mTempTouchState.windows[i];  
  175.             if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {  
  176.                 haveForegroundWindow = true;  
  177.                 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {  
  178.                     injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;  
  179.                     injectionPermission = INJECTION_PERMISSION_DENIED;  
  180.                     goto Failed;  
  181.                 }  
  182.             }  
  183.         }  
  184.         if (! haveForegroundWindow) {  
  185. #if DEBUG_INPUT_DISPATCHER_POLICY  
  186.             LOGD("Dropping event because there is no touched foreground window to receive it.");  
  187. #endif  
  188.             injectionResult = INPUT_EVENT_INJECTION_FAILED;  
  189.             goto Failed;  
  190.         }  
  191.   
  192.         // Permission granted to injection into all touched foreground windows.  
  193.         injectionPermission = INJECTION_PERMISSION_GRANTED;  
  194.     }  
  195.   
  196.     // Ensure all touched foreground windows are ready for new input.  
  197.     for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {  
  198.         const TouchedWindow& touchedWindow = mTempTouchState.windows[i];  
  199.         if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {  
  200.             // If the touched window is paused then keep waiting.  
  201.             if (touchedWindow.window->paused) {  
  202. #if DEBUG_INPUT_DISPATCHER_POLICY  
  203.                 LOGD("Waiting because touched window is paused.");  
  204. #endif  
  205.                 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
  206.                         NULL, touchedWindow.window, nextWakeupTime);  
  207.                 goto Unresponsive;  
  208.             }  
  209.   
  210.             // If the touched window is still working on previous events then keep waiting.  
  211.             if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {  
  212. #if DEBUG_FOCUS  
  213.                 LOGD("Waiting because touched window still processing previous input.");  
  214. #endif  
  215.                 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,  
  216.                         NULL, touchedWindow.window, nextWakeupTime);  
  217.                 goto Unresponsive;  
  218.             }  
  219.         }  
  220.     }  
  221.   
  222.     // If this is the first pointer going down and the touched window has a wallpaper  
  223.     // then also add the touched wallpaper windows so they are locked in for the duration  
  224.     // of the touch gesture.  
  225.     if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {  
  226.         const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();  
  227.         if (foregroundWindow->hasWallpaper) {  
  228.             for (size_t i = 0; i < mWindows.size(); i++) {  
  229.                 const InputWindow* window = & mWindows[i];  
  230.                 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {  
  231.                     mTempTouchState.addOrUpdateWindow(window,  
  232.                             InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));  
  233.                 }  
  234.             }  
  235.         }  
  236.     }  
  237.   
  238.     // Success!  Output targets.  
  239.     injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;  
  240.   
  241.     for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {  
  242.         const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);  
  243.         addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,  
  244.                 touchedWindow.pointerIds);  
  245.     }  
  246.   
  247.     // Drop the outside touch window since we will not care about them in the next iteration.  
  248.     mTempTouchState.removeOutsideTouchWindows();  
  249.   
  250. Failed:  
  251.     // Check injection permission once and for all.  
  252.     if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {  
  253.         if (checkInjectionPermission(NULL, entry->injectionState)) {  
  254.             injectionPermission = INJECTION_PERMISSION_GRANTED;  
  255.         } else {  
  256.             injectionPermission = INJECTION_PERMISSION_DENIED;  
  257.         }  
  258.     }  
  259.   
  260.     // Update final pieces of touch state if the injector had permission.  
  261.     if (injectionPermission == INJECTION_PERMISSION_GRANTED) {  
  262.         if (maskedAction == AMOTION_EVENT_ACTION_UP  
  263.                 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {  
  264.             // All pointers up or canceled.  
  265.             mTempTouchState.reset();  
  266.         } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {  
  267.             // First pointer went down.  
  268.             if (mTouchState.down) {  
  269. #if DEBUG_FOCUS  
  270.                 LOGD("Pointer down received while already down.");  
  271. #endif  
  272.             }  
  273.         } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {  
  274.             // One pointer went up.  
  275.             if (isSplit) {  
  276.                 int32_t pointerIndex = getMotionEventActionPointerIndex(action);  
  277.                 uint32_t pointerId = entry->pointerIds[pointerIndex];  
  278.   
  279.                 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {  
  280.                     TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);  
  281.                     if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {  
  282.                         touchedWindow.pointerIds.clearBit(pointerId);  
  283.                         if (touchedWindow.pointerIds.isEmpty()) {  
  284.                             mTempTouchState.windows.removeAt(i);  
  285.                             continue;  
  286.                         }  
  287.                     }  
  288.                     i += 1;  
  289.                 }  
  290.             }  
  291.         }  
  292.   
  293.         // Save changes to touch state.  
  294.         mTouchState.copyFrom(mTempTouchState);  
  295.     } else {  
  296. #if DEBUG_FOCUS  
  297.         LOGD("Not updating touch focus because injection was denied.");  
  298. #endif  
  299.     }  
  300.   
  301. Unresponsive:  
  302.     // Reset temporary touch state to ensure we release unnecessary references to input channels.  
  303.     mTempTouchState.reset();  
  304.   
  305.     nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);  
  306.     updateDispatchStatisticsLocked(currentTime, entry,  
  307.             injectionResult, timeSpentWaitingForApplication);  
  308. #if DEBUG_FOCUS  
  309.     LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "  
  310.             "timeSpentWaitingForApplication=%0.1fms",  
  311.             injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);  
  312. #endif  
  313.     return injectionResult;  
  314. }  

  最关键的几行代码,说明了Windows是如何找到触屏的输入焦点的:

 

Cpp代码  收藏代码
  1. if (window->visible) {    
  2.               if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {    
  3.                   bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE    
  4.                           | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;    
  5.                   if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {    
  6.                       if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {    
  7.                           newTouchedWindow = window;    
  8.                       }    
  9.                       break; // found touched window, exit window loop    
  10.                   }    
  11.               }    
  12.   
  13.               if (maskedAction == AMOTION_EVENT_ACTION_DOWN    
  14.                       && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {    
  15.                   int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;    
  16.                   if (isWindowObscuredAtPointLocked(window, x, y)) {    
  17.                       outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;    
  18.                   }    
  19.   
  20.                   mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));    
  21.               }    
  22.           }    

 

 

Java代码  收藏代码
  1.  // Focus tracking for touch.  
  2.     struct TouchedWindow {  
  3.         const InputWindow* window;  
  4.         int32_t targetFlags;  
  5.         BitSet32 pointerIds;  
  6.         sp<InputChannel> channel;  
  7.     };  
  8.     struct TouchState {  
  9.         bool down;  
  10.         bool split;  
  11.         Vector<TouchedWindow> windows;  
  12.   
  13.         TouchState();  
  14.         ~TouchState();  
  15.         void reset();  
  16.         void copyFrom(const TouchState& other);  
  17.         void addOrUpdateWindow(const InputWindow* window, int32_t targetFlags, BitSet32 pointerIds);  
  18.         void removeOutsideTouchWindows();  
  19.         const InputWindow* getFirstForegroundWindow();  
  20.     };  
  21.   
  22.   
  23.   
  24. 另外如何定义按键和其他触屏焦点的:  
  25.   
  26.   
  27.         /* Updates the cached window information provided to the input dispatcher. */  
  28.         public void updateInputWindowsLw() {  
  29.             // Populate the input window list with information about all of the windows that  
  30.             // could potentially receive input.  
  31.             // As an optimization, we could try to prune the list of windows but this turns  
  32.             // out to be difficult because only the native code knows for sure which window  
  33.             // currently has touch focus.  
  34.             final ArrayList<WindowState> windows = mWindows;  
  35.             final int N = windows.size();  
  36.             for (int i = N - 1; i >= 0; i--) {  
  37.                 final WindowState child = windows.get(i);  
  38.                 if (child.mInputChannel == null || child.mRemoved) {  
  39.                     // Skip this window because it cannot possibly receive input.  
  40.                     continue;  
  41.                 }  
  42.                   
  43.                 final int flags = child.mAttrs.flags;  
  44.                 final int type = child.mAttrs.type;  
  45.                   
  46.                <span style="color: #ff6600;"> final boolean hasFocus = (child == mInputFocus);</span>  
  47. //本行代码确定,一次性的focusWindow只有一个。  
  48.                 final boolean isVisible = child.isVisibleLw();  
  49.                 final boolean hasWallpaper = (child == mWallpaperTarget)  
  50.                         && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);    

 

发表评论
用户名: 匿名