Android Google XTS

GMS全称为Google Mobile Service,即谷歌移动服务。GMS是Google开发并推动Android的动力,是Google提供的Mobile Device上的一系列应用服务。

Android 系统是开源的,但是google 针对GMS 所提供的Search、Search by Voice、Gmail/Google Mail、Contact Sync、Calendar Sync、Talk、Maps、Street View、YouTube、Google Play服务却是收费的,需要授权(即厂商需要获得),包括CTS、GTS测试以及Google自身的商务考量。

国外许多运营商都要求供应商通过GMS认证,在国外一些运营商主导手机市场的地方,没有GMS认证走运营商渠道是寸步难行。虽然现在有大量的应用,具备GMS服务的功能,但作为谷歌原生的移动应用服务,GMS预置的服务具有稳定性好、兼容性好以及更新及时的主要特点。

一、认证申请流程

  • 申请与Google签署MADA、AFA等一系列协议。
  • 产品、外包装和产品说明书同时提交给3PL。
  • 3PL执行产品硬件测试,并提交测试报告给Google。
  • 获取Google的法律授权和保护。

PS:

  • MADA即Mobile Application Distribution Agreement,移动应用发布协议。
  • AFA即Anti Fragmentation Agreement,反碎片化协议 。
  • 3PL即3rd Party License,Google授权的第三方实验室。

二、GMS测试套件

1、测试前通用准备

  • 下载测试套件,通常找google接口人要取。
  • 准备版本 STS测试刷userdebug版本,其它测试刷user版本,特别的是VTS测试需要刷boot-debug img和system img、GSI测试需要刷system img。其中user固件烧写boot-debug.img后可以进行root权限操作,system.img是Google AOSP的system镜像。更特别的是高通项目还要刷boot.img,例如P800T要刷boot-5.4.img。
  • 全跑模块或者整个GMS测试建议设置手机为如下状态:

Language ---> English(United States)

WIFI连接翻墙网 BLUETOOTH打开 LOCATION ---> ON/High accuracy

Security ---> Screen lock ---> None

Display ---> Sleep ---> never/30m

System ---> Date&time ---> Select time zone(-7/-8) ---> Use 24-hour format

System ---> Aboutphone ---> Build number(点击多次再返回上一菜单) ---> Developer options (on) ---> Stay awake(on) ---> USB debugging(on)

SD card ---> 外置存储 Cellular data(数据) ---> on

2、CTS测试

全称:Compatibility TestSuite,即兼容性测试套件。

测试目的:保证API的兼容性,最终达到各种应用程序(包括二次开发的应用程序)可以兼容的在不同平台上的运行。

测试版本:使用user版本,测试时间约为48小时,建议使用3-4台设备并行执行(64bit项目case翻倍)。

测试套件:CTS套件分Android版本,需要下载对应版本的套件测试,但不分手机位数。

测试步骤:run cts -s 设备号 -m 测试模块 -t 测试项 注:测试命令可以从测试报告上获取。

3、CTS verifer测试

测试目的:CTS Verifier 是CTS测试的补充测试,通过手动测试执行CTS工具无法自动化测试的功能。

测试版本:同CTS测试。

测试套件:测试时要保证CTS verifer工具和CTS为同一版本。CTS verifer工具为一系列apk,主apk为CtsVerifier.apk,还有其它模块apk。

测试步骤:安装测试apk,进入apk并进行手动测试。部分测试有前置条件,如通过adb设置系统属性值:

adb shell settings put global hidden_api_policy 1

adb shell appops set com.android.cts.verifier android:read_device_identifiers allow

adb shell appops set com.android.cts.verifier MANAGE_EXTERNAL_STORAGE 0

4、GSI测试

全称:CTS-on-GSI测试,Compatibility Test Suite on Generic System Image,通用系统镜像上的兼容性测试。

测试目的:在替换谷歌提供AOSP的system.img (GSI)的版本上测试它的兼容性。

测试版本:user版本+system.img,测试时间约为48小时,建议使用3-4台设备并行执行(实际根据项目情况)。system.img镜像从VTS路径获取,区分位数。

测试套件:使用CTS测试套件测试。

测试步骤:run cts-on-gsi -m 测试模块 -t 测试项

5、VTS测试

全称:Vendor Test Suite,供应商测试套件 。

测试目的:向上用于测试与framework的兼容性,向下测试与OS kernel的兼容性。

测试版本:user版本+boot-debug.img+system.img 测试,同cts-on-gsi。

测试步骤:run vts -s 设备号 -m 测试模块 -t 测试项

前置条件:替换镜像

adb reboot bootloader

//已解锁可跳过此步骤

fastboot flashing unlock (power键选择unlock)

fastboot reboot fastboot

//vendor_boot-debug.img在项目flash包里

fastboot flash vendor_boot vendor_boot-debug.img

fastboot erase system

//system.img是Google的,注意下载对应VTS版本的, 如果补丁日期没有对应的可以使用最新的镜像,向下兼容

fastboot flash system system.img

fastboot -w reboot

//如无法开机需要手动清除数据。通过手机按键进入recovery,点击wipe data清除数据。

注意:高通项目通常还需要替换GKI,即boot.img,具体版本要咨询测试

6、GTS测试

全称:Google Mobile Services Test Suite,GMS套件测试。

测试目的:主要是对设备上的GMS应用进行测试,检查设备服务是否符合Google标准。

测试版本:user版本 。GTS套件不区分安卓版本,一般使用最新版本测试,每个版本有使用期限,超过这个期限谷歌会强制报废。

测试步骤:run gts -s 设备号 -m 测试模块 -t 测试项

7、STS测试

全称:Security Test Suite,补丁测试。

测试目的:测试Android Security Pacth是否生效,BTS作为补充。

测试版本:userdebug版本

测试套件:NA

测试步骤:run sts-dynamic-full -s 设备号 -m 测试模块 -t 测试项 或者 run sts-dynamic-incremental -s 设备号 -m 测试模块 -t 测试项

8、BTS扫描

测试内容:提供软件给Google,扫描软件中是否有预装恶意软件或潜在有害的应用程序。如应用缺失安全patch,有危险权限等等。

上传地址:https://partner.android.com/firmwares/

注意事项:

  • 扫完BTS后需要上传一个BTS的白名单报告,以确定possible的项是否exempted。

//执行如下命令

run gts -m GtsEdiHostTestCases -t android.edi.cts.PropertyDeviceInfo#testCollectDeviceInfo

  • 正式版本的白名单报告需要测试用专门的手机来跑,即如下21条Exempted是google豁免的
  • 把flash包的名字改为fingprint,并且部分字符需要修改,除了点号和短横其它符号都要改为英文波浪号,例如:
  • 上传flash包的时候还需要填写fingprint,这里的fingprint不用改符号 查看fingerprint命令:adb shell getprop ro.build.fingerprint

  • 上传的flash包的fingprint要保证在之前的上传中没有用过

  • gts报告的fingprint必须要和上传的flash包的fingprint一致

  • 上传白名单报告入口 依次如图

9、Checklist

全称:GMS MADA Compliance Checklist

简介:Android开源项目(AOSP)提供了常见的设备级功能,如电子邮件和呼叫,但GMS是一个专有的谷歌应用程序和API的集合,支持跨设备增强的功能。为确保安卓系统提供出色的用户体验,谷歌搜索、谷歌播放、YouTube、Gmail等应用程序无缝协作。此页面提供了一个手动测试用例列表,用于验证GMS应用程序是否正确集成,以及其他设备配置是否符合合作公司与谷歌达成的合同条款。

路径:MADA checklist

注意:除此之外还有其它需求相关的checklist,如Google EMADA Compliance checklist(即EEA checklist,欧洲经济区适用的checklist)

10、APTS

APTS长如下样子,听GMS测试leader说这个是测试性能的,其使用方法可以参考如下截图的README.txt

新工具:android-apts-12747879.zip

前置条件:使用user版本

整跑命令:run test/approval-mobile

单跑命令:run test/approval-mobile --test-case

旧工具 :android-apts-11771464.zip

前置条件:使用debug版本

命令: run test/approval-go --fingerprint-swap +fingerprint -s +设备号

例如: run test/approval-go --fingerprint-swap google/wembley/wembley:12/SP1A.210712.001/7539480:user/release -s 4008208820THC

11、建计划批量测试

需要在对应XTS工具包的subplan目录下创建cts-keybox.xml文件:

XML 复制代码
<?xml version='1.0' encoding='UTF-8'?>
<SubPlan version="2.0">
	<Entry include="arm64-v8a CtsKeystoreTestCases android.keystore.cts.KeyAttestationTest#testRsaAttestation_DeviceLocked "/>
	<Entry include="arm64-v8a CtsKeystoreTestCases android.keystore.cts.KeyAttestationTest#testCurve25519Attestation "/>
	<Entry include="arm64-v8a CtsKeystoreTestCases android.keystore.cts.KeyAttestationTest#testEcAttestation_DeviceLocked "/>
	<Entry include="arm64-v8a CtsKeystoreTestCases android.keystore.cts.KeyAttestationTest#testEcAttestation_KeyStoreExceptionWhenRequestingUniqueId "/>
	<Entry include="arm64-v8a CtsKeystoreTestCases android.keystore.cts.KeyAttestationTest#testRsaAttestation "/>
	<Entry include="arm64-v8a CtsKeystoreTestCases android.keystore.cts.KeyAttestationTest#testEcAttestation "/>
	<Entry include="arm64-v8a CtsKeystoreTestCases android.keystore.cts.KeyGenParameterSpecTest#testBuilderSetUidGenerateKeyThrowsException "/>
	<Entry include="arm64-v8a CtsKeystoreTestCases android.keystore.cts.DeviceOwnerKeyManagementTest#testAllVariationsOfDeviceIdAttestation "/>
    <Entry include="arm64-v8a CtsKeystorePerformanceTestCases android.keystore.cts.performance.AttestationPerformanceTest#testEcKeyAttestation "/>
    <Entry include="arm64-v8a CtsKeystorePerformanceTestCases android.keystore.cts.performance.AttestationPerformanceTest#testRsaKeyAttestation "/>
	<Entry include="arm64-v8a CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.MixedDeviceOwnerTest#testDelegatedCertInstallerDeviceIdAttestation "/>
	<Entry include="arm64-v8a CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.MixedDeviceOwnerTest#testKeyManagement "/>
	<Entry include="arm64-v8a CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testKeyManagement "/>
	<Entry include="arm64-v8a CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.MixedProfileOwnerTest#testKeyManagement "/>
	<Entry include="arm64-v8a CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.OrgOwnedProfileOwnerTest#testDelegatedCertInstallerDeviceIdAttestation "/>
	<Entry include="arm64-v8a CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.OrgOwnedProfileOwnerTest#testDeviceIdAttestationForProfileOwner "/>
	<Entry include="arm64-v8a CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testGenerateKeyPairLogged "/>
	<Entry include="arm64-v8a CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testDelegatedCertInstallerDirectly "/>
	<Entry include="arm64-v8a CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testSetKeyGrant" />
	<Entry include="arm64-v8a CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.MixedProfileOwnerTest#testGenerateKeyPairLogged "/>
	<Entry include="arm64-v8a CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.MixedProfileOwnerTest#testDelegatedCertInstallerDirectly "/>
	<Entry include="arm64-v8a CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.MixedProfileOwnerTest#testSetKeyGrant "/>
</SubPlan>

然后执行命令:

run cts --subplan cts-keybox -s 6eb8422d #其中cts-keybox为xml文件名字

三、XTS分析思路

如上各种测试之后,会出现一些failed项,此时我们需要解决这些failed,让其通过测试。下面先介绍针对原型项目,首轮GMS测试石遇到的XTS问题如何进行处理:

1、问题模块初步过滤

原型项目首轮GMS测试通常会遇到很多问题,按以往经验20-50个XTS问题符合预期情况,此时需要XTS模块owner进行初步分配,分配规则如下:

  • Media模块分配:通常会报大量的media模块相关问题,此类问题的测试用例都有media这样的字样
  • Audio模块分配:通常会有很多效果参数相关,大部分都分配给音频驱动
  • Display模块分配:此类通常有一些,此类问题的测试用例都有display或者surface这类的字符串
  • Camera模块分配:此类测试用例都有camera相关的字样
  • WIFI/Network模块分配:通常分配给短距同事
  • Sensor/VTS模块分配:通常分配给驱动同事
  • Telephone/Modem模块分配:直接分配给通信同事

2、研发自测Retry失败项

全部过滤一遍,并且相关分模块分发完以后,剩下的就是我们需要解决的,相关的fail项,最好是我们先进行retry一遍,因为在第一次跑的时候,很多fail可能是环境因素造成的,还有是别的测试项影响到了,所以一般都先自己retry一遍 ,先按照以下步骤进行自测:

  • Step1:测试之前先查看测试注意事项:http://online.mediatek.com/QuickStart/QS00017#QSS00138
  • Step2:确认retry是否可以pass?如果retry可以pass;可以不必纠结此Fail;
  • Step3:确认最新的daily build tool是否可以pass?若可以pass(合法有效,google认可),则不必纠结此Fail;
  • Step4:确认单跑(单个case或单跑模块)是否可以pass? 如果单跑可以pass,则不必纠结此Fail;
  • Step5:手机恢复出厂设置后是否可以pass?如果可以pass,则不必纠结此Fail;
  • Step6:更换测试机或者辅助机是否可以pass?如果可以pass,则不必纠结此Fail;
  • Step7:进入MTK Online CTS快速入门:查看对应版本google issue栏位,查找对应项是否为Google issue,如果是google issue,则不需要纠结此Fail;
  • Step8:进入MTK FAQ 搜索:https://online.mediatek.com/FAQ
  • Step9:自查如下信息

MTK平台进入CTS快速入门:https://online.mediatek.com/QuickStart/QS00017#QSS00135 查看对应版本google issue栏位,里面会更新当前比较新出现的问题,还有就是直接在搜索框里搜索

QCOM平台通常会有针对该平台的一个内部测试报告,可以直接在他们的官方网站上面搜索:

  • tep10:如果以上几个步骤,都无法定位您的问题,请向MTK提交eService过来分析,或者像高通平台提交case进行分析。

3、正向分析XTS日志和报告

我们处理fail项的时候一般会根据测试项的报告和log来处理,跑完测试项后报告和log会自动生成在工具的目录下面

首先是看报告,一般报告会直观的反馈fail项错误的原因,报告指的是test_result.html,test_result.xml两个文件。两者任看其一便可 test_result.html:

有些时候test_result.html 显示的信息不完整,或者没有这个文件,这个时候需要看test_result.xml

如果看报告得不到什么有效信息,那就需要我们取看相关的log,一般是看host_log 这个是终端打印的所有log,因为你直接在终端看的时候,他有些内容会压缩,不会打印出来,所以可以在host_log 看

最后通过如上的一些测试用例,我们可以去源码进行搜索,了解他们的测试逻辑,例如:

有些测试套件可能没有在源码里面,这个时候需要反编译他们的APK,例如:

四、XTS案例收集

下面关于一些比较场景的案例进行分析

1、半自动化 or 手动测试

Checklist问题

问题现象:进入Settings-Accessibility菜单 发现无Talkback应用

分析过程:由于该应用属于GMS包中的应用,初步判断Talkback版本不适配导致无法正常显示

我们在ftp中找到Talkback最新的版本下载到本地并解压出来

将解压出来的文件apk替换本地代码路径中的apk (os\la.qssi14\vendor\partner_gms\apps\talkback)

整编本地代码后刷机验证Talkback是否正常显示

问题总结:针对CheckList问题,因为没有自动化工具,通常使用人工去识别,需要充分理解相关的测试用例,通常涉及到UI和一些应用相关的功能

Notification Full Screen Intent Test

日志分析:通过和对比机对比

对比机:

