android GMS认证之testGoogleDuoPreloaded

这里写图片描述

7.1 GTS测试报了一个错

这里写图片描述

GtsPlacementTestCases - armeabi-v7a
Test Result Details
com.google.android.placement.gts.CoreGmsAppsTest#testGoogleDuoPreloaded fail junit.framework.AssertionFailedError: Mandatory app Hangouts not preloaded

问题浅探

从报错提示来看,就是强制要预置GMS应用Hangouts ,而检测手机说没有预置,所以报错。

真实的情况是这样的,客户要求一定要删除应用Hangouts ,加上应用Duo。

我们也可以从google/products/gms.mk文件看到如下说明:

# Note: Duo is mandatory for telephony devices, whereas Hangouts is for non-telephony devices. 

也就是说对于电话设备,Duo应用是强制预装的,而对于非电话设备Hangouts 应用是强制预装的。

我们是手机电话设备,这符合要求,没有问题啊?为什么GTS测试会报错呢?

问题解决之千回百转

千回百转之高通技术支持

我提了一个case给高通,把这个情况说明了,高通给了一个解决方案,要我们装Hangouts 应用也内置一下,测试看什么情况?
我看到这个方法,觉得有点扯,内置Hangouts 应用,此测试项肯定可以PASS的,果然,内置Hangouts 应用测试,此项PASS,我把情况反馈,高通人员回复说现在可以PASS了,请我将此CASE关闭。我眼前一黑,这,问题没有解决就急着要关CASE。

(果然是屁股决定脑袋,你坐什么位置,脑子里就只关心自己的有利益相关的问题,高通人员心里只是关心CASE快点关闭,而问题有没有解决不是他们考虑的问题)

千回百转之GMS认证代理

客户提这种要求,那么此问题客户也应该是遇到过,我要软件项目经理帮忙去GMS代理咨询一下,有没有遇到这种情况,很快代理有回复了。

define android.hardware.telephony 这个feature如果打开了,应该不会出现这种问题。Hangout对于7.0/7.1的New telephone设备来说应该是optional的, 此处应该不会报错.我刚咨询了一下谷歌, 最近有要送测的7.1 New device, GTS没有这个问题(没有预置hangout).7.0的new device上没有hangout的设备, GTS也没有遇到这个问题.此处遇到的问题, 应该是设备被识别成了non-telephony的设备, 可以从这个方面去check.

事实上我们可以在GTS测试报告的device-info-files/FeatureDeviceInfo.deviceinfo.json文件中看到:

    {
      "name": "android.hardware.telephony",
      "type": "sdk",
      "available": true,
      "version": 0
    },

也就是说android.hardware.telephony是支持的。

现在怎么办?

千回百转之自力更生

没有办法,还是自己再来分析。

先再看一下测试报的错误日志:

04-12 15:08:12 I/ConsoleReporter: [18c5ce29] Starting armeabi-v7a GtsPlacementTestCases with 1 test
04-12 15:08:12 D/ModuleListener: ModuleListener.testStarted(com.google.android.placement.gts.CoreGmsAppsTest#testGoogleDuoPreloaded)
04-12 15:08:12 D/ModuleListener: ModuleListener.testFailed(com.google.android.placement.gts.CoreGmsAppsTest#testGoogleDuoPreloaded, junit.framework.AssertionFailedError: Mandatory app Hangouts not preloaded
at junit.framework.Assert.fail(Assert.java:50)
at junit.framework.Assert.assertTrue(Assert.java:20)
at com.google.android.placement.gts.CoreGmsAppsTest.testGoogleDuoPreloaded(CoreGmsAppsTest.java:228)
at java.lang.reflect.Method.invoke(Native Method)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:115)
at android.support.test.internal.runner.junit3.AndroidTestResult.runProtected(AndroidTestResult.java:77)
at junit.framework.TestResult.run(TestResult.java:118)
at android.support.test.internal.runner.junit3.AndroidTestResult.run(AndroidTestResult.java:55)
at junit.framework.TestCase.run(TestCase.java:124)
at android.support.test.internal.runner.junit3.NonLeakyTestSuite$NonLeakyTest.run(NonLeakyTestSuite.java:63)
at android.support.test.internal.runner.junit3.AndroidTestSuite$1.run(AndroidTestSuite.java:97)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)

从这段日志,我们可以知道,是这android-gts/testcases/GtsPlacementTestCases.apk应用的测试。

GTS测试问题,有时候不好解决,为什么呢?一个关键的问题就是只在GTS的APK,而没有源码,导致我们分析问题,没有着力点

没有关系,我就不信邪,我想看看到底是怎么回事?

现在就是要反编译APK,看看能不能找到源码,再来分析此问题。

我度娘了一个APK反编译工具,下载了三个APK反编译工具,用了一下,一个不能用,一个用不了,但是这个是可以完美的将代码反编译出来。有请这位哥哥:AndroidKiller_1.3.1

