记不住密码怎么办?

http://a.app.qq.com/o/simple.jsp?pkgname=com.wa505.kf.epassword

一个是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;
}

void InputDispatcher::dispatchOnce() {nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();nsecs_t nextWakeupTime = LONG_LONG_MAX;{ // acquire lockAutoMutex _l(mLock);dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);if (runCommandsLockedInterruptible()) {nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately}} // release lock// Wait for callback or timeout or wake.  (make sure we round up, not down)nsecs_t currentTime = now();int32_t timeoutMillis;if (nextWakeupTime > currentTime) {uint64_t timeout = uint64_t(nextWakeupTime - currentTime);timeout = (timeout + 999999LL) / 1000000LL;timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);} else {timeoutMillis = 0;}mLooper->pollOnce(timeoutMillis);
}
    case EventEntry::TYPE_MOTION: {MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {dropReason = DROP_REASON_APP_SWITCH;}done = dispatchMotionLocked(currentTime, typedEntry,&dropReason, nextWakeupTime);break;
bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {// Preprocessing.if (! entry->dispatchInProgress) {entry->dispatchInProgress = true;resetTargetsLocked();logOutboundMotionDetailsLocked("dispatchMotion - ", entry);}// Clean up if dropping the event.if (*dropReason != DROP_REASON_NOT_DROPPED) {resetTargetsLocked();setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);return true;}bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;// Identify targets.if (! mCurrentInputTargetsValid) {int32_t injectionResult;if (isPointerEvent) {// Pointer event.  (eg. touchscreen)injectionResult = findTouchedWindowTargetsLocked(currentTime,entry, nextWakeupTime);} else {// Non touch event.  (eg. trackball)injectionResult = findFocusedWindowTargetsLocked(currentTime,entry, nextWakeupTime);}if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {return false;}setInjectionResultLocked(entry, injectionResult);if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {return true;}addMonitoringTargetsLocked();commitTargetsLocked();}// Dispatch the motion.dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);return true;
}
startDispatchCycleLocked 中的方法status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,xOffset, yOffset,motionEntry->xPrecision, motionEntry->yPrecision,motionEntry->downTime, firstMotionSample->eventTime,motionEntry->pointerCount, motionEntry->pointerIds,firstMotionSample->pointerCoords);
ViewRoot有个InputHandler
    private final InputHandler mInputHandler = new InputHandler() {public void handleKey(KeyEvent event, Runnable finishedCallback) {startInputEvent(finishedCallback);dispatchKey(event, true);}public void handleMotion(MotionEvent event, Runnable finishedCallback) {startInputEvent(finishedCallback);dispatchMotion(event, true);}};

InputHandler注册给了系统

 InputQueue.registerInputChannel(mInputChannel, mInputHandler,Looper.myQueue());
 dispatchMotion(event, true);方法如下
private void dispatchMotion(MotionEvent event, boolean sendDone) {int source = event.getSource();if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {dispatchPointer(event, sendDone);} else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {dispatchTrackball(event, sendDone);} else {// TODOLog.v(TAG, "Dropping unsupported motion event (unimplemented): " + event);if (sendDone) {finishInputEvent();}}} 

调用了dispatchPointer

ViewRoot本身就是Handler直接sendMessageAtTime

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

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

InputDisapatcher.cpp中调用了如下方法dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,true /*resumeWithAppendedMotionSample*/);

然后

dispatchEventToCurrentInputTargetsLocked

调用了如下方法

int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,const EventEntry* entry, nsecs_t* nextWakeupTime) {mCurrentInputTargets.clear();int32_t injectionResult;// If there is no currently focused window and no focused application// then drop the event.if (! mFocusedWindow) {if (mFocusedApplication) {
#if DEBUG_FOCUSLOGD("Waiting because there is no focused window but there is a ""focused application that may eventually add a window: %s.",getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
#endifinjectionResult = handleTargetsNotReadyLocked(currentTime, entry,mFocusedApplication, NULL, nextWakeupTime);goto Unresponsive;}LOGI("Dropping event because there is no focused window or focused application.");injectionResult = INPUT_EVENT_INJECTION_FAILED;goto Failed;}// Check permissions.if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;goto Failed;}// If the currently focused window is paused then keep waiting.if (mFocusedWindow->paused) {
#if DEBUG_FOCUSLOGD("Waiting because focused window is paused.");
#endifinjectionResult = handleTargetsNotReadyLocked(currentTime, entry,mFocusedApplication, mFocusedWindow, nextWakeupTime);goto Unresponsive;}// If the currently focused window is still working on previous events then keep waiting.if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
#if DEBUG_FOCUSLOGD("Waiting because focused window still processing previous input.");
#endifinjectionResult = handleTargetsNotReadyLocked(currentTime, entry,mFocusedApplication, mFocusedWindow, nextWakeupTime);goto Unresponsive;}// Success!  Output targets.injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));// Done.
Failed:
Unresponsive:nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);updateDispatchStatisticsLocked(currentTime, entry,injectionResult, timeSpentWaitingForApplication);
#if DEBUG_FOCUSLOGD("findFocusedWindow finished: injectionResult=%d, ""timeSpendWaitingForApplication=%0.1fms",injectionResult, timeSpentWaitingForApplication / 1000000.0);
#endifreturn injectionResult;
}

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

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

 /* Updates the cached window information provided to the input dispatcher. */public void updateInputWindowsLw() {// Populate the input window list with information about all of the windows that// could potentially receive input.// As an optimization, we could try to prune the list of windows but this turns// out to be difficult because only the native code knows for sure which window// currently has touch focus.final ArrayList<WindowState> windows = mWindows;final int N = windows.size();for (int i = N - 1; i >= 0; i--) {final WindowState child = windows.get(i);if (child.mInputChannel == null || child.mRemoved) {// Skip this window because it cannot possibly receive input.continue;}final int flags = child.mAttrs.flags;final int type = child.mAttrs.type;final boolean hasFocus = (child == mInputFocus);final boolean isVisible = child.isVisibleLw();final boolean hasWallpaper = (child == mWallpaperTarget)&& (type != WindowManager.LayoutParams.TYPE_KEYGUARD);// Add a window to our list of input windows.final InputWindow inputWindow = mTempInputWindows.add();inputWindow.inputChannel = child.mInputChannel;inputWindow.name = child.toString();inputWindow.layoutParamsFlags = flags;inputWindow.layoutParamsType = type;inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();inputWindow.visible = isVisible;inputWindow.canReceiveKeys = child.canReceiveKeys();inputWindow.hasFocus = hasFocus;inputWindow.hasWallpaper = hasWallpaper;inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;inputWindow.layer = child.mLayer;inputWindow.ownerPid = child.mSession.mPid;inputWindow.ownerUid = child.mSession.mUid;final Rect frame = child.mFrame;inputWindow.frameLeft = frame.left;inputWindow.frameTop = frame.top;inputWindow.frameRight = frame.right;inputWindow.frameBottom = frame.bottom;final Rect visibleFrame = child.mVisibleFrame;inputWindow.visibleFrameLeft = visibleFrame.left;inputWindow.visibleFrameTop = visibleFrame.top;inputWindow.visibleFrameRight = visibleFrame.right;inputWindow.visibleFrameBottom = visibleFrame.bottom;switch (child.mTouchableInsets) {default:case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:inputWindow.touchableAreaLeft = frame.left;inputWindow.touchableAreaTop = frame.top;inputWindow.touchableAreaRight = frame.right;inputWindow.touchableAreaBottom = frame.bottom;break;case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {Rect inset = child.mGivenContentInsets;inputWindow.touchableAreaLeft = frame.left + inset.left;inputWindow.touchableAreaTop = frame.top + inset.top;inputWindow.touchableAreaRight = frame.right - inset.right;inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;break;}case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {Rect inset = child.mGivenVisibleInsets;inputWindow.touchableAreaLeft = frame.left + inset.left;inputWindow.touchableAreaTop = frame.top + inset.top;inputWindow.touchableAreaRight = frame.right - inset.right;inputWindow.touchableAreaBottom = frame.bottom - inset.bottom;break;}}}// Send windows to native code.mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());// Clear the list in preparation for the next round.// Also avoids keeping InputChannel objects referenced unnecessarily.mTempInputWindows.clear();}

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

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

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

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

int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,const MotionEntry* entry, nsecs_t* nextWakeupTime) {enum InjectionPermission {INJECTION_PERMISSION_UNKNOWN,INJECTION_PERMISSION_GRANTED,INJECTION_PERMISSION_DENIED};mCurrentInputTargets.clear();nsecs_t startTime = now();// For security reasons, we defer updating the touch state until we are sure that// event injection will be allowed.//// FIXME In the original code, screenWasOff could never be set to true.//       The reason is that the POLICY_FLAG_WOKE_HERE//       and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw//       EV_KEY, EV_REL and EV_ABS events.  As it happens, the touch event was//       actually enqueued using the policyFlags that appeared in the final EV_SYN//       events upon which no preprocessing took place.  So policyFlags was always 0.//       In the new native input dispatcher we're a bit more careful about event//       preprocessing so the touches we receive can actually have non-zero policyFlags.//       Unfortunately we obtain undesirable behavior.////       Here's what happens:////       When the device dims in anticipation of going to sleep, touches//       in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause//       the device to brighten and reset the user activity timer.//       Touches on other windows (such as the launcher window)//       are dropped.  Then after a moment, the device goes to sleep.  Oops.////       Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE//       instead of POLICY_FLAG_WOKE_HERE...//bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;int32_t action = entry->action;int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;// Update the touch state as needed based on the properties of the touch event.int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {mTempTouchState.reset();mTempTouchState.down = true;} else {mTempTouchState.copyFrom(mTouchState);}bool isSplit = mTempTouchState.split && mTempTouchState.down;if (maskedAction == AMOTION_EVENT_ACTION_DOWN|| (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {/* Case 1: New splittable pointer going down. */int32_t pointerIndex = getMotionEventActionPointerIndex(action);int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);const InputWindow* newTouchedWindow = NULL;const InputWindow* topErrorWindow = NULL;// Traverse windows from front to back to find touched window and outside targets.size_t numWindows = mWindows.size();for (size_t i = 0; i < numWindows; i++) {const InputWindow* window = & mWindows.editItemAt(i);int32_t flags = window->layoutParamsFlags;if (flags & InputWindow::FLAG_SYSTEM_ERROR) {if (! topErrorWindow) {topErrorWindow = window;}}if (window->visible) {if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE| InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {newTouchedWindow = window;}break; // found touched window, exit window loop}}if (maskedAction == AMOTION_EVENT_ACTION_DOWN&& (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;if (isWindowObscuredAtPointLocked(window, x, y)) {outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;}mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));}}}// If there is an error window but it is not taking focus (typically because// it is invisible) then wait for it.  Any other focused window may in// fact be in ANR state.if (topErrorWindow && newTouchedWindow != topErrorWindow) {
#if DEBUG_FOCUSLOGD("Waiting because system error window is pending.");
#endifinjectionResult = handleTargetsNotReadyLocked(currentTime, entry,NULL, NULL, nextWakeupTime);injectionPermission = INJECTION_PERMISSION_UNKNOWN;goto Unresponsive;}// Figure out whether splitting will be allowed for this window.if (newTouchedWindow&& (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {// New window supports splitting.isSplit = true;} else if (isSplit) {// New window does not support splitting but we have already split events.// Assign the pointer to the first foreground window we find.// (May be NULL which is why we put this code block before the next check.)newTouchedWindow = mTempTouchState.getFirstForegroundWindow();}// If we did not find a touched window then fail.if (! newTouchedWindow) {if (mFocusedApplication) {
#if DEBUG_FOCUSLOGD("Waiting because there is no touched window but there is a ""focused application that may eventually add a new window: %s.",getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
#endifinjectionResult = handleTargetsNotReadyLocked(currentTime, entry,mFocusedApplication, NULL, nextWakeupTime);goto Unresponsive;}LOGI("Dropping event because there is no touched window or focused application.");injectionResult = INPUT_EVENT_INJECTION_FAILED;goto Failed;}// Set target flags.int32_t targetFlags = InputTarget::FLAG_FOREGROUND;if (isSplit) {targetFlags |= InputTarget::FLAG_SPLIT;}if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;}// Update the temporary touch state.BitSet32 pointerIds;if (isSplit) {uint32_t pointerId = entry->pointerIds[pointerIndex];pointerIds.markBit(pointerId);}mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);} else {/* Case 2: Pointer move, up, cancel or non-splittable pointer down. */// If the pointer is not currently down, then ignore the event.if (! mTempTouchState.down) {LOGI("Dropping event because the pointer is not down.");injectionResult = INPUT_EVENT_INJECTION_FAILED;goto Failed;}}// Check permission to inject into all touched foreground windows and ensure there// is at least one touched foreground window.{bool haveForegroundWindow = false;for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {const TouchedWindow& touchedWindow = mTempTouchState.windows[i];if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {haveForegroundWindow = true;if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;injectionPermission = INJECTION_PERMISSION_DENIED;goto Failed;}}}if (! haveForegroundWindow) {
#if DEBUG_INPUT_DISPATCHER_POLICYLOGD("Dropping event because there is no touched foreground window to receive it.");
#endifinjectionResult = INPUT_EVENT_INJECTION_FAILED;goto Failed;}// Permission granted to injection into all touched foreground windows.injectionPermission = INJECTION_PERMISSION_GRANTED;}// Ensure all touched foreground windows are ready for new input.for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {const TouchedWindow& touchedWindow = mTempTouchState.windows[i];if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {// If the touched window is paused then keep waiting.if (touchedWindow.window->paused) {
#if DEBUG_INPUT_DISPATCHER_POLICYLOGD("Waiting because touched window is paused.");
#endifinjectionResult = handleTargetsNotReadyLocked(currentTime, entry,NULL, touchedWindow.window, nextWakeupTime);goto Unresponsive;}// If the touched window is still working on previous events then keep waiting.if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
#if DEBUG_FOCUSLOGD("Waiting because touched window still processing previous input.");
#endifinjectionResult = handleTargetsNotReadyLocked(currentTime, entry,NULL, touchedWindow.window, nextWakeupTime);goto Unresponsive;}}}// If this is the first pointer going down and the touched window has a wallpaper// then also add the touched wallpaper windows so they are locked in for the duration// of the touch gesture.if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();if (foregroundWindow->hasWallpaper) {for (size_t i = 0; i < mWindows.size(); i++) {const InputWindow* window = & mWindows[i];if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {mTempTouchState.addOrUpdateWindow(window,InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));}}}}// Success!  Output targets.injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,touchedWindow.pointerIds);}// Drop the outside touch window since we will not care about them in the next iteration.mTempTouchState.removeOutsideTouchWindows();Failed:// Check injection permission once and for all.if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {if (checkInjectionPermission(NULL, entry->injectionState)) {injectionPermission = INJECTION_PERMISSION_GRANTED;} else {injectionPermission = INJECTION_PERMISSION_DENIED;}}// Update final pieces of touch state if the injector had permission.if (injectionPermission == INJECTION_PERMISSION_GRANTED) {if (maskedAction == AMOTION_EVENT_ACTION_UP|| maskedAction == AMOTION_EVENT_ACTION_CANCEL) {// All pointers up or canceled.mTempTouchState.reset();} else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {// First pointer went down.if (mTouchState.down) {
#if DEBUG_FOCUSLOGD("Pointer down received while already down.");
#endif}} else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {// One pointer went up.if (isSplit) {int32_t pointerIndex = getMotionEventActionPointerIndex(action);uint32_t pointerId = entry->pointerIds[pointerIndex];for (size_t i = 0; i < mTempTouchState.windows.size(); ) {TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {touchedWindow.pointerIds.clearBit(pointerId);if (touchedWindow.pointerIds.isEmpty()) {mTempTouchState.windows.removeAt(i);continue;}}i += 1;}}}// Save changes to touch state.mTouchState.copyFrom(mTempTouchState);} else {
#if DEBUG_FOCUSLOGD("Not updating touch focus because injection was denied.");
#endif}Unresponsive:// Reset temporary touch state to ensure we release unnecessary references to input channels.mTempTouchState.reset();nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);updateDispatchStatisticsLocked(currentTime, entry,injectionResult, timeSpentWaitingForApplication);
#if DEBUG_FOCUSLOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, ""timeSpentWaitingForApplication=%0.1fms",injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
#endifreturn injectionResult;
}

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

  if (window->visible) {  if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {  bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE  | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;  if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {  if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {  newTouchedWindow = window;  }  break; // found touched window, exit window loop  }  }  if (maskedAction == AMOTION_EVENT_ACTION_DOWN  && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {  int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;  if (isWindowObscuredAtPointLocked(window, x, y)) {  outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;  }  mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));  }  }  
 // Focus tracking for touch.struct TouchedWindow {const InputWindow* window;int32_t targetFlags;BitSet32 pointerIds;sp<InputChannel> channel;};struct TouchState {bool down;bool split;Vector<TouchedWindow> windows;TouchState();~TouchState();void reset();void copyFrom(const TouchState& other);void addOrUpdateWindow(const InputWindow* window, int32_t targetFlags, BitSet32 pointerIds);void removeOutsideTouchWindows();const InputWindow* getFirstForegroundWindow();};另外如何定义按键和其他触屏焦点的:/* Updates the cached window information provided to the input dispatcher. */public void updateInputWindowsLw() {// Populate the input window list with information about all of the windows that// could potentially receive input.// As an optimization, we could try to prune the list of windows but this turns// out to be difficult because only the native code knows for sure which window// currently has touch focus.final ArrayList<WindowState> windows = mWindows;final int N = windows.size();for (int i = N - 1; i >= 0; i--) {final WindowState child = windows.get(i);if (child.mInputChannel == null || child.mRemoved) {// Skip this window because it cannot possibly receive input.continue;}final int flags = child.mAttrs.flags;final int type = child.mAttrs.type; final boolean hasFocus = (child == mInputFocus);
//本行代码确定,一次性的focusWindow只有一个。final boolean isVisible = child.isVisibleLw();final boolean hasWallpaper = (child == mWallpaperTarget)&& (type != WindowManager.LayoutParams.TYPE_KEYGUARD);

记不住密码怎么办?

http://a.app.qq.com/o/simple.jsp?pkgname=com.wa505.kf.epassword

Android输入输出系统之TouchEvent流程相关推荐

  1. [置顶] Android输入输出系统之TouchEvent流程

    记不住密码怎么办? http://a.app.qq.com/o/simple.jsp?pkgname=com.wa505.kf.epassword 一个是InputReader,一个是InputDis ...

  2. X210 Android wince 系统烧写流程

    Android系统烧写 1.        制作SD卡启动工具: 1)        打开PartitionManager.exe工具,右键可移动磁盘,点击删除分区,SD卡就只剩一个分区,再右键点击分 ...

  3. android手机系统的启动流程-secureboot流程(以MTK平台为例)

    ★★★ 个人博客导读首页-点击此处 ★★★ MTK平台下的secureboot流程图: 镜像的验证方法:

  4. 计算机组成原理起始位,计算机组成原理第5章(输入输出系统).ppt

    文档介绍: 第五章输入输出系统5.6DMA方式5.5程序中断方式5.4程序查询方式5.3I/O接口5.2外部设备5.1概述辐滤咎尝迅香膜巍辆苞婉绒偶手赘柿基琉硕跑例退佰豆绽蛹姨亮柬鸳行爸计算机组成原理 ...

  5. Android系统的启动流程简要分析

    这是我结合网上的资料以及自己分析android4.4的源码整理的笔记,对整个安卓系统的流程启动进行了梳理,很多细节并未展开,只是简要的进行了介绍. 一.Android系统的架构介绍 Android的整 ...

  6. 结合源码探讨Android系统的启动流程

    结合源码探讨Android系统的启动流程 由于本人能力有限,所考虑或者疏忽错漏的地方或多或少应该存在.同时,Android从启动过程开始,实际上就涉及多个技术难点和多种通信机制的知识点. 基于上面两个 ...

  7. Android系统 lk启动流程简析

    本篇文章是对初步学习Android系统lk启动流程的一个大致简介.方便掌握lk启动流程的大致框架,具体细节后续再进行更新 1. 前言 需要了解的文件类型: 1)编译LK的链接文件(.ld) 2)汇编文 ...

  8. Android图形显示系统——一张图片的显示流程

    Android设备上一张图片的显示过程 应用示例 假如我们现在有一张这样的风景照 想在Android设备(比如一个小米pad)上显示出来.首先想到的是写一个应用,用一个ImageView,把这张照片附 ...

  9. android系统浏览器下载流程

    android系统浏览器下载流程 标签: android browser download 简介 当我们用浏览器点开一个下载链接,然后去下载,从宏观上认识,有下载进度的实时更新和界面的跳转.整个过程中 ...

