InputManagerService之事件的初始化与分发

本文详细探讨了InputManagerService在Android系统中的初始化过程,以及如何与其他模块协作获取和分发事件。重点讲解了InputManagerService如何通过InputReader、InputDispatcher与WindowManagerService交互,利用InputChannel实现应用程序与InputDispatcher之间的通信。文章解答了如何定位处理事件的模块,并概述了事件处理的主要步骤。

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

该篇文章接总章,来详细谈论说明InputManagerService 体系,从初始化到事件获取跟分发。咱们在进行前,先明确哪几个问题需要知道,然后看看在这篇文章中是否解决了这些问题。对于InputManagerService,大家第一个想知道是他起什么作用,这个在总章里面有详细说明,简而言之就是获得事件跟分发处理事件。那他如何或者跟其他模块配合获取事件?并且把这个事件进行分发?如何准确定位对应的处理事件的模块?咱们下面开始讨论这些问题,在这个文章出来的时候,android 已经到N了 ,也就是7.0。但是由于我的笔记(初稿) 在M的时候已经完成了,也就是去年。所以这篇文章还是基于M (6.0)来写。

        InputManagerService的初始化:

        跟其他模块一样,作为系统的核心服务初始化在SystemServer。基本系统的核心服务都是在这里初始化,这个可以研究下系统的启动流程,在启动的最后就是需要启动所有的核心服务。

       代码路径:    frameworks/base/services/java/com/android/server/SystemServer.java   

       在run 方法里面,M 是在startOtherService()里面初始化InputManagerService

      

         上面主要是新建IMS(InputManagerService 下面都用这个替换) 对象, 然后把WindowManagerService的InputMonitor作为参数传给IMS,重点关注下InputMonitor,这个跟事件的分发有关。然后在这里调用start方法启动IMS,这里的start 实际是调用 native 的start 方法。

         看下InputManagerServices的start方法:

         代码路径:frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

       

上面主要调用了com_android_service_input_InputManagerService.cpp 里面的nativeStart方法,Java层的start方法主要做了两个工作:一个工作就是调用nativeStart方法。另外一个就是point 跟 toucher 相关参数设置跟监听,对应这Input事件的主要两类:Key 跟 toucher。在nativeStart里面的mPtr对应啥呢?首先Java层 跟 native层通信调用,主要通过JNI。这里主要是mPtr指针强制类型转换为NativeInputManager对象,看下源码:

Java层代码:

代码路径:frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

    // Pointer to native input manager service object.
    private final long mPtr;
public InputManagerService(Context context) {
        this.mContext = context;
        this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
	mUseDevInputEventForAudioJack =
                context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
        Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
                + mUseDevInputEventForAudioJack);
	//这里对mPtr 进行初始化,调用的还是native的方法,把这个service跟 Systemcontext 传给native对应的方法
        mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
	 LocalServices.addService(InputManagerInternal.class, new LocalService());
    }
Native层代码:

  代码路径:/frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

    static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    if (messageQueue == NULL) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }   //这里把JAVA层的  Systemcontext 以及IMS自己 作为参数传过来了
 	NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
            messageQueue->getLooper());
    im->incStrong(0);
    return reinterpret_cast<jlong>(im);
   }
这个为什么要把IMS 传给NativeInputManager呢?看下NativeInputManager的构造函数

代码路径:frameworks/base/services/core/jni/com_android_server_input_inputmanagerservice.cpp

NativeInputManager::NativeInputManager(jobject contextObj,
        jobject serviceObj, const sp<Looper>& looper) :
        mLooper(looper), mInteractive(true) {
    JNIEnv* env = jniEnv();

    mContextObj = env->NewGlobalRef(contextObj);
    mServiceObj = env->NewGlobalRef(serviceObj);
   {
        AutoMutex _l(mLock);
        mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
        mLocked.pointerSpeed = 0;
        mLocked.pointerGesturesEnabled = true;
        mLocked.showTouches = false;
    }
	mInteractive = true;
	//这个是从底层读取input 信息的提供者
     sp<EventHub> eventHub = new EventHub();
    mInputManager = new InputManager(eventHub, this, this);
}
这里有一个重要的对象就是EventHub,如总章所说这个对象是事件获取的重要的对象。在这里也对Native层的InputManager进行了初始化。前面解决了mPtr 是啥,nativeStart又干了啥?

InputManagerService的读取跟分发启动:

static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
    //这里就是上面获得InputManager对象调用start()方法返回的结果
    status_t result = im->getInputManager()->start();
    if (result) {
        jniThrowRuntimeException(env, "Input manager could not be started.");
    }
}
查看下InputManager的start方法到底干了什么?frameworks/native/services/inputFlinger/InputManager.cpp

代码路径:frameworks/native/services/inputFlinger/InputManager.cpp

status_t InputManager::start() {
    status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
    if (result) {
        ALOGE("Could not start InputDispatcher thread due to error %d.", result);
        return result;
    }

    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
    if (result) {
        ALOGE("Could not start InputReader thread due to error %d.", result);

        mDispatcherThread->requestExit();
        return result;
    }

    return OK;
}
嘿嘿,这里就真
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值