android GMS认证之testScreenCaptureDisabled_allowedPrimaryUser

这里写图片描述

问题:

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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hfreeman2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值