一个是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代码
  1. voidInputDispatcher::dispatchOnce(){
  2. nsecs_tkeyRepeatTimeout=mPolicy->getKeyRepeatTimeout();
  3. nsecs_tkeyRepeatDelay=mPolicy->getKeyRepeatDelay();
  4. nsecs_tnextWakeupTime=LONG_LONG_MAX;
  5. {//acquirelock
  6. AutoMutex_l(mLock);
  7. dispatchOnceInnerLocked(keyRepeatTimeout,keyRepeatDelay,&nextWakeupTime);
  8. if(runCommandsLockedInterruptible()){
  9. nextWakeupTime=LONG_LONG_MIN;//forcenextpolltowakeupimmediately
  10. }
  11. }//releaselock
  12. //Waitforcallbackortimeoutorwake.(makesureweroundup,notdown)
  13. nsecs_tcurrentTime=now();
  14. int32_ttimeoutMillis;
  15. if(nextWakeupTime>currentTime){
  16. uint64_ttimeout=uint64_t(nextWakeupTime-currentTime);
  17. timeout=(timeout+999999LL)/1000000LL;
  18. timeoutMillis=timeout>INT_MAX?-1:int32_t(timeout);
  19. }else{
  20. timeoutMillis=0;
  21. }
  22. mLooper->pollOnce(timeoutMillis);
  23. }

Java代码
  1. caseEventEntry::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代码
  1. boolInputDispatcher::dispatchMotionLocked(
  2. nsecs_tcurrentTime,MotionEntry*entry,DropReason*dropReason,nsecs_t*nextWakeupTime){
  3. //Preprocessing.
  4. if(!entry->dispatchInProgress){
  5. entry->dispatchInProgress=true;
  6. resetTargetsLocked();
  7. logOutboundMotionDetailsLocked("dispatchMotion-",entry);
  8. }
  9. //Cleanupifdroppingtheevent.
  10. if(*dropReason!=DROP_REASON_NOT_DROPPED){
  11. resetTargetsLocked();
  12. setInjectionResultLocked(entry,*dropReason==DROP_REASON_POLICY
  13. ?INPUT_EVENT_INJECTION_SUCCEEDED:INPUT_EVENT_INJECTION_FAILED);
  14. returntrue;
  15. }
  16. boolisPointerEvent=entry->source&AINPUT_SOURCE_CLASS_POINTER;
  17. //Identifytargets.
  18. if(!mCurrentInputTargetsValid){
  19. int32_tinjectionResult;
  20. if(isPointerEvent){
  21. //Pointerevent.(eg.touchscreen)
  22. injectionResult=findTouchedWindowTargetsLocked(currentTime,
  23. entry,nextWakeupTime);
  24. }else{
  25. //Nontouchevent.(eg.trackball)
  26. injectionResult=findFocusedWindowTargetsLocked(currentTime,
  27. entry,nextWakeupTime);
  28. }
  29. if(injectionResult==INPUT_EVENT_INJECTION_PENDING){
  30. returnfalse;
  31. }
  32. setInjectionResultLocked(entry,injectionResult);
  33. if(injectionResult!=INPUT_EVENT_INJECTION_SUCCEEDED){
  34. returntrue;
  35. }
  36. addMonitoringTargetsLocked();
  37. commitTargetsLocked();
  38. }
  39. //Dispatchthemotion.
  40. dispatchEventToCurrentInputTargetsLocked(currentTime,entry,false);
  41. returntrue;
  42. }

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代码
  1. privatefinalInputHandlermInputHandler=newInputHandler(){
  2. publicvoidhandleKey(KeyEventevent,RunnablefinishedCallback){
  3. startInputEvent(finishedCallback);
  4. dispatchKey(event,true);
  5. }
  6. publicvoidhandleMotion(MotionEventevent,RunnablefinishedCallback){
  7. startInputEvent(finishedCallback);
  8. dispatchMotion(event,true);
  9. }
  10. };

InputHandler注册给了系统

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

