Android Input(一)-相关模块初始化

原创内容,转载请注明出处,多谢配合。

一、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初始化时创建了两个重要操作类:InputReaderInputDispatcher

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方法初始化对应的两个线程:InputReaderThreadInputDispatcherThread

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方法。

所以根据以上的初始化过程总结整个层次关系:

Android Input(一)-相关模块初始化_第1张图片

从这个初始化过程来看:IMS的逻辑基本上都是通过jni实现在native层。

下一篇文章:
Android Input(二)-输入子系统

你可能感兴趣的:(Android Input(一)-相关模块初始化)