网站被百度收录,wordpress退出函数,生成关键词的软件免费,微商城开店本系列博客主要描述Android 7.1系统中输入管理服务InputManagerService的源码分析。
概述
本文主要描述了InputManagerService服务的初始化和启动#xff0c;在Android7系统上InputManagerService服务的框架如下所示:
注#xff1a;箭头的方向#xff0c;并不能真实代表数…本系列博客主要描述Android 7.1系统中输入管理服务InputManagerService的源码分析。
概述
本文主要描述了InputManagerService服务的初始化和启动在Android7系统上InputManagerService服务的框架如下所示:
注箭头的方向并不能真实代表数据流向方向。 1、FrameWorks层inputManagerService对外提供服务的模块
2、JNI层因为InputManagerService要去管理底层硬件输入设备而在Android 7系统的所有与硬件相关的部分都会涉及到JNI层。用C代码去管理硬件设备;
3、Inputfliger: 是InputManager事件处理的核心事件包括事件的获取和分发等
4、kernel层主要涉及的input输入驱动并且将设备产生的事件通过inpu子系统上传给C inputflinger层;
5、硬件层具体的输入设备因为输入设备的类型很过这里只是大概罗列出了嵌入式设备上常用的几个;
InputManagerService服务的初始化和启动比较简单由SystemServer服务创建并拉起。
源码路径
本文描述中涉及的源码有:
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
framesworks/native/services/inputflinger/inputManager.cpp
InputManagerServie服务的初始化
java层的服务初始化
在系统核心服务SystemServer初始化中在启动其他服务startOtherService方法中会创建InputManagerService服务。代码片段如下所示
frameworks/base/services/java/com/android/server/SystemServer.java private void startOtherServices() {......traceBeginAndSlog(StartInputManagerService);/* 创建InputManagerService服务 */inputManager new InputManagerService(context);Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);traceBeginAndSlog(StartWindowManagerService);wm WindowManagerService.main(context, inputManager,mFactoryTestMode ! FactoryTest.FACTORY_TEST_LOW_LEVEL,!mFirstBoot, mOnlyCore);ServiceManager.addService(Context.WINDOW_SERVICE, wm);/* 注册InputManagerServie服务 */ServiceManager.addService(Context.INPUT_SERVICE, inputManager);Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);if (!disableVrManager) {traceBeginAndSlog(StartVrManagerService);mSystemServiceManager.startService(VrManagerService.class);Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);}mActivityManagerService.setWindowManager(wm);/* 设置InputManagerService的窗口回调接口 */inputManager.setWindowManagerCallbacks(wm.getInputMonitor());......}
1、在systemServer的服务中创建InputManagerService;
2、设置InputManagerService的窗口回调接口因此最终的事件要传递给上层App的Windows窗口去处理;
创建InputManagerService并进入它的构造方法继续初始化代码片段如下所示:
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java public InputManagerService(Context context) {this.mContext context;/* 创建Handler, 并使用displayThead现成的Looper */this.mHandler new InputManagerHandler(DisplayThread.get().getLooper());mUseDevInputEventForAudioJack context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);Slog.i(TAG, Initializing input manager, mUseDevInputEventForAudioJack mUseDevInputEventForAudioJack);/* 调用InputManagerService服务的JNI方法nativeInit继续初始化 */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());}
在构造方法中:
1、创建InputManagerHander并使用DisplayThread线程的Looper处理Handler消息;
2、调用InputManagerService服务的JNI方法nativeInit()方法继续初始化并且将mHandler.getLooper().getQueue()队列传递给JNI层在前面的初始化中InputManagerService自己的Handler使用了DisplayThread的Looper, 也就是说在这个地方等同于将DisplayThread线程的消息队列传递给了InputManagerService的JNI层;
native层的初始化
根据前面的描述InputManagerService服务的Java层调用nativeInit方法继续初始化Native层初始化代码片段如下所示:
a、nativeInit()
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,jobject serviceObj, jobject contextObj, jobject messageQueueObj) {/* 将java层的messageQueue对象转化到对应的native层的messageQueue对象 */spMessageQueue messageQueue android_os_MessageQueue_getMessageQueue(env, messageQueueObj);if (messageQueue NULL) {jniThrowRuntimeException(env, MessageQueue is not initialized.);return 0;}/* 创建NativeInputManager输入管理 */NativeInputManager* im new NativeInputManager(contextObj, serviceObj,messageQueue-getLooper());im-incStrong(0);/* 将native层的对象指针返回java层 */return reinterpret_castjlong(im);
}1、将java层的MessageQueue对象转化到它对应native层的C对象这个比较管理涉及到后面的事件处理暂时先不描述;
2、创建NativeInputManager对象
3、返回JNI创建的C对象的指针返回java层;
b、NativeInputManger的初始化
NativeInputManager的初始化关键代码片段如下所示
NativeInputManager::NativeInputManager(jobject contextObj,jobject serviceObj, const spLooper looper) :mLooper(looper), mInteractive(true) {....../* 创建EventHub() 事件获取*/spEventHub eventHub new EventHub();mInputManager new InputManager(eventHub, this, this);
1、创建EventHub()对象该对象主要就是获取输入事件(各种输入设备产生的事件和软件模拟产生的事件);
2、创建InputManager对象;
c、InputManager对象的初始化
framesworks/native/services/inputflinger/inputManager.cpp
InputManager对象初始化中如下所示: const spEventHubInterface eventHub,const spInputReaderPolicyInterface readerPolicy,const spInputDispatcherPolicyInterface dispatcherPolicy) {/* 创建事件分发对象 */mDispatcher new InputDispatcher(dispatcherPolicy);/* 创建事件获取对象 */mReader new InputReader(eventHub, readerPolicy, mDispatcher);initialize();
1、创建事件分发对象
2、创建事件获取对象
3、创建事件分发和事件获取线程如下所示
void InputManager::initialize() {/* 创建事件获取线程 */mReaderThread new InputReaderThread(mReader);/* 创建事件分发线程 */mDispatcherThread new InputDispatcherThread(mDispatcher);
}
至此InputManagerService服务从java层的初始化过程到JNI层的初始化过程描述完成.
InputManagerService服务启动
Java层的启动
InputManagerSerivice服务在Java层的启动也是在SystemServer服务中完成。非常简单。执行代码片段如下所示:
frameworks/base/services/java/com/android/server/SystemServer.java
/* 设置InputManagerService的窗口回调接口 */inputManager.setWindowManagerCallbacks(wm.getInputMonitor());/* 启动InputManagerService服务 */inputManager.start();
然后调用InputManagerService中的start方法关键执行代码片段如下
public void start() {Slog.i(TAG, Starting input manager);/* 调用JNI层nativeStart */nativeStart(mPtr);// Add ourself to the Watchdog monitors.Watchdog.getInstance().addMonitor(this);
1、直接调用jni层的nativeStart的接口
Native层的启动
jni层的启动关键代码片段如下所示
static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {NativeInputManager* im reinterpret_castNativeInputManager*(ptr);status_t result im-getInputManager()-start();if (result) {jniThrowRuntimeException(env, Input manager could not be started.);}
}
最终调用InputManager的start方法
framesworks/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;
}
总结
1、InputManagerService服务的注册和启动都在SystemServer服务中完成;
2、InputManagerservice服务初始化过程中会在native层注册事件获取和分发的线程
3、整个初始化过程中从Java层到native层都传递了DisplayThread线程的Looper的MessageQueue;