IMS:injectInputEvent注入Input事件
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
添加到mInboundQueue
,mLooper->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事件相关推荐
- input 事件_14. 教你零基础搭建小程序:小程序事件绑定(1)
图文版 本章以及下一章学习小程序的事件绑定,我们通过一个案例来讲解其中相关的知识点,便于大家理解哦~~ 首先,先来看这个案例的需求. 我们使用画图工具,先在上面绘制一个小程序页面, 如下图: 再在页面 ...
- 【C#|.NET】从控制反转(依赖注入)想到事件注入 (非AOP)
前文 事件注入的想法是由依赖注入所联想到 依赖注入不算什么吸引人的话题 本篇就不详说了 不过有闲暇时间的机会不妨按照自己的兴趣去摸索.研究一些东西,也是一种乐子. 在抓虫系列里简单的描述一下依赖注入在 ...
- jquery input事件
1 /* 2 * jQuery input event 3 * Author: tangbin 4 * Blog: http://www.planeart.cn 5 * Date: 2011-08-1 ...
- 阻止中文输入法输入拼音的时候触发input事件
阻止中文输入法输入拼音的时候触发input事件 前言 最近看element-ui源码的时候看到el-input发现的.这个少见的事件. compositionstart.compositionend事 ...
- input输入框的input事件和change事件
input输入框的onchange事件,要在 input 失去焦点的时候才会触发: 在输入框内容变化的时候不会触发change,当鼠标在其他地方点一下才会触发: onchange 事件也可用于单选框与 ...
- uinput 用法 android 上层使用uinput 的用法来模拟 input 事件
android 上层使用uinput 的用法来模拟 input 事件 #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif#include <stdio. ...
- 处理打拼音时触发input事件bug
1 /* 处理预输入,例如输入中文汉字时,拼音的预加载不触发输入事件*/ 2 var cpLock = false; 3 /* 添加搜索延迟*/ 4 var timeoutId = 0; 5 6 /* ...
- 解决input中输入中文过程中会触发input事件的问题
问题描述: 监听文本输入框的input事件,在拼写汉字时会触发input事件,如下图: 需求: 选词完成后触发input事件,只触发一次. 解决办法: 通过查阅资料得知在输入中文(包括语音识别时)会先 ...
- html输入框禁止输入汉字,input输入框输入中文时,监听的input事件怎样屏蔽拼音状态...
在input输入框输入中文时,需要即时查询出匹配输入内容的结果,一般我们会使用input事件监听用户输入事件,但是在输入汉语拼音时,也会触发input事件,前端就会不断发送请求,用户体验非常差劲. 针 ...
最新文章
- 封装、继承、多态、访问符,范围修饰符
- SiamMask:视频跟踪最高精度 (中科院王强大神作品)
- python turtle setheading_一文掌握Python绘图库Turtle的使用
- PrintJ的设计模式之旅——1.模式之父
- 项目上线后,谈一下感触比较深的一点:查询优化
- pucch的uci格式_LTE规范中关于DCI/PDCCH以及UCI/PUCCH写的比较模糊?
- 写一个Windows上的守护进程(4)日志其余
- 实际返回的行数超出请求的行数_代码行数越少越好?
- 西班牙语dele等级_2020年西班牙语DELE考试时间一览表
- IE提示“Internet Explorer无法打开站点XX,已终止操作”的解决办法
- CMDS目的端数据库碎片整理记录
- thinkadmin中日期的使用
- 基金从业考试如何备考?
- 行深智能亮相乌镇互联网大会,荣获直通乌镇全球互联网大赛一等奖
- 数控雕刻机和数控铣床都有什么区别
- 更改高通平台开机logo和开机动画以及fastboot界面显示
- 如何用最低的成本成就最高流量系列 各种线上推广手段的投入产出比数字公布(IreSearch.cn/龚文祥)(推荐帖)
- 牛客网Chino with Equation【组合数】
- 大量数据进行数组操作的Redim Preserve替代方法
- matlab threshold算法_控制与应用技术|基于模糊滑模算法的永磁同步电机无位置传感器矢量控制...