有工具后,反编译的操作如此简单,我都不好意思说出来,直接给大家看看我们反编译后的代码界面吧:

这里写图片描述

那我们赶快搜索一下testGoogleDuoPreloaded方法,看看源码吧:

.method public testGoogleDuoPreloaded()V
    .locals 4

    .prologue
    .line 217
    invoke-direct {p0}, Lcom/google/android/placement/gts/CoreGmsAppsTest;->playStorePreloaded()Z

    move-result v0

    if-nez v0, :cond_0

    .line 218
    const-string/jumbo v0, "CoreGmsAppsTest"

    const-string/jumbo v1, "Bypass as no Play Store preloaded."

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 219
    return-void

    .line 222
    :cond_0
    iget-object v0, p0, Lcom/google/android/placement/gts/CoreGmsAppsTest;->mPackageManager:Landroid/content/pm/PackageManager;

    const-string/jumbo v1, "android.hardware.telephony"

    invoke-virtual {v0, v1}, Landroid/content/pm/PackageManager;->hasSystemFeature(Ljava/lang/String;)Z

    move-result v0

    if-eqz v0, :cond_2

    .line 223
    invoke-direct {p0}, Lcom/google/android/placement/gts/CoreGmsAppsTest;->isNewProduct()Z

    move-result v0

    if-eqz v0, :cond_1

    .line 225
    const-string/jumbo v0, "Mandatory app Google Duo not preloaded"

    const-string/jumbo v1, "com.google.android.apps.tachyon"

    invoke-direct {p0, v1}, Lcom/google/android/placement/gts/CoreGmsAppsTest;->isSystemApp(Ljava/lang/String;)Z

    move-result v1

    invoke-static {v0, v1}, Lcom/google/android/placement/gts/CoreGmsAppsTest;->assertTrue(Ljava/lang/String;Z)V

    .line 216
    :goto_0
    return-void

    .line 228
    :cond_1
    const-string/jumbo v0, "Mandatory app Hangouts not preloaded"

    const-string/jumbo v1, "com.google.android.talk"

    invoke-direct {p0, v1}, Lcom/google/android/placement/gts/CoreGmsAppsTest;->isSystemApp(Ljava/lang/String;)Z

    move-result v1

    invoke-static {v0, v1}, Lcom/google/android/placement/gts/CoreGmsAppsTest;->assertTrue(Ljava/lang/String;Z)V

    goto :goto_0

    .line 232
    :cond_2
    const-string/jumbo v0, "Mandatory app Hangouts not preloaded"

    const-string/jumbo v1, "com.google.android.talk"

    invoke-direct {p0, v1}, Lcom/google/android/placement/gts/CoreGmsAppsTest;->isSystemApp(Ljava/lang/String;)Z

    move-result v1

    invoke-static {v0, v1}, Lcom/google/android/placement/gts/CoreGmsAppsTest;->assertTrue(Ljava/lang/String;Z)V

    .line 234
    const-string/jumbo v0, "Google Duo must not be preloaded without feature %s"

    const/4 v1, 0x1

    new-array v1, v1, [Ljava/lang/Object;

    .line 235
    const-string/jumbo v2, "android.hardware.telephony"

    const/4 v3, 0x0

    aput-object v2, v1, v3

    .line 234
    invoke-static {v0, v1}, Ljava/lang/String;->format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;

    move-result-object v0

    .line 235
    const-string/jumbo v1, "com.google.android.apps.tachyon"

    invoke-direct {p0, v1}, Lcom/google/android/placement/gts/CoreGmsAppsTest;->isSystemApp(Ljava/lang/String;)Z

    move-result v1

    .line 234
    invoke-static {v0, v1}, Lcom/google/android/placement/gts/CoreGmsAppsTest;->assertFalse(Ljava/lang/String;Z)V

    goto :goto_0
.end method

如果你说不知道怎么看反编译的源码,没有关系,非常简单,参考一下:

Android逆向反编译之smali基础
http://blog.csdn.net/sjim_/article/details/50443860

结合测试报错日志,我们直接看228行代码报错的地方:

    .line 228
    :cond_1
const-string/jumbo v0, "Mandatory app Hangouts not preloaded"

此处就是报错提示的代码,那么我们只需要去确认一下228行代码上面做了一些什么工作就可以了。

检测Play Store应用是否内置

invoke-direct {p0}, Lcom/google/android/placement/gts/CoreGmsAppsTest;->playStorePreloaded()Z

我们当然是内置了Play Store应用,这个没有问题

检测设备feature(android.hardware.telephony)是否开启。

    .line 222
    :cond_0
    iget-object v0, p0, Lcom/google/android/placement/gts/CoreGmsAppsTest;->mPackageManager:Landroid/content/pm/PackageManager;

    const-string/jumbo v1, "android.hardware.telephony"

    invoke-virtual {v0, v1}, Landroid/content/pm/PackageManager;->hasSystemFeature(Ljava/lang/String;)Z

这个我们有二个办法来确认,一个是上面说的方法来确认:
在GTS测试报告的device-info-files/FeatureDeviceInfo.deviceinfo.json文件中看到:

    {
      "name": "android.hardware.telephony",
      "type": "sdk",
      "available": true,
      "version": 0
    },

另外一个办法是参考反编译代码来验证,非常简单,一行办法搞定:

Log.i(TAG, "hasSystemFeature:"+MainActivity.this.getPackageManager().hasSystemFeature("android.hardware.telephony"));

我们验证此feature是已经打开了。

检测设备是否是新设备。

    .line 223
invoke-direct {p0}, Lcom/google/android/placement/gts/CoreGmsAppsTest;->isNewProduct()Z

那我们再搜索一下方法isNewProduct()Z:

.method private isNewProduct()Z
    .locals 4

    .prologue
    const/4 v1, 0x1

    const/4 v2, 0x0

    .line 100
    const-string/jumbo v3, "ro.product.first_api_level"

    .line 99
    invoke-static {v3, v2}, Landroid/os/SystemProperties;->getInt(Ljava/lang/String;I)I

    move-result v0

    .line 101
    .local v0, "firstApiLevel":I
    if-eqz v0, :cond_0

    sget v3, Landroid/os/Build$VERSION;->SDK_INT:I

    if-ne v0, v3, :cond_1

    :cond_0
    :goto_0
    return v1

    :cond_1
    move v1, v2

    goto :goto_0
.end method

从反编译后的源码,我们可以看到这就是比较二个值是否相等:

ro.product.first_api_level
Landroid/os/Build$VERSION;->SDK_INT

我从我们的设备来查看了一个系统属性:

[ro.product.first_api_level]: [24]

而再查看Landroid/os/Build$VERSION;->SDK_INT,在./frameworks/base/core/java/android/os/Build.java文件中,可以看到:

public static final int SDK_INT = SystemProperties.getInt(
                "ro.build.version.sdk", 0);

也就是系统属性:ro.build.version.sdk

我查看设备的ro.build.version.sdk值:

[ro.build.version.sdk]: [25]

看到了没,二个不相等,哈哈,问题定位到了,现在是7.1的设备SDK值是25,而ro.product.first_api_level还是24,没有及时更新过来。好了,搜索了一下代码,定位到:

./vendor/tinno/v3931/wik_fr/SUB_PROJECTS/orange/gms.mk

# Overrides
PRODUCT_PROPERTY_OVERRIDES += \
    ro.product.first_api_level=24 \
    ro.setupwizard.require_network=OPTIONAL \
    ro.setupwizard.mode=OPTIONAL \
    ro.com.google.gmsversion=7.1_r3

将代码修改为:

# Overrides
PRODUCT_PROPERTY_OVERRIDES += \
    ro.product.first_api_level=25 \
    ro.setupwizard.require_network=OPTIONAL \
    ro.setupwizard.mode=OPTIONAL \
    ro.com.google.gmsversion=7.1_r3

再编译验证,PASS。

此问题解决了。

自我感受

最后,结尾了,说几句自己的感受吧。说实在话,此BUG你也是前世造了什么孽,偏偏要落在我的手上,这叫天堂有路你不走,地狱无门你闯进来。如果你分到别人的名下还可以威风威风,当然在我的名下也是把我折腾了一番,但是最后,还是让我送你上路了。

解完此问题,有一种神鬼莫测,巧夺天工之感。

但是,你牛,你再牛有什么用,还不就是一个小程序员,别人只会觉得人就是把一个数字4改为了数字5,还不是一个没有什么影响力的底层小屌丝。这就是一个工作6年的程序员的心理微妙的变化。怎么办?

一个男人,白天他是那么的潇洒,其实他独自扛着一座大山。

责任,梦想,心胸,抱负,现在的有时候觉得程序员真的不是自己所再向往的,犹记得当年对手机,对软件开发的挚爱,现在已不再。

这就是为什么我好久没有更新技术博客的原因。

看来,我要再次打点行装,告别现在的拥有,去追寻那个新的梦想所在。

后话

又过了几个月,MTK的一个项目过GMS认证,忽然对ro.product.first_api_level有要求:

NOTE:
1. Do not declare the ro.product.first_api_level value at all if the build is the first factory ROM build of the product from July, 2017

————————————————-

Hi Keith,

New device第一版過認證的軟件 do not set ro.product.first_api_level
MR升級版本中 ro.product.first_api_level 值必須設為第一版 approved 軟件 api level一致的值

另外請將 Android.mk內容修改成右圖
partner_gms/apps/WebViewGoogle/Android.mk

这里写图片描述

从这,我们可以看出谷歌也认识到了自己的代码是有问题,已经有相关的规定,在处理此问题了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hfreeman2008

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

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

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

打赏作者

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

抵扣说明:

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

余额充值