天天看點

【Touch事件傳遞-- 粗略索引記錄筆記- 從Native到Java IMS到View Looper 監聽UnixDomainSocket】目的

目的

  • 粗略的索引,便于我的記憶
  • 可能不适合你觀看

線程、程序

IMS,WMS都是在SystemService程序内的不同線程

結構

  • IMS兩個Thread
    • InputReaderThread 輪訓裝置 dev/input
    • InputDispatcherThread 分發
      • 通過 InputMoniter和WMS連接配接
      • 通過InputChannel 和APP連接配接
        • 通過UnixDomainSocket 連接配接APP
        • Looper的epoll監聽了這個fd的變化
  • App的Looper傳遞給ViewRootImpl
    • Looper回調 InputEventReceiver
    • InputEventReceiver 傳遞給ViewRootImpl
  • ViewRootImpl 傳遞給 Activity
  • Activity傳遞給PhoneWindow
  • PhoneWIndow傳遞給DecorView
  • DecorView作為ViewGroup
  • ViewGroup傳遞給View

IPC

InputChannel通過UnixDomainSocket 連接配接APP

  • InputChannel 為ViewRootImpl的字段
  • setView時IPC給WMS
  • WMS将InputChannel 傳遞給 IMS的dispatcher

InputChannel将fd綁定到Looper的代碼

// ViewRootImpl
                    mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,
                            Looper.myLooper());

//WindowInputEventReceiver                    
final class WindowInputEventReceiver extends InputEventReceiver 

//InputEventReceiver 
    private InputChannel mInputChannel;
    private MessageQueue mMessageQueue;
    public InputEventReceiver(InputChannel inputChannel, Looper looper) {
//***
        mInputChannel = inputChannel;
        mMessageQueue = looper.getQueue();
        mReceiverPtr = nativeInit(new WeakReference<InputEventReceiver>(this),
                inputChannel, mMessageQueue);

//android_view_InputEventReceiver.cpp
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
        jobject inputChannelObj, jobject messageQueueObj) {
    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
            inputChannelObj);
    if (inputChannel == nullptr) {
        jniThrowRuntimeException(env, "InputChannel is not initialized.");
        return 0;
    }
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    if (messageQueue == nullptr) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }
    sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env,
            receiverWeak, inputChannel, messageQueue);
// NativeInputEventReceiver
class NativeInputEventReceiver : public LooperCallback {

void NativeInputEventReceiver::setFdEvents(int events) {
    if (mFdEvents != events) {
        mFdEvents = events;
        int fd = mInputConsumer.getChannel()->getFd();
        if (events) {
            mMessageQueue->getLooper()->addFd(fd, 0, events, this, nullptr);
        } else {
            mMessageQueue->getLooper()->removeFd(fd);
        }
    }
}
           

mMessageQueue->getLooper()->addFd(fd, 0, events, this, nullptr);

Looper epoll 監聽的fd

  • 額外監聽的IMS用的InputChannle(IPC用的unix domain socket)
  • MessageQueue enqueue導緻pipe的fd變化
  • 螢幕重新整理的那個