android Input专题- Q/R/S 10/11/12 InputManager源码分析

Posted Android高级知识分享官

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android Input专题- Q/R/S 10/11/12 InputManager源码分析相关的知识,希望对你有一定的参考价值。

android手机大厂Framework系统-Input系统专题实战课
https://ke.qq.com/course/4963459

[入门课,实战课,跨进程专题
ps需要学习深入framework课程和课程优惠
新课程优惠获取请加入qq群:422901085

1、SystemServer中InputManagerService创建与启动

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

    private void startOtherServices() 
 			//省略部分
            traceBeginAndSlog("StartInputManagerService");
            inputManager = new InputManagerService(context);
            traceEnd();
               traceBeginAndSlog("StartWindowManagerService");
            // WMS needs sensor service ready
            ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
            mSensorServiceStart = null;
            wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
                    new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
            ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
            ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
                    /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
            traceEnd();
 			//省略部分
 			   traceBeginAndSlog("StartInputManager");
            inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
            inputManager.start();//这里再调用start
            traceEnd();
           //省略部分
 

这里以前讲过在SystemServer中会对系统中很多service进行启动,这里我们就发现有对InputManagerService进行对应的构造和添加

2、Native层面的InputManager启动

 public InputManagerService(Context context) 
        this.mContext = context;
        this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
		
     //省略部分
        mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());

     //省略部分
    

这里InputManagerService构造方法中就是调用了nativeInit,这个方法是native方法
来看看对应的native方法:
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 == nullptr) 
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    

    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
            messageQueue->getLooper());
    im->incStrong(0);
    return reinterpret_cast<jlong>(im);

这里主要就是构造了一个NativeInputManager:
base/services/core/jni/com_android_server_input_InputManagerService.cpp

NativeInputManager::NativeInputManager(jobject contextObj,
        jobject serviceObj, const sp<Looper>& looper) :
        mLooper(looper), mInteractive(true) 
    //省略部分
    mInputManager = new InputManager(this, this);
    defaultServiceManager()->addService(String16("inputflinger"),
            mInputManager, false);


这里主要就是对我们InputManager进行构造,然后把它添加到了servicemanager,而且传递的两个参数都是NativeInputManager类本身
这里它的类结构其实是实现了几个接口方便InputManager里面传递和调用:
base/services/core/jni/com_android_server_input_InputManagerService.cpp

class NativeInputManager : public virtual RefBase,
    public virtual InputReaderPolicyInterface,
    public virtual InputDispatcherPolicyInterface,
    public virtual PointerControllerPolicyInterface 

那么接下来重点就分析我们的InputManager构造:
native/services/inputflinger/InputManager.cpp


InputManager::InputManager(
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) 
    mDispatcher = new InputDispatcher(dispatcherPolicy);
    mClassifier = new InputClassifier(mDispatcher);
    mReader = createInputReader(readerPolicy, mClassifier);
    initialize();


这里首先是进行了new InputDispatcher,再是把构造对象作为InputClassifier的构造参数,然后再是createInputReader,而且把InputClassifier对象也传递给了InputReader,看看createInputReader:

sp<InputReaderInterface> createInputReader(
        const sp<InputReaderPolicyInterface>& policy,
        const sp<InputListenerInterface>& listener) 
    return new InputReader(new EventHub(), policy, listener);


InputReader::InputReader(const sp<EventHubInterface>& eventHub,
        const sp<InputReaderPolicyInterface>& policy,
        const sp<InputListenerInterface>& listener) :
        mContext(this), mEventHub(eventHub), mPolicy(policy),
        mNextSequenceNum(1), mGlobalMetaState(0), mGeneration(1),
        mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
        mConfigurationChangesToRefresh(0) 
    mQueuedListener = new QueuedInputListener(listener);//listener是作为后面连接InputDispatcher纽带

     // acquire lock
        AutoMutex _l(mLock);
//第一次执行时候,一般都是一些初始化的,还没获取到真正一些devices相关信息
        refreshConfigurationLocked(0);
        updateGlobalMetaStateLocked();
     // release lock

