Android系统源码阅读(11):Android的InputManagerService的工作过程

本文详细探讨了Android 6.0.1_r50中InputManagerService的创建过程,从SystemServer启动服务,到InputManagerService的构造,再到InputDispatcher和InputReader的启动。在构造InputManagerService时,涉及到了DisplayThread的Looper、NativeInputManager对象的创建以及Input事件的分发和获取。文章还介绍了启动InputManagerService后,如何通过nativeStart开始InputManager的运行,并启动监听Input事件的线程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android系统源码阅读(11):Android的InputManagerService的工作过程

请对照AOSP版本:6.0.1_r50。


1. 创建InputManager

这里和老罗当年的版本有很大不同了,有了InputManagerService管理InputManager。

这里写图片描述

1.1

想要探索如何启动的相关server,需要从SystemServer开始探寻。从SystemServer的进程开始运行开始,它就会创建一些系统server,这里就会启动other services。

其中,会创建Input Manager和Window Manager两个服务。

frameworks/base/services/java/com/android/server/SystemServer.java :

Slog.i(TAG, "Input Manager");
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);
//..
inputManager.start();

1.2

先来仔细端详一下InputManagerService的构造函数。这里会调用c++层的初始化函数。
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java :

this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper);
//..
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());

注意这里将DisplayThread的Looper传递过去,DisplayThread是一个单例模式的类,它会启动唯一的线程。同时DisplayThread是一个HandlerThread的子类,实现了Looper循环机制。DisplayThread是用来执行和显示有关的操作,显示操作一般需要比较小的延迟。DisplayThread只能被WindowManager、DisplayManager,InputManager用来执行一些快速地实时操作。

1.3

这一步首先将java层的MessageQueue变为了c++的MessageQueue。然后构造了一个NativeInputManager对象,最后将指向该对象的指针im返回给java层。

frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp :

NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, messageQueue->getLooper());

1.4

在构造NativeInputManager时,会创建一个InputManager对象mInputManager。

frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp :

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

1.5

这一步会创建一个dispatcher负责分发输入事件,一个reader负责获取事件。
frameworks/native/services/inputflinger/InputManager.cpp :

mDispatcher = new InputDispatcher(dispatcherPolicy);
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
initialize();

1.6

这里会创建两个线程,在以后的步骤中会用来运行前面创建的dispathcer和reader。

frameworks/native/services/inputflinger/InputManager.cpp :

mReaderThread = new InputReaderThread(mReader);
mDispatcherThread = new InputDispatcherThread(mDispatcher);

2. 启动InputManager

将视线再次回到SystemServer中,在创建完InputManagerService后,需要将这个Service启动,同样是在1.1的startOtherServices函数里,调用了InputManagerService的成员函数start。

这里写图片描述

2.1

这里首先调用了c++层的nativeStart,然后InputManagerService将自己交给Watchdog监视。然后注册了PointerSpeedSetting和ShowTouchesSetting两个Observer。

frameworks/base/services/core/java/com/android/server/input/InputManagerService.java :

nativeStart(mPtr);

// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);

registerPointerSpeedSettingObserver();
registerShowTouchesSettingObserver();

这两个Observer暂时还没搞清楚是干什么的。

2.2

这一步将传来的ptr参数转化为一个NativeInputManager指针,同时开始启动NativeInputManager中的InputManager。

frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp :

NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
status_t result = im->getInputManager()->start();

2.3

这里会启动在1.6中创建的两个线程,分别用来分发和监听Input事件。

frameworks/native/services/inputflinger/InputManager.cpp :

status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);)

3. 启动InputDispatcher

在2.3中运行的线程以threadLoop为入口,开始进入循环。

这里写图片描述

3.1

这一步直接将任务交给InputDispatcher的dispatchOnce函数。

frameworks/native/services/inputflinger/InputDispatcher.cpp :<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值