InputManager启动流程
文章目录
一. InputManagerService的创建
SystemServer.java
private void startOtherServices() {
// ...省略
// 创建InputManagerService对象
inputManager = new InputManagerService(context);
// 将服务添加到SystemManager中
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
// 调用start方法开启线程
inputManager.start();
// ... 省略
}
InputManagerService.java
public InputManagerService(Context context) {
this.mContext = context;
this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
// native初始化
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
// ... 省略
}
com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
// Java端传进来的messagequeue,转化成native的
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
// 创建NativeIputManager
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
messageQueue->getLooper());
im->incStrong(0);
// 地址返回到Java端保存
return reinterpret_cast<jlong>(im);
}
- 获取Java端MessageQueue
- 创建一个NativeInputManager
- 将NativeInputManager的地址返回,也就是说InputManagerService拥有NativeManager的指针
二. NativeInputManager的创建过程
再看创建NativeInputManager的过程
NativeInputManager::NativeInputManager(jobject contextObj,
jobject serviceObj, const sp<Looper>& looper) :
mLooper(looper), mInteractive(true) {
JNIEnv* env = jniEnv();
// 将context和InputManagerService变成全局引用
mContextObj = env->NewGlobalRef(contextObj);
mServiceObj = env->NewGlobalRef(serviceObj);
// ... 省略
// 创建一个EventHub
sp<EventHub> eventHub = new EventHub();
// 创建InputManager
mInputManager = new InputManager(eventHub, this, this);
}
这里主要将context和InputManagerService的引用变为全局,可能后面会用,创建了一个EventHub(下面分析)以及创建了一个InptuManager
也就是说,NativeInputManager包含了一个InputManager,InputManager包含了一个EventHub
继续看EventHub的创建
三. EventHub的创建过程
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);
// 创建epoll
mEpollFd = epoll_create(EPOLL_SIZE_HINT);
LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno);
// 初始化inotify
mINotifyFd = inotify_init();
// static const char *DEVICE_PATH = "/dev/input";
// inotify添加DEVICE_PATH路径进行监听
int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
LOG_ALWAYS_FATAL_IF(result < 0, "Could not register INotify for %s. errno=%d",
DEVICE_PATH, errno);
struct epoll_event eventItem;
memset(&eventItem, 0, sizeof(eventItem));
eventItem.events = EPOLLIN;
eventItem.data.u32 = EPOLL_ID_INOTIFY;
// 添加fd到epoll
result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance. errno=%d", errno);
// ... 省略
}
EventHub的构造方法中主要是创建了一个epoll以及inotify的初始化,是为了监听/dev/input目录的文件变化,猜测应该是为了热插拔
接下来再看InputManager的创建过程
四. InputManager的创建过程
InputManager::InputManager(
const sp<EventHubInterface>& eventHub, // 前面创建的eventhub
const sp<InputReaderPolicyInterface>& readerPolicy, // inputReader
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) { // inputDispatcher
// 前面构造方法中传的是this说明NativeInputManager实现了InputReaderPolicyInterface和InputDispatcherPolicyInterface
// 创建InputDispatcher
mDispatcher = new InputDispatcher(dispatcherPolicy);
// 创建InputReader
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
// 线程创建,后面说
initialize();
}
上面这段主要是创建了InputDispatcher和InputReader的对象,并在initialize中创建了InputDispatcher的线程和InputReader的线程,其中在创建InputReader的时候给eventhub和InputDispatcher传进去了,接下来分析InputDispatcher和InputReader的创建过程
五. InputDispatcher的创建过程
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);
mKeyRepeatState.lastKeyEntry = NULL;
policy->getDispatcherConfiguration(&mConfig);
}
好像没看到很关键的东西,暂时跳过,继续看InputReader的创建过程
六. InputReader的创建过程
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();
//!!! Changed,for control touch device enable, modify by ZhouYou,Start
mPropertyMonitorThread = new PropertyMonitorThread(this);
mTouchEnable = true;
mPropertyMonitorThread->run("PropertyMonitorThread", PRIORITY_URGENT_DISPLAY);
//!!! Changed,for control touch device enable, modify by ZhouYou,End
} // release lock
}
好像也没啥关键的,我们目前只需要知道他们的关系就行了
- NativeInputManager创建了InputManager
- InputManager创建了EventHub,InputReader,InputDispatcher
继续看initialize()
七. 工作线程创建
void InputManager::initialize() {
mReaderThread = new InputReaderThread(mReader);
mDispatcherThread = new InputDispatcherThread(mDispatcher);
}
上面这个比较简单,就是创建了两个线程,仅仅是创建,并未启动
简单总结一下:
- SystemServer创建了InputManagerService
- InputManagerService创建了NativeInputManager
- NativeInputManager创建了InputManager
- InputManager创建了EventHub,InputReader,InputDispatcher,以及InputReaderThread,InputDispatcherThread
- Java端的InputManagerService持有NativeInputManager的指针
基本关系如上
继续往回分析,所有的对象都创建完成之后,NativeInputManager的构造方法也就结束了,如下:
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
messageQueue->getLooper());
return reinterpret_cast<jlong>(im);
将NativeInputManager的指针返回后nativeInit方法也就结束了
public InputManagerService(Context context) {
// ... 省略
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
// ... 省略
}
nativeInit返回后,InputManagerService也创建完成了,我们回过去继续看SystemServer的代码,如下
private void startOtherServices() {
// ...省略
// 创建InputManagerService对象
inputManager = new InputManagerService(context);
// 将服务添加到SystemManager中
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
// 调用start方法开启线程
inputManager.start();
// ... 省略
}
在创建完成InputManagerService之后,除了将它添加到ServiceManager中之外,还调用了它的start方法,我们继续看start方法
八. 线程启动
public void start() {
Slog.i(TAG, "Starting input manager");
nativeStart(mPtr); // 这里就是nativeInit返回的NativeInputManager的指针地址,这里又传回去了
// ... 省略
}
继续分析native方法 com_android_server_input_InputManagerService.cpp
static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
// 将上面传进来的地址转化成NativeInputManager的指针
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
// 调用了InputManager的start方法
status_t result = im->getInputManager()->start();
if (result) {
jniThrowRuntimeException(env, "Input manager could not be started.");
}
}
继续看start方法
status_t InputManager::start() {
// 前面我们知道,在initialize方法中创建了两个线程,就是下面的两个线程,现在调用了他们的run方法
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;
}
调用完start方法,mDispatcherThread和mReaderThread就跑起来了,至此,InputManager启动流程就结束了
九. 总结
总结:
- 比较关键的三个地方是EventHub,InputReader,InputDispatcher
- 其中EventHub用来读取驱动的原始事件
- InputReader用来解析事件,包装事件
- InputDispatcher用来事件分发
具体的启动流程跟着代码走一遍就行了。