分析Input子系统的启动主要是看InputManagerService
的启动,InputManagerService
是java层的一个系统服务,继承IInputManager.Stub
,作为binder服务端,在SystemServer
中启动:
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
......t.traceBegin("StartInputManagerService");inputManager = new InputManagerService(context);t.traceEnd();......}
InputManagerService
public InputManagerService(Context context) {
this.mContext = context;//创建handler,运行在"android.display"线程this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());......mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());}
InputManagerService
构造函数中创建了一个InputManagerHandler
,使用的是"android.display"线程的looper对象,运行在"android.display"线程。
nativeInit
// com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
//java层MessageQueue的mPtr指向native层MessageQueue,这里//就是将mPtr强转为native层MessageQueuesp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);if (messageQueue == nullptr) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");return 0;}//创建NativeInputManagerNativeInputManager* im = new NativeInputManager(contextObj, serviceObj,messageQueue->getLooper());im->incStrong(0);return reinterpret_cast<jlong>(im);
}
nativeInit实际上就做了一件事,拿到java层InputManagerService
传递下来的"android.display"线程的Looper对应的MessageQueue获取native层MessageQueue,之后通过此native层MessageQueue的Looper创建NativeInputManager
。
NativeInputManager
// com_android_server_input_InputManagerService.cpp
NativeInputManager::NativeInputManager(jobject contextObj,jobject serviceObj, const sp<Looper>& looper) :mLooper(looper), mInteractive(true) {
JNIEnv* env = jniEnv();//java层的InputManagerService对象mServiceObj = env->NewGlobalRef(serviceObj);{
AutoMutex _l(mLock);mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;mLocked.pointerSpeed = 0;mLocked.pointerGesturesEnabled = true;mLocked.showTouches = false;mLocked.pointerCapture = false;mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;}mInteractive = true;//创建InputManagermInputManager = new InputManager(this, this);//将mInputManager添加到ServiceManager,可以通过getService获取defaultServiceManager()->addService(String16("inputflinger"),mInputManager, false);
}
NativeInputManager
构造函数也很简单,就是创建了InputManager
,并添加到ServiceManager,InputManager
是binder服务端,它的构造函数中接收两个对象:InputReaderPolicyInterface
和InputDispatcherPolicyInterface
public:InputManager(const sp<InputReaderPolicyInterface>& readerPolicy,const sp<InputDispatcherPolicyInterface>& dispatcherPolicy);
而NativeInputManager
是这两个对象的子类,所以传递的是this
class NativeInputManager : public virtual RefBase,public virtual InputReaderPolicyInterface,public virtual InputDispatcherPolicyInterface,public virtual PointerControllerPolicyInterface {
InputManager
InputManager::InputManager(const sp<InputReaderPolicyInterface>& readerPolicy,const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
//(1)mDispatcher = createInputDispatcher(dispatcherPolicy);//(2)mClassifier = new InputClassifier(mDispatcher);//(3)mReader = createInputReader(readerPolicy, mClassifier);
}
InputManager
构造函数中创建了这三个对象:
private:sp<InputDispatcherInterface> mDispatcher;sp<InputClassifierInterface> mClassifier;sp<InputReaderInterface> mReader;
};
现在来分别看看这三个对象的初始化过程,首先看(1):mDispatcher = createInputDispatcher(dispatcherPolicy)
createInputDispatcher
//InputDispatcherFactory.cpp
sp<InputDispatcherInterface> createInputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) {
return new android::inputdispatcher::InputDispatcher(policy);
}
这里简单粗暴的直接new了一个InputDispatcher
,InputDispatcher
是InputDispatcherInterface
的子类,InputDispatcher
是一个非常重要的对象,它是Input事件发送到对应窗口的分发者
// --- InputDispatcher ---InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy): mPolicy(policy),mPendingEvent(nullptr),mLastDropReason(DropReason::NOT_DROPPED),mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),mAppSwitchSawKeyDown(false),mAppSwitchDueTime(LONG_LONG_MAX),mNextUnblockedEvent(nullptr),mDispatchEnabled(false),mDispatchFrozen(false),mInputFilterEnabled(false),// mInTouchMode will be initialized by the WindowManager to the default device config.// To avoid leaking stack in case that call never comes, and for tests,// initialize it here anyways.mInTouchMode(true),mFocusedDisplayId(ADISPLAY_ID_DEFAULT) {
//创建自己的LoopermLooper = new Looper(false);mReporter = createInputReporter();mKeyRepeatState.lastKeyEntry = nullptr;//获取java层的一些配置参数,写到mConfig中,主要就是如下两个值: //public static final int DEFAULT_LONG_PRESS_TIMEOUT = 400;//private static final int KEY_REPEAT_DELAY = 50;policy->getDispatcherConfiguration(&mConfig);
}
接着再看第二个对象:(2)
mClassifier = new InputClassifier(mDispatcher);
// --- InputClassifier ---
InputClassifier::InputClassifier(const sp<InputListenerInterface>& listener): mListener(listener), mHalDeathRecipient(new HalDeathRecipient(*this)) {
}
它的构造函数非常简单,将前面创建的InputDispatcher
保存在了mListener
中,并创建了一个监听HAL的死亡回调对象,InputClassifierM
是一个空壳子,它提供的如下函数内部实现都是调用到了InputDispatcher
中去:
class InputClassifier : public InputClassifierInterface {
public:explicit InputClassifier(const sp<InputListenerInterface>& listener);virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) override;virtual void notifyKey(const NotifyKeyArgs* args) override;virtual void notifyMotion(const NotifyMotionArgs* args) override;virtual void notifySwitch(const NotifySwitchArgs* args) override;virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) override;
再看第三个对象(3)
mReader = createInputReader(readerPolicy, mClassifier);
sp<InputReaderInterface> createInputReader(const sp<InputReaderPolicyInterface>& policy,const sp<InputListenerInterface>& listener) {
return new InputReader(std::make_unique<EventHub>(), policy, listener);
}
同样是直接new的一个InputReader
,它接收了一个EventHub
对象,这个对象非常重要,它是读取驱动原始Input事件的主要类,InputReader
构造函数比较简单,代码不多,所以我们先来分析EventHub
的初始化。
// --- InputReader ---InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,const sp<InputReaderPolicyInterface>& policy,const sp<InputListenerInterface>& listener): mContext(this),mEventHub(eventHub),mPolicy(policy),mGlobalMetaState(0),mGeneration(1),mNextInputDeviceId(END_RESERVED_ID),mDisableVirtualKeysTimeout(LLONG_MIN),mNextTimeout(LLONG_MAX),mConfigurationChangesToRefresh(0) {
mQueuedListener = new QueuedInputListener(listener);{
// acquire lockAutoMutex _l(mLock);refreshConfigurationLocked(0);updateGlobalMetaStateLocked();} // release lock
}
EventHub
继承EventHubInterface
,这是它的构造函数:
EventHub::EventHub(void): mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD),mNextDeviceId(1),mControllerNumbers(),mOpeningDevices(nullptr),mClosingDevices(nullptr),mNeedToSendFinishedDeviceScan(false),mNeedToReopenDevices(false),mNeedToScanDevices(true),mPendingEventCount(0),mPendingEventIndex(0),mPendingINotify(false) {
ensureProcessCanBlockSuspend();//创建epoll,对EPOLL_CLOEXEC个fd进行监听mEpollFd = epoll_create1(EPOLL_CLOEXEC);//创建inotifymINotifyFd = inotify_init();//对"/dev/input"目录下的文件进行监听,监听事件是文件的创建与删除mInputWd = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);if (isV4lScanningEnabled()) {
//对"/dev"目录进行监听mVideoWd = inotify_add_watch(mINotifyFd, VIDEO_DEVICE_PATH, IN_DELETE | IN_CREATE);} else {
mVideoWd = -1;}//创建epoll事件结构体struct epoll_event eventItem = {
};//监听事件://EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);//EPOLLWAKEUP:系统会在事件排队时就保持唤醒,从epoll_wait调用开始,持续要下一次epoll_wait调用eventItem.events = EPOLLIN | EPOLLWAKEUP;//epoll监听的fd为mINotifyFdeventItem.data.fd = mINotifyFd;//将mINotifyFd添加到epollint result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);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.fd = mWakeReadPipeFd;//将读管道添加到epollresult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);}
如果有看过我前一篇文章AndroidR Input子系统(1)INotify与Epoll机制就会对上面这段代码非常熟悉了,简单总结下INotify与Epoll:
INotify的用法分为三步:
- 使用
inotify_init
创建一个inotify对象 - 使用
inotify_add_watch
对文件路径进行监听 - 使用
read
读取监听到的事件
Epoll的使用步骤也很简单:
- 通过
epoll_create
创建epoll对象 - 为需要监听的fd构建一个
epoll_event
结构体,并注册到epoll_ctl
进行监听 - 调用
epoll_wait
进入监听状态,传入一个epoll_event
结构体数组,用于收集监听到的事件 - 遍历第三步的
epoll_event
结构体数组,依次取出事件处理
EventHub
构造函数中结合INotify与Epoll对"/dev/input"目录进行监听,以及创建了一对管道,将读端mWakeReadPipeFd
添加到Epoll进行监听,之后只需要调用epoll_wait
等待事件发生就行了,至于在哪里调的epoll_wait
,我们后面再看。
EventHub
创建完之后再回来看InputReader
,它的构造函数就比较简单了。
InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,const sp<InputReaderPolicyInterface>& policy,const sp<InputListenerInterface>& listener): mContext(this),mEventHub(eventHub),mPolicy(policy),mGlobalMetaState(0),mGeneration(1),mNextInputDeviceId(END_RESERVED_ID),mDisableVirtualKeysTimeout(LLONG_MIN),mNextTimeout(LLONG_MAX),mConfigurationChangesToRefresh(0) {
//创建QueuedInputListener,并传入InputClassifiermQueuedListener = new QueuedInputListener(listener);{
// acquire lockAutoMutex _l(mLock);refreshConfigurationLocked(0);updateGlobalMetaStateLocked();} // release lock
}
到此InputManager
的构造函数中创建的三个对象InputDispatcher
,InputClassifier
,InputReader
就分析完了,即InputManagerService
构造方法中调用的nativeInit
函数就结束了,接着再回到SystemService
中,InputManagerService
创建完成之后,会调用它的start
方法:
//SystemService.javaprivate void startOtherServices(@NonNull TimingsTraceAndSlog t) {
......inputManager = new InputManagerService(context); ......inputManager.start();.....}
InputManagerService.start
//InputManagerService.java
public void start() {
Slog.i(TAG, "Starting input manager");nativeStart(mPtr);// 添加Watchdog的监听Watchdog.getInstance().addMonitor(this);//注册一系列Settings数据库值的监听.....}
这个方法中我们关注的是nativeStart
这个方法,mPtr指向nativeInit
中创建的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.");}
}
NativeInputManager
的getInputManager
返回nativeStart
创建的InputManager
,调用其start
函数:
status_t InputManager::start() {
//(1)status_t result = mDispatcher->start();if (result) {
ALOGE("Could not start InputDispatcher thread due to error %d.", result);return result;}//(2)result = mReader->start();if (result) {
ALOGE("Could not start InputReader due to error %d.", result);mDispatcher->stop();return result;}return OK;
}
这个函数中非常重要的两步就是分别调用了InputDispatcher
和InputReader
的start
函数,首先来看(1):
//InputDispatcher.cpp
status_t InputDispatcher::start() {
if (mThread) {
return ALREADY_EXISTS;}mThread = std::make_unique<InputThread>("InputDispatcher", [this]() {
dispatchOnce(); }, [this]() {
mLooper->wake(); });return OK;
}
mThread
如果已经存在则返回,否则创建,mThread
类型为InputThread
,InputThread
内部有一个Thread
,InputThread
的构造函数中接受三个参数:
class InputThread {
public:explicit InputThread(std::string name, std::function<void()> loop,std::function<void()> wake = nullptr);
一个string,代表此线程名称,还有两个std::function
,传递的则是两个Lambda
表达式,这两个Lambda
表达式中分别调用dispatchOnce()
和mLooper->wake()
这两个函数,接着再看InputThread
构造函数的具体实现:
//InputThread.cpp
InputThread::InputThread(std::string name, std::function<void()> loop, std::function<void()> wake): mName(name), mThreadWake(wake) {
mThread = new InputThreadImpl(loop);mThread->run(mName.c_str(), ANDROID_PRIORITY_URGENT_DISPLAY);
}
InputThread
构造函数中将接收的两个Lambda
表达式一个传递给了InputThreadImpl
,另一个保存在了自己mThreadWake
中,
InputThreadImpl
继承Thread
,是一个线程,
接着调用run
函数启动线程,线程启动之后就会调用自己的threadLoop
函数:
class InputThreadImpl : public Thread {
public:explicit InputThreadImpl(std::function<void()> loop): Thread(/* canCallJava */ true), mThreadLoop(loop) {
}~InputThreadImpl() {
}private:std::function<void()> mThreadLoop;bool threadLoop() override {
mThreadLoop();return true;}
};
InputThreadImpl
的threadLoop
函数很简单,调用了自己的mThreadLoop
函数,mThreadLoop
接收了一个Lambda
表达式:([this]() { dispatchOnce(); }
),即
线程启动时就会调用
InputThreadImplInputDispatcher
的dispatchOnce
函数,至于dispatchOnce
的细节我们在后面再分析。
接着我们再来看看InputReader
的start
函数:
status_t InputReader::start() {
if (mThread) {
return ALREADY_EXISTS;}mThread = std::make_unique<InputThread>("InputReader", [this]() {
loopOnce(); }, [this]() {
mEventHub->wake(); });return OK;
}
InputReader
的start
函数就和InputDispatcher
有异曲同工之妙了,只不过线程的名字和两个Lambda
表达式不一样,所以我们知道最终这个线程启动之后会调用InputReader
的loopOnce()
函数。
到此Input
系统的启动篇就分析完了,我们大致总结一下:
SystemServer
创建InputManagerService
这个系统服务。InputManagerService
构造方法中创建"android.display"线程,调用nativeInit
函数,将"android.display"线程的Looper对应的MessageQueue传递到native层。nativeInit
函数中创建NativeInputManager
对象,并将其指针返回到java层mPtr
保存。NativeInputManager
构造函数中创建InputManager
对象,并将其注册到ServiceManager
,其服务名称为:“inputflinger”,InputManager
构造函数中创建三个重要对象:InputDispatcher
,InputClassifier
,InputReader
,比较重要的是在构造InputReader
是创建了EventHub
对象。EventHub
构造函数中通过inotify和epoll机制对目录"/dev/input"监听,主要监听此目录下文件的创建和删除,到此nativeInit
函数完毕。SystemServer
中会接着调用InputManagerService
的start
方法,此方法中调用nativeStart
作进一步初始化,nativeStart
函数中调用InputManager
的start
函数。InputManager
的start
函数中分别调用了InputDispatcher
和InputReader
的start
函数,即分别启动了其内部线程InputThreadImpl
,InputDispatcher
内部线程(名字:“InputDispatcher”)启动调用了自己的dispatchOnce()
函数,InputReader
内部线程(名字:“InputReader”)启动调用了自己的loopOnce()
函数。