Android 5.0输入系统分析之InputReader和InputDispatcher线程启动过程

Android输入系统工作流程如图(1),InputReader线程不断地从Input Driver中读取原始数据销做处理,放入enqueueInboundEventLocked队例中,InputDispatcher线程不断从enqueueInboundEventLocked队例中取出数据进行处理,把能传给用户的数据放入mInboundQueue队例中,然后最后APP进程从mInboundQueue队例中取出数据进行处理。

Android 5.0输入系统分析之InputReader和InputDispatcher线程启动过程

首先说明,所有图片来自:http://blog.****.net/jinzhuojun/article/details/41909159  这哥们写的很好,本人刚刚学习android,很多都是参考此文和自已理解写的,一定有不足之处,希望各位大神出来指正。

接下来,先分析InputReader线程和InputDispatcher线程如何启动的?从图(2)的时序图来一步步进行分析

Android 5.0输入系统分析之InputReader和InputDispatcher线程启动过程

在systemServer.java初始化IMS ,初始化WMS,然后把IMS 作为参数据传给WMS,最后把InputReader线程和InputDispatcher线程start起来

     

<1>            inputManager = new InputManagerService(context);


            Slog.i(TAG, "Window Manager");
            wm = WindowManagerService.main(context, inputManager,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,

                    !mFirstBoot, mOnlyCore);


            ServiceManager.addService(Context.WINDOW_SERVICE, wm);

            ServiceManager.addService(Context.INPUT_SERVICE, inputManager); //add service


            mActivityManagerService.setWindowManager(wm);
  

            inputManager.setWindowManagerCallbacks(wm.getInputMonitor());


 <2>           inputManager.start();


先分分析<1>点 inputManager = new InputManagerService(context);

初始化InputManagerService,进入InputManagerService.java的构造函数InputManagerService

public InputManagerService(Context context) {
        this.mContext = context;
        this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());


        mUseDevInputEventForAudioJack =
                context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
        Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
                + mUseDevInputEventForAudioJack);
        mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());  


        LocalServices.addService(InputManagerInternal.class, new LocalService()); 
    }

调用了nativeInit,也就是调用(JNI)com_android_server_input_InputManagerService.cpp中nativeInit 函数

static jlong nativeInit(JNIEnv* env, jclass clazz,
        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
    sp<MessageQueue> 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<jlong>(im);
}

在nativeInit 函数中初始化了NativeInputManager,进入NativeInputManager构造函数NativeInputManager

NativeInputManager::NativeInputManager(jobject contextObj,      jobject serviceObj, const sp<Looper>& looper) :  mLooper(looper), mInteractive(true) {


   ......


    sp<EventHub> eventHub = new EventHub();
    mInputManager = new InputManager(eventHub, this, this);
}

可以在NativeInputManager函数中看到初始化了EventHub和InputManager,从中可以知道NativeInputManager层是java世界与c++世界中间桥梁,也就是IMS和InputManager的中间层

EventHub构造函数:

EventHub::EventHub(void) :
        mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mControllerNumbers(),
        mOpeningDevices(0), mClosingDevices(0),
        mNeedToSendFinishedDeviceScan(false),
        mNeedToReopenDevices(false), mNeedToScanDevices(true),
        mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) {
    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);


    mEpollFd = epoll_create(EPOLL_SIZE_HINT);
    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);


    mINotifyFd = inotify_init();
    int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
    LOG_ALWAYS_FATAL_IF(result < 0, "Could not register INotify for %s.  errno=%d",
            DEVICE_PATH, errno);


    struct epoll_event eventItem;
    memset(&eventItem, 0, sizeof(eventItem));
    eventItem.events = EPOLLIN;
    eventItem.data.u32 = EPOLL_ID_INOTIFY;
    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance.  errno=%d", errno);


    int wakeFds[2];
    result = pipe(wakeFds);
    LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);


    mWakeReadPipeFd = wakeFds[0];
    mWakeWritePipeFd = wakeFds[1];


    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking.  errno=%d",
            errno);


    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking.  errno=%d",
            errno);


    eventItem.data.u32 = EPOLL_ID_WAKE;
    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance.  errno=%d",
            errno);


    int major, minor;
    getLinuxRelease(&major, &minor);
    // EPOLLWAKEUP was introduced in kernel 3.5
    mUsingEpollWakeup = major > 3 || (major == 3 && minor >= 5);
}

初始化inotify和epoll,用来监听Input Driver的数据和设备节点变化,后面InputReader线程中会用到。

InputManager构造函数:

InputManager::InputManager(
        const sp<EventHubInterface>& eventHub,
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
    mDispatcher = new InputDispatcher(dispatcherPolicy);
    mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
    initialize();
}

InputDispatcher和InputReader只是简单初始化。接下来initialize函数

void InputManager::initialize() {
    mReaderThread = new InputReaderThread(mReader);
    mDispatcherThread = new InputDispatcherThread(mDispatcher);
}

创建了InputDispatcher,InputReader线程。现在<1> inputManager = new InputManagerService(context);跑完了

接下来就是<2>  inputManager.start();那么就是调用了InputManagerService.java中start函数

 public void start() {
        Slog.i(TAG, "Starting input manager");
        nativeStart(mPtr);

    }

nativeStart调用了(JNI) com_android_server_input_InputManagerService.cpp中nativeStart函数

static void nativeStart(JNIEnv* env, jclass clazz, jlong ptr) {
    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);


    status_t result = im->getInputManager()->start();
    if (result) {
        jniThrowRuntimeException(env, "Input manager could not be started.");
    }
}

在nativeStart函数中调用了InputManager.java的start函数

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;
}

现在可以看到InputDispatcher和InputReader线程启动起来了。接下来下编分析InputReader线程是如何运转的。