Java代码
  1. dispatchMotion(event,true);方法如下
  2. rivatevoiddispatchMotion(MotionEventevent,booleansendDone){
  3. intsource=event.getSource();
  4. if((source&InputDevice.SOURCE_CLASS_POINTER)!=0){
  5. dispatchPointer(event,sendDone);
  6. }elseif((source&InputDevice.SOURCE_CLASS_TRACKBALL)!=0){
  7. dispatchTrackball(event,sendDone);
  8. }else{
  9. //TODO
  10. Log.v(TAG,"Droppingunsupportedmotionevent(unimplemented):"+event);
  11. if(sendDone){
  12. finishInputEvent();
  13. }
  14. }
  15. }

调用了dispatchPointer

ViewRoot本身就是Handler直接sendMessageAtTime

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

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

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

然后

Java代码
  1. dispatchEventToCurrentInputTargetsLocked

调用了如下方法

Java代码
  1. int32_tInputDispatcher::findFocusedWindowTargetsLocked(nsecs_tcurrentTime,
  2. constEventEntry*entry,nsecs_t*nextWakeupTime){
  3. mCurrentInputTargets.clear();
  4. int32_tinjectionResult;
  5. //Ifthereisnocurrentlyfocusedwindowandnofocusedapplication
  6. //thendroptheevent.
  7. if(!mFocusedWindow){
  8. if(mFocusedApplication){
  9. #ifDEBUG_FOCUS
  10. LOGD("Waitingbecausethereisnofocusedwindowbutthereisa"
  11. "focusedapplicationthatmayeventuallyaddawindow:%s.",
  12. getApplicationWindowLabelLocked(mFocusedApplication,NULL).string());
  13. #endif
  14. injectionResult=handleTargetsNotReadyLocked(currentTime,entry,
  15. mFocusedApplication,NULL,nextWakeupTime);
  16. gotoUnresponsive;
  17. }
  18. LOGI("Droppingeventbecausethereisnofocusedwindoworfocusedapplication.");
  19. injectionResult=INPUT_EVENT_INJECTION_FAILED;
  20. gotoFailed;
  21. }
  22. //Checkpermissions.
  23. if(!checkInjectionPermission(mFocusedWindow,entry->injectionState)){
  24. injectionResult=INPUT_EVENT_INJECTION_PERMISSION_DENIED;
  25. gotoFailed;
  26. }
  27. //Ifthecurrentlyfocusedwindowispausedthenkeepwaiting.
  28. if(mFocusedWindow->paused){
  29. #ifDEBUG_FOCUS
  30. LOGD("Waitingbecausefocusedwindowispaused.");
  31. #endif
  32. injectionResult=handleTargetsNotReadyLocked(currentTime,entry,
  33. mFocusedApplication,mFocusedWindow,nextWakeupTime);
  34. gotoUnresponsive;
  35. }
  36. //Ifthecurrentlyfocusedwindowisstillworkingonpreviouseventsthenkeepwaiting.
  37. if(!isWindowFinishedWithPreviousInputLocked(mFocusedWindow)){
  38. #ifDEBUG_FOCUS
  39. LOGD("Waitingbecausefocusedwindowstillprocessingpreviousinput.");
  40. #endif
  41. injectionResult=handleTargetsNotReadyLocked(currentTime,entry,
  42. mFocusedApplication,mFocusedWindow,nextWakeupTime);
  43. gotoUnresponsive;
  44. }
  45. //Success!Outputtargets.
  46. injectionResult=INPUT_EVENT_INJECTION_SUCCEEDED;
  47. addWindowTargetLocked(mFocusedWindow,InputTarget::FLAG_FOREGROUND,BitSet32(0));
  48. //Done.
  49. Failed:
  50. Unresponsive:
  51. nsecs_ttimeSpentWaitingForApplication=getTimeSpentWaitingForApplicationLocked(currentTime);
  52. updateDispatchStatisticsLocked(currentTime,entry,
  53. injectionResult,timeSpentWaitingForApplication);
  54. #ifDEBUG_FOCUS
  55. LOGD("findFocusedWindowfinished:injectionResult=%d,"
  56. "timeSpendWaitingForApplication=%0.1fms",
  57. injectionResult,timeSpentWaitingForApplication/1000000.0);
  58. #endif
  59. returninjectionResult;
  60. }

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

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

