Framework 全局监听屏幕点击事件 INPUT_EVENT_INJECTION

简介: Framework 全局监听屏幕点击事件 INPUT_EVENT_INJECTION

需求:用户点击屏幕后取消原有定时任务,无操作后顺延原来定时任务


简单分析


要想全局监听,那必须是在 framework 中了,应该从哪里切入呢?先看看 log,每点击一次屏幕后发现打印


InputDispatcher: Asynchronous input event injection succeeded.


全局搜索找到 frameworks\native\services\inputflinger\InputDispatcher.cpp 中


这就有点难顶了,cpp 中想要通知 java 层还是有点困难的,一开始尝试了在此处发送广播

#include <unistd.h>
switch (injectionResult) {
case INPUT_EVENT_INJECTION_SUCCEEDED:
ALOGV(“Asynchronous input event injection succeeded.”);
execlp(“am”, “am”, “broadcast”,
“-n”, “com.android.systemui/com.pdd.sutie.CustomerReceiver”,
“-a”, “com.pdd.action.inputevent.inject”,
NULL);
exit(errno);


通过函数 execlp() 调用 am 指令发送广播,尝试后发现会把 system 进程搞挂,看来 execlp() 不能在此使用,那就只能搂底浆了,

从 cpp 往上找,最终找到


frameworks\base\services\core\java\com\android\server\input\InputManagerService.java 中


调用顺序如下

InputManagerService.java
injectInputEventInternal(event, mode)
com_android_server_input_InputManagerService.cpp
im->getInputManager()->getDispatcher()->injectInputEvent(
InputDispatcher.cpp
int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
uint32_t policyFlags)


解决办法


frameworks\base\services\core\java\com\android\server\input\InputManagerService.java

@Override // Binder call
    public boolean injectInputEvent(InputEvent event, int mode) {
        return injectInputEventInternal(event, mode);
    }
    private boolean injectInputEventInternal(InputEvent event, int mode) {
        if (event == null) {
            throw new IllegalArgumentException("event must not be null");
        }
        if (mode != InputManager.INJECT_INPUT_EVENT_MODE_ASYNC
                && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
                && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
            throw new IllegalArgumentException("mode is invalid");
        }
        final int pid = Binder.getCallingPid();
        final int uid = Binder.getCallingUid();
        final long ident = Binder.clearCallingIdentity();
        final int result;
        try {
            result = nativeInjectInputEvent(mPtr, event, pid, uid, mode,
                    INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        switch (result) {
            case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
                Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
                throw new SecurityException(
                        "Injecting to another application requires INJECT_EVENTS permission");
            case INPUT_EVENT_INJECTION_SUCCEEDED:
                //cczheng add for listen lcd input start
                android.util.Log.e("InputDispatcher", "Input event injection from pid " + pid + " succeeded.");
                Intent pIntent = new Intent("com.pdd.action.inputevent.inject");
                pIntent.setComponent(new android.content.ComponentName("com.android.systemui",
                            "com.pdd.sutie.CustomerReceiver"));
                mContext.sendBroadcast(pIntent);
                //cczheng add for listen lcd input end
                return true;
            case INPUT_EVENT_INJECTION_TIMED_OUT:
                Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
                return false;
            case INPUT_EVENT_INJECTION_FAILED:
            default:
                Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
                return false;
        }
    }

Android Input(四) -InputDispatcher分发事件

Android10 InputManagerService事件输入输出

目录
相关文章
|
6天前
|
JavaScript 前端开发
点击事件中的this|click事件与change事件|v-model
点击事件中的this|click事件与change事件|v-model
14 0
Revit空闲事件(Idling Event)增强和外部事件(External Event)
Revit空闲事件(Idling Event)增强和外部事件(External Event)
Revit空闲事件(Idling Event)增强和外部事件(External Event)
|
iOS开发
iOS开发- runtime基本用法解析和用runtime给键盘添加工具栏和按钮响应事件
iOS开发- runtime基本用法解析和用runtime给键盘添加工具栏和按钮响应事件
116 0
|
前端开发
前端面试题:1.页面加载完成(onload)之前触发的事件;2.History,Location,Window,Navigation的区别;3.e.target和e.currentTarget的区别
★Navagator:提供有关浏览器的信息 ★Window: Window对象处于对象层次的最顶层, 它提供了处理Navagator窗口的方法和属性 ★Location:提供了与当前打开的URL-工作的方 法和属性,是一个静态的对象 ★History:提供了与历史清单有关的信息 ★Document:包含与文档元素一起工作的对象,它将这些元素封装起来供编程人员使用
221 0
|
JavaScript
element-ui中下拉command传递多参数事件封装
element-ui中下拉command传递多参数事件封装
448 0
element-ui中下拉command传递多参数事件封装
如何给UI上可以接收focus事件的element动态注册onfocus处理函数
如何给UI上可以接收focus事件的element动态注册onfocus处理函数
126 0
如何给UI上可以接收focus事件的element动态注册onfocus处理函数
|
存储
如何实现Window Form上的自定义事件
本文将介绍如何在Window窗体上自定义一个自定义事件(custom event) ,并通过订阅事件来进行事件的通知。
741 0
如何实现Window Form上的自定义事件
|
C#
WPF Label控件在数据绑定Content属性变化触发TargetUpdated事件简单实现类似TextChanged 事件效果
原文:WPF Label控件在数据绑定Content属性变化触发TargetUpdated事件简单实现类似TextChanged 事件效果   本以为Label也有TextChanged 事件,但在使用的时候却没找到,网友说Label的Content属性改变肯定是使用赋值操作,赋值的时候就可以对其进行相应的操作所以不需TextChanged 事件。
1952 0
|
前端开发 C#
WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参
原文:WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参 ContextMenu无论定义在.cs或.xaml文件中,都不继承父级的DataContext,所以如果要绑定父级的DataContext,直接DataContext=“{Bind...
3252 0