Android OTA Upgrade Package Production script detailed (three, packaging)

Source: Internet
Author: User
Tags sha1

This is the main process statement packaged in the Mian function in Ota_from_target_files:

#抽象一个新的临时文件 temp_zip_file = tempfile. Namedtemporaryfile () #创建一个zip包用来进行打包 output_zip = ZipFile. ZipFile (Temp_zip_file, "w", Compression=zipfile. zip_deflated) #判断是差分还是整包 If Options.incremental_source is None:writefullotapackage (Input_zip, output_zip) if OPTI Ons.package_key is none: #判断是否制定了签名的key, if not the default key to sign, about the platform signature problem, the relevant blog post has been designed, please consult the students themselves Options.package_key = OPTIONS. Info_dict.get ("Default_system_dev_certificate", "Build/target/product/security/testkey") Else: #这里是    The series of operations involved in making a differential packet is temporarily skipped.    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 ()
Step two: Make the whole package

The following is part of the code that makes the whole package main function writefullotapackage.

#函数的处理过程是先获得脚本的生成器. The default format is edify. Then get metadata metadata, this data comes as for some environment variables of Android. Then get the device configuration parameters such as the version of the API function. It then determines whether the timestamp is ignored.  def writefullotapackage (Input_zip, Output_zip): # todo:how to determine this?  We don ' t know what version it'll # is installed on top of.  For now, we expect the API just won ' t # very often. #这里引入了一个新的模块edify_generator and abstract a script generator that is used to generate edify scripts.  The script here refers to Updater-script, which installs the script, which is a text file. #edify有两个主要的文件. These files can be found in the Meta-inf/com/google/android folder within the. zip file. ①update-binary-The binary interpreter that is executed when the user chooses to swipe in. zip (typically in recovery mode).  ②updater-script--The installation script, which is a text file. #那么edify是什么呢? Edify is a simple scripting language for installing CyanogenMod and other software from a. zip file. The edify script is not necessarily used to update the firmware. It can be used to replace/Add/Remove specific files, even format partitions.  Typically, the edify script runs when the user chooses "brush write zip" in recovery mode. Script = Edify_generator.  Edifygenerator (3, options.info_dict) #创建一个元数据字典用来封装更行包的相关的系统属性, such as ro.build.fingerprint (System fingerprint).               metadata = {"Post-build": Getbuildprop ("Ro.build.fingerprint", options.info_dict),   "Pre-device": Getbuildprop ("Ro.product.device", # (device used)                                      options.info_dict), "Post-timestamp": Getbuildprop ("RO.BUILD.DATE.UTC", # (System compile time (digital version), no need to modify) options.info_dict),} #获得一些环境变量, encapsulated in devices  In the Pecificparams class, this is a class that encapsulates device-specific attributes, and each of the following device parameters is mentioned before, and is not described here. 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) #下面这段代码我们可以理解为不允许降级, which means that the Assert statement in the script makes the update zip package available only for upgrading older versions. If not OPTIONS.omit_prereq:ts = Getbuildprop ("RO.BUILD.DATE.UTC", options.info_dict) #得到系统编译世界时间 Ts_text = GETBUILDP ROP ("Ro.build.date", options.info_dict) #得到编译日期 script.  Assertolderbuild (ts, ts_text) #下面的Assert语句 that the update zip package can only be used on the same device, that is, the ro.product.device of the target device must be the same as in Update.zip. Appendassertions (script, options.info_dict) #回调函数 for invoking device-related code. When you start the upgradeCall Device_specific. Fullota_assertions ()

  def fullota_assertions (self): "", "called after emitting, the block of assertions at the    top of a full    OTA package.
   implementations can add whatever additional    assertions they like.    "" " Return Self._docall ("Fullota_assertions")

  def _docall (self, function_name, *args, **kwargs): "" "Call the    named function in the Device-specific module, passing
   the given args and Kwargs.  The first argument to the call would be the    DeviceSpecific object itself.  If There is no module, or    the module does not define the function, return the value of the    ' default ' Kwarg (which itself defaults to None).    "" " 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)

The above is just a simple call, but to put it simply, the value of Self.module here is none, before which we did not load the "device_specific" module. There are no relevant module files found under the Build/tools/release tools/directory (note!). You can also refer to the log printed as "Unable to load device-specific module" when making the whole package; Assuming none ")

Next, we get a Recovery_image file object. The specific implementation code is as follows:

