分析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层MessageQueue
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == nullptr) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
//创建NativeInputManager
NativeInputManager* 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;
//创建InputManager
mInputManager = 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) {
//创建自己的Looper
mLooper = 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 lock
AutoMutex _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);
//创建inotify
mINotifyFd = 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为mINotifyFd
eventItem.data.fd = mINotifyFd;
//将mINotifyFd添加到epoll
int 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;
//将读管道添加到epoll
result = 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,并传入InputClassifier
mQueuedListener = new QueuedInputListener(listener);
{ // acquire lock
AutoMutex _l(mLock);
refreshConfigurationLocked(0);
updateGlobalMetaStateLocked();
} // release lock
}
到此InputManager
的构造函数中创建的三个对象InputDispatcher
,InputClassifier
,InputReader
就分析完了,即InputManagerService
构造方法中调用的nativeInit
函数就结束了,接着再回到SystemService
中,InputManagerService
创建完成之后,会调用它的start
方法:
//SystemService.java
private 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()
函数。