bash 复制代码
2024-12-13 17:26:54.898 1910-1910 NotificationListener com.android.systemui D onNotificationPosted: StatusBarNotification(pkg=com.android.cts.verifier user=UserHandle{0} id=1001 tag=271a2380-54bf-4aec-ae67-e44cc539d308 key=0|com.android.cts.verifier|1001|271a2380-54bf-4aec-ae67-e44cc539d308|10217: Notification(channel=NotifFsiVerifier shortcut=null contentView=null vibrate=null sound=null defaults=0x0 flags=0x80 color=0x00000000 actions=1 vis=PRIVATE))
2024-12-13 17:26:54.905 1442-2191 PowerGroup system_server I Waking up power group from Dozing (groupId=0, uid=10167, reason=WAKE_REASON_APPLICATION, details=com.android.systemui:full_screen_intent)...
2024-12-13 17:26:54.906 1442-2191 PowerManagerService system_server I Waking up from Dozing (uid=10167, reason=WAKE_REASON_APPLICATION, details=com.android.systemui:full_screen_intent)... 2024-12-13 17:26:54.908 1910-8220 KeyguardViewMediator com.android.systemui D onStartedWakingUp, seq = 16, mPowerGestureIntercepted = false 2024-12-13 17:26:54.908 1910-8220 KeyguardViewMediator com.android.systemui D notifyStartedWakingUp

测试机:

bash 复制代码
2024-12-12 20:50:24.540 1477-1615 DreamManagerService system_server W Dream ComponentInfo{com.android.dreams.alwaysondisplay/com.android.dreams.alwaysondisplay.AlwaysOnDisplay} does not exist
2024-12-12 20:50:25.669 2619-2619 NotificationListener com.android.systemui D onNotificationPosted: StatusBarNotification(pkg=com.android.cts.verifier user=UserHandle{0} id=1001 tag=6d7828a3-96c7-44d6-8bb4-e9d9ca9d51e4 key=0|com.android.cts.verifier|1001|6d7828a3-96c7-44d6-8bb4-e9d9ca9d51e4|10166: Notification(channel=NotifFsiVerifier shortcut=null contentView=null vibrate=null sound=null defaults=0x0 flags=0x80 color=0x00000000 actions=1 vis=PRIVATE))

问题分析:开始进行Notification Full Screen Intent测试,屏幕不会自动亮屏。

从log看,测试的时候notification已经发了,但没有亮屏显示。需要配置了Doze,来通知才会亮屏显示。

W Dream ComponentInfo{com.android.dreams.alwaysondisplay/com.android.dreams.alwaysondisplay.AlwaysOnDisplay} does not exist

这个是表示有配置了这个功能,但没有安装AlwaysOnDisplay.apk。这个是MTK 的aod,没有通知亮屏的功能。

解决方法:可以将配置AlwaysOnDisplay的地方替换成com.android.systemui/com.android.systemui.doze.DozeService 。

问题总结:Notification Full Screen的相关通知来亮屏需要配置了Doze,可以通过配置alwaysondisplay或者systemui的DozeService 来实现自动亮屏的功能。

GtsInteractiveGeminiTestCases

问题背景:更新了2025-01的google gms包之后,报出此条异常,此条为GV测试,半自动化

日志分析:com.google.android.geminiinteractive.gts.GeminiTest#outOfBox_LPPOrCornerSwipe3ButtonNavMode_showAssistApp|fail|expected to be true|

如上日志此测试项为新增测试项,看起来和自动唤醒语音助手有关系,之前在北美项目遇到过,配置了两个相关的参数,如上截图圈出来的,配置参数:

反编译测试用例源码,可以看到这里的两个配置对应商米的两个测试逻辑,如果支持LPP(长按电源键)弹出LongPressPowerButtonTriggerDefaultAssistAppStep测试界面,如果不支持LPP弹出SwipeFromBottomCornerIn3ButtonNavmodeStep测试界面。

LongPressPowerButtonTriggerDefaultAssistAppStep测试界面:翻译过来就是长按电源键,需要默认调用assist应用

SwipeFromBottomCornerIn3ButtonNavmodeStep测试界面:翻译过来就是三键导航模式下,需要底部往上滑动调用assist应用,注意这个是手势模式特有功能,后研究google要求如果长按电源键LPP不支持,那么必现的实现一个这样的功能

解决方案:如下google gms文档要求,要求开机默认能够通过一种方式唤醒assist应用

通常LPP长按电源键默认实现了这个功能,如下截图在settings界面打开此开关

如果这个功能没有默认设定,那么需要手动实现三键导航模式底部下滑唤醒assist,在android 15上面已经上了相关patch,但是针对android 14需要自己实现

https://cs.android.com/android/_/android/platform/packages/apps/Launcher3/+/053997ed827c36acf9880a339b106fa687fbed94

https://cs.android.com/android/_/android/platform/frameworks/base/+/36635f19e8435bad8c76d56c41514f14f6d6facd

https://cs.android.com/android/platform/superproject/+/android15-qpr1-release:build/release/aconfig/ap4a/com.android.systemui.shared/

最后推动客户去评审需求,客户内部评审之后客户GMS测试组王士林咨询了google实验室,此条测试项为A15强制要求,在A14并没有强制要求,是否可以在测试之前手动去设置Digital assistant,实验室给到回复可以这样操作

问题总结:此类需求问题和google gms规范冲突,建议去和客户去pk

Work profile Screenshot Test

问题背景:在进行CTS-V测试的时候,进入Work profile Screenshot截图之后,找不到截图的图片,正常情况应该如下

测试步骤:

  • 步骤 1 进入 Work profile Screenshot Test 测试
  • 步骤 2 单击"OPEN WORK APP"按钮
  • 步骤 3 使用待测设备的物理按键截取当前页面
  • 步骤 4 单击"CHOOSE SCREENSHOT"按钮,选择步骤 3 抓取的截图。验证下图(右)中棋盘区域图像:− 图像中包含"Work App"。− 图像中不包含任何其他应用窗口或导航栏内容(如返回、主页、时钟、电池、信号等)。
  • 步骤 5 如以上测试步骤和现象均满足,则测试 Pass,单击"PASS"按钮
  • 测试结果FAIL,截图保存失败,未找到截图

问题分析:此问题必现,因为对fw profile工作机制并不是很熟,因此夹版本定位到客户有对vendor_required_apps_managed_profile这些参数进行定制,最后发现这些配置在GMS包里面已经配置好了,因此解决方案就是和gms包配置进行对齐:

2、安全补丁STS相关

StsHostTestCases

报错日志:android.security.sts.CVE_2024_0049#testPocCVE_2024_0049

分析过程:如上STS是检测是否有安全补丁遗漏,基本上可以通过名字看出来遗漏哪一笔patch:CVE_2024_0049

我们通常可以在google官方网站https://source.android.com/docs/security/features搜索如上编号:

核对2024年3月的安全补丁v1.2版本对应的patch在system A14里面已经合入,通常此情况一般为我们对原生代码的定制,使其原生代码逻辑已经不生效了,例如在传音项目就经常遇到

奇怪的是812纯wifi的机器有不会报错,810带telephone的机器存在报错,他们都是同一份软件,但是我们的vendor A11没用合入,因为google已经没维护,按照google规范把A12的此笔patch打入到vendor A11里面验证PASS

问题总结:针对STS问题我们可以通过google安全补丁网站查询对应的CVE编号来核对具体缺少的patch,如果已经存在patch则考虑是否存在定制或者遗留地方修改

高通特定CVE-2021-30335导致STS进入Dump

问题描述:商米T602项目合入2025-03的安全补丁之后,研发自测STS跑的过程中没有出现异常。测试上报跑STS的时候进入dump

日志分析:抓取日志发现出现CVE-2021-30335相关的异常日志

解决方案:在google官方网站搜索此条patch为高通特有的组件,关于内核相关的漏洞,但是无法访问,最后提高通case申请patch

问题总结:针对高通项目,高通不提供安全补丁,因此只能合入google原生,但是高通又有自己的定制和特性,难免会存在各种patch漏合入的情况,此类问题只有遇到问题具体分析,咨询高通

蓝牙共性问题之GtsTetheringTestCases

