Android系统更新防互刷功能实现与分析

写在前面:

为了帮助理解,这里首先描述一个应用场景。

一个项目有两个版本(一个项目两个版本的原因或许是由于硬件不同导致的,如不同容量电池,不同分辨率摄像头等),在升级的时候很容易将相同项目的两个版本的升级包混淆,因此需要实现两个版本的防互刷功能,那么在该应用场景下需要如何实现呢?

注意,这里肯定会有疑问了,既然一个项目两个版本容易混淆更新包,那么把它作为两个项目来实施不是有效避免这个问题了吗?当然,把一个项目由于不同版本分拆为不同的项目来做当然可以有效的避免更新包混淆的问题,这也是一个比较快捷的方案。因此该博文是在实施一个项目的场景下来开展的。

第一步:了解校验原理

熟悉ota_from_target_files、edify_generator.py或则了解install.c和updater-script脚本执行过程的朋友应该很清楚在更新包安装的一开始会对一些属性信息进行校验,这里贴出部分脚本生成器edify_generator.py的相关的函数:

#校验时间戳

def AssertOlderBuild(self, timestamp, timestamp_text): """Assert that the build on the device is older (or the same as) the given timestamp.""" self.script.append( (‘(!less_than_int(%s, getprop("ro.build.date.utc"))) || ‘ ‘abort("Can\’t install this package (%s) over newer ‘ ‘build (" + getprop("ro.build.date") + ").");’ ) % (timestamp, timestamp_text))

校验时间戳,我们需要理解上面的方法,上面的函数只是生成一条edify语句,实际上在生成的updater-script脚本中,也就是下面这条语句:

(!less_than_int(%s, getprop("ro.build.date.utc")))①||abort("Can’t install this package (%s) over newerbuild (" + getprop("ro.build.date") + ").");②

arg1:timestamp, arg2:timestamp_text//参数1为世界时间,参数2为日期格式

上面的代码告诉我们如果①的值为True则执行下一步,否则执行语句②,语句①对比时间戳大小,语句②为中断语句。也就是说如果当前更新包的打包时间如果比手机Build的时间older,就执行中止语句。

#校验设备信息 def AssertDevice(self, device): """Assert that the device identifier is the given string.""" cmd = (‘getprop("ro.product.device") == "%s" || ‘ ‘abort("This package is for \\"%s\\" devices; ‘ ‘this is a \\"" + getprop("ro.product.device") + "\\".");’ ) % (device, device) self.script.append(cmd)

若更新包中打包的设备信息如果与手机Build中的设备信息不一致就会执行中止语句。

#校验系统指纹

defAssertSomeFingerprint(self, *fp): """Assert that the current system build fingerprint is one of *fp.""" if not fp: raise ValueError("must specify some fingerprints") cmd = ( ‘ ||\n ‘.join([(‘file_getprop("/system/build.prop", ‘ ‘"ro.build.fingerprint") == "%s"’) % i for i in fp]) + ‘ ||\n abort("Package expects build fingerprint of %s; this ‘ ‘device has " + getprop("ro.build.fingerprint") + ".");’ ) % (" or ".join(fp),) self.script.append(cmd)

若更新包中新旧版本的系统指纹与当前手机中的系统指纹不一致就会执行中止语句。

无论是时间戳还是设备信息还是系统指纹都是从build.prop中取值。但是,这里呢,要对fingerprint信息简单介绍一下,fingerprint就是我们常说的系统指纹,我们可以在adb模式下能否通过getprop ro.build.fingerprint的方式进行查看或者参考alps\frameworks\base\core\java\android\os\Build.java下对应的FINGERPRINT的取值方式在代码中进行取值。每个项目的每个版本Fingerprint都不同,按照Google的要求,前后不允许带有空格、空行、断行,字符不超过91个,,

Fingerprint字段定义格式如下:BUILD_FINGERPRINT :=$(PRODUCT_BRAND)/$(TARGET_PRODUCT)/$(TARGET_DEVICE):$(PLATFORM_VERSION)/$(BUILD_ID)/$(BUILD_NUMBER):$(TARGET_BUILD_VARIANT)/$(BUILD_VERSION_TAGS)如:Google/Y100-T00/GoogleY100-T:4.2.2/GoogleY100-T00/CHSC01B001:user/release-keysTCT/TCL_J900T/Camry2_TD:4.2.1/JOP40D/TCL_J900T_V2.0:user/release-keys具体配置请按以下:1.PRODUCT_BRAND为getprop文件中的相关字段:ro.product.brand的信息,全字母大写or首字母大写均可。Eg:Google2.TARGET_PRODUCT为getprop文件中的相关字段:ro.product.name的信息,全字母大写,Eg:Y516-T00。3.TARGET_DEVICE为getprop文件中的相关字段:ro.product.device的信息4.ID为getprop文件中的相关字段:ro.build.id的信息,5.version.incremental为getprop文件中的相关字段:ro.build.version.incremental的信息。要求version.incremental是内部版本号(真实版本号)6.VERSION.RELEASE为getprop文件中的相关字段:ro.build.version.release的信息,一般为Android系统版本号7.TYPE必须是user版本,不能是eng版本。

8.TAGS必须是release-keys,不能是test-keys,(将宏MTK_SIGNATURE_CUSTOMIZATION = yes)。如果该版本带有或者后续将开发OTA升级功能,须使用ota-rel-keys,release-keys,普通版本请使用release-keys。

巨龟千岁,却也平淡无奇;昙花瞬间,却能绚丽无比。

Android系统更新防互刷功能实现与分析

相关文章:

你感兴趣的文章:

标签云: