GTS中的GtsDevicePolicyTestCases问题分析过程

最近某个项目中在系统新增加了device-admin的权限,这个权限在我们以往的项目中没有适配过,后面出的一系列问题解决起来也颇为头疼,现在记录一下出的其中一个问题:GtsDevicePolicyTestCases android.devicepolicy.gts.ManagedProvisioningRequiredAppsTest#newlyProvisionedFullyManagedDevice_hasRequiredApps

从测试从测试结果中我们可以看到报错的是没有launcher来响应home的广播事件,这不应该啊,检查系统发现launcher也是正常,使用adb模拟home的广播时间launcher也能正常反应

没办法,只能上狠活了

由于GTS测试源码是闭源的,所以我立马掏出反编译工具查看报错的行数

可以看出在断言处失败,我们先来看看测试代码大体在做些什么:

首先注释表明了这条case需要设备支持device-admin权限,然后安装了一个能够设备管理的apk,并设置权限赋予给P,然后一系列的模拟托管设备操作来到了isGmsCoreInstalled方法中,这个方法是判断设备是否包含GMS core(Google Moblie Service),但由于我的是TV设备所以结果为假

后面的就不用看了,因为根本还没到下面的流程,不过通过开头的几句代码我们可以大概想到这个条case想测试device-admin权限的完整性

我们直接跟进测试报错上的报错追溯到最底层:当我看到这里的时候,感觉很失望,因为这段代码并没有直接说明为什么launcher没有响应home事件,代码大概意思是获取Intent响应事件的包名

但是没有关系,我们还可以从log中查找线索:

log中我们看到DevicePolicyManager会去模拟删除一系列apk来验证device-admin权限功能是否正常,但是在删除的apk中我居然发现了launcher app,这下一切都真相大白了

现在问题原因知道,下一步就是要解决这个问题,我们直接查看DevicePolicyManager的源码查看什么样的条件下才会去删除这一部分apk

frameworks/base/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java:

我们看到removeNonRequiredAppsForManagedDevice方法中执行了删除的操作,所需要删除的apk列表从mOverlayPackagesProvider.getNonRequiredApps()方法中传出来,我们查看一下这个方法:

frameworks/base/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java

可以看到applist是从getLaunchableApps()方法中拿到,然后才一系列的过滤操作,注意到注释中“disallowed or have a launcher icon.”,不允许带有启动器icon,这句话是什么意思呢?我第一眼看到这个注释感觉很迷惑,我们看看getLaunchableApps()这个方法里面:

可以看到launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER),这下明白了,launcher中带有Intent.CATEGORY_LAUNCHER属性(android.intent.category.LAUNCHER)的会被视为删除的apk之一,我们查看一下launcher apk中是否有声明这个属性

果然存在,而且和android.intent.category.LEANBACK_LAUNCHER一并存在,我们把这个声明拿掉后重测case,pass了!

为什么launcher不能有android.intent.category.LAUNCHER这个声明呢?当应用程序具有此类别时,它将出现在设备的主屏幕或应用程序列表中,用户可以通过主屏幕或者应用程序列表直接启动app,但是我们是TV设备,TV设备有一个专门的launcher声明“android.intent.category.LEANBACK_LAUNCHER”,这是专门为 Android TV 设备设计的启动器类别,也能够让launcher app图标出现在Leanback Launcher上,如果在TV设备上同时添加这两个声明,可能会导致图标重复啊,权限冲突等一系列问题。

目前为止这个问题就解决完成了,以上分析包含个人的一些拙见,如果有不对的地方,欢迎评论指正!