问题场景

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

Android4.4正常。

前置说明

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

分析过程

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

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

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

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

2. 继续跟进问题。

(1)android.app.Instrumentation

(2)android.hardware.input.InputManager

(3)android.hardware.input.IInputManager

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

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

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

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

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

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

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

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

(4) 系统日志如下:

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

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

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

   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):

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

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

总结

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

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

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

Android Instrumention.sendPointerSync发送Event失败分析的更多相关文章

  1. 转——Android应用开发性能优化完全分析

    [工匠若水 http://blog.csdn.net/yanbober 转载请注明出处.] 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉 ...

  2. Android 应用开发性能优化完全分析

    1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...

  3. 【转】Android应用开发性能优化完全分析

    http://blog.csdn.net/yanbober/article/details/48394201 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关 ...

  4. Android应用开发性能优化完全分析

    1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...

  5. Android应用程序发送广播(sendBroadcast)的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6744448 前面我们分析了Android应用程 ...

  6. Android之 MTP框架和流程分析

    概要 本文的目的是介绍Android系统中MTP的一些相关知识.主要的内容包括:第1部分 MTP简介            对Mtp协议进行简单的介绍.第2部分 MTP框架            介绍 ...

  7. 转:Android应用开发性能优化完全分析

    转自:http://blog.csdn.net/yanbober/article/details/48394201 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜 ...

  8. Android Debuggerd 简要介绍和源码分析(转载)

    转载: http://dylangao.com/2014/05/16/android-debuggerd-%E7%AE%80%E8%A6%81%E4%BB%8B%E7%BB%8D%E5%92%8C%E ...

  9. android 常见死机问题--log分析

    http://blog.csdn.net/fangchongbory/article/details/7645815         android 常见死机问题--log分析============ ...

随机推荐

  1. 清空stringbuilder

    大家知道对于字符串频繁拼接是使用stringbuilder.Append方法比使用string+=方法效率高很多,但有时需要清空stringbuilder时却不知道怎么清空,因为它没有clear或em ...

  2. linux下的触控板手势xSwipe and tag

    这个最初是采用的touchegg.开始没有效果,后来网上发现是因为需要禁用系统的2指3指操作参考 http://askubuntu.com/questions/266057/cant-get-touc ...

  3. jsp:软件包 javax.servlet 不存在

    jdk里面有javax.servlet和javax.servlet.http这两个包吗? JavaServlet程序运行还需要安装JDK以外的包吗...? why?我运行JavaServlet程序的时 ...

  4. LR11录制脚本时打不开浏览器,如何解决?

    请教一下各位大神,我安装的LR11,在录制脚本的时候打不开浏览器,已经试过了网上的方法还是不行,以下是搜到的方法: 无法打开IE的主要原因是,LR的注册信息被修改了,所以无法找到IE的路径. 解决这个 ...

  5. SQL Server 2012安装后找不到服务器名称的解决办法!!!

    网上说使用localhost即可,确实没错,但是有的仍旧会报出无法找到错误,我在无法通过的时候又重新安装了SQLServer,这次选中全部默认安装,之前使用的是选择安装,然后发现多了几个配置,其中有一 ...

  6. 通过反射获取父类泛型的Class对象 ParameterizedType

    ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0] 这个方法这么用啊,返回什么,请给 ...

  7. gulp-rev-orig

    给客户演示项目时,老是会出现由于缓存,造成的最新的样式或者效果出不来的情况,还得需要手动清除缓存操作,一方面呢,会给客户留下不好的印象,而且也会多了清缓存这一过程,和同事商量过后,决定使用在css或者 ...

  8. css中怎么设置透明度的问题

    小伙伴们是不是在找怎么样去设置页面的透明度的方法呢...别找了,我这儿就有,而且肯定够用了. 我自己会用到的就有两种,可以和大家分享一下. 1.用opcity的方法去设置透明度.代码如下: .div ...

  9. :尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。 ---> System.BadImageFormatException: 试图加载格式不正确的程序。

    iis有程序池有一个属性  是否启用32位应用程序默认是true的特别注意windows2008 服务器系统iis默认的是true 这样发布一下也是必须要做的

  10. HashMap LinkedHashMap源码分析笔记

    MapClassDiagram