由于之前做蓝牙hid的连接,以及输入事件的读取,突然想好好研究一下andorid输入事件到底是怎么管理的。
首先先看看系统服务InputManagerService的工作。以下都是基于Andorid4.3源码。
一般的系统服务是在SystemServer.java的ServerThread中启动,InputManagerService也不例外。
@Override public void run() { ..... Slog.i(TAG, "Input Manager"); //新建InputManagerService对象. inputManager = new InputManagerService(context, wmHandler); Slog.i(TAG, "Window Manager"); //这是窗口服务,先不说这个。 wm = WindowManagerService.main(context, power, display, inputManager, uiHandler, wmHandler, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL, !firstBoot, onlyCore); ServiceManager.addService(Context.WINDOW_SERVICE, wm); //将InputManagerService添加到Serviceanager,便于其他用户访问 ServiceManager.addService(Context.INPUT_SERVICE, inputManager); ActivityManagerService.self().setWindowManager(wm); inputManager.setWindowManagerCallbacks(wm.getInputMonitor()); inputManager.start();//启动服务 display.setWindowManager(wm); //向DisplayManagerService设置InputManagerService display.setInputManager(inputManager); .... }
有上面代码总结其启动过程:
路径:frameworks/base/services/java/com/android/server/input/InputManagerService.java
创建InputManagerService对象,会先调用其构造函数。构造函数如下
public InputManagerService(Context context, Handler handler) { this.mContext = context; this.mHandler = new InputManagerHandler(handler.getLooper()); //获取config_useDevInputEventForAudioJack的值,该值为true,则通过inputEvent处理耳机插拔,否则通过UEent处理耳机插拔。默认为false。 mUseDevInputEventForAudioJack = context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack); Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack=" + mUseDevInputEventForAudioJack); //调用native方法进行初始化操作 mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue()); }
该值为TRUE使用Linux /dev/input/event子系统的变化来检测开关的耳机/麦克风插孔,值为假时使用uevent框架。默认false。
<!-- When true use the linux /dev/input/event subsystem to detect the switch changes on the headphone/microphone jack. When false use the older uevent framework. --> <bool name="config_useDevInputEventForAudioJack">false</bool>
nativeInit调用到com_android_server_input_InputManagerService.cpp文件中,
路径:frameworks/base/services/jni/com_android_server_input_InputManagerService.cpp
nativeInit代码如下
static jint nativeInit(JNIEnv* env, jclass clazz, jobject serviceObj, jobject contextObj, jobject messageQueueObj) { sp<MessageQueue> 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); //返回 NativeInputManager对象的指针 return reinterpret_cast<jint>(im); }
nativeInit中主要是创建一个NativeInputManager对象,用来连接java层和native层。
NativeInputManager代码也在com_android_server_input_InputManagerService.cpp该文件中,接着看一下NativeInputManager的构造函数
NativeInputManager::NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper) : mLooper(looper) { JNIEnv* env = jniEnv(); mContextObj = env->NewGlobalRef(contextObj); mServiceObj = env->NewGlobalRef(serviceObj); { AutoMutex _l(mLock); mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE; mLocked.pointerSpeed = 0; mLocked.pointerGesturesEnabled = true; mLocked.showTouches = false; } //创建EventHub对象,该对象主要用来访问设备节点,获取输入事件、设备节点的添加和删除 sp<EventHub> eventHub = new EventHub(); //创建InputManager对象,管理InputReader与InputDispatcher. mInputManager = new InputManager(eventHub, this, this); }EventHub先不说了,之后再抽时间研究研究。
InputManager
路径:frameworks/base/services/input/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(); }接着看initialize()函数
void InputManager::initialize() { mReaderThread = new InputReaderThread(mReader); mDispatcherThread = new InputDispatcherThread(mDispatcher); }创建一个InputReaderThread线程,供InputReader运行;
创建了一个InputDispatcherThread线程,供InputDispatcher运行。
InputDispatcher和InputReader构造函数中没有什么特别的东西,就不说了。
到这里输入系统的几个重要部分都创建完成了。如下是其结构图(网上找的)
在SystemServer中调用InputManagerService的start()方法正式启动服务,函数如下:
public void start() { Slog.i(TAG, "Starting input manager"); nativeStart(mPtr); //将inputmanagerservice添加到Wathcdog中,Watchdog检测service是否正常工作 // Add ourself to the Watchdog monitors. Watchdog.getInstance().addMonitor(this); //监听数据库中的Settings.System.POINTER_SPEED、Settings.System.SHOW_TOUCHES的变化,具体还不太清楚。 registerPointerSpeedSettingObserver(); registerShowTouchesSettingObserver(); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { updatePointerSpeedFromSettings(); updateShowTouchesFromSettings(); } }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler); updatePointerSpeedFromSettings(); updateShowTouchesFromSettings(); }
nativeStart()函数调用到com_android_server_input_InputManagerService.cpp中的nativeStart()函数
static void nativeStart(JNIEnv* env, jclass clazz, jint ptr) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); //调用InputManager中的start方法。 status_t result = im->getInputManager()->start(); if (result) { jniThrowRuntimeException(env, "Input manager could not be started."); } }
nativeStart主要是调用InputManager的start()方法,并将结果返回给java层。接着看InputManager类中的start()方法。
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; }
上述方法中工作就是将mDispatcherThread、mDispatcherThread线程开始运行。
待续。。。。。。。。。。