http://blog.csdn.net/huangyabin001/article/details/43792631
这是在ota_from_target_files中mian函数中打包的主要流程语句:
[python] view plain copy
-
-
temp_zip_file = tempfile.NamedTemporaryFile()
-
-
output_zip = zipfile.ZipFile(temp_zip_file, "w",
-
compression=zipfile.ZIP_DEFLATED)
-
-
if OPTIONS.incremental_source is None:
-
WriteFullOTAPackage(input_zip, output_zip)
-
if OPTIONS.package_key is None:
-
-
OPTIONS.package_key = OPTIONS.info_dict.get(
-
"default_system_dev_certificate",
-
"build/target/product/security/testkey")
-
else:
-
-
print "unzipping source target-files..."
-
OPTIONS.source_tmp, source_zip = common.UnzipTemp(OPTIONS.incremental_source)
-
OPTIONS.target_info_dict = OPTIONS.info_dict
-
OPTIONS.source_info_dict = common.LoadInfoDict(source_zip)
-
if OPTIONS.package_key is None:
-
OPTIONS.package_key = OPTIONS.source_info_dict.get(
-
"default_system_dev_certificate",
-
"build/target/product/security/testkey")
-
if OPTIONS.verbose:
-
print "--- source info ---"
-
common.DumpInfoDict(OPTIONS.source_info_dict)
-
WriteIncrementalOTAPackage(input_zip, source_zip, output_zip)
-
-
output_zip.close()
第二步:制作整包
下面是制作整包主函数WriteFullOTAPackage中的部分代码。
-
-
def WriteFullOTAPackage(input_zip, output_zip):
-
-
-
-
-
-
-
script = edify_generator.EdifyGenerator(3, OPTIONS.info_dict)
-
-
metadata = {"post-build": GetBuildProp("ro.build.fingerprint",
-
OPTIONS.info_dict),
-
"pre-device": GetBuildProp("ro.product.device",
-
OPTIONS.info_dict),
-
"post-timestamp": GetBuildProp("ro.build.date.utc",
-
OPTIONS.info_dict),
-
}
-
-
device_specific = common.DeviceSpecificParams(
-
input_zip=input_zip,
-
input_version=OPTIONS.info_dict["recovery_api_version"],
-
output_zip=output_zip,
-
script=script,
-
input_tmp=OPTIONS.input_tmp,
-
metadata=metadata,
-
info_dict=OPTIONS.info_dict)
-
-
if not OPTIONS.omit_prereq:
-
ts = GetBuildProp("ro.build.date.utc", OPTIONS.info_dict)
-
ts_text = GetBuildProp("ro.build.date", OPTIONS.info_dict)
-
script.AssertOlderBuild(ts, ts_text)
-
-
AppendAssertions(script, OPTIONS.info_dict)
-
-
device_specific.FullOTA_Assertions()
-
def FullOTA_Assertions(self):
-
-
-
-
return self._DoCall("FullOTA_Assertions")
-
def _DoCall(self, function_name, *args, **kwargs):
-
-
-
-
-
-
if self.module is None or not hasattr(self.module, function_name):
-
return kwargs.get("default", None)
-
return getattr(self.module, function_name)(*((self,) + args), **kwargs)
上面只是很简单的调用,不过也简单的说一下,这里self.module的值为None,在此之前我们并未没有载入“device_specific”模块。在build/tools/release tools/目录下面也没有找到相关模块文件(注! 也可参考在制作整包时所打印的log如“unable to load device-specific module; assuming none”)
接着,我们得到一个recovery_image的文件对象。具体实现的代码如下:
recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
OPTIONS.input_tmp, "RECOVERY")
-
def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir,
-
info_dict=None):
-
-
-
-
-
-
prebuilt_path = os.path.join(unpack_dir, "BOOTABLE_IMAGES", prebuilt_name)
-
if os.path.exists(prebuilt_path):
-
print "using prebuilt %s..." % (prebuilt_name,)
-
return File.FromLocalFile(name, prebuilt_path)
-
else:
-
print "building image from target_files %s..." % (tree_subdir,)
-
fs_config = "META/" + tree_subdir.lower() + "_filesystem_config.txt"
-
-
return File(name, BuildBootableImage(os.path.join(unpack_dir, tree_subdir),
-
os.path.join(unpack_dir, fs_config),
-
info_dict))
下面贴出File中具体函数,首先我们看到类的入口函数中有一个参数data,那么上面返回的File对象中的第二个参数即为data,可以理解为输入流:
-
class File(object):
-
def __init__(self, name, data):
-
self.name = name
-
self.data = data
-
self.size = len(data)
-
self.sha1 = sha1(data).hexdigest()
-
-
@classmethod
-
def FromLocalFile(cls, name, diskname):
-
f = open(diskname, "rb")
-
data = f.read()
-
f.close()
-
return File(name, data)
-
-
def WriteToTemp(self):
-
t = tempfile.NamedTemporaryFile()
-
t.write(self.data)
-
t.flush()
-
return t
-
-
def AddToZip(self, z):
-
ZipWriteStr(z, self.name, self.data)
-
-
DIFF_PROGRAM_BY_EXT = {
-
".gz" : "imgdiff",
-
".zip" : ["imgdiff", "-z"],
-
".jar" : ["imgdiff", "-z"],
-
".apk" : ["imgdiff", "-z"],
-
".img" : "imgdiff",
-
}
-
def BuildBootableImage(sourcedir, fs_config_file, info_dict=None):
-
-
-
-
-
-
if (not os.access(os.path.join(sourcedir, "RAMDISK"), os.F_OK) or
-
not os.access(os.path.join(sourcedir, "kernel"), os.F_OK)):
-
return None
-
-
if info_dict is None:
-
info_dict = OPTIONS.info_dict
-
-
-
ramdisk_img = tempfile.NamedTemporaryFile()
-
img = tempfile.NamedTemporaryFile()
-
-
if os.access(fs_config_file, os.F_OK):
-
-
cmd = ["mkbootfs", "-f", fs_config_file, os.path.join(sourcedir, "RAMDISK")]
-
else:
-
cmd = ["mkbootfs", os.path.join(sourcedir, "RAMDISK")]
-
p1 = Run(cmd, stdout=subprocess.PIPE)
-
-
p2 = Run(["minigzip"],
-
stdin=p1.stdout, stdout=ramdisk_img.file.fileno())
-
-
p2.wait()
-
p1.wait()
-
assert p1.returncode == 0, "mkbootfs of %s ramdisk failed" % (targetname,)
-
assert p2.returncode == 0, "minigzip of %s ramdisk failed" % (targetname,)
-
-
cmd = ["mkbootimg", "--kernel", os.path.join(sourcedir, "kernel")]
-
-
fn = os.path.join(sourcedir, "cmdline")
-
if os.access(fn, os.F_OK):
-
cmd.append("--cmdline")
-
cmd.append(open(fn).read().rstrip("\n"))
-
-
fn = os.path.join(sourcedir, "base")
-
if os.access(fn, os.F_OK):
-
cmd.append("--base")
-
cmd.append(open(fn).read().rstrip("\n"))
-
-
fn = os.path.join(sourcedir, "pagesize")
-
if os.access(fn, os.F_OK):
-
cmd.append("--pagesize")
-
cmd.append(open(fn).read().rstrip("\n"))
-
-
args = info_dict.get("mkbootimg_args", None)
-
if args and args.strip():
-
cmd.extend(args.split())
-
-
-
fn = os.path.join(sourcedir, "board")
-
if os.access(fn, os.F_OK):
-
cmd.append("--board")
-
cmd.append(open(fn).read().rstrip("\n")[:15])
-
-
-
-
-
cmd.extend(["--ramdisk", os.path.join(sourcedir, "ramdisk"),
-
"--output", img.name])
-
-
p = Run(cmd, stdout=subprocess.PIPE)
-
p.communicate()
-
assert p.returncode == 0, "mkbootimg of %s image failed" % (
-
os.path.basename(sourcedir),)
-
-
img.seek(os.SEEK_SET, 0)
-
data = img.read()
-
-
ramdisk_img.close()
-
img.close()
-
-
return data
上面是使用Android命令行文件打包基本流程,其实本人理解的也不是很透彻,也参考了一些网上的资料,如果有疑问,欢迎指正,讨论。
阅读(1491) | 评论(0) | 转发(0) |