blob: 1dcc8071217e40a6d3086891d9b596c6d368cd40
1 | # Copyright (C) 2012 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 | """Emit extra commands needed for Group during OTA installation |
16 | (installing the bootloader).""" |
17 | |
18 | import os |
19 | import tempfile |
20 | import struct |
21 | import common |
22 | import sparse_img |
23 | import add_img_to_target_files |
24 | |
25 | def SetBootloaderEnv(script, name, val): |
26 | """Set bootloader env name with val.""" |
27 | script.AppendExtra('set_bootloader_env("%s", "%s");' % (name, val)) |
28 | |
29 | def GetBuildProp(prop, info_dict): |
30 | """Return the fingerprint of the build of a given target-files info_dict.""" |
31 | try: |
32 | return info_dict.get("build.prop", {})[prop] |
33 | except KeyError: |
34 | raise common.ExternalError("couldn't find %s in build.prop" % (prop,)) |
35 | |
36 | def HasTargetImage(target_files_zip, image_path): |
37 | try: |
38 | target_files_zip.getinfo(image_path) |
39 | return True |
40 | except KeyError: |
41 | return False |
42 | |
43 | def BuildExt4(name, input_dir, info_dict, block_list=None): |
44 | """Build the (sparse) vendor image and return the name of a temp |
45 | file containing it.""" |
46 | return add_img_to_target_files.CreateImage(input_dir, info_dict, name, block_list=block_list) |
47 | |
48 | def GetImage(which, tmpdir, info_dict): |
49 | # Return an image object (suitable for passing to BlockImageDiff) |
50 | # for the 'which' partition (most be "system" or "vendor"). If a |
51 | # prebuilt image and file map are found in tmpdir they are used, |
52 | # otherwise they are reconstructed from the individual files. |
53 | |
54 | path = os.path.join(tmpdir, "IMAGES", which + ".img") |
55 | mappath = os.path.join(tmpdir, "IMAGES", which + ".map") |
56 | if os.path.exists(path) and os.path.exists(mappath): |
57 | print "using %s.img from target-files" % (which,) |
58 | # This is a 'new' target-files, which already has the image in it. |
59 | else: |
60 | print "building %s.img from target-files" % (which,) |
61 | # This is an 'old' target-files, which does not contain images |
62 | # already built. Build them. |
63 | mappath = tempfile.mkstemp()[1] |
64 | common.OPTIONS.tempfiles.append(mappath) |
65 | path = BuildExt4(which, tmpdir, info_dict, block_list = mappath) |
66 | |
67 | return sparse_img.SparseImage(path, mappath) |
68 | |
69 | def BuildCustomerImage(info): |
70 | print "amlogic extensions:BuildCustomerImage" |
71 | if info.info_dict.get("update_user_parts") == "true" : |
72 | partsList = info.info_dict.get("user_parts_list"); |
73 | for list_i in partsList.split(' '): |
74 | tmp_tgt = GetImage(list_i, info.input_tmp, info.info_dict) |
75 | tmp_tgt.ResetFileMap() |
76 | tmp_diff = common.BlockDifference(list_i, tmp_tgt, src = None) |
77 | tmp_diff.WriteScript(info.script,info.output_zip) |
78 | |
79 | def BuildCustomerIncrementalImage(info, *par, **dictarg): |
80 | print "amlogic extensions:BuildCustomerIncrementalImage" |
81 | fun = [] |
82 | for pp in par: |
83 | fun.append(pp) |
84 | if info.info_dict.get("update_user_parts") == "true" : |
85 | partsList = info.info_dict.get("user_parts_list"); |
86 | for list_i in partsList.split(' '): |
87 | if HasTargetImage(info.source_zip, list_i.upper() + "/"): |
88 | tmp_diff = fun[0](list_i, info.source_zip, info.target_zip, info.output_zip) |
89 | recovery_mount_options = common.OPTIONS.info_dict.get("recovery_mount_options") |
90 | info.script.Mount("/"+list_i, recovery_mount_options) |
91 | so_far = tmp_diff.EmitVerification(info.script) |
92 | size = [] |
93 | if tmp_diff.patch_list: |
94 | size.append(tmp_diff.largest_source_size) |
95 | tmp_diff.RemoveUnneededFiles(info.script) |
96 | total_patch_size = 1.0 + tmp_diff.TotalPatchSize() |
97 | total_patch_size += tmp_diff.TotalPatchSize() |
98 | tmp_diff.EmitPatches(info.script, total_patch_size, 0) |
99 | tmp_items = fun[1](list_i, "META/" + list_i + "_filesystem_config.txt") |
100 | |
101 | fun[2](tmp_items, info.target_zip, None) |
102 | temp_script = info.script.MakeTemporary() |
103 | tmp_items.GetMetadata(info.target_zip) |
104 | tmp_items.Get(list_i).SetPermissions(temp_script) |
105 | fun[2](tmp_items, info.source_zip, None) |
106 | if tmp_diff and tmp_diff.verbatim_targets: |
107 | info.script.Print("Unpacking new files...") |
108 | info.script.UnpackPackageDir(list_i, "/" + list_i) |
109 | |
110 | tmp_diff.EmitRenames(info.script) |
111 | if common.OPTIONS.verify and tmp_diff: |
112 | info.script.Print("Remounting and verifying partition files...") |
113 | info.script.Unmount("/" + list_i) |
114 | info.script.Mount("/" + list_i) |
115 | tmp_diff.EmitExplicitTargetVerification(info.script) |
116 | |
117 | |
118 | def FullOTA_Assertions(info): |
119 | print "amlogic extensions:FullOTA_Assertions" |
120 | |
121 | def FullOTA_InstallBegin(info): |
122 | print "amlogic extensions:FullOTA_InstallBegin" |
123 | platform = GetBuildProp("ro.board.platform", info.info_dict) |
124 | print "ro.board.platform: %s" % (platform) |
125 | if "meson3" in platform: |
126 | SetBootloaderEnv(info.script, "upgrade_step", "0") |
127 | elif "meson6" in platform: |
128 | SetBootloaderEnv(info.script, "upgrade_step", "0") |
129 | else: |
130 | SetBootloaderEnv(info.script, "upgrade_step", "3") |
131 | |
132 | def FullOTA_InstallEnd(info): |
133 | print "amlogic extensions:FullOTA_InstallEnd" |
134 | bootloader_img_exist = 0 |
135 | try: |
136 | bootloader_img_info = info.input_zip.getinfo("BOOTLOADER/bootloader") |
137 | bootloader_img_exist = 1 |
138 | bootloader_img = common.File("bootloader.img", info.input_zip.read("BOOTLOADER/bootloader")); |
139 | except KeyError: |
140 | print 'WARNING: No BOOTLOADER found' |
141 | |
142 | if bootloader_img_exist: |
143 | common.CheckSize(bootloader_img.data, "bootloader.img", info.info_dict) |
144 | common.ZipWriteStr(info.output_zip, "bootloader.img", bootloader_img.data) |
145 | info.script.WriteRawImage("/bootloader", "bootloader.img") |
146 | SetBootloaderEnv(info.script, "upgrade_step", "1") |
147 | else: |
148 | SetBootloaderEnv(info.script, "upgrade_step", "1") |
149 | |
150 | SetBootloaderEnv(info.script, "force_auto_update", "false") |
151 | |
152 | |
153 | def IncrementalOTA_VerifyBegin(info): |
154 | print "amlogic extensions:IncrementalOTA_VerifyBegin" |
155 | |
156 | def IncrementalOTA_VerifyEnd(info): |
157 | print "amlogic extensions:IncrementalOTA_VerifyEnd" |
158 | |
159 | def IncrementalOTA_InstallBegin(info): |
160 | platform = GetBuildProp("ro.board.platform", info.info_dict) |
161 | print "ro.board.platform: %s" % (platform) |
162 | if "meson3" in platform: |
163 | SetBootloaderEnv(info.script, "upgrade_step", "0") |
164 | elif "meson6" in platform: |
165 | SetBootloaderEnv(info.script, "upgrade_step", "0") |
166 | else: |
167 | SetBootloaderEnv(info.script, "upgrade_step", "3") |
168 | print "amlogic extensions:IncrementalOTA_InstallBegin" |
169 | |
170 | def IncrementalOTA_ImageCheck(info, name): |
171 | source_image = False; target_image = False; updating_image = False; |
172 | |
173 | image_path = name.upper() + "/" + name |
174 | image_name = name + ".img" |
175 | |
176 | if HasTargetImage(info.source_zip, image_path): |
177 | source_image = common.File(image_name, info.source_zip.read(image_path)); |
178 | |
179 | if HasTargetImage(info.target_zip, image_path): |
180 | target_image = common.File(image_name, info.target_zip.read(image_path)); |
181 | |
182 | if target_image: |
183 | if source_image: |
184 | updating_image = (source_image.data != target_image.data); |
185 | else: |
186 | updating_image = 1; |
187 | |
188 | if updating_image: |
189 | message_process = "install " + name + " image..." |
190 | info.script.Print(message_process); |
191 | common.ZipWriteStr(info.output_zip, image_name, target_image.data) |
192 | if name == "dtb": |
193 | info.script.WriteDtbImage(image_name) |
194 | else: |
195 | info.script.WriteRawImage("/" + name, image_name) |
196 | |
197 | if name == "bootloader": |
198 | if updating_image: |
199 | SetBootloaderEnv(info.script, "upgrade_step", "1") |
200 | else: |
201 | SetBootloaderEnv(info.script, "upgrade_step", "2") |
202 | |
203 | |
204 | def IncrementalOTA_InstallEnd(info): |
205 | print "amlogic extensions:IncrementalOTA_InstallEnd" |
206 | IncrementalOTA_ImageCheck(info, "logo"); |
207 | IncrementalOTA_ImageCheck(info, "dtb"); |
208 | IncrementalOTA_ImageCheck(info, "bootloader"); |
209 |