testSplitscreenSameTokenTwoMissedStop
今天出现一条CTS的fail,之前没出现过,复现步骤必须设置锁屏为none,设置swipe能跑过的,比较奇怪的是之前版本没有出现过,问了测试同事,发现我们这次跑的时候是用多台机器分开跑,于是想明白了,以前全跑的时候应该是跑这条case之前有其他case将锁屏设置为swipe了,这次由于分开跑,这条case和设置swipe的case分开了导致,看一下导致这条case fail的原因:
android.app.usage.cts.UsageReportingTest#testSplitscreenSameTokenTwoMissedStop
junit.framework.AssertionFailedError: Timeout: android.app.usage.cts/SuperSecretToken found in list of active activities and tokens
at junit.framework.Assert.fail(Assert.java:50)
at com.android.compatibility.common.util.TestUtils.failWithLog(TestUtils.java:36)
at com.android.compatibility.common.util.TestUtils.waitUntil(TestUtils.java:76)
at android.app.usage.cts.UsageReportingTest.assertAppOrTokenUsed(UsageReportingTest.java:361)
at android.app.usage.cts.UsageReportingTest.testSplitscreenSameTokenTwoMissedStop(UsageReportingTest.java:350)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:52)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:148)
at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:142)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:919)
/cts/tests/tests/app.usage/src/android/app/usage/cts/UsageReportingTest.java
类里面testSplitscreenSameTokenTwoMissedStop方法里调用assertAppOrTokenUsed断言失败导致,这个方法里调了两次这个方法,根据行号,是断言为false时失败
public void testSplitscreenSameTokenTwoMissedStop() throws Exception {
//开启两个Activity进入分屏模式
launchActivitiesInSplitScreen(
getLaunchActivityBuilder().setTargetActivity(
new ComponentName(mTargetPackage,
Activities.ActivityOne.class.getName())),
getLaunchActivityBuilder().setTargetActivity(
new ComponentName(mTargetPackage,
Activities.ActivityTwo.class.getName())));
assertAppOrTokenUsed(mFullToken0, true);
// 让设备进去睡眠,即灭屏
mUiDevice.sleep();
// 灭屏后再等待1s
Thread.sleep(1000);
assertAppOrTokenUsed(mFullToken0, false);
}
assertAppOrTokenUsed
private void assertAppOrTokenUsed(String entity, boolean expected) throws Exception {
final String failMessage;
if (expected) {
failMessage = entity + " not found in list of active activities and tokens";
} else {
failMessage = entity + " found in list of active activities and tokens";
}
TestUtils.waitUntil(failMessage, ASSERT_TIMEOUT_SECONDS, () -> {
final String activeUsages =
mUiDevice.executeShellCommand("dumpsys usagestats apptimelimit actives");
final String[] actives = activeUsages.split("\n");
boolean found = false;
for (String active: actives) {
if (active.equals(entity)) {
found = true;
break;
}
}
return found == expected;
});
}
mFullToken0的值为应用包名拼接一个TOKEN_0
private static final String TOKEN_0 = "SuperSecretToken";
public void setUp() throws Exception {
super.setUp();
.......
mTargetPackage = InstrumentationRegistry.getTargetContext().getPackageName();
mFullToken0 = mTargetPackage + "/" + TOKEN_0;
}
回到之前代码
通过执行dumpsys usagestats apptimelimit actives命令得到字符串,再以"\n"换行符切割字符串得到的其实就是应用包名,所以此条case测试的就是进去分屏模式,灭屏,看是否能找到还活跃着的Activity,找到即fail,没找到则pass,为什么公司机器有这个问题,google参考机是能够pass的,后来经过调查我们机器没有配置DozeService,添加如下代码能够pass,但是公司机器配置较低,添加DozeService会增加功耗于是此条case只能申请waive
<string name="config_dozeComponent" translatable="false">com.android.systemui/com.android.systemui.doze.DozeService</string>