Android InputManagerService启动流程(二)

与 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 的引用,这样做的目的是:

  1. 使WMS能够直接访问输入事件管理系统
  2. 建立窗口管理与输入事件处理的协作机制
  3. 确保窗口操作与用户输入的同步处理

之后将 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 进行事件分发。

触控事件的分发过程我们下一篇讲解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A-sL1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值