aosp15版本InputReader事件如何通知到InputDispatcher的?

背景:

针对学员提出的新版本的事件通知notify部分,InputReader代码到底是如何调用到InputDispatcher的notifyMotion,notifyKey等方法的。
在这里插入图片描述

马哥这边看了aosp15的代码后,确实发现这块代码明显比以前绕了比较多,主要加入了多个层次的事件流转,有点雷士以前事件到了ViewRootImpl中要经过多个InputStage进行process,针对这块马哥今天搞一个文章专门来进行解释一下。

InputReader部分源码分析

aosp15版本源码如下
InputReader代码中在整个代码核心流程如下
frameworks/native/services/inputflinger/reader/InputReader.cpp

void InputReader::loopOnce() {
//省略部分不重要
//getEvents获取相关的RawEvent
    std::vector<RawEvent> events = mEventHub->getEvents(timeoutMillis);
  
  if (!events.empty()) {
  //处理原始RawEvent进行转变NotifyArgs
            mPendingArgs += processEventsLocked(events.data(), events.size());
        }
        
        //针对NotifyArgs进行notify
    for (const NotifyArgs& args : notifyArgs) {
        ATRACE_NAME("mNextListener.notify");
        mNextListener.notify(args);
    }

}

在新版本这里mNextListener.notify(args)具体调用到哪里呢?
mNextListener实际上是InputReader构造时候传递进来的

InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
                         const sp<InputReaderPolicyInterface>& policy,
                         InputListenerInterface& listener)
      : mContext(this),
        mEventHub(eventHub),
        mPolicy(policy),
        mNextListener(listener),

构造InputReader是在createInputReader进行构造的:
frameworks/native/services/inputflinger/reader/InputReaderFactory.cpp

//第二个参数就是给上面的mNextListener赋值的
std::unique_ptr<InputReaderInterface> createInputReader(
        const sp<InputReaderPolicyInterface>& policy, InputListenerInterface& listener) {
    return std::make_unique<InputReader>(std::make_unique<EventHub>(), policy, listener);
}

那么什么时候调用的createInputReader呢?
frameworks/native/services/inputflinger/InputManager.cpp

/**
 * The event flow is via the "InputListener" interface, as follows:
 *   InputReader
 *     -> UnwantedInteractionBlocker
 *     -> InputFilter
 *     -> PointerChoreographer
 *     -> InputProcessor
 *     -> InputDeviceMetricsCollector
 *     -> InputDispatcher
 */
InputManager::InputManager(const sp<InputReaderPolicyInterface>& readerPolicy,
                           InputDispatcherPolicyInterface& dispatcherPolicy,
                           PointerChoreographerPolicyInterface& choreographerPolicy,
                           InputFilterPolicyInterface& inputFilterPolicy) {
    mInputFlingerRust = createInputFlingerRust();

    mDispatcher = createInputDispatcher(dispatcherPolicy);
    mTracingStages.emplace_back(
            std::make_unique<TracedInputListener>("InputDispatcher", *mDispatcher));

    if (ENABLE_INPUT_FILTER_RUST) {
        mInputFilter = std::make_unique<InputFilter>(*mTracingStages.back(), *mInputFlingerRust,
                                                     inputFilterPolicy);
        mTracingStages.emplace_back(
                std::make_unique<TracedInputListener>("InputFilter", *mInputFilter));
    }

    if (ENABLE_INPUT_DEVICE_USAGE_METRICS) {
        mCollector = std::make_unique<InputDeviceMetricsCollector>(*mTracingStages.back());
        mTracingStages.emplace_back(
                std::make_unique<TracedInputListener>("MetricsCollector", *mCollector));
    }

    mProcessor = std::make_unique<InputProcessor>(*mTracingStages.back());
    mTracingStages.emplace_back(
            std::make_unique<TracedInputListener>("InputProcessor", *mProcessor));

    mChoreographer =
            std::make_unique<PointerChoreographer>(*mTracingStages.back(), choreographerPolicy);
    mTracingStages.emplace_back(
            std::make_unique<TracedInputListener>("PointerChoreographer", *mChoreographer));

    mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mTracingStages.back());
    mTracingStages.emplace_back(
            std::make_unique<TracedInputListener>("UnwantedInteractionBlocker", *mBlocker));
