IMS:injectInputEvent注入Input事件

android11-release
IMS:InputManagerService启动简要
IMS:InputReader线程获取输入事件
IMS:InputDispatcher线程分发事件


adb命令输入KEYCODE_VOLUME_UP


adb shell input keyevent KEYCODE_VOLUME_UP

frameworks\base\core\java\android\view\KeyEvent.java
frameworks\base\cmds\input\src\com\android\commands\input\Input.java


injectKeyEvent(event); 调用IMS.injectInputEvent,最终走到通过JNI调用InputDispatcher::injectInputEvent

public class Input extends BaseCommand {// ... ... ... ...Input() {COMMANDS.put("text", new InputText());COMMANDS.put("keyevent", new InputKeyEvent());COMMANDS.put("tap", new InputTap());COMMANDS.put("swipe", new InputSwipe());COMMANDS.put("draganddrop", new InputDragAndDrop());COMMANDS.put("press", new InputPress());COMMANDS.put("roll", new InputRoll());COMMANDS.put("motionevent", new InputMotionEvent());}@Overridepublic void onRun() throws Exception {String arg = nextArgRequired();int inputSource = InputDevice.SOURCE_UNKNOWN;// Get source (optional).if (SOURCES.containsKey(arg)) {inputSource = SOURCES.get(arg);arg = nextArgRequired();}// Get displayId (optional).int displayId = INVALID_DISPLAY;if ("-d".equals(arg)) {displayId = getDisplayId();arg = nextArgRequired();}// Get command and run.InputCmd cmd = COMMANDS.get(arg);if (cmd != null) {try {cmd.run(inputSource, displayId);return;} catch (NumberFormatException ex) {throw new IllegalArgumentException(INVALID_ARGUMENTS + arg);}}throw new IllegalArgumentException("Error: Unknown command: " + arg);}// ... ... ... ...class InputKeyEvent implements InputCmd {@Overridepublic void run(int inputSource, int displayId) {String arg = nextArgRequired();final boolean longpress = "--longpress".equals(arg);if (longpress) {arg = nextArgRequired();}do {final int keycode = KeyEvent.keyCodeFromString(arg);sendKeyEvent(inputSource, keycode, longpress, displayId);} while ((arg = nextArg()) != null);}private void sendKeyEvent(int inputSource, int keyCode, boolean longpress, int displayId) {final long now = SystemClock.uptimeMillis();int repeatCount = 0;KeyEvent event = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, repeatCount,0 /*metaState*/, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/, 0 /*flags*/,inputSource);event.setDisplayId(displayId);injectKeyEvent(event);if (longpress) {repeatCount++;injectKeyEvent(KeyEvent.changeTimeRepeat(event, now, repeatCount,KeyEvent.FLAG_LONG_PRESS));}injectKeyEvent(KeyEvent.changeAction(event, KeyEvent.ACTION_UP));}}

InputDispatcher::injectInputEvent注入Input事件


frameworks\base\services\core\java\com\android\server\input\InputManagerService.java
frameworks\base\services\core\jni\com_android_server_input_InputManagerService.cpp
frameworks\native\services\inputflinger\dispatcher\InputDispatcher.cpp

adb注入的是KeyEvent,InputDispatcher::injectInputEvent 将 injectedEntries(EventEntry队列)通过InputDispatcher::enqueueInboundEventLocked 添加到mInboundQueuemLooper->wake() 唤醒 InputDispatcher线程,最后返回注入结果injectionResult

int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid,int32_t injectorUid, int32_t syncMode,std::chrono::milliseconds timeout, uint32_t policyFlags) {#if DEBUG_INBOUND_EVENT_DETAILSALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, ""syncMode=%d, timeout=%lld, policyFlags=0x%08x",event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
#endif// ... ... ... ...std::queue<EventEntry*> injectedEntries;switch (event->getType()) {case AINPUT_EVENT_TYPE_KEY: {const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);int32_t action = incomingKey.getAction();if (!validateKeyEvent(action)) {return INPUT_EVENT_INJECTION_FAILED;}int32_t flags = incomingKey.getFlags();int32_t keyCode = incomingKey.getKeyCode();int32_t metaState = incomingKey.getMetaState();accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,/*byref*/ keyCode, /*byref*/ metaState);KeyEvent keyEvent;keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),incomingKey.getDownTime(), incomingKey.getEventTime());if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {policyFlags |= POLICY_FLAG_VIRTUAL;}if (!(policyFlags & POLICY_FLAG_FILTERED)) {android::base::Timer t;mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",std::to_string(t.duration().count()).c_str());}}mLock.lock();KeyEntry* injectedEntry =new KeyEntry(incomingKey.getId(), incomingKey.getEventTime(),VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),incomingKey.getDisplayId(), policyFlags, action, flags, keyCode,incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),incomingKey.getDownTime());injectedEntries.push(injectedEntry);break;}// ... ... ... ...}// ... ... ... ...bool needWake = false;while (!injectedEntries.empty()) {needWake |= enqueueInboundEventLocked(injectedEntries.front());injectedEntries.pop();}mLock.unlock();if (needWake) {mLooper->wake();}
// ... ... ... ...
#if DEBUG_INJECTIONALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",injectionResult, injectorPid, injectorUid);
#endifreturn injectionResult;
}

