1 # Copyright (C) 2010 The Android Open Source Project 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 15 import sha 16 import re 17 18 import common 19 20 def FindRadio(zipfile): 21 matches = [] 22 for name in zipfile.namelist(): 23 if re.match(r"^RADIO/radio[.](.+[.])?img$", name): 24 matches.append(name) 25 if len(matches) > 1: 26 raise ValueError("multiple radio images in target-files zip!") 27 if matches: 28 print "using %s as radio.img" % (matches[0],) 29 return zipfile.read(matches[0]) 30 else: 31 return None 32 33 def FullOTA_InstallEnd(info): 34 try: 35 bootloader_img = info.input_zip.read("RADIO/bootloader.img") 36 except KeyError: 37 print "no bootloader.img in target_files; skipping install" 38 else: 39 common.ZipWriteStr(info.output_zip, "bootloader.img", bootloader_img) 40 info.script.Print("Writing bootloader...") 41 info.script.WriteRawImage("/bootloader", "bootloader.img") 42 43 radio_img = FindRadio(info.input_zip) 44 if not radio_img: 45 print "no radio.img in target_files; skipping install" 46 else: 47 common.ZipWriteStr(info.output_zip, "radio.img", radio_img) 48 info.script.Print("Writing radio...") 49 info.script.WriteRawImage("/radio", "radio.img") 50 51 def IncrementalOTA_VerifyEnd(info): 52 target_radio_img = FindRadio(info.target_zip) 53 source_radio_img = FindRadio(info.source_zip) 54 if not target_radio_img or not source_radio_img: return 55 if source_radio_img != target_radio_img: 56 info.script.CacheFreeSpaceCheck(len(source_radio_img)) 57 radio_type, radio_device = common.GetTypeAndDevice("/radio", info.info_dict) 58 info.script.PatchCheck("%s:%s:%d:%s:%d:%s" % ( 59 radio_type, radio_device, 60 len(source_radio_img), sha.sha(source_radio_img).hexdigest(), 61 len(target_radio_img), sha.sha(target_radio_img).hexdigest())) 62 63 def IncrementalOTA_InstallEnd(info): 64 try: 65 target_bootloader_img = info.target_zip.read("RADIO/bootloader.img") 66 try: 67 source_bootloader_img = info.source_zip.read("RADIO/bootloader.img") 68 except KeyError: 69 source_bootloader_img = None 70 71 if source_bootloader_img == target_bootloader_img: 72 print "bootloader unchanged; skipping" 73 else: 74 common.ZipWriteStr(info.output_zip, "bootloader.img", target_bootloader_img) 75 info.script.Print("Writing bootloader...") 76 info.script.WriteRawImage("/bootloader", "bootloader.img") 77 78 except KeyError: 79 print "no bootloader.img in target target_files; skipping install" 80 81 82 tf = FindRadio(info.target_zip) 83 if not tf: 84 # failed to read TARGET radio image: don't include any radio in update. 85 print "no radio.img in target target_files; skipping install" 86 else: 87 tf = common.File("radio.img", tf) 88 89 sf = FindRadio(info.source_zip) 90 if not sf: 91 # failed to read SOURCE radio image: include the whole target 92 # radio image. 93 tf.AddToZip(info.output_zip) 94 info.script.Print("Writing radio...") 95 info.script.WriteRawImage("/radio", tf.name) 96 else: 97 sf = common.File("radio.img", sf) 98 99 if tf.sha1 == sf.sha1: 100 print "radio image unchanged; skipping" 101 else: 102 diff = common.Difference(tf, sf) 103 common.ComputeDifferences([diff]) 104 _, _, d = diff.GetPatch() 105 if d is None or len(d) > tf.size * common.OPTIONS.patch_threshold: 106 # computing difference failed, or difference is nearly as 107 # big as the target: simply send the target. 108 tf.AddToZip(info.output_zip) 109 info.script.Print("Writing radio...") 110 info.script.WriteRawImage("radio", tf.name) 111 else: 112 common.ZipWriteStr(info.output_zip, "radio.img.p", d) 113 info.script.Print("Patching radio...") 114 radio_type, radio_device = common.GetTypeAndDevice( 115 "/radio", info.info_dict) 116 info.script.ApplyPatch( 117 "%s:%s:%d:%s:%d:%s" % (radio_type, radio_device, 118 sf.size, sf.sha1, tf.size, tf.sha1), 119 "-", tf.size, tf.sha1, sf.sha1, "radio.img.p") 120