1.制作ota
make otapackage
自动模式下,执行ota_from_target_files时,
制作升级包的函数会调用edify_generator.py脚本里的函数去自动编写updater-script。而edify_generator.py里的函数和updater-script的语法规则是一一对应的
ota_from_target_files
def WriteFullOTAPackage(input_zip, output_zip):
script.FormatPartition("userdata")
#擦除 userdata 分区。
script.FormatPartition("system")
# 擦除 system分区。
script.Mount("MTD", "system", "/system")
#在脚本中增加语句,安装 system分区到 /system 目录。
script.UnpackPackageDir("recovery", "/system")
script.UnpackPackageDir("system", "/system")
#将recovery以及system中的内容拷贝到 /system目录。其中recovery 目录包含一个patch 以及应用该patch 的脚本。
symlinks = CopySystemFiles(input_zip, output_zip)
script.MakeSymlinks(symlinks)
#从输入 ZIP 包 /system 拷贝文件到输出 ZIP 包 /system。由于这个过程不支持链接文件,所以它将这些文件返回。 。所有的link文件都指向 toolbox
# (如何判断符号链接的? IsSymLink() 判断)
MakeRecoveryPatch(output_zip, recovery_img, boot_img)
# MakeRecoveryPatch 做了两件事:
#1.在输出 ZIP包中生成一个patch: recovery/recovery-from-boot.p(boot.img和 recovery.img的patch), 它最后会位于:system/recovery-from-boot.p
#2.在输出 ZIP包中生成一个脚本:recovery/etc/install-recovery.sh , 它最后会位于system/etc/install-recovery.sh.
Item.GetMetadata(input_zip)
# 从 META/filesystem_config.txt 中获得 system 目录下的各文件权限信息。
Item.Get("system").SetPermissions(script)
# 在脚本中增加语句,设置 system 目录下文件的权限及属主等。
script.WriteRawImage("boot", "boot.img")
#将 boot.img 写到 boot 分区。
script.AddToZip(input_zip, output_zip)
#将前面生成的脚本输出到:META-INF/com/google/android/updater-script (对于edify)
2.执行ota
执行updater-script脚本的时候具体逻辑是指当更新包中版本低于当前手机中的版本时终止安装更新。
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))
Android恢复出厂设置流程分析
1.getActivity().sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));
- 广播接收
public void onReceive(final Context context, final Intent intent)
Thread thr = new Thread("Reboot") {
@Override
public void run() {
try {
RecoverySystem.rebootWipeUserData(context);
bootCommand(context, "--wipe_data\n--locale=" + Locale.getDefault().toString());
//bootCommand : 写入/cache/recovery中
FileWriter command = new FileWriter(COMMAND_FILE);
try {
command.write(arg);
command.write("\n");
} finally {
command.close();
}
// Having written the command file, go ahead and reboot
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
pm.reboot("recovery")
Edify语法简介(Updater-Script)
函数名称: mount
函数语法: mount(fs_type, partition_type, location, mount_point)
参数详解: fs_type-----------------"yaffs2" 或 "ext4"
partition_type----------"MTD" 或 "EMMC"
location-----------------分区(partition) 或 驱动器(device)
mount_poin------------挂载文件系统的目标文件夹(target folder to mount FS)
作用解释: 挂载一个文件系统到指定的挂载点
mount("MTD", "system", "/system");挂载system分区,设置返回指针"/system”
mount("vfat", "/dev/block/mmcblk1p2", "/system")
函数名称: format
函数语法: format(fs_type, partition_type, location)
format("MTD", "system");格式化system分区
函数名称: delete
函数语法: delete(file1, file2, ..., fileN)
函数名称: delete_recursive
函数语法: delete_recursive(dir1, dir2,...,dirN)
参数详解: 字符串,要递归删除的目录
delete_recursive("/data/dalvik-cache");删除文件夹/data/dalvik-cache
函数名称: show_progress
函数语法: show_progress(frac, sec)
参数详解: frac----------------------进度完成数值
Sec----------------------总秒数
函数名称: package_extract_dir
函数语法: package_extract_dir(package_path, destination_path)
参数详解: package_path----------字符串,升级包内要提取的目录
package_extract_dir("system", "/system")
函数名称: symlink
函数语法: symlink(target, src1, src2, ..., srcN)
参数详解: target-------------------字符串,符号链接的目标
srcX ---------------------字符串,要创建的符号链接的目标点
symlink("toolbox", "/system/bin/ps");建立指向toolbox的符号链接/system/bin/ps
函数名称: set_perm
函数语法: set_perm(uid, gid, mode, file1, file2, ..., fileN)
参数详解: uid----------------------用户ID(user id)
Gid----------------------用户组ID(group id)
Mode--------------------权限模式(permission mode)
fileX---------------------要设置许可的文件(file to set permission on)
set_perm(0,2000,0550, "system/etc/init.goldfish.sh");
函数名称: run_program
函数语法: run_program(prog, arg1, .., argN)
参数详解: prog--------------------字符串,要执行的程序
argN--------------------字符串,要执行的程序的运行参数
作用解释: 以指定的参执行程序
函数示例: run_program("/system/xbin/installbusybox.sh");
函数名称: ui_print
函数语法: ui_print(msg1, ..., msgN)