android GMS认证之testScreenCaptureDisabled_allowedPrimaryUser_hfreeman2008的博客-程序员信息网

技术标签: cts  android  gms  android GMS认证  

这里写图片描述

问题:

android 6.0 CTS测试报下面的fail:

com.android.cts.devicepolicy.MixedProfileOwnerTest
-- testScreenCaptureDisabled_allowedPrimaryUser fail
junit.framework.AssertionFailedError at junit.framework.Assert.fail(Assert.java:48)

这里写图片描述

初步分析:

查看device_logcat:

I TestRunner: failed: testScreenCapturePossible(com.android.cts.deviceandprofileowner.ScreenCaptureDisabledTest)
I TestRunner: ----- begin exception -----
D SettingsInterface:  from settings cache , name = multi_sim_voice_call , value = null
D SettingsInterface:  from settings cache , name = multi_sim_voice_call , value = null
I TestRunner: junit.framework.AssertionFailedError
I TestRunner:   at junit.framework.Assert.fail(Assert.java:48)
I TestRunner:   at junit.framework.Assert.assertTrue(Assert.java:20)
I TestRunner:   at junit.framework.Assert.assertNotNull(Assert.java:218)
I TestRunner:   at junit.framework.Assert.assertNotNull(Assert.java:211)
I TestRunner:   at com.android.cts.deviceandprofileowner.ScreenCaptureDisabledTest.testScreenCapturePossible(ScreenCaptureDisabledTest.java:67)
I TestRunner:   at java.lang.reflect.Method.invoke(Native Method)
I TestRunner:   at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
I TestRunner:   at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
I TestRunner:   at junit.framework.TestCase.runBare(TestCase.java:134)
I TestRunner:   at junit.framework.TestResult$1.protect(TestResult.java:115)
I TestRunner:   at android.support.test.internal.runner.junit3.AndroidTestResult.runProtected(AndroidTestResult.java:77)
I TestRunner:   at junit.framework.TestResult.run(TestResult.java:118)
I TestRunner:   at android.support.test.internal.runner.junit3.AndroidTestResult.run(AndroidTestResult.java:55)
I TestRunner:   at junit.framework.TestCase.run(TestCase.java:124)
I TestRunner:   at android.support.test.internal.runner.junit3.NonLeakyTestSuite$NonLeakyTest.run(NonLeakyTestSuite.java:63)
I TestRunner:   at junit.framework.TestSuite.runTest(TestSuite.java:243)
I TestRunner:   at junit.framework.TestSuite.run(TestSuite.java:238)
I TestRunner:   at android.support.test.internal.runner.junit3.DelegatingTestSuite.run(DelegatingTestSuite.java:103)
I TestRunner:   at android.support.test.internal.runner.junit3.AndroidTestSuite.run(AndroidTestSuite.java:69)
I TestRunner:   at android.support.test.internal.runner.junit3.JUnit38ClassRunner.run(JUnit38ClassRunner.java:90) I TestRunner:     at org.junit.runners.Suite.runChild(Suite.java:128) I TestRunner:   at org.junit.runners.Suite.runChild(Suite.java:24) I TestRunner:    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
I TestRunner:   at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
I TestRunner:   at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) I TestRunner:  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) I TestRunner: 	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) I TestRunner:    at org.junit.runners.ParentRunner.run(ParentRunner.java:300) I TestRunner:  at org.junit.runner.JUnitCore.run(JUnitCore.java:157) I TestRunner:     at org.junit.runner.JUnitCore.run(JUnitCore.java:136) I TestRunner:     at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:54) I TestRunner:    at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:228) I TestRunner:    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1893) I TestRunner: ----- end exception ----- I TestRunner: finished: testScreenCapturePossible(com.android.cts.deviceandprofileowner.ScreenCaptureDisabledTest)

我们打开ScreenCaptureDisabledTest.java文件,查看67行:

