Android输入系统(二)

Android输入系统(二)

前言:
今天大概来说说启动流程
由于我们前面文章提到过,SystemServer中启动了所有的Java服务,那么当然也包括输入系统的Java服务

启动InputManagerService

@(/frameworks/base/services/java/com/android/server/SystemServer.java)

    inputManager = new InputManagerService(context);//[1]
    wm = WindowManagerService.main(context, inputManager,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
            !mFirstBoot, mOnlyCore);
    ServiceManager.addService(Context.WINDOW_SERVICE, wm);
    ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
    mSystemServiceManager.startService(VrManagerService.class);
    mActivityManagerService.setWindowManager(wm);
    inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
    inputManager.start();//[2]

上面代码可以看出InputManagerService和WMS有着密不可分的关系,我们暂时不去深究内部关系,重点关心输入系统的结构上

1.InputManagerService构造函数

 public InputManagerService(Context context) {
        this.mContext = context;
        this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());//对DisplayThread线程进行消息处理
        mUseDevInputEventForAudioJack =
                context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
        mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());//[1.1]指向native input manager service object.
        LocalServices.addService(InputManagerInternal.class, new LocalService());//将服务添加到本地服务的全局注册表
    }

小结:
- 使用DisplayThread线程进行消息处理
- 指向native层的InputManagerService

1.1nativeInit()

@(com_android_server_input_InputManagerService.cpp)

static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);//得到DisplayThread的MessageQueue
    if (messageQueue == NULL) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }
    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
            messageQueue->getLooper());//[1.1.1]创建Native层的NativeInputManager对象
    im->incStrong(0);
    return reinterpret_cast<jlong>(im);
}

小结:
- 传递进来的是java层的InputManagerService对象引用和全局Context和DisplayThread的Loop
- 创建Ntive层的NativeInputManager对象

1.1.1NativeInputManager

@(com_android_server_input_InputManagerService.cpp)

NativeInputManager::NativeInputManager(jobject contextObj,
        jobject serviceObj, const sp<Looper>& looper) :
        mLooper(looper), mInteractive(true) {
    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;
    }
    mInteractive = true;
    sp<EventHub> eventHub = new EventHub();//创建EventHbu对象[1.1.1.1]
    mInputManager = new InputManager(eventHub, this, this);//[1.1.1.2]创建InputManager对象
}

小结:
- 将looper给成员变量mLooper,Context给mContextObj,java层的InputManagerService引用给mServiceObj
- 创建EventHub对象
- 创建InputManager对象,传入NativeInputManager和eventHub,其中NativeInputManager存有java层的InputManagerService对象引用和全局Context和DisplayThread的Loop

1.1.1.1EventHub

@(framework\native\services\inputflinger\EventHbu.cpp)

EventHub::EventHub(void) :
        mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mControllerNumbers(),
        mOpeningDevices(0), mClosingDevices(0),
        mNeedToSendFinishedDeviceScan(false),
        mNeedToReopenDevices(false), mNeedToScanDevices(true),
        mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) {
    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);

    mEpollFd = epoll_create(EPOLL_SIZE_HINT);//创建epoll
    ...
    mINotifyFd = inotify_init();//初始化inotify
    int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);//添加观测目录"/dev/input"
    struct epoll_event eventItem;
    memset(&eventItem, 0, sizeof(eventItem));
    eventItem.events = EPOLLIN;
    eventItem.data.u32 = EPOLL_ID_INOTIFY;
    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);//将mINotifyFd添加到epoll中
    int wakeFds[2];//两个文件句柄,因为要跨进程所以必须将其中一个传递到另外一个非父子进程中
    result = pipe(wakeFds);//通过管道实现
    mWakeReadPipeFd = wakeFds[0];
    mWakeWritePipeFd = wakeFds[1];
    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);//设置管道的读写是非阻塞
    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
    ...
    eventItem.data.u32 = EPOLL_ID_WAKE;
    //将管道读添加到epoll中
    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
    ...
    int major, minor;
    getLinuxRelease(&major, &minor);
    ...
    mUsingEpollWakeup = major > 3 || (major == 3 && minor >= 5);
}

小结:
- 创建epoll用于监听文件的更新情况
- 创建inotify用于监听目录的更新情况
- 创建管道用于进程间通信

