Merge "Fall back to normal split if imgdiff fails when splitting large apks"
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index 6bca99e..1ef55ff 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -1178,42 +1178,10 @@
def FindTransfers(self):
"""Parse the file_map to generate all the transfers."""
- def AddSplitTransfers(tgt_name, src_name, tgt_ranges, src_ranges,
- style, by_id):
- """Add one or multiple Transfer()s by splitting large files.
-
- For BBOTA v3, we need to stash source blocks for resumable feature.
- However, with the growth of file size and the shrink of the cache
- partition source blocks are too large to be stashed. If a file occupies
- too many blocks, we split it into smaller pieces by getting multiple
- Transfer()s.
-
- The downside is that after splitting, we may increase the package size
- since the split pieces don't align well. According to our experiments,
- 1/8 of the cache size as the per-piece limit appears to be optimal.
- Compared to the fixed 1024-block limit, it reduces the overall package
- size by 30% for volantis, and 20% for angler and bullhead."""
-
- assert style == "diff"
- # Possibly split large files into smaller chunks.
+ def AddSplitTransfers(tgt_name, src_name, tgt_ranges, src_ranges, style,
+ by_id):
+ """Add one or multiple Transfer()s by splitting large files."""
pieces = 0
-
- # Change nothing for small files.
- if (tgt_ranges.size() <= max_blocks_per_transfer and
- src_ranges.size() <= max_blocks_per_transfer):
- Transfer(tgt_name, src_name, tgt_ranges, src_ranges,
- self.tgt.RangeSha1(tgt_ranges), self.src.RangeSha1(src_ranges),
- style, by_id)
- return
-
- if tgt_name.split(".")[-1].lower() in ("apk", "jar", "zip"):
- split_enable = (not self.disable_imgdiff and src_ranges.monotonic and
- tgt_ranges.monotonic)
- if split_enable and (self.tgt.RangeSha1(tgt_ranges) !=
- self.src.RangeSha1(src_ranges)):
- large_apks.append((tgt_name, src_name, tgt_ranges, src_ranges))
- return
-
while (tgt_ranges.size() > max_blocks_per_transfer and
src_ranges.size() > max_blocks_per_transfer):
tgt_split_name = "%s-%d" % (tgt_name, pieces)
@@ -1239,6 +1207,43 @@
self.tgt.RangeSha1(tgt_ranges), self.src.RangeSha1(src_ranges),
style, by_id)
+ def FindZipsAndAddSplitTransfers(tgt_name, src_name, tgt_ranges,
+ src_ranges, style, by_id):
+ """Find all the zip archives and add split transfers for the other files.
+
+ For BBOTA v3, we need to stash source blocks for resumable feature.
+ However, with the growth of file size and the shrink of the cache
+ partition source blocks are too large to be stashed. If a file occupies
+ too many blocks, we split it into smaller pieces by getting multiple
+ Transfer()s.
+
+ The downside is that after splitting, we may increase the package size
+ since the split pieces don't align well. According to our experiments,
+ 1/8 of the cache size as the per-piece limit appears to be optimal.
+ Compared to the fixed 1024-block limit, it reduces the overall package
+ size by 30% for volantis, and 20% for angler and bullhead."""
+
+ assert style == "diff"
+
+ # Change nothing for small files.
+ if (tgt_ranges.size() <= max_blocks_per_transfer and
+ src_ranges.size() <= max_blocks_per_transfer):
+ Transfer(tgt_name, src_name, tgt_ranges, src_ranges,
+ self.tgt.RangeSha1(tgt_ranges), self.src.RangeSha1(src_ranges),
+ style, by_id)
+ return
+
+ if tgt_name.split(".")[-1].lower() in ("apk", "jar", "zip"):
+ split_enable = (not self.disable_imgdiff and src_ranges.monotonic and
+ tgt_ranges.monotonic)
+ if split_enable and (self.tgt.RangeSha1(tgt_ranges) !=
+ self.src.RangeSha1(src_ranges)):
+ large_apks.append((tgt_name, src_name, tgt_ranges, src_ranges))
+ return
+
+ AddSplitTransfers(tgt_name, src_name, tgt_ranges, src_ranges,
+ style, by_id)
+
def AddTransfer(tgt_name, src_name, tgt_ranges, src_ranges, style, by_id,
split=False):
"""Wrapper function for adding a Transfer()."""
@@ -1287,7 +1292,7 @@
assert tgt_changed + tgt_skipped.size() == tgt_size
print('%10d %10d (%6.2f%%) %s' % (tgt_skipped.size(), tgt_size,
tgt_skipped.size() * 100.0 / tgt_size, tgt_name))
- AddSplitTransfers(
+ FindZipsAndAddSplitTransfers(
"%s-skipped" % (tgt_name,),
"%s-skipped" % (src_name,),
tgt_skipped, src_skipped, style, by_id)
@@ -1304,7 +1309,7 @@
return
# Add the transfer(s).
- AddSplitTransfers(
+ FindZipsAndAddSplitTransfers(
tgt_name, src_name, tgt_ranges, src_ranges, style, by_id)
def ParseAndValidateSplitInfo(patch_size, tgt_ranges, src_ranges,
@@ -1403,10 +1408,13 @@
src_file, tgt_file, patch_file]
p = common.Run(cmd, stdout=subprocess.PIPE)
p.communicate()
- # TODO(xunchang) fall back to the normal split if imgdiff fails.
if p.returncode != 0:
- raise ValueError("Failed to create patch between {} and {}".format(
- src_name, tgt_name))
+ print("Failed to create patch between {} and {},"
+ " falling back to bsdiff".format(src_name, tgt_name))
+ with transfer_lock:
+ AddSplitTransfers(tgt_name, src_name, tgt_ranges, src_ranges,
+ "diff", self.transfers)
+ continue
with open(patch_info_file) as patch_info:
lines = patch_info.readlines()