输入框架层包含一个服务(位于services目录),一个接口(位于core目录),一个工具(位于cmds目录)。
android.view
libinput中的C++类,在jni层都有一个对应的Native开头的类,封装libinput中的对象的指针。在java层有一个类对应,其Ptr成员保存Native类的指针。
java源代码位于:frameworks/base/core/java/android/view。
jni源代码位于:frameworks/base/core/jni。
java | jni | C++ |
InputChannel | NativeInputChannel | InputChannel |
KeyCharacterMap | NativeKeyCharacterMap | KeyCharacterMap |
InputDevice | InputDeviceInfo | |
KeyEvent | KeyEvent | |
MotionEvent | MotionEvent | |
InputEventSender | NativeInputEventSender | InputPublisher |
InputEventReceiver | NativeInputEventReceiver | InputConsumer |
InputChannel(java)的静态native方法nativeOpenInputChannelPair()创建一对InputChannel。NativeInputChannel支持序列化Parcel,是跨进程传递UNIX域套接字句柄的关键。
InputEventReceiver 的jni层对象NativeInputEventReceiver通过MessageQueue处理InputChannel文件描述符上的数据到达,通过InputConsumer读取输入事件,回调java层对象方法。这些都在上层Looper线程中执行。另一方面,将应答写入InputChannel。
InputEventSender的jni层对象NativeInputEventSender通过InputPublisher向InputChannel写入输入事件,并通过MessageQueue等待应答,然后读取应答并回调java层。
ViewRootImpl是应用层接收并处理输入事件的关键。其setView方法中创建了一个然后通过IWindowSession(com.android.server.wm.Session实现)注册该窗口,最终由WindowManagerService打开一对InputChannel,并将读取端返回给ViewRootImpl。
ViewRootImpl通过嵌套类WindowInputEventReceiver(继承InputEventReceiver)读取输入事件,事件在队列中排队处理。
类名 | 说明 |
InputChannel | |
KeyCharacterMap | |
InputDevice | |
KeyEvent | |
MotionEvent | |
InputEventReceiver | |
InputEventSender | |
ViewRootImpl | 窗口,管理输入事件,调用会话接口使用窗口服务 |
InputQueue | 提供由应用处理输入事件的机制,在native层使用 |
InputStage | 分发策略,如果没有处理(包括丢弃),本地丢弃或者本地处理(onProcess),然后向前转发(onDeliverToNext) |
AsyncInputStage | 异步分发,保持顺序向前转发。 |
ViewRootImpl.WindowInputEventReceiver | 继承InputEventReceiver,将收到的输入事件排队处理 |
FallbackEventHandler | 输入事件处理器策略基类,在EarlyPostIme、ViewPostIme阶段被调用 |
android.hardware.input
源代码位于:frameworks/base/core/java/android/hardware/input。
InputManager转发调用到input服务,分发设备增加、删除、改变事件到注册的InputDeviceListener。
com.android.internal.view
源代码位于:frameworks/base/core/java/com/android/internal/view。
内部实现类:
类名 | 说明 |
IInputContext | 输入法回调应用的接口方法定义,接口是异步的,通过IInputContextCallback返回Get结果 |
IInputContextCallback | 应用响应输入法返回Get请求的信息。 |
InputBindResult | 输入法管理服务成功绑定了一个输入法后返回的信息 |
IInputConnectionWrapper | 通过InputConnection实现IInputContext,使用异步消息机制转发到Looper线程执行,执行时检查InputConnection失效或者禁用 |
InputConnectionWrapper | 通过IInputContext实现InputConnection接口,异步Get转换为同步 |
IInputMethod | 输入法接口 |
IInputMethodClient | 输入法管理服务回调客户端的接口 |
IInputMethodManager | 输入法管理服务的接口定义 |
IInputMethodSession | 输入法会话接口,startInput返回 |
IInputSessionCallback | 输入法通知应用会话创建成功的接口 |
android.view.inputmethod
提供应用访问接口,与服务通信。
源代码位于:frameworks/base/core/java/android/view/inputmethod。
类型说明:
类名 | 说明 |
InputMethodManager | 输入法管理服务的本地代理 |
InputMethod | 进程内输入法接口,相对于IInputMethod,使用InputConnection,不处理InputChannel |
InputMethodSession | 进程内输入法会话接口,相对于IInputMethodSession,多了几个dispatch*Event接口 |
InputMethodInfo | 输入法描述信息 |
InputConnection | 输入法回调应用的接口方法定义 |
BaseInputConnection | 实现InputConnection接口,与Editable绑定 |
SuggestionSpan | 文字替换建议 |
EditorInfo | |
CompletionInfo | |
InputBinding | 绑定一个InputConnection和一个Token,传给输入法 |
InputMethodSubtype | 输入法子类型描述,Locale、Mode(键盘,语音) |
InputConnectionWrapper | 包装另一个InputConnection接口 |
InputMethodManager辅助类型(嵌套类)说明:
类名 | 说明 |
ImeInputEventSender | 继承InputEventSender,与输入法通信也是通过InputChannel实现 |
FinishedInputEventCallback | 输入事件应答接口,一般由ViewRoot实现 |
ControlledInputConnectionWrapper | 继承IInputConnectionWrapper,控制active |
PendingEvent | 等待应答的输入事件 |
InputMethodManager通过IInputConnectionWrapper适配InputConnection到IInputContext。应用通过InputMethodManager转发调用IInputMethodSession的接口。
com.android.internal.inputmethod
辅助类型:
类名 | 说明 |
InputMethodUtils | |
InputMethodUtils. InputMethodSettings |
- 系统输入法:isSystemIme,FLAG_SYSTEM
- 辅助输入法:isAuxiliaryIme
- 子类型:语言 + 模式(键盘或者语音)
- 自动子类型:包含至少一个默认激活的子类型
- 默认激活:isDefaultEnabledIme,必须满足:
- 系统输入法
- 满足下面一组:
- 组1
- 声明一个boolean类型资源,其值为true
- 包含当前语言设置的子类型
- 组2:
- 包含英语键盘子类型
- 组1
- 选择满足Locale的隐性可用子类型:
- 对于所有默认激活子类型
- 每个模式选择第一个
- 有可用的,返回列表
- 对于所有子类型
- 每个模式选择一个,满足(优先级)
- Locale相等
- Locale更通用的第一个
- 每个模式选择一个,满足(优先级)
- 如果键盘类型不支持TAG_ASCII_CAPABLE
- 增加定义了TAG_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE的键盘子类型
- 如果没有键盘类型
- 寻找语言匹配,或者第一个
- 增加的返回列表中
- 返回列表
- 输入法设置
- 激活的输入法
- 设置名:Settings.Secure.ENABLED_INPUT_METHODS
- 设置格式:ime0;subtype0;subtype1;subtype2:ime1:ime2;subtype0
- 子类型历史
- 设置名:Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY
- 设置格式:ime0;subtype:ime1:subtype
- 默认输入法
- 设置名:Settings.Secure.DEFAULT_INPUT_METHOD
- 默认输入法子类型
- 设置名:Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE
- 禁用的系统输入法
- 设置名:Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS
- 获取激活的子类型
- 根据输入法设置获取激活的子类型
- 如果允许隐性可用,且上面获取的集合为空
- 选择满足Locale的隐性可用子类型【见第六项】
android.inputmethodservice
源代码位于:frameworks/base/core/java/android/view/inputmethod。
类型说明:
类名 | 说明 |
IInputMethodWrapper | 包装一个IInputMethod实例,使用异步消息机制转发到Looper线程执行,创建的会话通过IInputMethodSessionWrapper包装 |
IInputMethodSessionWrapper | 包装一个IInputMethodSession实例,使用异步消息机制转发到Looper线程执行 |
AbstractInputMethodService | 一个输入法服务的抽象,通过Bind返回InputMethod实例返回的输入法使用IInputMethodWrapper包装。派生类通过继承AbstractInputMethodImpl抽象接口实现输入法,通过继承AbstractInputMethodSessionImpl实现输入法会话。 |
InputMethodService | 基本实现一个输入法服务 |
SoftInputWindow | 输入法窗口 |
KeyboardView | 软键盘UI |
Keyboard | 软键盘布局定义 |
com.android.server.input
源代码位于:frameworks/base/services/java/android/server/input。
input服务运行在SystemServer进程,是一个binder服务,可以跨进程访问。其java代码存在于services.jar中,jni层代码属于libandroid_servers库。
java | jni | C++ |
InputManagerService | NativeInputManager | InputManager InputReader InputDispatcher |
InputApplicationHandle | NativeInputApplicationHandle | InputApplicationHandle InputApplicationInfo |
InputWindowHandle | NativeInputWindowHandle | InputWindowHandle InputWindowInfo |
jni
源代码位于:frameworks/base/services/jni。
NativeInputManager实现了下列接口:
- InputReaderPolicyInterface
- InputDispatcherPolicyInterface
- PointerControllerPolicyInterface
NativeInputManager创建了libinputservice 中定义的EventHub、InputManager,负责分派java调用到InputManager内的InputReader、InputDispatcher,转发接口方法回调到java层。
NativeInputApplicationHandle继承InputApplicationHandle,其updateInfo,获取java成员的信息,转换为C++类型。
NativeInputWindowHandle继承InputWindowHandle,实现了updateInfo,获取java成员的信息,转换为C++类型。
java
源代码位于:frameworks/base/services/java/com/android/server/input。
InputManagerService实现IInputManager接口,转发NativeInputManager的回调到WindowManagerCallbacks,后者由WindowManagerService中的InputMonitor实现,最终调用到PhoneWindowManager。InputMonitor也封装InputManagerService的部分方法,供WindowManagerService调用。
InputManagerService由SystemServer启动,其jni库libandroid_servers静态绑定libinputservice,因此input没有native层的服务。
com.android.server
源代码位于:frameworks/base/services/java/com/android/server。
InputMethodManagerService,input_method服务由SystemServer启动,实现IInputMethodManager接口,是Binder类型的接口,可以跨进程访问。
input
Input是framework提供的一个输入工具,可以模拟输入键盘、鼠标等设备的事件。
Input利用InputManager(java)提供的injectInputEvent方法向framework层直接插入输入事件。
源代码位于frameworks/base/cmds/input。