1.1.1.2InputManager
InputManager::InputManager(
        const sp<EventHubInterface>& eventHub,
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
    mDispatcher = new InputDispatcher(dispatcherPolicy);//[1.1.1.2.1]创建InputDispatcher
    mReader = new InputReader(eventHub, readerPolicy, mDispatcher);//[1.1.1.2.2]创InputReader
    initialize();//[1.1.1.2.3]
}
---------------------------------------------------------------------------------------------
>这里注意传递new InputReader传递进来的参数是NativeInputManager.this,对照参数的接收
class NativeInputManager : public virtual RefBase,
    public virtual InputReaderPolicyInterface,
    public virtual InputDispatcherPolicyInterface,
    public virtual PointerControllerPolicyInterface {

小结:
- 创建InputDispatcher
- 创建InputReader并且创建InputReaderThread和InputDispatcherThread两个线程

1.1.1.2.1InputDispatcher
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
    mPolicy(policy),
    mPendingEvent(NULL), mLastDropReason(DROP_REASON_NOT_DROPPED),
    mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
    mNextUnblockedEvent(NULL),
    mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
    mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
    mLooper = new Looper(false);//创建Loop
    mKeyRepeatState.lastKeyEntry = NULL;
    policy->getDispatcherConfiguration(&mConfig);//[1.1.1.2.1.1]//policy是NativeInputManager.this
}
#1.1.1.2.1.1getDispatcherConfiguration()
void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
    JNIEnv* env = jniEnv();
    jint keyRepeatTimeout = env->CallIntMethod(mServiceObj,
            gServiceClassInfo.getKeyRepeatTimeout);
    if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
        outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
    }
    jint keyRepeatDelay = env->CallIntMethod(mServiceObj,
            gServiceClassInfo.getKeyRepeatDelay);
    if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
        outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
    }
}
1.1.1.2.2InputReader
InputReader::InputReader(const sp<EventHubInterface>& eventHub,
        const sp<InputReaderPolicyInterface>& policy,
        const sp<InputListenerInterface>& listener) :
        mContext(this), mEventHub(eventHub), mPolicy(policy),
        mGlobalMetaState(0), mGeneration(1),
        mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
        mConfigurationChangesToRefresh(0) {
    mQueuedListener = new QueuedInputListener(listener);

    { // acquire lock
        AutoMutex _l(mLock);
        refreshConfigurationLocked(0);
        updateGlobalMetaStateLocked();
    } // release lock
}
1.1.1.2.3initialize()

创建两个线程

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

2inputManager.start()

   public void start() {
        nativeStart(mPtr);//[2.1]
        registerPointerSpeedSettingObserver();
        registerShowTouchesSettingObserver();
        registerAccessibilityLargePointerSettingObserver();
        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                updatePointerSpeedFromSettings();
                updateShowTouchesFromSettings();
                updateAccessibilityLargePointerFromSettings();
            }
        }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
        updatePointerSpeedFromSettings();//更新触摸点速度
        updateShowTouchesFromSettings();//显示触摸点
        updateAccessibilityLargePointerFromSettings();//更新是否允许触摸点
    }
2.1nativeStart()

@(com_android_server_input_InputManagerService.cpp)

//注意这里的ptr是mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
//记录的是NativeInputManager对象
static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
    status_t result = im->getInputManager()->start();
    if (result) {
        jniThrowRuntimeException(env, "Input manager could not be started.");
    }
}
2.1.1NativeInputManager.start()

@(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;
}

运行NativeInputManager中的两个线程
mReaderThread = new InputReaderThread(mReader);
mDispatcherThread = new InputDispatcherThread(mDispatcher);

总结:
java层:
- 在InputManagerService的构造中传入DisplayThread线程的Looper.使用DisplayThread的Message消息队列
- 加入本地服务中
- 将InputManagerServce传递到WMS中
- 将InputManagerService添加到ServiceManager中
- 启动inputManager服务

Native层:
- 创建Native层的NativeInputManager就是Java层的InputManagerService
- NativeInputManager对象持有Java层的Context,InputManagerService.this等等
- 创建EventHub,InputManager
- 使用epoll,inotify机制
- 开启两个线程,一个用于接收事件派发,一个用于获取事件处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值