这里就是构造出了InputReader,而且传递了一个EventHub,也是立即构造的,整个input系统其实就是InputReader和InputDispatcher最为重要。而且二者其实也是间接相连的:

这样才方便后面InputReader读取加工好了数据就传递到InputDispatcher中,让InputDispatcher做下一步的传递工作。

再来看到有new一个EventHub,来看看它是干啥的:
native/services/inputflinger/EventHub.cpp

EventHub::EventHub(void) :
        mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mControllerNumbers(),
        mOpeningDevices(nullptr), mClosingDevices(nullptr),
        mNeedToSendFinishedDeviceScan(false),
        mNeedToReopenDevices(false), mNeedToScanDevices(true),
        mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) 
    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);

    mEpollFd = epoll_create1(EPOLL_CLOEXEC);
//省略部分
    mINotifyFd = inotify_init();
    mInputWd = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
//省略部分

    struct epoll_event eventItem;
    memset(&eventItem, 0, sizeof(eventItem));
    eventItem.events = EPOLLIN;
    eventItem.data.fd = mINotifyFd;
    int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
  //省略部分
    int wakeFds[2];
    result = pipe(wakeFds);
  
    mWakeReadPipeFd = wakeFds[0];
    mWakeWritePipeFd = wakeFds[1];

    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);

    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
  
    eventItem.data.fd = mWakeReadPipeFd;
    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
   //省略部分

我相信看到这里的EventHub,大家应该会有非常非常熟悉的想到getevent源码,二者其实本质的功能都是一样的,这里使用的epoll来监听各个fd的变化,getevent中使用是poll。
这里大概可以看出EventHub职责就是来获取/dev/input/路径设备的,及对数据进行获取,和getevent职责一样,后面再使用到的时候再进行具体分析。

接下来继续分析InputManager构造的最后一个方法initialize:

void InputManager::initialize() 
    mReaderThread = new InputReaderThread(mReader);
    mDispatcherThread = new InputDispatcherThread(mDispatcher);

这里把mReaderThread和mDispatcherThread构造出来了,它们就是native层面的Thread对象,这里在入门课时候就已经讲解过了,但是这里只是创建了线程并没有启动,那么到这里构造部分就分析完成了,但是还没看到最关键的两个线程启动。其实这个启动是在文章一开始的SystemServer类中startOtherServices触发的,通过调用inputManager.start()方法:
base/services/core/java/com/android/server/input/InputManagerService.java

   public void start() 
        Slog.i(TAG, "Starting input manager");
        nativeStart(mPtr);
   //省略部分
    

这里调用是nativeStart方法,有到了我们的native层:
base/services/core/jni/com_android_server_input_InputManagerService.cpp

static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) 
    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);

    status_t result = im->getInputManager()->start();
    if (result) 
        jniThrowRuntimeException(env, "Input manager could not be started.");
    

这里其实只干了一件关键事情,调用了InputManager的start:
native/services/inputflinger/InputManager.cpp

status_t InputManager::start() 
    status_t result = mDispatcherThread->run("InputDispatcher",
            PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
   //省略部分
    result = mReaderThread->run("InputReader",
            PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
   //省略部分
    return OK;

这里其实就是干了把InputDispatcher和InputReader两个线程启动运行起来,那本节课就先分析到这里,目前就算把InputDispatcher和InputReader开始执行部分引出来了。

以上是关于android Input专题- Q/R/S 10/11/12 InputManager源码分析的主要内容,如果未能解决你的问题,请参考以下文章

android Input专题- Q/R/S 10/11/12 InputManager源码分析

android Input专题- Q/R/S 10/11/12 InputReader源码分析1

android Input专题- Q/R/S 10/11/12 InputReader源码分析1

android Input专题- Q/R/S 10/11/12 InputReader源码分析1

android P/Q/R/S 9/10/11/12多任务手势动画OtherActivityInputConsumer情况-第一节

android P/Q/R/S 9/10/11/12多任务手势动画OtherActivityInputConsumer情况-第一节