当前位置: 首页 > news >正文

Input系统学习-----injectInputEvent注入事件调用流程

input命令可以用来注入事件,代码在frameworks/base/cmds/input/src/com/android/commands/input/Input.java

注入点击等触碰事件时,在Android 10版本后还可以通过-d来指定displayId,这个对多屏手机具有测试参考作用。

InputManager的injectInputEvent方法最终调用到InputDispatcher::injectInputEvent

int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t displayId,

        int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,

        uint32_t policyFlags) {

enqueueInboundEventLocked(entry);

------  mInboundQueue.enqueueAtTail(entry);

这里调用到enqueueInboundEventLocked,屏幕的触碰事件也是调用到enqueueInboundEventLocked,是通过TouchInputMapper::dispatchMotion调用到的

void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,

        int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,

        const PointerProperties* properties, const PointerCoords* coords,

        const uint32_t* idToIndex, BitSet32 idBits,

        int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {

    NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,

            action, flags, metaState, buttonState, edgeFlags,

            mViewport.displayId, pointerCount, pointerProperties, pointerCoords,

            xPrecision, yPrecision, downTime);

    getListener()->notifyMotion(&args);

}

void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {

        if (shouldSendMotionToInputFilterLocked(args)) {

            mLock.unlock();

            MotionEvent event;

            event.initialize(args->deviceId, args->source, args->action, args->flags,

                    args->edgeFlags, args->metaState, args->buttonState, 0, 0,

                    args->xPrecision, args->yPrecision,

                    args->downTime, args->eventTime,

                    args->pointerCount, args->pointerProperties, args->pointerCoords);

            policyFlags |= POLICY_FLAG_FILTERED;

            if (!mPolicy->filterInputEvent(&event, policyFlags)) {

                return; // event was consumed by the filter

            }

            mLock.lock();

        }

        // Just enqueue a new motion event.

        MotionEntry* newEntry = new MotionEntry(args->eventTime,

                args->deviceId, args->source, policyFlags,

                args->action, args->flags, args->metaState, args->buttonState,

                args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,

                args->displayId,

                args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0);

        needWake = enqueueInboundEventLocked(newEntry);

        mLock.unlock();

    } // release lock

都有enqueueInboundEventLocked调用,

enqueueInboundEventLocked会触发dispatchOnce中的调用

loop流程

bool InputDispatcherThread::threadLoop() {

    mDispatcher->dispatchOnce();

    return true;

}

void InputDispatcher::dispatchOnce()

有指令时调用

        if (!haveCommandsLocked()) {

            dispatchOnceInnerLocked(&nextWakeupTime);

        }

bool InputDispatcher::haveCommandsLocked() const {

    return !mCommandQueue.isEmpty();

}

dispatchOnceInnerLocked

void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {

dispatchMotionLocked

event是从mPendingEvent里面获取的

bool InputDispatcher::dispatchMotionLocked(

        nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {

findTouchedWindowTargetsLocked

获取 inputTargets

然后,dispatchEventLocked(currentTime, entry, inputTargets);

   

里面调用connect进行了分发

void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,

        EventEntry* eventEntry, const Vector& inputTargets) {

#if DEBUG_DISPATCH_CYCLE

    ALOGD("dispatchEventToCurrentInputTargets");

#endif

    ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true

    pokeUserActivityLocked(eventEntry);

    for (size_t i = 0; i < inputTargets.size(); i++) {

        const InputTarget& inputTarget = inputTargets.itemAt(i);

        ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);

        if (connectionIndex >= 0) {

            sp connection = mConnectionsByFd.valueAt(connectionIndex);

            prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);

        } else {

#if DEBUG_FOCUS

            ALOGD("Dropping event delivery to target with channel '%s' because it "

                    "is no longer registered with the input dispatcher.",

                    inputTarget.inputChannel->getName().string());

#endif

        }

    }

}

参考资料

InputManagerService分析一:IMS的启动与事件传递

InputManagerService分析一:IMS的启动与事件传递_李炼的博客-CSDN博客

相关文章:

  • Java项目:SSM物业缴费管理系统
  • 函数指针(函数作为参数传递给其他函数)
  • 2023考研推荐新闻传播专业入门可以看的好书
  • 解决Long类型web前端精度丢失问题
  • Docker服务编排
  • 为什么自动化营销对于独立站运营来说很重要?
  • 服务器模型选择
  • 使用Android studio开发一个数独游戏APP 系列第二讲
  • MySQL中的时间类型
  • linux的基础指令
  • Docker容器中安装Mysql和Redis等全过程(以在阿里云服务器中的Docker安装Mysql和Redis为例)
  • java---SPFA算法---判断负权回路(每日一道算法2022.8.31)
  • 操作系统(Linux)
  • 基础 | 并发编程 - [LockSupport]
  • Uboot命令应用
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • extract-text-webpack-plugin用法
  • Java,console输出实时的转向GUI textbox
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • Koa2 之文件上传下载
  • OSS Web直传 (文件图片)
  • php面试题 汇集2
  • Spring Cloud中负载均衡器概览
  • use Google search engine
  • vue-cli3搭建项目
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 力扣(LeetCode)22
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 盘点那些不知名却常用的 Git 操作
  • 前端代码风格自动化系列(二)之Commitlint
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 终端用户监控:真实用户监控还是模拟监控?
  • 如何正确理解,内页权重高于首页?
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • ​queue --- 一个同步的队列类​
  • (06)Hive——正则表达式
  • (3)STL算法之搜索
  • (4.10~4.16)
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (备忘)Java Map 遍历
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (九)c52学习之旅-定时器
  • (强烈推荐)移动端音视频从零到上手(下)
  • (一)WLAN定义和基本架构转
  • (转)使用VMware vSphere标准交换机设置网络连接
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • .NET : 在VS2008中计算代码度量值
  • .Net 6.0 处理跨域的方式