Java代码
  1. /*Updatesthecachedwindowinformationprovidedtotheinputdispatcher.*/
  2. publicvoidupdateInputWindowsLw(){
  3. //Populatetheinputwindowlistwithinformationaboutallofthewindowsthat
  4. //couldpotentiallyreceiveinput.
  5. //Asanoptimization,wecouldtrytoprunethelistofwindowsbutthisturns
  6. //outtobedifficultbecauseonlythenativecodeknowsforsurewhichwindow
  7. //currentlyhastouchfocus.
  8. finalArrayList<WindowState>windows=mWindows;
  9. finalintN=windows.size();
  10. for(inti=N-1;i>=0;i--){
  11. finalWindowStatechild=windows.get(i);
  12. if(child.mInputChannel==null||child.mRemoved){
  13. //Skipthiswindowbecauseitcannotpossiblyreceiveinput.
  14. continue;
  15. }
  16. finalintflags=child.mAttrs.flags;
  17. finalinttype=child.mAttrs.type;
  18. finalbooleanhasFocus=(child==mInputFocus);
  19. finalbooleanisVisible=child.isVisibleLw();
  20. finalbooleanhasWallpaper=(child==mWallpaperTarget)
  21. &&(type!=WindowManager.LayoutParams.TYPE_KEYGUARD);
  22. //Addawindowtoourlistofinputwindows.
  23. finalInputWindowinputWindow=mTempInputWindows.add();
  24. inputWindow.inputChannel=child.mInputChannel;
  25. inputWindow.name=child.toString();
  26. inputWindow.layoutParamsFlags=flags;
  27. inputWindow.layoutParamsType=type;
  28. inputWindow.dispatchingTimeoutNanos=child.getInputDispatchingTimeoutNanos();
  29. inputWindow.visible=isVisible;
  30. inputWindow.canReceiveKeys=child.canReceiveKeys();
  31. inputWindow.hasFocus=hasFocus;
  32. inputWindow.hasWallpaper=hasWallpaper;
  33. inputWindow.paused=child.mAppToken!=null?child.mAppToken.paused:false;
  34. inputWindow.layer=child.mLayer;
  35. inputWindow.ownerPid=child.mSession.mPid;
  36. inputWindow.ownerUid=child.mSession.mUid;
  37. finalRectframe=child.mFrame;
  38. inputWindow.frameLeft=frame.left;
  39. inputWindow.frameTop=frame.top;
  40. inputWindow.frameRight=frame.right;
  41. inputWindow.frameBottom=frame.bottom;
  42. finalRectvisibleFrame=child.mVisibleFrame;
  43. inputWindow.visibleFrameLeft=visibleFrame.left;
  44. inputWindow.visibleFrameTop=visibleFrame.top;
  45. inputWindow.visibleFrameRight=visibleFrame.right;
  46. inputWindow.visibleFrameBottom=visibleFrame.bottom;
  47. switch(child.mTouchableInsets){
  48. default:
  49. caseViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
  50. inputWindow.touchableAreaLeft=frame.left;
  51. inputWindow.touchableAreaTop=frame.top;
  52. inputWindow.touchableAreaRight=frame.right;
  53. inputWindow.touchableAreaBottom=frame.bottom;
  54. break;
  55. caseViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:{
  56. Rectinset=child.mGivenContentInsets;
  57. inputWindow.touchableAreaLeft=frame.left+inset.left;
  58. inputWindow.touchableAreaTop=frame.top+inset.top;
  59. inputWindow.touchableAreaRight=frame.right-inset.right;
  60. inputWindow.touchableAreaBottom=frame.bottom-inset.bottom;
  61. break;
  62. }
  63. caseViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:{
  64. Rectinset=child.mGivenVisibleInsets;
  65. inputWindow.touchableAreaLeft=frame.left+inset.left;
  66. inputWindow.touchableAreaTop=frame.top+inset.top;
  67. inputWindow.touchableAreaRight=frame.right-inset.right;
  68. inputWindow.touchableAreaBottom=frame.bottom-inset.bottom;
  69. break;
  70. }
  71. }
  72. }
  73. //Sendwindowstonativecode.
  74. mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
  75. //Clearthelistinpreparationforthenextround.
  76. //AlsoavoidskeepingInputChannelobjectsreferencedunnecessarily.
  77. mTempInputWindows.clear();
  78. }

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

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

