由于之前做蓝牙hid的连接,以及输入事件的读取,突然想好好研究一下andorid输入事件到底是怎么管理的。

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

InputManagerService产生

一般的系统服务是在SystemServer.javaServerThread中启动,InputManagerService也不例外。

@Overridepublic 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);       ....}

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

  1. 创建InputManagerService对象
    InputManagerService初始化时传递了一个参数wmHandler,其创建如下
    HandlerThread wmHandlerThread = new HandlerThread("WindowManager");
    wmHandlerThread.start();
    Handler wmHandler = new Handler(wmHandlerThread.getLooper());
    这说明InputManagerService和WindowManagerService会有功能上的一些交互。
  2. 调用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主要是调用InputManagerstart()方法,并将结果返回给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;}

上述方法中工作就是将mDispatcherThreadmDispatcherThread线程开始运行。



待续。。。。。。。。。。

更多相关文章

  1. android-viewbadger为你的Android(安卓)app中的view添加角标
  2. Android调用系统裁剪的实现方法
  3. Android(安卓)View创建和销毁调用的所有方法
  4. Android(安卓)Wi-Fi Display(Miracast)介绍
  5. android native jni 代码
  6. Android(安卓)Java笔试题(带大部分答案)
  7. android 拍照或从相册获取图片 返回 bitmap
  8. Android基于ViewPager+Fragment实现左右滑屏效果的方法
  9. 如何监听Phone的状态,第三方App如何拨打/接听电话?

随机推荐

  1. 【Android-File】Android文件的读写
  2. Android(安卓)pthread mutex 实现分析
  3. android 渐变背景
  4. Android(安卓)Error:AAPT: error: resourc
  5. android中的Touch触摸事件传递机制
  6. 【Android】事件分发机制源码解析
  7. android之Display.getRotation()_传感器
  8. android 防止反编译
  9. Android应用程序键盘(Keyboard)消息处理机
  10. android布局属性详解