Recovery_img = Common. Getbootableimage ("Recovery.img", "recovery.img",
Options.input_tmp, "RECOVERY")

def getbootableimage (name, Prebuilt_name, Unpack_dir, Tree_subdir, Info_dict=none): "" "Return a File  Object (with Name ' name ') with the desired bootable image. Look for it in ' Unpack_dir '/bootable_images under the name ' Prebuilt_name ', otherwise construct it from the source files  In ' unpack_dir '/' Tree_subdir '. "" "  #连接两个文件名地址, such as Os.path.join ("D:\", "join.txt") The result is D:\join.txt, if we have written action, it will generate the corresponding directory under the corresponding file, otherwise there will not be this file exists. Prebuilt_path = Os.path.join (Unpack_dir, "Bootable_images", Prebuilt_name) if Os.path.exists (prebuilt_path): print "us ing prebuilt%s ... "% (Prebuilt_name,) return File.fromlocalfile (name, Prebuilt_path) else:print" Building image F Rom target_files%s ... "% (Tree_subdir,) fs_config =" meta/"+ tree_subdir.lower () +" _filesystem_config.txt "#将创建的文件对象封 Loaded in the file class returned, here we refer to the file source code, we can find that the file class is just an abstraction of the files, specifically also encapsulates the write and read operation return file (name, Buildbootableimage (Os.path.join ( Unpack_dir, Tree_subdir), Os.path.join (unpack_dir, Fs_config), info_dict)) 

The following paste the specific function in file, we first see the class's entry function has a parameter data, then the file object returned above the second parameter is data, can be understood as the input stream:

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"],< c20/> ". Jar": ["Imgdiff", "-Z"],    ". apk": ["Imgdiff", "-Z"],    ". img": "Imgdiff",    }

def buildbootableimage (SourceDir, Fs_config_file, Info_dict=none): "" Take a kernel, cmdline, and RAMDisk directory from  The input (in ' SourceDir '), and turn them to a boot image.  Return the image data, or None if SourceDir does not appear to contains files for building the requested image. "" "   #作为access () the mode parameter to test if the path exists. 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): #使用mkbootfs工具 (Mkbootfs tool is compiled after the Android source code, in the source directory/out/host/linux-x86/bin automatically generated) create RAMDisk 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) #fileno () is used to obtain the file descriptor used by the stream specified by the parameter stream, while Mkbootfs and MinigziP is the MKBOOTFS and Minigzip tool described by the MKBOOTFS and Minigzip variables to generate a cpio of ramdisk.img in the format.  The source code for both tools Mkbootfs and Minigzip is located in the System/core/cpio and External/zlib directories respectively. P2 = Run (["Minigzip"], Stdin=p1.stdout, Stdout=ramdisk_img.file.fileno ()) p2.wait () p1.wait () Assert P1.retur Ncode = = 0, "Mkbootfs of%s RAMDisk failed"% (TargetName,) assert P2.returncode = = 0, "Minigzip of%s RAMDisk failed"% (TargetName,) #调用Android给的命令行文件mkbootimg (out/host/linux-x86/bin/) to package 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 O S.access (FN, os. F_OK): Cmd.append ("--pagesize") cmd.append (Open (FN). Read (). Rstrip ("\ n")) args = Info_dict.get ("Mkbootimg_args", Non e) if args and ARGs.strip (): Cmd.extend (Args.split ()) #wschen 2013-06-06 for firmware version in bootimage header and limit max length To bytes fn = os.path.join (sourcedir, "board") if Os.access (FN, os. F_OK): Cmd.append ("--board") cmd.append (Open (FN). Read (). Rstrip ("\ n") [: +]) # cmd.extend (["--ramdisk", RAMDISK_IMG.N ame,# "--output", Img.name]) cmd.extend (["--ramdisk", Os.path.join (SourceDir, "RAMDisk"), "--ou Tput ", img.name]) p = Run (cmd, stdout=subprocess. PIPE) p.communicate () assert P.returncode = = 0, "Mkbootimg of%s image failed"% (Os.path.basename (sourcedir),) I Mg.seek (OS. Seek_set, 0) data = Img.read () ramdisk_img.close () Img.close () return data
The above is the use of Android command line file packaging basic process, in fact, I understand is not very thorough, but also refer to some online information, if there is doubt, welcome correction, discussion.












Android OTA Upgrade Package Production script detailed (three, packaging)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.