cts/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledTest.java
public void testScreenCapturePossible() throws Exception {
        assertNotNull(getInstrumentation().getUiAutomation().takeScreenshot());
}

我们看到也就是说截屏回来的是null,导致报fail了,我们添加对应的log,也确认返回的是null。

解决方法一:借刀杀人

此问题我不知道怎么解,我先提了一个eservice给MTK。

我们询问一下有关的同事,惊奇的发现我们的订单和原型都有此问题,但是wik的订单竟然没有此fail项。
我去用他们项目的软件刷机,确认他们确实是没有此fail项。
我再向相关的同事咨询相关的修改,他们的回复是没有改任何东西。

好吧,就这一个线索,开工干活吧。

先分析了一下wik订单和我们订单的代码差异部分,觉得应该就是二部分。
一个是在vendor目录下订单的自定义部分
一个是在代码中针对wik订单的自定义部分

好吧,那就回溯吧。
我让我们部门的二位同事去回溯一下wik订单的自定义部分,我来追vendor目录下订单的自定义部分。(原因是我觉得wik订单的自定义部分简单,而vendor目录下订单部分比较不好定位)。

期间出现各种问题,一会那二位同事说找到了,但是又不可以重现确认,导致我也来和他们一起回溯,一会MTK要提供对应的log,我要编译给MTK提供Log。老大一天问几次进度,非常有压力,担心自己的方向判断有误,会导致团队的工作没有意义。

这也是我第一次带领二位同事来解决一个问题,老大每天问几次进度,每天都是要求今天要解决,但是每天都是没有进展。而二位同事是新人,压力基本上都是在我一个人身上。
最后,终于在星期三的晚上十二点半,我大概找到了是在mk文件的几个修改,我移植过来此fail项就可以pass。然后星期四上午,我确定wik没有此fail项是因为他们内置了一个clearmaster的三方应用。我无语啊,我只听说内置三方应用可以导致新的问题,还是第一次见到说可以解决问题。好吧,问题找到了,我们在我们的项目上也内置此应用,测试此fail项确实可以pass。窃喜啊。再全面验证,fuck,内置此应用竟然导致了一个新的GTS的fail项。

哥,我错了,我本来以为可以借wik订单的砍刀把这个导致fail项的坏人砍了,没有想到会伤及无辜,砍到了另外的小伙伴,好吧,这把砍刀还给你,我另外想办法。

解决方法二:直捣黄龙

然后,我们还是要求MTK来解决此问题,MTK要求我提供了二份Log:
dumpsys.txt和sf.txt
提取log的命令:

adb shell dumpsys window w > dumpsys.txt
adb shell dumpsys SurfaceFlinger >sf.txt

MTK分析如下:
1. 先查看sf.txt

+ Layer 0xb74ec420 ()
  Region transparentRegion (this=0xb74ec590, count=1)
    [  0,   0,   0,   0]
  Region visibleRegion (this=0xb74ec428, count=1)
    [  0,   0, 120,  48]
  Region surfaceDamageRegion (this=0xb74ec464, count=1)
    [  0,   0,   0,   0]
      layerStack=   0, z=   231005, pos=(0,0), size=( 120,  48), crop=(   0,   0, 120,  48), isOpaque=0, invalidate=0, alpha=0xff, flags=0x00000080, tr=[1.00, 0.00][0.00, 1.00]
      client=0xb7577000
      format= 1, activeBuffer=[ 120x  48: 128,  1], queued-frames=0, mRefreshPending=0
      mSecure=1, mProtectedByApp=0, mFiltering=0, mNeedsFiltering=0
            mTexName=10 mCurrentTexture=2
            mCurrentCrop=[0,0,0,0] mCurrentTransform=0
            mAbandoned=0
            -BufferQueue mMaxAcquiredBufferCount=1, mDequeueBufferCannotBlock=0, default-size=[120x48], default-format=1, transform-hint=00, FIFO(0)={}
             this=0xb7567680 (mConsumerName=, mConnectedApi=1, mConsumerUsageBits=0x900, mOverrideMaxBufferCount=0, mId=76, mPid=244, producer=[5687:com.ape.smartgesture], consumer=[244:/system/bin/surfaceflinger])
             [00:0xb757a628] state=FREE    , 0xb757a6d0 [ 120x  48: 128,  1]
             [01:0xb73aea20] state=DEQUEUED, 0xb74f8310 [ 120x  48: 128,  1]
            >[02:0xb7568490] state=ACQUIRED, 0xb74edfe8 [ 120x  48: 128,  1]
                *BufferQueueDump mIsBackupBufInited=0, mAcquiredBufs(size=1), mMode=TRACK_CONSUMER
                 [00] handle=0xb74edfe8, fence=0xb73ae6c8, time=0x400d88d8e0