Java代码
  1. /**
  2. *Z-ordered(bottom-mostfirst)listofallWindowobjects.
  3. */
  4. finalArrayList<WindowState>mWindows=newArrayList<WindowState>();

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

Java代码
  1. int32_tInputDispatcher::findTouchedWindowTargetsLocked(nsecs_tcurrentTime,
  2. constMotionEntry*entry,nsecs_t*nextWakeupTime){
  3. enumInjectionPermission{
  4. INJECTION_PERMISSION_UNKNOWN,
  5. INJECTION_PERMISSION_GRANTED,
  6. INJECTION_PERMISSION_DENIED
  7. };
  8. mCurrentInputTargets.clear();
  9. nsecs_tstartTime=now();
  10. //Forsecurityreasons,wedeferupdatingthetouchstateuntilwearesurethat
  11. //eventinjectionwillbeallowed.
  12. //
  13. //FIXMEIntheoriginalcode,screenWasOffcouldneverbesettotrue.
  14. //ThereasonisthatthePOLICY_FLAG_WOKE_HERE
  15. //andPOLICY_FLAG_BRIGHT_HEREflagsweresetonlywhenpreprocessingraw
  16. //EV_KEY,EV_RELandEV_ABSevents.Asithappens,thetoucheventwas
  17. //actuallyenqueuedusingthepolicyFlagsthatappearedinthefinalEV_SYN
  18. //eventsuponwhichnopreprocessingtookplace.SopolicyFlagswasalways0.
  19. //Inthenewnativeinputdispatcherwe'reabitmorecarefulaboutevent
  20. //preprocessingsothetoucheswereceivecanactuallyhavenon-zeropolicyFlags.
  21. //Unfortunatelyweobtainundesirablebehavior.
  22. //
  23. //Here'swhathappens:
  24. //
  25. //Whenthedevicedimsinanticipationofgoingtosleep,touches
  26. //inwindowswhichhaveFLAG_TOUCHABLE_WHEN_WAKINGcause
  27. //thedevicetobrightenandresettheuseractivitytimer.
  28. //Touchesonotherwindows(suchasthelauncherwindow)
  29. //aredropped.Thenafteramoment,thedevicegoestosleep.Oops.
  30. //
  31. //AlsonoticehowscreenWasOffwasbeinginitializedusingPOLICY_FLAG_BRIGHT_HERE
  32. //insteadofPOLICY_FLAG_WOKE_HERE...
  33. //
  34. boolscreenWasOff=false;//originalpolicy:policyFlags&POLICY_FLAG_BRIGHT_HERE;
  35. int32_taction=entry->action;
  36. int32_tmaskedAction=action&AMOTION_EVENT_ACTION_MASK;
  37. //Updatethetouchstateasneededbasedonthepropertiesofthetouchevent.
  38. int32_tinjectionResult=INPUT_EVENT_INJECTION_PENDING;
  39. InjectionPermissioninjectionPermission=INJECTION_PERMISSION_UNKNOWN;
  40. if(maskedAction==AMOTION_EVENT_ACTION_DOWN){
  41. mTempTouchState.reset();
  42. mTempTouchState.down=true;
  43. }else{
  44. mTempTouchState.copyFrom(mTouchState);
  45. }
  46. boolisSplit=mTempTouchState.split&&mTempTouchState.down;
  47. if(maskedAction==AMOTION_EVENT_ACTION_DOWN
  48. ||(isSplit&&maskedAction==AMOTION_EVENT_ACTION_POINTER_DOWN)){
  49. /*Case1:Newsplittablepointergoingdown.*/
  50. int32_tpointerIndex=getMotionEventActionPointerIndex(action);
  51. int32_tx=int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
  52. int32_ty=int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
  53. constInputWindow*newTouchedWindow=NULL;
  54. constInputWindow*topErrorWindow=NULL;
  55. //Traversewindowsfromfronttobacktofindtouchedwindowandoutsidetargets.
  56. size_tnumWindows=mWindows.size();
  57. for(size_ti=0;i<numWindows;i++){
  58. constInputWindow*window=&mWindows.editItemAt(i);
  59. int32_tflags=window->layoutParamsFlags;
  60. if(flags&InputWindow::FLAG_SYSTEM_ERROR){
  61. if(!topErrorWindow){
  62. topErrorWindow=window;
  63. }
  64. }
  65. if(window->visible){
  66. if(!(flags&InputWindow::FLAG_NOT_TOUCHABLE)){
  67. boolisTouchModal=(flags&(InputWindow::FLAG_NOT_FOCUSABLE
  68. |InputWindow::FLAG_NOT_TOUCH_MODAL))==0;
  69. if(isTouchModal||window->touchableAreaContainsPoint(x,y)){
  70. if(!screenWasOff||flags&InputWindow::FLAG_TOUCHABLE_WHEN_WAKING){
  71. newTouchedWindow=window;
  72. }
  73. break;//foundtouchedwindow,exitwindowloop
  74. }
  75. }
  76. if(maskedAction==AMOTION_EVENT_ACTION_DOWN
  77. &&(flags&InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)){
  78. int32_toutsideTargetFlags=InputTarget::FLAG_OUTSIDE;
  79. if(isWindowObscuredAtPointLocked(window,x,y)){
  80. outsideTargetFlags|=InputTarget::FLAG_WINDOW_IS_OBSCURED;
  81. }
  82. mTempTouchState.addOrUpdateWindow(window,outsideTargetFlags,BitSet32(0));
  83. }
  84. }
  85. }
  86. //Ifthereisanerrorwindowbutitisnottakingfocus(typicallybecause
  87. //itisinvisible)thenwaitforit.Anyotherfocusedwindowmayin
  88. //factbeinANRstate.
  89. if(topErrorWindow&&newTouchedWindow!=topErrorWindow){
  90. #ifDEBUG_FOCUS
  91. LOGD("Waitingbecausesystemerrorwindowispending.");
  92. #endif
  93. injectionResult=handleTargetsNotReadyLocked(currentTime,entry,
  94. NULL,NULL,nextWakeupTime);
  95. injectionPermission=INJECTION_PERMISSION_UNKNOWN;
  96. gotoUnresponsive;
  97. }
  98. //Figureoutwhethersplittingwillbeallowedforthiswindow.
  99. if(newTouchedWindow
  100. &&(newTouchedWindow->layoutParamsFlags&InputWindow::FLAG_SPLIT_TOUCH)){
  101. //Newwindowsupportssplitting.
  102. isSplit=true;
  103. }elseif(isSplit){
  104. //Newwindowdoesnotsupportsplittingbutwehavealreadysplitevents.
  105. //Assignthepointertothefirstforegroundwindowwefind.
  106. //(MaybeNULLwhichiswhyweputthiscodeblockbeforethenextcheck.)
  107. newTouchedWindow=mTempTouchState.getFirstForegroundWindow();
  108. }
  109. //Ifwedidnotfindatouchedwindowthenfail.
  110. if(!newTouchedWindow){
  111. if(mFocusedApplication){
  112. #ifDEBUG_FOCUS
  113. LOGD("Waitingbecausethereisnotouchedwindowbutthereisa"
  114. "focusedapplicationthatmayeventuallyaddanewwindow:%s.",
  115. getApplicationWindowLabelLocked(mFocusedApplication,NULL).string());
  116. #endif
  117. injectionResult=handleTargetsNotReadyLocked(currentTime,entry,
  118. mFocusedApplication,NULL,nextWakeupTime);
  119. gotoUnresponsive;
  120. }
  121. LOGI("Droppingeventbecausethereisnotouchedwindoworfocusedapplication.");
  122. injectionResult=INPUT_EVENT_INJECTION_FAILED;
  123. gotoFailed;
  124. }
  125. //Settargetflags.
  126. int32_ttargetFlags=InputTarget::FLAG_FOREGROUND;
  127. if(isSplit){
  128. targetFlags|=InputTarget::FLAG_SPLIT;
  129. }
  130. if(isWindowObscuredAtPointLocked(newTouchedWindow,x,y)){
  131. targetFlags|=InputTarget::FLAG_WINDOW_IS_OBSCURED;
  132. }
  133. //Updatethetemporarytouchstate.
  134. BitSet32pointerIds;
  135. if(isSplit){
  136. uint32_tpointerId=entry->pointerIds[pointerIndex];
  137. pointerIds.markBit(pointerId);
  138. }
  139. mTempTouchState.addOrUpdateWindow(newTouchedWindow,targetFlags,pointerIds);
  140. }else{
  141. /*Case2:Pointermove,up,cancelornon-splittablepointerdown.*/
  142. //Ifthepointerisnotcurrentlydown,thenignoretheevent.
  143. if(!mTempTouchState.down){
  144. LOGI("Droppingeventbecausethepointerisnotdown.");
  145. injectionResult=INPUT_EVENT_INJECTION_FAILED;
  146. gotoFailed;
  147. }
  148. }
  149. //Checkpermissiontoinjectintoalltouchedforegroundwindowsandensurethere
  150. //isatleastonetouchedforegroundwindow.
  151. {
  152. boolhaveForegroundWindow=false;
  153. for(size_ti=0;i<mTempTouchState.windows.size();i++){
  154. constTouchedWindow&touchedWindow=mTempTouchState.windows[i];
  155. if(touchedWindow.targetFlags&InputTarget::FLAG_FOREGROUND){
  156. haveForegroundWindow=true;
  157. if(!checkInjectionPermission(touchedWindow.window,entry->injectionState)){
  158. injectionResult=INPUT_EVENT_INJECTION_PERMISSION_DENIED;
  159. injectionPermission=INJECTION_PERMISSION_DENIED;
  160. gotoFailed;
  161. }
  162. }
  163. }
  164. if(!haveForegroundWindow){
  165. #ifDEBUG_INPUT_DISPATCHER_POLICY
  166. LOGD("Droppingeventbecausethereisnotouchedforegroundwindowtoreceiveit.");
  167. #endif
  168. injectionResult=INPUT_EVENT_INJECTION_FAILED;
  169. gotoFailed;
  170. }
  171. //Permissiongrantedtoinjectionintoalltouchedforegroundwindows.
  172. injectionPermission=INJECTION_PERMISSION_GRANTED;
  173. }
  174. //Ensurealltouchedforegroundwindowsarereadyfornewinput.
  175. for(size_ti=0;i<mTempTouchState.windows.size();i++){
  176. constTouchedWindow&touchedWindow=mTempTouchState.windows[i];
  177. if(touchedWindow.targetFlags&InputTarget::FLAG_FOREGROUND){
  178. //Ifthetouchedwindowispausedthenkeepwaiting.
  179. if(touchedWindow.window->paused){
  180. #ifDEBUG_INPUT_DISPATCHER_POLICY
  181. LOGD("Waitingbecausetouchedwindowispaused.");
  182. #endif
  183. injectionResult=handleTargetsNotReadyLocked(currentTime,entry,
  184. NULL,touchedWindow.window,nextWakeupTime);
  185. gotoUnresponsive;
  186. }
  187. //Ifthetouchedwindowisstillworkingonpreviouseventsthenkeepwaiting.
  188. if(!isWindowFinishedWithPreviousInputLocked(touchedWindow.window)){
  189. #ifDEBUG_FOCUS
  190. LOGD("Waitingbecausetouchedwindowstillprocessingpreviousinput.");
  191. #endif
  192. injectionResult=handleTargetsNotReadyLocked(currentTime,entry,
  193. NULL,touchedWindow.window,nextWakeupTime);
  194. gotoUnresponsive;
  195. }
  196. }
  197. }
  198. //Ifthisisthefirstpointergoingdownandthetouchedwindowhasawallpaper
  199. //thenalsoaddthetouchedwallpaperwindowssotheyarelockedinfortheduration
  200. //ofthetouchgesture.
  201. if(maskedAction==AMOTION_EVENT_ACTION_DOWN){
  202. constInputWindow*foregroundWindow=mTempTouchState.getFirstForegroundWindow();
  203. if(foregroundWindow->hasWallpaper){
  204. for(size_ti=0;i<mWindows.size();i++){
  205. constInputWindow*window=&mWindows[i];
  206. if(window->layoutParamsType==InputWindow::TYPE_WALLPAPER){
  207. mTempTouchState.addOrUpdateWindow(window,
  208. InputTarget::FLAG_WINDOW_IS_OBSCURED,BitSet32(0));
  209. }
  210. }
  211. }
  212. }
  213. //Success!Outputtargets.
  214. injectionResult=INPUT_EVENT_INJECTION_SUCCEEDED;
  215. for(size_ti=0;i<mTempTouchState.windows.size();i++){
  216. constTouchedWindow&touchedWindow=mTempTouchState.windows.itemAt(i);
  217. addWindowTargetLocked(touchedWindow.window,touchedWindow.targetFlags,
  218. touchedWindow.pointerIds);
  219. }
  220. //Droptheoutsidetouchwindowsincewewillnotcareabouttheminthenextiteration.
  221. mTempTouchState.removeOutsideTouchWindows();
  222. Failed:
  223. //Checkinjectionpermissiononceandforall.
  224. if(injectionPermission==INJECTION_PERMISSION_UNKNOWN){
  225. if(checkInjectionPermission(NULL,entry->injectionState)){
  226. injectionPermission=INJECTION_PERMISSION_GRANTED;
  227. }else{
  228. injectionPermission=INJECTION_PERMISSION_DENIED;
  229. }
  230. }
  231. //Updatefinalpiecesoftouchstateiftheinjectorhadpermission.
  232. if(injectionPermission==INJECTION_PERMISSION_GRANTED){
  233. if(maskedAction==AMOTION_EVENT_ACTION_UP
  234. ||maskedAction==AMOTION_EVENT_ACTION_CANCEL){
  235. //Allpointersuporcanceled.
  236. mTempTouchState.reset();
  237. }elseif(maskedAction==AMOTION_EVENT_ACTION_DOWN){
  238. //Firstpointerwentdown.
  239. if(mTouchState.down){
  240. #ifDEBUG_FOCUS
  241. LOGD("Pointerdownreceivedwhilealreadydown.");
  242. #endif
  243. }
  244. }elseif(maskedAction==AMOTION_EVENT_ACTION_POINTER_UP){
  245. //Onepointerwentup.
  246. if(isSplit){
  247. int32_tpointerIndex=getMotionEventActionPointerIndex(action);
  248. uint32_tpointerId=entry->pointerIds[pointerIndex];
  249. for(size_ti=0;i<mTempTouchState.windows.size();){
  250. TouchedWindow&touchedWindow=mTempTouchState.windows.editItemAt(i);
  251. if(touchedWindow.targetFlags&InputTarget::FLAG_SPLIT){
  252. touchedWindow.pointerIds.clearBit(pointerId);
  253. if(touchedWindow.pointerIds.isEmpty()){
  254. mTempTouchState.windows.removeAt(i);
  255. continue;
  256. }
  257. }
  258. i+=1;
  259. }
  260. }
  261. }
  262. //Savechangestotouchstate.
  263. mTouchState.copyFrom(mTempTouchState);
  264. }else{
  265. #ifDEBUG_FOCUS
  266. LOGD("Notupdatingtouchfocusbecauseinjectionwasdenied.");
  267. #endif
  268. }
  269. Unresponsive:
  270. //Resettemporarytouchstatetoensurewereleaseunnecessaryreferencestoinputchannels.
  271. mTempTouchState.reset();
  272. nsecs_ttimeSpentWaitingForApplication=getTimeSpentWaitingForApplicationLocked(currentTime);
  273. updateDispatchStatisticsLocked(currentTime,entry,
  274. injectionResult,timeSpentWaitingForApplication);
  275. #ifDEBUG_FOCUS
  276. LOGD("findTouchedWindowfinished:injectionResult=%d,injectionPermission=%d,"
  277. "timeSpentWaitingForApplication=%0.1fms",
  278. injectionResult,injectionPermission,timeSpentWaitingForApplication/1000000.0);
  279. #endif
  280. returninjectionResult;
  281. }

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

