[개요]
InpuFW대해서 전반적인 Input event가 어떻게 동작하는지에 대해 정리하고자 합니다.
InputMangerService Servie 등록부터 시작
EventHub에서 event를 받게 되면 InputReader로 전달되게 됩니다. 이 때, InputReader, InputDispatcher thread를 깨우는 과정이 시작됩니다.
- Android가 시작되면 SystemServer에서는 각종 Service들이 시작됩니다. IMS 또한 SystemServer에서 IMS를 등록하는 것을 알 수 있습니다.
// SystemServer.java
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
inputManager = new InputManagerService(context);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
// Start InputManager
inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
inputManager.start();
}
- IMS.java에서 호출을 받으면, JNI를 통하여 native를 호출한다. 추가로 Watchdog monitor를 추가시키는 것을 볼 수 있다.
// InputManagerService.java
public void start() {
Slog.i(TAG, "Starting input manager");
nativeStart(mPtr);
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
- JNI단에서는 InputManager를 호출한다.
// 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.");
}
}
- 이미 thread가 있으면 종료하고 없으면 InputDispatcher,Reader thread를 생성한다.
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;
}
- Looper->wake, EventHub->wake 시키면서 Thread가 정상적으로 동작할 수 있게 셋팅 끝.
// InputDispatcher.cpp
status_t InputDispatcher::start() {
if (mThread) {
return ALREADY_EXISTS;
}
mThread = std::make_unique<InputThread>(
"InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
return OK;
}
// InputReader.cpp
status_t InputReader::start() {
if (mThread) {
return ALREADY_EXISTS;
}
mThread = std::make_unique<InputThread>(
"InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
return OK;
}
- 이후 InputReader에서 Event 처리 시작.
// InputReader.cpp
void InputReader::loopOnce() {
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
if (count) {
processEventsLocked(mEventBuffer, count);
}