//传递的mTracingStages.back作为第二个参数,
    mReader = createInputReader(readerPolicy, *mTracingStages.back());
}

这里看到最后 *mTracingStages.back()指的就是mTracingStages集合中最后一个,也就是

std::make_unique<TracedInputListener>("UnwantedInteractionBlocker", *mBlocker)

然后可以看到是一个TracedInputListener类型

/*
 * An implementation of the listener interface that traces the calls to its inner listener.
 */
class TracedInputListener : public InputListenerInterface {
public:
    explicit TracedInputListener(const char* name, InputListenerInterface& innerListener);

    virtual void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& 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 notifySensor(const NotifySensorArgs& args) override;
    virtual void notifyDeviceReset(const NotifyDeviceResetArgs& args) override;
    void notifyVibratorState(const NotifyVibratorStateArgs& args) override;
    void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) override;

private:
    InputListenerInterface& mInnerListener;
    const char* mName;
};

构造这个TracedInputListener时候会,传递一个UnwantedInteractionBlocker类型参数,会赋值给TracedInputListener的mInnerListener对象。
但是注意这里的UnwantedInteractionBlocker构造也需要一个参数InputListenerInterface,会赋值给UnwantedInteractionBlocker的成员变量mQueuedListener

UnwantedInteractionBlocker::UnwantedInteractionBlocker(InputListenerInterface& listener)
      : UnwantedInteractionBlocker(listener, isPalmRejectionEnabled()){};

UnwantedInteractionBlocker::UnwantedInteractionBlocker(InputListenerInterface& listener,
                                                       bool enablePalmRejection)
      : mQueuedListener(listener), mEnablePalmRejection(enablePalmRejection) {}

而且会依次类推到InputDispatcher对应的TracedInputListener

  std::make_unique<TracedInputListener>("InputDispatcher", *mDispatcher)

mDispatcher构造如下,也发现基础
frameworks/native/services/inputflinger/dispatcher/InputDispatcher.h

class InputDispatcher : public android::InputDispatcherInterface {
public:
    static constexpr bool kDefaultInTouchMode = true;

    explicit InputDispatcher(InputDispatcherPolicyInterface& policy);
    // Constructor used for testing.
    explicit InputDispatcher(InputDispatcherPolicyInterface&,
                             std::unique_ptr<trace::InputTracingBackendInterface>);

    void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
    void notifyKey(const NotifyKeyArgs& args) override;
    void notifyMotion(const NotifyMotionArgs& args) override;
    void notifySwitch(const NotifySwitchArgs& args) override;
    void notifySensor(const NotifySensorArgs& args) override;
    void notifyVibratorState(const NotifyVibratorStateArgs& args) override;
    void notifyDeviceReset(const NotifyDeviceResetArgs& args) override;
    void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) override;

frameworks/native/services/inputflinger/dispatcher/include/InputDispatcherInterface.h

/* Notifies the system about input events generated by the input reader.
 * The dispatcher is expected to be mostly asynchronous. */
