与 AMS(ActivityManagerService)、WMS(WindowManagerService)、PMS(PackageManagerService)等核心系统服务类似,InputManagerService(以下简称 IMS)同样是在 Android 系统的 SystemServer 进程中完成初始化的。这些系统服务都是 Android 框架层的核心组件,它们通常在系统启动阶段由 SystemServer 统一加载和管理。
一、SystemServer 加载
先来看一下 SystemServer 的入口函数:
/*frameworks/base/services/java/com/android/server/SystemServer.java*/
public static void main(String[] args) {
new SystemServer().run();
}
main方法中只调用了SystemServer的run方法,下面看一下run方法:
/*frameworks/base/services/java/com/android/server/SystemServer.java*/
private void run() {
...
try {
traceBeginAndSlog("StartServices");
//启动引导服务
startBootstrapServices();
//启动核心服务
startCoreServices();
//启动其他服务
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
...
}
可以看出,系统服务主要分为三种类型,分别是引导服务、核心服务和其他服务,我们今天要讨论的 IMS 属于其他服务,这里主要关注startOtherServices方法的定义,具体如下:
/*frameworks/base/services/java/com/android/server/SystemServer.java*/
private void startOtherServices() {
...
t.traceBegin("StartInputManager");
inputManager = new InputManagerService(context);//1
traceEnd();
traceBeginAndSlog("StartWindowManagerService");
// WMS needs sensor service ready
ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
mSensorServiceStart = null;
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());//2
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);//3
traceEnd();
...
t.traceBegin("StartInputManager");
inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
inputManager.start();//4
t.traceEnd();
...
}
首先实例化 InputManagerService 对象,随后在启动 WMS 时将 IMS 引用作为参数传入,使 WMS 能够持有 IMS 的引用,这样做的目的是:
- 使WMS能够直接访问输入事件管理系统
- 建立窗口管理与输入事件处理的协作机制
- 确保窗口操作与用户输入的同步处理
之后将 IMS 注册到 ServiceManager 中,最后调用 IMS 的start方法,启动相关input线程。
二、IMS 启动与触控事件的读取
系统封装了一个名为 EventHub 的对象,该对象基于 Linux 的 inotify 和 epoll 机制,用于监控/dev/input目录下的设备事件节点。通过调用 EventHub 的 getEvents 接口,即可监听并获取相关事件。
接上一小节,IMS 启动后会首先通过 JNI 调用创建 InputManager 对象,随后实例化 InputReader 对象。接着通过 start 方法为 InputReader 创建一个名为 InputThread 的 Loop 工作线程,该线程的主要职责是通过 EventHub 的 getEvents 方法持续监听并读取输入事件。具体流程如下图所示:

简要代码流程如下:
/*frameworks/base/services/java/com/android/server/SystemServer.java*/
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
...
// 1.创建InputManagerService对象
inputManager = new InputManagerService(context);
...
// 2.start启动相关input线程
inputManager.start();
...
}
/*frameworks/base/services/core/java/com/android/server/input/InputManagerService.java*/
public InputManagerService(Context context) {
...
// 1.JNI调用,完成InputManager初始化动作
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
...
}
public void start() {
// 2.JNI调用,启动InputManager工作线程
nativeStart(mPtr);
...
}
/*frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp*/
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
...
// 创建NativeInputManager对象
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
messageQueue->getLooper());
...
}
NativeInputManager::NativeInputManager(jobject contextObj,
jobject serviceObj, const sp<Looper>& looper) :
mLooper(looper), mInteractive(true) {
...
// 创建InputManager对象
mInputManager = new InputManager(this, this);
...
}
static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
...
// 调用InputManager的start方法
status_t result = im->getInputManager()->start();
...
}
/*frameworks/native/services/inputflinger/InputManager.cpp*/
InputManager::InputManager(
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
// 创建InputDispatcher触控事件分发对象
mDispatcher = createInputDispatcher(dispatcherPolicy);
mClassifier = new InputClassifier(mDispatcher);
// 1.createInputReader创建InputReader事件读取对象,间接持有InputDispatcher的引用,等事件读取完成后通知其进行事件分发
mReader = createInputReader(readerPolicy, mClassifier);
}
status_t InputManager::start() {
// 启动InputDispatcher工作线程
status_t result = mDispatcher->start();
...
// 启动InputReader工作线程
result = mReader->start();
...
return OK;
}
/*frameworks/native/services/inputflinger/reader/InputReader.cpp*/
InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
const sp<InputReaderPolicyInterface>& policy,
const sp<InputListenerInterface>& listener)
: mContext(this),
// 初始化EventHub对象
mEventHub(eventHub),
mPolicy(policy),
mGlobalMetaState(0),
mGeneration(1),
mNextInputDeviceId(END_RESERVED_ID),
mDisableVirtualKeysTimeout(LLONG_MIN),
mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0) {
// 持有InputDispatcher的引用
mQueuedListener = new QueuedInputListener(listener);
...
}
status_t InputReader::start() {
if (mThread) {
return ALREADY_EXISTS;
}
// 创建名为“InputReader”的InputThread的loop工作线程,并在其中循环执行loopOnce函数
mThread = std::make_unique<InputThread>(
"InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
return OK;
}
void InputReader::loopOnce() {
int32_t oldGeneration;
int32_t timeoutMillis;
bool inputDevicesChanged = false;
std::vector<InputDeviceInfo> inputDevices;
{
...
// 1. 从EventHub中监听读取触控事件
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
{
...
if (count) {
// 2.处理读取到的触控事件
processEventsLocked(mEventBuffer, count);
}
...
}
...
// 3.mQueuedListener其实就是InputDispatcher对象,flush会通知唤醒InputDispatcher分发事件
mQueuedListener->flush();
}
上述流程中,输入事件最终由名为 InputThread 的循环工作线程持续监听并读取。这些事件首先通过 InputReader::processEventsLocked 方法被封装成 RawEvent,随后通知 InputDispatcher 进行事件分发。
触控事件的分发过程我们下一篇讲解。
&spm=1001.2101.3001.5002&articleId=157935765&d=1&t=3&u=9dfe68787b57419b9b3d32b5cbe70807)
1207

被折叠的 条评论
为什么被折叠?



