原创内容,转载请注明出处,多谢配合。
一、Android输入系统介绍
牵涉到的模块:
- InputReader: 负责从硬件获取输入,转换成事件(Event), 并传给Input Dispatcher.
- InputDispatcher: 将InputReader传送过来的Events分发给合适的窗口,并监控ANR。
- InputManagerService: 负责InputReader 和 InputDispatcher的创建,并提供Policy 用于Events的预处理。
- WindowManagerService:管理InputManager 与 View(Window) 以及 ActivityManager 之间的通信。
- View and Activity:接收按键并处理。
- ActivityManagerService:ANR 处理。
牵涉到的进程:
system_server 与 应用进程。
进程对应的主要工作线程:
其中system_server中包含InputReaderThread和InputDispatcherThread。
应用进程相关的主要是 UIThread。
二、初始化
在SystemServer的初始化过程中,IMS和WMS 被创建出来,并将WMS中的monitor传给了IMS,作为回调。
frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {
WindowManagerService wm = null;
InputManagerService inputManager = null;
…
inputManager = new InputManagerService(context);
...
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
…
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
...
}
IMS的构造方法中执行了nativeInit,这是个native方法,属于jni调用,该方法中创建了一个NativeInputManager实例,并且和java层使用的是同一个looper。
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
public InputManagerService(Context context) {
this.mContext = context;
this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
...
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
...
}
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
messageQueue->getLooper());
im->incStrong(0);
return reinterpret_cast(im);
}
在NativeInputManager的初始化中创建了一个Eventhub,同时将这个Eventhub传给新建的Inputmanager,Eventhub就是将数据从硬件驱动上读出来然后传递上来的通道。
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
NativeInputManager::NativeInputManager(jobject contextObj,
jobject serviceObj, const sp& looper) :
mLooper(looper), mInteractive(true) {
...
sp eventHub = new EventHub();
mInputManager = new InputManager(eventHub, this, this);
}
InputManager初始化时创建了两个重要操作类:InputReader
和InputDispatcher
。
frameworks/native/services/inputflinger/InputManager.cpp
InputManager::InputManager(
const sp& eventHub,
const sp& readerPolicy,
const sp& dispatcherPolicy) {
mDispatcher = new InputDispatcher(dispatcherPolicy);
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
initialize();
}
initialize方法初始化对应的两个线程:InputReaderThread
和InputDispatcherThread
。
void InputManager::initialize() {
mReaderThread = new InputReaderThread(mReader);
mDispatcherThread = new InputDispatcherThread(mDispatcher);
}
InputManager的start方法,让两个线程run起来。
frameworks/native/services/inputflinger/InputManager.cpp
status_t InputManager::start() {
status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
if (result) {
ALOGE("Could not start InputDispatcher thread due to error %d.", result);
return result;
}
result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
if (result) {
ALOGE("Could not start InputReader thread due to error %d.", result);
mDispatcherThread->requestExit();
return result;
}
return OK;
}
那么这个InputManager的start方法在哪调的呢?回看IMS的start方法
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
public void start() {
Slog.i(TAG, "Starting input manager");
nativeStart(mPtr);
...
}
这里又是调的native方法: nativeStart(mPtr)
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
NativeInputManager* im = reinterpret_cast(ptr);
status_t result = im->getInputManager()->start();
if (result) {
jniThrowRuntimeException(env, "Input manager could not be started.");
}
}
这里获取InputManager并调用它的start方法。
所以根据以上的初始化过程总结整个层次关系:
从这个初始化过程来看:IMS的逻辑基本上都是通过jni实现在native层。
下一篇文章:
Android Input(二)-输入子系统