class InputDispatcherInterface : public InputListenerInterface {

那么回到最开始mNextListener其实就是个TracedInputListener对象,里面的mInnerListener其实就是UnwantedInteractionBlocker,mNextListener的notify方法最后调用到如下代码:

void InputListenerInterface::notify(const NotifyArgs& generalArgs) {
    Visitor v{
            [&](const NotifyInputDevicesChangedArgs& args) { notifyInputDevicesChanged(args); },
            [&](const NotifyKeyArgs& args) { notifyKey(args); },
            [&](const NotifyMotionArgs& args) { notifyMotion(args); },
            [&](const NotifySwitchArgs& args) { notifySwitch(args); },
            [&](const NotifySensorArgs& args) { notifySensor(args); },
            [&](const NotifyVibratorStateArgs& args) { notifyVibratorState(args); },
            [&](const NotifyDeviceResetArgs& args) { notifyDeviceReset(args); },
            [&](const NotifyPointerCaptureChangedArgs& args) { notifyPointerCaptureChanged(args); },
    };
    std::visit(v, generalArgs);
}

这里其实大家可以理解为会根据notify传递的参数类型决定调用具体notifyMotion,notifyKey等方法,这里涉及到了一个新语法Visitor相关,具体看下面ai解释。

新语法Visitor解释

这里直接使用AI搜索解释更为清楚

这段代码展示了C++17中std::variant和std::visit的典型用法,实现了一种类型安全的访问者模式。

代码结构分析
1. Visitor对象的定义

Visitor v{
    [&](const NotifyInputDevicesChangedArgs& args) { notifyInputDevicesChanged(args); },
    [&](const NotifyKeyArgs& args) { notifyKey(args); },
    // ... 其他lambda表达式
};

这里定义了一个Visitor对象v,它包含多个lambda函数,每个lambda对应一种可能的参数类型。

2. std::visit调用

std::visit(v, generalArgs);

std::visit会根据generalArgs实际存储的类型,自动调用对应的lambda函数。

底层机制
std::variant类型
generalArgs很可能是一个std::variant类型,类似:

using GeneralArgs = std::variant<
    NotifyInputDevicesChangedArgs,
    NotifyKeyArgs, 
    NotifyMotionArgs,
    // ... 其他参数类型
>;

Visitor的工作方式
编译时多态:
编译器会为每种可能的类型生成对应的调用代码

类型安全:
不需要手动类型检查或转换

高效:
通常通过函数表实现,比动态多态更轻量

等价的手动实现
如果没有std::visit,可能需要这样写:

// 传统方式 - 需要手动类型检查
if (std::holds_alternative<NotifyKeyArgs>(generalArgs)) {
    notifyKey(std::get<NotifyKeyArgs>(generalArgs));
} else if (std::holds_alternative<NotifyMotionArgs>(generalArgs)) {
    notifyMotion(std::get<NotifyMotionArgs>(generalArgs));
}
// ... 更多else if

应用场景
这种模式常见于:

事件处理系统(如本例)

消息传递

状态机

抽象语法树遍历

优势
类型安全:编译时检查所有类型都已处理

可扩展性:添加新类型时,编译器会提示需要更新Visitor

性能:避免了虚函数调用的开销

清晰性:所有处理逻辑集中在一处

如何到达的InputDispatcher的notifyMotion

其实在InputManager进行构造时候就有相关的注释进行说明:

 * The event flow is via the "InputListener" interface, as follows:
 *   InputReader
 *     -> UnwantedInteractionBlocker
 *     -> InputFilter
 *     -> PointerChoreographer
 *     -> InputProcessor
 *     -> InputDeviceMetricsCollector
 *     -> InputDispatcher

这里就没必要每个地方都进行分析了,最后用Perfetto展示他的调用流程如下:
在这里插入图片描述

可以看到从最开始的是到的UnwantedInteractionBlocker对应的TracedInputListener的中notify方法,一步步到InputDispatcher的notifyMotion方法中。

注意这里面的每个TracedInputListener中的notifyMotion等都有自带打印trace
在这里插入图片描述在这里插入图片描述
等。。。

它们trace的打印代码就是在如下代码中打印的:

frameworks/native/services/inputflinger/InputListener.cpp
在这里插入图片描述到此就分析完成了新版本aosp15上InputReader中的notify是如何一步步调用到InputDispatch的notifyMotion。

原文参考:
https://mp.weixin.qq.com/s/MbNAL1UqCsiGdUuasyuI_g

更多framework实战开发干货,请关注下面“千里马学框架”

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值