设备加入
- EventHub检测到设备加入(getEvents)
- if (eventItem.data.u32 == EPOLL_ID_INOTIFY)
- mPendingINotify = true【延迟到其他事件后处理】
- if (mPendingINotify && mPendingEventIndex >= mPendingEventCount)【其他事件处理完了 】
- mPendingINotify = false
- readNotifyLocked()
- read()【读取inotify句柄】
- if(event->mask & IN_CREATE)
- openDeviceLocked()
- EventHub打开设备(openDeviceLocked)
- open()【打开设备文件】
- ioctl()【读取名字,EVIOCGNAME】
- 检查是否排除(mExcludedDevices)
- close()【如果是,关闭设备文件】
- 读取设备信息
- ioctl()【读取设备驱动版本,EVIOCGVERSION】
- ioctl()【读取设备input_id,包括总线、产品号、厂商、版本,EVIOCGID】
- ioctl()【读取设备硬件位置,EVIOCGPHYS】
- ioctl()【读取设备GUID,EVIOCGUNIQ】
- setDescriptor()【计算descriptor,用sha1作用于几个字段的组合】
- fcntl()【设置非阻塞,F_SETFL】
- new Device【deviceId=mNextDeviceId++】
- loadConfigurationLocked()【加载设备配置,*.idc文件】
- getInputDeviceConfigurationFilePathByDeviceIdentifier()【libinput】
- PropertyMap::load()【解析配置文件】
- 检查设备的输入事件类型
- ioctl()【EVIOCGBIT,EV_KEY、EV_ABS、EV_REL、EV_SW、EV_LED、EV_FF】
- ioctl()【EVIOCGPROP】
- 【判断设备的类别,比如INPUT_DEVICE_CLASS_KEYBOARD】
- haveKeyboardKeys【keyBitmask:0~BTN_MISC,KEY_OK~KEY_MAX+1】
- haveGamepadButtons【keyBitmask:BTN_MISC~BTN_MOUSE,BTN_JOYSTICK~BTN_DIGI,两组游戏杆按钮】
- haveKeyboardKeys || haveGamepadButtons
- classes |= INPUT_DEVICE_CLASS_KEYBOARD
- BTN_MOUSE && REL_X && REL_Y
- classes |= INPUT_DEVICE_CLASS_CURSOR
- if (classes & INPUT_DEVICE_CLASS_TOUCH)
- loadVirtualKeyMapLocked()
- VirtualKeyMap::load(/sys/board_properties/virtualkeys.<name>)
- 【如果失败】
- classes |= INPUT_DEVICE_CLASS_KEYBOARD
- loadVirtualKeyMapLocked()
- if (classes & (INPUT_DEVICE_CLASS_KEYBOARD|INPUT_DEVICE_CLASS_JOYSTICK))
- loadKeyMapLocked()
- keyMap.load()【加载*.kl,*.kcm】
- loadKeyMapLocked()
- if (classes & INPUT_DEVICE_CLASS_KEYBOARD)
- isEligibleBuiltInKeyboard()
- mBuiltInKeyboardId = id 【第一个,只有一个内建输入设备】
- hasKeycodeLocked(AKEYCODE_Q)(由AKC反向查找LKC集,并且keyBitmask至少有LKC集里面一个)
- classes |= INPUT_DEVICE_CLASS_ALPHAKEY
- ioctl()【禁止内核重复key事件,EVIOCSREP】
- isExternalDeviceLocked()(${device.internal},BUS_USB、BUS_BLUETOOTH)
- classes |= INPUT_DEVICE_CLASS_EXTERNAL
- if (classes & (INPUT_DEVICE_CLASS_JOYSTICK|INPUT_DEVICE_CLASS_GAMEPAD))
- controllerNumber = getNextControllerNumberLocked()
- epoll_ctl()(注册到epoll池中)
- ioctl()【设置唤醒锁,EVIOCSSUSPENDBLOCK】
- ioctl()【设置时间戳使用monotonic时钟,EVIOCSCLOCKID】
- addDeviceLocked()(添加设备)
- mDevices.add()
- mOpeningDevices【加入正在打开的设备列表,单向链表】
- EventHub返回设备加入事件(getEvents)
- while (mOpeningDevices != NULL)
- event = ??
- event += 1
- mNeedToSendFinishedDeviceScan = true
- if (mNeedToSendFinishedDeviceScan)
- event = ??
- event += 1
- InputReader处理设备增加事件(loopOnce)
- mEventHub->getEvents()
- processEventsLocked()
- if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT)
- else
- switch (rawEvent->type)
- case EventHubInterface::DEVICE_ADDED
- addDeviceLocked()
- case EventHubInterface::DEVICE_ADDED
- switch (rawEvent->type)
- InputReader增加设备(addDeviceLocked)
- createDeviceLocked()
- new InputDevice
- if (classes & INPUT_DEVICE_CLASS_SWITCH)
- device->addMapper(new SwitchInputMapper)
- if (classes & INPUT_DEVICE_CLASS_VIBRATOR)
- device->addMapper(new VibratorInputMapper)
- 转换classes到keyboardSource和keyboardType
- if (keyboardSource != 0)
- device->addMapper(new KeyboardInputMapper)
- if (classes & INPUT_DEVICE_CLASS_CURSOR)
- device->addMapper(new CursorInputMapper)
- if (classes & INPUT_DEVICE_CLASS_TOUCH_MT)
- device->addMapper(new MultiTouchInputMapper)
- else if (classes & INPUT_DEVICE_CLASS_TOUCH)
- device->addMapper(new SingleTouchInputMapper)
- if (classes & INPUT_DEVICE_CLASS_JOYSTICK)
- device->addMapper(new JoystickInputMapper)
- mDevices.add()
- bumpGenerationLocked()
- ++mGeneration
- InputReader增加设备后续处理(loopOnce)
- if (oldGeneration != mGeneration)
- inputDevicesChanged = true
- getInputDevicesLocked(inputDevices)【获取所有设备信息】
- forall mDevices()
- device->getDeviceInfo()【填充InputDeviceInfo结构】
- forall mMappers
- mapper->populateDeviceInfo()
- forall mMappers
- device->getDeviceInfo()【填充InputDeviceInfo结构】
- forall mDevices()
- if (inputDevicesChanged)
- mPolicy->notifyInputDevicesChanged【InputReaderPolicyInterface】
设备删除
- EventHub检测到设备加入(getEvents)
- if (eventItem.data.u32 == EPOLL_ID_INOTIFY)
- mPendingINotify = true【延迟到其他事件后处理】
- if (mPendingINotify && mPendingEventIndex >= mPendingEventCount)【其他事件处理完成】
- mPendingINotify = false
- readNotifyLocked()
- read()
- if(event->mask & IN_CREATE)
- else
- closeDeviceByPathLocked()
- getDeviceByPathLocked()
- closeDeviceLocked()
- closeDeviceByPathLocked()
- EventHub关闭设备(closeDeviceLocked)
- if (device->id == mBuiltInKeyboardId)
- mBuiltInKeyboardId = NO_BUILT_IN_KEYBOARD
- if (!device->isVirtual())【fd < 0】
- epoll_ctl()【从epoll池中,EPOLL_CTL_DEL】
- releaseControllerNumberLocked()
- mDevices.removeItem()
- device->close()
- ::close()
- mOpeningDevices()【从正在打开列表中删除】
- mClosingDevices()【进入正在关闭列表,单向链表】
- EventHub返回设备删除事件(getEvents)
- while (mClosingDevices)
- event = ??
- event += 1
- mNeedToSendFinishedDeviceScan = true
- if (mNeedToSendFinishedDeviceScan)
- event = ??
- event += 1
- InputReader处理设备删除事件(loopOnce)
- mEventHub->getEvents()
- processEventsLocked()
- if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT)
- else
- switch (rawEvent->type)
- case EventHubInterface::DEVICE_REMOVED
- removeDeviceLocked()
- case EventHubInterface::DEVICE_REMOVED
- switch (rawEvent->type)
- InputReader删除设备(removeDeviceLocked)
- mDevices.removeItemsAt()
- bumpGenerationLocked()
- ++mGeneration
- device->reset()【重置设备】
- forall mMappers
- mapper->reset()
- mContext->updateGlobalMetaState()【更新GlobalMetaState】
- InputReader::updateGlobalMetaStateLocked()
- forall mDevices
- mGlobalMetaState |= device->getMetaState()
- forall mDevices
- InputReader::updateGlobalMetaStateLocked()
- notifyReset()【增加设备重置事件】
- mContext->getListener()->notifyDeviceReset()
- QueuedInputListener->notifyDeviceReset()
- mArgsQueue.push(new NotifyDeviceResetArgs()
- QueuedInputListener->notifyDeviceReset()
- mContext->getListener()->notifyDeviceReset()
- forall mMappers
- delete device
- InputReader删除设备后续处理(loopOnce)
- if (oldGeneration != mGeneration)
- inputDevicesChanged = true
- getInputDevicesLocked(inputDevices)【获取所有设备信息】
- if (inputDevicesChanged)
- mPolicy->notifyInputDevicesChanged()【InputReaderPolicyInterface】
输入事件(Native层)
- EventHub收到设备输入事件(getEvents)
- mDevices.indexOfKey()
- mDevices.valueAt()
- if (eventItem.events & EPOLLHUP)
- read()【读取设备输入事件,事件数不超过剩余空间】
- if (errno == ENODEV)
- deviceChanged = true
- closeDeviceLocked()
- else
- event = ??
- event += 1
- else if (eventItem.events & EPOLLHUP)
- deviceChanged = true
- closeDeviceLocked()
- InputReader处理设备输入事件(loopOnce)
- mEventHub->getEvents()【步骤一】
- processEventsLocked()
- if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT)
- batchSize【搜索后续相同设备的输入事件】
- processEventsForDeviceLocked()
- mDevices.valueAt()【工具id查找设备】
- device->process()【InputDevice, 步骤三】
- mQueuedListener->flush()
- foreach mArgsQueue【针对事件一个个回调】
- args->notify
- InputListenerInterface->notify*(InputDispatcher)
- args->notify
- foreach mArgsQueue【针对事件一个个回调】
- if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT)
- InputDevice处理设备输入事件(process)
- if (mDropUntilNextSync)【SYN_DROPPED到SYN_REPORT全部丢弃】
- if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT)
- mDropUntilNextSync = false
- if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT)
- else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED)
- mDropUntilNextSync = true
- reset()【状态重置,见流程“设备删除”】
- else
- forall mMappers【设备上的所有Mapper处理】
- mapper->process()【累积事件直到EV_SYN/SYN_REPORT】
- getListener()->notify*()【QueuedInputListener排队】
- mapper->process()【累积事件直到EV_SYN/SYN_REPORT】
- forall mMappers【设备上的所有Mapper处理】
- InputDispatcher排队输入事件
- notifyKey()【键击事件】
- KeyEvent.initialize()
- mPolicy->interceptKeyBeforeQueueing()【策略预处理】
- if (shouldSendKeyToInputFilterLocked)【mInputFilterEnabled】
- if (!mPolicy->filterInputEvent)
- return
- if (!mPolicy->filterInputEvent)
- new KeyEntry【创建一个键击事件节点】
- enqueueInboundEventLocked()【插入队列,返回是否需要唤醒,needWake】
- mInboundQueue.isEmpty()【如果队列原来为空,唤醒,needWake】
- mInboundQueue.enqueueAtTail()
- isAppSwitchKeyEventLocked()【如果应用切换,唤醒】
- findTouchedWindowAtLocked()【如果触摸另一个应用窗口,唤醒】
- if (needWake)
- mLooper->wake(唤醒分派线程)
- notifyMotion()【移动事件】
- mPolicy->interceptMotionBeforeQueueing()【策略预处理】
- if (shouldSendMotionToInputFilterLocked)
- MotionEvent.initialize()
- if (!mPolicy->filterInputEvent)
- return
- new MotionEntry【创建一个移动事件节点】
- enqueueInboundEventLocked()【同上】
- if (needWake)
- mLooper->wake()
- notifySwitch()【开关事件】
- mPolicy->notifySwitch()
- InputDispatcher分派输入事件(dispatchOnce)
- if (!haveCommandsLocked)()【命令队列没有命令】
- dispatchOnceInnerLocked()【处理一个事件】
- if (!mPolicy->isKeyRepeatEnabled)
- resetKeyRepeatLocked()【释放最近键击事件,mKeyRepeatState】
- if (!mPendingEvent)【如果没有等待事件,获取下一个事件】
- if (mInboundQueue.isEmpty)【如果没有排队事件,看看是否重复最近的键击事件】
- if (mKeyRepeatState.lastKeyEntry)
- if (currentTime >= mKeyRepeatState.nextRepeatTime)
- synthesizeKeyRepeatLocked【合成一个重复键击事件mPendingEvent】
- if (currentTime >= mKeyRepeatState.nextRepeatTime)
- if (!mPendingEvent)【没有事件,返回】
- return
- if (mKeyRepeatState.lastKeyEntry)
- else
- mInboundQueue.dequeueAtHead()【取队列开头mPendingEvent】
- if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)
- pokeUserActivityLocked()【??】
- resetANRTimeoutsLocked()【】
- if (mInboundQueue.isEmpty)【如果没有排队事件,看看是否重复最近的键击事件】
- switch (mPendingEvent->type)【根据事件类型,做相应处理】
- case EventEntry::TYPE_KEY【键击事件】
- dispatchKeyLocked()【分派键击事件】
- 【处理键击自动重复】
- 【策略要求稍后重试,return】
- 【策略在分派前干预,postCommandLocked】
- if (*dropReason != DROP_REASON_NOT_DROPPED)
- setInjectionResultLocked()【丢弃处理】
- findFocusedWindowTargetsLocked()【寻找焦点窗口】
- addMonitoringTargetsLocked()【添加监视目标管道mMonitoringChannels】
- dispatchEventLocked()【分派到各个目标,步骤七】
- dispatchKeyLocked()【分派键击事件】
- case EventEntry::TYPE_MOTION【移动事件】
- dispatchMotionLocked()【分派移动事件】
- if (isPointerEvent)【触摸、点击事件】
- findTouchedWindowTargetsLocked()【寻找触摸窗口】
- else【其他,比如轨迹球】
- findFocusedWindowTargetsLocked()【寻找焦点窗口】
- if (isMainDisplay())
- addMonitoringTargetsLocked()【添加监视目标】
- dispatchEventLocked()【分派到各个目标,步骤七】
- if (isPointerEvent)【触摸、点击事件】
- dispatchMotionLocked()【分派移动事件】
- case EventEntry::TYPE_KEY【键击事件】
- if (done)
- if (dropReason != DROP_REASON_NOT_DROPPED)【事件要被丢弃】
- dropInboundEventLocked()【步骤六】】
- releasePendingEventLocked()【释放mPendingEvent】
- if (dropReason != DROP_REASON_NOT_DROPPED)【事件要被丢弃】
- if (!mPolicy->isKeyRepeatEnabled)
- dispatchOnceInnerLocked()【处理一个事件】
- InputDispatcher丢弃事件的处理(dropInboundEventLocked)
- synthesizeCancelationEventsForAllConnectionsLocked()
- foreach mConnectionsByFd()【每一个连接分别处理】
- synthesizeCancelationEventsForConnectionLocked()
- InputState::synthesizeCancelationEvents()【根据当前输入状态合成一系列取消事件DispatchEntry】
- foreach cancelationEvents
- enqueueDispatchEntryLocked()【插入连接的发送事件队列】
- startDispatchCycleLocked()【启动分派循环,步骤八】
- synthesizeCancelationEventsForConnectionLocked()
- foreach mConnectionsByFd()【每一个连接分别处理】
- InputDispatcher的分派事件(dispatchEventLocked)
- foreach inputTargets
- mConnectionsByFd.valueAt()【根据InputChannel找到内部Connection】
- prepareDispatchCycleLocked()
- splitMotionEvent()【分割移动事件,穿过窗口???】
- enqueueDispatchEntriesLocked()【一个事件EventEntry被拆成多个逻辑事件DispatchEntry】
- enqueueDispatchEntryLocked()【插入连接的发送事件队列】
- startDispatchCycleLocked()【启动分派循环,步骤八】
- InputDispatcher的分派循环(startDispatchCycleLocked)
- while (!connection->outboundQueue.isEmpty())
- switch (eventEntry->type)
- case EventEntry::TYPE_KEY
- connection->inputPublisher.publishKeyEvent()
- mChannel->sendMessage()【InputChannel】
- ::send()【写入UNIX套接字】
- mChannel->sendMessage()【InputChannel】
- connection->inputPublisher.publishKeyEvent()
- case EventEntry::TYPE_MOTION
- connection->inputPublisher.publishMotionEvent()
- mChannel->sendMessage
- connection->inputPublisher.publishMotionEvent()
- case EventEntry::TYPE_KEY
- if (status)
- if (status == WOULD_BLOCK)【套接字队列满】
- connection->inputPublisherBlocked = true
- else
- abortBrokenDispatchCycleLocked()
- return
- if (status == WOULD_BLOCK)【套接字队列满】
- connection->outboundQueue.dequeue()【从发送队列删除】
- connection->waitQueue.enqueueAtTail()【加入等待应答队列】
- switch (eventEntry->type)
输入事件(Java层)
- InputStage分发
- InputStage.deliver()
- if [已经处理或者丢弃]
- forward()
- mNext.deliver()
- forward()
- else if [应该丢弃]
- finish(false)
- forward()
- finish(false)
- else
- onProcess()
- apply(result)
- forward()
- finish(true/false)
- if [已经处理或者丢弃]
- 输入事件分发策略:
类名 | 说明 |
NativePreImeInputStage | 发给InputQueue异步处理(sendInputEvent), 继承InputQueue.FinishedInputEventCallback 目前只有RootViewSurfaceTaker派生类读取InputQueue |
ViewPreImeInputStage | 发给View树预处理(dispatchKeyEventPreIme) |
ImeInputStage | 发给InputMethodManager 异步处理(dispatchInputEvent), 继承InputMethodManager.FinishedInputEventCallback |
EarlyPostImeInputStage | 发给FallbackEventHandler处理(preDispatchKeyEvent) |
NativePostImeInputStage | 发给InputQueue异步处理(sendInputEvent), 继承InputQueue.FinishedInputEventCallback |
ViewPostImeInputStage | 发给View树处理(dispatchKeyEvent、 dispatchKeyShortcutEvent、dispatchUnhandledMove、 dispatchPointerEvent、dispatchTrackballEvent、 dispatchGenericMotionEvent) |
SyntheticInputStage | 合成事件,再排队处理 SyntheticTrackballHandler、SyntheticJoystickHandler、 SyntheticTouchNavigationHandler、SyntheticKeyHandler |
外部输入事件
- InputManager处理(java,injectInputEvent)
- mIm.injectInputEvent(IInputManager)
- InputManagerService::injectInputEvent()
- Binder.clearCallingIdentity()【清除调用者身份,使用服务的权限】
- nativeInjectInputEvent()
- android_view_KeyEvent_toNative()
- android_view_MotionEvent_getNativePtr()
- im->getInputManager()->getDispatcher()->injectInputEvent()
- InputManagerService::injectInputEvent()
- InputDispatcher处理(C++,injectInputEvent)
- hasInjectionPermission()【如果有Injection,POLICY_FLAG_TRUSTED】
- mPolicy->checkInjectEventsPermissionNonReentrant()
- switch (event->getType())
- case AINPUT_EVENT_TYPE_KEY
- mPolicy->interceptKeyBeforeQueueing()
- new KeyEntry
- case AINPUT_EVENT_TYPE_MOTION
- mPolicy->interceptMotionBeforeQueueing()
- new MotionEntry
- for motionEvent->getHistorySize() ~ 1
- new MotionEntry
- case AINPUT_EVENT_TYPE_KEY
- new InjectionState【只赋给最后一个EventEntry】
- for firstInjectedEntry ~ NULL
- enqueueInboundEventLocked()【插入队列,见流程“输入事件”】
- 【等待同步InjectionState】
- if (INPUT_EVENT_INJECTION_SYNC_NONE)
- 【不等待】
- else
- 【等待INPUT_EVENT_INJECTION_PENDING改变】
- mInjectionResultAvailableCondition.waitRelative()
- if (INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED)
- 【等待pendingForegroundDispatches变为0】
- mInjectionSyncFinishedCondition.waitRelative()
- 【等待pendingForegroundDispatches变为0】
- 【等待INPUT_EVENT_INJECTION_PENDING改变】
- if (INPUT_EVENT_INJECTION_SYNC_NONE)
外部设置布局
- 调用InputManager设置某个设备的覆盖布局
- InputManager::setCurrentKeyboardLayoutForInputDevice()
- mIm.setCurrentKeyboardLayoutForInputDevice()【IInputManager,跨进程】
- mDataStore.setCurrentKeyboardLayout()【PersistentDataStore】
- mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS)
- mIm.setCurrentKeyboardLayoutForInputDevice()【IInputManager,跨进程】
- InputManagerService处理消息
- InputManagerService::handleMessage()
- case MSG_RELOAD_KEYBOARD_LAYOUTS
- reloadKeyboardLayouts()
- nativeReloadKeyboardLayouts()【调用JNI】
- reloadKeyboardLayouts()
- case MSG_RELOAD_KEYBOARD_LAYOUTS
- InputManagerService的JNI处理
- nativeReloadKeyboardLayouts()
- im->getInputManager()->getReader()->requestRefreshConfiguration()【CHANGE_KEYBOARD_LAYOUTS】
- mConfigurationChangesToRefresh【记录任务】
- mEventHub->wake()【唤醒线程处理】
- im->getInputManager()->getReader()->requestRefreshConfiguration()【CHANGE_KEYBOARD_LAYOUTS】
- InputReader的线程中处理配置更新
- InputReader::loopOnce()【线程循环】
- refreshConfigurationLocked()【如果mConfigurationChangesToRefresh】
- foreach mDevices
- device->configure()
- if (changes & CHANGE_KEYBOARD_LAYOUTS)
- mContext->getPolicy()->getKeyboardLayoutOverlay()【步骤五】
- mContext->getEventHub()->setKeyboardLayoutOverlay()
- KeyCharacterMap::combine()【合并map】
- if (changes & CHANGE_KEYBOARD_LAYOUTS)
- device->configure()
- foreach mDevices
- refreshConfigurationLocked()【如果mConfigurationChangesToRefresh】
- 反向调用,NativeInputManager读取布局
- NativeInputManager::getKeyboardLayoutOverlay()
- InputManagerService::getKeyboardLayoutOverlay()【方向调用java】
- getCurrentKeyboardLayoutForInputDevice()
- visitKeyboardLayout()【查找】
- KeyboardLayoutDescriptor.parse()
- pm.getReceiverInfo()【PackageManager】
- visitKeyboardLayoutsInPackage()
- pm.getResourcesForApplication()
- visitKeyboardLayout()【查找】
- getCurrentKeyboardLayoutForInputDevice()
- KeyCharacterMap::loadContents()
- InputManagerService::getKeyboardLayoutOverlay()【方向调用java】
开始输入法
- 调用InputManager设置某个设备的覆盖布局
- InputManager::setCurrentKeyboardLayoutForInputDevice()
- mIm.setCurrentKeyboardLayoutForInputDevice()【IInputManager,跨进程】
- mDataStore.setCurrentKeyboardLayout()【PersistentDataStore】
- mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS)
- mIm.setCurrentKeyboardLayoutForInputDevice()【IInputManager,跨进程】
- InputMethodManagerService::startInput()
- InputMethodManagerService开始输入法(startInput)
- startInputLocked()
- mClients.get()【获取ClientState】
- mIWindowManager.inputMethodClientHasFocus()【判断客户端是否有焦点】
- startInputUncheckedLocked()【IInputManager,跨进程】
- if (mCurClient != cs)【客户端改变了】
- isKeyguardLocked()【??】
- unbindCurrentClientLocked()
- executeOrSendMessage()【向新客户端发送MSG_SET_ACTIVE消息】
- if (target.asBinder() instanceof Binder)
- mCaller.sendMessage(msg)
- else【大部分情况走这个分支】
- handleMessage()
- if (target.asBinder() instanceof Binder)
- mCurSeq++,切换mCurClient,mCurInputContext,mCurAttribute
- if (mCurId != null)
- if (cs.curSession != null)
- return attachNewInputLocked()
- if (!mBoundToMethod)
- executeOrSendMessage(mCurMethod, MSG_BIND_INPUT)
- executeOrSendMessage(session.method, MSG_START_INPUT)
- if (mShowRequested)
- showCurrentInputLocked()
- executeOrSendMessage(mCurMethod, MSG_SHOW_SOFT_INPUT)
- bindCurrentInputMethodService()【Visible】
- showCurrentInputLocked()
- return new InputBindResult()
- if (!mBoundToMethod)
- return attachNewInputLocked()
- if (cs.curSession != null)
- return startInputInnerLocked()
- mMethodMap.get()【获取InputMethodInfo】
- unbindCurrentMethodLocked()
- if (mVisibleBound)
- mContext.unbindService()
- if (mHaveConnection)
- mContext.unbindService()
- if (mCurToken != null)
- mWindowManagerService.saveLastInputMethodWindowForTransition()
- mIWindowManager.removeWindowToken()
- clearCurMethodLocked()
- executeOrSendMessage(mCurClient.client, MSG_UNBIND_METHOD)
- if (mVisibleBound)
- mCurIntent = new Intent()
- bindCurrentInputMethodService(BIND_NOT_VISIBLE)
- mCurToken = new Binder()
- mIWindowManager.addWindowToken()
- return new InputBindResult()
- if (mCurClient != cs)【客户端改变了】