关于IMS的初始化可以看我前面发的这篇文章:
input事件分发流程:
IMS问题复盘:
1. IMS启动流程
1.1 InputManagerService.start
/frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
public void start() {
Slog.i(TAG, "Starting input manager");
nativeStart(mPtr);
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
registerPointerSpeedSettingObserver();
registerShowTouchesSettingObserver();
registerAccessibilityLargePointerSettingObserver();
registerLongPressTimeoutObserver();
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updatePointerSpeedFromSettings();
updateShowTouchesFromSettings();
updateAccessibilityLargePointerFromSettings();
updateDeepPressStatusFromSettings("user switched");
}
}, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
updatePointerSpeedFromSettings();
updateShowTouchesFromSettings();
updateAccessibilityLargePointerFromSettings();
updateDeepPressStatusFromSettings("just booted");
}
这里主要调用nativeStart,将nativeInit创建的mPtr带入,这里的mPtr就是NativeInputManager的实例。
1.2 com_android_server_input_InputManagerService.nativeStart
/frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
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.");
}
}
1.3 InputManager.start
/frameworks/native/services/inputflinger/InputManager.cpp
status_t InputManager::start() {
status_t result = mDispatcher->start();
if (result) {
ALOGE("Could not start InputDispatcher thread due to error %d.", result);
return result;
}
result = mReader->start();
if (result) {
ALOGE("Could not start InputReader due to error %d.", result);
mDispatcher->stop();
return result;
}
return OK;
}
1.4 InputDispatcher.start
/frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
status_t InputDispatcher::start() {
if (mThread) {
return ALREADY_EXISTS;
}
mThread = std::make_unique<InputThread>(
"InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
return OK;
}
这里主要有三个作用创建名为InputDispatcher的线程;调用dispatchOnce函数;唤醒looper。InputDispatcher的start函数就是无限运行dispatchOnce()。
1.5 InputReader.start
/frameworks/native/services/inputflinger/reader/InputReader.cpp
status_t InputReader::start() {
if (mThread) {
return ALREADY_EXISTS;
}
mThread = std::make_unique<InputThread>(
"InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
return OK;
}
这里做的工作跟上面的InputDispatcher的start函数类似,创建名为InputReader的线程;调用loopOnce方法(这里面会去通过getEvents函数获取input event,如果正常的话会调用processEventsLocked通知给InputDispatcher);调用EventHub的wake函数往 write fd中写入一个字节,然后epoll监听的read fd就有事件发生,epoll就被唤醒了,这和Looper的wake机制一模一样。
1.6 IMS启动流程总结
- 为InputDispatcher和InputReader分别创建了InputThread,这两个线程恰好以它们的类名为名。
- InputDispatcher使用Looper的epoll作为模型,无限运行dispatchOnce(),在没有命令处理时会block在epoll处,当IMS(java层) 或 InputReader有事件要dispatch时,它们会唤醒InputDispatcher。
- 在InputReader中通过getEvents函数获取input event,调用EventHub的wake函数往 write fd中写入一个字节,然后epoll监听的read fd就有事件发生,epoll就被唤醒了。