Android framework重要服务之InputManagerService的启动流程

Posted 小陈乱敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android framework重要服务之InputManagerService的启动流程相关的知识,希望对你有一定的参考价值。

前言

InputManagerService(输入管理服务)简称IMS,在安卓系统中负责它管理整个系统的输入部分,包括键盘、鼠标、触摸屏等等,它与WindowManager密切相关,本章将结合安卓11源码梳理IMS的启动流程。

一、启动IMS服务

IMS启动流程位于frameworks/base/services/java/com/android/server/SystemServer.java,相关代码如下:

private void startOtherServices(@NonNull TimingsTraceAndSlog t) 
    ...
    
    // 开始启动IMS
    t.traceBegin("StartInputManagerService");
    inputManager = new InputManagerService(context);
    t.traceEnd();
    ...
    
    // 添加inputManager服务
    ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
    ...
    
    // 启动InputManager
    t.traceBegin("StartInputManager");
    inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
    inputManager.start();
    t.traceEnd();
 

二、IMS启动流程

IMS在SystemServer.java中被启动后,会前往 frameworks/base/services/core/java/com/android/server/input/InputManagerService.java 中继续其启动流程,IMS的启动过程如下:

public InputManagerService(Context context) 
    this.mContext = context;
    // 将InputManager加入"android.display"线程
    this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());

    mStaticAssociations = loadStaticInputPortAssociations();
    mUseDevInputEventForAudioJack =
            context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
    Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
            + mUseDevInputEventForAudioJack);
            
    // 初始化native层InputManager
    mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());

    String doubleTouchGestureEnablePath = context.getResources().getString(
            R.string.config_doubleTouchGestureEnableFile);
    mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :
        new File(doubleTouchGestureEnablePath);

    // 注册本地服务
    LocalServices.addService(InputManagerInternal.class, new LocalService());


// 设置window反馈回调函数
public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) 
    if (mWindowManagerCallbacks != null) 
        unregisterLidSwitchCallbackInternal(mWindowManagerCallbacks);
    
    mWindowManagerCallbacks = callbacks;
    registerLidSwitchCallbackInternal(mWindowManagerCallbacks);
 

1. native层初始化

由于IMS底层都是由C++实现的,故需要对native层的IMS进行初始化,ative层的IMS初始化位于frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
        jobject serviceObj, jobject contextObj, jobject messageQueueObj) 
        // 获取messageQueue,该messageQueue由java传入, mHandler.getLooper().getQueue()
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);   
 
    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
            messageQueue->getLooper());
    // 智能指针增加引用
    im->incStrong(0);  
    // 转jlong返回
    return reinterpret_cast<jlong>(im);   

...
 
NativeInputManager::NativeInputManager(jobject contextObj,
        jobject serviceObj, const sp<Looper>& looper) :
        mLooper(looper), mInteractive(true) 
    JNIEnv* env = jniEnv();
    ...
    
    // 初始化InputManager
    InputManager* im = new InputManager(this, this);
    mInputManager = im;
    defaultServiceManager()->addService(String16("inputflinger"), im);
 
  1. 初始化InputManager

InputManager初始化inputDispatcher和InputReader,其初始化位于frameworks/native/services/inputflinger/InputManager.cpp:

InputManager::InputManager(
        const sp<EventHubInterface>& eventHub,
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) 
    // 初始化InputDispatcher
    mDispatcher = new InputDispatcher(dispatcherPolicy);   
    // 初始化InputReader
    mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
    initialize();
 

3. 启动InputManager

InputManager在Native层初始化完毕后,将由java层调用其启动流程,该流程位于frameworks/base/services/core/java/com/android/server/input/InputManagerService.java:

public void start() 
    Slog.i(TAG, "Starting input manager");
    nativeStart(mPtr);
 
    // Add ourself to the Watchdog monitors.
    Watchdog.getInstance().addMonitor(this);
    ...
    
 

4. 启动native层InputManager

nativestart调用InputManager的start方法来运行线程,该部分代码位于com_android_server_input_InputManagerService.cpp:

static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) 
    // 将jlong转为NativeInputManager指针
    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
    
    // 获取InputManager并启动
    status_t result = im->getInputManager()->start();
    if (result) 
        jniThrowRuntimeException(env, "Input manager could not be started.");
    

 
// 启动运行 InputDispatcher(InputDispatcherThread)  InputReader(InputReaderThread)线程
// frameworks/native/services/inputflinger/InputManager.cpp
status_t InputManager::start() 
    // 启动dispatcher线程
    status_t result = mDispatcher->start();
    if (result) 
        ALOGE("Could not start InputDispatcher thread due to error %d.", result);
        return result;
    
    
    // 启动InputReader线程
    result = mReader->start();
    if (result) 
        ALOGE("Could not start InputReader due to error %d.", result);

        mDispatcher->stop();
        return result;
    

    return OK;
 

InputDispatcher、InputReader 线程threadLoop

当native层InputManager启动InputDispatcher、InputReader线程后,这两个线程就会进入threadLoop环节,至此IMS启动完成。

// frameworks/native/services/inputflinger/InputDispatcher.cpp
bool InputDispatcherThread::threadLoop() 
    mDispatcher->dispatchOnce();
    return true;

 
// frameworks/native/services/inputflinger/InputReader.cpp
bool InputReaderThread::threadLoop() 
    mReader->loopOnce();
    return true;
 

三、 总结

以上就是对IMS的启动总体流程做了大致的梳理,现在总结出IMS启动流程的时序图,其中EventHub相关知识、input事件分发流程以及native层Input事件注入等重要环节将在之后的章节中重点讨论。

最后

如果大伙有什么好的学习方法或建议欢迎大家在评论中积极留言哈,希望大家能够共同学习、共同努力、共同进步。

小编在这里祝小伙伴们在未来的日子里都可以 升职加薪,当上总经理,出任CEO,迎娶白富美,走上人生巅峰!!

不论遇到什么困难,都不应该成为我们放弃的理由!

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,需要一份小编整理出来的学习资料的关注我主页或者点击扫描下方二维码免费领取~

这里是关于我自己的Android 学习,面试文档,视频收集大整理**,有兴趣的伙伴们可以看看~

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。

以上是关于Android framework重要服务之InputManagerService的启动流程的主要内容,如果未能解决你的问题,请参考以下文章

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android Framework 记录之二

Android Framework 之 Window / WindowManager基本概念及addView源码分析

Android Framework 之 Window / WindowManager基本概念及addView源码分析