diff options
| -rw-r--r-- | CleanSpec.mk | 4 | ||||
| -rw-r--r-- | core/Makefile | 55 | ||||
| -rw-r--r-- | core/board_config.mk | 12 | ||||
| -rw-r--r-- | core/config.mk | 17 | ||||
| -rw-r--r-- | target/product/base_system.mk | 2 | ||||
| -rw-r--r-- | target/product/developer_gsi_keys.mk | 31 | ||||
| -rw-r--r-- | target/product/emulator_system.mk | 24 | ||||
| -rw-r--r-- | target/product/handheld_product.mk | 1 | ||||
| -rw-r--r-- | target/product/updatable_apex.mk | 8 | ||||
| -rwxr-xr-x | tools/extract_kernel.py | 5 | ||||
| -rw-r--r-- | tools/fs_config/Android.mk | 4 | ||||
| -rwxr-xr-x | tools/fs_config/fs_config_generator.py | 6 | ||||
| -rwxr-xr-x | tools/releasetools/add_img_to_target_files.py | 3 | ||||
| -rw-r--r-- | tools/releasetools/common.py | 3 | ||||
| -rwxr-xr-x | tools/releasetools/merge_target_files.py | 4 | ||||
| -rwxr-xr-x | tools/releasetools/ota_from_target_files.py | 68 | ||||
| -rwxr-xr-x | tools/releasetools/sign_target_files_apks.py | 4 | ||||
| -rw-r--r-- | tools/releasetools/test_ota_from_target_files.py | 69 | ||||
| -rwxr-xr-x | tools/releasetools/validate_target_files.py | 9 |
19 files changed, 279 insertions, 50 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk index 7c9c6da6f9..386e14c124 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -639,6 +639,10 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib*/libstagefright_soft*) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/odm/build.prop) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/odm/build.prop) +# Remove libcameraservice and libcamera_client from base_system +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib*/libcameraservice.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib*/libcamera_client.so) + # ************************************************ # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST # ************************************************ diff --git a/core/Makefile b/core/Makefile index 589f6ac536..d7d1965d44 100644 --- a/core/Makefile +++ b/core/Makefile @@ -3417,6 +3417,14 @@ define super-slot-suffix $(if $(filter true,$(AB_OTA_UPDATER)),$(if $(filter true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS)),,_a)) endef +ifndef BOARD_SUPER_PARTITION_WARN_LIMIT +BOARD_SUPER_PARTITION_WARN_LIMIT := $$(($(BOARD_SUPER_PARTITION_SIZE) * 95 / 100)) +endif + +ifndef BOARD_SUPER_PARTITION_ERROR_LIMIT +BOARD_SUPER_PARTITION_ERROR_LIMIT := $(BOARD_SUPER_PARTITION_SIZE) +endif + droid_targets: check-all-partition-sizes .PHONY: check-all-partition-sizes check-all-partition-sizes-nodeps @@ -3447,6 +3455,10 @@ endif # $(1): human-readable max size string # $(2): max size expression # $(3): list of partition names +# $(4): human-readable warn size string +# $(5): warn size expression +# $(6): human readable error size string +# $(7): error size expression define check-sum-of-partition-sizes partition_size_list="$$(for i in $(call read-size-of-partitions,$(3)); do \ echo $(call round-partition-size,$${i}); \ @@ -3457,6 +3469,17 @@ define check-sum-of-partition-sizes echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' "$(2)" '==' $$(( $(2) )); \ exit 1; \ else \ + if [[ ! -z "$(7)" ]] && [ $$(( $${sum_sizes_expr} )) -gt $$(( $(7) )) ]; then \ + echo "!!!! ERROR !!!! The sum of sizes of [$(strip $(3))] is larger than $(strip $(6)):"; \ + echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' "$(7)" '==' $$(( $(7) )); \ + echo "Super partition is" $$(( $$(( $$(( $${sum_sizes_expr} )) * 100)) / $$(( $(2) )) )) "percent occupied!"; \ + exit 1; \ + fi; \ + if [[ ! -z "$(5)" ]] && [ $$(( $${sum_sizes_expr} )) -gt $$(( $(5) )) ]; then \ + echo "!!!! WARNING !!!! The sum of sizes of [$(strip $(3))] is larger than $(strip $(4)):"; \ + echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '>' "$(5)" '==' $$(( $(5) )); \ + echo "Super partition is" $$(( $$(( $$(( $${sum_sizes_expr} )) * 100)) / $$(( $(2) )) )) "percent occupied!"; \ + fi; \ echo "The sum of sizes of [$(strip $(3))] is within $(strip $(1)):"; \ echo $${sum_sizes_expr} '==' $$(( $${sum_sizes_expr} )) '<=' "$(2)" '==' $$(( $(2) )); \ fi; @@ -3466,7 +3489,12 @@ define check-all-partition-sizes-target # Check sum(all partitions) <= super partition (/ 2 for A/B devices launched with dynamic partitions) $(if $(BOARD_SUPER_PARTITION_SIZE),$(if $(BOARD_SUPER_PARTITION_PARTITION_LIST), \ $(call check-sum-of-partition-sizes,BOARD_SUPER_PARTITION_SIZE$(if $(call super-slot-suffix), / 2), \ - $(BOARD_SUPER_PARTITION_SIZE)$(if $(call super-slot-suffix), / 2),$(BOARD_SUPER_PARTITION_PARTITION_LIST)))) + $(BOARD_SUPER_PARTITION_SIZE)$(if $(call super-slot-suffix), / 2),$(BOARD_SUPER_PARTITION_PARTITION_LIST), \ + BOARD_SUPER_PARTITION_WARN_LIMIT$(if $(call super-slot-suffix), / 2), \ + $(BOARD_SUPER_PARTITION_WARN_LIMIT)$(if $(call super-slot-suffix), / 2), \ + BOARD_SUPER_PARTITION_ERROR_LIMIT$(if $(call super-slot-suffix), / 2), \ + $(BOARD_SUPER_PARTITION_ERROR_LIMIT)$(if $(call super-slot-suffix), / 2)) \ + )) # For each group, check sum(partitions in group) <= group size $(foreach group,$(call to-upper,$(BOARD_SUPER_PARTITION_GROUPS)), \ @@ -3545,6 +3573,7 @@ endif ifeq ($(build_otatools_package),true) OTATOOLS := $(HOST_OUT_EXECUTABLES)/minigzip \ $(HOST_OUT_EXECUTABLES)/aapt \ + $(HOST_OUT_EXECUTABLES)/aapt2 \ $(HOST_OUT_EXECUTABLES)/checkvintf \ $(HOST_OUT_EXECUTABLES)/mkbootfs \ $(HOST_OUT_EXECUTABLES)/mkbootimg \ @@ -4432,21 +4461,27 @@ $(PROGUARD_DICT_ZIP) : endif # TARGET_BUILD_APPS -# ----------------------------------------------------------------- -# super partition image (dist) -ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION)) - -# BOARD_SUPER_PARTITION_SIZE must be defined to build super image. -ifneq ($(BOARD_SUPER_PARTITION_SIZE),) +ifeq (true,$(PRODUCT_USE_DYNAMIC_PARTITIONS)) -# Dump variables used by build_super_image.py. +# Dump variables used by build_super_image.py (for building super.img and super_empty.img). +# $(1): output file define dump-super-image-info $(call dump-dynamic-partitions-info,$(1)) $(if $(filter true,$(AB_OTA_UPDATER)), \ echo "ab_update=true" >> $(1)) endef +endif # PRODUCT_USE_DYNAMIC_PARTITIONS + +# ----------------------------------------------------------------- +# super partition image (dist) + +ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION)) + +# BOARD_SUPER_PARTITION_SIZE must be defined to build super image. +ifneq ($(BOARD_SUPER_PARTITION_SIZE),) + ifneq (true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS)) # For real devices and for dist builds, build super image from target files to an intermediate directory. @@ -4526,7 +4561,7 @@ endif # PRODUCT_BUILD_SUPER_PARTITION == "true" # ----------------------------------------------------------------- # super empty image -ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION)) +ifeq (true,$(PRODUCT_USE_DYNAMIC_PARTITIONS)) ifneq ($(BOARD_SUPER_PARTITION_SIZE),) INSTALLED_SUPERIMAGE_EMPTY_TARGET := $(PRODUCT_OUT)/super_empty.img @@ -4542,7 +4577,7 @@ $(INSTALLED_SUPERIMAGE_EMPTY_TARGET): $(LPMAKE) $(BUILD_SUPER_IMAGE) $(call dist-for-goals,dist_files,$(INSTALLED_SUPERIMAGE_EMPTY_TARGET)) endif # BOARD_SUPER_PARTITION_SIZE != "" -endif # PRODUCT_BUILD_SUPER_PARTITION == "true" +endif # PRODUCT_USE_DYNAMIC_PARTITIONS == "true" # ----------------------------------------------------------------- diff --git a/core/board_config.mk b/core/board_config.mk index ac0f27da53..e58b123863 100644 --- a/core/board_config.mk +++ b/core/board_config.mk @@ -508,8 +508,16 @@ endif # APEXes are by default flattened, i.e. non-updatable. # It can be unflattened (and updatable) by inheriting from # updatable_apex.mk -ifeq (,$(TARGET_FLATTEN_APEX)) -TARGET_FLATTEN_APEX := true +# +# APEX flattening can also be forcibly enabled (resp. disabled) by +# setting OVERRIDE_TARGET_FLATTEN_APEX to true (resp. false), e.g. by +# setting the OVERRIDE_TARGET_FLATTEN_APEX environment variable. +ifdef OVERRIDE_TARGET_FLATTEN_APEX + TARGET_FLATTEN_APEX := $(OVERRIDE_TARGET_FLATTEN_APEX) +else + ifeq (,$(TARGET_FLATTEN_APEX)) + TARGET_FLATTEN_APEX := true + endif endif ifeq (,$(TARGET_BUILD_APPS)) diff --git a/core/config.mk b/core/config.mk index 8c73281032..4386489414 100644 --- a/core/config.mk +++ b/core/config.mk @@ -888,16 +888,12 @@ ifeq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true) # - BOARD_{GROUP}_PARTITION_PARTITION_LIST: the list of partitions that belongs to this group. # If empty, no partitions belong to this group, and the sum of sizes is effectively 0. $(foreach group,$(call to-upper,$(BOARD_SUPER_PARTITION_GROUPS)), \ - $(eval BOARD_$(group)_PARTITION_LIST ?=) \ - $(eval .KATI_READONLY := BOARD_$(group)_PARTITION_LIST) \ -) -ifeq ($(PRODUCT_BUILD_SUPER_PARTITION),true) -$(foreach group,$(call to-upper,$(BOARD_SUPER_PARTITION_GROUPS)), \ $(eval BOARD_$(group)_SIZE := $(strip $(BOARD_$(group)_SIZE))) \ $(if $(BOARD_$(group)_SIZE),,$(error BOARD_$(group)_SIZE must not be empty)) \ $(eval .KATI_READONLY := BOARD_$(group)_SIZE) \ + $(eval BOARD_$(group)_PARTITION_LIST ?=) \ + $(eval .KATI_READONLY := BOARD_$(group)_PARTITION_LIST) \ ) -endif # PRODUCT_BUILD_SUPER_PARTITION # BOARD_*_PARTITION_LIST: a list of the following tokens valid_super_partition_list := system vendor product product_services odm @@ -919,10 +915,6 @@ BOARD_SUPER_PARTITION_PARTITION_LIST := \ $(BOARD_$(group)_PARTITION_LIST)) .KATI_READONLY := BOARD_SUPER_PARTITION_PARTITION_LIST -endif # PRODUCT_USE_DYNAMIC_PARTITIONS - -ifeq ($(PRODUCT_BUILD_SUPER_PARTITION),true) - ifneq ($(BOARD_SUPER_PARTITION_SIZE),) ifeq ($(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS),true) @@ -982,8 +974,11 @@ BOARD_BUILD_RETROFIT_DYNAMIC_PARTITIONS_OTA_PACKAGE := endif # PRODUCT_RETROFIT_DYNAMIC_PARTITIONS endif # BOARD_SUPER_PARTITION_SIZE +BOARD_SUPER_PARTITION_BLOCK_DEVICES ?= .KATI_READONLY := BOARD_SUPER_PARTITION_BLOCK_DEVICES +BOARD_SUPER_PARTITION_METADATA_DEVICE ?= .KATI_READONLY := BOARD_SUPER_PARTITION_METADATA_DEVICE +BOARD_BUILD_RETROFIT_DYNAMIC_PARTITIONS_OTA_PACKAGE ?= .KATI_READONLY := BOARD_BUILD_RETROFIT_DYNAMIC_PARTITIONS_OTA_PACKAGE $(foreach device,$(call to-upper,$(BOARD_SUPER_PARTITION_BLOCK_DEVICES)), \ @@ -992,7 +987,7 @@ $(foreach device,$(call to-upper,$(BOARD_SUPER_PARTITION_BLOCK_DEVICES)), \ $(error BOARD_SUPER_PARTITION_$(device)_DEVICE_SIZE must not be empty)) \ $(eval .KATI_READONLY := BOARD_SUPER_PARTITION_$(device)_DEVICE_SIZE)) -endif # PRODUCT_BUILD_SUPER_PARTITION +endif # PRODUCT_USE_DYNAMIC_PARTITIONS # ############################################################### # Set up final options. diff --git a/target/product/base_system.mk b/target/product/base_system.mk index ecc217dcd0..2f8a634729 100644 --- a/target/product/base_system.mk +++ b/target/product/base_system.mk @@ -123,8 +123,6 @@ PRODUCT_PACKAGES += \ libbinder_ndk \ libc.bootstrap \ libcamera2ndk \ - libcamera_client \ - libcameraservice \ libc_malloc_debug \ libc_malloc_hooks \ libcutils \ diff --git a/target/product/developer_gsi_keys.mk b/target/product/developer_gsi_keys.mk new file mode 100644 index 0000000000..a7e3d62cb9 --- /dev/null +++ b/target/product/developer_gsi_keys.mk @@ -0,0 +1,31 @@ +# +# Copyright (C) 2019 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. +# + +# Device makers who are willing to support booting the public Developer-GSI +# in locked state can add the following line into a device.mk to inherit this +# makefile. This file will then install the up-to-date GSI public keys into +# the first-stage ramdisk to pass verified boot. +# +# In device/<company>/<board>/device.mk: +# $(call inherit-product, $(SRC_TARGET_DIR)/product/developer_gsi_keys.mk) +# +# Currently, the developer GSI images can be downloaded from the following URL: +# https://developer.android.com/topic/generic-system-image/releases +# +PRODUCT_PACKAGES += \ + q-developer-gsi.avbpubkey \ + r-developer-gsi.avbpubkey \ + s-developer-gsi.avbpubkey \ diff --git a/target/product/emulator_system.mk b/target/product/emulator_system.mk new file mode 100644 index 0000000000..4b6987cd9b --- /dev/null +++ b/target/product/emulator_system.mk @@ -0,0 +1,24 @@ +# +# Copyright (C) 2019 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. +# +# This file lists emulator experimental modules added to PRODUCT_PACKAGES, +# only included by targets sdk_phone_x86/64 and sdk_gphone_x86/64 + +PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST := \ + system/lib/libemulator_multidisplay_jni.so \ + system/lib64/libemulator_multidisplay_jni.so \ + system/priv-app/MultiDisplayProvider/MultiDisplayProvider.apk \ + +PRODUCT_PACKAGES += MultiDisplayProvider diff --git a/target/product/handheld_product.mk b/target/product/handheld_product.mk index 0d100b267f..54dcaf25ec 100644 --- a/target/product/handheld_product.mk +++ b/target/product/handheld_product.mk @@ -27,7 +27,6 @@ PRODUCT_PACKAGES += \ Camera2 \ Contacts \ DeskClock \ - Email \ Gallery2 \ LatinIME \ Launcher3QuickStep \ diff --git a/target/product/updatable_apex.mk b/target/product/updatable_apex.mk index 038f66ee64..9b8716584f 100644 --- a/target/product/updatable_apex.mk +++ b/target/product/updatable_apex.mk @@ -16,6 +16,8 @@ # Inherit this when the target needs to support updating APEXes -PRODUCT_PROPERTY_OVERRIDES := ro.apex.updatable=true -PRODUCT_PACKAGES := com.android.apex.cts.shim.v1_prebuilt -TARGET_FLATTEN_APEX := false +ifneq ($(OVERRIDE_TARGET_FLATTEN_APEX),true) + PRODUCT_PACKAGES := com.android.apex.cts.shim.v1_prebuilt + PRODUCT_PROPERTY_OVERRIDES := ro.apex.updatable=true + TARGET_FLATTEN_APEX := false +endif diff --git a/tools/extract_kernel.py b/tools/extract_kernel.py index 16ccb22d47..42561cf0c6 100755 --- a/tools/extract_kernel.py +++ b/tools/extract_kernel.py @@ -47,7 +47,10 @@ def get_version(input_bytes, start_idx): null_idx = input_bytes.find('\x00', start_idx) if null_idx < 0: return None - linux_banner = input_bytes[start_idx:null_idx].decode() + try: + linux_banner = input_bytes[start_idx:null_idx].decode() + except UnicodeDecodeError: + return None mo = re.match(LINUX_BANNER_REGEX, linux_banner) if mo: return mo.group(1) diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk index 96db0f39fb..af0da46b29 100644 --- a/tools/fs_config/Android.mk +++ b/tools/fs_config/Android.mk @@ -99,7 +99,7 @@ $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_G --aid-header $(PRIVATE_ANDROID_FS_HDR) \ --capability-header $(PRIVATE_ANDROID_CAP_HDR) \ --partition system \ - --all-partitions $(subst $(space),$(comma),$(PRIVATE_PARTITION_LIST)) \ + --all-partitions "$(subst $(space),$(comma),$(PRIVATE_PARTITION_LIST))" \ --dirs \ --out_file $@ \ $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) @@ -124,7 +124,7 @@ $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_G --aid-header $(PRIVATE_ANDROID_FS_HDR) \ --capability-header $(PRIVATE_ANDROID_CAP_HDR) \ --partition system \ - --all-partitions $(subst $(space),$(comma),$(PRIVATE_PARTITION_LIST)) \ + --all-partitions "$(subst $(space),$(comma),$(PRIVATE_PARTITION_LIST))" \ --files \ --out_file $@ \ $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) diff --git a/tools/fs_config/fs_config_generator.py b/tools/fs_config/fs_config_generator.py index dccff928f9..109b29a160 100755 --- a/tools/fs_config/fs_config_generator.py +++ b/tools/fs_config/fs_config_generator.py @@ -1004,10 +1004,6 @@ class FSConfigGen(BaseGenerator): self._partition = args['partition'] self._all_partitions = args['all_partitions'] - if self._partition == 'system' and self._all_partitions is None: - sys.exit( - 'All other partitions must be provided if generating output' - ' for the system partition') self._out_file = args['out_file'] @@ -1137,6 +1133,8 @@ class FSConfigGen(BaseGenerator): path = fs_config.path if self._partition == 'system': + if not self._all_partitions: + return True for skip_partition in self._all_partitions.split(','): if path.startswith(skip_partition) or path.startswith( 'system/' + skip_partition): diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py index 1090d57194..f2b9afa657 100755 --- a/tools/releasetools/add_img_to_target_files.py +++ b/tools/releasetools/add_img_to_target_files.py @@ -870,10 +870,11 @@ def AddImagesToTargetFiles(filename): banner("vbmeta") AddVBMeta(output_zip, partitions, "vbmeta", vbmeta_partitions) - if OPTIONS.info_dict.get("build_super_partition") == "true": + if OPTIONS.info_dict.get("use_dynamic_partitions") == "true": banner("super_empty") AddSuperEmpty(output_zip) + if OPTIONS.info_dict.get("build_super_partition") == "true": if OPTIONS.info_dict.get( "build_retrofit_dynamic_partitions_ota_package") == "true": banner("super split images") diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index d743c3e2dd..9a27ad3f94 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -97,6 +97,9 @@ SPECIAL_CERT_STRINGS = ("PRESIGNED", "EXTERNAL") AVB_PARTITIONS = ('boot', 'recovery', 'system', 'vendor', 'product', 'product_services', 'dtbo', 'odm') +# Chained VBMeta partitions. +AVB_VBMETA_PARTITIONS = ('vbmeta_system', 'vbmeta_vendor') + # Partitions that should have their care_map added to META/care_map.pb PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product', 'product_services', 'odm') diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py index 3b72551a37..712e3f7cde 100755 --- a/tools/releasetools/merge_target_files.py +++ b/tools/releasetools/merge_target_files.py @@ -395,6 +395,10 @@ def process_misc_info_txt( merged_info_dict[key] = '%s %s' % ( system_info_dict.get(key, ''), merged_info_dict.get(key, '')) + # Ensure that add_img_to_target_files rebuilds super split images for + # devices that retrofit dynamic partitions. This flag may have been set to + # false in the partial builds to prevent duplicate building of super.img. + merged_dict['build_super_partition'] = 'true' output_misc_info_txt = os.path.join( output_target_files_temp_dir, diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py index 8b55f034b3..27854fd66b 100755 --- a/tools/releasetools/ota_from_target_files.py +++ b/tools/releasetools/ota_from_target_files.py @@ -243,6 +243,12 @@ AB_PARTITIONS = 'META/ab_partitions.txt' UNZIP_PATTERN = ['IMAGES/*', 'META/*', 'RADIO/*'] RETROFIT_DAP_UNZIP_PATTERN = ['OTA/super_*.img', AB_PARTITIONS] +# Images to be excluded from secondary payload. We essentially only keep +# 'system_other' and bootloader partitions. +SECONDARY_PAYLOAD_SKIPPED_IMAGES = [ + 'boot', 'dtbo', 'modem', 'odm', 'product', 'radio', 'recovery', + 'system_ext', 'vbmeta', 'vbmeta_system', 'vbmeta_vendor', 'vendor'] + class BuildInfo(object): """A class that holds the information for a given build. @@ -1859,6 +1865,43 @@ def GetTargetFilesZipForSecondaryImages(input_file, skip_postinstall=False): Returns: The filename of the target-files.zip for generating secondary payload. """ + + def GetInfoForSecondaryImages(info_file): + """Updates info file for secondary payload generation. + + Scan each line in the info file, and remove the unwanted partitions from + the dynamic partition list in the related properties. e.g. + "super_google_dynamic_partitions_partition_list=system vendor product" + will become "super_google_dynamic_partitions_partition_list=system". + + Args: + info_file: The input info file. e.g. misc_info.txt. + + Returns: + A string of the updated info content. + """ + + output_list = [] + with open(info_file) as f: + lines = f.read().splitlines() + + # The suffix in partition_list variables that follows the name of the + # partition group. + LIST_SUFFIX = 'partition_list' + for line in lines: + if line.startswith('#') or '=' not in line: + output_list.append(line) + continue + key, value = line.strip().split('=', 1) + if key == 'dynamic_partition_list' or key.endswith(LIST_SUFFIX): + partitions = value.split() + partitions = [partition for partition in partitions if partition + not in SECONDARY_PAYLOAD_SKIPPED_IMAGES] + output_list.append('{}={}'.format(key, ' '.join(partitions))) + else: + output_list.append(line) + return '\n'.join(output_list) + target_file = common.MakeTempFile(prefix="targetfiles-", suffix=".zip") target_zip = zipfile.ZipFile(target_file, 'w', allowZip64=True) @@ -1877,12 +1920,33 @@ def GetTargetFilesZipForSecondaryImages(input_file, skip_postinstall=False): 'IMAGES/system.map'): pass + # Copy images that are not in SECONDARY_PAYLOAD_SKIPPED_IMAGES. + elif info.filename.startswith(('IMAGES/', 'RADIO/')): + image_name = os.path.basename(info.filename) + if image_name not in ['{}.img'.format(partition) for partition in + SECONDARY_PAYLOAD_SKIPPED_IMAGES]: + common.ZipWrite(target_zip, unzipped_file, arcname=info.filename) + # Skip copying the postinstall config if requested. elif skip_postinstall and info.filename == POSTINSTALL_CONFIG: pass - elif info.filename.startswith(('META/', 'IMAGES/', 'RADIO/')): - common.ZipWrite(target_zip, unzipped_file, arcname=info.filename) + elif info.filename.startswith('META/'): + # Remove the unnecessary partitions for secondary images from the + # ab_partitions file. + if info.filename == AB_PARTITIONS: + with open(unzipped_file) as f: + partition_list = f.read().splitlines() + partition_list = [partition for partition in partition_list if partition + and partition not in SECONDARY_PAYLOAD_SKIPPED_IMAGES] + common.ZipWriteStr(target_zip, info.filename, '\n'.join(partition_list)) + # Remove the unnecessary partitions from the dynamic partitions list. + elif (info.filename == 'META/misc_info.txt' or + info.filename == DYNAMIC_PARTITION_INFO): + modified_info = GetInfoForSecondaryImages(unzipped_file) + common.ZipWriteStr(target_zip, info.filename, modified_info) + else: + common.ZipWrite(target_zip, unzipped_file, arcname=info.filename) common.ZipClose(target_zip) diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py index e8c4163e95..1b3d6f1096 100755 --- a/tools/releasetools/sign_target_files_apks.py +++ b/tools/releasetools/sign_target_files_apks.py @@ -972,6 +972,10 @@ def GetCodenameToApiLevelMap(input_tf_zip): codename = codename.strip() if codename: result[codename] = api_level + + # Work around APKs that still target 'Q' instead of API 29 (b/132882632). + result['Q'] = 29 + return result diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py index 466fde1af3..07dcffb6aa 100644 --- a/tools/releasetools/test_ota_from_target_files.py +++ b/tools/releasetools/test_ota_from_target_files.py @@ -588,18 +588,22 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): with zipfile.ZipFile(target_file) as verify_zip: namelist = verify_zip.namelist() + ab_partitions = verify_zip.read('META/ab_partitions.txt') self.assertIn('META/ab_partitions.txt', namelist) - self.assertIn('IMAGES/boot.img', namelist) self.assertIn('IMAGES/system.img', namelist) - self.assertIn('IMAGES/vendor.img', namelist) self.assertIn('RADIO/bootloader.img', namelist) - self.assertIn('RADIO/modem.img', namelist) self.assertIn(POSTINSTALL_CONFIG, namelist) + self.assertNotIn('IMAGES/boot.img', namelist) self.assertNotIn('IMAGES/system_other.img', namelist) self.assertNotIn('IMAGES/system.map', namelist) + self.assertNotIn('RADIO/modem.img', namelist) + + expected_ab_partitions = ['system', 'bootloader'] + self.assertEqual('\n'.join(expected_ab_partitions), ab_partitions) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipForSecondaryImages_skipPostinstall(self): input_file = construct_target_files(secondary=True) target_file = GetTargetFilesZipForSecondaryImages( @@ -609,16 +613,16 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): namelist = verify_zip.namelist() self.assertIn('META/ab_partitions.txt', namelist) - self.assertIn('IMAGES/boot.img', namelist) self.assertIn('IMAGES/system.img', namelist) - self.assertIn('IMAGES/vendor.img', namelist) self.assertIn('RADIO/bootloader.img', namelist) - self.assertIn('RADIO/modem.img', namelist) + self.assertNotIn('IMAGES/boot.img', namelist) self.assertNotIn('IMAGES/system_other.img', namelist) self.assertNotIn('IMAGES/system.map', namelist) + self.assertNotIn('RADIO/modem.img', namelist) self.assertNotIn(POSTINSTALL_CONFIG, namelist) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipForSecondaryImages_withoutRadioImages(self): input_file = construct_target_files(secondary=True) common.ZipDelete(input_file, 'RADIO/bootloader.img') @@ -629,16 +633,65 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): namelist = verify_zip.namelist() self.assertIn('META/ab_partitions.txt', namelist) - self.assertIn('IMAGES/boot.img', namelist) self.assertIn('IMAGES/system.img', namelist) - self.assertIn('IMAGES/vendor.img', namelist) self.assertIn(POSTINSTALL_CONFIG, namelist) + self.assertNotIn('IMAGES/boot.img', namelist) self.assertNotIn('IMAGES/system_other.img', namelist) self.assertNotIn('IMAGES/system.map', namelist) self.assertNotIn('RADIO/bootloader.img', namelist) self.assertNotIn('RADIO/modem.img', namelist) + @test_utils.SkipIfExternalToolsUnavailable() + def test_GetTargetFilesZipForSecondaryImages_dynamicPartitions(self): + input_file = construct_target_files(secondary=True) + misc_info = '\n'.join([ + 'use_dynamic_partition_size=true', + 'use_dynamic_partitions=true', + 'dynamic_partition_list=system vendor product', + 'super_partition_groups=google_dynamic_partitions', + 'super_google_dynamic_partitions_group_size=4873781248', + 'super_google_dynamic_partitions_partition_list=system vendor product', + ]) + dynamic_partitions_info = '\n'.join([ + 'super_partition_groups=google_dynamic_partitions', + 'super_google_dynamic_partitions_group_size=4873781248', + 'super_google_dynamic_partitions_partition_list=system vendor product', + ]) + + with zipfile.ZipFile(input_file, 'a') as append_zip: + common.ZipWriteStr(append_zip, 'META/misc_info.txt', misc_info) + common.ZipWriteStr(append_zip, 'META/dynamic_partitions_info.txt', + dynamic_partitions_info) + + target_file = GetTargetFilesZipForSecondaryImages(input_file) + + with zipfile.ZipFile(target_file) as verify_zip: + namelist = verify_zip.namelist() + updated_misc_info = verify_zip.read('META/misc_info.txt') + updated_dynamic_partitions_info = verify_zip.read( + 'META/dynamic_partitions_info.txt') + + self.assertIn('META/ab_partitions.txt', namelist) + self.assertIn('IMAGES/system.img', namelist) + self.assertIn(POSTINSTALL_CONFIG, namelist) + self.assertIn('META/misc_info.txt', namelist) + self.assertIn('META/dynamic_partitions_info.txt', namelist) + + self.assertNotIn('IMAGES/boot.img', namelist) + self.assertNotIn('IMAGES/system_other.img', namelist) + self.assertNotIn('IMAGES/system.map', namelist) + + # Check the vendor & product are removed from the partitions list. + expected_misc_info = misc_info.replace('system vendor product', + 'system') + expected_dynamic_partitions_info = dynamic_partitions_info.replace( + 'system vendor product', 'system') + self.assertEqual(expected_misc_info, updated_misc_info) + self.assertEqual(expected_dynamic_partitions_info, + updated_dynamic_partitions_info) + + @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipWithoutPostinstallConfig(self): input_file = construct_target_files() target_file = GetTargetFilesZipWithoutPostinstallConfig(input_file) diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py index 1c856a8e14..37d5d27bf5 100755 --- a/tools/releasetools/validate_target_files.py +++ b/tools/releasetools/validate_target_files.py @@ -327,11 +327,14 @@ def ValidateVerifiedBootImages(input_tmp, info_dict, options): cmd = ['avbtool', 'verify_image', '--image', image, '--key', key] # Append the args for chained partitions if any. - for partition in common.AVB_PARTITIONS: + for partition in common.AVB_PARTITIONS + common.AVB_VBMETA_PARTITIONS: key_name = 'avb_' + partition + '_key_path' if info_dict.get(key_name) is not None: + # Use the key file from command line if specified; otherwise fall back + # to the one in info dict. + key_file = options.get(key_name, info_dict[key_name]) chained_partition_arg = common.GetAvbChainedPartitionArg( - partition, info_dict, options[key_name]) + partition, info_dict, key_file) cmd.extend(["--expected_chain_partition", chained_partition_arg]) proc = common.Run(cmd) @@ -357,7 +360,7 @@ def main(): help='the verity public key to verify the bootable images (Verified ' 'Boot 1.0), or the vbmeta image (Verified Boot 2.0, aka AVB), where ' 'applicable') - for partition in common.AVB_PARTITIONS: + for partition in common.AVB_PARTITIONS + common.AVB_VBMETA_PARTITIONS: parser.add_argument( '--avb_' + partition + '_key_path', help='the public or private key in PEM format to verify AVB chained ' |