0%

fingerprint介绍

1. fingerprint编译过程

1
2
3
4
5
6
7
8
9
10
PRODUCT_BRAND := SPRD
PRODUCT_DEVICE := --TARGET_DEVICE
PRODUCT_NAME := --TARGET_PRODUCT
# build_id.mk
BUILD_ID :=
TARGET_BUILD_VARIANT:userdebug:user
BUILD_VERSION_TAGS:test-keys release-keys
BF_BUILD_NUMBER := $(USER)$$($(DATE_FROM_FILE) +%m%d%H%M)

BUILD_FINGERPRINT := $(PRODUCT_BRAND)/$(TARGET_PRODUCT)/$(TARGET_DEVICE):$(PLATFORM_VERSION)/$(BUILD_ID)/$(BF_BUILD_NUMBER):$(TARGET_BUILD_VARIANT)/$(BUILD_VERSION_TAGS)

SPRD/sp9832e_1h10_oversea/sp9832e_1h10:9/PPR1.180610.021/liguang.zhang12111501:userdebug/test-keys

fingerprint的变动是跟着BF_BUILD_NUMBER字段变更的, 而BF_BUILD_NUMBER字段只在make时更新, 即执行一次make更新一次.
整编时, 一次编译出所有的img, img中所有的fingerprint都是一样的.

1
2
3
4
5
6
7
8
9
10
11
12
@startuml
start
#HotPink:make;
->system.img\nvendor.img\nproduct.img\nrecovery.img\n;
note right:ro.build.fingerprint\nro.product.build.fingerprint\nro.vendor.build.fingerprint
#pink:pac;
:make productimage;
->product.img;
note right:ro.product.build.fingerprint
:replace pac;
end
@enduml

2. fingerprint用途

2.1. ota升级

差分升级时会校验fingerprint. 升级包中的fingerprint来自ota素材包(target_file)中的system分区的build.prop文件.
src recovery分区的fingerprint来自prop.default
即进到recovery模式下getprop ro.build.fingerprint 与基础版本和目标版本的ro.build.fingerprint值进行比对, 有一个相等则符合要求.

  • prop.default结构:
    ro.build.fingerprint -< 来自system编译过程
    ro.product.build.fingerprint -< 来自product编译过程

如果只make productimage, 则recovery分区的prop.default不会更新.

2.2. system package升级

升级之前data分区保存的old ro.build.fingerprint和升级之后的ro.build.fingerprint作比较, 如果不相同, 为upgrade条件.

2.3. google兼容性测试

相同的ro.build.fingerprint被认为是同一个包, 不再重复测试.

vts测试会同时使用ro.vendor.build.fingerprint

3. fingerprint方案

覆盖property, 会有system分区升级的问题.
不覆盖property, 会有送测问题.

  1. 现有方案, 不做改动
  • google兼容性测试问题
  • 只升级product分区(如果应用放在product分区), 升级完后, product中的应用不会更新
  1. ro.product.build.fingerprint覆盖ro.build.fingerprint
  • 只升级system分区
    fingerprint读的product分区的, 升级结束后, fingerprint没变, 升级完后system中应用不更新
  • 只升级product分区 ok
    升级结束后, fingerprint变动
  • 同时升级system分区和product分区
    product分区如果没变化, 还是有问题.
  1. 不覆盖property, 修改libc, 读取ro.build.fingerprint时, 使用ro.product.build.fingerprint值替换.
  • recovery中使用android:base:GetProperty
  • android上层使用android:base:GetProperty访问
  • native层也可以使用property_get访问
  • shell中对应toolbox, 使用类似android:base:GetProperty访问
  1. 手机开机时, 在初始化ro.build.fingerprint, 即将该ro属性加载到内存中时, 使用ro.product.build.fingerprint值替换

    前提是ro.product.build.fingerprint已经在前面加载到内存中了.

修改init会同时作用到正常开机和recovery子系统, 但因为在recovery子系统中, ro.build.fingerprint在ro.product.build.fingerprint前面, 所以在recovery子系统中ro.build.fingerprint不会被替换掉.

正常开机 init 替换ro.build.fingerprint流程

1
2
3
4
5
6
7
@startuml
start
:set ro.product.build.fingerprint;
note right: read from product.img
:replace ro.build.fingerprint;
end
@enduml

3.1. 小结

综合考虑上述方案, 采用第4个方案修改较小, 副作用也比较小. 上述方案中2/3/4其实是对应的同一种, 仅修改方式不同. 副作用也是相同的.

4. 修改方案提出的要求

考虑下面几种场景:

4.1. google兼容性测试

需要综合考虑cts/gts/vts测试的要求, 重点是vts测试使用ro.vendor.build.fingperint, 如果vendor分区不跟product分区的fingerprint保持一致, 会带来同一个pac包, cts/gts的测试target和vts的测试target不是同一个的问题.

因此需要保证vendor分区的ro.vendor.build.fingperint和product分区的ro.product.build.fingerprint保持一致.

4.2. 对功能影响层面

主要影响ota升级流程和升级结束后应用的更新流程.
需要重点考虑只有某一个分区变动的情况:

4.2.1. 只有product分区变动了

这种情况对应多个product(config)对应同一软件版本的情况.
需要将vendor和product的编译绑到一起(对应4.1中的要求)
可以采用下面流程, 利用编译vendor会先编译product的规则.

1
2
3
4
5
6
7
8
9
10
11
12
@startuml
start
:make;
:pac;
:...;
:remove vendor & product;
note right: delete vendor.img/product.img and its dir in $PRODUCT_OUT
:make vendorimg;
:make productimg;
:repac;
end
@enduml

而对应ota升级流程(recovery中的系统升级), 对差分升级来说, 如果需要差分升级product/vendor, 需要重新制作ota的target-files, 并重新制作ota的差分包.
而对ota整包升级则不受影响

4.2.2. 只有system分区变动

这种情况对应芯片厂商向下游厂商只推送system.img情况. 由于最终的ro.build.fingerprint来自于product分区, 下游厂商需要重新编译vendor.img 和 product.img(或者手动修改vendor和product中的ro.vendor.build.fingperintro.product.build.fingerprint, 目的是要和system.img中的ro.build.fingerprint保持一致), 再重新打包.

对应ota升级(recovery子系统中进行升级的情况), 因底包(system.img/vendor.img/product.img)变动了, 需要重新制作targetfiles素材包和ota差分包, ota整包不用考虑.

4.2.3. 只有vendor分区变动

这种情况对应(4.2.1中)只有product分区变动的情况

5. Requirements

The solution description:
When init initially sets the value of the ro.build.fingerprint property, first check if ro.product.build.fingerprint is empty. If it is not empty, use this value replace the value of ro.build.fingerprint.
At such situation, multiple product partitions (configurations) correspond to the same software version. Usually, only product partition is different.

Need to consider the requirements of the cts/gts/vts test, the focus is on the vts test using ro.vendor.build.fingperint. If ro.vendor.build.fingerprint in vendor partition is not consistent with the fingerprint of the product partition, it will bring the problem of for same pac package, cts/gts test target and the vts test target are not same.

Therefore, need to ensure that the ro.vendor.build.fingperint in vendor partition is consistent with the ro.product.build.fingerprint in product partition.
And for OTA incremental upgrade, should make OTA target-files for all different product and vendor image.