mInboundQueue分发查看IMS:InputDispatcher线程分发事件,这里可以看到注入 Input 事件直接加入到mInboundQueue由InputDispatcher分发,没有经过InputReader

IMS:injectInputEvent注入反馈结果

IMS:injectInputEvent注入Input事件相关推荐

  1. input 事件_14. 教你零基础搭建小程序:小程序事件绑定(1)

    图文版 本章以及下一章学习小程序的事件绑定,我们通过一个案例来讲解其中相关的知识点,便于大家理解哦~~ 首先,先来看这个案例的需求. 我们使用画图工具,先在上面绘制一个小程序页面, 如下图: 再在页面 ...

  2. 【C#|.NET】从控制反转(依赖注入)想到事件注入 (非AOP)

    前文 事件注入的想法是由依赖注入所联想到 依赖注入不算什么吸引人的话题 本篇就不详说了 不过有闲暇时间的机会不妨按照自己的兴趣去摸索.研究一些东西,也是一种乐子. 在抓虫系列里简单的描述一下依赖注入在 ...

  3. jquery input事件

    1 /* 2 * jQuery input event 3 * Author: tangbin 4 * Blog: http://www.planeart.cn 5 * Date: 2011-08-1 ...

  4. 阻止中文输入法输入拼音的时候触发input事件

    阻止中文输入法输入拼音的时候触发input事件 前言 最近看element-ui源码的时候看到el-input发现的.这个少见的事件. compositionstart.compositionend事 ...

  5. input输入框的input事件和change事件

    input输入框的onchange事件,要在 input 失去焦点的时候才会触发: 在输入框内容变化的时候不会触发change,当鼠标在其他地方点一下才会触发: onchange 事件也可用于单选框与 ...

  6. uinput 用法 android 上层使用uinput 的用法来模拟 input 事件

    android 上层使用uinput 的用法来模拟 input 事件 #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif#include <stdio. ...

  7. 处理打拼音时触发input事件bug

    1 /* 处理预输入,例如输入中文汉字时,拼音的预加载不触发输入事件*/ 2 var cpLock = false; 3 /* 添加搜索延迟*/ 4 var timeoutId = 0; 5 6 /* ...

  8. 解决input中输入中文过程中会触发input事件的问题

    问题描述: 监听文本输入框的input事件,在拼写汉字时会触发input事件,如下图: 需求: 选词完成后触发input事件,只触发一次. 解决办法: 通过查阅资料得知在输入中文(包括语音识别时)会先 ...

  9. html输入框禁止输入汉字,input输入框输入中文时,监听的input事件怎样屏蔽拼音状态...

    在input输入框输入中文时,需要即时查询出匹配输入内容的结果,一般我们会使用input事件监听用户输入事件,但是在输入汉语拼音时,也会触发input事件,前端就会不断发送请求,用户体验非常差劲. 针 ...

最新文章

  1. 封装、继承、多态、访问符,范围修饰符
  2. SiamMask:视频跟踪最高精度 (中科院王强大神作品)
  3. python turtle setheading_一文掌握Python绘图库Turtle的使用
  4. PrintJ的设计模式之旅——1.模式之父
  5. 项目上线后,谈一下感触比较深的一点:查询优化
  6. pucch的uci格式_LTE规范中关于DCI/PDCCH以及UCI/PUCCH写的比较模糊?
  7. 写一个Windows上的守护进程(4)日志其余
  8. 实际返回的行数超出请求的行数_代码行数越少越好?
  9. 西班牙语dele等级_2020年西班牙语DELE考试时间一览表
  10. IE提示“Internet Explorer无法打开站点XX,已终止操作”的解决办法
  11. CMDS目的端数据库碎片整理记录
  12. thinkadmin中日期的使用
  13. 基金从业考试如何备考?
  14. 行深智能亮相乌镇互联网大会,荣获直通乌镇全球互联网大赛一等奖
  15. 数控雕刻机和数控铣床都有什么区别
  16. 更改高通平台开机logo和开机动画以及fastboot界面显示
  17. 如何用最低的成本成就最高流量系列 各种线上推广手段的投入产出比数字公布(IreSearch.cn/龚文祥)(推荐帖)
  18. 牛客网Chino with Equation【组合数】
  19. 大量数据进行数组操作的Redim Preserve替代方法
  20. matlab threshold算法_控制与应用技术|基于模糊滑模算法的永磁同步电机无位置传感器矢量控制...

热门文章

  1. java中Excel导入,下载模板,附带前端展示
  2. PyCharm 使用 Sublime-Monokai 配色方案
  3. uni-app 使用uCharts图表插件
  4. 11.02-smbios
  5. Linux kernel panic解决方法
  6. MATLAB矩阵的建立与访问
  7. python权限管理设置_python权限管理框架
  8. PHP打印输出log
  9. python如何调用函数计算出成绩的不及格率_Excel利用这个函数轻松完成自动计算及格率、合格率...
  10. 表示数值的字符串——《剑指offer》