Displays (1 entries)

我们可以看到有一个window的mSecure=1,其它的window mSecure=0,就个就是导致CTS 截屏测试fail项的根源所在。因为这个window的mSecure=1,导致截屏测试时截屏不成功,返回为null,所以CTS测试报fail。
我们再看,可以知道此window的大小是size=( 120, 48),但是这个window是叫什么名字,在那个应用中呢?我们看不出来:

我们再查看dumpsys.txt文件:

搜索120,哈哈,我们可以明确的看120,48大小的window是什么名字了?

WINDOW MANAGER WINDOWS (dumpsys window windows)
  Window #12 Window{45f2d04 u0 com.ape.smartgesture}:
    mDisplayId=0 stackId=0 mSession=Session{
   36bbc6c 1629:1000} [email protected]43b1517
    mOwnerUid=1000 mShowToOwnerOnly=true package=com.ape.smartgesture appop=SYSTEM_ALERT_WINDOW
    mAttrs=WM.LayoutParams{(0,0)(120x48) gr=#800033 sim=#20 ty=2010 fl=#1000108 fmt=1}
    Requested w=120 h=48 mLayoutSeq=499
    mBaseLayer=231000 mSubLayer=0 mAnimLayer=231000+0=231000 mLastLayer=231000
    mToken=WindowToken{cb3e76f null}
    mRootToken=WindowToken{cb3e76f null}
    mViewVisibility=0x0 mHaveFrame=true mObscured=false
    mSeq=0 mSystemUiVisibility=0x0
    mGivenContentInsets=[0,0][0,0] mGivenVisibleInsets=[0,0][0,0]
    mConfiguration={
   1.0 460mcc1mnc en_US ldltr sw360dp w360dp h568dp 320dpi nrml port finger -keyb/v/h -nav/h s.7}
    mHasSurface=true mShownFrame=[0.0,0.0][120.0,48.0] isReadyForDisplay()=true
    mFrame=[0,0][120,48] last=[0,0][120,48]
    mSystemDecorRect=[0,0][120,48] last=[0,0][0,0]
    Frames: containing=[0,0][720,1184] parent=[0,0][720,1184]
        display=[0,0][720,1184] overscan=[0,0][720,1184]
        content=[0,0][120,48] visible=[0,48][120,48]
        decor=[0,0][720,1280]
        outset=[0,0][0,0]
    Cur insets: overscan=[0,0][0,0] content=[0,0][0,0] visible=[0,48][0,0] stable=[0,48][0,0] outsets=[0,0][0,0]
    Lst insets: overscan=[0,0][0,0] content=[0,0][0,0] visible=[0,48][0,0] stable=[0,48][0,0] physical=[0,0][0,0] outset=[0,0][0,0]
    WindowStateAnimator{
   7f78c7c }:
      mSurface=Surface(name=)
      mDrawState=HAS_DRAWN mLastHidden=false
      Surface: shown=true layer=231000 alpha=1.0 rect=(0.0,0.0) 120.0 x 48.0
    mLastFreezeDuration=+68ms

非常明确,Log告诉我们此window是com.ape.smartgesture应用。

好,我把此应用删除,此fail项就可以pass。

至此,问题其实已经解决了。

最终解决方法:

启示录

1. 问题解决的方法是有许多的,要选择最根本的解决问题的方法

其实解决问题,有正面的直接解决,也有变通的方式规避,具体取什么方式的解决方法,还是要看具体的问题。

2. 问题的定位和分析远比解决问题的本身更重要

这,说的好像是没有意义,但是解决问题的方法确实是比解决问题本身更重要

3. log是解决特定问题的有利武器

log是不会说谎的证人证词,他会忠实目击证人,关键是我们要读懂他

4. 特定的开发命令在解决分析问题时,可以提供许多有效的Log信息

我们抓取log的方式是由所需要的Log决定的,对于这些特定的开发命令,还是要熟悉。

5. 团队合作,对于领队来说,个人觉得有几个点非常重要:

(1) 一定要时刻清楚自己团队的目标:
团队的目标是什么,我们要实现什么,实现的方案方向是否有偏差,实现的方案是否有风险?带头大哥一定是一位船长的角色,在他的心中,带领大家到达目标才是他的最大的责任。所以目标一定是他眼睛牢牢盯着地方。

(2) 合理安排团队的工作
工作安排,这个主要还是要根据工作任务和成员的能力来安排,最好是任务能均衡。

(3) 团队要如何承担压力
工作压力,其实最大的人肯定是团队负责人。这个以前没有负责团队不觉得,只是感觉负责人就是在上面指手画脚,什么事都不要做。其实不是,负责人第为第一责任人,压力肯定是最大的。一个合格的负责人,应该做的是把压力适度的压到团队成员身上去。但是自己还是要承担绝大部分的压力,以便让团队成员在一个压力适度的气氛下合作。这之间的分寸应该是一个团队负责人水平高低的一个重要指标。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/hfreeman2008/article/details/51010386

智能推荐

图像分类算法优化技巧_AI之路的博客-程序员信息网_图像分类模型训练

论文:Bag of Tricks for Image Classification with Convolutional Neural Networks论文链接:https://arxiv.org/abs/1812.01187论文复现对很多人而言难度都比较大,因为常常涉及很多细节,部分细节对于模型效果影响很大,但是却很少有文章介绍这些细节,前段时间正好看到这篇文章,再加上之前就有关注Gluon...

s3c2410移植nand支持到uboot, 使用nand.c ,linux mtd 架构_王凯Android的博客-程序员信息网

http://blog.csdn.net/lanmanck/article/details/4206459 u-boot-1.1.6与1.1.4相比,两者有较大的不同,1.1.6 更像是复制了 kernel 的方法来实现。 下面对nand flash的初始化代码nand_init()进行分析: 1.如果定义(CONFIG_COMMANDS & CFG_CMD_NAND)

自旋锁简介以及实现_wwxy261的博客-程序员信息网

什么是自旋锁?自旋锁(spinlock):是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。获取锁的线程一直处于活跃状态,但是并没有执行任何有效的任务,使用这种锁会造成busy-waiting。它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使...

Qt去掉对话框边框并且窗口可移动的实现_令狐掌门的博客-程序员信息网_qt隐藏边框

Qt开发时,有时需要对窗口进行定制,例如去掉边框,做异形窗口等,做法比较简单,添加几句代码即可。现在构造函数中添加://去掉边框this->setWindowFlags(Qt::FramelessWindowHint); 此时,虽然去掉了边框,但是窗口无法移动,需要重写鼠标的按下,移动事件,在头文件中添加如下代码:void mousePr...

python中os.path.join()的循环用法_Python os.path.join()用法及代码示例_weixin_39827850的博客-程序员信息网

Python中的OS模块提供了与操作系统进行交互的功能。操作系统属于Python的标准实用程序模块。该模块提供了使用依赖于操作系统的功能的便携式方法。 os.path模块是Python中OS模块的sub-module,用于通用路径名操作。os.path.join()Python中的方法会智能地连接一个或多个路径组件。此方法将各个路径组成部分与每个非空部分之后的最后一个路径组成部分恰好用一个目录分隔...

nvidia-jetson系列硬件平台上安装Qt_Zhongyl_的博客-程序员信息网_jetson qt 安装

nvidia-jetson系列硬件平台上安装Qt目标平台:Jetson Nano、Jetson TX2、etson Xavier NX、Jetson AGX Xavier概述:系统环境:我的设备是下列环境,其实只要是L4T版本的应该都是可以的镜像烧录方式:SDKManager系统镜像版本:L4T-32.4.2系统版本:ubuntu18.04安装Qt库步骤:预览sudo apt-get updatesudo apt-get install qt (输入完不要回车,按一下t

随便推点

CSFramework---通信层(Communication)的实现_Ailsa Zhang的博客-程序员信息网

C/S 开发框架之通信层的实现CSFramework编写的主要目的是,为未来编写相应的服务器/客户端模式下的应用系统提供便利。也就是说,我们的CSFramework将完成最底层的相应工作,使得开发人员在使用此框架时,无需再编写底层操作的代码。最底层–通信层(Communication)的实现基于服务器端和客户端,双方之间需要进行信息的交互,也就是说,无论是服务器端还是客户端,都同时作为信息的...

指令集_diandianyangyi的博客-程序员信息网_指令集怎么写

转载自 http://www.cnblogs.com/li-daphne/p/4067241.html一个完整的指令集结构包括Instuction Fetch Instuction DecodeOperand FetchExcuteResult StoreNext Instruction

php内存管理机制、垃圾回收机制_jacklin_001的博客-程序员信息网_php内存管理机制和垃圾回收机制

一、内存管理机制<?php//内存管理机制var_dump(memory_get_usage());//获取内存方法,加上true返回实际内存,不加则返回表现内存$a = "laruence";var_dump(memory_get_usage());unset($a);var_dump(memory_get_usage());//输出(在我的个人电脑上, 可能会因为系统,PHP版本,载入的扩展不同而不同)://int 240552//int 240720//int 2405

全息裸眼3D主题餐厅沉浸式互动投影无人未来点餐系统_komstone的博客-程序员信息网

全息裸眼3D主题餐厅互动投影无人未来餐厅点餐系统【3D/AR/VR/全息互动投影视觉开发】(1)功能:自身团队开发3D程序,激光雷达感应更精确更灵敏,手势翻页查看菜单,多点触摸点菜,扫码买单付款,真正的有交互有互动,而不是播放视频(2)自定义:可自己编辑菜谱图片名称价格,自定义编辑菜谱书本的数量位置大小,自定义买单二维码(3)内容定制:可根据客户需求定制开发背景特效,对接视频服务器...

paddleocr打包exe,10大报错的解决。。。。成功打包运行_Joyce1001的博客-程序员信息网_paddle打包exe

打包paddleocr时,出现Error: Can not import avx core while this file exists: xxxxxx(你安装Python的径)\paddle2.0\lib\site-packages\paddle\fluid\core_avx.pyd错误:解决方法:进入paddle安装对应的虚拟环境下,如下图所示,找到paddle/libs,如下所示:Copy所有的dll文件到dist下的:pyinstaller可执行文件报错astor:解决方法:注销这三行.

16S 基础知识、分析工具和分析流程详解_weixin_30249203的博客-程序员信息网

工作中有个真理:如果你连自己所做的工作的来龙去脉都讲不清楚,那你是绝对不可能把这份工作做好的。 这适用于任何行业。如果你支支吾吾,讲不清楚,那么说难听点,你在混日子,没有静下心来工作。 检验标准:随时向别人解释你的工作,让别人提出尖锐的问题,看你是不是答不上来。 16S概念 什么是16S?S是什么意思? 16S分析是用来干嘛的?能分析什么? 16S大致的分析原理是什么? 有点生物学基础的...

推荐文章

热门文章

相关标签