Android 源码分析 - 输入 - Java层

        输入框架层包含一个服务(位于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. 系统输入法
  2. 满足下面一组:
    1. 组1
      1. 声明一个boolean类型资源,其值为true
      2. 包含当前语言设置的子类型
    2. 组2:
      1. 包含英语键盘子类型
  • 选择满足Locale的隐性可用子类型:
  1. 对于所有默认激活子类型
    1. 每个模式选择第一个
  2. 有可用的,返回列表
  3. 对于所有子类型
    1. 每个模式选择一个,满足(优先级)
      1. Locale相等
      2. Locale更通用的第一个
  4. 如果键盘类型不支持TAG_ASCII_CAPABLE
    1. 增加定义了TAG_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE的键盘子类型
  5. 如果没有键盘类型
    1. 寻找语言匹配,或者第一个
    2. 增加的返回列表中
  6. 返回列表
  • 输入法设置
  1. 激活的输入法
    1. 设置名:Settings.Secure.ENABLED_INPUT_METHODS
    2. 设置格式:ime0;subtype0;subtype1;subtype2:ime1:ime2;subtype0
  2. 子类型历史
    1. 设置名:Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY
    2. 设置格式:ime0;subtype:ime1:subtype
  3. 默认输入法
    1. 设置名:Settings.Secure.DEFAULT_INPUT_METHOD
  4. 默认输入法子类型
    1. 设置名:Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE
  5. 禁用的系统输入法
    1. 设置名:Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS
  • 获取激活的子类型
  1. 根据输入法设置获取激活的子类型
  2. 如果允许隐性可用,且上面获取的集合为空
    1. 选择满足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实现了下列接口:

  1. InputReaderPolicyInterface
  2. InputDispatcherPolicyInterface
  3. 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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting Horse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值