diff options
32 files changed, 375 insertions, 72 deletions
diff --git a/core/Makefile b/core/Makefile index c9b8cd11fb..6c90b51fcb 100644 --- a/core/Makefile +++ b/core/Makefile @@ -597,16 +597,32 @@ $(INSTALLED_ODM_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(POST_PROCESS_PROPS) INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET := $(TARGET_OUT_SYSTEM_EXT)/build.prop ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET) +ifdef TARGET_SYSTEM_EXT_PROP +system_ext_prop_files := $(TARGET_SYSTEM_EXT_PROP) +else +system_ext_prop_files := $(wildcard $(TARGET_DEVICE_DIR)/system_ext.prop) +endif + FINAL_SYSTEM_EXT_PROPERTIES += \ $(call collapse-pairs, $(PRODUCT_SYSTEM_EXT_PROPERTIES)) FINAL_SYSTEM_EXT_PROPERTIES := $(call uniq-pairs-by-first-component, \ $(FINAL_SYSTEM_EXT_PROPERTIES),=) -$(INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(POST_PROCESS_PROPS) +$(INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(POST_PROCESS_PROPS) $(system_ext_prop_files) @echo Target system_ext buildinfo: $@ @mkdir -p $(dir $@) $(hide) echo > $@ $(hide) $(call generate-common-build-props,system_ext,$@) + $(hide) $(foreach file,$(system_ext_prop_files), \ + if [ -f "$(file)" ]; then \ + echo Target system_ext properties from: "$(file)"; \ + echo "" >> $@; \ + echo "#" >> $@; \ + echo "# from $(file)" >> $@; \ + echo "#" >> $@; \ + cat $(file) >> $@; \ + echo "# end of $(file)" >> $@; \ + fi;) $(hide) echo "#" >> $@; \ echo "# ADDITIONAL SYSTEM_EXT BUILD PROPERTIES" >> $@; \ echo "#" >> $@; diff --git a/core/base_rules.mk b/core/base_rules.mk index 7147f6df69..3c973bb46a 100644 --- a/core/base_rules.mk +++ b/core/base_rules.mk @@ -716,6 +716,18 @@ ifneq (,$(filter $(SOONG_OUT_DIR)%,$(LOCAL_FULL_TEST_CONFIG))) endif endif + +ifeq ($(use_testcase_folder),true) +ifneq ($(my_test_data_file_pairs),) +$(foreach pair, $(my_test_data_file_pairs), \ + $(eval parts := $(subst :,$(space),$(pair))) \ + $(eval src_path := $(word 1,$(parts))) \ + $(eval file := $(word 2,$(parts))) \ + $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \ + $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite),$(arch_dir)), \ + $(call filter-copy-pair,$(src_path),$(call append-path,$(dir),$(file)),$(my_installed_test_data)))))) +endif +else ifneq ($(my_test_data_file_pairs),) $(foreach pair, $(my_test_data_file_pairs), \ $(eval parts := $(subst :,$(space),$(pair))) \ @@ -725,6 +737,7 @@ $(foreach pair, $(my_test_data_file_pairs), \ $(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite),$(arch_dir)), \ $(src_path):$(call append-path,$(dir),$(file)))))) endif +endif diff --git a/core/config.mk b/core/config.mk index df56edb6cd..d120d61651 100644 --- a/core/config.mk +++ b/core/config.mk @@ -507,22 +507,12 @@ USE_D8 := true # Tools that are prebuilts for TARGET_BUILD_APPS # ifeq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK))) - AIDL := $(HOST_OUT_EXECUTABLES)/aidl AAPT := $(HOST_OUT_EXECUTABLES)/aapt - AAPT2 := $(HOST_OUT_EXECUTABLES)/aapt2 MAINDEXCLASSES := $(HOST_OUT_EXECUTABLES)/mainDexClasses - SIGNAPK_JAR := $(HOST_OUT_JAVA_LIBRARIES)/signapk$(COMMON_JAVA_PACKAGE_SUFFIX) - SIGNAPK_JNI_LIBRARY_PATH := $(HOST_OUT_SHARED_LIBRARIES) - ZIPALIGN := $(HOST_OUT_EXECUTABLES)/zipalign else # TARGET_BUILD_APPS || TARGET_BUILD_PDK - AIDL := $(prebuilt_build_tools_bin)/aidl AAPT := $(prebuilt_sdk_tools_bin)/aapt - AAPT2 := $(prebuilt_sdk_tools_bin)/aapt2 MAINDEXCLASSES := $(prebuilt_sdk_tools)/mainDexClasses - SIGNAPK_JAR := $(prebuilt_sdk_tools)/lib/signapk$(COMMON_JAVA_PACKAGE_SUFFIX) - SIGNAPK_JNI_LIBRARY_PATH := $(prebuilt_sdk_tools)/$(HOST_OS)/lib64 - ZIPALIGN := $(prebuilt_build_tools_bin)/zipalign endif # TARGET_BUILD_APPS || TARGET_BUILD_PDK ifeq (,$(TARGET_BUILD_APPS)) @@ -543,12 +533,11 @@ DEPMOD := $(HOST_OUT_EXECUTABLES)/depmod FILESLIST := $(SOONG_HOST_OUT_EXECUTABLES)/fileslist FILESLIST_UTIL :=$= build/make/tools/fileslist_util.py HOST_INIT_VERIFIER := $(HOST_OUT_EXECUTABLES)/host_init_verifier -SOONG_JAVAC_WRAPPER := $(SOONG_HOST_OUT_EXECUTABLES)/soong_javac_wrapper -SOONG_ZIP := $(SOONG_HOST_OUT_EXECUTABLES)/soong_zip -MERGE_ZIPS := $(SOONG_HOST_OUT_EXECUTABLES)/merge_zips XMLLINT := $(SOONG_HOST_OUT_EXECUTABLES)/xmllint -ZIP2ZIP := $(SOONG_HOST_OUT_EXECUTABLES)/zip2zip -ZIPTIME := $(prebuilt_build_tools_bin)/ziptime + +# SOONG_ZIP is exported by Soong, but needs to be defined early for +# $OUT/dexpreopt.global. It will be verified against the Soong version. +SOONG_ZIP := $(SOONG_HOST_OUT_EXECUTABLES)/soong_zip # --------------------------------------------------------------- # Generic tools. diff --git a/core/definitions.mk b/core/definitions.mk index 0b2ae73741..a442bc0e0c 100644 --- a/core/definitions.mk +++ b/core/definitions.mk @@ -2270,7 +2270,7 @@ endef # $(1): the package file we are signing. define sign-package-arg $(hide) mv $(1) $(1).unsigned -$(hide) $(JAVA) -Djava.library.path=$(SIGNAPK_JNI_LIBRARY_PATH) -jar $(SIGNAPK_JAR) \ +$(hide) $(JAVA) -Djava.library.path=$$(dirname $(SIGNAPK_JNI_LIBRARY_PATH)) -jar $(SIGNAPK_JAR) \ $(PRIVATE_CERTIFICATE) $(PRIVATE_PRIVATE_KEY) \ $(PRIVATE_ADDITIONAL_CERTIFICATES) $(1).unsigned $(1).signed $(hide) mv $(1).signed $(1) @@ -2419,6 +2419,16 @@ define compat-copy-pair $(if $(filter-out $(2), $(LOCAL_INSTALLED_MODULE)), $(1):$(2)) endef +# Create copy pair for $(1) $(2) +# If $(2) is substring of $(3) do nothing. +# $(1): source path +# $(2): destination path +# $(3): filter-out target +# The format of copy pair is src:dst +define filter-copy-pair +$(if $(findstring $(2), $(3)),,$(1):$(2)) +endef + # Copies many files. # $(1): The files to copy. Each entry is a ':' separated src:dst pair # $(2): An optional directory to prepend to the destination diff --git a/core/java_common.mk b/core/java_common.mk index a23d92d9f6..dfe75f3257 100644 --- a/core/java_common.mk +++ b/core/java_common.mk @@ -86,6 +86,8 @@ ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),micro) $(proto_java_srcjar): $(HOST_OUT_EXECUTABLES)/protoc-gen-javamicro else ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),nano) $(proto_java_srcjar): PRIVATE_PROTO_JAVA_OUTPUT_OPTION := --javanano_out + $(proto_java_srcjar): PRIVATE_PROTOC_FLAGS += --plugin=$(HOST_OUT_EXECUTABLES)/protoc-gen-javanano + $(proto_java_srcjar): $(HOST_OUT_EXECUTABLES)/protoc-gen-javanano else ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),stream) $(proto_java_srcjar): PRIVATE_PROTO_JAVA_OUTPUT_OPTION := --javastream_out $(proto_java_srcjar): PRIVATE_PROTOC_FLAGS += --plugin=$(HOST_OUT_EXECUTABLES)/protoc-gen-javastream diff --git a/core/main.mk b/core/main.mk index 9eea513d6f..ba04ece191 100644 --- a/core/main.mk +++ b/core/main.mk @@ -44,11 +44,7 @@ BUILD_NUMBER_FILE := $(OUT_DIR)/build_number.txt .KATI_READONLY := BUILD_NUMBER_FILE $(KATI_obsolete_var BUILD_NUMBER,See https://android.googlesource.com/platform/build/+/master/Changes.md#BUILD_NUMBER) -ifeq ($(HOST_OS),darwin) -DATE_FROM_FILE := date -r $(BUILD_DATETIME_FROM_FILE) -else DATE_FROM_FILE := date -d @$(BUILD_DATETIME_FROM_FILE) -endif .KATI_READONLY := DATE_FROM_FILE # Pick a reasonable string to use to identify files. @@ -1498,7 +1494,7 @@ files: $(modules_to_install) \ # ------------------------------------------------------------------- .PHONY: checkbuild -checkbuild: $(modules_to_check) droid_targets +checkbuild: $(modules_to_check) droid_targets check-elf-files ifeq (true,$(ANDROID_BUILD_EVERYTHING_BY_DEFAULT)) droid: checkbuild diff --git a/core/package_internal.mk b/core/package_internal.mk index b80ccb3e76..557a2c6160 100644 --- a/core/package_internal.mk +++ b/core/package_internal.mk @@ -455,7 +455,7 @@ private_key := $(LOCAL_CERTIFICATE).pk8 certificate := $(LOCAL_CERTIFICATE).x509.pem additional_certificates := $(foreach c,$(LOCAL_ADDITIONAL_CERTIFICATES), $(c).x509.pem $(c).pk8) -$(LOCAL_BUILT_MODULE): $(private_key) $(certificate) $(SIGNAPK_JAR) +$(LOCAL_BUILT_MODULE): $(private_key) $(certificate) $(SIGNAPK_JAR) $(SIGNAPK_JNI_LIBRARY_PATH) $(LOCAL_BUILT_MODULE): PRIVATE_PRIVATE_KEY := $(private_key) $(LOCAL_BUILT_MODULE): PRIVATE_CERTIFICATE := $(certificate) diff --git a/core/proguard_basic_keeps.flags b/core/proguard_basic_keeps.flags index a0f577d8ba..28ec2d043f 100644 --- a/core/proguard_basic_keeps.flags +++ b/core/proguard_basic_keeps.flags @@ -72,3 +72,7 @@ # Less spammy. -dontnote + +# The lite proto runtime uses reflection to access fields based on the names in +# the schema, keep all the fields. +-keepclassmembers class * extends com.google.protobuf.MessageLite { <fields>; } diff --git a/core/version_defaults.mk b/core/version_defaults.mk index 00c5ed02f3..30890c0e0b 100644 --- a/core/version_defaults.mk +++ b/core/version_defaults.mk @@ -256,11 +256,7 @@ endif ifndef PLATFORM_SECURITY_PATCH_TIMESTAMP # Used to indicate the matching timestamp for the security patch string in PLATFORM_SECURITY_PATCH. - ifneq (,$(findstring Darwin,$(UNAME))) - PLATFORM_SECURITY_PATCH_TIMESTAMP := $(shell date -jf '%Y-%m-%d %T %Z' '$(PLATFORM_SECURITY_PATCH) 00:00:00 GMT' +%s) - else - PLATFORM_SECURITY_PATCH_TIMESTAMP := $(shell date -d 'TZ="GMT" $(PLATFORM_SECURITY_PATCH)' +%s) - endif + PLATFORM_SECURITY_PATCH_TIMESTAMP := $(shell date -d 'TZ="GMT" $(PLATFORM_SECURITY_PATCH)' +%s) endif .KATI_READONLY := PLATFORM_SECURITY_PATCH_TIMESTAMP @@ -289,11 +285,7 @@ ifndef BUILD_DATETIME BUILD_DATETIME := $(shell date +%s) endif -ifneq (,$(findstring Darwin,$(UNAME))) -DATE := date -r $(BUILD_DATETIME) -else DATE := date -d @$(BUILD_DATETIME) -endif .KATI_READONLY := DATE # Everything should be using BUILD_DATETIME_FROM_FILE instead. diff --git a/target/board/BoardConfigGsiCommon.mk b/target/board/BoardConfigGsiCommon.mk index 50b32f4f24..61aa67cd7d 100644 --- a/target/board/BoardConfigGsiCommon.mk +++ b/target/board/BoardConfigGsiCommon.mk @@ -35,9 +35,9 @@ BOARD_AVB_ROLLBACK_INDEX := 0 # GSI specific System Properties ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) -TARGET_SYSTEM_PROP := build/make/target/board/gsi_system.prop +TARGET_SYSTEM_EXT_PROP := build/make/target/board/gsi_system_ext.prop else -TARGET_SYSTEM_PROP := build/make/target/board/gsi_system_user.prop +TARGET_SYSTEM_EXT_PROP := build/make/target/board/gsi_system_ext_user.prop endif # Set this to create /cache mount point for non-A/B devices that mounts /cache. diff --git a/target/board/generic/system.prop b/target/board/generic/system_ext.prop index ad8e5b806e..ad8e5b806e 100644 --- a/target/board/generic/system.prop +++ b/target/board/generic/system_ext.prop diff --git a/target/board/generic_arm64/system.prop b/target/board/generic_arm64/system_ext.prop index 5b0183a37c..5b0183a37c 100644 --- a/target/board/generic_arm64/system.prop +++ b/target/board/generic_arm64/system_ext.prop diff --git a/target/board/generic_x86/system.prop b/target/board/generic_x86/system_ext.prop index 64829f3ce4..64829f3ce4 100644 --- a/target/board/generic_x86/system.prop +++ b/target/board/generic_x86/system_ext.prop diff --git a/target/board/generic_x86_64/system.prop b/target/board/generic_x86_64/system_ext.prop index ed9d1731c7..ed9d1731c7 100644 --- a/target/board/generic_x86_64/system.prop +++ b/target/board/generic_x86_64/system_ext.prop diff --git a/target/board/generic_x86_arm/system.prop b/target/board/generic_x86_arm/system_ext.prop index 64829f3ce4..64829f3ce4 100644 --- a/target/board/generic_x86_arm/system.prop +++ b/target/board/generic_x86_arm/system_ext.prop diff --git a/target/board/gsi_system.prop b/target/board/gsi_system_ext.prop index dd3227efb2..dd3227efb2 100644 --- a/target/board/gsi_system.prop +++ b/target/board/gsi_system_ext.prop diff --git a/target/board/gsi_system_user.prop b/target/board/gsi_system_ext_user.prop index db6d880b7a..db6d880b7a 100644 --- a/target/board/gsi_system_user.prop +++ b/target/board/gsi_system_ext_user.prop diff --git a/target/product/base_system.mk b/target/product/base_system.mk index 2ef104bd40..dab84877db 100644 --- a/target/product/base_system.mk +++ b/target/product/base_system.mk @@ -270,8 +270,6 @@ PRODUCT_PACKAGES += \ viewcompiler \ voip-common \ vold \ - vndkcore.libraries.txt \ - vndkprivate.libraries.txt \ WallpaperBackup \ watchdogd \ wificond \ @@ -364,6 +362,7 @@ PRODUCT_PACKAGES_DEBUG := \ adb_keys \ arping \ gdbserver \ + idlcli \ init-debug.rc \ iotop \ iperf3 \ diff --git a/target/product/go_defaults_common.mk b/target/product/go_defaults_common.mk index 7b9c783334..d4655f1f00 100644 --- a/target/product/go_defaults_common.mk +++ b/target/product/go_defaults_common.mk @@ -39,6 +39,7 @@ PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD := false # Do not spin up a separate process for the network stack on go devices, use an in-process APK. PRODUCT_PACKAGES += InProcessNetworkStack +PRODUCT_PACKAGES += CellBroadcastAppPlatform # Strip the local variable table and the local variable type table to reduce # the size of the system image. This has no bearing on stack traces, but will diff --git a/target/product/gsi/Android.mk b/target/product/gsi/Android.mk index 54f41ca947..1987c9c27a 100644 --- a/target/product/gsi/Android.mk +++ b/target/product/gsi/Android.mk @@ -150,6 +150,8 @@ ifneq ($(TARGET_SKIP_CURRENT_VNDK),true) LOCAL_REQUIRED_MODULES += \ llndk.libraries.txt \ vndksp.libraries.txt \ + vndkcore.libraries.txt \ + vndkprivate.libraries.txt \ $(addsuffix .vendor,$(VNDK_CORE_LIBRARIES)) \ $(addsuffix .vendor,$(VNDK_SAMEPROCESS_LIBRARIES)) endif 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/sdk_phone_x86.mk b/target/product/sdk_phone_x86.mk index b3e205c0d6..efb3c6e705 100644 --- a/target/product/sdk_phone_x86.mk +++ b/target/product/sdk_phone_x86.mk @@ -14,6 +14,29 @@ # limitations under the License. # QEMU_USE_SYSTEM_EXT_PARTITIONS := true +PRODUCT_USE_DYNAMIC_PARTITIONS := true + +# +# All components inherited here go to system image +# +$(call inherit-product, $(SRC_TARGET_DIR)/product/mainline_system.mk) + +# Enable mainline checking for excat this product name +ifeq (sdk_phone_x86,$(TARGET_PRODUCT)) +PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := relaxed +endif + +# +# All components inherited here go to product image +# +$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_product.mk) + +# +# All components inherited here go to vendor image +# +$(call inherit-product-if-exists, device/generic/goldfish/x86-vendor.mk) +$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk) +$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86/device.mk) $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_x86.mk) diff --git a/target/product/sdk_phone_x86_64.mk b/target/product/sdk_phone_x86_64.mk index 8062459248..267796f39c 100644 --- a/target/product/sdk_phone_x86_64.mk +++ b/target/product/sdk_phone_x86_64.mk @@ -14,8 +14,33 @@ # limitations under the License. # QEMU_USE_SYSTEM_EXT_PARTITIONS := true +PRODUCT_USE_DYNAMIC_PARTITIONS := true -$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_x86_64.mk) +# +# All components inherited here go to system image +# +$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk) +$(call inherit-product, $(SRC_TARGET_DIR)/product/mainline_system.mk) + +# Enable mainline checking for excat this product name +ifeq (sdk_phone_x86_64,$(TARGET_PRODUCT)) +PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := relaxed +endif + +PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST += \ + root/init.zygote64_32.rc \ + +# +# All components inherited here go to product image +# +$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_product.mk) + +# +# All components inherited here go to vendor image +# +$(call inherit-product-if-exists, device/generic/goldfish/x86_64-vendor.mk) +$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk) +$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86_64/device.mk) # Define the host tools and libs that are parts of the SDK. -include sdk/build/product_sdk.mk diff --git a/target/product/security/Android.mk b/target/product/security/Android.mk index a0b2d6dc65..3631cfdb27 100644 --- a/target/product/security/Android.mk +++ b/target/product/security/Android.mk @@ -1,7 +1,7 @@ LOCAL_PATH:= $(call my-dir) ####################################### -# verity_key +# verity_key (installed to /, i.e. part of system.img) include $(CLEAR_VARS) LOCAL_MODULE := verity_key @@ -9,9 +9,29 @@ LOCAL_SRC_FILES := $(LOCAL_MODULE) LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) +# For devices using a separate ramdisk, we need a copy there to establish the chain of trust. +ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true) +LOCAL_REQUIRED_MODULES := verity_key_ramdisk +endif + include $(BUILD_PREBUILT) ####################################### +# verity_key (installed to ramdisk) +# +# Enabling the target when using system-as-root would cause build failure, as TARGET_RAMDISK_OUT +# points to the same location as TARGET_ROOT_OUT. +ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true) + include $(CLEAR_VARS) + LOCAL_MODULE := verity_key_ramdisk + LOCAL_MODULE_CLASS := ETC + LOCAL_SRC_FILES := verity_key + LOCAL_MODULE_STEM := verity_key + LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT) + include $(BUILD_PREBUILT) +endif + +####################################### # adb key, if configured via PRODUCT_ADB_KEYS ifdef PRODUCT_ADB_KEYS ifneq ($(filter eng userdebug,$(TARGET_BUILD_VARIANT)),) diff --git a/target/product/telephony_system.mk b/target/product/telephony_system.mk index 584cf1ee63..4da9bdfb47 100644 --- a/target/product/telephony_system.mk +++ b/target/product/telephony_system.mk @@ -21,6 +21,6 @@ PRODUCT_PACKAGES := \ ONS \ CarrierDefaultApp \ CallLogBackup \ - CellBroadcastReceiver \ + CellBroadcastAppPlatform \ PRODUCT_COPY_FILES := \ diff --git a/tools/extract_kernel.py b/tools/extract_kernel.py index 42561cf0c6..8ca11d1cc6 100755 --- a/tools/extract_kernel.py +++ b/tools/extract_kernel.py @@ -100,19 +100,25 @@ def dump_configs(input_bytes): return o -def try_decompress(cmd, search_bytes, input_bytes): - idx = input_bytes.find(search_bytes) - if idx < 0: - return None - - idx = 0 +def try_decompress_bytes(cmd, input_bytes): sp = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - o, _ = sp.communicate(input=input_bytes[idx:]) + o, _ = sp.communicate(input=input_bytes) # ignore errors return o +def try_decompress(cmd, search_bytes, input_bytes): + idx = 0 + while True: + idx = input_bytes.find(search_bytes, idx) + if idx < 0: + raise StopIteration() + + yield try_decompress_bytes(cmd, input_bytes[idx:]) + idx += 1 + + def decompress_dump(func, input_bytes): """ Run func(input_bytes) first; and if that fails (returns value evaluates to @@ -122,15 +128,15 @@ def decompress_dump(func, input_bytes): if o: return o for cmd, search_bytes in COMPRESSION_ALGO: - decompressed = try_decompress(cmd, search_bytes, input_bytes) - if decompressed: - o = func(decompressed) - if o: - return o + for decompressed in try_decompress(cmd, search_bytes, input_bytes): + if decompressed: + o = decompress_dump(func, decompressed) + if o: + return o # Force decompress the whole file even if header doesn't match - decompressed = try_decompress(cmd, b"", input_bytes) + decompressed = try_decompress_bytes(cmd, input_bytes) if decompressed: - o = func(decompressed) + o = decompress_dump(func, decompressed) if o: return o diff --git a/tools/fs_config/fs_config_generator.py b/tools/fs_config/fs_config_generator.py index 2956b1121a..1405fd3bc5 100755 --- a/tools/fs_config/fs_config_generator.py +++ b/tools/fs_config/fs_config_generator.py @@ -1066,6 +1066,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/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py index 67cec1c8b7..82ea53970f 100755 --- a/tools/releasetools/ota_from_target_files.py +++ b/tools/releasetools/ota_from_target_files.py @@ -250,6 +250,7 @@ UNZIP_PATTERN = ['IMAGES/*', 'META/*', 'OTA/*', 'RADIO/*'] TARGET_DIFFING_UNZIP_PATTERN = ['BOOT', 'RECOVERY', 'SYSTEM/*', 'VENDOR/*', 'PRODUCT/*', 'SYSTEM_EXT/*', 'ODM/*'] RETROFIT_DAP_UNZIP_PATTERN = ['OTA/super_*.img', AB_PARTITIONS] +SECONDARY_IMAGES_SKIP_PARTITIONS = ['odm', 'product', 'system_ext', 'vendor'] class BuildInfo(object): @@ -298,6 +299,9 @@ class BuildInfo(object): that it always uses the first dict to calculate the fingerprint or the device name. The rest would be used for asserting OEM properties only (e.g. one package can be installed on one of these devices). + + Raises: + ValueError: On invalid inputs. """ self.info_dict = info_dict self.oem_dicts = oem_dicts @@ -312,6 +316,13 @@ class BuildInfo(object): self._device = self.GetOemProperty("ro.product.device") self._fingerprint = self.CalculateFingerprint() + # Sanity check the build fingerprint. + if (' ' in self._fingerprint or + any(ord(ch) > 127 for ch in self._fingerprint)): + raise ValueError( + 'Invalid build fingerprint: "{}". See the requirement in Android CDD ' + '3.2.2. Build Parameters.'.format(self._fingerprint)) + @property def is_ab(self): return self._is_ab @@ -1792,6 +1803,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_IMAGES_SKIP_PARTITIONS] + 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) @@ -1808,12 +1856,32 @@ def GetTargetFilesZipForSecondaryImages(input_file, skip_postinstall=False): elif info.filename in ('IMAGES/system.img', 'IMAGES/system.map'): pass + # Images like vendor and product are not needed in the secondary payload. + elif info.filename in ['IMAGES/{}.img'.format(partition) for partition in + SECONDARY_IMAGES_SKIP_PARTITIONS]: + pass # Skip copying the postinstall config if requested. elif skip_postinstall and info.filename == POSTINSTALL_CONFIG: pass - elif info.filename.startswith(('META/', 'IMAGES/', 'RADIO/')): + 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_IMAGES_SKIP_PARTITIONS] + 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) + elif info.filename.startswith(('IMAGES/', 'RADIO/')): 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 3119afa65a..1f41431b78 100755 --- a/tools/releasetools/sign_target_files_apks.py +++ b/tools/releasetools/sign_target_files_apks.py @@ -602,11 +602,16 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info, ReplaceVerityPrivateKey(misc_info, OPTIONS.replace_verity_private_key[1]) if OPTIONS.replace_verity_public_key: - dest = "ROOT/verity_key" if system_root_image else "BOOT/RAMDISK/verity_key" - # We are replacing the one in boot image only, since the one under - # recovery won't ever be needed. + # Replace the one in root dir in system.img. ReplaceVerityPublicKey( - output_tf_zip, dest, OPTIONS.replace_verity_public_key[1]) + output_tf_zip, 'ROOT/verity_key', OPTIONS.replace_verity_public_key[1]) + + if not system_root_image: + # Additionally replace the copy in ramdisk if not using system-as-root. + ReplaceVerityPublicKey( + output_tf_zip, + 'BOOT/RAMDISK/verity_key', + OPTIONS.replace_verity_public_key[1]) # Replace the keyid string in BOOT/cmdline. if OPTIONS.replace_verity_keyid: diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py index ee831e3ae2..9b2fbb6771 100644 --- a/tools/releasetools/test_ota_from_target_files.py +++ b/tools/releasetools/test_ota_from_target_files.py @@ -174,6 +174,14 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase): self.assertRaises(AssertionError, BuildInfo, self.TEST_INFO_DICT_USES_OEM_PROPS, None) + def test_init_badFingerprint(self): + info_dict = copy.deepcopy(self.TEST_INFO_DICT) + info_dict['build.prop']['ro.build.fingerprint'] = 'bad fingerprint' + self.assertRaises(ValueError, BuildInfo, info_dict, None) + + info_dict['build.prop']['ro.build.fingerprint'] = 'bad\x80fingerprint' + self.assertRaises(ValueError, BuildInfo, info_dict, None) + def test___getitem__(self): target_info = BuildInfo(self.TEST_INFO_DICT, None) self.assertEqual('value1', target_info['property1']) @@ -588,11 +596,11 @@ 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) @@ -600,6 +608,9 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): self.assertNotIn('IMAGES/system_other.img', namelist) self.assertNotIn('IMAGES/system.map', namelist) + expected_ab_partitions = ['boot', 'system', 'bootloader', 'modem'] + self.assertEqual('\n'.join(expected_ab_partitions), ab_partitions) + @test_utils.SkipIfExternalToolsUnavailable() def test_GetTargetFilesZipForSecondaryImages_skipPostinstall(self): input_file = construct_target_files(secondary=True) @@ -612,7 +623,6 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): 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) @@ -633,7 +643,6 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): 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/system_other.img', namelist) @@ -642,6 +651,55 @@ class OtaFromTargetFilesTest(test_utils.ReleaseToolsTestCase): 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/boot.img', 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/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/test_validate_target_files.py b/tools/releasetools/test_validate_target_files.py index 0f0d773c6a..9c816eb416 100644 --- a/tools/releasetools/test_validate_target_files.py +++ b/tools/releasetools/test_validate_target_files.py @@ -143,21 +143,52 @@ class ValidateTargetFilesTest(test_utils.ReleaseToolsTestCase): verity_image_builder.Build(output_file) @test_utils.SkipIfExternalToolsUnavailable() - def test_ValidateVerifiedBootImages_systemImage(self): + def test_ValidateVerifiedBootImages_systemRootImage(self): input_tmp = common.MakeTempDir() os.mkdir(os.path.join(input_tmp, 'IMAGES')) system_image = os.path.join(input_tmp, 'IMAGES', 'system.img') self._generate_system_image(system_image) # Pack the verity key. - verity_key_mincrypt = os.path.join( - input_tmp, 'BOOT', 'RAMDISK', 'verity_key') + verity_key_mincrypt = os.path.join(input_tmp, 'ROOT', 'verity_key') os.makedirs(os.path.dirname(verity_key_mincrypt)) shutil.copyfile( os.path.join(self.testdata_dir, 'testkey_mincrypt'), verity_key_mincrypt) info_dict = { + 'system_root_image' : 'true', + 'verity' : 'true', + } + options = { + 'verity_key' : os.path.join(self.testdata_dir, 'testkey.x509.pem'), + 'verity_key_mincrypt' : verity_key_mincrypt, + } + ValidateVerifiedBootImages(input_tmp, info_dict, options) + + @test_utils.SkipIfExternalToolsUnavailable() + def test_ValidateVerifiedBootImages_nonSystemRootImage(self): + input_tmp = common.MakeTempDir() + os.mkdir(os.path.join(input_tmp, 'IMAGES')) + system_image = os.path.join(input_tmp, 'IMAGES', 'system.img') + self._generate_system_image(system_image) + + # Pack the verity key into the root dir in system.img. + verity_key_mincrypt = os.path.join(input_tmp, 'ROOT', 'verity_key') + os.makedirs(os.path.dirname(verity_key_mincrypt)) + shutil.copyfile( + os.path.join(self.testdata_dir, 'testkey_mincrypt'), + verity_key_mincrypt) + + # And a copy in ramdisk. + verity_key_ramdisk = os.path.join( + input_tmp, 'BOOT', 'RAMDISK', 'verity_key') + os.makedirs(os.path.dirname(verity_key_ramdisk)) + shutil.copyfile( + os.path.join(self.testdata_dir, 'testkey_mincrypt'), + verity_key_ramdisk) + + info_dict = { 'verity' : 'true', } options = { @@ -167,6 +198,39 @@ class ValidateTargetFilesTest(test_utils.ReleaseToolsTestCase): ValidateVerifiedBootImages(input_tmp, info_dict, options) @test_utils.SkipIfExternalToolsUnavailable() + def test_ValidateVerifiedBootImages_nonSystemRootImage_mismatchingKeys(self): + input_tmp = common.MakeTempDir() + os.mkdir(os.path.join(input_tmp, 'IMAGES')) + system_image = os.path.join(input_tmp, 'IMAGES', 'system.img') + self._generate_system_image(system_image) + + # Pack the verity key into the root dir in system.img. + verity_key_mincrypt = os.path.join(input_tmp, 'ROOT', 'verity_key') + os.makedirs(os.path.dirname(verity_key_mincrypt)) + shutil.copyfile( + os.path.join(self.testdata_dir, 'testkey_mincrypt'), + verity_key_mincrypt) + + # And an invalid copy in ramdisk. + verity_key_ramdisk = os.path.join( + input_tmp, 'BOOT', 'RAMDISK', 'verity_key') + os.makedirs(os.path.dirname(verity_key_ramdisk)) + shutil.copyfile( + os.path.join(self.testdata_dir, 'verity_mincrypt'), + verity_key_ramdisk) + + info_dict = { + 'verity' : 'true', + } + options = { + 'verity_key' : os.path.join(self.testdata_dir, 'testkey.x509.pem'), + 'verity_key_mincrypt' : verity_key_mincrypt, + } + self.assertRaises( + AssertionError, ValidateVerifiedBootImages, input_tmp, info_dict, + options) + + @test_utils.SkipIfExternalToolsUnavailable() def test_ValidateFileConsistency_incompleteRange(self): input_tmp = common.MakeTempDir() os.mkdir(os.path.join(input_tmp, 'IMAGES')) diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py index d189499dc3..c299a488ae 100755 --- a/tools/releasetools/validate_target_files.py +++ b/tools/releasetools/validate_target_files.py @@ -276,15 +276,12 @@ def ValidateVerifiedBootImages(input_tmp, info_dict, options): # Verify verity signed system images in Verified Boot 1.0. Note that not using # 'elif' here, since 'boot_signer' and 'verity' are not bundled in VB 1.0. if info_dict.get('verity') == 'true': - # First verify that the verity key that's built into the root image (as - # /verity_key) matches the one given via command line, if any. - if info_dict.get("system_root_image") == "true": - verity_key_mincrypt = os.path.join(input_tmp, 'ROOT', 'verity_key') - else: - verity_key_mincrypt = os.path.join( - input_tmp, 'BOOT', 'RAMDISK', 'verity_key') + # First verify that the verity key is built into the root image (regardless + # of system-as-root). + verity_key_mincrypt = os.path.join(input_tmp, 'ROOT', 'verity_key') assert os.path.exists(verity_key_mincrypt), 'Missing verity_key' + # Verify /verity_key matches the one given via command line, if any. if options['verity_key_mincrypt'] is None: logging.warn( 'Skipped checking the content of /verity_key, as the key file not ' @@ -295,6 +292,18 @@ def ValidateVerifiedBootImages(input_tmp, info_dict, options): "Mismatching mincrypt verity key files" logging.info('Verified the content of /verity_key') + # For devices with a separate ramdisk (i.e. non-system-as-root), there must + # be a copy in ramdisk. + if info_dict.get("system_root_image") != "true": + verity_key_ramdisk = os.path.join( + input_tmp, 'BOOT', 'RAMDISK', 'verity_key') + assert os.path.exists(verity_key_ramdisk), 'Missing verity_key in ramdisk' + + assert filecmp.cmp( + verity_key_mincrypt, verity_key_ramdisk, shallow=False), \ + 'Mismatching verity_key files in root and ramdisk' + logging.info('Verified the content of /verity_key in ramdisk') + # Then verify the verity signed system/vendor/product images, against the # verity pubkey in mincrypt format. for image in ('system.img', 'vendor.img', 'product.img'): |