最新文章

  1. Spring Boot 中 @EnableXXX 注解的驱动逻辑
  2. 项目中的一个AOP的编写案例(配置+案例)
  3. Oracle 11gR2 RAC 中的 Grid Plug and Play(GPnP) 是什么?
  4. postman mysql_postman连接mysql执行操作
  5. 05Vue.js快速入门-Vue实例详解与生命周期
  6. 2018web前端面试题总结
  7. 揭秘在召唤师峡谷中移动路径选择逻辑?
  8. 06-在IDEA中实战Git
  9. GO语言的进阶之路-Golang高级数据结构定义
  10. element中form表单resetFields()方法重置表单无效
  11. 推荐一下干货-------为什么你的app不耐看
  12. C++ 课设 职工工资管理系统
  13. HTML美化页面(下)
  14. 八类网线和七类网线的区别_七类网线和六类网线区别有哪些
  15. 大数据服务器环境准备(三台服务)
  16. Dr.com校园网客户端故障解决方法
  17. 从SNP_VCF文件提取SNV
  18. UE4:转换成VR项目
  19. 单片机c语言编写一个时钟程序,单片机基于c语言编写时钟.doc
  20. matlab计算胎心率,基于盲分离的胎心音心率检测算法与实现

热门文章

  1. alt+数字 符号大全_【BIM工具箱】Revit中特殊符号大全和输入技巧
  2. 怎么做圆一圈圈扩散效果_推广为什么没有效果,网络推广怎么做才有效果?
  3. spark和python的关系_spark submit和pyspark有什么区别?
  4. 量子不可克隆 计算机,量子不可克隆证明及推理
  5. C++ string类型与数值型变量的相互转换
  6. matlab 中调用s函数表达式,[求助]S函数中能否调用M函数
  7. C++知识点1——基础
  8. java plc通讯_树莓派+西门子PLC+Aliyun
  9. java 定时_结合真实案例,清晰梳理几种定时任务的退出「JAVA并发」
  10. shell脚本按行读取文件的几种方式