Android源码分析:系统进程中事件的读取与分发
之前分析的是从InputChannel中读取Event,并且向后传递,进行消费和处理的过程。但是之前的部分呢,事件如何产生,事件怎么进入到InputChanel当中的,事件又是如何跨进程到达App进程,这里继续来分析。 以上为system进程的流程的简化图,这里我们可以看到几个重要的组件,这里以触摸事件来进行分析(后文的分析也将会以触摸事件为主进行分析)并且简单的描绘了事件从EventHub到服务端的InputChannel发送事件的全部过程。具体内容一起来看下面的代码。 InputManagerService的创建 因为事件的分发涉及到不少类,我们先从InputManagerService(IMS)的初始化出发,进行分析。入口代码在SystemServer.java中,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 private void startOtherServices(@NonNull TimingsTraceAndSlog t) { WindowManagerService wm = null; InputManagerService inputManager = null; inputManager = new InputManagerService(context); wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore, new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager); ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO); ServiceManager.addService(Context.INPUT_SERVICE, inputManager, /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL); inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback()); inputManager.start(); } 这里我们可以看到WMS的创建我们传入了IMS,并且IMS也依赖WindowMnagerCallbacks,我们先看一下IMS的构造方法。 1 2 3 4 5 6 7 8 9 10 11 public InputManagerService(Context context) { this(new Injector(context, DisplayThread.get().getLooper())); } @VisibleForTesting InputManagerService(Injector injector) { ... mHandler = new InputManagerHandler(injector.getLooper()); mNative = injector.getNativeService(this); ... } 我们主要关注这个mNative的构建,它是NativeImpl,它的创建过程如下: 1 new NativeInputManagerService.NativeImpl(service, mContext, mLooper.getQueue()); 这里的Looper是前面传进来的DisplayThread的Looper。在NativeImpl的构造方法中调用了init方法,并获取到了它的native指针,这里需要看com_android_server_input_InputManagerService.cpp中的natvieInit方法,代码如下: 1 2 3 4 5 6 7 8 static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj, jobject contextObj, jobject messageQueueObj) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, messageQueue->getLooper()); im->incStrong(0); return reinterpret_cast<jlong>(im); } 这里创建了NativeInputManager。 NativeInputManager初始化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 NativeInputManager::NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper) : mLooper(looper), mInteractive(true) { JNIEnv* env = jniEnv(); mServiceObj = env->NewGlobalRef(serviceObj); { AutoMutex _l(mLock); mLocked.systemUiLightsOut = false; mLocked.pointerSpeed = 0; mLocked.pointerAcceleration = android::os::IInputConstants::DEFAULT_POINTER_ACCELERATION; mLocked.pointerGesturesEnabled = true; mLocked.showTouches = false; mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT; } mInteractive = true; InputManager* im = new InputManager(this, this); mInputManager = im; defaultServiceManager()->addService(String16("inputflinger"), im); } 这个构造方法中,传入的jobject为我们之前的NativeImpl,后面有需要调用java层的时候会用到它。除此之外我们看到又创建了一个InputManger,并且把它注册到了ServiceManger当中,名称为inputflinger。 我们继续看InputManager的初始化代码,它传如的两个参数readerPolicy和dispatcherPolicy的实现都在NativeInputManager当中。它的代码如下: 1 2 3 4 5 6 7 8 InputManager::InputManager( const sp<InputReaderPolicyInterface>& readerPolicy, const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) { mDispatcher = createInputDispatcher(dispatcherPolicy); mClassifier = std::make_unique<InputClassifier>(*mDispatcher); mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mClassifier); mReader = createInputReader(readerPolicy, *mBlocker); } 这里首先创建了InputDispatcher,之后创建的mClassifier、mBlocker和InputDispatcher一样都是继承自InputListenerInterface,它们的作用为在事件经过InputDispatcher分发之前,可以做一些预处理。最后创建InputReader,事件会经由它传递到InputDispatcher,最后再由InputDispatcher分到到InputChannel。下面来详细分析。 事件源的初始化 因为InputDispatcher初始化代码比较简单,我们从createInputReader的源码开始看起来: 1 2 3 4 std::unique_ptr<InputReaderInterface> createInputReader( const sp<InputReaderPolicyInterface>& policy, InputListenerInterface& listener) { return std::make_unique<InputReader>(std::make_unique<EventHub>(), policy, listener); } 我们可以看到在创建InputReader之前首先创建了一个EventHub,看名字我们就知道它是一个事件的收集中心。我们看它的构造方法,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 EventHub::EventHub(void) : mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), ... mPendingINotify(false) { ensureProcessCanBlockSuspend(); mEpollFd = epoll_create1(EPOLL_CLOEXEC); //创建epoll实例,flag表示执行新的exec时候会自动关闭 mINotifyFd = inotify_init1(IN_CLOEXEC); //创建inotify实例,该实例用于监听文件的变化 if (std::filesystem::exists(DEVICE_INPUT_PATH, errorCode)) { addDeviceInputInotify(); } else { addDeviceInotify(); isDeviceInotifyAdded = true; } struct epoll_event eventItem = {}; eventItem.events = EPOLLIN | EPOLLWAKEUP; eventItem.data.fd = mINotifyFd; int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem); int wakeFds[2]; result = pipe2(wakeFds, O_CLOEXEC); mWakeReadPipeFd = wakeFds[0]; mWakeWritePipeFd = wakeFds[1]; result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK); result = fcntl(mWakeWritePi
以上内容来自博客订阅源,版权归原作者。关注作者后可以在 关注列表 第一时间查看作者文章。

登录后,加入这场讨论。
登录参与