zoukankan      html  css  js  c++  java
  • Linux/Android——Input系统之frameworks层InputManagerService (六)【转】

    本文转载自:http://blog.csdn.net/u013491946/article/details/72638954

     
     

          上一篇Linux/Android——input系统之 kernel层 与 frameworks层交互 (五)  中有介绍kernel层一下以及与Android这边frameworks层之间的联系,算是打通android 应用层与 kernel驱动层,对整个input系统的学习是至关重要的,其中frameworks层只是简单记录了几个接入点,这里开始分析frameworks层的细节部分。

                                                撰写不易,转载需注明出处:http://blog.csdn.net/jscese/article/details/42392311

    input服务的启动:

     android启动的时候会启动很多个service,这个可以参考SystemServer.Java ,会启动InputManagerService这个服务:

    [objc] view plain copy
     
     
     
     
    1.    Slog.i(TAG, "Input Manager");  
    2.             inputManager = new InputManagerService(context, wmHandler);  
    3.   
    4. ...  
    5.   
    6.             ServiceManager.addService(Context.INPUT_SERVICE, inputManager);  

    直接看InputManagerService.java中的start函数:

    [java] view plain copy
     
     
     
     
    1.     public void start() {  
    2.         Slog.i(TAG, "Starting input manager");  
    3.         nativeStart(mPtr);   //调用了本地方法,JNI对应的cpp 在server下的jni目录下  
    4.   
    5. ...  
    6.   
    7. }  

    这个牵扯到android的server的jni,最开始是在SystemServer中加载android_server这个动态库,

    至于这个动态库的编译可参考/frameworks/base/services/jni/Android.mk中的内容

    所以在调用这个nativeStart方法时,相关的动态库已经加载到SystemServer的进程中。

    先看下这个start函数在jni文件中的实现,frameworks/base/services/jni/com_android_server_input_InputManagerService.cpp中:

    [objc] view plain copy
     
     
     
     
    1. static void nativeStart(JNIEnv* env, jclass clazz, jint ptr) {  
    2.     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);  //这个NativeInputManager 是在上面InputMangerService构造的时候调用nativeInit时new出来的  
    3.   
    4.     status_t result = im->getInputManager()->start(); //这里是调用了NativeInputManager中的InputManager中的start方法,同样这个InputManager是NativeInputManager构造的时候new出来的  
    5.     if (result) {  
    6.         jniThrowRuntimeException(env, "Input manager could not be started.");  
    7.     }  
    8. }  

    其实熟悉JNI的话,我分析到这里,就应该差不多了。。对于JNI 不是很了解的话可以参考我之前的博客:Andorid——ubuntu下的 NDK / JNI 

     

    看下NativeInputManager构造函数中的:

    [objc] view plain copy
     
     
     
     
    1. sp<EventHub> eventHub = new EventHub();  
    2. mInputManager = new InputManager(eventHub, this, this);  

    这里的JNI部分就不多说了,现在就看这个InputManager的start方法,上面提到到Android.mk,可以看到include了一个libinput的动态库,

    而这个动态库的路径是在/frameworks/base/services/input下,这就明了啦.此目录下有InputManager.cpp . EventHub.cpp等

    直接看start:

    [objc] view plain copy
     
     
     
     
    1. status_t InputManager::start() {  
    2.     status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);  //这个mDispatcherThread是在InputManager构造函数里调用initialize初始化,这里很明显启动了这个名为InputDispatcher的线程  
    3.     if (result) {  
    4.         ALOGE("Could not start InputDispatcher thread due to error %d.", result);  
    5.         return result;  
    6.     }  
    7.   
    8.     result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY); //同上,开启线程  
    9.     if (result) {  
    10.         ALOGE("Could not start InputReader thread due to error %d.", result);  
    11.   
    12.         mDispatcherThread->requestExit();  
    13.         return result;  
    14.     }  
    15.   
    16.     return OK;  
    17. }  

    到这里算是看到真面目的感觉,看这两个线程,字面意思,一个是分发给input事件给当前的activity的,一个是读取从下层发上来的input事件的

    InputDispatcher分发:

     从上面的线程启动分析:

    [objc] view plain copy
     
     
     
     
    1. bool InputDispatcherThread::threadLoop() {  
    2.     mDispatcher->dispatchOnce();  
    3.     return true;  
    4. }  
    调用分发一次的函数:
    [objc] view plain copy
     
     
     
     
    1. void InputDispatcher::dispatchOnce() {  
    2.     nsecs_t nextWakeupTime = LONG_LONG_MAX;  
    3.     { // acquire lock  
    4.         AutoMutex _l(mLock);  
    5.         mDispatcherIsAliveCondition.broadcast();  
    6.   
    7.         // Run a dispatch loop if there are no pending commands.  
    8.         // The dispatch loop might enqueue commands to run afterwards.  
    9.         if (!haveCommandsLocked()) {           //如果有缓存的命令就调用下面的runCommand去执行,没有的话这里去检查是否有新的input事件,这里定义一个唤醒时间控制  
    10.             dispatchOnceInnerLocked(&nextWakeupTime);  
    11.         }  
    12.   
    13.         // Run all pending commands if there are any.  
    14.         // If any commands were run then force the next poll to wake up immediately.  
    15.         if (runCommandsLockedInterruptible()) {  
    16.             nextWakeupTime = LONG_LONG_MIN;  
    17.         }  
    18.     } // release lock  
    19.   
    20.     // Wait for callback or timeout or wake.  (make sure we round up, not down)  
    21.     nsecs_t currentTime = now();  
    22.     int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);  
    23.     mLooper->pollOnce(timeoutMillis);  //执行上面一次分发之后,就进入了loop,这个loop会持续的检测对应的管道中是否有内容可读,而另外一个线程InputReader 读取到input事件之后就会往这个管道写入  
    24. }  

    这个是处理input事件的,后续分析,先看怎么读取事件.

    InputReader读取:

      源码位于frameworks/base/libs/ui/InputReader.cpp ,开启线程如下:

    [objc] view plain copy
     
     
     
     
    1. bool InputReaderThread::threadLoop() {  
    2.     mReader->loopOnce();  
    3.     return true;  
    4. }  

    这里看这个loopOnce:
    [objc] view plain copy
     
     
     
     
    1. void InputReader::loopOnce() {  
    2.   
    3. ...  
    4.   
    5.    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);  //这里去获取event事件  
    6.   
    7. ...  
    8.   
    9.         if (count) {  
    10.             processEventsLocked(mEventBuffer, count); //如果获取到事件,就处理  
    11.         }  
    12.   
    13. ...  
    14.   
    15. }  

    可以看到这里就到了获取event事件了。上一篇中有提到!

    getEvent中会一直read,直到get到event之后,通过precessevent处理,最终会唤醒上面介绍到的InputDispatcherThread,通知它有新的事件来了

  • 相关阅读:
    windows下基于IIS配置ssl证书
    IIS HTTP重定向到HTTPS
    C#:调用存储过程方法
    IIS无法启动解决方案
    C#工具:ASP.net 调用MySQL 帮助类(包括存储过程调用)
    C#工具:ASP.net 调用SQLserver帮助类
    HTTPClick调用WebApi帮助类
    三元运算符判断三种状态
    pandas模块
    numpy模块
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/7808955.html
Copyright © 2011-2022 走看看