Cpp代码
  1. if(window->visible){
  2. if(!(flags&InputWindow::FLAG_NOT_TOUCHABLE)){
  3. boolisTouchModal=(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;//foundtouchedwindow,exitwindowloop
  10. }
  11. }
  12. if(maskedAction==AMOTION_EVENT_ACTION_DOWN
  13. &&(flags&InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)){
  14. int32_toutsideTargetFlags=InputTarget::FLAG_OUTSIDE;
  15. if(isWindowObscuredAtPointLocked(window,x,y)){
  16. outsideTargetFlags|=InputTarget::FLAG_WINDOW_IS_OBSCURED;
  17. }
  18. mTempTouchState.addOrUpdateWindow(window,outsideTargetFlags,BitSet32(0));
  19. }
  20. }

Java代码
  1. //Focustrackingfortouch.
  2. structTouchedWindow{
  3. constInputWindow*window;
  4. int32_ttargetFlags;
  5. BitSet32pointerIds;
  6. sp<InputChannel>channel;
  7. };
  8. structTouchState{
  9. booldown;
  10. boolsplit;
  11. Vector<TouchedWindow>windows;
  12. TouchState();
  13. ~TouchState();
  14. voidreset();
  15. voidcopyFrom(constTouchState&other);
  16. voidaddOrUpdateWindow(constInputWindow*window,int32_ttargetFlags,BitSet32pointerIds);
  17. voidremoveOutsideTouchWindows();
  18. constInputWindow*getFirstForegroundWindow();
  19. };
  20. 另外如何定义按键和其他触屏焦点的:
  21. /*Updatesthecachedwindowinformationprovidedtotheinputdispatcher.*/
  22. publicvoidupdateInputWindowsLw(){
  23. //Populatetheinputwindowlistwithinformationaboutallofthewindowsthat
  24. //couldpotentiallyreceiveinput.
  25. //Asanoptimization,wecouldtrytoprunethelistofwindowsbutthisturns
  26. //outtobedifficultbecauseonlythenativecodeknowsforsurewhichwindow
  27. //currentlyhastouchfocus.
  28. finalArrayList<WindowState>windows=mWindows;
  29. finalintN=windows.size();
  30. for(inti=N-1;i>=0;i--){
  31. finalWindowStatechild=windows.get(i);
  32. if(child.mInputChannel==null||child.mRemoved){
  33. //Skipthiswindowbecauseitcannotpossiblyreceiveinput.
  34. continue;
  35. }
  36. finalintflags=child.mAttrs.flags;
  37. finalinttype=child.mAttrs.type;
  38. <spanstyle="color:#ff6600;">finalbooleanhasFocus=(child==mInputFocus);</span>
  39. //本行代码确定,一次性的focusWindow只有一个。
  40. finalbooleanisVisible=child.isVisibleLw();
  41. finalbooleanhasWallpaper=(child==mWallpaperTarget)
  42. &&(type!=WindowManager.LayoutParams.TYPE_KEYGUARD);

更多相关文章

  1. Android(安卓)特殊用法--来自中国移动开发社区
  2. 菜鸟学Android开发系列之:发送短信拨打电话
  3. 〖Android〗/system/etc/event-log-tags
  4. Android(安卓)progressBar代码设置进度条颜色、背景颜色以及圆角
  5. 求 在独立service 中 调用contentprovider的方法
  6. Android实现系统打印功能
  7. Android(安卓)中的BroadCastReceiver
  8. Android(安卓)- Handler is abstract, cannot be instantiated.
  9. 查询存储空间的代码

随机推荐

  1. Android与H5互调详细介绍
  2. Android之网络丢包事件
  3. Android(安卓)扫码盒子全局接收付款码
  4. Android之网络丢包事件
  5. Android的多任务之路
  6. Android采用HTML设计软件界面
  7. Android系统体系结构
  8. android的makefile分析
  9. Android普及入门
  10. Google:Android(安卓)2.3在所有Android系