日志分析:com.google.android.tethering.gts.ProvisioningTest#testRunSilentBluetoothTetherProvisioningAndEnable

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 02-11 11:15:14 D/ModuleListener: ModuleListener.testStarted(com.google.android.tethering.gts.ProvisioningTest#testRunSilentBluetoothTetherProvisioningAndEnable) on dced9042 02-11 11:15:49 I/ModuleListener: [1/2] dced9042 com.google.android.tethering.gts.ProvisioningTest#testRunSilentBluetoothTetherProvisioningAndEnable FAILURE: junit.framework.AssertionFailedError at junit.framework.Assert.fail(Assert.java:48) at junit.framework.Assert.assertTrue(Assert.java:20) at junit.framework.Assert.assertTrue(Assert.java:27) at com.google.android.tethering.gts.ProvisioningTest*.lambda$runBluetoothTest$5(ProvisioningTest.java:232)* at com.google.android.tethering.gts.ProvisioningTest.$r8$lambda$YHUX8nLTpHu--tARh7pC4D4shwM(Unknown Source:0) at com.google.android.tethering.gts.ProvisioningTest$$ExternalSyntheticLambda4.run(D8$$SyntheticClass:0) at com.android.testutils.TestPermissionUtil$runAsShell$2.invoke(TestPermissionUtil.kt:82) at com.android.testutils.TestPermissionUtil$runAsShell$2.invoke(TestPermissionUtil.kt:82) at com.android.testutils.TestPermissionUtil.runAsShell(TestPermissionUtil.kt:54) at com.android.testutils.TestPermissionUtil.runAsShell(TestPermissionUtil.kt:82) at com.android.testutils.TestPermissionUtil.runAsShell$default(TestPermissionUtil.kt:77) at com.android.testutils.TestPermissionUtil.runAsShell(Unknown Source:22) at com.google.android.tethering.gts.ProvisioningTest.runBluetoothTest(ProvisioningTest.java:229) at com.google.android.tethering.gts.ProvisioningTest.testRunSilentBluetoothTetherProvisioningAndEnable(ProvisioningTest.java:207) 02-11 11:15:49.988 1002 13399 13399 E droid.bluetooth: Failed to register native method com.android.bluetooth.hid.HidHostService.getProtocolModeNative([BZ)Z in /system/app/Bluetooth/Bluetooth.apk |

原因分析:反编译测试用例apk

看测试用例在检测蓝牙tethering是否处于活动状态,和蓝牙开启状态有关,排查与合入的蓝牙补丁有关,高通平台合入patch需要注意带qcom路径的文件是否合入,报错的话可以提高通case咨询

问题总结:高通对蓝牙模块进行了定制,所以针对高通项目在合入google安全补丁的时候需要特别注意是否存在蓝牙模块的修改,因为高通定制目录差异很大,最保险的方式是去给高通申请patch

3、多媒体相关

CtsVideoTestCases

错误报告:

分析过程:

  • 首先通过以测报错可以看出是, c2.android.avc.encoder的video/avc 720x480格式的期望帧率是 47到83,而实际测试帧率是244到236,所以给出的判断就为falied,所以测试项失败。

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| java.lang.AssertionError: Expected achievable frame rates for c2.android.avc.encoder video/avc 720x480: [47.0, 83.0]. Measured frame rate: [244.24467084261397, 236.76031292660932]. expected null, but was:<Expected achievable frame rates for c2.android.avc.encoder video/avc 720x480: [47.0, 83.0]. Measured frame rate: [244.24467084261397, 236.76031292660932]. > at org.junit.Assert.fail(Assert.java:89) at org.junit.Assert.failNotNull(Assert.java:756) at org.junit.Assert.assertNull(Assert.java:738) at android.video.cts.VideoEncoderDecoderTest.doTest(VideoEncoderDecoderTest.java:552) at android.video.cts.VideoEncoderDecoderTest.perf(VideoEncoderDecoderTest.java:209) at android.video.cts.VideoEncoderDecoderTest.testPerf(VideoEncoderDecoderTest.java:331) |

  • 从android.video.cts.VideoEncoderDecoderTest#testPerf此测试项的代码逻辑去看如下:

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public static String verifyAchievableFrameRates(String name, String mime, int w, int h, boolean fasterIsOk, boolean bFramesEnabled, double... measuredFps) { Range<Double> reported = MediaUtils.getVideoCapabilities(name, mime).getAchievableFrameRatesFor(w, h); String kind = "achievable frame rates for " + name + " " + mime + " " + w + "x" + h; if (reported == null) { return "Failed to get " + kind; } double tolerance = FRAMERATE_TOLERANCE; if (bFramesEnabled) { tolerance *= EXTRA_TOLERANCE_BFRAMES; } double lowerBoundary1 = reported.getLower() / tolerance; double upperBoundary1 = reported.getUpper() * tolerance; double lowerBoundary2 = reported.getUpper() / Math.pow(tolerance, 2); double upperBoundary2 = reported.getLower() * Math.pow(tolerance, 2); Log.d(TAG, name + " " + mime + " " + w + "x" + h + " lowerBoundary1 " + lowerBoundary1 + " upperBoundary1 " + upperBoundary1 + " lowerBoundary2 " + lowerBoundary2 + " upperBoundary2 " + upperBoundary2 + " measured " + Arrays.toString(measuredFps)); // boolean fasterIsOk = mUpdatedSwCodec & encoderName.startsWith("c2.android."); // 包含c2.android.的编码格式 只需要解码帧率大于下限 if (fasterIsOk) { double lower = Math.max(lowerBoundary1, lowerBoundary2); for (double measured : measuredFps) { if (measured >= lower) { return null; } } } else { double lower = Math.max(lowerBoundary1, lowerBoundary2); double upper = Math.min(upperBoundary1, upperBoundary2); for (double measured : measuredFps) { if (measured >= lower && measured <= upper) { return null; } } } return "Expected " + kind + ": " + reported + ".\n" + "Measured frame rate: " + Arrays.toString(measuredFps) + ".\n"; } |

从上述 VideoEncoderDecoderTest的testPerf最终执行逻辑就是 就是 verifyAchievableFrameRates方法,去判断实际的运行帧率,与配置文件的配置帧率是否符合,其中含有 c2.android.的编码格式 只需要实际解码帧率大于配置帧率下限即可。

  • 所以只需针对上述使用到的帧率搜索项目里面使用的media_codecs_performance.xml文件进行配置就可以了

修改链接如下:http://13.76.45.58:8088/c/qcm6490/systemsteam/meig-android-12-os-la.um-vndr-qcom-proprietary/+/20808

修改逻辑:

  • 修改的帧率区间一般要包含实际测试帧率区间
  • 修改的range以一个比率不要太夸张,即upper-limit / lower-limit <= 2.2 , 比如上图所示的的530/570=1.075<2.2

问题总结:针对media此类问题,通常为性能不满足导致,需要修改相关配置使其达到满足条件;如果在测试过程中无法PASS又不想重出版本可以尝试pull vendor/etc/media_codecs_performance.xml文件修改参数并推送进去

CtsVideoTestCases

报错日志:12-09 23:24:52.414 10279 10869 10881 D MediaPerfUtils: c2.android.h263.encoder video/3gpp 176x144 lowerBoundary1 59.090909090909086 upperBoundary1 385.00000000000006 lowerBoundary2 36.15702479338842 upperBoundary2 629.2 measured [831.0177110023136, 844.7577476996865]

12-09 23:24:52.456 10279 10869 10881 E TestRunner: failed: testPerf[video/3gpp_c2.android.h263.encoder_176x144_0](android.video.cts.VideoEncoderDecoderTest)

12-09 23:24:52.456 10279 10869 10881 E TestRunner: ----- begin exception -----

12-09 23:24:52.456 10279 10869 10881 E TestRunner: java.lang.AssertionError: Expected achievable frame rates for c2.android.h263.encoder video/3gpp 176x144: [130.0, 175.0].

12-09 23:24:52.456 10279 10869 10881 E TestRunner: Measured frame rate:[831.0177110023136, 844.7577476996865].

12-09 23:24:52.456 10279 10869 10881 E TestRunner: expected null, but was:<Expected achievable frame rates for c2.android.h263.encoder video/3gpp 176x144: [130.0, 175.0].

12-09 23:24:52.456 10279 10869 10881 E TestRunner: Measured frame rate: [831.0177110023136, 844.7577476996865].

解决方案:

range=较小的值-较大的值 [130.0, 175.0], 实际测量较小的值>较小的值/2.2, 实际测量较大的值<较大的值*2.2,比如上述结果 844 > 175*2.2=385 = upperBoundary1的值。修改合适的区间即可

比如上述修改:844 < 420*2.2 =924 , 这个区间的间隔不要太大就行

问题总结:测试设备当前的性能会影响测试结果,实际测试出来的*帧率*参数大于 upperBoundary1,测试用例要求要小于upperBoundary1,所以出现上述错误

WvtsDeviceTestCases

报错日志:com.google.android.wvts.WidevineBusinessLogicTests#testWidevineVersion

<TestCase name="com.google.android.wvts.WidevineBusinessLogicTests">

<Test result="fail" name="testWidevineVersion">

<Failure message="java.lang.AssertionError: CDM build is not up to date 16.0.1&#64;001. Expect minimum build 007">

<StackTrace>java.lang.AssertionError: CDM build is not up to date 16.0.1&#64;001. Expect minimum build 007

at org.junit.Assert.fail(Assert.java:89)

at org.junit.Assert.assertTrue(Assert.java:42)

at com.google.android.wvts.WidevineBusinessLogicTests.testWidevineVersion(WidevineBusinessLogicTests.java:191)</StackTrace>

</Failure>

分析过程:最初以为这个widevine版本可能是测试什么工具,让测试使用最新的临时工具来跑此条,但是之前能过pass的版本和当前版本都无法pass,可以证明为google机器变动导致,后经过沟通咨询其他人,需要更新vendor目录下的widevine,针对此条测试用例,反编译GTS工具的测试逻辑如下:

跟对这块比较熟悉的同事了解到,可以抓取bugreport的日志来查看当前widevine的版本号:

解决方案:widevine库太老,因此集成最新版本的widevine库即可

值得注意的是在选择版本的时候需要根据项目的vendor的版本,例如P812项目的vendor还是R,那么久选择widevine-r-widevine-partner-fs-release(20240614).tar.gz文件,最后直接替换所有源码

解决方案:

验证方式:除了跑对应的XTS测试项,因为更新了widevine,最好还是下载Netflix进行测试一下,它是一个视频播放软件,但是里面的视频都具有版权,因此普通账号需要充值,我们可以找测试要这个账号进行验证。

问题总结:WvtsDeviceTestCases此类case比较特殊,通常在新的基线上面并不会报此版本过低,P81X项目为什么报版本过低是因为vendor使用的Android 11基线,好几年都没有更新这个。另外如果有widevine相关联的XTS请写Widevine KEY来进行测试

4、Google闭源组件相关

GtsMbaPrivilegedPermissionTestCases

报错日志:com.google.android.mbaprivilegedpermission.gts.GtsDebugCertificateTest#testMbaPrivilegedPermission

bash 复制代码
​java.lang.RuntimeException: Test failed due to unrecognized service account for this product, please submit an initial GTS report for this product with full EDI (run gts -m GtsEdiHostTestCases) at https://partner.android.com/approvals/upload-report and try again. at org.junit.Assert.fail(Assert.java:89) at com.android.compatibility.common.util.BusinessLogicTestCase.failTest(BusinessLogicTestCase.java:126) at java.lang.reflect.Method.invoke(Native Method) at com.android.compatibility.common.util.BusinessLogicExecutor$ResolvedMethod.invoke(BusinessLogicExecutor.java:232) at com.android.compatibility.common.util.BusinessLogicExecutor.invokeMethod(BusinessLogicExecutor.java:157) at com.android.compatibility.common.util.BusinessLogicExecutor.executeAction(BusinessLogicExecutor.java:76) at com.android.compatibility.common.util.BusinessLogic$BusinessLogicRuleAction.invoke(BusinessLogic.java:336) at com.android.compatibility.common.util.BusinessLogic$BusinessLogicRule.invokeActions(BusinessLogic.java:282) at com.android.compatibility.common.util.BusinessLogic$BusinessLogicRulesList.invokeRules(BusinessLogic.java:242) at com.android.compatibility.common.util.BusinessLogic.applyLogicFor(BusinessLogic.java:87) at com.android.compatibility.common.util.BusinessLogicTestCase.executeBusinessLogicForTest(BusinessLogicTestCase.java:79) at com.android.compatibility.common.util.BusinessLogicTestCase.executeBusinessLogic(BusinessLogicTestCase.java:65) at com.android.compatibility.common.util.BusinessLogicTestCase.handleBusinessLogic(BusinessLogicTestCase.java:61)

​

解决方案:Tinno MADA的项目 使用tinno的json 文件 ,跑GTS 时 需要关注 APE_API_KEY

下图展示的是传音的json

即使用不同的MADA进行申请,就得用对应的MADA。有一些客户有自己的MADA,就得用他们的MADA json文件。

将该文件放入相应的目录下 ,在运行./ gts-tradefed 之前 切换json 文件,命令如下图,后面正常执行跑测命令

总结:testMbaPrivilegedPermission的结果如果是要求我们提交GtsEdiHostTestCases白名单,那么说明google服务器没有该项目相关的信息,提示我们用公司MAD去进行申请。因此这种情况有两种:GMS测试机器的mada key选择的和这个项目申请的不匹配,需要在gms测试机器切换一下对应的mada key;当前项目向服务申请还没有成功,需要重新提交GtsEdiHostTestCases进行申请

GtsOsTestCases

报错日志:此案例有三条子项出现异常

com.google.android.os.gts.SysConfigTest#testValidSysConfigPresent:根据如下日志为gms包缺少link相关的配置

FAILURE: java.lang.AssertionError: Modification of required config file:

Missing elements for tag linkedApps: 'com.google.android.apps.photos'

. required={com.google.android.youtube, com.android.vending, com.google.android.apps.docs, com.google.android.apps.maps, com.google.android.videos, com.google.android.apps.photos, com.google.android.calendar, com.google.android.talk}

. all={com.google.android.youtube, com.google.android.apps.docs.editors.docs, com.google.android.apps.docs.editors.sheets, com.google.android.apps.docs.editors.slides, com.android.vending, com.google.android.apps.docs, com.google.android.apps.maps, com.google.android.gms, com.google.android.videos, com.google.android.calendar, com.google.android.apps.photosgo, com.google.android.apps.wallpaper, com.google.android.talk, com.google.android.apps.youtube.music}

com.google.android.os.gts.MainlineModulePreloadTest#testModulesPreloadedCorrectly:根据如下日志没有集成 com.google.android.conscrypt

FAILURE: java.lang.AssertionError: Package com.google.android.conscrypt not found which must be preloaded

com.google.android.os.gts.MainlineModulePreloadTest#testModulesPreloadedCorrectly:根据如下日志表示之前白名单申请的信息不对或者白名单没有进行申请

Failure message="java.lang.RuntimeException: Test failed due to unrecognized service account for this product, please submit an initial GTS report for this product with full EDI (run gts -m GtsEdiHostTestCases) at https://partner.android.com/approvals/upload-report and try again."

如上报错,unrecognized service account for this product表示设备没有注册,提示我们跑白名单run gts -m GtsEdiHostTestCases上传报告进行申请,原因为申请白名单之后,我们有对fp属性进行修改,请教了timo大神,回复如下:

com.google.android.os.gts.MainlineConfigurationTest#testMainlineApprovedTrain:根据如下日志没有集成mainline里面的一些包

FAILURE: java.lang.AssertionError: Module(s) not approved for preloading found.: com.google.android.go.permission: 350910080, com.google.android.go.sdkext: 350910000, com.google.mainline.go.primary: 350931000, com.google.android.go.os.statsd: 350911020, com.google.android.go.ipsec: 350820420, com.google.android.go.neuralnetworks: 350820420, com.google.android.go.media: 350914000, com.google.android.go.appsearch: 350820420, com.google.android.go.art: 350913340, com.google.android.go.captiveportallogin: 350820420, com.google.android.go.resolv: 350820420, com.google.android.go.wifi: 350912040, com.google.android.go.cellbroadcast: 350910020, com.google.mainline.go.primary.libs: 350931000, com.google.android.go.adbd: 350820420, com.google.android.go.networkstack: 350911020, com.google.android.go.configinfrastructure: 350820420, com.google.android.go.scheduling: 350820420, com.google.android.go.extservices: 350912023, com.google.android.go.adservices: 350923060, com.google.android.go.tethering: 350911120, com.google.android.go.documentsui: 350915120, com.google.android.go.uwb: 350911040, com.google.android.go.ondevicepersonalization: 350923040, com.google.android.go.media.swcodec: 350914020, com.google.android.go.conscrypt: 350820420, com.google.mainline.go.telemetry: 350907000, com.google.android.go.healthfitness: 350921160, com.google.android.go.tzdata5: 341510170, com.google.android.go.mediaprovider: 350914160, Try factory reset or preload Mainline modules approved for preloading only.

com.google.android.os.gts.MainlineConfigurationTest#testMainlineModuleProviderOverlay:根据如下日志检查针对go项目检查mainline的com.google.mainline.go.primary失败

FAILURE: org.junit.ComparisonFailure: Invalid config_defaultModuleMetadataProvider: com.google.mainline.go.primary expected: com.google.android.modulemetadata expected:<com.google.[mainline.go.primary]> but was:<com.google.[android.modulemetadata]>

com.google.android.os.gts.SecurityPatchTest#testSecurityPatchDate:根据如下日志很明显为需要更新安全补丁

FAILURE: junit.framework.AssertionFailedError: ro.build.version.security_patch should be "2024-09" or later. Found "2024-08-05"

at junit.framework.Assert.fail(Assert.java:50)

at junit.framework.Assert.assertTrue(Assert.java:20)

at com.google.android.os.gts.SecurityPatchTest.testSecurityPatchDate(SecurityPatchTest.java:113)

问题总结:GtsOsTestCases主要用来测试google mainline/google gms/google security是否符合要求,遇到此类问题,我们只需要把对应的模块更新到最新即可

GtsPermissionTestCases

报错日志:com.google.android.permission.gts.DefaultPermissionGrantPolicyTest#testDefaultGrantsWithRemoteExceptions

解决方案:如上这类测试用例是为了检查所有应用有没有申请不该申请的权限,通常我们只需要去掉权限即可,但是要确认对应权限的功能是否受到影响,如果确定一定要保留此功能,可以申请google豁免

注意事项:此类问题通常会报所有的应用的权限,如果比较多,test.html可能展现不完,需要去check日志

规避方案:如下代码可以绕过白名单检查,规避权限问题

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 557875c..d35781f 100755 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -176,6 +176,12 @@      @GuardedBy("mDelegates")      private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>();   +    private static  final String[] mGtsWhitelistPackageName = { +            "com.android.bluetooth", +    }; +      UserManager getUserManager() {          if (mUserManager == null) {              mUserManager = UserManager.get(mContext); @@ -832,6 +838,18 @@      @Override      public int checkPermission(String permName, String pkgName) { +        String caller = mContext.getPackageName(); +        if ("com.google.android.permission.gts".equals(caller) || +            "android.permission.cts".equals(caller)) { +          int size = mGtsWhitelistPackageName.length; +            for(int i = 0; i < size; i++){ +                if(mGtsWhitelistPackageName[i].equals(pkgName)){ +                   return PERMISSION_DENIED; +                } +            } +        }          return PermissionManager.checkPackageNamePermission(permName, pkgName, getUserId());      } |

问题总结:GtsPermissionTestCases用例是针对应用权限有没有滥使用的情况,此类问题可以根据日志进行去掉对应权限即可 ,如果在无法去掉权限的情况下,我们可以考虑申请google豁免或者添加权限白名单判断包名来进行跳过

MctsMediaDrmFrameworkTestCases

报错日志:MctsMediaDrmFrameworkTestCases

com.android.tradefed.targetprep.TargetSetupError[APK_INSTALLATION_FAILED|520001|DEPENDENCY_ISSUE]: Failed to install android.media.drmframework.cts with [/tmp/xts-root-dir-a592ef1e-9dc0-40b3-9c57-0c700aa8f230/android-cts/testcases/MctsMediaDrmFrameworkTestCases/arm64/MctsMediaDrmFrameworkTestCases.apk] on SH482317502066. Reason: 'Unknown failure: Exception occurred while executing 'install': java.lang.IllegalArgumentException: Error: Failed to parse APK file: /data/local/tmp/MctsMediaDrmFrameworkTestCases.apk: Requires newer sdk version #35 (current version is #34) at com.android.server.pm.PackageManagerShellCommand.setParamsSize(PackageManagerShellCommand.java:697) at

问题分析:根据日志来看完全没有跑起来,且后面的done的值为false,特定咨询了google,google回复如下:

问题总结:针对一些老工具和新工具之间新增的测试用例,可能是google mainline问题,后google在mainline上面进行移除之后,工具跑出来的结果就是5个0。特别注意MTCS这类测试用例apk可能并不在自动化测试工具,但是会从google服务器下载的测试用例apk进行测试,因此针对google服务器的变动,可能测试结果随时都不一样

GtsReadLogStringTest/GtsLocationContextMultiDeviceTestCases

日志分析:测试在跑这两条用例的时候,没有跑起来,DONE里面也没有任何状态显示,如下截图:

进一步分析日志,发现在跑之前发现有判断版本的逻辑进行跳过打印

解决方案:因为直接没有出结果,最后给google提case进行豁免,google回复让我们使用新工具进行测试

问题总结:针对完全没有跑起来,DONE也没有true和false的结果,我们优先确认哈是否环境问题,如果排除环境可以怀疑google移除,或者跟踪日志定位什么原因没有跑起来,此类问题已经确定后最终解释权还是得提google让google提供方案

什么条件下才需要提交豁免? --->丁鹏程整理(不一定正确,单纯经验分享)

站在google的立场,google规定只要fp属性不一致,就需要去提交豁免,例如这个MR1版本申请的豁免ID,在MR2版本上面同样出现了相同的报错,按照google的要求需要在MR2上面也去提交申请豁免

但是在实际过程中,我们通常并没有严格按照这个要求执行,即MR1版本申请的豁免ID,在MR2版本上面同样出现了相同的报错,我们复用了之前的豁免ID,提交给google,最后也是拿到了appr认证,因此针对上述条件下,个人建议,google在没有强制严格执行的情况下,我们可以放手一搏,毕竟google那边的审核也是人工审核,是人工就难免存在纰漏。

但还是有些场景需要注意,需要我们重新申请豁免ID,例如项目A申请了豁免ID,在项目B上面同样出现了相同的报错,他们不仅仅是fp属性不一致,device name等信息也都不一致,为了避开google的嫌疑和质问,我们通常的做法是在不同项目上面都会去申请豁免ID,因为如果google因为这个原因给你拒绝了,google也是按照规章办事情,合情合理。即google是否认可你的豁免ID,解释权全部归google所有。

下面有一个案例,磐珑P81X项目,该项目有两个device name,有五个sku,内部项目名称有三个(P810/P811/P812),一共如下10个版本,那么这个项目同一个问题需要申请多少个豁免ID呢?

最后和TIMO大神沟通,此问题的关键在于判断下面10个版本,哪些是leading项目,哪些是vba变种项目?

  • 按照google的要求leading项目需要CTS全部测试,vba变种项目不需要进行CTS全部测试,可以直接复用leading项目的报告,因此他们的fp虽然不一致,但是到底哪些需要申请豁免ID,针对于CTS的问题取决于哪些版本是leading
  • 针对GTS不一样,GTS要求leading项目和vba变种项目都需要去全部测试,因此无法复用leading项目的报告,因此leading和vba项目都需要单独申请豁免ID;google系统自动判定
  • 但是如果提交给google的方式都是全部测试,即没有通过vba变种的方式去整理报告,那么在google系统就无法当成vba变种项目,因此这种情况下就定死了,无法更改,所有的版本都需要申请豁免,即时提交上去会被google卡住
  • 总结一下:是否申请豁免,取决于提交给google的测试报告,如果leading项目需要提交全部模块的报告,如果有失败项就需要提交豁免;如果作为vba项目GTS需要全部跑,CTS不需要全部跑可以直接复用,因此vba项目里面有失败项就需要提交豁免;如果本身是vba项目,但是提交的方式是全部模块测试,那么有对应的失败项也必须的提交豁免。

BUT,规矩是死的,人是活的,针对如上这个案例的情况,其实我们完全可以不用去每一个sku都提一个豁免申请,参考google回复,如下图,言外之意就说如果堆栈报错信息完全一致,可以只创建一个实例即可

问题总结:针对哪些情况下需要申请google豁免,google明面规定只要送测的报告有失败项,fp属性不一致,就需要去申请豁免,但是规矩是死的,人是活的,在这种情况下,我们也可以去钻空子,但是风险相对大一点而已

5、进程CRASH相关案例

XTS中有很多测试项是用来对系统进程稳定性的检查,测试用例命名有Rollback InstallHost等关键字的测试项,如下就针对这类XTS项进行一个介绍:

CtsRollbackManagerHostTestCases

报错日志:

bash 复制代码
com.android.cts.rollback.host.RollbackManagerHostTest#testApexAndApkStagedRollback

java.lang.AssertionError: on-device tests failed: com.android.cts.rollback.host.app.HostTestHelper#testApexAndApkStagedRollback_Phase2_InstallSecond: expected: 2 but was : 1 at com.android.cts.rollback.host.app.HostTestHelper.testApexAndApkStagedRollback_Phase2_InstallSecond(HostTestHelper.java:456) at com.android.tradefed.testtype.junit4.BaseHostJUnit4Test.runDeviceTests(BaseHostJUnit4Test.java:749) at com.android.tradefed.testtype.junit4.BaseHostJUnit4Test.runDeviceTests(BaseHostJUnit4Test.java:648) at com.android.tradefed.testtype.junit4.BaseHostJUnit4Test.runDeviceTests(BaseHostJUnit4Test.java:591) at com.android.tradefed.testtype.junit4.BaseHostJUnit4Test.runDeviceTests(BaseHostJUnit4Test.java:537) at com.android.tradefed.testtype.junit4.BaseHostJUnit4Test.runDeviceTests(BaseHostJUnit4Test.java:357) at com.android.tradefed.testtype.junit4.BaseHostJUnit4Test.runDeviceTests(BaseHostJUnit4Test.java:313) at com.android.cts.rollback.host.RollbackManagerHostTest.run(RollbackManagerHostTest.java:54) at com.android.cts.rollback.host.RollbackManagerHostTest.testApexAndApkStagedRollback(RollbackManagerHostTest.java:171) at

分析过程:

搜索测试用例testApexAndApkStagedRollback,从命名可以大概知道此用例有四个步骤,第一步安装应用,第二步安装应用,第三部进行回滚,当前报错为第二步testApexAndApkStagedRollback_Phase2_InstallSecond

搜索执行方法testApexAndApkStagedRollback_Phase2_InstallSecond,结合"expected: 2 but was : 1 at",此时获取com.android.apex.cts.shim结果为1,期望为2

结合如上测试逻辑,分析log日志如下:

由此发现gnss_service的crash导致这里的session失败,引起com.android.apex.cts.shim版本还是1,至于这块逻辑还没有具体研究,结合之前的案例,gnss_service的crash导致,使用关闭gnss_service的版本此条能够pass。

问题总结:CtsRollbackManagerHostTestCases是针对系统进程安装回滚相关的测试用例,通常是某些应用或进程crash导致他们无法通过pass

CtsInstallHostTestCases

报错日志:

bash 复制代码
arm64-v8a CtsInstallHostTestCases Test Result Details
android.cts.install.host.InstallTest#testStagedInstall[SINGLE_APEX_Rollbacktrue]
fail
java.lang.AssertionError: on-device tests failed:
android.cts.install.host.InstallTest#testStagedInstall[SINGLE_APEX_Rollbackfalse]
fail
java.lang.AssertionError: on-device tests failed:
android.cts.install.host.InstallTest#testAbandonStagedSessionAfterReboot[SINGLE_APEX_Rollbackfalse]
fail
java.lang.AssertionError: on-device tests failed:
android.cts.install.host.InstallTest#testStagedInstall[MULTIPLE_MIX_Rollbacktrue]
fail
java.lang.AssertionError: on-device tests failed:
android.cts.install.host.InstallTest#testAbandonStagedSessionAfterReboot[MULTIPLE_MIX_Rollbacktrue]
fail
java.lang.AssertionError: on-device tests failed:
android.cts.install.host.InstallTest#testStagedInstall[MULTIPLE_MIX_Rollbackfalse]
fail
java.lang.AssertionError: on-device tests failed:
android.cts.install.host.InstallTest#testAbandonStagedSessionAfterReboot[MULTIPLE_MIX_Rollbackfalse]
fail
java.lang.AssertionError: on-device tests failed:
android.cts.install.host.SamegradeTest#testStagedSameGrade[SINGLE_APEX_Rollbacktrue]
fail
java.lang.AssertionError: on-device tests failed:
android.cts.install.host.SamegradeTest#testStagedSamegradeSystemApex[SINGLE_APEX_Rollbacktrue]
fail
java.lang.AssertionError: on-device tests failed:
android.cts.install.host.SamegradeTest#testStagedSameGrade[SINGLE_APEX_Rollbackfalse]
fail
java.lang.AssertionError: on-device tests failed:
android.cts.install.host.SamegradeTest#testStagedSamegradeSystemApex[SINGLE_APEX_Rollbackfalse]
fail

如上报错日志类似在关键日志如下,大致同CtsRollbackManagerHostTestCases 类似

packageInstallerSessionInfo.Not true that session {appPackageName = com.android.apex.cts.shim;sessionId = 1792447974; isStagedSessionReady = false; isStagedSessionApplied = false; isStagedSessionFailed = true; stagedSessionErrorMessage = APEX activation failed. Reason: Session reverte*d due to crashing native process: qccsyshal@1.2-service} is *in state APPLIED

问题总结:CtsInstallHostTestCases 是针对系统进程安装回滚相关的测试用例,通常是某些应用或进程crash导致他们无法通过pass

CtsStagedInstallHostTestCases

**报错日志:**arm64-v8a CtsStagedInstallHostTestCases Test Result Details

testGetInactiveApexFactoryPackagesAfterApexInstall_containsNoDuplicates

testInstallStagedApexWithoutApexSuffix

testApexInfoListAfterUpdate

testInstallStagedApex_SameGrade_NewOneWins

testStagedInstallDowngradeApex_DowngradeNotRequested_Fails

testApexSetsUpdatedSystemAppFlag

testAfterRotationNewKeyCanUpdateFurther

testSamegradeSystemApex

testInstallStagedApex

testTrustedOldKeyIsAccepted

testInstallStagedApex_SameGrade

等测试failed同CtsInstallHostTestCases 一致,基本上都有如下关键日志:

packageInstallerSessionInfo.Not true that session {appPackageName = com.android.apex.cts.shim; sessionId = 2053928693; isStagedSessionReady = false; isStagedSessionApplied = false; isStagedSessionFailed = true; stagedSessionErrorMessage = APEX activation failed. Reason: Session reverted due to crashing native process: qccsyshal@1.2-service} is in state APPLIED expected to be true

表示在测试用例在尝试安装 com.android.apex.cts.shim,触发了qccsyshal服务的崩溃,导致安装失败

问题总结:CtsStagedInstallHostTestCases同CtsInstallHostTestCases基本一致,区别就是测试启动阶段是否存在一些进程crash问题

GtsBootHealthHostTestCases

报错日志:

arm64-v8a GtsBootHealthHostTestCases Test Result Details android.boothealth.gts.BootHealthHostTest#testUpdatableProcessCrashNotDetected fail Upadatable process crash detected: qccsyshal@1.2-service

02-04 20:59:50 I/ConsoleReporter: [1/1 arm64-v8a GtsBootHealthHostTestCases LBA9003506710379] android.boothealth.gts.BootHealthHostTest#testUpdatableProcessCrashNotDetected fail: Upadatable process crash detected: qccsyshal@1.2-service02-04 20:59:50 I/ConsoleReporter: [1/1 arm64-v8a GtsBootHealthHostTestCases LBA9003506710379] android.boothealth.gts.BootHealthHostTest#testUpdatableProcessCrashNotDetected fail: Upadatable process crash detected: qccsyshal@1.2-service expected to be false at android.boothealth.gts.BootHealthHostTest.testUpdatableProcessCrashNotDetected(BootHealthHostTest.java:75)

02-04 20:59:50 D/PrettyTestEventLogger: ==================== android.boothealth.gts.BootHealthHostTest#testUpdatableProcessCrashNotDetected ENDED: Wed Feb 04 20:59:50 CST 2026 ====================02-04 20:59:50 I/ModuleListener: [1/1] LBA9003506710379 com.android.compatibility.common.tradefed.testtype.JarHostTest android.boothealth.gts.BootHealthHostTest#testUpdatableProcessCrashNotDetected FAILURE: Upadatable process crash detected: qccsyshal@1.2-service expected to be false at android.boothealth.gts.BootHealthHostTest.testUpdatableProcessCrashNotDetected(BootHealthHostTest.java:75)

分析日志:如上报错日志很明显打印了qccsyshal服务进程持续的异常,持续抓取logcat日志可以发现此进程持续crash,该进程同样为高通自定义进程

本来想提高通case咨询到底能否干掉,最后因为余额不够,我们私自决定干掉此进程,问题得到解决

问题总结:GtsBootHealthHostTestCases从命名来看BootHealthHost用来检查启动过程中系统是否健康,即是否有大量进程在后台持续crash的目的

CtsStatsdAtomHostTestCases

报错日志:

arm64-v8a CtsStatsdAtomHostTestCases[instant]

Test Result Details

android.cts.statsdatom.statsd.UidAtomTests#testSyncState

fail
Failed to install CtsStatsdAtomApp.apk: Unknown failure: cmd: Failure calling service package: Broken pipe (32)

</Module>

<Module name="CtsStatsdAtomHostTestCases[instant]" abi="arm64-v8a" runtime="9787" done="true" pass="0" total_tests="1">

<TestCase name="android.cts.statsdatom.statsd.UidAtomTests">

<Test result="fail" name="testSyncState">

<Failure message="Failed to install CtsStatsdAtomApp.apk: Unknown failure: cmd: Failure calling service package: Broken pipe (32)">

<StackTrace>Failed to install CtsStatsdAtomApp.apk: Unknown failure: cmd: Failure calling service package: Broken pipe (32)
value of: installPackage(...)
expected: null
but was : Unknown failure: cmd: Failure calling service package: Broken pipe (32)
at android.cts.statsdatom.lib.DeviceUtils.installTestApp(DeviceUtils.java:185)

at android.cts.statsdatom.lib.DeviceUtils.installStatsdTestApp(DeviceUtils.java:173)

at android.cts.statsdatom.statsd.UidAtomTests.setUp(UidAtomTests.java:92)

at junit.framework.TestCase.runBare(TestCase.java:140)

at com.android.tradefed.testtype.DeviceTestResult$1.protect(DeviceTestResult.java:99)

at com.android.tradefed.testtype.DeviceTestResult.runProtected(DeviceTestResult.java:73)

at com.android.tradefed.testtype.DeviceTestResult.run(DeviceTestResult.java:104)

at junit.framework.TestCase.run(TestCase.java:130)

at com.android.tradefed.testtype.DeviceTestCase.run(DeviceTestCase.java:170)

at com.android.tradefed.testtype.JUnitRunUtil.runTest(JUnitRunUtil.java:65)

安装应用的时候失败Failed to install CtsStatsdAtomApp.apk

日志分析 :如上最后一句表示CtsStatsdAtomApp应用安装失败,失败原因出现了Broken pipe, 这表明在执行包安装命令时,服务连接出现了中断

问题总结:CtsStatsdAtomHostTestCases Broken pipe 这些关键字,那么为什么会出现这种情况,常见的场景为native进程CRASH持续出现。

CtsAdServicesTopicsAppUpdateTests

报错日志: arm64-v8a CtsAdServicesTopicsAppUpdateTests

Test Result Details

com.android.adservices.tests.cts.topics.appupdate.AppUpdateTest#testAppUpdate

fail

expected: com.android.adservices.tests.cts.topics.NON_EMPTY_TOPIC_RESPONSE

日志分析:

bash 复制代码
<Reason message="There were 2 failures: com.android.tradefed.targetprep.TargetSetupError[APK_INSTALLATION_FAILED|520001|DEPENDENCY_ISSUE]: Failed to install com.android.adservices.tests.cts.topics.appupdate with [/tmp/xts-root-dir-8f22ae00-b90e-48ad-a250-78bba18a625c/android-cts/testcases/CtsAdServicesTopicsAppUpdateTests/arm64/CtsAdServicesTopicsAppUpdateTests.apk] on fa2cbe7. Reason: 'Unknown failure: cmd: Failure calling service package: Broken pipe (32)' [fa2cbe7 lahaina:sh4-2 BQ2A.251125.001-BP2A.250605.031.A3] at com.android.tradefed.targetprep.TestAppInstallSetup.installSinglePackage(TestAppInstallSetup.java:608) at com.android.tradefed.targetprep.TestAppInstallSetup.installer(TestAppInstallSetup.java:568) at com.android.tradefed.targetprep.TestAppInstallSetup.setUp(TestAppInstallSetup.java:449) at com.android.tradefed.testtype.suite.ModuleDefinition.runPreparerSetup(ModuleDefinition.java:1111) at com.android.tradefed.testtype.suite.ModuleDefinition.runTargetPreparation(ModuleDefinition.java:1597) at com.android.tradefed.testtype.suite.ModuleDefinition.runPreparation(ModuleDefinition.java:1070) at com.android.tradefed.testtype.suite.ModuleDefinition.run(ModuleDefinition.java:542) at com.android.tradefed.testtype.suite.ITestSuite.runSingleModule(ITestSuite.java:1495) at com.android.tradefed.testtype.suite.ITestSuite.run(ITestSuite.java:1117) at com.android.tradefed.invoker.shard.TestsPoolPoller.run(TestsPoolPoller.java:166) at com.android.tradefed.invoker.InvocationExecution.runTest(InvocationExecution.java:1538) at com.android.tradefed.invoker.InvocationExecution.runTests(InvocationExecution.java:1313) at com.android.tradefed.invoker.TestInvocation.prepareAndRun(TestInvocation.java:685) at com.android.tradefed.invoker.TestInvocation.performInvocation(TestInvocation.java:304) at com.android.tradefed.invoker.TestInvocation.invoke(TestInvocation.java:1522) at com.android.tradefed.command.CommandScheduler$InvocationThread.run(CommandScheduler.java:723) Instrumentation run failed due to 'Process crashed.' Java Crash Messages sorted from most recent: com.android.adservices.tests.cts.topics.NON_EMPTY_TOPIC_RESPONSE but was : com.android.adservices.tests.cts.topics.EMPTY_TOPIC_RESPONSE expected: com.android.adservices.tests.cts.topics.NON_EMPTY_TOPIC_RESPONSE but was : com.android.adservices.tests.cts.topics.EMPTY_TOPIC_RESPONSE at com.android.adservices.tests.cts.topics.appupdate.AppUpdateTest$1.onReceive(AppUpdateTest.java:259) at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0(LoadedApk.java:1839) at android.app.LoadedApk$ReceiverDispatcher$Args.$r8$lambda$mcNAAl1SQ4MyJPyDg8TJ2x2h0Rk(Unknown Source:0) at android.app.LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) at android.os.Handler.handleCallback(Handler.java:995) at android.os.Handler.dispatchMessage(Handler.java:103) at android.os.Looper.loopOnce(Looper.java:248) at android.os.Looper.loop(Looper.java:338) at android.app.ActivityThread.main(ActivityThread.java:9137) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:940) Native Crash Messages sorted from most recent: fingerprint: Ascom/SH4-AADE/SH4-2:16/BQ2A.251125.001-BP2A.250605.031.A3/A16_001.00:user/release-keys app: /vendor/bin/hw/vendor.ascom.hardware.dect&#64;1.0-service Build fingerprint: 'Ascom/SH4-AADE/SH4-2:16/BQ2A.251125.001-BP2A.250605.031.A3/A16_001.00:user/release-keys' Revision: '0' ABI: 'arm64' Timestamp: 2026-02-10 09:28:32.966162617-0800 Process uptime: 8s Cmdline: /vendor/bin/hw/vendor.ascom.hardware.dect@1.0-service pid: 14230, tid: 14235, name: dect@1.0-servic >>> /vendor/bin/hw/vendor.ascom.hardware.dect@1.0-service <<< uid: 1000 tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE) signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr -------- Abort message: 'Parameter validation for ro.boot.dect.ee_vdd_register failed' x0 0000000000000000 x1 000000000000379b x2 0000000000000006 x3 0000007b60ff8520 x4 6c6071606f2d7362 x5 6c6071606f2d7362 x6 6c6071606f2d7362 x7 7f7f7f7f7f7f7f7f x8 00000000000000f0 x9 6a06783e0f43a89c x10 000000ff00000020 x11 0000007b60ff84c0 x12 ffffffffffffffff x13 b400007cc4605ff0 x14 0000000b00971b09 x15 0000000034155555 x16 0000007df4d210f8 x17 0000007df4d07dc0 x18 0000007b5e854000 x19 0000000000003796 x20 000000000000379b x21 00000000ffffffff x22 b400007cc4605ff0 x23 0000000000000040 x24 0000007b60ff8f80 x25 0000000000000001 x26 b400007d1460b590 x27 00000062766d8630 x28 0000007b60ff8738 x29 0000007b60ff85a0 lr 0000007df4ca3268 sp 0000007b60ff8520 pc 0000007df4ca328c pst 0000000000001000 10 total frames backtrace: #00 pc 000000000007128c /apex/com.android.runtime/lib64/bionic/libc.so (abort+160) (BuildId: 85a1677149dd58c9bc79f641cb77adea) #01 pc 0000000000009744 /system/lib64/liblog.so (_android_log_default_aborter+16) (BuildId: 742a62f59164792c8ccb54af8b1498b9) #02 pc 00000000000157b8 /vendor/lib64/libbase.so (android::base::LogMessage::~LogMessage()+544) (BuildId: 3401c510f3b6c370f62f471ac6338549) #03 pc 0000000000033888 /vendor/bin/hw/vendor.ascom.hardware.dect@1.0-service

即dect进程在持续crash,导致应用安装过程中可能出现异常,为什么会导致这种呢?AI解释如下:

问题总结:CtsAdServicesTopicsAppUpdateTests同CtsStatsdAtomHostTestCases一致 Broken pipe 这些关键字,通常原因也是有native进程持续CRASH

6、网络导致的案例

香港卡相关测试项

案例背景:在ASCOM A16第二轮测试过程中,出现NET相关模块无法正常跑起来

问题分析:根据测试反馈之前在老工具使用白卡也都能跑起来,但目前的现象是,直接没有结果,后tel owner经过确认,使用香港卡,这些测试项可以跑起来

解决方案:最终建议测试使用香港卡,如下此项全部能够PASS

CtsHostsideNetworkTests

日志分析:com.android.cts.net.HostsideRestrictBackgroundNetworkTests#testMeteredNetworkAccess_expeditedJob

如上报错为网络操作导致,从如下测试用例源码也可以看出来,这里判断网络超时等待超过6秒,就会报出此错误,和通信沟通需要插卡联网进行测试

问题总结:CtsHostsideNetworkTests很多用例主要关于网络测试,因此需要联网插卡进行retry和单跑

CtsNetTestCases

日志分析:android.net.cts.NetworkAgentTest#testAllowedUids_WithCarrierServicePackage java.lang.AssertionError: Can't modify carrier service package

查看android 14 源码,并没有testAllowedUids_WithCarrierServicePackage测试方法,查看android 15源码,查看对应用例方法如下:

与其他android 14 pass的项目log对比,测试结果为ASSUMPTION_FAILURE,也算通过

测试通过原因查看测试用例,对 FEATURE_TELEPHONY_SUBSCRIPTION feature做了检查,测试结果为ASSUMPTION_FAILURE ,表示并没有配置这个feature

按照上述分析,去掉此项目的feature,测试结果也为ASSUMPTION_FAILURE,但是客户不接受这种修改方法

解决方案:最后客户不接受此种方案,继续正面分析跟踪此问题,前面已经确认set-carrier-server-package-override命令执行失败,因此本地在A14和A15分别执行了此条命令,发现在A15上面能够直接执行成功,在A14上面需要先adb root之后才能执行成功,因此考虑是否在A14执行此条命令存在什么异常?最后加日志发现在setCarrierServicePackageOverride方法中有一个权限检查,因为这个权限检查导致后面的流程无法执行下去,对比A15的代码发现没有这一行代码,因此在A14注释了此行代码,进行验证OK:

问题总结:针对共性问题,可以先寻找一些相关联的规律,例如此题发现A14和A15表现不一样,那么正向去分析,找到A14和A15存在一些代码差异,针对差异解决问题

CtsNetTestCases

问题背景:商米项目的一轮测试报告整理如下,和网络/VPN/卡的关系

问题总结:CtsNetTestCases模块是针对网络相关的测试项,因此遇到此类问题最好换网络环境retry

7、应用KEY导致的案例

本篇主要针对XTS对一系列KEY的相关测试项,目前收集到的主要有如下几类问题:

如上一些基本概念可以先阅读https://blog.csdn.net/qq_27672101/article/details/144224249进行了解,然后在看此篇关于XTS的一些测试项

CtsSecurityTestCases

报错日志:android.security.cts.PackageSignatureTest#te stPackageSignatures fail: junit.framework.AssertionFailedError: These packages should not be signed with a well known key: [com.android.ons, com.android.printspooler, com.mediatek.frameworkresoverlay, com.android.bedstead.testapp.DeviceAdminTestApp, com.google.android.overlay.gmsconfig.personalsafety, com.mediatek.SettingsProviderResOverlay, com.android.pacprocessor, com.mediatek.capctrl.service, com.android.role.notes.enabled, com.android.systemui.accessibility.accessibilitymenu, ..........................

GtsAppBlacklistDeviceTestCases

报错日志:com.google.android.appblacklist.gts.GtsAppBlacklistDeviceTest#testForBlacklistedApps FAILURE: junit.framework.AssertionFailedError: Packages with a blacklisted signature:

com.mediatek.ims

com.android.providers.telephony

com.android.dynsystem

com.mediatek.camera

com.mediatek.telephony

com.android.providers.media

com.android.networkstack.tethering.overlay

com.mediatek.location.lppe.main

com.android.wallpapercropper

com.mediatek.SettingsProviderResOverlay

原因分析:参考https://blog.csdn.net/dzhwang/article/details/84096776,即编译构建的时候对镜像进行签名,或者apk进行签名,使用了平台默认的key,这个key需要使用客户或者自己的,即我们要更换一下key

GtsMbaPrivilegedPermissionTestCases

报错日志:com.google.android.mbaprivilegedpermission.gts.GtsDebugCertificateTest#testMbaPrivilegedPermission

java.lang.RuntimeException: Violation of the Debug certificate policy

com.qualcomm.qti.qcolor\] is denylisted - debug certificate \[com.android.providers.telephony\] is denylisted - debug certificate \[com.android.dynsystem\] is denylisted - debug certificate \[com.qti.service.colorservice\] is denylisted - debug certificate \[com.qualcomm.qti.xrwifi\] is denylisted - debug certificate \[com.qualcomm.qti.server.qtiwifi\] is denylisted - debug certificate \[com.qualcomm.qti.simcontacts\] is denylisted - debug certificate \[com.android.wallpapercropper\] is denylisted - debug certificate \[com.android.externalstorage\] is denylisted - debug certificate \[com.qualcomm.uimremoteclient\] is denylisted - debug certificate \[com.qualcomm.qti.uceShimService\] is denylisted - debug certificate ........... **总结:testPackageSignatures和testForBlacklistedApps和testMbaPrivilegedPermission 这样的测试用例是针对APK应用签名的校验,即编译的时候需要对所有应用或者OTA包进行应用签名,使用默认android的签名就会被检查出来,解决方案就是更新自己的应用签名** #### BTS which has been signed by a certificate that is known to be compromised and should be replaced 报错日志:BTS扫描出现一堆应用签名异常 |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ``` Alert - Fix to unblock (26) Blocked app /system/app/Bluetooth/Bluetooth.apk This build contains pre-installed "com.android.bluetooth" at /system/app/Bluetooth/Bluetooth.apk which has been signed by a certificate that is known to be compromised and should be replaced. If you believe this finding is incorrect please reach out to your TAM and provide details that help us to validate inaccuracies and improve detection. Blocked app /system/priv-app/BlockedNumberProvider/BlockedNumberProvider.apk This build contains pre-installed "com.android.providers.blockednumber" at /system/priv-app/BlockedNumberProvider/BlockedNumberProvider.apk which has been signed by a certificate that is known to be compromised and should be replaced. If you believe this finding is incorrect please reach out to your TAM and provide details that help us to validate inaccuracies and improve detection. Blocked app /system/priv-app/DownloadProviderUi/DownloadProviderUi.apk This build contains pre-installed "com.android.providers.downloads.ui" at /system/priv-app/DownloadProviderUi/DownloadProviderUi.apk which has been signed by a certificate that is known to be compromised and should be replaced. If you believe this finding is incorrect please reach out to your TAM and provide details that help us to validate inaccuracies and improve detection. Blocked app /_by_plabel_/system_ext/app/DynamicDDSService/DynamicDDSService.apk This build contains pre-installed "com.qualcomm.qti.dynamicddsservice" at /_by_plabel_/system_ext/app/DynamicDDSService/DynamicDDSService.apk which has been signed by a certificate that is known to be compromised and should be replaced. ``` | **问题总结:同testPackageSignatures和testForBlacklistedApps一样,是针对系统应用签名的一个检测,即编译的时候需要对所有应用或者OTA包进行应用签名,使用默认android的签名就会被检查出来,解决方案就是更新自己的应用签名** ### 8、Google KEY导致的案例 Google KEY比较复杂,在A16之前的版本叫做keybox,在A16之后的版本叫做RKP。 * KEYBOX流程:参考[https://blog.csdn.net/qq_27672101/article/details/160654440](https://blog.csdn.net/qq_27672101/article/details/160654440 "https://blog.csdn.net/qq_27672101/article/details/160654440") * RKP流程:惨了[https://blog.csdn.net/qq_27672101/article/details/160654440](https://blog.csdn.net/qq_27672101/article/details/160654440 "https://blog.csdn.net/qq_27672101/article/details/160654440") 结合KEYBOX和RKP,其实都需要有如下流程: * **生成Google Attestation ID** * 生成CSR(RKP方式通过rkp命令生成/keybox方式直接切割keybox然后写入) * Google校验秘钥是否正确 ![](https://i-blog.csdnimg.cn/direct/36f2550a98174ccea8483caf22f18b73.png) 由此google key相关的案例非常的多,如上案例。 针对这类问题,在A16之前的版本写入keybox,在A16之后的版本通过rkp的方式生成,在测试之前需要登陆google账号,链接外网进行测试。 但是站在如上三部曲的角度,可以分为如下几类 #### 第一类:没有写keybox秘钥导致的案例 #### GtsGmscoreHostTestCases 报错日志:run gts -m GtsGmscoreHostTestCases com.google.android.gts.cast.VirtualDisplayHostTest#testTestActivityEmbeddingOnVirtualDisplay com.google.android.gts.security.AttestationRootHostTest#testRsaAttestationChainTee com.google.android.gts.security.AttestationRootHostTest#testEcAttestationChainTee ![](https://i-blog.csdnimg.cn/direct/f3a667905ef44123a51cf45b338c3c11.png) 解决方案:写google key重新跑此条PASS **总结:GtsGmscoreHostTestCases子项com.google.android.gts.security.AttestationRootHostTest关于google key的测试,通常保证google key一致,写入google key都可以pass** #### GtsEdiHostTestCases **针对大版本升级项目,需要进行白名单申请,测试GtsEdiHostTestCases fail** 报错日志:run gts -m GtsEdiHostTestCases 命令执行异常 Log 显示测试执行了以下命令来获取 CSR(证书签名请求): adb shell cmd remote_provisioning csr --challenge WErIaO5/5QWkuKfuGnNMMQ== default 该命令的作用是让设备生成一个包含硬件信任信息的 CSR。如果该命令输出为空(没有任何内容返回),Gts 的收集器就会生成一个空文件,从而触发报错。 01-12 23:56:02 D/RunUtil: Running command \[adb, -s, c3f06050, shell, cmd, remote_provisioning, list\] with timeout: 2m 0s 01-12 23:56:02 D/RunUtil: Running command \[adb, -s, c3f06050, shell, cmd, **remote_provisioning, csr** , --challenge, WErIaO5/5QWkuKfuGnNMMQ==, default\] with timeout: 2m 0s 01-12 23:56:03 E/DeviceInfo:**File is empty: HardwareTrustDeviceInfo.deviceinfo.json** **[java.io](http://java.io "java.io").EOFException: File is empty: HardwareTrustDeviceInfo.deviceinfo.json** at com.android.compatibility.common.util.DeviceInfo.testCollectDeviceInfo(DeviceInfo.java:63) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:61) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 01-12 23:56:03 I/ConsoleReporter: \[12/13 arm64-v8a GtsEdiHostTestCases c3f06050\] com.google.android.gts.edi.**HardwareTrustDeviceInfo** #testCollectDeviceInfo fail: java.lang.AssertionError: Failed to collect device info (HardwareTrustDeviceInfo.deviceinfo.json): File is empty: HardwareTrustDeviceInfo.deviceinfo.json at org.junit.Assert.fail(Assert.java:89) at com.android.compatibility.common.util.DeviceInfo.testCollectDeviceInfo(DeviceInfo.java:70) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:61) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 测试用例: ![](https://i-blog.csdnimg.cn/direct/ed686ec127e344eaa6784a5e0ae66136.png) 解决方案:写入Google Attestation ID ,验证PASS **总结:根据测试用例来看,主要测试RKP和CSR相关认证,项目RKP存在问题,获取CSR异常。** 在A16之后强制执行RKP+CSR进行安全认证策略,即之前本地写google keybox的方式行不通了 需要生成google attestation id, 由于项目CSR生成失败,所以还是建议后续CSR生成上传后一并测试该条case。 注意事项:项目不用写本地google key,attestation id需要在userdebug上生成,生成attestation id 方法: |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ``` adb shell qseecom_sample_client -v samplap64 15 1     #擦除rpmb分区 rm -rf /mnt/vendor/persist/data/Dd*        #删除key目录 adb reboot                        #然后启动失败后选factory reset启动 adb root adb shell qseecom_sample_client v smplap64 14 1 LD_LIBRARY_PATH=/vendor/lib64/hw KmInstallKeybox 1 1 true rkp ``` | ![](https://i-blog.csdnimg.cn/direct/4d4fdef531d84096bfddf6a02e7d6498.png)本地测试,不需要生成CSR和上传CSR,仅需生成attestation_id即可pass。 #### CtsKeystoreTestCases 报错日志:run cts -m CtsKeystoreTestCases android.keystore.cts.KeyAttestationTest#testRsaAttestation android.keystore.cts.KeyAttestationTest#testEcAttestation android.keystore.cts.KeyAttestationTest#testEcAttestation_UniqueIdWorksWithCorrectPermission android.keystore.cts.KeyAttestationTest#testEcAttestation_DeviceLocked android.keystore.cts.KeyAttestationTest#testRsaAttestation_DeviceLocked 解决方案:写google key重新跑此条PASS **总结:CtsKeystoreTestCases子项android.keystore.cts.KeyAttestationTest关于google key的测试,通常保证google key一致,写入google key都可以pass** #### odsign_e2e_tests 报错日志:com.android.tests.odsign.OnDeviceSigningHostTest#verifyArtUpgradeGeneratesAnyArtifacts ![](https://i-blog.csdnimg.cn/direct/5ed333ef0b0b412fbc44ed3f25cefe58.png) com.android.tests.odsign.OnDeviceSigningHostTest#verifyArtUpgradeSignsFiles java.lang.AssertionError: on-device tests failed: com.android.tests.odsign.ArtifactsSignedTest#testArtArtifactsHaveFsverity: java.nio.file.NoSuchFileException: /data/misc/apexdata/com.android.art/dalvik-cache at sun.nio.fs.UnixFileAttributeViews$Basic.readAttributes(UnixFileAttributeViews.java:55) at sun.nio.fs.UnixFileSystemProvider.readAttributes(UnixFileSystemProvider.java:150) at sun.nio.fs.LinuxFileSystemProvider.readAttributes(LinuxFileSystemProvider.java:115) at java.nio.file.Files.readAttributes(Files.java:1737) at 问题分析:如下从代码来看,可能跟秘钥验证相关,没有找到对应的缓存文件 ![](https://i-blog.csdnimg.cn/direct/0d19af890526409d8f05af149a19cb4c.png) 最后在MTK中搜索出如下case,了解到此条需要写google key ###### ![](https://i-blog.csdnimg.cn/direct/ed4ca27335254c6394923ca21be42922.png) **问题总结:odsign_e2e_tests也是关于google key的测试,通常保证google key一致,写入google key都可以pass** #### CtsIdentityTestCases 报错日志:android.security.identity.cts.DynamicAuthTest#dynamicAuthTest java.lang.RuntimeException: Unexpected ServiceSpecificException with code 1 04-03 13:50:53.478 10218 12577 12589 E TestRunner: failed: dynamicAuthTest(android.security.identity.cts.DynamicAuthTest) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: ----- begin exception ----- 04-03 13:50:53.478 10218 12577 12589 E TestRunner: java.lang.RuntimeException: Unexpected ServiceSpecificException with code 1 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at android.security.identity.**CredstoreIdentityCredentialStore.createCredential(CredstoreIdentityCredentialStore.java:135)** 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at android.security.identity.cts.ProvisioningTest.createCredentialWithChallengeAndAcpId(ProvisioningTest.java:142) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at android.security.identity.cts.ProvisioningTest.createCredential(ProvisioningTest.java:121) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at android.security.identity.cts.DynamicAuthTest.dynamicAuthTest(DynamicAuthTest.java:76) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at java.lang.reflect.Method.invoke(Native Method) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:61) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:148) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:142) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at java.util.concurrent.FutureTask.run(FutureTask.java:264) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at java.lang.Thread.run(Thread.java:1012) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: **Caused by: android.os.ServiceSpecificException: HAL failed with exception code -8 (EX_SERVICE_SPECIFIC), service-specific error code 1, message 'Error initializing WritableIdentityCredential' (code 1)** 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at android.os.Parcel.createExceptionOrNull(Parcel.java:3093) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at android.os.Parcel.createException(Parcel.java:3063) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at android.os.Parcel.readException(Parcel.java:3046) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at android.os.Parcel.readException(Parcel.java:2988) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at android.security.identity.ICredentialStore$Stub$Proxy.createCredential(ICredentialStore.java:197) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: at android.security.identity.CredstoreIdentityCredentialStore.createCredential(CredstoreIdentityCredentialStore.java:125) 04-03 13:50:53.478 10218 12577 12589 E TestRunner: ... 12 more 此案例比较奇怪,我司内部版本在没有写google key的时候,单跑第一条报如上错误,从报错日志来看android.hardware.identity硬件抽象层服务存在问题,在写入了google key之后,此条能够PASS;但是在客户版本写了google key之后,还是出现一模一样的错误,就跟google key没有写一样。 初步分析同样环境排除google环境问题,剩下只有两种可能情况:google key秘钥不匹配;代码引入需要夹版本。最后确定为代码引入,客户注释了android.hardware.identity上层服务,但是没有注释hal层的声明。跟踪identity模块源码如下: ![](https://i-blog.csdnimg.cn/direct/6e381a0c923d479f87611805c8c5273c.png) ![](https://i-blog.csdnimg.cn/direct/26fe9f55072a4a858305d4bb907c5eac.png) ![](https://i-blog.csdnimg.cn/direct/44dff7bab4bb40598e2ee6a675c8c0cd.png) 最后确定我司版本在熔丝的机器上面也会出现这样的错误,按照商米的说法是他们的项目都出现了这个问题,最后的解决方案是干掉这个服务 **问题总结:CtsIdentityTestCases针对Identity服务相关的测试,此服务看起来是google实现的关于身份认证等相关信息的服务,Identity服务的工作依赖于keystore-tee安全机制,因此依赖google key。但是怎么和熔断扯上关系,是完全不太清楚** #### CtsAppSecurityHostTestCases 报错日志:android.appsecurity.cts.AdoptableHostTest#testEjected ![](https://i-blog.csdnimg.cn/direct/fbdaf3185a2a435881967caab7788dc6.png) 从如上日志可以看出来跟磁盘存储相关 原因分析:和MTK沟通内容如下。恢复出厂后不连接wifi,请插入一张SD卡 ,然后再去测试。步骤一:该case主要测试SD卡格式化等操作,测试可以里面使用了虚拟SD卡进行操作,如果贵司有品质很好的实体SD卡,那就插入实体SD卡进行case,如果没有品质很好的SD卡,建议不要插入SD卡,case会自动使用虚拟SD卡。步骤二:贵司在测试case之前可以先将设备刷机或者恢复出厂设置,完整开机向导之后断开wifi连接,也不要插入sim卡,让设备处于无网络数据的状态,然后静置设备十分钟再去测试,且测试时一定保证一台电脑只连接一台测试设备。步骤三:如果通过以上步骤2 case依然failed,请再重复步骤2,再去进行测试,直到有能pass的报告生成。后retry通过 **问题总结:android.appsecurity.cts.AdoptableHostTest#testEjected属于对SD卡的测试项,要么插入品质很好的SD卡,要么不插入会自动使用虚拟SD卡** #### 第二类:验证keymaster hal层模块是否正常 VTS测试有针对hal层模块的相关测试,google这套安全架构里面处于这层的就是keymaster hal,这块代码通常平台闭源,我们能做的事情不多,遇到此类问题通常需要提高通case。 PS:在A16之后,keymaster变成了AIDL,并且还多了一个VtsHalRemotelyProvisionedComponentTargetTest来对远程秘钥生成RKP的一个校验 #### VtsHalKeymasterV4_0TargetTest 报错日志:PerInstance/AttestationTest#RsaAttestation/0_default 和 PerInstance/AttestationTest#EcAttestation/0_default 和 ![](https://i-blog.csdnimg.cn/direct/4d102ecfd266444eab9d85108f48b8e7.png) 问题分析:boot_a分区没有匹配google key,报的是keymaster的异常,不清楚和google key有什么关系 ![](https://i-blog.csdnimg.cn/direct/7156b16239d847edba709c39d95fb7a1.png) 解决方案:写google key重新跑此条PASS **总结:VtsHalKeymasterV4_0TargetTest子项PerInstance/AttestationTest关于google key的测试,通常保证google key一致,写入google key都可以pass** #### VtsAidlKeyMintTargetTest 报错日志:arm64-v8a VtsAidlKeyMintTargetTest Test Result Details PerInstance/AttestKeyTest#EcdsaAttestationID/0_android_hardware_security_keymint_IKeyMintDevice_default fail Device IMEI: Permission denied. PerInstance/NewKeyGenerationTest#EcdsaAttestationIdTags/0_android_hardware_security_keymint_IKeyMintDevice_default fail Device IMEI: Permission denied. PerInstance/NewKeyGenerationTest#EcdsaAttestationIdAllTags/0_android_hardware_security_keymint_IKeyMintDevice_default fail Device IMEI: Permission denied. 问题分析:此条测试项无论是keybox的方式,还是rkp的方式,最后都pass了 **总结:同VtsHalKeymasterV4_0TargetTest是针对比较老的keymaster hidl服务进程的测试,VtsAidlKeyMintTargetTest是针对比较新的keymaster aidl服务进程的一个测试,如果此项无法通过,那么需要找平台进行跟进。** #### VtsHalRemotelyProvisionedComponentTargetTest 报错日志:arm64-v8a VtsHalRemotelyProvisionedComponentTargetTest Test Result Details PerInstance/CertificateRequestV2Test#EmptyRequest/0_android_hardware_security_keymint_IRemotelyProvisionedComponent_default fail hardware/interfaces/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp:941: Failure PerInstance/CertificateRequestV2Test#NonEmptyRequest/0_android_hardware_security_keymint_IRemotelyProvisionedComponent_default fail hardware/interfaces/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp:963: Failure PerInstance/CertificateRequestV2Test#NonEmptyRequestReproducible/0_android_hardware_security_keymint_IRemotelyProvisionedComponent_default fail hardware/interfaces/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp:994: Failure PerInstance/CertificateRequestV2Test#NonEmptyRequestMultipleKeys/0_android_hardware_security_keymint_IRemotelyProvisionedComponent_default fail hardware/interfaces/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp:1020: Failure 问题分析:此条报错在生成了Attestation ID之后就能够全部pass **总结:同前面两条不一样的,VtsHalRemotelyProvisionedComponentTargetTest是针对远程RKP的服务进程进行测试,如果此项无法通过,那么还是得需要找平台进行跟进。** #### 第三类:RKP方式没有生成**Attestation ID**的案例 #### GtsEdiHostTestCases 报错日志:arm64-v8a GtsEdiHostTestCases Test Result Details com.google.android.gts.edi.HardwareTrustDeviceInfo#testCollectDeviceInfo fail java.lang.AssertionError: Failed to collect device info (HardwareTrustDeviceInfo.deviceinfo.json): **File is empty: HardwareTrustDeviceInfo.deviceinfo.json** 用例分析:使用keybox的方式进行测试,就会报如上异常日志;但是使用RKP的方式去生成Attstation ID之后,并生成CSR秘钥,但是这个CSR秘钥并没有上传到google服务器,报告如下跳过了此条测试项 ##### ![](https://i-blog.csdnimg.cn/direct/93adacb1cd9847d9aaf428b33fdbea99.png) **总结:com.google.android.gts.edi.HardwareTrustDeviceInfo#testCollectDeviceInfo在生成Attstation ID之后能够pass,但是这条会跳过。** #### CtsKeystoreTestCases 报错日志:此条测试项报错如下几类 * **android.keystore.cts.DeviceOwnerKeyManagementTest#testAllVariationsOfDeviceIdAttestation** |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Unexpected failure while generating key RSA with ID flags 1: java.lang.UnsupportedOperationException: **Device does not support Device ID attestation.** In case of AOSP/GSI builds, system provided properties could be different from provisioned properties in KeyMaster/KeyMint. In such cases, make sure attestation specific properties (Build.\*_FOR_ATTESTATION) are configured correctly. expected to be true at android.keystore.cts.DeviceOwnerKeyManagementTest.generateKeyAndCheckAttestation(DeviceOwnerKeyManagementTest.java:432) at android.keystore.cts.DeviceOwnerKeyManagementTest.assertAllVariantsOfDeviceIdAttestation(DeviceOwnerKeyManagementTest.java:484) at android.keystore.cts.DeviceOwnerKeyManagementTest.testAllVariationsOfDeviceIdAttestation(DeviceOwnerKeyManagementTest.java:556) | KeyMint 在带 设备 ID/设备标识 的 attestation 请求上返回 CANNOT_ATTEST_IDS,框架侧映射为「不支持 Device ID attestation」。常见方向:未实现/未开启设备 ID 证明、Keybox/工厂数据与系统 Build(含 FOR_ATTESTATION)不一致。 * **testRsaAttestation/testEcAttestation/testCurve25519Attestation** java.lang.Exception: Failed on key size 512 challenge \[\], purposes \[2, 3\] paddings \[PKCS1\] a**nd devicePropertiesAttestation true at android.keystore.cts.KeyAttestationTest.testRsaAttestatio**ns(KeyAttestationTest.java:1036) at android.keystore.cts.KeyAttestationTest.testRsaAttestation(KeyAttestationTest.java:804) at android.keystore.cts.KeyAttestationTest.testRsaAttestation(KeyAttestationTest.java:706) ... 8 trimmed Caused by: java.security.ProviderException: Failed to generate key pair. at android.security.keystore2.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:712) at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:750) at android.keystore.cts.KeyAttestationTest.generateKeyPair(KeyAttestationTest.java:2194) at android.keystore.cts.KeyAttestationTest.testRsaAttestation(KeyAttestationTest.java:1215) at android.keystore.cts.KeyAttestationTest.testRsaAttestations(KeyAttestationTest.java:1025) ... 11 more Caused by: android.security.KeyStoreException: Unable to attest device ids (internal Keystore code: -66 message: system/security/keystore2/src/security_level.rs:680 Caused by: 0: system/security/keystore2/src/security_level.rs:674: While generating without a provided attestation key and params: \[KeyParameter { tag: r#KEY_SIZE, value: Integer(512) }, KeyParameter { tag: r#ALGORITHM, value: Algorithm(r#RSA) }, KeyParameter { tag: r#PURPOSE, value: KeyPurpose(r#SIGN) }, KeyParameter { tag: r#PURPOSE, value: KeyPurpose(r#VERIFY) }, KeyParameter { tag: r#PADDING, value: PaddingMode(r#RSA_PKCS1_1_5_SIGN) }, KeyParameter { tag: r#DIGEST, value: Digest(r#NONE) }, KeyParameter { tag: r#DIGEST, value: Digest(r#SHA_2_256) }, KeyParameter { tag: r#DIGEST, value: Digest(r#SHA_2_512) }, KeyParameter { tag: r#NO_AUTH_REQUIRED, value: BoolValue(true) }, KeyParameter { tag: r#ACTIVE_DATETIME, value: DateTime(1775199733799) }, KeyParameter { tag: r#ORIGINATION_EXPIRE_DATETIME, value: DateTime(1775200733799) }, KeyParameter { tag: r#USAGE_EXPIRE_DATETIME, value: DateTime(1775201733799) }, KeyParameter { tag: r#CERTIFICATE_NOT_AFTER, value: DateTime(2461449600000) }, KeyParameter { tag: r#CERTIFICATE_NOT_BEFORE, value: DateTime(0) }, KeyParameter { tag: r#CERTIFICATE_SERIAL, value: Blob(\[1\]) }, KeyParameter { tag: r#CERTIFICATE_SUBJECT, value: Blob(\[48, 31, 49, 29, 48, 27, 6, 3, 85, 4, 3, 19, 20, 65, 110, 100, 114, 111, 105, 100, 32, 75, 101, 121, 115, 116, 111, 114, 101, 32, 75, 101, 121\]) }, KeyParameter { tag: r#RSA_PUBLIC_EXPONENT, value: LongInteger(65537) }, KeyParameter { tag: r#ATTESTATION_CHALLENGE, value: Blob(\[\]) }, KeyParameter { tag: r#ATTESTATION_ID_BRAND, value: Blob(\[65, 115, 99, 111, 109\]) }, KeyParameter { tag: r#ATTESTATION_ID_DEVICE, value: Blob(\[83, 72, 52, 45, 50\]) }, KeyParameter { tag: r#ATTESTATION_ID_PRODUCT, value: Blob(\[83, 72, 52, 45, 65, 65, 66, 67\]) }, KeyParameter { tag: r#ATTESTATION_ID_MANUFACTURER, value: Blob(\[65, 115, 99, 111, 109\]) }, KeyParameter { tag: r#ATTESTATION_ID_MODEL, value: Blob(\[77, 121, 99, 111, 32, 52, 32, 87, 105, 45, 70, 105\]) }, KeyParameter { tag: r#CREATION_DATETIME, value: DateTime(1775199735061) }, KeyParameter { tag: r#ATTESTATION_APPLICATION_ID, value: Blob(\[48, 65, 49, 27, 48, 25, 4, 20, 97, 110, 100, 114, 111, 105, 100, 46, 107, 101, 121, 115, 116, 111, 114, 101, 46, 99, 116, 115, 2, 1, 36, 49, 34, 4, 32, 164, 13, 168, 10, 89, 209, 112, 202, 169, 80, 207, 21, 193, 140, 69, 77, 71, 163, 155, 38, 152, 157, 139, 100, 14, 205, 116, 91, 167, 27, 245, 220\]) }\]. 1: Error::Km(r#CANNOT_ATTEST_IDS)) (public error code: 8 internal Keystore code: -66) at android.security.KeyStore2.getKeyStoreException(KeyStore2.java:428) at android.security.KeyStoreSecurityLevel.handleExceptions(KeyStoreSecurityLevel.java:58) at android.security.KeyStoreSecurityLevel.generateKey(KeyStoreSecurityLevel.java:149) at android.security.keystore2.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:699) ... 15 more 在 devicePropertiesAttestation true 时要把 ATTESTATION_ID_\* 写进证书,KeyMint 拒绝 → CANNOT_ATTEST_IDS。同模块里 testRsaAttestation_NoChallenge 等未开设备属性证明的用例能通过,说明 普通密钥证明可用,卡在「设备属性/ID 证明」 * **KeyAttestationTest#testEcAttestation_DeviceLocked/KeyAttestationTest#testRsaAttestation_DeviceLocked** java.lang.AssertionError:**The device's bootloader must be locked**. This may not be the default for pre-production devices. at org.junit.Assert.fail(Assert.java:89) at org.junit.Assert.assertTrue(Assert.java:42) at android.keystore.cts.KeyAttestationTest.checkRootOfTrust(KeyAttestationTest.java:1875) at android.keystore.cts.KeyAttestationTest.checkDeviceLocked(KeyAttestationTest.java:1806) at android.keystore.cts.KeyAttestationTest.testEcAttestation_DeviceLocked(KeyAttestationTest.java:491) at android.keystore.cts.KeyAttestationTest.testEcAttestation_DeviceLocked(KeyAttestationTest.java:502) attestation 扩展里的 Root of Trust,要求 bootloader 处于 locked。当前设备(或工程配置)为 unlock 或 RoT 未反映为 locked,与 logcat 里大量 keyguard deviceLocked(用户锁屏)不是同一概念------测的是 引导加载程序锁定状态。 原因分析:此条第一条报错,是因为没有生成attestation ID,第二条报错是因为attestation ID没有导致无法写入秘钥,第三条是设备处于解锁状态。最后通过RKP的方式生成Attestation ID之后,此条除了**testEcAttestation_DeviceLocked和testRsaAttestation_DeviceLocked之外都能PASS** **总结:在RKP的方式里面Attestation相关的测试项,需要依赖设备具有attestation ID,否则一定会失败。这些测试项也没有真正的和google服务器进行秘钥校验。另外DeviceLocked相关的测试项需要使用已经锁定的设备进行测试才能PASS。** #### CtsDevicePolicyManagerTestCases 报错日志:arm64-v8a CtsDevicePolicyManagerTestCases Test Result Details com.android.cts.devicepolicy.MixedDeviceOwnerTest#testDelegatedCertInstallerDeviceIdAttestation fail java.lang.AssertionError: on-device tests failed: com.android.cts.devicepolicy.MixedDeviceOwnerTest#testKeyManagement fail java.lang.AssertionError: on-device tests failed: com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testKeyManagement fail org.junit.ComparisonFailure: expected:\<\[Success:\]\> but was:\<\[\]\> com.android.cts.devicepolicy.MixedProfileOwnerTest#testKeyManagement fail java.lang.AssertionError: on-device tests failed: com.android.cts.devicepolicy.OrgOwnedProfileOwnerTest#testDelegatedCertInstallerDeviceIdAttestation fail org.junit.ComparisonFailure: expected:\<\[Success:\]\> but was:\<\[\]\> com.android.cts.devicepolicy.OrgOwnedProfileOwnerTest#testDeviceIdAttestationForProfileOwner fail java.lang.AssertionError: on-device tests failed: 分析过程:此条在ASCOM A16项目最初也是通过keybox的方式来进行测试,也报了很多attestation相关的异常,在通过rkp的方式生成了attestation ID之后,这些项能够全部PASS **总结:CtsDevicePolicyManagerTestCases中关于Attestation相关的测试项也是需要生成attestation ID之后才能PASS** #### 第四类:RKP CSR秘钥校验是否有效 前文的大部分XTS问题在生成了attestation ID之后就能PASS,但是接下来这条却不行,是google真正校验csr秘钥是否有效,即必须在把CSR上传到google服务器才能通过的测试项: #### GtsGoogleAttestationHostTestCases 报错日志:com.google.android.gts.security.AttestationRootHostTest#testRsaAttestationChainTee/com.google.android.gts.security.AttestationRootHostTest#testEcAttestationChainTee 如下报错表示如下秘钥没有得到google认证,原因是RKP生成的CSR并没有上传到google服务器 |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ``` java.lang.AssertionError: on-device tests failed: com.google.android.gts.security.AttestationRootTest#testRsaAttestationChainTee: java.security.ProviderException: Failed to generate key pair. at android.security.keystore2.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:712) at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:750) at com.google.android.gts.security.AttestationRootTest.generateKeyPair(AttestationRootTest.java:248) at com.google.android.gts.security.AttestationRootTest.testRsaAttestationChainTee(AttestationRootTest.java:197) ... 8 trimmed Caused by: android.security.KeyStoreException: -74 (internal Keystore code: -74 message: system/security/keystore2/src/security_level.rs:680 Caused by: 0: system/security/keystore2/src/security_level.rs:674: While generating without a provided attestation key and params: [KeyParameter { tag: r#KEY_SIZE, value: Integer(2048) } , KeyParameter { tag: r#ALGORITHM, value: Algorithm(r#RSA) } , KeyParameter { tag: r#PURPOSE, value: KeyPurpose(r#SIGN) } , KeyParameter { tag: r#PURPOSE, value: KeyPurpose(r#VERIFY) } , KeyParameter { tag: r#PADDING, value: PaddingMode(r#RSA_PSS) } , KeyParameter { tag: r#DIGEST, value: Digest(r#SHA_2_256) } , KeyParameter { tag: r#NO_AUTH_REQUIRED, value: BoolValue(true) } , KeyParameter { tag: r#CERTIFICATE_NOT_AFTER, value: DateTime(2461449600000) } , KeyParameter { tag: r#CERTIFICATE_NOT_BEFORE, value: DateTime(0) } , KeyParameter { tag: r#CERTIFICATE_SERIAL, value: Blob([1]) } , KeyParameter { tag: r#CERTIFICATE_SUBJECT, value: Blob([48, 31, 49, 29, 48, 27, 6, 3, 85, 4, 3, 19, 20, 65, 110, 100, 114, 111, 105, 100, 32, 75, 101, 121, 115, 116, 111, 114, 101, 32, 75, 101, 121]) } , KeyParameter { tag: r#RSA_PUBLIC_EXPONENT, value: LongInteger(65537) } , KeyParameter { tag: r#ATTESTATION_CHALLENGE, value: Blob([99, 104, 97, 108, 108, 101, 110, 103, 101]) } , KeyParameter { tag: r#CREATION_DATETIME, value: DateTime(1774884669430) } , KeyParameter { tag: r#ATTESTATION_APPLICATION_ID, value: Blob([48, 76, 49, 38, 48, 36, 4, 31, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101, 46, 97, 110, 100, 114, 111, 105, 100, 46, 103, 116, 115, 46, 115, 101, 99, 117, 114, 105, 116, 121, 2, 1, 37, 49, 34, 4, 32, 25, 117, 178, 241, 113, 119, 188, 137, 165, 223, 243, 31, 158, 100, 166, 202, 226, 129, 165, 61, 193, 209, 213, 155, 29, 20, 127, 225, 200, 42, 250, 0]) } ]. 1: Error::Km(r#ATTESTATION_KEYS_NOT_PROVISIONED)) (public error code: 10 internal Keystore code: -74) at android.security.KeyStore2.getKeyStoreException(KeyStore2.java:428) at android.security.KeyStoreSecurityLevel.handleExceptions(KeyStoreSecurityLevel.java:58) at android.security.KeyStoreSecurityLevel.generateKey(KeyStoreSecurityLevel.java:149) at android.security.keystore2.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:699) ... 12 more at com.android.tradefed.testtype.junit4.BaseHostJUnit4Test.runDeviceTests(BaseHostJUnit4Test.java:755) at com.android.tradefed.testtype.junit4.BaseHostJUnit4Test.runDeviceTests(BaseHostJUnit4Test.java:486) at com.google.android.gts.security.AttestationRootHostTest.runMethod(AttestationRootHostTest.java:263) at com.google.android.gts.security.AttestationRootHostTest.testRsaAttestationChainTee(AttestationRootHostTest.java:134) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:61) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.runChild(DeviceJUnit4ClassRunner.java:111) at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.runChild(DeviceJUnit4ClassRunner.java:63) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) ``` | 分析记录:此案例主要原因就是CSR无法上传到google服务器,接下来针对这个问题进行说明,主要有如下几个步骤 ##### 步骤一、生成google id |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ``` C:\Users\pengcheng.ding>adb root restarting adbd as root C:\Users\pengcheng.ding>adb shell SH4-1:/ # LD_LIBRARY_PATH=/vendor/lib64/hw KmInstallKeybox 1 1 true rkp qmi_client_send_msg_sync success for get dev_ser_num 0 qmi_client_send_msg_sync success for get dev_ser_num 1 Brand: Ascom Device: SH4-1 Product: SH4-ABCE SerialNum: 532c7d54 Manufacturer: Ascom Model: Myco 4 Slim Cellular Wi-Fi TEE done InstallKeybox is done! SH4-1:/ # exit ``` | ##### 步骤二、结合高通命令生成CSR |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ``` C:\Users\pengcheng.ding>adb shell /vendor/bin/rkp_factory_extraction_tool64 --output_format build+csr --allow_degenerate default > dpc_csr.json Bundle extraction failed for 'widevine'. Description: Status(-8, EX_SERVICE_SPECIFIC): '1: Failed to parse the verified device info cbor.'. Unable to build CSR for 'android.hardware.drm.IDrmFactory/widevine': Status(-8, EX_SERVICE_SPECIFIC): '1: Failed to parse the verified device info cbor.', exiting. C:\Users\pengcheng.ding>type dpc_csr.json {"build_fingerprint":"Ascom/SH4-ABCE/SH4-1:16/BQ2A.260103.001-BP2A.250705.008/eng.androi:userdebug/release-keys","csr":"hQGggqUBAQMnIAYEgQIhWCBvHSvJo100BTtnqa2ciDZWYejHejObmtcx9qXFto1cLIRDoQEnoFhYpAFpUVVBTENPTU0AAm9SS1AgRGV2aWNlIEtleQA6AEdEV1gtpQEBAycgBgSBAiFYIG8dK8mjXTQFO2eprZyINlZh6Md6M5ua1zH2pcW2jVwsOgBHRFhBIFhA6nUjlIL12YLLjGdSP3mUvTTbz1gSjOGox6gqcESFcMmD7yGGCmnVnepWk/yo78mjCUvumfzzbKgT+mhtke3nDYRDoQEnoFkBfYJYQOF1q9lxMkzqKCuH711d9t678eUP/2qvHt10d/RQTGDadDPS1WYD4ym+kmKU6zWFgfPS0+iWws/LtI3ozk/cKF9ZATeEA2drZXltaW50rmVicmFuZGVBc2NvbWVmdXNlZAFlbW9kZWx4Gk15Y28gNCBTbGltIENlbGx1bGFyIFdpLUZpZmRldmljZWVTSDQtMWdwcm9kdWN0aFNINC1BQkNFaHZiX3N0YXRlZm9yYW5nZWpvc192ZXJzaW9uZjE2MDAwMGxtYW51ZmFjdHVyZXJlQXNjb21tdmJtZXRhX2RpZ2VzdFgg//2vigkltzjPJmhSudF7E7TXHu5/uqgI0gKRuvV7i6Vuc2VjdXJpdHlfbGV2ZWxjdGVlcGJvb3RfcGF0Y2hfbGV2ZWwaATUl0XBib290bG9hZGVyX3N0YXRlaHVubG9ja2VkcnN5c3RlbV9wYXRjaF9sZXZlbBoAAxdrcnZlbmRvcl9wYXRjaF9sZXZlbBoBNSXRgFhAeNyMnZZp0ElR0od+rBpTU9sAfpiM8CcR/reVkupNt5WPcsy0l3RpEHgJo8sXyti8++fdsJeAxKEgV52L3rGtAKFrZmluZ2VycHJpbnR4WUFzY29tL1NINC1BQkNFL1NINC0xOjE2L0JRMkEuMjYwMTAzLjAwMS1CUDJBLjI1MDcwNS4wMDgvZW5nLmFuZHJvaTp1c2VyZGVidWcvcmVsZWFzZS1rZXlz","name":"default","serialno":"532c7d54"} ``` | ##### 步骤三、上传CSR到google服务器报格式错误 |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ``` C:\Users\junhui.li>python device_info_uploader.py --credentials cred.json --json-csr csr.json --cache-token --company-id 1398696844 1/1: Uploading batch containing 1 csr(s) Opening your web browser to authenticate... Waiting for a response from the Google OAuth service. If you receive an error in your browser, interrupt this script. GET path: /?iss=https://accounts.google.com&code=4/0AfrIepAEdNjMkwQe8chGTin-Tpe6a1CRjqcrxd2YjVHCgvb4mTCvWRscqW4x5iuxxhvbfg&scope=https://www.googleapis.com/auth/androidPartner 127.0.0.1 - - [06/Mar/2026 15:38:01] "GET /?iss=https://accounts.google.com&code=4/0AfrIepAEdNjMkwQe8chGTin-Tpe6a1CRjqcrxd2YjVHCgvb4mTCvWRscqW4x5iuxxhvbfg&scope=https://www.googleapis.com/auth/androidPartner HTTP/1.1" 200 - Batch API response:{ "errors": [ { "certificatePayload": { "certificateSigningRequest": "hQGggqUBAQMnIAYEAiFYIG8dK8mjXTQFO2eprZyINlZh6Md6M5ua1zH2pcW2jVwshEOhASegWFekAWlRVUFMQ09NTQACb1JLUCBEZXZpY2UgS2V5ADoAR0RXWCylAQEDJyAGBAIhWCBvHSvJo100BTtnqa2ciDZWYejHejObmtcx9qXFto1cLDoAR0RYQSBYQEznD5bkSImf9ltxKjkY+4GM0lkJPFVBKp7yI7tq0LPCiC/19Iy5kYJwDXQ6/KwJo1ZoN0qm4F6i4v2UEkEuTwKEQ6EBJ6BZAW6CWEBHdIwMNGChnnMEyXj062qnz3habMIFmR1XMoIobyxFPrueKHPUTLu/tb1Gv1IEx2XqwdYubXfKV+WChea8z1epWQEohANna2V5bWludK5lYnJhbmRlQXNjb21lZnVzZWQBZW1vZGVsbE15Y28gNCBXaS1GaWZkZXZpY2VlU0g0LTJncHJvZHVjdGhTSDQtQUFCQ2h2Yl9zdGF0ZWZvcmFuZ2Vqb3NfdmVyc2lvbmYxNjAwMDBsbWFudWZhY3R1cmVyZUFzY29tbXZibWV0YV9kaWdlc3RYIEyi4i/PAPXjWjH9vi8dE3L0gnmHZincp0yvXCXT7piJbnNlY3VyaXR5X2xldmVsY3RlZXBib290X3BhdGNoX2xldmVsGgE1JW1wYm9vdGxvYWRlcl9zdGF0ZWh1bmxvY2tlZHJzeXN0ZW1fcGF0Y2hfbGV2ZWwaAAMXanJ2ZW5kb3JfcGF0Y2hfbGV2ZWwaATUlbYBYQOUnv3I/OR2h8O+ZwSpfxJ2zfSlEquD4lomMg+/vgVcMS1D7nA8PxIfvdE2HrVv+xqFkUSl6PZyyI51p89asGwOha2ZpbmdlcnByaW50eFxBc2NvbS9TSDQtQUFCQy9TSDQtMjoxNi9CUTJBLjI1MTEyNS4wMDEtQlAyQS4yNTA2MDUuMDMxLkEzL0ExNl8wMDEuMDA6dXNlcmRlYnVnL3JlbGVhc2Uta2V5cw==" }, "status": { "code": 3, "message": "Can't deserialize certificate signing requests during registration. Please make sure that your CSR is not corrupted: Couldn't parse Signing CoseKey (Ec2SigningKey/OkpSigningKey) from provided cbor" } } ], "requestId": "ec74b12e-54c9-4053-9ef6-e8faf00b331e" } Errors occurred when uploading csrs: 200 { "errors": [ { "certificatePayload": { "certificateSigningRequest": "hQGggqUBAQMnIAYEAiFYIG8dK8mjXTQFO2eprZyINlZh6Md6M5ua1zH2pcW2jVwshEOhASegWFekAWlRVUFMQ09NTQACb1JLUCBEZXZpY2UgS2V5ADoAR0RXWCylAQEDJyAGBAIhWCBvHSvJo100BTtnqa2ciDZWYejHejObmtcx9qXFto1cLDoAR0RYQSBYQEznD5bkSImf9ltxKjkY+4GM0lkJPFVBKp7yI7tq0LPCiC/19Iy5kYJwDXQ6/KwJo1ZoN0qm4F6i4v2UEkEuTwKEQ6EBJ6BZAW6CWEBHdIwMNGChnnMEyXj062qnz3habMIFmR1XMoIobyxFPrueKHPUTLu/tb1Gv1IEx2XqwdYubXfKV+WChea8z1epWQEohANna2V5bWludK5lYnJhbmRlQXNjb21lZnVzZWQBZW1vZGVsbE15Y28gNCBXaS1GaWZkZXZpY2VlU0g0LTJncHJvZHVjdGhTSDQtQUFCQ2h2Yl9zdGF0ZWZvcmFuZ2Vqb3NfdmVyc2lvbmYxNjAwMDBsbWFudWZhY3R1cmVyZUFzY29tbXZibWV0YV9kaWdlc3RYIEyi4i/PAPXjWjH9vi8dE3L0gnmHZincp0yvXCXT7piJbnNlY3VyaXR5X2xldmVsY3RlZXBib290X3BhdGNoX2xldmVsGgE1JW1wYm9vdGxvYWRlcl9zdGF0ZWh1bmxvY2tlZHJzeXN0ZW1fcGF0Y2hfbGV2ZWwaAAMXanJ2ZW5kb3JfcGF0Y2hfbGV2ZWwaATUlbYBYQOUnv3I/OR2h8O+ZwSpfxJ2zfSlEquD4lomMg+/vgVcMS1D7nA8PxIfvdE2HrVv+xqFkUSl6PZyyI51p89asGwOha2ZpbmdlcnByaW50eFxBc2NvbS9TSDQtQUFCQy9TSDQtMjoxNi9CUTJBLjI1MTEyNS4wMDEtQlAyQS4yNTA2MDUuMDMxLkEzL0ExNl8wMDEuMDA6dXNlcmRlYnVnL3JlbGVhc2Uta2V5cw==" }, "status": { "code": 3, "message": "Can't deserialize certificate signing requests during registration. Please make sure that your CSR is not corrupted: Couldn't parse Signing CoseKey (Ec2SigningKey/OkpSigningKey) from provided cbor" } } ], "requestId": "ec74b12e-54c9-4053-9ef6-e8faf00b331e" } Refer to https://docs.partner.android.com/gms/building/integrating/att-keys/rkp-errors for detailed explanations of each error code. ``` | 如上秘钥上传到google服务器,google服务器解析报错,高通说google问题,google也不知道找高通去看,最后我把这个秘钥丢给了扣子空间进行解析,得出了如下结论: ![](https://i-blog.csdnimg.cn/direct/cb6b2f2979314ae8b9284928969d8eef.png)最后结论是秘钥算法是符合要求,但是组装的格式不太对,可能是keymaster返回的数据异常,给到高通之后,高通提供了新的keymint.mbn文件,重新生成,再次上传google服务器: |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ``` C:\Users\junhui.li>python device_info_uploader.py --credentials cred.json --json-csr dpc_csr.json --company-id=1398696844 --verbose 1/1: Uploading batch containing 1 csr(s) request body: {'device_payloads': [{'certificate_payloads': [ {'certificate_signing_request': 'hQGggqUBAQMnIAYEgQIhWCBvHSvJo100BTtnqa2ciDZWYejHejObmtcx9qXFto1cLIRDoQEnoFhYpAFpUVVBTENPTU0AAm9SS1AgRGV2aWNlIEtleQA6AEdEV1gtpQEBAycgBgSBAiFYIG8dK8mjXTQFO2eprZyINlZh6Md6M5ua1zH2pcW2jVwsOgBHRFhBIFhA6nUjlIL12YLLjGdSP3mUvTTbz1gSjOGox6gqcESFcMmD7yGGCmnVnepWk/yo78mjCUvumfzzbKgT+mhtke3nDYRDoQEnoFkBfYJYQOF1q9lxMkzqKCuH711d9t678eUP/2qvHt10d/RQTGDadDPS1WYD4ym+kmKU6zWFgfPS0+iWws/LtI3ozk/cKF9ZATeEA2drZXltaW50rmVicmFuZGVBc2NvbWVmdXNlZAFlbW9kZWx4Gk15Y28gNCBTbGltIENlbGx1bGFyIFdpLUZpZmRldmljZWVTSDQtMWdwcm9kdWN0aFNINC1BQkNFaHZiX3N0YXRlZm9yYW5nZWpvc192ZXJzaW9uZjE2MDAwMGxtYW51ZmFjdHVyZXJlQXNjb21tdmJtZXRhX2RpZ2VzdFgg//2vigkltzjPJmhSudF7E7TXHu5/uqgI0gKRuvV7i6Vuc2VjdXJpdHlfbGV2ZWxjdGVlcGJvb3RfcGF0Y2hfbGV2ZWwaATUl0XBib290bG9hZGVyX3N0YXRlaHVubG9ja2VkcnN5c3RlbV9wYXRjaF9sZXZlbBoAAxdrcnZlbmRvcl9wYXRjaF9sZXZlbBoBNSXRgFhAeNyMnZZp0ElR0od+rBpTU9sAfpiM8CcR/reVkupNt5WPcsy0l3RpEHgJo8sXyti8++fdsJeAxKEgV52L3rGtAKFrZmluZ2VycHJpbnR4WUFzY29tL1NINC1BQkNFL1NINC0xOjE2L0JRMkEuMjYwMTAzLjAwMS1CUDJBLjI1MDcwNS4wMDgvZW5nLmFuZHJvaTp1c2VyZGVidWcvcmVsZWFzZS1rZXlz'} ]}], 'company_id': '1398696844', 'is_test': False} Opening your web browser to authenticate... Waiting for a response from the Google OAuth service. If you receive an error in your browser, interrupt this script. GET path: /?iss=https://accounts.google.com&code=4/0Aci98E-WSBq5vxyGljCIiNEXuSrmOPepkDwJKHJNpoHJqAfJO4oLfs8EuMtl4b-DZjo5lA&scope=https://www.googleapis.com/auth/androidPartner 127.0.0.1 - - [15/Apr/2026 21:32:44] "GET /?iss=https://accounts.google.com&code=4/0Aci98E-WSBq5vxyGljCIiNEXuSrmOPepkDwJKHJNpoHJqAfJO4oLfs8EuMtl4b-DZjo5lA&scope=https://www.googleapis.com/auth/androidPartner HTTP/1.1" 200 - Batch API response:{ "errors": [ { "certificatePayload": { "certificateSigningRequest": "hQGggqUBAQMnIAYEgQIhWCBvHSvJo100BTtnqa2ciDZWYejHejObmtcx9qXFto1cLIRDoQEnoFhYpAFpUVVBTENPTU0AAm9SS1AgRGV2aWNlIEtleQA6AEdEV1gtpQEBAycgBgSBAiFYIG8dK8mjXTQFO2eprZyINlZh6Md6M5ua1zH2pcW2jVwsOgBHRFhBIFhA6nUjlIL12YLLjGdSP3mUvTTbz1gSjOGox6gqcESFcMmD7yGGCmnVnepWk/yo78mjCUvumfzzbKgT+mhtke3nDYRDoQEnoFkBfYJYQOF1q9lxMkzqKCuH711d9t678eUP/2qvHt10d/RQTGDadDPS1WYD4ym+kmKU6zWFgfPS0+iWws/LtI3ozk/cKF9ZATeEA2drZXltaW50rmVicmFuZGVBc2NvbWVmdXNlZAFlbW9kZWx4Gk15Y28gNCBTbGltIENlbGx1bGFyIFdpLUZpZmRldmljZWVTSDQtMWdwcm9kdWN0aFNINC1BQkNFaHZiX3N0YXRlZm9yYW5nZWpvc192ZXJzaW9uZjE2MDAwMGxtYW51ZmFjdHVyZXJlQXNjb21tdmJtZXRhX2RpZ2VzdFgg//2vigkltzjPJmhSudF7E7TXHu5/uqgI0gKRuvV7i6Vuc2VjdXJpdHlfbGV2ZWxjdGVlcGJvb3RfcGF0Y2hfbGV2ZWwaATUl0XBib290bG9hZGVyX3N0YXRlaHVubG9ja2VkcnN5c3RlbV9wYXRjaF9sZXZlbBoAAxdrcnZlbmRvcl9wYXRjaF9sZXZlbBoBNSXRgFhAeNyMnZZp0ElR0od+rBpTU9sAfpiM8CcR/reVkupNt5WPcsy0l3RpEHgJo8sXyti8++fdsJeAxKEgV52L3rGtAKFrZmluZ2VycHJpbnR4WUFzY29tL1NINC1BQkNFL1NINC0xOjE2L0JRMkEuMjYwMTAzLjAwMS1CUDJBLjI1MDcwNS4wMDgvZW5nLmFuZHJvaTp1c2VyZGVidWcvcmVsZWFzZS1rZXlz" } , "status": { "code": 6, "message": "This CSR was not uploaded. Device public key (o\u001d+ɣ]4\u0005;g 6Va z3 1 Ŷ \\,) already exists. Please call BatchUpdate to modify an existing key's data." } } ], "requestId": "fb4fb6e0-eefb-4c6d-9f91-c803e2ae2372" } Errors occurred when uploading csrs: 200 { "errors": [ { "certificatePayload": { "certificateSigningRequest": "hQGggqUBAQMnIAYEgQIhWCBvHSvJo100BTtnqa2ciDZWYejHejObmtcx9qXFto1cLIRDoQEnoFhYpAFpUVVBTENPTU0AAm9SS1AgRGV2aWNlIEtleQA6AEdEV1gtpQEBAycgBgSBAiFYIG8dK8mjXTQFO2eprZyINlZh6Md6M5ua1zH2pcW2jVwsOgBHRFhBIFhA6nUjlIL12YLLjGdSP3mUvTTbz1gSjOGox6gqcESFcMmD7yGGCmnVnepWk/yo78mjCUvumfzzbKgT+mhtke3nDYRDoQEnoFkBfYJYQOF1q9lxMkzqKCuH711d9t678eUP/2qvHt10d/RQTGDadDPS1WYD4ym+kmKU6zWFgfPS0+iWws/LtI3ozk/cKF9ZATeEA2drZXltaW50rmVicmFuZGVBc2NvbWVmdXNlZAFlbW9kZWx4Gk15Y28gNCBTbGltIENlbGx1bGFyIFdpLUZpZmRldmljZWVTSDQtMWdwcm9kdWN0aFNINC1BQkNFaHZiX3N0YXRlZm9yYW5nZWpvc192ZXJzaW9uZjE2MDAwMGxtYW51ZmFjdHVyZXJlQXNjb21tdmJtZXRhX2RpZ2VzdFgg//2vigkltzjPJmhSudF7E7TXHu5/uqgI0gKRuvV7i6Vuc2VjdXJpdHlfbGV2ZWxjdGVlcGJvb3RfcGF0Y2hfbGV2ZWwaATUl0XBib290bG9hZGVyX3N0YXRlaHVubG9ja2VkcnN5c3RlbV9wYXRjaF9sZXZlbBoAAxdrcnZlbmRvcl9wYXRjaF9sZXZlbBoBNSXRgFhAeNyMnZZp0ElR0od+rBpTU9sAfpiM8CcR/reVkupNt5WPcsy0l3RpEHgJo8sXyti8++fdsJeAxKEgV52L3rGtAKFrZmluZ2VycHJpbnR4WUFzY29tL1NINC1BQkNFL1NINC0xOjE2L0JRMkEuMjYwMTAzLjAwMS1CUDJBLjI1MDcwNS4wMDgvZW5nLmFuZHJvaTp1c2VyZGVidWcvcmVsZWFzZS1rZXlz" } , "status": { "code": 6, "message": "This CSR was not uploaded. Device public key (o\u001d+ɣ]4\u0005;g 6Va z3 1 Ŷ \\,) already exists. Please call BatchUpdate to modify an existing key's data." } } ], "requestId": "fb4fb6e0-eefb-4c6d-9f91-c803e2ae2372" } Refer to https://docs.partner.android.com/gms/building/integrating/att-keys/rkp-errors for detailed explanations of each error code. ``` | 这次上传报错不再是格式不对了,因此重新去跑了一下此条测试项: |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | java.lang.AssertionError: on-device tests failed: com.google.android.gts.security.AttestationRootTest#testRsaAttestationChainTee: junit.framework.AssertionFailedError: \***Certificate chain is valid, but does not have production root**\* at junit.framework.Assert.fail(Assert.java:50) at junit.framework.Assert.assertTrue(Assert.java:20) at com.google.android.gts.security.AttestationRootTest.verifyCertificateChain(AttestationRootTest.java:315) at com.google.android.gts.security.AttestationRootTest.verifyAttestationChain(AttestationRootTest.java:132) at com.google.android.gts.security.AttestationRootTest.testRsaAttestationChainTee(AttestationRootTest.java:198) | 根据如上日志,这些秘钥是有效的,但是不属于根的证书,经过评估准备拿EFUS的机器进行测试。 **最后确定和EFUS机器没有关系,Certificate chain is valid, but does not have production root的原因是XTS工具问题,使用PAB临时工具能够PASS。**

相关推荐
eSsO KERF3 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
pengyu5 小时前
【Kotlin 协程修仙录 · 筑基境 · 后阶】 | 调度器的艺术:Dispatchers 四大护法与 withContext 性能密码
android·kotlin
uElY ITER5 小时前
MySQL 中如何进行 SQL 调优
android·sql·mysql
xxjj998a5 小时前
Laravel3.x:奠定现代PHP框架的重要里程碑
android·开发语言·php
Yang-Never6 小时前
Git -> Git Worktree 工作树
android·开发语言·git·android studio
xingpanvip6 小时前
星盘接口开发文档:日运语料接口指南
android·开发语言·前端·css·php·lua
计算机安禾6 小时前
【Linux从入门到精通】第42篇:深入理解Linux内存管理
android·linux·运维
XD7429716367 小时前
科技早报晚报|2026年5月1日:本地优先文档、安卓离线 IDE 与双击即用密码库,今天最值得跟进的 3 个机会
android·ide·科技·科技新闻·开发者工具·本地优先
计算机安禾7 小时前
【Linux从入门到精通】第40篇:LAMP/LNMP环境一键部署脚本实战
android·linux·adb