Android Input输入子系统分析

来源:互联网 发布:淘宝联盟手机版官方 编辑:程序博客网 时间:2024/05/10 09:13

最开始接触android系统便是touch驱动,属于典型的input输入子系统设备,但是从未认真总结过,蓦然回首,总结一下:

input输入子系统是对一些输入设备的总体规划,标准的接口,外设中诸如键盘,鼠标,触摸屏等都是典型的input设备,这些设备的事件处理都是走input输入子系统流程,而input系统在底层有相应的驱动,在上层有相应的守护server,首先看InputManagerService的启动:


            inputManager = new InputManagerService(context, wmHandler);            Slog.i(TAG, "Window Manager");            wm = WindowManagerService.main(context, power, display, inputManager,                    wmHandler, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,                    !firstBoot, onlyCore);            ServiceManager.addService(Context.WINDOW_SERVICE, wm);            ServiceManager.addService(Context.INPUT_SERVICE, inputManager);            ActivityManagerService.self().setWindowManager(wm);            inputManager.setWindowManagerCallbacks(wm.getInputMonitor());            inputManager.start();

首行便是初始化一个InputManagerService的实例,


public InputManagerService(Context context, Handler handler) {        this.mContext = context;        this.mHandler = new InputManagerHandler(handler.getLooper());        mUseDevInputEventForAudioJack =                context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);        Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="                + mUseDevInputEventForAudioJack);        mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());    }


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* im = new NativeInputManager(contextObj, serviceObj,            messageQueue->getLooper());    im->incStrong(0);    return reinterpret_cast<jint>(im);}

代码段如下:


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;    }    sp<EventHub> eventHub = new EventHub();    mInputManager = new InputManager(eventHub, this, this);}

初始化InputManager实例;

InputManager::InputManager(        const sp<EventHubInterface>& eventHub,        const sp<InputReaderPolicyInterface>& readerPolicy,        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {    mDispatcher = new InputDispatcher(dispatcherPolicy);    mReader = new InputReader(eventHub, readerPolicy, mDispatcher);#ifdef USE_POWER_HINT_INPUT_BOOST    mMonitor = new PhsInputMonitor(eventHub, readerPolicy);#endif    initialize();}

initialize()方法,初始化两个线程,InputReader和InputDispatcher等,

void InputManager::initialize() {    mReaderThread = new InputReaderThread(mReader);    mDispatcherThread = new InputDispatcherThread(mDispatcher);}


回到一开始的代码段的紫色行,代码调用了inputManager的start()方法:

public void start() {        Slog.i(TAG, "Starting input manager");        nativeStart(mPtr);        // Add ourself to the Watchdog monitors.        Watchdog.getInstance().addMonitor(this);        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();    }

红色标注的代码段是关键,


static void nativeStart(JNIEnv* env, jclass clazz, jint ptr) {    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);    status_t result = im->getInputManager()->start();    if (result) {        jniThrowRuntimeException(env, "Input manager could not be started.");    }}

调用至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;    }#ifdef USE_POWER_HINT_INPUT_BOOST    mMonitor->startMonitor();#endif    return OK;}

末段,开启了上边提到的两个关键线程,mDispatcherThread和mReaderThread,后面继续分析input子系统在上层的这两个关键线程:大体流程就是ReaderThread通过EventHub获取kernel上报的input事件,唤醒DispatherThread去处理相关input事件,Dispatcher根据事件的类型以及有效性做一个判断,从而决定事件发送不发送,发送给谁等。详细的方法调用流程,后面的文章会做分析。。。先告一段落!
















0 0
原创粉丝点击