diff options
| -rw-r--r-- | core/Makefile | 3 | ||||
| -rw-r--r-- | core/version_defaults.mk | 19 | ||||
| -rw-r--r-- | tools/releasetools/blockimgdiff.py | 44 | ||||
| -rwxr-xr-x | tools/releasetools/build_image.py | 6 | ||||
| -rw-r--r-- | tools/releasetools/test_blockimgdiff.py | 77 |
5 files changed, 127 insertions, 22 deletions
diff --git a/core/Makefile b/core/Makefile index 60f9837644..cf39a8b703 100644 --- a/core/Makefile +++ b/core/Makefile @@ -792,6 +792,7 @@ define generate-userimage-prop-dictionary $(if $(INTERNAL_USERIMAGES_EXT_VARIANT),$(hide) echo "fs_type=$(INTERNAL_USERIMAGES_EXT_VARIANT)" >> $(1)) $(if $(BOARD_SYSTEMIMAGE_PARTITION_SIZE),$(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(1)) $(if $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "system_fs_type=$(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE)" >> $(1)) +$(if $(BOARD_SYSTEMIMAGE_EXTFS_INODE_COUNT),$(hide) echo "system_extfs_inode_count=$(BOARD_SYSTEMIMAGE_EXTFS_INODE_COUNT)" >> $(1)) $(if $(BOARD_SYSTEMIMAGE_JOURNAL_SIZE),$(hide) echo "system_journal_size=$(BOARD_SYSTEMIMAGE_JOURNAL_SIZE)" >> $(1)) $(if $(BOARD_HAS_EXT4_RESERVED_BLOCKS),$(hide) echo "has_ext4_reserved_blocks=$(BOARD_HAS_EXT4_RESERVED_BLOCKS)" >> $(1)) $(if $(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "system_squashfs_compressor=$(BOARD_SYSTEMIMAGE_SQUASHFS_COMPRESSOR)" >> $(1)) @@ -805,6 +806,7 @@ $(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(hide) echo "userdata_size=$(BOARD_U $(if $(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "cache_fs_type=$(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE)" >> $(1)) $(if $(BOARD_CACHEIMAGE_PARTITION_SIZE),$(hide) echo "cache_size=$(BOARD_CACHEIMAGE_PARTITION_SIZE)" >> $(1)) $(if $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "vendor_fs_type=$(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE)" >> $(1)) +$(if $(BOARD_VENDORIMAGE_EXTFS_INODE_COUNT),$(hide) echo "vendor_extfs_inode_count=$(BOARD_VENDORIMAGE_EXTFS_INODE_COUNT)" >> $(1)) $(if $(BOARD_VENDORIMAGE_PARTITION_SIZE),$(hide) echo "vendor_size=$(BOARD_VENDORIMAGE_PARTITION_SIZE)" >> $(1)) $(if $(BOARD_VENDORIMAGE_JOURNAL_SIZE),$(hide) echo "vendor_journal_size=$(BOARD_VENDORIMAGE_JOURNAL_SIZE)" >> $(1)) $(if $(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR),$(hide) echo "vendor_squashfs_compressor=$(BOARD_VENDORIMAGE_SQUASHFS_COMPRESSOR)" >> $(1)) @@ -814,6 +816,7 @@ $(if $(BOARD_VENDORIMAGE_SQUASHFS_DISABLE_4K_ALIGN),$(hide) echo "vendor_squashf $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH),$(hide) echo "vendor_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_BASE_FS_PATH)" >> $(1)) $(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1)) $(if $(BOARD_OEMIMAGE_JOURNAL_SIZE),$(hide) echo "oem_journal_size=$(BOARD_OEMIMAGE_JOURNAL_SIZE)" >> $(1)) +$(if $(BOARD_OEMIMAGE_EXTFS_INODE_COUNT),$(hide) echo "oem_extfs_inode_count=$(BOARD_OEMIMAGE_EXTFS_INODE_COUNT)" >> $(1)) $(if $(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG),$(hide) echo "extfs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG)" >> $(1)) $(if $(INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG),$(hide) echo "squashfs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG)" >> $(1)) $(hide) echo "selinux_fc=$(SELINUX_FC)" >> $(1) diff --git a/core/version_defaults.mk b/core/version_defaults.mk index 3c84ce5458..38ca5e27ba 100644 --- a/core/version_defaults.mk +++ b/core/version_defaults.mk @@ -43,7 +43,16 @@ ifeq "" "$(PLATFORM_VERSION)" # which is the version that we reveal to the end user. # Update this value when the platform version changes (rather # than overriding it somewhere else). Can be an arbitrary string. - PLATFORM_VERSION := 7.1.1 + + # When you add a new PLATFORM_VERSION which will result in a new + # PLATFORM_SDK_VERSION please ensure you add a corresponding isAtLeast* + # method in the following java file: + # frameworks/support/compat/gingerbread/android/support/v4/os/BuildCompat.java + + # When you change PLATFORM_VERSION for a given PLATFORM_SDK_VERSION + # please add that PLATFORM_VERSION to the following text file: + # cts/tests/tests/os/assets/platform_versions.txt + PLATFORM_VERSION := 7.1.2 endif ifeq "" "$(PLATFORM_SDK_VERSION)" @@ -55,6 +64,14 @@ ifeq "" "$(PLATFORM_SDK_VERSION)" # intermediate builds). During development, this number remains at the # SDK version the branch is based on and PLATFORM_VERSION_CODENAME holds # the code-name of the new development work. + + # When you change PLATFORM_SDK_VERSION please ensure you also update the + # corresponding methods for isAtLeast* in the following java file: + # frameworks/support/compat/gingerbread/android/support/v4/os/BuildCompat.java + + # When you increment the PLATFORM_SDK_VERSION please ensure you also + # clear out the following text file of all older PLATFORM_VERSION's: + # cts/tests/tests/os/assets/platform_versions.txt PLATFORM_SDK_VERSION := 25 endif diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py index 31dabc724e..cc06a425e8 100644 --- a/tools/releasetools/blockimgdiff.py +++ b/tools/releasetools/blockimgdiff.py @@ -1000,8 +1000,11 @@ class BlockImageDiff(object): heap.append(xf.heap_item) heapq.heapify(heap) - sinks = set(u for u in G if not u.outgoing) - sources = set(u for u in G if not u.incoming) + # Use OrderedDict() instead of set() to preserve the insertion order. Need + # to use 'sinks[key] = None' to add key into the set. sinks will look like + # { key1: None, key2: None, ... }. + sinks = OrderedDict.fromkeys(u for u in G if not u.outgoing) + sources = OrderedDict.fromkeys(u for u in G if not u.incoming) def adjust_score(iu, delta): iu.score += delta @@ -1012,26 +1015,28 @@ class BlockImageDiff(object): while G: # Put all sinks at the end of the sequence. while sinks: - new_sinks = set() + new_sinks = OrderedDict() for u in sinks: if u not in G: continue s2.appendleft(u) del G[u] for iu in u.incoming: adjust_score(iu, -iu.outgoing.pop(u)) - if not iu.outgoing: new_sinks.add(iu) + if not iu.outgoing: + new_sinks[iu] = None sinks = new_sinks # Put all the sources at the beginning of the sequence. while sources: - new_sources = set() + new_sources = OrderedDict() for u in sources: if u not in G: continue s1.append(u) del G[u] for iu in u.outgoing: adjust_score(iu, +iu.incoming.pop(u)) - if not iu.incoming: new_sources.add(iu) + if not iu.incoming: + new_sources[iu] = None sources = new_sources if not G: break @@ -1050,11 +1055,13 @@ class BlockImageDiff(object): del G[u] for iu in u.outgoing: adjust_score(iu, +iu.incoming.pop(u)) - if not iu.incoming: sources.add(iu) + if not iu.incoming: + sources[iu] = None for iu in u.incoming: adjust_score(iu, -iu.outgoing.pop(u)) - if not iu.outgoing: sinks.add(iu) + if not iu.outgoing: + sinks[iu] = None # Now record the sequence in the 'order' field of each transfer, # and by rearranging self.transfers to be in the chosen sequence. @@ -1073,8 +1080,7 @@ class BlockImageDiff(object): # Each item of source_ranges will be: # - None, if that block is not used as a source, - # - a transfer, if one transfer uses it as a source, or - # - a set of transfers. + # - an ordered set of transfers. source_ranges = [] for b in self.transfers: for s, e in b.src_ranges: @@ -1082,23 +1088,19 @@ class BlockImageDiff(object): source_ranges.extend([None] * (e-len(source_ranges))) for i in range(s, e): if source_ranges[i] is None: - source_ranges[i] = b + source_ranges[i] = OrderedDict.fromkeys([b]) else: - if not isinstance(source_ranges[i], set): - source_ranges[i] = set([source_ranges[i]]) - source_ranges[i].add(b) + source_ranges[i][b] = None for a in self.transfers: - intersections = set() + intersections = OrderedDict() for s, e in a.tgt_ranges: for i in range(s, e): if i >= len(source_ranges): break - b = source_ranges[i] - if b is not None: - if isinstance(b, set): - intersections.update(b) - else: - intersections.add(b) + # Add all the Transfers in source_ranges[i] to the (ordered) set. + if source_ranges[i] is not None: + for j in source_ranges[i]: + intersections[j] = None for b in intersections: if a is b: continue diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py index fdf7271c54..cd61246a0b 100755 --- a/tools/releasetools/build_image.py +++ b/tools/releasetools/build_image.py @@ -402,6 +402,8 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None): return False build_command.extend(["-d", base_fs_file]) build_command.extend(["-L", prop_dict["mount_point"]]) + if "extfs_inode_count" in prop_dict: + build_command.extend(["-i", prop_dict["extfs_inode_count"]]) if "selinux_fc" in prop_dict: build_command.append(prop_dict["selinux_fc"]) elif fs_type.startswith("squash"): @@ -582,6 +584,7 @@ def ImagePropFromGlobalDict(glob_dict, mount_point): copy_prop("system_squashfs_block_size", "squashfs_block_size") copy_prop("system_squashfs_disable_4k_align", "squashfs_disable_4k_align") copy_prop("system_base_fs_file", "base_fs_file") + copy_prop("system_extfs_inode_count", "extfs_inode_count") elif mount_point == "system_other": # We inherit the selinux policies of /system since we contain some of its files. d["mount_point"] = "system" @@ -595,6 +598,7 @@ def ImagePropFromGlobalDict(glob_dict, mount_point): copy_prop("system_squashfs_compressor_opt", "squashfs_compressor_opt") copy_prop("system_squashfs_block_size", "squashfs_block_size") copy_prop("system_base_fs_file", "base_fs_file") + copy_prop("system_extfs_inode_count", "extfs_inode_count") elif mount_point == "data": # Copy the generic fs type first, override with specific one if available. copy_prop("fs_type", "fs_type") @@ -614,11 +618,13 @@ def ImagePropFromGlobalDict(glob_dict, mount_point): copy_prop("vendor_squashfs_block_size", "squashfs_block_size") copy_prop("vendor_squashfs_disable_4k_align", "squashfs_disable_4k_align") copy_prop("vendor_base_fs_file", "base_fs_file") + copy_prop("vendor_extfs_inode_count", "extfs_inode_count") elif mount_point == "oem": copy_prop("fs_type", "fs_type") copy_prop("oem_size", "partition_size") copy_prop("oem_journal_size", "journal_size") copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks") + copy_prop("oem_extfs_inode_count", "extfs_inode_count") return d diff --git a/tools/releasetools/test_blockimgdiff.py b/tools/releasetools/test_blockimgdiff.py new file mode 100644 index 0000000000..03e8c8beea --- /dev/null +++ b/tools/releasetools/test_blockimgdiff.py @@ -0,0 +1,77 @@ +# +# Copyright (C) 2016 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from __future__ import print_function + +import common +import unittest + +from collections import OrderedDict +from blockimgdiff import BlockImageDiff, EmptyImage, DataImage, Transfer +from rangelib import RangeSet + +class BlockImageDiffTest(unittest.TestCase): + + def test_GenerateDigraphOrder(self): + """Make sure GenerateDigraph preserves the order. + + t0: <0-5> => <...> + t1: <0-7> => <...> + t2: <0-4> => <...> + t3: <...> => <0-10> + + t0, t1 and t2 must go before t3, i.e. t3.goes_after = + { t0:..., t1:..., t2:... }. But the order of t0-t2 must be preserved. + """ + + src = EmptyImage() + tgt = EmptyImage() + block_image_diff = BlockImageDiff(tgt, src) + + transfers = block_image_diff.transfers + t0 = Transfer( + "t1", "t1", RangeSet("10-15"), RangeSet("0-5"), "move", transfers) + t1 = Transfer( + "t2", "t2", RangeSet("20-25"), RangeSet("0-7"), "move", transfers) + t2 = Transfer( + "t3", "t3", RangeSet("30-35"), RangeSet("0-4"), "move", transfers) + t3 = Transfer( + "t4", "t4", RangeSet("0-10"), RangeSet("40-50"), "move", transfers) + + block_image_diff.GenerateDigraph() + t3_goes_after_copy = t3.goes_after.copy() + + # Elements in the set must be in the transfer evaluation order. + elements = list(t3_goes_after_copy) + self.assertEqual(t0, elements[0]) + self.assertEqual(t1, elements[1]) + self.assertEqual(t2, elements[2]) + + # Now switch the order of t0, t1 and t2. + transfers[0], transfers[1], transfers[2] = ( + transfers[2], transfers[0], transfers[1]) + t3.goes_after.clear() + t3.goes_before.clear() + block_image_diff.GenerateDigraph() + + # The goes_after must be different from last run. + self.assertNotEqual(t3_goes_after_copy, t3.goes_after) + + # Assert that each element must agree with the transfer order. + elements = list(t3.goes_after) + self.assertEqual(t2, elements[0]) + self.assertEqual(t0, elements[1]) + self.assertEqual(t1, elements[2]) |