Android Instrumention.sendPointerSync发送Event失败分析

简介:

问题场景

    Android4.3,进入被测app某个Activity后,测试案例ClickOnScreen出现异常(Click can not be completed!)。

    Android4.4正常。

 

前置说明

    测试案例使用的是本人实现的测试框架,它底层调用了Robotium。

 

分析过程

    1. 框架调用了Robotium的ClickOnScreen,源码如下:

    (com.jayway.android.robotium.solo.Clicker)

     clicker

    当sendPointerSync(发送点击事件给被测app)10次都失败,便会断言异常:Click can not be completed。

    而引发sendPointerSync的异常是:SecurityException。在Android中,出现SecurityException异常是因为权限不足,一般的情况是:被测试App和测试案例的签名不一致,而这在instrumention启动被测试app就出现,不用等到instrument.sendPointerSync,这里是其他的问题引发的。

 

    2. 继续跟进问题。

    (1)android.app.Instrumentation

    2

    (2)android.hardware.input.InputManager

    3

    (3)android.hardware.input.IInputManager

   4

    最后是调用Binder.transect进行跨进程调用。

 

   3. 被调用者是系统服务,可追朔到InputManagerService的injectInputEvent。

   (1)/frameworks/base/services/java/com/android/server/input/InputManagerService.java

    5

    终于发现了我们要找的SecurityException,导致INPUT_EVENT_INJECTION_PERMISSION_DENIED是jni层的nativeInjectInputEvent

   (2)/frameworks/base/services/jni/com_android_server_input_InputManagerService.cpp

    x

   (3)/frameworks/base/services/input/InputDispatcher.cpp

    7

    终于发现了INPUT_EVENT_INJECTION_PERMISSION_DENIED踪迹,继续查看checkInjectionPermission:

    8

    查看系统日志,发现是造成Permission验证失败的原因是:当前windowHandle(被测app)->owneruid与注入者(instrument)->injectoruid不一致。并且windowHandle(被测app)的owneruid竟然是1000(系统账户)!

    (4) 系统日志如下:

    9

    同时,根据windowHandle->getName().string(),我意外发现“凶手”的Name是:hidden nav(隐藏的nav??….)。

 

    4. 在 被测app源码 和 Android源码中分别查找,最终发在“凶手”匿藏在PhoneWindowManager中……

    (1)/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

    10

   mHideNavFakeWindow的创建了addFackWindow,mHideNavFakeWindow的owneruid=Process.getmyid()(这里不列代码了), 而PhoneWindowManager是内部服务PhoneWindowService的策略类,属于系统用户。所以mHideNavFakeWindow这个透明的窗口,也是系统用户级别了(mHideNavFakeWindow为了满足某特殊需要,不得不设置为系统用户)…

而执行这个分支,需要满足一个条件:在重渲染ui界面时,被设置了标记:View.SYSTEM_UI_FLAG_HIDE_NAVIGATION。

    在被测App源码代码中search,终于发现疑似凶手:view.getRootView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); 而它确实就在出现ClickOnScreen异常的Activity里。最后经调试,确认问题确实如此。

 

4.3 与 4.4表现不一致的原因

    对比PhoneWindowManager 4.3和4.4的代码,发4.4做了改进,如下(右为4.4):

11

    而在被测app的代码中…..

    12

   就是 被测试App 在4.4时,会增加一个flag,导致了它撞大运般地在4.4中执行流程发生了改变,避免了mHideNavFakeWindow创建,从而也避免异常的发生。

 

总结

    1. 个人认为这是Android设计上的bug,它的instrument在极端的情况下会失效。

    2. 除非测试案例在系统中以系统用户启动,否则在4.3以下系统,该问题无法避免!

    3. 只要有mHideNavFakeWindow的存在,原则上所有的操作都会失败,包括drag在内,但Robotium对drag的异常进行了拦截并直接丢弃,所以使用drag表面是成功的,但实际上是失败,这会导致运行中出现无法解释的诡异问题。



本文转自hyddd博客园博客,原文链接:http://www.cnblogs.com/hyddd/p/3995281.html,如需转载请自行联系原作者。


目录
相关文章
|
15天前
|
安全 Shell Android开发
Android系统 init.rc sys/class系统节点写不进解决方案和原理分析
Android系统 init.rc sys/class系统节点写不进解决方案和原理分析
28 0
|
15天前
|
安全 Android开发
Android13 Root实现和原理分析
Android13 Root实现和原理分析
45 0
|
15天前
|
Java Android开发
Android系统 获取用户最后操作时间回调实现和原理分析
Android系统 获取用户最后操作时间回调实现和原理分析
17 0
|
2月前
|
搜索推荐 Android开发 iOS开发
安卓与iOS系统的用户界面设计对比分析
本文通过对安卓和iOS两大操作系统的用户界面设计进行对比分析,探讨它们在设计理念、交互方式、视觉风格等方面的差异及各自特点,旨在帮助读者更好地理解和评估不同系统的用户体验。
31 1
|
3月前
|
Android开发 数据安全/隐私保护 iOS开发
安卓与iOS系统的发展趋势与比较分析
【2月更文挑战第6天】 在移动互联网时代,安卓和iOS系统作为两大主流移动操作系统,各自呈现出不同的发展趋势。本文将从技术角度出发,对安卓和iOS系统的发展方向、特点及未来趋势进行比较分析,以期为读者提供更深入的了解和思考。
42 4
|
15天前
|
存储 Java Android开发
Android系统 设置第三方应用为默认Launcher实现和原理分析
Android系统 设置第三方应用为默认Launcher实现和原理分析
28 0
|
22小时前
|
编解码 缓存 安全
Android SELinux 参数语法介绍及基础分析
Android SELinux 参数语法介绍及基础分析
5 0
|
15天前
|
存储 安全 文件存储
Android OTA升级后输入法异常和应用丢失的分析
Android OTA升级后输入法异常和应用丢失的分析
20 1
|
15天前
|
存储 Java Shell
Android系统 实现低内存白名单防LMK原理分析
Android系统 实现低内存白名单防LMK原理分析
26 0
|
15天前
|
存储 Java Linux
Android系统获取event事件回调等几种实现和原理分析
Android系统获取event事件回调等几种实现和原理分析
31 0