android /inputmanager-jni,Linux/Android——Input系统之frameworks层InputManagerService (六)【转】...

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

input服务的启动:

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

Slog.i(TAG, "Input Manager");

inputManager = new InputManagerService(context, wmHandler);

...

ServiceManager.addService(Context.INPUT_SERVICE, inputManager);

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

public void start() {

Slog.i(TAG, "Starting input manager");

nativeStart(mPtr);   //调用了本地方法,JNI对应的cpp 在server下的jni目录下

...

}

这个牵扯到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中:

static void nativeStart(JNIEnv* env, jclass clazz, jint ptr) {

NativeInputManager* im = reinterpret_cast(ptr);  //这个NativeInputManager 是在上面InputMangerService构造的时候调用nativeInit时new出来的

status_t result = im->getInputManager()->start(); //这里是调用了NativeInputManager中的InputManager中的start方法,同样这个InputManager是NativeInputManager构造的时候new出来的

if (result) {

jniThrowRuntimeException(env, "Input manager could not be started.");

}

}

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

看下NativeInputManager构造函数中的:

sp eventHub = new EventHub();

mInputManager = new InputManager(eventHub, this, this);

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

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

直接看start:

status_t InputManager::start() {

status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);  //这个mDispatcherThread是在InputManager构造函数里调用initialize初始化,这里很明显启动了这个名为InputDispatcher的线程

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;

}

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

InputDispatcher分发:

从上面的线程启动分析:

bool InputDispatcherThread::threadLoop() {

mDispatcher->dispatchOnce();

return true;

}

调用分发一次的函数:

void InputDispatcher::dispatchOnce() {

nsecs_t nextWakeupTime = LONG_LONG_MAX;

{ // acquire lock

AutoMutex _l(mLock);

mDispatcherIsAliveCondition.broadcast();

// Run a dispatch loop if there are no pending commands.

// The dispatch loop might enqueue commands to run afterwards.

if (!haveCommandsLocked()) {           //如果有缓存的命令就调用下面的runCommand去执行,没有的话这里去检查是否有新的input事件,这里定义一个唤醒时间控制

dispatchOnceInnerLocked(&nextWakeupTime);

}

// Run all pending commands if there are any.

// If any commands were run then force the next poll to wake up immediately.

if (runCommandsLockedInterruptible()) {

nextWakeupTime = LONG_LONG_MIN;

}

} // release lock

// Wait for callback or timeout or wake.  (make sure we round up, not down)

nsecs_t currentTime = now();

int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);

mLooper->pollOnce(timeoutMillis);  //执行上面一次分发之后,就进入了loop,这个loop会持续的检测对应的管道中是否有内容可读,而另外一个线程InputReader 读取到input事件之后就会往这个管道写入

}

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

InputReader读取:

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

bool InputReaderThread::threadLoop() {

mReader->loopOnce();

return true;

}

这里看这个loopOnce:

void InputReader::loopOnce() {

...

size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);  //这里去获取event事件

...

if (count) {

processEventsLocked(mEventBuffer, count); //如果获取到事件,就处理

}

...

}

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值