First step: Unzip (ota_from_target_files)
Print "unzipping target target-files ..." options.input_tmp, input_zip = Common. Unziptemp (Args[0])
The above code is the entry to start the decompression
def unziptemp (filename, Pattern=none): "" "Unzip the given archive into a temporary directory and return the name. If filename is of the form "Foo.zip+bar.zip", unzip Foo.zip to a temp dir, then unzip Bar.zip into That_dir/bootable_im AGES. Returns (TempDir, zipobj) where Zipobj is a zipfile. ZipFile (of the main file), open for reading. "" "# This function is used to create a temporary folder, the parameter refers to the temporary folder prefix, the return value TMP is the absolute path of the temporary folder, and assigned to the options of the Tempfiles property TMP = Tempfile.mkdtemp (prefix=" targetfiles-") OPTIONS.tempfiles.append (TMP) def unzip_to_dir (filename, dirname): #这里设置了一个变量名cmd的数组, It contains commands and parameters that need to be executed, namely "Unzip-o-Q filename-d dirname" cmd = ["Unzip", "-O", "-Q", filename, "-D", dirname] if PA Ttern is not None:cmd.append (pattern) #这里调用了Run方法 p = Run (cmd, stdout=subprocess. PIPE) "" "Popen.communicate (Input=none) interacts with the child process. Send data to stdin, or read data from stdout and stderr. Optional parameter input Specifies the parameters that are sent to the child process. Communicate () returns a tuple: (Stdoutdata,stderrdata). Note: If you want to send data to it through the process's stdin, the parameter stdin must be set to pipe when the Popen object is created. Similarly, if you want to obtain data from stdout and stderr, you must use the StDout and stderr are set to pipe. "" "P.communicate () if p.returncode! = 0:raise Externalerror (" Failed to unzip input target-files \ "%s\" "% (filename,)) #match: Matches the regular expression only from the beginning of the string, the match returns the matching item successfully, otherwise none is returned; m = Re.match (r "^ (. *[. Zip) \+ (. *[.) Zip) $ ", filename, re. IGNORECASE) #如果这里加上并执行 "" "" "Print M" "statement, the result is" "" "[Target.zip]" "" "If M:unzip_to_dir (M.group (1), TMP) Unzip_to_dir (M.G Roup (2), Os.path.join (tmp, "bootable_images")) filename = M.group (1) Else: #这里执行解压操作, the value of the file name is "Target.zip", and the value of TEM is "/tmp /targetfiles-fex9ah "and calls the Upzip_to_dir method to perform the extract command Unzip_to_dir (filename, tmp) #这里返回临时路径和存储了zipfile内容的变量 # Here the second parameter with R means to read the zip file, W is to create a ZIP file return tmp, ZipFile. ZipFile (filename, "R")#这里开启新的进程来执行解压缩的命令
def Run (args, **kwargs): "" " Create and return a subprocess. Popen object, printing the command line in the terminal if-v was specified. "" " If Options.verbose: print " running:", "". Join (args) "" " here Call the Popen module to open a new process for executing system commands, which can be used to control the process, Copying the returned results to a variable is easier to handle. The value of args is actually a list that specifies the process's executable file and its parameters. "" " return subprocess. Popen (args, **kwargs)
Then go back to the main function to process the results returned by the decompression
options.target_tmp = options.input_tmp options.info_dict = Common. Loadinfodict (Input_zip)
The second step is to parse the information in Meta/misc_info.txt and Imagesizes.txt in Target.zip, such as:
This is the content in Misc_info.txt:
recovery_api_version=3fstab_version=2tool_extensions=out/target/product/wt98360/obj/custgen/config/. /commondefault_system_dev_certificate=build/target/product/security/testkeymkbootimg_args=use_set_metadata= 1update_rename_support=1fs_type=ext4system_size=1363148800userdata_size=1152385024cache_size=132120576extfs_ Sparse_flag=-smkyaffs2_extra_flags=-c 2048-s selinux_fc=out/target/product/wt98360/root/file_contexts
The specific code is as follows:
def loadinfodict (Zip): "" "Read and parse the Meta/misc_info.txt key/value pairs from the input target files and return a Dict. "" " #定义一个字典变量用于存储处理后的信息 d = {} try: #这里zip. Read () method to open Meta/misc_info.txt in update.zip and press "\ n" to slice for line in Zip.read ("M Eta/misc_info.txt "). Split (" \ n "): line = Line.strip () #用于移除字符串头尾指定的字符 (default is a space) if not line or Line.startswith (" # "): continue# skips the comment information k, v = line.split ("=", 1) #这里按照第一个 "=" for slicing d[k] = v# encapsulated into a data dictionary except keyerror: # OK if misc_info . txt doesn ' t exist pass # backwards Compatibility:these values used to is in their own # files. Look for them, in case we ' re processing a old # target_files zip. If "mkyaffs2_extra_flags" not in d:try:d["mkyaffs2_extra_flags"] = Zip.read ("Meta/mkyaffs2-extra-flags.txt"). Str IP () except keyerror: # OK if flags don ' t exist pass if "recovery_api_version" not in d:try:d["rec Overy_api_version "] = Zip.read (" Meta/recovery-api-version.txt "). Strip () except KeyError:raise valueerror ("can ' t find recovery API version in input target-files") if "tool_extensions" isn't in D:t ry:d["tool_extensions"] = Zip.read ("Meta/tool-extensions.txt"). Strip () except Keyerror: # OK if extensions D On ' t exist pass if "fstab_version" is not in d:d["fstab_version"] = "1" try:data = Zip.read ("meta/imagesizes.t XT ") for Data.split (" \ n "): If not line:continue name, value = Line.split (" ", 1) if not value: Continue if Name = = "BlockSize": d[name] = value Else:d[name + "_size"] = value except Keyerror: Pass def makeint (key): If key in D:if d[key].endswith (' m '): D[key] = D[key].split ("M") [0] D[ke Y] = Int (D[key], 0) * 1024x768 * 1024x768 Else:d[key] = Int (D[key], 0) makeint ("Recovery_api_version") makeint ("Blo Cksize ") makeint (" System_size ") makeint (" Userdata_size ") makeint (" Cache_size ") makeint (" Recovery_size ") Makeint (" Boot_size ") Makeint (" Fstab_Version ") #wschen 2012-11-07 makeint (" custom_size ") d[" fstab "] = Loadrecoveryfstab (Zip, d[" fstab_version "]) d[" build. Prop "] = Loadbuildprop (Zip) return D
The above code, at the end of the method to parse the partition table and the Build property, then the specific operation process, we have detailed analysis below
The third step, parsing recovery partition information
The version of Fastab_version here is 2, so
def loadrecoveryfstab (Zip, fstab_version):
Class Partition (object):
Pass
Try
data = Zip.read ("Recovery/ramdisk/etc/recovery.fstab") #当前target. zip does not have this file, so there is no explanation here
Except Keyerror:
print ' warning:could not ' find Recovery/ramdisk/etc/recovery.fstab in%s. '% zip
data = ""
if fstab_version = = 1:
D = {}
For line in Data.split ("\ n"):
line = Line.strip ()
If not line or Line.startswith ("#"): Continue
Pieces = Line.split ()
If not (3 <= len (Pieces) <= 4):
Raise ValueError ("Malformed Recovery.fstab line: \"%s\ ""% (line,) ")
p = Partition ()
P.mount_point = Pieces[0]
P.fs_type = pieces[1]
P.device = pieces[2]
P.length = 0
options = None
If Len (Pieces) >= 4:
If Pieces[3].startswith ("/"):
P.device2 = pieces[3]
If Len (Pieces) >= 5:
options = Pieces[4]
Else
P.device2 = None
options = Pieces[3]
Else
P.device2 = None
If options:
options = Options.split (",")
For I in Options:
If I.startswith ("Length="):
p.length = Int (i[7:])
Else
print "%s:unknown option \"%s\ ""% (p.mount_point, i)
D[p.mount_point] = P
elif Fstab_version = = 2:
D = {}
For line in Data.split ("\ n"):
line = Line.strip ()
If not line or Line.startswith ("#"): Continue
Pieces = Line.split ()
If Len (pieces)! = 5:
Raise ValueError ("Malformed Recovery.fstab line: \"%s\ ""% (line,) ")
# Ignore entries that is managed by Vold
options = Pieces[4]
If "voldmanaged=" in Options:continue
# it ' s a good line, parse It
p = Partition ()
P.device = Pieces[0]
P.mount_point = pieces[1]
P.fs_type = pieces[2]
P.device2 = None
P.length = 0
options = Options.split (",")
For I in Options:
If I.startswith ("Length="):
p.length = Int (i[7:])
Else
# Ignore all unknown options in the unified fstab
Continue
D[p.mount_point] = P
Else
Raise ValueError ("Unknown fstab_version: \"%d\ ""% (fstab_version,))
Return D
The fourth step is to parse the System/build.prop property information, save the parsed attribute information as a data dictionary, and return
def loadbuildprop (Zip): try: data = Zip.read ("System/build.prop") except Keyerror: print "Warning: Could not find System/build.prop in%s "% zip data =" " d = {} for line in data.split (" \ n "): line = LINE.S Trip () if not line or Line.startswith ("#"): Continue name, value = Line.split ("=", 1) d[name] = value r Eturn D
Android OTA Upgrade Package Production script detailed (two, unzip)