您的位置:首页 > 移动开发 > Android开发

Android 输入系统(一)InputManagerService

2017-03-15 13:53 316 查看
由于之前做蓝牙hid的连接,以及输入事件的读取,突然想好好研究一下andorid输入事件到底是怎么管理的。

首先先看看系统服务InputManagerService的工作。以下都是基于Andorid4.3源码。

                                                                                                                                                                                                              
               

InputManagerService产生

一般的系统服务是在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);
....
}

有上面代码总结其启动过程:

创建InputManagerService对象  

InputManagerService初始化时传递了一个参数wmHandler,其创建如下

HandlerThread wmHandlerThread = new HandlerThread("WindowManager");

        wmHandlerThread.start();

Handler wmHandler = new Handler(wmHandlerThread.getLooper());

这说明InputManagerService和WindowManagerService会有功能上的一些交互。
调用InputManagerService的start函数。
                                                                                                                                                                                                              
               

InputManagerService 初始化工作

路径: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());
}

config_useDevInputEventForAudioJack设置是在frameworks/base/core/res/res/values/config.xml中

该值为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构造函数中没有什么特别的东西,就不说了。

到这里输入系统的几个重要部分都创建完成了。如下是其结构图(网上找的)



                                                                                                                                                                                                              
               

InputManagerService启动

在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线程开始运行。

待续。。。。。。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: