Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1385314
  • 博文数量: 478
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4833
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-28 11:12
文章分类

全部博文(478)

文章存档

2019年(1)

2018年(27)

2017年(21)

2016年(171)

2015年(258)

我的朋友

分类: Android平台

2016-09-01 15:02:42

设计细节

(一) 文件权限

META/filesystem_config.txt

system 0 0 755

system/fonts 0 0 755

system/fonts/DroidSans-Bold.ttf 0 0 644

system/fonts/DroidSansDevanagari-Regular.ttf 0 0 644

system/fonts/AndroidClock.ttf 0 0 644

system/fonts/DroidSerif-Bold.ttf 0 0 644

system/fonts/Roboto-Bold.ttf 0 0 644

system/fonts/Lohit-Kannada.ttf 0 0 644

system/fonts/RobotoCondensed-Regular.ttf 0 0 644

system/fonts/DroidSerif-Regular.ttf 0 0 644

system/fonts/DroidSerif-Italic.ttf 0 0 644

system/fonts/Lohit-Telugu.ttf 0 0 644

……


该文件由fs_config工具生成。

升级命令set_perm_recursive能够递归设置目录下的所有文件权限,利用它能够提高效率(至少减少了升级脚本的行数)。这里的思想是寻找目录下最常见的权限设置,先通过set_perm_recursive设置,然后处理例外的情形。

在遍历目录时不处理符号链接,其权限都是root、root、777。

在增量升级的时候,权限设置会全部重新做一遍。

(二) 增量算法

  • 构建文件字典(路径->File):source_data、target_data
  • 对source_data的文件,
    • 构建path:matching_file_cache
    • 如果目标文件集中没有路径相同文件,增加file、sha1映射
  • 对每个target_data中的文件
    • 在matching_file_cache寻找匹配文件,
      • 如果找到path匹配,返回之
      • 如果update_rename_support为False,返回None
      • 如果文件小于1K,返回None
      • 如果sha1匹配,并且没有绑定,返回之
      • 如果file(文件名)匹配,并且没有重命名绑定,返回之
      • 返回None
    • 如果找到匹配,但是路径不一样,加入到重命名组renames(字典:源文件路径->目标File),增加重命名绑定
    • 如果没有找到匹配,加入到覆盖组:verbatim_targets(二元组:目标文件名,文件大小)
    • 如果找到匹配,但是sha1不一样,加入到差异组:diffs(数组:Difference)
    • 如果找到匹配,并且sha1一样,直接pass
  • 计算差异组的差异文件
  • 对每个差异组文件
    • 如果差异文件大小大于目标文件大小的一定比例(patch_threshold),移动到覆盖组
    • 否则,移动到补丁组:patch_list(五元组:源文件名,目标文件File,源文件File,目标文件大小,差异文件大小),更新最大源文件大小:largest_source_size
  • 升级顺序
    • 补丁组
    • 覆盖组
    • 重命名组

从目标文件的角度总结一下:

  • 如果有path匹配
    • 如果sha1不一样,差异组
      • 如果差异太大,覆盖组
      • 否则补丁组
    • 否则,不加入任何组
  • 如果有sha1匹配,重命名组
  • 如果file匹配,重命名组,同时加入差异组
    • 如果差异太大,覆盖组
    • 否则补丁组
  • 如果没有匹配,覆盖组

加入覆盖组,目标文件输出到zip,加入补丁组,差异文件输出到zip。

如果同时在补丁组和重命名组,先做补丁,再重命名。

(三) recovery升级

Recovery升级是在正常升级完成之后才执行的,目的是保证至少有一个可用系统存在。

Recovery的升级文件是recovery分区相对与boot分区的补丁文件。通过打补丁的方式升级,因为这两个分区(或者img文件)包含很多相同内容,所以这种方式升级可以减少升级包的大小。

在主系统init.rc中,有启动recovery升级的服务定义:

service flash_recovery /system/etc/install-recovery.sh

class main

oneshot


该shell脚本在函数MakeRecoveryPatch中生成,内容为:

#!/system/bin/sh

if ! applypatch -c %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s; then

log -t recovery "Installing new recovery image"

applypatch %(bonus_args)s %(boot_type)s:%(boot_device)s:%(boot_size)d:%(boot_sha1)s %(recovery_type)s:%(recovery_device)s %(recovery_sha1)s %(recovery_size)d %(boot_sha1)s:/system/recovery-from-boot.p

else

log -t recovery "Recovery image already installed"

fi


(四) 符号链接

符号链接收集在二元数组(链接目标名,链接名)中,创建链接时以链接目标分组,同时创建到同一个目标的多个链接。

(五) 升级进度

升级进度有两个层次的控制,show_progress(frac, dur)控制进度在dur秒内增加frac。如果dur为0,那么由set_progress(frac)在上一个show_progress划定的块里面更新进度。

全量更新:

ShowProgress(0.5, 0) —— 解压system、recovery

ShowProgress(0.2, 0) —— 设置文件权限

ShowProgress(0.2, 10) —— 更新boot分区

ShowProgress(0.1, 0) —— 其他

增量更新:

ShowProgress(0.1, 0) —— 校验文件sha1,删除文件

SetProgress(so_far / total_verify_size)

ShowProgress(0.8, 0) —— 打补丁

SetProgress(so_far / total_patch_size)

ShowProgress(0.1, 10) —— 创建符号链接,重命名文件

(六) 签名

密钥来源:

  • -k (OPTIONS.package_key)
  • META/misc_info.txt(OPTIONS.info_dict[“default_system_dev_certificate”])
  • “build/target/product/security/testkey”

公钥扩展名: .x509.pem

私钥扩展名: .pk8

签名程序: signapk.jar -w <公钥> <私钥> <输入文件> <输出文件>

阅读(1129) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~