Merge "Read product/device RRO dirs separately from soong"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 21034ad..3d9a1ef 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -603,6 +603,16 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib*)
+# Clean up old testcase files
+$(call add-clean-step, rm -rf $(TARGET_OUT_TESTCASES)/*)
+$(call add-clean-step, rm -rf $(HOST_OUT_TESTCASES)/*)
+$(call add-clean-step, rm -rf $(HOST_CROSS_OUT_TESTCASES)/*)
+$(call add-clean-step, rm -rf $(TARGET_OUT_DATA)/*)
+$(call add-clean-step, rm -rf $(HOST_OUT)/vts/*)
+$(call add-clean-step, rm -rf $(HOST_OUT)/framework/vts-tradefed.jar)
+
+# Clean up old location of system_other.avbpubkey
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/security/avb/)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/OWNERS b/OWNERS
index 9f621d8..77496f1 100644
--- a/OWNERS
+++ b/OWNERS
@@ -5,7 +5,5 @@
# To expedite LON reviews
hansson@google.com
-per-file * = ccross@android.com,dwillemsen@google.com,hansson@google.com
-
# For version updates
per-file version_defaults.mk = aseaton@google.com,elisapascual@google.com
diff --git a/core/Makefile b/core/Makefile
index 8a73f4e..69c75ca 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -222,10 +222,22 @@
BUILDINFO_SH := build/make/tools/buildinfo.sh
BUILDINFO_COMMON_SH := build/make/tools/buildinfo_common.sh
-# Generates a set of common build system properties to a file.
+
+# Generates a set of sysprops common to all partitions to a file.
# $(1): Partition name
# $(2): Output file name
define generate-common-build-props
+ PRODUCT_BRAND="$(PRODUCT_BRAND)" \
+ PRODUCT_DEVICE="$(TARGET_DEVICE)" \
+ PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
+ PRODUCT_MODEL="$(PRODUCT_MODEL)" \
+ PRODUCT_NAME="$(TARGET_PRODUCT)" \
+ $(call generate-common-build-props-with-product-vars-set,$(1),$(2))
+endef
+
+# Like the above macro, but requiring the relevant PRODUCT_ environment
+# variables to be set when called.
+define generate-common-build-props-with-product-vars-set
BUILD_FINGERPRINT="$(BUILD_FINGERPRINT_FROM_FILE)" \
BUILD_ID="$(BUILD_ID)" \
BUILD_NUMBER="$(BUILD_NUMBER_FROM_FILE)" \
@@ -233,12 +245,7 @@
DATE="$(DATE_FROM_FILE)" \
PLATFORM_SDK_VERSION="$(PLATFORM_SDK_VERSION)" \
PLATFORM_VERSION="$(PLATFORM_VERSION)" \
- PRODUCT_BRAND="$(PRODUCT_BRAND)" \
- PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
- PRODUCT_MODEL="$(PRODUCT_MODEL)" \
- PRODUCT_NAME="$(TARGET_PRODUCT)" \
TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
- TARGET_DEVICE="$(TARGET_DEVICE)" \
bash $(BUILDINFO_COMMON_SH) "$(1)" >> $(2)
endef
@@ -426,7 +433,12 @@
$(hide) $(foreach prop,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_OEM_PROPERTIES), \
echo "import /oem/oem.prop $(prop)" >> $@;)
endif
- $(hide) $(call generate-common-build-props,system,$@)
+ $(hide) PRODUCT_BRAND="$(PRODUCT_SYSTEM_BRAND)" \
+ PRODUCT_MANUFACTURER="$(PRODUCT_SYSTEM_MANUFACTURER)" \
+ PRODUCT_MODEL="$(PRODUCT_SYSTEM_MODEL)" \
+ PRODUCT_NAME="$(PRODUCT_SYSTEM_NAME)" \
+ PRODUCT_DEVICE="$(PRODUCT_SYSTEM_DEVICE)" \
+ $(call generate-common-build-props-with-product-vars-set,system,$@)
$(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
TARGET_BUILD_FLAVOR="$(TARGET_BUILD_FLAVOR)" \
TARGET_DEVICE="$(TARGET_DEVICE)" \
@@ -718,6 +730,15 @@
$(call dist-for-goals,droidcore,$(BUILD_SYSTEM_STATS))
# -----------------------------------------------------------------
+# build /product/etc/security/avb/system_other.avbpubkey if needed
+ifdef BUILDING_SYSTEM_OTHER_IMAGE
+ifeq ($(BOARD_AVB_ENABLE),true)
+INSTALLED_PRODUCT_SYSTEM_OTHER_AVBKEY_TARGET := $(TARGET_OUT_PRODUCT_ETC)/security/avb/system_other.avbpubkey
+ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_PRODUCT_SYSTEM_OTHER_AVBKEY_TARGET)
+endif # BOARD_AVB_ENABLE
+endif # BUILDING_SYSTEM_OTHER_IMAGE
+
+# -----------------------------------------------------------------
# Modules ready to be converted to Soong, ordered by how many
# modules depend on them.
SOONG_CONV := $(sort $(SOONG_CONV))
@@ -1451,8 +1472,7 @@
$(if $(BOARD_AVB_ENABLE),\
$(if $(BOARD_AVB_SYSTEM_OTHER_KEY_PATH),\
$(hide) echo "avb_system_other_key_path=$(BOARD_AVB_SYSTEM_OTHER_KEY_PATH)" >> $(1)
- $(hide) echo "avb_system_other_algorithm=$(BOARD_AVB_SYSTEM_OTHER_ALGORITHM)" >> $(1)
- $(hide) echo "avb_system_extract_system_other_key=true" >> $(1)))
+ $(hide) echo "avb_system_other_algorithm=$(BOARD_AVB_SYSTEM_OTHER_ALGORITHM)" >> $(1)))
$(if $(BOARD_AVB_ENABLE),$(hide) echo "avb_vendor_hashtree_enable=$(BOARD_AVB_ENABLE)" >> $(1))
$(if $(BOARD_AVB_ENABLE),$(hide) echo "avb_vendor_add_hashtree_footer_args=$(BOARD_AVB_VENDOR_ADD_HASHTREE_FOOTER_ARGS)" >> $(1))
$(if $(BOARD_AVB_ENABLE),\
@@ -2968,9 +2988,11 @@
BOARD_AVB_SYSTEM_OTHER_ALGORITHM := $(BOARD_AVB_ALGORITHM)
endif
-# To extract the public key of SYSTEM_OTHER_KEY_PATH will into system.img:
-# /system/etc/security/avb/system_other.avbpubkey.
-FULL_SYSTEMIMAGE_DEPS += $(BOARD_AVB_SYSTEM_OTHER_KEY_PATH)
+$(INSTALLED_PRODUCT_SYSTEM_OTHER_AVBKEY_TARGET): $(AVBTOOL) $(BOARD_AVB_SYSTEM_OTHER_KEY_PATH)
+ @echo Extracting system_other avb key: $@
+ @rm -f $@
+ @mkdir -p $(dir $@)
+ $(AVBTOOL) extract_public_key --key $(BOARD_AVB_SYSTEM_OTHER_KEY_PATH) --output $@
ifndef BOARD_AVB_SYSTEM_OTHER_ROLLBACK_INDEX
BOARD_AVB_SYSTEM_OTHER_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
@@ -4317,6 +4339,13 @@
# BOARD_SUPER_PARTITION_SIZE must be defined to build super image.
ifneq ($(BOARD_SUPER_PARTITION_SIZE),)
+# Dump variables used by build_super_image.py.
+define dump-super-image-info
+ $(call dump-dynamic-partitions-info,$(1))
+ $(if $(filter true,$(AB_OTA_UPDATER)), \
+ echo "ab_update=true" >> $(1))
+endef
+
ifneq (true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS))
INSTALLED_SUPERIMAGE_TARGET := $(PRODUCT_OUT)/super.img
$(INSTALLED_SUPERIMAGE_TARGET): extracted_input_target_files := $(patsubst %.zip,%,$(BUILT_TARGET_FILES_PACKAGE))
@@ -4324,7 +4353,22 @@
$(call pretty,"Target super fs image: $@")
PATH=$(dir $(LPMAKE)):$$PATH \
$(BUILD_SUPER_IMAGE) -v $(extracted_input_target_files) $@
-endif
+
+# supernod uses images in the $(PRODUCT_OUT) directory instead of images from target files package.
+.PHONY: superimage-nodeps supernod
+superimage-nodeps supernod: intermediates := $(call intermediates-dir-for,PACKAGING,superimage-nodeps)
+superimage-nodeps supernod: | $(LPMAKE) $(BUILD_SUPER_IMAGE) \
+ $(foreach p, $(BOARD_SUPER_PARTITION_PARTITION_LIST), $(INSTALLED_$(call to-upper,$(p))IMAGE_TARGET))
+ $(call pretty,"make $(INSTALLED_SUPERIMAGE_TARGET): ignoring dependencies")
+ mkdir -p $(intermediates)
+ rm -rf $(intermediates)/misc_info.txt
+ $(call dump-super-image-info,$(intermediates)/misc_info.txt)
+ $(foreach p,$(BOARD_SUPER_PARTITION_PARTITION_LIST), \
+ echo "$(p)_image=$(INSTALLED_$(call to-upper,$(p))IMAGE_TARGET)" >> $(intermediates)/misc_info.txt;)
+ PATH=$(dir $(LPMAKE)):$$PATH \
+ $(BUILD_SUPER_IMAGE) -v $(intermediates)/misc_info.txt $(INSTALLED_SUPERIMAGE_TARGET)
+
+endif # PRODUCT_RETROFIT_DYNAMIC_PARTITIONS != "true"
$(call dist-for-goals,dist_files,$(INSTALLED_SUPERIMAGE_TARGET))
@@ -4334,10 +4378,7 @@
$(call pretty,"Target empty super fs image: $@")
mkdir -p $(intermediates)
rm -rf $(intermediates)/misc_info.txt
- $(call dump-dynamic-partitions-info,$(intermediates)/misc_info.txt)
-ifeq ($(AB_OTA_UPDATER),true)
- echo "ab_update=true" >> $(intermediates)/misc_info.txt
-endif
+ $(call dump-super-image-info,$(intermediates)/misc_info.txt)
PATH=$(dir $(LPMAKE)):$$PATH \
$(BUILD_SUPER_IMAGE) -v $(intermediates)/misc_info.txt $@
diff --git a/core/app_prebuilt_internal.mk b/core/app_prebuilt_internal.mk
new file mode 100644
index 0000000..b429dca
--- /dev/null
+++ b/core/app_prebuilt_internal.mk
@@ -0,0 +1,280 @@
+#
+# 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.
+#
+
+############################################################
+# Internal build rules for APPS prebuilt modules
+############################################################
+
+ifneq (APPS,$(LOCAL_MODULE_CLASS))
+$(call pretty-error,app_prebuilt_internal.mk is for APPS modules only)
+endif
+
+ifdef LOCAL_COMPRESSED_MODULE
+ ifneq (true,$(LOCAL_COMPRESSED_MODULE))
+ $(call pretty-error, Unknown value for LOCAL_COMPRESSED_MODULE $(LOCAL_COMPRESSED_MODULE))
+ endif
+ LOCAL_BUILT_MODULE_STEM := package.apk.gz
+ ifndef LOCAL_INSTALLED_MODULE_STEM
+ PACKAGES.$(LOCAL_MODULE).COMPRESSED := gz
+ LOCAL_INSTALLED_MODULE_STEM := $(LOCAL_MODULE).apk.gz
+ endif
+else # LOCAL_COMPRESSED_MODULE
+ LOCAL_BUILT_MODULE_STEM := package.apk
+ ifndef LOCAL_INSTALLED_MODULE_STEM
+ LOCAL_INSTALLED_MODULE_STEM := $(LOCAL_MODULE).apk
+ endif
+endif # LOCAL_COMPRESSED_MODULE
+
+include $(BUILD_SYSTEM)/base_rules.mk
+built_module := $(LOCAL_BUILT_MODULE)
+
+# Run veridex on product, product_services and vendor modules.
+# We skip it for unbundled app builds where we cannot build veridex.
+module_run_appcompat :=
+ifeq (true,$(non_system_module))
+ifeq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK))) # ! unbundled app build
+ifneq ($(UNSAFE_DISABLE_HIDDENAPI_FLAGS),true)
+ module_run_appcompat := true
+endif
+endif
+endif
+
+PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
+
+my_extract_apk := $(strip $(LOCAL_EXTRACT_APK))
+
+# Select dpi-specific source
+ifdef LOCAL_DPI_VARIANTS
+my_dpi := $(firstword $(filter $(LOCAL_DPI_VARIANTS),$(PRODUCT_AAPT_PREF_CONFIG) $(PRODUCT_AAPT_PREBUILT_DPI)))
+ifdef my_dpi
+ifdef LOCAL_DPI_FILE_STEM
+my_prebuilt_dpi_file_stem := $(LOCAL_DPI_FILE_STEM)
+else
+my_prebuilt_dpi_file_stem := $(LOCAL_MODULE)_%.apk
+endif
+my_prebuilt_src_file := $(dir $(my_prebuilt_src_file))$(subst %,$(my_dpi),$(my_prebuilt_dpi_file_stem))
+
+ifneq ($(strip $(LOCAL_EXTRACT_DPI_APK)),)
+my_extract_apk := $(subst %,$(my_dpi),$(LOCAL_EXTRACT_DPI_APK))
+endif # LOCAL_EXTRACT_DPI_APK
+endif # my_dpi
+endif # LOCAL_DPI_VARIANTS
+
+ifdef my_extract_apk
+my_extracted_apk := $(intermediates)/extracted.apk
+
+$(my_extracted_apk): PRIVATE_EXTRACT := $(my_extract_apk)
+$(my_extracted_apk): $(my_prebuilt_src_file)
+ @echo Extract APK: $@
+ $(hide) mkdir -p $(dir $@) && rm -f $@
+ $(hide) unzip -p $< $(PRIVATE_EXTRACT) >$@
+
+my_prebuilt_src_file := $(my_extracted_apk)
+my_extracted_apk :=
+my_extract_apk :=
+ifeq ($(PRODUCT_ALWAYS_PREOPT_EXTRACTED_APK),true)
+# If the product property is set, always preopt for extracted modules to prevent executing out of
+# the APK.
+my_preopt_for_extracted_apk := true
+endif
+endif
+
+dex_preopt_profile_src_file := $(my_prebuilt_src_file)
+
+rs_compatibility_jni_libs :=
+include $(BUILD_SYSTEM)/install_jni_libs.mk
+
+ifeq ($(LOCAL_CERTIFICATE),EXTERNAL)
+ # The magic string "EXTERNAL" means this package will be signed with
+ # the default dev key throughout the build process, but we expect
+ # the final package to be signed with a different key.
+ #
+ # This can be used for packages where we don't have access to the
+ # keys, but want the package to be predexopt'ed.
+ LOCAL_CERTIFICATE := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
+ PACKAGES.$(LOCAL_MODULE).EXTERNAL_KEY := 1
+
+ $(built_module) : $(LOCAL_CERTIFICATE).pk8 $(LOCAL_CERTIFICATE).x509.pem
+ $(built_module) : PRIVATE_PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
+ $(built_module) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
+endif
+ifeq ($(LOCAL_CERTIFICATE),)
+ # It is now a build error to add a prebuilt .apk without
+ # specifying a key for it.
+ $(error No LOCAL_CERTIFICATE specified for prebuilt "$(my_prebuilt_src_file)")
+else ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)
+ # The magic string "PRESIGNED" means this package is already checked
+ # signed with its release key.
+ #
+ # By setting .CERTIFICATE but not .PRIVATE_KEY, this package will be
+ # mentioned in apkcerts.txt (with certificate set to "PRESIGNED")
+ # but the dexpreopt process will not try to re-sign the app.
+ PACKAGES.$(LOCAL_MODULE).CERTIFICATE := PRESIGNED
+ PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
+else
+ # If this is not an absolute certificate, assign it to a generic one.
+ ifeq ($(dir $(strip $(LOCAL_CERTIFICATE))),./)
+ LOCAL_CERTIFICATE := $(dir $(DEFAULT_SYSTEM_DEV_CERTIFICATE))$(LOCAL_CERTIFICATE)
+ endif
+
+ PACKAGES.$(LOCAL_MODULE).PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
+ PACKAGES.$(LOCAL_MODULE).CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
+ PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
+
+ $(built_module) : $(LOCAL_CERTIFICATE).pk8 $(LOCAL_CERTIFICATE).x509.pem
+ $(built_module) : PRIVATE_PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
+ $(built_module) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
+endif
+
+include $(BUILD_SYSTEM)/app_certificate_validate.mk
+
+# Disable dex-preopt of prebuilts to save space, if requested.
+ifndef LOCAL_DEX_PREOPT
+ifeq ($(DONT_DEXPREOPT_PREBUILTS),true)
+LOCAL_DEX_PREOPT := false
+endif
+endif
+
+# If the module is a compressed module, we don't pre-opt it because its final
+# installation location will be the data partition.
+ifdef LOCAL_COMPRESSED_MODULE
+LOCAL_DEX_PREOPT := false
+endif
+
+my_dex_jar := $(my_prebuilt_src_file)
+
+#######################################
+# defines built_odex along with rule to install odex
+include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
+#######################################
+ifneq ($(LOCAL_REPLACE_PREBUILT_APK_INSTALLED),)
+# There is a replacement for the prebuilt .apk we can install without any processing.
+$(built_module) : $(LOCAL_REPLACE_PREBUILT_APK_INSTALLED)
+ $(transform-prebuilt-to-target)
+
+else # ! LOCAL_REPLACE_PREBUILT_APK_INSTALLED
+# Sign and align non-presigned .apks.
+# The embedded prebuilt jni to uncompress.
+ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)
+# For PRESIGNED apks we must uncompress every .so file:
+# even if the .so file isn't for the current TARGET_ARCH,
+# we can't strip the file.
+embedded_prebuilt_jni_libs :=
+endif
+ifndef embedded_prebuilt_jni_libs
+# No LOCAL_PREBUILT_JNI_LIBS, uncompress all.
+embedded_prebuilt_jni_libs :=
+endif
+$(built_module): PRIVATE_EMBEDDED_JNI_LIBS := $(embedded_prebuilt_jni_libs)
+
+ifdef LOCAL_COMPRESSED_MODULE
+$(built_module) : $(MINIGZIP)
+endif
+
+ifeq ($(module_run_appcompat),true)
+$(built_module) : $(appcompat-files)
+$(LOCAL_BUILT_MODULE): PRIVATE_INSTALLED_MODULE := $(LOCAL_INSTALLED_MODULE)
+endif
+
+ifneq ($(BUILD_PLATFORM_ZIP),)
+$(built_module) : .KATI_IMPLICIT_OUTPUTS := $(dir $(LOCAL_BUILT_MODULE))package.dex.apk
+endif
+ifneq ($(LOCAL_CERTIFICATE),PRESIGNED)
+ifdef LOCAL_DEX_PREOPT
+$(built_module) : PRIVATE_STRIP_SCRIPT := $(intermediates)/strip.sh
+$(built_module) : $(intermediates)/strip.sh
+$(built_module) : | $(DEXPREOPT_STRIP_DEPS)
+$(built_module) : .KATI_DEPFILE := $(built_module).d
+endif
+endif
+$(built_module) : $(my_prebuilt_src_file) | $(ZIPALIGN) $(ZIP2ZIP) $(SIGNAPK_JAR)
+ $(transform-prebuilt-to-target)
+ $(uncompress-prebuilt-embedded-jni-libs)
+ifeq (true, $(LOCAL_UNCOMPRESS_DEX))
+ $(uncompress-dexs)
+endif # LOCAL_UNCOMPRESS_DEX
+ifdef LOCAL_DEX_PREOPT
+ifneq ($(BUILD_PLATFORM_ZIP),)
+ @# Keep a copy of apk with classes.dex unstripped
+ $(hide) cp -f $@ $(dir $@)package.dex.apk
+endif # BUILD_PLATFORM_ZIP
+endif # LOCAL_DEX_PREOPT
+ifneq ($(LOCAL_CERTIFICATE),PRESIGNED)
+ @# Only strip out files if we can re-sign the package.
+# Run appcompat before stripping the classes.dex file.
+ifeq ($(module_run_appcompat),true)
+ifeq ($(LOCAL_USE_AAPT2),true)
+ $(call appcompat-header, aapt2)
+else
+ $(appcompat-header)
+endif
+ $(run-appcompat)
+endif # module_run_appcompat
+ifdef LOCAL_DEX_PREOPT
+ mv -f $@ $@.tmp
+ $(PRIVATE_STRIP_SCRIPT) $@.tmp $@
+endif # LOCAL_DEX_PREOPT
+ $(sign-package)
+ # No need for align-package because sign-package takes care of alignment
+else # LOCAL_CERTIFICATE == PRESIGNED
+ $(align-package)
+endif # LOCAL_CERTIFICATE
+ifdef LOCAL_COMPRESSED_MODULE
+ $(compress-package)
+endif # LOCAL_COMPRESSED_MODULE
+endif # ! LOCAL_REPLACE_PREBUILT_APK_INSTALLED
+
+
+###############################
+## Install split apks.
+ifdef LOCAL_PACKAGE_SPLITS
+ifdef LOCAL_COMPRESSED_MODULE
+$(error $(LOCAL_MODULE): LOCAL_COMPRESSED_MODULE is not currently supported for split installs)
+endif # LOCAL_COMPRESSED_MODULE
+
+# LOCAL_PACKAGE_SPLITS is a list of apks to be installed.
+built_apk_splits := $(addprefix $(intermediates)/,$(notdir $(LOCAL_PACKAGE_SPLITS)))
+installed_apk_splits := $(addprefix $(my_module_path)/,$(notdir $(LOCAL_PACKAGE_SPLITS)))
+
+# Rules to sign the split apks.
+my_src_dir := $(sort $(dir $(LOCAL_PACKAGE_SPLITS)))
+ifneq (1,$(words $(my_src_dir)))
+$(error You must put all the split source apks in the same folder: $(LOCAL_PACKAGE_SPLITS))
+endif
+my_src_dir := $(LOCAL_PATH)/$(my_src_dir)
+
+$(built_apk_splits) : $(LOCAL_CERTIFICATE).pk8 $(LOCAL_CERTIFICATE).x509.pem
+$(built_apk_splits) : PRIVATE_PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
+$(built_apk_splits) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
+$(built_apk_splits) : $(intermediates)/%.apk : $(my_src_dir)/%.apk
+ $(copy-file-to-new-target)
+ $(sign-package)
+
+# Rules to install the split apks.
+$(installed_apk_splits) : $(my_module_path)/%.apk : $(intermediates)/%.apk
+ @echo "Install: $@"
+ $(copy-file-to-new-target)
+
+# Register the additional built and installed files.
+ALL_MODULES.$(my_register_name).INSTALLED += $(installed_apk_splits)
+ALL_MODULES.$(my_register_name).BUILT_INSTALLED += \
+ $(foreach s,$(LOCAL_PACKAGE_SPLITS),$(intermediates)/$(notdir $(s)):$(my_module_path)/$(notdir $(s)))
+
+# Make sure to install the splits when you run "make <module_name>".
+$(my_all_targets): $(installed_apk_splits)
+
+endif # LOCAL_PACKAGE_SPLITS
+
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 2fbf524..7e7d6dc 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -242,6 +242,33 @@
partition_tag := $(if $(call should-install-to-system,$(my_module_tags)),,_DATA)
endif
endif
+# For test modules that lack a suite tag, set null-suite as the default.
+# We only support adding a default suite to native tests, native benchmarks, and instrumentation tests.
+# This is because they are the only tests we currently auto-generate test configs for.
+ifndef LOCAL_COMPATIBILITY_SUITE
+ ifneq ($(filter NATIVE_TESTS NATIVE_BENCHMARK, $(LOCAL_MODULE_CLASS)),)
+ LOCAL_COMPATIBILITY_SUITE := null-suite
+ endif
+ ifneq ($(filter APPS, $(LOCAL_MODULE_CLASS)),)
+ ifneq ($(filter $(my_module_tags),tests),)
+ LOCAL_COMPATIBILITY_SUITE := null-suite
+ endif
+ endif
+endif
+
+use_testcase_folder :=
+ifdef ENABLE_DEFAULT_TEST_LOCATION
+ ifeq ($(my_module_path),)
+ ifneq ($(LOCAL_MODULE),$(filter $(LOCAL_MODULE),$(DEFAULT_DATA_OUT_MODULES)))
+ ifdef LOCAL_COMPATIBILITY_SUITE
+ ifneq (true, $(LOCAL_IS_HOST_MODULE))
+ use_testcase_folder := true
+ endif
+ endif
+ endif
+ endif
+endif
+
ifeq ($(my_module_path),)
install_path_var := $(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT$(partition_tag)_$(LOCAL_MODULE_CLASS)
ifeq (true,$(LOCAL_PRIVILEGED_MODULE))
@@ -249,6 +276,16 @@
endif
my_module_path := $($(install_path_var))
+
+ # If use_testcase_folder be set, and LOCAL_MODULE_PATH not set,
+ # overwrite the default path under testcase.
+ ifeq ($(use_testcase_folder),true)
+ arch_dir := $($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
+ testcase_folder := $($(my_prefix)OUT_TESTCASES)/$(LOCAL_MODULE)/$(arch_dir)
+ my_module_path := $(testcase_folder)
+ arch_dir :=
+ endif
+
ifeq ($(strip $(my_module_path)),)
$(error $(LOCAL_PATH): unhandled install path "$(install_path_var) for $(LOCAL_MODULE)")
endif
@@ -324,7 +361,9 @@
# Neither do Runtime Resource Overlay apks, which contain just the overlaid resources.
else ifeq ($(LOCAL_IS_RUNTIME_RESOURCE_OVERLAY),true)
else
- my_module_path := $(my_module_path)/$(LOCAL_MODULE)
+ ifneq ($(use_testcase_folder),true)
+ my_module_path := $(my_module_path)/$(LOCAL_MODULE)
+ endif
endif
endif
LOCAL_INSTALLED_MODULE := $(my_module_path)/$(my_installed_module_stem)
@@ -429,12 +468,21 @@
my_init_rc_installed :=
my_init_rc_pairs :=
my_installed_symlinks :=
+my_default_test_module :=
+ifeq ($(use_testcase_folder),true)
+arch_dir := $($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
+my_default_test_module := $($(my_prefix)OUT_TESTCASES)/$(LOCAL_MODULE)/$(arch_dir)/$(my_installed_module_stem)
+arch_dir :=
+endif
+
ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
+ifneq ($(LOCAL_INSTALLED_MODULE),$(my_default_test_module))
$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
$(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE)
@echo "Install: $@"
$(copy-file-to-new-target)
$(PRIVATE_POST_INSTALL_CMD)
+endif
ifndef LOCAL_IS_HOST_MODULE
# Rule to install the module's companion init.rc.
@@ -544,20 +592,6 @@
endif
endif
-# For test modules that lack a suite tag, set null-suite as the default.
-# We only support adding a default suite to native tests, native benchmarks, and instrumentation tests.
-# This is because they are the only tests we currently auto-generate test configs for.
-ifndef LOCAL_COMPATIBILITY_SUITE
-ifneq ($(filter NATIVE_TESTS NATIVE_BENCHMARK, $(LOCAL_MODULE_CLASS)),)
-LOCAL_COMPATIBILITY_SUITE := null-suite
-endif
-ifneq ($(filter APPS, $(LOCAL_MODULE_CLASS)),)
-ifneq ($(filter $(my_module_tags),tests),)
-LOCAL_COMPATIBILITY_SUITE := null-suite
-endif
-endif
-endif
-
###########################################################
## Compatibility suite files.
###########################################################
@@ -575,11 +609,24 @@
ifdef LOCAL_MULTILIB
multi_arch := true
endif
+
ifdef multi_arch
+arch_dir := /$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
+else
+ifeq ($(use_testcase_folder),true)
arch_dir := /$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)
endif
+endif
+
multi_arch :=
+my_default_test_module :=
+my_default_test_module := $($(my_prefix)OUT_TESTCASES)/$(LOCAL_MODULE)$(arch_dir)/$(my_installed_module_stem)
+ifneq ($(LOCAL_INSTALLED_MODULE),$(my_default_test_module))
+# Install into the testcase folder
+$(LOCAL_INSTALLED_MODULE) : $(my_default_test_module)
+endif
+
# The module itself.
$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
$(eval my_compat_dist_$(suite) := $(foreach dir, $(call compatibility_suite_dirs,$(suite),$(arch_dir)), \
@@ -671,6 +718,17 @@
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))) \
@@ -680,6 +738,9 @@
$(eval my_compat_dist_$(suite) += $(foreach dir, $(call compatibility_suite_dirs,$(suite),$(arch_dir)), \
$(src_path):$(call append-path,$(dir),$(file))))))
endif
+endif
+
+
arch_dir :=
is_native :=
@@ -715,6 +776,10 @@
$(ALL_MODULES.$(my_register_name).CHECKED) $(my_checked_module)
ALL_MODULES.$(my_register_name).BUILT := \
$(ALL_MODULES.$(my_register_name).BUILT) $(LOCAL_BUILT_MODULE)
+ifndef LOCAL_IS_HOST_MODULE
+ALL_MODULES.$(my_register_name).TARGET_BUILT := \
+ $(ALL_MODULES.$(my_register_name).TARGET_BUILT) $(LOCAL_BUILT_MODULE)
+endif
ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
ALL_MODULES.$(my_register_name).INSTALLED := \
$(strip $(ALL_MODULES.$(my_register_name).INSTALLED) \
diff --git a/core/binary.mk b/core/binary.mk
index ad3d76b..da188ae 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1214,17 +1214,17 @@
# with vendor_available: false
my_link_type := native:vendor
my_warn_types :=
- my_allowed_types := native:vendor native:vndk
+ my_allowed_types := native:vendor native:vndk native:platform_vndk
endif
else ifneq ($(filter $(TARGET_RECOVERY_OUT)/%,$(call get_non_asan_path,$(LOCAL_MODULE_PATH))),)
my_link_type := native:recovery
my_warn_types :=
# TODO(b/113303515) remove native:platform and my_allowed_ndk_types
-my_allowed_types := native:recovery native:platform $(my_allowed_ndk_types)
+my_allowed_types := native:recovery native:platform native:platform_vndk $(my_allowed_ndk_types)
else
my_link_type := native:platform
my_warn_types := $(my_warn_ndk_types)
-my_allowed_types := $(my_allowed_ndk_types) native:platform
+my_allowed_types := $(my_allowed_ndk_types) native:platform native:platform_vndk
endif
my_link_deps := $(addprefix STATIC_LIBRARIES:,$(my_whole_static_libraries) $(my_static_libraries))
diff --git a/core/check_elf_file.mk b/core/check_elf_file.mk
index 8f2eafb..0faaadd 100644
--- a/core/check_elf_file.mk
+++ b/core/check_elf_file.mk
@@ -13,14 +13,18 @@
# - intermediates
# - my_installed_module_stem
# - my_prebuilt_src_file
+# - my_check_elf_file_shared_lib_files
ifndef LOCAL_IS_HOST_MODULE
ifneq ($(filter $(LOCAL_MODULE_CLASS),SHARED_LIBRARIES EXECUTABLES NATIVE_TESTS),)
check_elf_files_stamp := $(intermediates)/check_elf_files.timestamp
$(check_elf_files_stamp): PRIVATE_SONAME := $(if $(filter $(LOCAL_MODULE_CLASS),SHARED_LIBRARIES),$(my_installed_module_stem))
$(check_elf_files_stamp): PRIVATE_ALLOW_UNDEFINED_SYMBOLS := $(LOCAL_ALLOW_UNDEFINED_SYMBOLS)
-$(check_elf_files_stamp): PRIVATE_SHARED_LIBRARY_FILES := # This variable will be set by `core/main.mk`
-$(check_elf_files_stamp): $(my_prebuilt_src_file) $(CHECK_ELF_FILE) $(LLVM_READOBJ)
+# PRIVATE_SHARED_LIBRARY_FILES are file paths to built shared libraries.
+# In addition to $(my_check_elf_file_shared_lib_files), some file paths are
+# added by `resolve-shared-libs-for-elf-file-check` from `core/main.mk`.
+$(check_elf_files_stamp): PRIVATE_SHARED_LIBRARY_FILES := $(my_check_elf_file_shared_lib_files)
+$(check_elf_files_stamp): $(my_prebuilt_src_file) $(my_check_elf_file_shared_lib_files) $(CHECK_ELF_FILE) $(LLVM_READOBJ)
@echo Check prebuilt ELF binary: $<
$(hide) mkdir -p $(dir $@)
$(hide) rm -f $@
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 7485b8b..d67c9f8 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -266,6 +266,7 @@
LOCAL_SOONG_DEVICE_RRO_DIRS :=
LOCAL_SOONG_PRODUCT_RRO_DIRS :=
LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES :=
+LOCAL_SOONG_SYMBOL_PATH :=
LOCAL_SOONG_TOC :=
LOCAL_SOONG_UNSTRIPPED_BINARY :=
# '',true
@@ -296,6 +297,7 @@
LOCAL_USES_LIBRARIES:=
LOCAL_VENDOR_MODULE:=
LOCAL_VINTF_FRAGMENTS:=
+LOCAL_VNDK_DEPEND_ON_CORE_VARIANT:=
LOCAL_VTSC_FLAGS:=
LOCAL_VTS_INCLUDES:=
LOCAL_VTS_MODE:=
diff --git a/core/combo/arch/x86/amberlake.mk b/core/combo/arch/x86/amberlake.mk
new file mode 100644
index 0000000..37100a4
--- /dev/null
+++ b/core/combo/arch/x86/amberlake.mk
@@ -0,0 +1,13 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors
+# that have AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86/broadwell.mk b/core/combo/arch/x86/broadwell.mk
new file mode 100644
index 0000000..37100a4
--- /dev/null
+++ b/core/combo/arch/x86/broadwell.mk
@@ -0,0 +1,13 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors
+# that have AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86/icelake.mk b/core/combo/arch/x86/icelake.mk
new file mode 100644
index 0000000..76fe212
--- /dev/null
+++ b/core/combo/arch/x86/icelake.mk
@@ -0,0 +1,14 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors
+# that have AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_AVX512 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86/kabylake.mk b/core/combo/arch/x86/kabylake.mk
new file mode 100644
index 0000000..50518d6
--- /dev/null
+++ b/core/combo/arch/x86/kabylake.mk
@@ -0,0 +1,13 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors.
+# that support AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86/skylake.mk b/core/combo/arch/x86/skylake.mk
new file mode 100644
index 0000000..03705c0
--- /dev/null
+++ b/core/combo/arch/x86/skylake.mk
@@ -0,0 +1,15 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors.
+# that support AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_AVX512 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
+
diff --git a/core/combo/arch/x86/stoneyridge.mk b/core/combo/arch/x86/stoneyridge.mk
new file mode 100644
index 0000000..30405a1
--- /dev/null
+++ b/core/combo/arch/x86/stoneyridge.mk
@@ -0,0 +1,12 @@
+# Configuration for Linux on x86.
+# Generating binaries for Stoney Ridge processors.
+#
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AES_NI := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86/tigerlake.mk b/core/combo/arch/x86/tigerlake.mk
new file mode 100644
index 0000000..76fe212
--- /dev/null
+++ b/core/combo/arch/x86/tigerlake.mk
@@ -0,0 +1,14 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors
+# that have AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_AVX512 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86/whiskeylake.mk b/core/combo/arch/x86/whiskeylake.mk
new file mode 100644
index 0000000..37100a4
--- /dev/null
+++ b/core/combo/arch/x86/whiskeylake.mk
@@ -0,0 +1,13 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors
+# that have AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86/x86.mk b/core/combo/arch/x86/x86.mk
index a55cc7a..db55ff8 100644
--- a/core/combo/arch/x86/x86.mk
+++ b/core/combo/arch/x86/x86.mk
@@ -11,3 +11,6 @@
ARCH_X86_HAVE_SSSE3 := false
ARCH_X86_HAVE_MOVBE := false
ARCH_X86_HAVE_POPCNT := false
+ARCH_X86_HAVE_AVX := false
+ARCH_X86_HAVE_AVX2 := false
+ARCH_X86_HAVE_AVX512 := false
diff --git a/core/combo/arch/x86_64/amberlake.mk b/core/combo/arch/x86_64/amberlake.mk
new file mode 100644
index 0000000..37100a4
--- /dev/null
+++ b/core/combo/arch/x86_64/amberlake.mk
@@ -0,0 +1,13 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors
+# that have AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86_64/broadwell.mk b/core/combo/arch/x86_64/broadwell.mk
new file mode 100644
index 0000000..37100a4
--- /dev/null
+++ b/core/combo/arch/x86_64/broadwell.mk
@@ -0,0 +1,13 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors
+# that have AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86_64/icelake.mk b/core/combo/arch/x86_64/icelake.mk
new file mode 100644
index 0000000..76fe212
--- /dev/null
+++ b/core/combo/arch/x86_64/icelake.mk
@@ -0,0 +1,14 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors
+# that have AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_AVX512 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86_64/kabylake.mk b/core/combo/arch/x86_64/kabylake.mk
new file mode 100644
index 0000000..37100a4
--- /dev/null
+++ b/core/combo/arch/x86_64/kabylake.mk
@@ -0,0 +1,13 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors
+# that have AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86_64/skylake.mk b/core/combo/arch/x86_64/skylake.mk
new file mode 100644
index 0000000..76fe212
--- /dev/null
+++ b/core/combo/arch/x86_64/skylake.mk
@@ -0,0 +1,14 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors
+# that have AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_AVX512 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86_64/stoneyridge.mk b/core/combo/arch/x86_64/stoneyridge.mk
new file mode 100644
index 0000000..f7d9583
--- /dev/null
+++ b/core/combo/arch/x86_64/stoneyridge.mk
@@ -0,0 +1,12 @@
+# Configuration for Linux on x86_64.
+# Generating binaries for Stoney Ridge processors.
+#
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AES_NI := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86_64/tigerlake.mk b/core/combo/arch/x86_64/tigerlake.mk
new file mode 100644
index 0000000..76fe212
--- /dev/null
+++ b/core/combo/arch/x86_64/tigerlake.mk
@@ -0,0 +1,14 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors
+# that have AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_AVX512 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86_64/whiskeylake.mk b/core/combo/arch/x86_64/whiskeylake.mk
new file mode 100644
index 0000000..37100a4
--- /dev/null
+++ b/core/combo/arch/x86_64/whiskeylake.mk
@@ -0,0 +1,13 @@
+# Configuration for Linux on x86.
+# Generating binaries for processors
+# that have AVX2 feature flag
+#
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_SSE4 := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := true
+ARCH_X86_HAVE_AVX2 := true
+ARCH_X86_HAVE_POPCNT := true
+ARCH_X86_HAVE_MOVBE := true
diff --git a/core/combo/arch/x86_64/x86_64.mk b/core/combo/arch/x86_64/x86_64.mk
index 26a9d0f..e7c8928 100755
--- a/core/combo/arch/x86_64/x86_64.mk
+++ b/core/combo/arch/x86_64/x86_64.mk
@@ -11,3 +11,6 @@
ARCH_X86_HAVE_SSE4 := true
ARCH_X86_HAVE_SSE4_1 := true
ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX := false
+ARCH_X86_HAVE_AVX2 := false
+ARCH_X86_HAVE_AVX512 := false
diff --git a/core/config.mk b/core/config.mk
index 242558e..cca6200 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -836,17 +836,18 @@
ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
$(error BOARD_BUILD_SYSTEM_ROOT_IMAGE cannot be true for devices with dynamic partitions)
endif
-
- requirements := \
- PRODUCT_USE_DYNAMIC_PARTITION_SIZE \
- PRODUCT_BUILD_SUPER_PARTITION \
-
- $(foreach req,$(requirements),$(if $(filter false,$($(req))),\
- $(error PRODUCT_USE_DYNAMIC_PARTITIONS requires $(req) to be true)))
-
- requirements :=
+ ifneq ($(PRODUCT_USE_DYNAMIC_PARTITION_SIZE),true)
+ $(error PRODUCT_USE_DYNAMIC_PARTITION_SIZE must be true for devices with dynamic partitions)
+ endif
endif
+ifeq ($(PRODUCT_BUILD_SUPER_PARTITION),true)
+ ifneq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true)
+ $(error Can only build super partition for devices with dynamic partitions)
+ endif
+endif
+
+
ifeq ($(PRODUCT_USE_DYNAMIC_PARTITION_SIZE),true)
ifneq ($(BOARD_SYSTEMIMAGE_PARTITION_SIZE),)
@@ -886,7 +887,7 @@
endif # PRODUCT_USE_DYNAMIC_PARTITION_SIZE
-ifeq ($(PRODUCT_BUILD_SUPER_PARTITION),true)
+ifeq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true)
# BOARD_SUPER_PARTITION_GROUPS defines a list of "updatable groups". Each updatable group is a
# group of partitions that share the same pool of free spaces.
@@ -897,12 +898,16 @@
# - 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)_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) \
)
+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) \
+)
+endif # PRODUCT_BUILD_SUPER_PARTITION
# BOARD_*_PARTITION_LIST: a list of the following tokens
valid_super_partition_list := system vendor product product_services odm
@@ -924,6 +929,10 @@
$(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)
@@ -1174,4 +1183,12 @@
include $(BUILD_SYSTEM)/soong_config.mk
endif
+# If ENABLE_DEFAULT_TEST_LOCATION is true, move default install path from
+# $(my_prefix)OUT_DATA to $(my_prefix)OUT_TESTCASES
+ENABLE_DEFAULT_TEST_LOCATION := true
+-include external/linux-kselftest/android/kselftest_test_list.mk
+-include external/ltp/android/ltp_package_list.mk
+DEFAULT_DATA_OUT_MODULES := ltp $(ltp_packages) $(kselftest_modules)
+.KATI_READONLY := ENABLE_DEFAULT_TEST_LOCATION DEFAULT_DATA_OUT_MODULES
+
include $(BUILD_SYSTEM)/dumpvar.mk
diff --git a/core/definitions.mk b/core/definitions.mk
index ce6a941..02b737c 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -651,6 +651,18 @@
###########################################################
## Convert a list of short modules names (e.g., "framework", "Browser")
+## into the list of files that are built *for the target* for those modules.
+## NOTE: this won't return reliable results until after all
+## sub-makefiles have been included.
+## $(1): target list
+###########################################################
+
+define module-target-built-files
+$(foreach module,$(1),$(ALL_MODULES.$(module).TARGET_BUILT))
+endef
+
+###########################################################
+## Convert a list of short modules names (e.g., "framework", "Browser")
## into the list of files that should be used when linking
## against that module as a public API.
## TODO: Allow this for more than JAVA_LIBRARIES modules
@@ -2478,6 +2490,25 @@
$$(align-package)
endef
+# Create copy pair for compatibility suite
+# Filter out $(LOCAL_INSTALLED_MODULE) to prevent overriding target
+# $(1): source path
+# $(2): destination path
+# The format of copy pair is src:dst
+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
@@ -3367,3 +3398,19 @@
initialize-package-file \
add-jni-shared-libs-to-package,\
These functions have been removed)
+
+###########################################################
+## Verify the variants of a VNDK library are identical
+##
+## $(1): Path to the core variant shared library file.
+## $(2): Path to the vendor variant shared library file.
+## $(3): TOOLS_PREFIX
+###########################################################
+LIBRARY_IDENTITY_CHECK_SCRIPT := build/make/tools/check_identical_lib.sh
+define verify-vndk-libs-identical
+@echo "Checking VNDK vendor variant: $(2)"
+$(hide) CLANG_BIN="$(LLVM_PREBUILTS_PATH)" \
+ CROSS_COMPILE="$(strip $(3))" \
+ XZ="$(XZ)" \
+ $(LIBRARY_IDENTITY_CHECK_SCRIPT) $(SOONG_STRIP_PATH) $(1) $(2)
+endef
diff --git a/core/dpi_specific_apk.mk b/core/dpi_specific_apk.mk
index ad734b5..ad073c7 100644
--- a/core/dpi_specific_apk.mk
+++ b/core/dpi_specific_apk.mk
@@ -67,6 +67,7 @@
ALL_MODULES += $(dpi_apk_name)
ALL_MODULES.$(dpi_apk_name).CLASS := APPS
ALL_MODULES.$(dpi_apk_name).BUILT := $(built_dpi_apk)
+ALL_MODULES.$(dpi_apk_name).TARGET_BUILT := $(built_dpi_apk)
PACKAGES := $(PACKAGES) $(dpi_apk_name)
PACKAGES.$(dpi_apk_name).PRIVATE_KEY := $(private_key)
PACKAGES.$(dpi_apk_name).CERTIFICATE := $(certificate)
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 506ec4d..1704daf 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -523,6 +523,11 @@
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_APPS_PRIVILEGED \
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_TESTCASES
+MODULE_CLASS_APPS := app
+MODULE_CLASS_EXECUTABLES := bin
+MODULE_CLASS_JAVA_LIBRARIES := framework
+MODULE_CLASS_NATIVE_TESTS := nativetest
+MODULE_CLASS_METRIC_TESTS := benchmarktest
TARGET_OUT_DATA := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_DATA)
TARGET_OUT_DATA_EXECUTABLES := $(TARGET_OUT_EXECUTABLES)
TARGET_OUT_DATA_SHARED_LIBRARIES := $(TARGET_OUT_SHARED_LIBRARIES)
@@ -542,6 +547,7 @@
TARGET_OUT_VENDOR_NATIVE_TESTS := $(TARGET_OUT_DATA)/nativetest$(TARGET_VENDOR_TEST_SUFFIX)
TARGET_OUT_VENDOR_METRIC_TESTS := $(TARGET_OUT_DATA)/benchmarktest$(TARGET_VENDOR_TEST_SUFFIX)
endif
+MODULE_CLASS_FAKE := fake_packages
TARGET_OUT_DATA_FAKE := $(TARGET_OUT_DATA)/fake_packages
.KATI_READONLY := \
TARGET_OUT_DATA \
@@ -556,7 +562,13 @@
TARGET_OUT_DATA_METRIC_TESTS \
TARGET_OUT_VENDOR_NATIVE_TESTS \
TARGET_OUT_VENDOR_METRIC_TESTS \
- TARGET_OUT_DATA_FAKE
+ TARGET_OUT_DATA_FAKE \
+ MODULE_CLASS_APPS \
+ MODULE_CLASS_EXECUTABLES \
+ MODULE_CLASS_JAVA_LIBRARIES \
+ MODULE_CLASS_NATIVE_TESTS \
+ MODULE_CLASS_METRIC_TESTS \
+ MODULE_CLASS_FAKE
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_EXECUTABLES := $(TARGET_OUT_DATA_EXECUTABLES)
$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_SHARED_LIBRARIES := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES)
diff --git a/core/install_jni_libs_internal.mk b/core/install_jni_libs_internal.mk
index e0f1ad4..a79a49a 100644
--- a/core/install_jni_libs_internal.mk
+++ b/core/install_jni_libs_internal.mk
@@ -113,12 +113,12 @@
my_warn_types := native:platform $(my_warn_ndk_types)
my_allowed_types := $(my_allowed_ndk_types)
ifneq (,$(filter true,$(LOCAL_VENDOR_MODULE) $(LOCAL_ODM_MODULE) $(LOCAL_PROPRIETARY_MODULE)))
- my_allowed_types += native:vendor native:vndk
+ my_allowed_types += native:vendor native:vndk native:platform_vndk
endif
else
my_link_type := app:platform
my_warn_types := $(my_warn_ndk_types)
-my_allowed_types := $(my_allowed_ndk_types) native:platform native:vendor native:vndk native:vndk_private
+my_allowed_types := $(my_allowed_ndk_types) native:platform native:vendor native:vndk native:vndk_private native:platform_vndk
endif
my_link_deps := $(addprefix SHARED_LIBRARIES:,$(LOCAL_JNI_SHARED_LIBRARIES))
diff --git a/core/main.mk b/core/main.mk
index 5d97027..43c80ee 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -257,6 +257,15 @@
ADDITIONAL_PRODUCT_PROPERTIES += dalvik.vm.systemservercompilerfilter=$(PRODUCT_SYSTEM_SERVER_COMPILER_FILTER)
endif
+# Sets the default value of ro.postinstall.fstab.prefix to /system.
+# Device board config should override the value to /product when needed by:
+#
+# PRODUCT_PRODUCT_PROPERTIES += ro.postinstall.fstab.prefix=/product
+#
+# It then uses ${ro.postinstall.fstab.prefix}/etc/fstab.postinstall to
+# mount system_other partition.
+ADDITIONAL_DEFAULT_PROPERTIES += ro.postinstall.fstab.prefix=/system
+
# -----------------------------------------------------------------
###
### In this section we set up the things that are different
@@ -492,6 +501,10 @@
subdir_makefiles_total := $(words init post finish)
endif
+droid_targets: no_vendor_variant_vndk_check
+.PHONY: no_vendor_variant_vndk_check
+no_vendor_variant_vndk_check:
+
$(info [$(call inc_and_print,subdir_makefiles_inc)/$(subdir_makefiles_total)] finishing build rules ...)
# -------------------------------------------------------------------
@@ -1135,27 +1148,28 @@
)
endef
-ifeq (true|,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ENFORCE_PACKAGES_EXIST)|$(filter true,$(ALLOW_MISSING_DEPENDENCIES)))
- _whitelist := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ENFORCE_PACKAGES_EXIST_WHITELIST)
- _modules := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES)
- # Sanity check all modules in PRODUCT_PACKAGES exist. We check for the
- # existence if either <module> or the <module>_32 variant.
- _nonexistant_modules := $(filter-out $(ALL_MODULES),$(_modules))
- _nonexistant_modules := $(foreach m,$(_nonexistant_modules),\
- $(if $(call get-32-bit-modules,$(m)),,$(m)))
- $(call maybe-print-list-and-error,$(filter-out $(_whitelist),$(_nonexistant_modules)),\
- $(INTERNAL_PRODUCT) includes non-existant modules in PRODUCT_PACKAGES)
- $(call maybe-print-list-and-error,$(filter-out $(_nonexistant_modules),$(_whitelist)),\
- $(INTERNAL_PRODUCT) includes redundant whitelist entries for nonexistant PRODUCT_PACKAGES)
-endif
-
ifdef FULL_BUILD
- # Check to ensure that all modules in PRODUCT_HOST_PACKAGES exist
- #
- # Many host modules are Linux-only, so skip this check on Mac. If we ever have Mac-only modules,
- # maybe it would make sense to have PRODUCT_HOST_PACKAGES_LINUX/_DARWIN?
- ifneq ($(HOST_OS),darwin)
- ifneq (true,$(ALLOW_MISSING_DEPENDENCIES))
+ ifneq (true,$(ALLOW_MISSING_DEPENDENCIES))
+ # Check to ensure that all modules in PRODUCT_PACKAGES exist (opt in per product)
+ ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ENFORCE_PACKAGES_EXIST))
+ _whitelist := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ENFORCE_PACKAGES_EXIST_WHITELIST)
+ _modules := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES)
+ # Sanity check all modules in PRODUCT_PACKAGES exist. We check for the
+ # existence if either <module> or the <module>_32 variant.
+ _nonexistant_modules := $(filter-out $(ALL_MODULES),$(_modules))
+ _nonexistant_modules := $(foreach m,$(_nonexistant_modules),\
+ $(if $(call get-32-bit-modules,$(m)),,$(m)))
+ $(call maybe-print-list-and-error,$(filter-out $(_whitelist),$(_nonexistant_modules)),\
+ $(INTERNAL_PRODUCT) includes non-existant modules in PRODUCT_PACKAGES)
+ $(call maybe-print-list-and-error,$(filter-out $(_nonexistant_modules),$(_whitelist)),\
+ $(INTERNAL_PRODUCT) includes redundant whitelist entries for nonexistant PRODUCT_PACKAGES)
+ endif
+
+ # Check to ensure that all modules in PRODUCT_HOST_PACKAGES exist
+ #
+ # Many host modules are Linux-only, so skip this check on Mac. If we ever have Mac-only modules,
+ # maybe it would make sense to have PRODUCT_HOST_PACKAGES_LINUX/_DARWIN?
+ ifneq ($(HOST_OS),darwin)
_modules := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_HOST_PACKAGES)
_nonexistant_modules := $(foreach m,$(_modules),\
$(if $(filter FAKE,$(ALL_MODULES.$(m).CLASS))$(filter $(HOST_OUT_ROOT)/%,$(ALL_MODULES.$(m).INSTALLED)),,$(m)))
@@ -1573,21 +1587,21 @@
ifeq ($(EMMA_INSTRUMENT),true)
$(JACOCO_REPORT_CLASSES_ALL) : $(INSTALLED_SYSTEMIMAGE_TARGET)
$(call dist-for-goals, dist_files, $(JACOCO_REPORT_CLASSES_ALL))
+ endif
- # Put XML formatted API files in the dist dir.
- $(TARGET_OUT_COMMON_INTERMEDIATES)/api.xml: $(call java-lib-header-files,android_stubs_current) $(APICHECK)
- $(TARGET_OUT_COMMON_INTERMEDIATES)/system-api.xml: $(call java-lib-header-files,android_system_stubs_current) $(APICHECK)
- $(TARGET_OUT_COMMON_INTERMEDIATES)/test-api.xml: $(call java-lib-header-files,android_test_stubs_current) $(APICHECK)
+ # Put XML formatted API files in the dist dir.
+ $(TARGET_OUT_COMMON_INTERMEDIATES)/api.xml: $(call java-lib-header-files,android_stubs_current) $(APICHECK)
+ $(TARGET_OUT_COMMON_INTERMEDIATES)/system-api.xml: $(call java-lib-header-files,android_system_stubs_current) $(APICHECK)
+ $(TARGET_OUT_COMMON_INTERMEDIATES)/test-api.xml: $(call java-lib-header-files,android_test_stubs_current) $(APICHECK)
- api_xmls := $(addprefix $(TARGET_OUT_COMMON_INTERMEDIATES)/,api.xml system-api.xml test-api.xml)
- $(api_xmls):
+ api_xmls := $(addprefix $(TARGET_OUT_COMMON_INTERMEDIATES)/,api.xml system-api.xml test-api.xml)
+ $(api_xmls):
$(hide) echo "Converting API file to XML: $@"
$(hide) mkdir -p $(dir $@)
$(hide) $(APICHECK_COMMAND) --input-api-jar $< --api-xml $@
- $(call dist-for-goals, dist_files, $(api_xmls))
- api_xmls :=
- endif
+ $(call dist-for-goals, dist_files, $(api_xmls))
+ api_xmls :=
# Building a full system-- the default is to build droidcore
droid_targets: droidcore dist_files
diff --git a/core/native_benchmark.mk b/core/native_benchmark.mk
index e73bcad..4750649 100644
--- a/core/native_benchmark.mk
+++ b/core/native_benchmark.mk
@@ -6,8 +6,10 @@
LOCAL_STATIC_LIBRARIES += libgoogle-benchmark
+ifndef ENABLE_DEFAULT_TEST_LOCATION
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_METRIC_TESTS)/$(LOCAL_MODULE)
LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_METRIC_TESTS)/$(LOCAL_MODULE)
+endif
ifndef LOCAL_MULTILIB
ifndef LOCAL_32_BIT_ONLY
diff --git a/core/ninja_config.mk b/core/ninja_config.mk
index 684ab9f..e9e89c3 100644
--- a/core/ninja_config.mk
+++ b/core/ninja_config.mk
@@ -50,7 +50,6 @@
user \
userdataimage \
userdebug \
- valgrind-test-art% \
vts \
win_sdk \
winsdk-tools
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 0998481..89296e6 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -762,10 +762,17 @@
ifdef LOCAL_COMPATIBILITY_SUITE
+ifndef ENABLE_DEFAULT_TEST_LOCATION
$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
$(eval my_compat_dist_$(suite) := $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
$(foreach s,$(my_split_suffixes),\
$(intermediates)/package_$(s).apk:$(dir)/$(LOCAL_MODULE)_$(s).apk))))
+else
+$(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \
+ $(eval my_compat_dist_$(suite) := $(foreach dir, $(call compatibility_suite_dirs,$(suite)), \
+ $(foreach s,$(my_split_suffixes),\
+ $(call compat-copy-pair,$(intermediates)/package_$(s).apk,$(dir)/$(LOCAL_MODULE)_$(s).apk)))))
+endif
$(call create-suite-dependencies)
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 49613e9..e505945 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -39,6 +39,13 @@
LOCAL_CHECKED_MODULE := $(my_prebuilt_src_file)
+ifeq (APPS,$(LOCAL_MODULE_CLASS))
+include $(BUILD_SYSTEM)/app_prebuilt_internal.mk
+else
+#
+# Non-APPS prebuilt modules handling almost to the end of the file
+#
+
my_strip_module := $(firstword \
$(LOCAL_STRIP_MODULE_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) \
$(LOCAL_STRIP_MODULE))
@@ -69,44 +76,11 @@
prebuilt_module_is_dex_javalib :=
endif
-# Run veridex on product, product_services and vendor modules.
-# We skip it for unbundled app builds where we cannot build veridex.
-module_run_appcompat :=
-ifeq (true,$(non_system_module))
-ifeq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK))) # ! unbundled app build
-ifneq ($(UNSAFE_DISABLE_HIDDENAPI_FLAGS),true)
- module_run_appcompat := true
-endif
-endif
-endif
-
-ifdef LOCAL_COMPRESSED_MODULE
-ifneq (true,$(LOCAL_COMPRESSED_MODULE))
-$(call pretty-error, Unknown value for LOCAL_COMPRESSED_MODULE $(LOCAL_COMPRESSED_MODULE))
-endif
-endif
-
-ifeq ($(LOCAL_MODULE_CLASS),APPS)
-ifdef LOCAL_COMPRESSED_MODULE
-LOCAL_BUILT_MODULE_STEM := package.apk.gz
-else
-LOCAL_BUILT_MODULE_STEM := package.apk
-endif # LOCAL_COMPRESSED_MODULE
-
-ifndef LOCAL_INSTALLED_MODULE_STEM
-ifdef LOCAL_COMPRESSED_MODULE
-PACKAGES.$(LOCAL_MODULE).COMPRESSED := gz
-LOCAL_INSTALLED_MODULE_STEM := $(LOCAL_MODULE).apk.gz
-else
-LOCAL_INSTALLED_MODULE_STEM := $(LOCAL_MODULE).apk
-endif # LOCAL_COMPRESSED_MODULE
-endif # LOCAL_INSTALLED_MODULE_STEM
-
-else # $(LOCAL_MODULE_CLASS) != APPS)
ifdef LOCAL_COMPRESSED_MODULE
$(error $(LOCAL_MODULE) : LOCAL_COMPRESSED_MODULE can only be defined for module class APPS)
endif # LOCAL_COMPRESSED_MODULE
-endif
+
+my_check_elf_file_shared_lib_files :=
ifneq ($(filter true keep_symbols no_debuglink mini-debug-info,$(my_strip_module)),)
ifdef LOCAL_IS_HOST_MODULE
@@ -123,6 +97,12 @@
include $(BUILD_SYSTEM)/dynamic_binary.mk
built_module := $(linked_module)
+ ifneq ($(LOCAL_SDK_VERSION),)
+ # binary.mk filters out NDK_MIGRATED_LIBS from my_shared_libs, thus those NDK libs are not added
+ # to DEPENDENCIES_ON_SHARED_LIBRARIES. Assign $(my_ndk_shared_libraries_fullpath) to
+ # my_check_elf_file_shared_lib_files so that check_elf_file.py can see those NDK stub libs.
+ my_check_elf_file_shared_lib_files := $(my_ndk_shared_libraries_fullpath)
+ endif
else # my_strip_module not true
include $(BUILD_SYSTEM)/base_rules.mk
built_module := $(LOCAL_BUILT_MODULE)
@@ -239,234 +219,7 @@
endif
endif
-ifeq ($(LOCAL_MODULE_CLASS),APPS)
-PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
-
-my_extract_apk := $(strip $(LOCAL_EXTRACT_APK))
-
-# Select dpi-specific source
-ifdef LOCAL_DPI_VARIANTS
-my_dpi := $(firstword $(filter $(LOCAL_DPI_VARIANTS),$(PRODUCT_AAPT_PREF_CONFIG) $(PRODUCT_AAPT_PREBUILT_DPI)))
-ifdef my_dpi
-ifdef LOCAL_DPI_FILE_STEM
-my_prebuilt_dpi_file_stem := $(LOCAL_DPI_FILE_STEM)
-else
-my_prebuilt_dpi_file_stem := $(LOCAL_MODULE)_%.apk
-endif
-my_prebuilt_src_file := $(dir $(my_prebuilt_src_file))$(subst %,$(my_dpi),$(my_prebuilt_dpi_file_stem))
-
-ifneq ($(strip $(LOCAL_EXTRACT_DPI_APK)),)
-my_extract_apk := $(subst %,$(my_dpi),$(LOCAL_EXTRACT_DPI_APK))
-endif # LOCAL_EXTRACT_DPI_APK
-endif # my_dpi
-endif # LOCAL_DPI_VARIANTS
-
-ifdef my_extract_apk
-my_extracted_apk := $(intermediates)/extracted.apk
-
-$(my_extracted_apk): PRIVATE_EXTRACT := $(my_extract_apk)
-$(my_extracted_apk): $(my_prebuilt_src_file)
- @echo Extract APK: $@
- $(hide) mkdir -p $(dir $@) && rm -f $@
- $(hide) unzip -p $< $(PRIVATE_EXTRACT) >$@
-
-my_prebuilt_src_file := $(my_extracted_apk)
-my_extracted_apk :=
-my_extract_apk :=
-ifeq ($(PRODUCT_ALWAYS_PREOPT_EXTRACTED_APK),true)
-# If the product property is set, always preopt for extracted modules to prevent executing out of
-# the APK.
-my_preopt_for_extracted_apk := true
-endif
-endif
-
-dex_preopt_profile_src_file := $(my_prebuilt_src_file)
-
-rs_compatibility_jni_libs :=
-include $(BUILD_SYSTEM)/install_jni_libs.mk
-
-ifeq ($(LOCAL_CERTIFICATE),EXTERNAL)
- # The magic string "EXTERNAL" means this package will be signed with
- # the default dev key throughout the build process, but we expect
- # the final package to be signed with a different key.
- #
- # This can be used for packages where we don't have access to the
- # keys, but want the package to be predexopt'ed.
- LOCAL_CERTIFICATE := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
- PACKAGES.$(LOCAL_MODULE).EXTERNAL_KEY := 1
-
- $(built_module) : $(LOCAL_CERTIFICATE).pk8 $(LOCAL_CERTIFICATE).x509.pem
- $(built_module) : PRIVATE_PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
- $(built_module) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
-endif
-ifeq ($(LOCAL_CERTIFICATE),)
- # It is now a build error to add a prebuilt .apk without
- # specifying a key for it.
- $(error No LOCAL_CERTIFICATE specified for prebuilt "$(my_prebuilt_src_file)")
-else ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)
- # The magic string "PRESIGNED" means this package is already checked
- # signed with its release key.
- #
- # By setting .CERTIFICATE but not .PRIVATE_KEY, this package will be
- # mentioned in apkcerts.txt (with certificate set to "PRESIGNED")
- # but the dexpreopt process will not try to re-sign the app.
- PACKAGES.$(LOCAL_MODULE).CERTIFICATE := PRESIGNED
- PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
-else
- # If this is not an absolute certificate, assign it to a generic one.
- ifeq ($(dir $(strip $(LOCAL_CERTIFICATE))),./)
- LOCAL_CERTIFICATE := $(dir $(DEFAULT_SYSTEM_DEV_CERTIFICATE))$(LOCAL_CERTIFICATE)
- endif
-
- PACKAGES.$(LOCAL_MODULE).PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
- PACKAGES.$(LOCAL_MODULE).CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
- PACKAGES := $(PACKAGES) $(LOCAL_MODULE)
-
- $(built_module) : $(LOCAL_CERTIFICATE).pk8 $(LOCAL_CERTIFICATE).x509.pem
- $(built_module) : PRIVATE_PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
- $(built_module) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
-endif
-
-include $(BUILD_SYSTEM)/app_certificate_validate.mk
-
-# Disable dex-preopt of prebuilts to save space, if requested.
-ifndef LOCAL_DEX_PREOPT
-ifeq ($(DONT_DEXPREOPT_PREBUILTS),true)
-LOCAL_DEX_PREOPT := false
-endif
-endif
-
-# If the module is a compressed module, we don't pre-opt it because its final
-# installation location will be the data partition.
-ifdef LOCAL_COMPRESSED_MODULE
-LOCAL_DEX_PREOPT := false
-endif
-
-my_dex_jar := $(my_prebuilt_src_file)
-
-#######################################
-# defines built_odex along with rule to install odex
-include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
-#######################################
-ifneq ($(LOCAL_REPLACE_PREBUILT_APK_INSTALLED),)
-# There is a replacement for the prebuilt .apk we can install without any processing.
-$(built_module) : $(LOCAL_REPLACE_PREBUILT_APK_INSTALLED)
- $(transform-prebuilt-to-target)
-
-else # ! LOCAL_REPLACE_PREBUILT_APK_INSTALLED
-# Sign and align non-presigned .apks.
-# The embedded prebuilt jni to uncompress.
-ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)
-# For PRESIGNED apks we must uncompress every .so file:
-# even if the .so file isn't for the current TARGET_ARCH,
-# we can't strip the file.
-embedded_prebuilt_jni_libs :=
-endif
-ifndef embedded_prebuilt_jni_libs
-# No LOCAL_PREBUILT_JNI_LIBS, uncompress all.
-embedded_prebuilt_jni_libs :=
-endif
-$(built_module): PRIVATE_EMBEDDED_JNI_LIBS := $(embedded_prebuilt_jni_libs)
-
-ifdef LOCAL_COMPRESSED_MODULE
-$(built_module) : $(MINIGZIP)
-endif
-
-ifeq ($(module_run_appcompat),true)
-$(built_module) : $(appcompat-files)
-$(LOCAL_BUILT_MODULE): PRIVATE_INSTALLED_MODULE := $(LOCAL_INSTALLED_MODULE)
-endif
-
-ifneq ($(BUILD_PLATFORM_ZIP),)
-$(built_module) : .KATI_IMPLICIT_OUTPUTS := $(dir $(LOCAL_BUILT_MODULE))package.dex.apk
-endif
-ifneq ($(LOCAL_CERTIFICATE),PRESIGNED)
-ifdef LOCAL_DEX_PREOPT
-$(built_module) : PRIVATE_STRIP_SCRIPT := $(intermediates)/strip.sh
-$(built_module) : $(intermediates)/strip.sh
-$(built_module) : | $(DEXPREOPT_STRIP_DEPS)
-$(built_module) : .KATI_DEPFILE := $(built_module).d
-endif
-endif
-$(built_module) : $(my_prebuilt_src_file) | $(ZIPALIGN) $(ZIP2ZIP) $(SIGNAPK_JAR)
- $(transform-prebuilt-to-target)
- $(uncompress-prebuilt-embedded-jni-libs)
-ifeq (true, $(LOCAL_UNCOMPRESS_DEX))
- $(uncompress-dexs)
-endif # LOCAL_UNCOMPRESS_DEX
-ifdef LOCAL_DEX_PREOPT
-ifneq ($(BUILD_PLATFORM_ZIP),)
- @# Keep a copy of apk with classes.dex unstripped
- $(hide) cp -f $@ $(dir $@)package.dex.apk
-endif # BUILD_PLATFORM_ZIP
-endif # LOCAL_DEX_PREOPT
-ifneq ($(LOCAL_CERTIFICATE),PRESIGNED)
- @# Only strip out files if we can re-sign the package.
-# Run appcompat before stripping the classes.dex file.
-ifeq ($(module_run_appcompat),true)
-ifeq ($(LOCAL_USE_AAPT2),true)
- $(call appcompat-header, aapt2)
-else
- $(appcompat-header)
-endif
- $(run-appcompat)
-endif # module_run_appcompat
-ifdef LOCAL_DEX_PREOPT
- mv -f $@ $@.tmp
- $(PRIVATE_STRIP_SCRIPT) $@.tmp $@
-endif # LOCAL_DEX_PREOPT
- $(sign-package)
- # No need for align-package because sign-package takes care of alignment
-else # LOCAL_CERTIFICATE == PRESIGNED
- $(align-package)
-endif # LOCAL_CERTIFICATE
-ifdef LOCAL_COMPRESSED_MODULE
- $(compress-package)
-endif # LOCAL_COMPRESSED_MODULE
-endif # ! LOCAL_REPLACE_PREBUILT_APK_INSTALLED
-
-
-###############################
-## Install split apks.
-ifdef LOCAL_PACKAGE_SPLITS
-ifdef LOCAL_COMPRESSED_MODULE
-$(error $(LOCAL_MODULE): LOCAL_COMPRESSED_MODULE is not currently supported for split installs)
-endif # LOCAL_COMPRESSED_MODULE
-
-# LOCAL_PACKAGE_SPLITS is a list of apks to be installed.
-built_apk_splits := $(addprefix $(intermediates)/,$(notdir $(LOCAL_PACKAGE_SPLITS)))
-installed_apk_splits := $(addprefix $(my_module_path)/,$(notdir $(LOCAL_PACKAGE_SPLITS)))
-
-# Rules to sign the split apks.
-my_src_dir := $(sort $(dir $(LOCAL_PACKAGE_SPLITS)))
-ifneq (1,$(words $(my_src_dir)))
-$(error You must put all the split source apks in the same folder: $(LOCAL_PACKAGE_SPLITS))
-endif
-my_src_dir := $(LOCAL_PATH)/$(my_src_dir)
-
-$(built_apk_splits) : $(LOCAL_CERTIFICATE).pk8 $(LOCAL_CERTIFICATE).x509.pem
-$(built_apk_splits) : PRIVATE_PRIVATE_KEY := $(LOCAL_CERTIFICATE).pk8
-$(built_apk_splits) : PRIVATE_CERTIFICATE := $(LOCAL_CERTIFICATE).x509.pem
-$(built_apk_splits) : $(intermediates)/%.apk : $(my_src_dir)/%.apk
- $(copy-file-to-new-target)
- $(sign-package)
-
-# Rules to install the split apks.
-$(installed_apk_splits) : $(my_module_path)/%.apk : $(intermediates)/%.apk
- @echo "Install: $@"
- $(copy-file-to-new-target)
-
-# Register the additional built and installed files.
-ALL_MODULES.$(my_register_name).INSTALLED += $(installed_apk_splits)
-ALL_MODULES.$(my_register_name).BUILT_INSTALLED += \
- $(foreach s,$(LOCAL_PACKAGE_SPLITS),$(intermediates)/$(notdir $(s)):$(my_module_path)/$(notdir $(s)))
-
-# Make sure to install the splits when you run "make <module_name>".
-$(my_all_targets): $(installed_apk_splits)
-
-endif # LOCAL_PACKAGE_SPLITS
-
-else ifeq ($(prebuilt_module_is_dex_javalib),true) # ! LOCAL_MODULE_CLASS != APPS
+ifeq ($(prebuilt_module_is_dex_javalib),true)
my_dex_jar := $(my_prebuilt_src_file)
# This is a target shared library, i.e. a jar with classes.dex.
@@ -693,6 +446,8 @@
endif # JAVA_LIBRARIES
+endif # APPS
+
$(built_module) : $(LOCAL_ADDITIONAL_DEPENDENCIES)
my_prebuilt_src_file :=
diff --git a/core/product-graph.mk b/core/product-graph.mk
index 1efc687..a114b65 100644
--- a/core/product-graph.mk
+++ b/core/product-graph.mk
@@ -36,8 +36,6 @@
this_makefile := build/make/core/product-graph.mk
-products_svg := $(OUT_DIR)/products.svg
-products_pdf := $(OUT_DIR)/products.pdf
products_graph := $(OUT_DIR)/products.dot
ifeq ($(strip $(ANDROID_PRODUCT_GRAPH)),)
products_list := $(INTERNAL_PRODUCT)
@@ -137,13 +135,8 @@
$(eval product_debug_files += $(call product-debug-filename, $(p))) \
)
-$(products_pdf): $(products_graph)
- @echo Product graph PDF: $@
- dot -Tpdf -Nshape=box -o $@ $<
-
-$(products_svg): $(products_graph) $(product_debug_files)
- @echo Product graph SVG: $@
- dot -Tsvg -Nshape=box -o $@ $<
-
-product-graph: $(products_pdf) $(products_svg)
.PHONY: product-graph
+product-graph: $(products_graph)
+ @echo Product graph .dot file: $(products_graph)
+ @echo Command to convert to pdf: dot -Tpdf -Nshape=box -o $(OUT_DIR)/products.pdf $(products_graph)
+ @echo Command to convert to svg: dot -Tsvg -Nshape=box -o $(OUT_DIR)/products.svg $(products_graph)
diff --git a/core/product.mk b/core/product.mk
index a367a6b..bb63ab8 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -126,6 +126,11 @@
PRODUCT_DEVICE \
PRODUCT_MANUFACTURER \
PRODUCT_BRAND \
+ PRODUCT_SYSTEM_NAME \
+ PRODUCT_SYSTEM_MODEL \
+ PRODUCT_SYSTEM_DEVICE \
+ PRODUCT_SYSTEM_BRAND \
+ PRODUCT_SYSTEM_MANUFACTURER \
PRODUCT_PROPERTY_OVERRIDES \
PRODUCT_DEFAULT_PROPERTY_OVERRIDES \
PRODUCT_PRODUCT_PROPERTIES \
diff --git a/core/product_config.mk b/core/product_config.mk
index cff42db..7ab1d6d 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -299,18 +299,39 @@
PRODUCT_AAPT_CONFIG := \
$(subst $(space),$(comma),$(strip $(PRODUCT_AAPT_CONFIG)))
+PRODUCT_SYSTEM_NAME := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_NAME))
+ifndef PRODUCT_SYSTEM_NAME
+ PRODUCT_SYSTEM_NAME := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_NAME))
+endif
+
+PRODUCT_SYSTEM_DEVICE := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_DEVICE))
+ifndef PRODUCT_SYSTEM_DEVICE
+ PRODUCT_SYSTEM_DEVICE := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE)
+endif
+
PRODUCT_BRAND := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_BRAND))
+PRODUCT_SYSTEM_BRAND := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BRAND))
+ifndef PRODUCT_SYSTEM_BRAND
+ PRODUCT_SYSTEM_BRAND := $(PRODUCT_BRAND)
+endif
PRODUCT_MODEL := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_MODEL))
ifndef PRODUCT_MODEL
PRODUCT_MODEL := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_NAME))
endif
+PRODUCT_SYSTEM_MODEL := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_MODEL))
+ifndef PRODUCT_SYSTEM_MODEL
+ PRODUCT_SYSTEM_MODEL := $(PRODUCT_MODEL)
+endif
-PRODUCT_MANUFACTURER := \
- $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_MANUFACTURER))
+PRODUCT_MANUFACTURER := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_MANUFACTURER))
ifndef PRODUCT_MANUFACTURER
PRODUCT_MANUFACTURER := unknown
endif
+PRODUCT_SYSTEM_MANUFACTURER := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_MANUFACTURER))
+ifndef PRODUCT_SYSTEM_MANUFACTURER
+ PRODUCT_SYSTEM_MANUFACTURER := $(PRODUCT_MANUFACTURER)
+endif
ifeq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_CHARACTERISTICS),)
TARGET_AAPT_CHARACTERISTICS := default
diff --git a/core/soong_cc_prebuilt.mk b/core/soong_cc_prebuilt.mk
index dd33852..679d5b8 100644
--- a/core/soong_cc_prebuilt.mk
+++ b/core/soong_cc_prebuilt.mk
@@ -86,11 +86,13 @@
endif
ifdef LOCAL_USE_VNDK
- name_without_suffix := $(patsubst %.vendor,%,$(LOCAL_MODULE))
- ifneq ($(name_without_suffix),$(LOCAL_MODULE)
- SPLIT_VENDOR.$(LOCAL_MODULE_CLASS).$(name_without_suffix) := 1
+ ifneq ($(LOCAL_VNDK_DEPEND_ON_CORE_VARIANT),true)
+ name_without_suffix := $(patsubst %.vendor,%,$(LOCAL_MODULE))
+ ifneq ($(name_without_suffix),$(LOCAL_MODULE)
+ SPLIT_VENDOR.$(LOCAL_MODULE_CLASS).$(name_without_suffix) := 1
+ endif
+ name_without_suffix :=
endif
- name_without_suffix :=
endif
# Check prebuilt ELF binaries.
@@ -113,26 +115,52 @@
endif
endif
+ifeq ($(LOCAL_VNDK_DEPEND_ON_CORE_VARIANT),true)
+ # Add $(LOCAL_BUILT_MODULE) as a dependency to no_vendor_variant_vndk_check so
+ # that the vendor variant will be built and checked against the core variant.
+ no_vendor_variant_vndk_check: $(LOCAL_BUILT_MODULE)
+
+ my_core_register_name := $(subst .vendor,,$(my_register_name))
+ my_core_variant_files := $(call module-target-built-files,$(my_core_register_name))
+ my_core_shared_lib := $(sort $(filter %.so,$(my_core_variant_files)))
+ $(LOCAL_BUILT_MODULE): PRIVATE_CORE_VARIANT := $(my_core_shared_lib)
+
+ # The built vendor variant library needs to depend on the built core variant
+ # so that we can perform identity check against the core variant.
+ $(LOCAL_BUILT_MODULE): $(my_core_shared_lib)
+endif
+
+ifeq ($(LOCAL_VNDK_DEPEND_ON_CORE_VARIANT),true)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PREBUILT_MODULE_FILE) $(LIBRARY_IDENTITY_CHECK_SCRIPT)
+ $(call verify-vndk-libs-identical,\
+ $(PRIVATE_CORE_VARIANT),\
+ $<,\
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)TOOLS_PREFIX))
+ $(copy-file-to-target)
+else
$(LOCAL_BUILT_MODULE): $(LOCAL_PREBUILT_MODULE_FILE)
$(transform-prebuilt-to-target)
+endif
ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
$(hide) chmod +x $@
endif
ifndef LOCAL_IS_HOST_MODULE
ifdef LOCAL_SOONG_UNSTRIPPED_BINARY
- # Store a copy with symbols for symbolic debugging
- my_unstripped_path := $(TARGET_OUT_UNSTRIPPED)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_module_path))
- # drop /root as /root is mounted as /
- my_unstripped_path := $(patsubst $(TARGET_OUT_UNSTRIPPED)/root/%,$(TARGET_OUT_UNSTRIPPED)/%, $(my_unstripped_path))
- symbolic_output := $(my_unstripped_path)/$(my_installed_module_stem)
- $(eval $(call copy-one-file,$(LOCAL_SOONG_UNSTRIPPED_BINARY),$(symbolic_output)))
- $(call add-dependency,$(LOCAL_BUILT_MODULE),$(symbolic_output))
+ ifneq ($(LOCAL_VNDK_DEPEND_ON_CORE_VARIANT),true)
+ my_symbol_path := $(if $(LOCAL_SOONG_SYMBOL_PATH),$(LOCAL_SOONG_SYMBOL_PATH),$(my_module_path))
+ # Store a copy with symbols for symbolic debugging
+ my_unstripped_path := $(TARGET_OUT_UNSTRIPPED)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_symbol_path))
+ # drop /root as /root is mounted as /
+ my_unstripped_path := $(patsubst $(TARGET_OUT_UNSTRIPPED)/root/%,$(TARGET_OUT_UNSTRIPPED)/%, $(my_unstripped_path))
+ symbolic_output := $(my_unstripped_path)/$(my_installed_module_stem)
+ $(eval $(call copy-one-file,$(LOCAL_SOONG_UNSTRIPPED_BINARY),$(symbolic_output)))
+ $(call add-dependency,$(LOCAL_BUILT_MODULE),$(symbolic_output))
- ifeq ($(BREAKPAD_GENERATE_SYMBOLS),true)
- my_breakpad_path := $(TARGET_OUT_BREAKPAD)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_module_path))
- breakpad_output := $(my_breakpad_path)/$(my_installed_module_stem).sym
- $(breakpad_output) : $(LOCAL_SOONG_UNSTRIPPED_BINARY) | $(BREAKPAD_DUMP_SYMS) $(PRIVATE_READELF)
+ ifeq ($(BREAKPAD_GENERATE_SYMBOLS),true)
+ my_breakpad_path := $(TARGET_OUT_BREAKPAD)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_symbol_path))
+ breakpad_output := $(my_breakpad_path)/$(my_installed_module_stem).sym
+ $(breakpad_output) : $(LOCAL_SOONG_UNSTRIPPED_BINARY) | $(BREAKPAD_DUMP_SYMS) $(PRIVATE_READELF)
@echo "target breakpad: $(PRIVATE_MODULE) ($@)"
@mkdir -p $(dir $@)
$(hide) if $(PRIVATE_READELF) -S $< > /dev/null 2>&1 ; then \
@@ -141,7 +169,8 @@
echo "skipped for non-elf file."; \
touch $@; \
fi
- $(call add-dependency,$(LOCAL_BUILT_MODULE),$(breakpad_output))
+ $(call add-dependency,$(LOCAL_BUILT_MODULE),$(breakpad_output))
+ endif
endif
endif
endif
diff --git a/core/soong_config.mk b/core/soong_config.mk
index ddc8cf3..baba31b 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -116,6 +116,8 @@
$(call add_json_list, BootJars, $(PRODUCT_BOOT_JARS))
+$(call add_json_bool, VndkUseCoreVariant, $(TARGET_VNDK_USE_CORE_VARIANT))
+
$(call add_json_bool, Product_is_iot, $(filter true,$(PRODUCT_IOT)))
$(call add_json_bool, Treble_linker_namespaces, $(filter true,$(PRODUCT_TREBLE_LINKER_NAMESPACES)))
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index 6214ac6..9692a99 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -94,6 +94,8 @@
ALL_MODULES.$(my_register_name).INSTALLED += $(installed_odex)
# Make sure to install the .odex and .vdex when you run "make <module_name>"
$(my_all_targets): $(installed_odex)
+ # Copy $(LOCAL_BUILT_MODULE) and its dependencies when installing boot.art
+ $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE): $(LOCAL_BUILT_MODULE)
endif
endif # is_boot_jar
diff --git a/core/target_test_internal.mk b/core/target_test_internal.mk
index b5c3a7c..1ed1195 100644
--- a/core/target_test_internal.mk
+++ b/core/target_test_internal.mk
@@ -29,6 +29,15 @@
$(error $(LOCAL_PATH): Do not set LOCAL_MODULE_PATH_64 when building test $(LOCAL_MODULE))
endif
+use_testcase_folder := false
+ifdef ENABLE_DEFAULT_TEST_LOCATION
+ ifneq ($(LOCAL_MODULE),$(filter $(LOCAL_MODULE),$(DEFAULT_DATA_OUT_MODULES)))
+ use_testcase_folder := true
+ endif
+endif
+
+ifneq ($(use_testcase_folder),true)
ifndef LOCAL_MODULE_RELATIVE_PATH
LOCAL_MODULE_RELATIVE_PATH := $(LOCAL_MODULE)
endif
+endif
diff --git a/core/tasks/tools/package-modules.mk b/core/tasks/tools/package-modules.mk
index 629a9b2..82b4c6a 100644
--- a/core/tasks/tools/package-modules.mk
+++ b/core/tasks/tools/package-modules.mk
@@ -40,6 +40,8 @@
$(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).PICKUP_FILES)))\
$(eval _built_files := $(strip $(ALL_MODULES.$(m).BUILT_INSTALLED)\
$(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).BUILT_INSTALLED)))\
+ $(eval _module_class_folder := $($(strip MODULE_CLASS_$(word 1, $(strip $(ALL_MODULES.$(m).CLASS)\
+ $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).CLASS))))))\
$(if $(_pickup_files)$(_built_files),,\
$(call my_missing_files,$(m)))\
$(eval my_pickup_files += $(_pickup_files))\
@@ -49,9 +51,15 @@
$(if $(filter $(TARGET_OUT_ROOT)/%,$(ins)),\
$(eval bui := $(word 1,$(bui_ins)))\
$(eval my_built_modules += $(bui))\
+ $(if $(filter $(_module_class_folder), nativetest benchmarktest),\
+ $(eval module_class_folder_stem := $(_module_class_folder)$(findstring 64, $(patsubst $(PRODUCT_OUT)/%,%,$(ins)))),\
+ $(eval module_class_folder_stem := $(_module_class_folder)))\
$(eval my_copy_dest := $(patsubst data/%,DATA/%,\
- $(patsubst system/%,DATA/%,\
- $(patsubst $(PRODUCT_OUT)/%,%,$(ins)))))\
+ $(patsubst testcases/%,DATA/$(module_class_folder_stem)/%,\
+ $(patsubst testcases/$(m)/$(TARGET_ARCH)/%,DATA/$(module_class_folder_stem)/$(m)/%,\
+ $(patsubst testcases/$(m)/$(TARGET_2ND_ARCH)/%,DATA/$(module_class_folder_stem)/$(m)/%,\
+ $(patsubst system/%,DATA/%,\
+ $(patsubst $(PRODUCT_OUT)/%,%,$(ins))))))))\
$(eval my_copy_pairs += $(bui):$(my_staging_dir)/$(my_copy_dest)))\
))
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 835d9fe..6923698 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -252,7 +252,7 @@
# It must be of the form "YYYY-MM-DD" on production devices.
# It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
# If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
- PLATFORM_SECURITY_PATCH := 2019-02-05
+ PLATFORM_SECURITY_PATCH := 2019-03-05
endif
.KATI_READONLY := PLATFORM_SECURITY_PATCH
diff --git a/target/board/gsi_system.prop b/target/board/gsi_system.prop
index 0c04a95..d768c83 100644
--- a/target/board/gsi_system.prop
+++ b/target/board/gsi_system.prop
@@ -4,5 +4,8 @@
# GSI always disables adb authentication
ro.adb.secure=0
+# TODO(b/120679683): disable RescueParty before all problem apps solved
+persist.sys.disable_rescue=true
+
# TODO(b/78105955): disable privapp_permissions checking before the bug solved
ro.control_privapp_permissions=disable
diff --git a/target/board/gsi_system_user.prop b/target/board/gsi_system_user.prop
index 1aa553b..becb783 100644
--- a/target/board/gsi_system_user.prop
+++ b/target/board/gsi_system_user.prop
@@ -1,5 +1,8 @@
# GSI always generate dex pre-opt in system image
ro.cp_system_other_odex=0
+# TODO(b/120679683): disable RescueParty before all problem apps solved
+persist.sys.disable_rescue=true
+
# TODO(b/78105955): disable privapp_permissions checking before the bug solved
ro.control_privapp_permissions=disable
diff --git a/target/product/base_vendor.mk b/target/product/base_vendor.mk
index f7c8ed3..bf01957 100644
--- a/target/product/base_vendor.mk
+++ b/target/product/base_vendor.mk
@@ -19,6 +19,7 @@
adbd.recovery \
android.hardware.health@2.0-impl-default.recovery \
cgroups.recovery.json \
+ charger.recovery \
init_second_stage.recovery \
ld.config.recovery.txt \
linker.recovery \
diff --git a/target/product/mainline_system.mk b/target/product/mainline_system.mk
index 0ddc3db..ecd5691 100644
--- a/target/product/mainline_system.mk
+++ b/target/product/mainline_system.mk
@@ -81,7 +81,6 @@
libminui \
libnl \
libprotobuf-cpp-full \
- libprotobuf-cpp-full-rtti \
PRODUCT_PACKAGES_DEBUG += \
avbctl \
diff --git a/tools/buildinfo_common.sh b/tools/buildinfo_common.sh
index f7f798c..6041d79 100755
--- a/tools/buildinfo_common.sh
+++ b/tools/buildinfo_common.sh
@@ -21,7 +21,7 @@
echo "ro.${partition}.build.version.sdk=$PLATFORM_SDK_VERSION"
echo "ro.product.${partition}.brand=$PRODUCT_BRAND"
-echo "ro.product.${partition}.device=$TARGET_DEVICE"
+echo "ro.product.${partition}.device=$PRODUCT_DEVICE"
echo "ro.product.${partition}.manufacturer=$PRODUCT_MANUFACTURER"
echo "ro.product.${partition}.model=$PRODUCT_MODEL"
echo "ro.product.${partition}.name=$PRODUCT_NAME"
diff --git a/tools/check_elf_file.py b/tools/check_elf_file.py
index 38c1cf4..de855c6 100755
--- a/tools/check_elf_file.py
+++ b/tools/check_elf_file.py
@@ -260,13 +260,20 @@
_SYMBOL_ENTRY_END_PATTERN = ' }'
- @classmethod
- def _parse_symbol_name(cls, name_with_version):
+ @staticmethod
+ def _parse_symbol_name(name_with_version):
"""Split `name_with_version` into name and version. This function may split
at last occurrence of `@@` or `@`."""
- name, version = name_with_version.rsplit('@', 1)
- if name and name[-1] == '@':
- name = name[:-1]
+ pos = name_with_version.rfind('@')
+ if pos == -1:
+ name = name_with_version
+ version = ''
+ else:
+ if pos > 0 and name_with_version[pos - 1] == '@':
+ name = name_with_version[0:pos - 1]
+ else:
+ name = name_with_version[0:pos]
+ version = name_with_version[pos + 1:]
return (name, version)
diff --git a/tools/check_identical_lib.sh b/tools/check_identical_lib.sh
new file mode 100755
index 0000000..01007c0
--- /dev/null
+++ b/tools/check_identical_lib.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+set -e
+
+STRIP_PATH="${1}"
+CORE="${2}"
+VENDOR="${3}"
+
+stripped_core="${CORE}.vndk_lib_check.stripped"
+stripped_vendor="${VENDOR}.vndk_lib_check.stripped"
+
+function cleanup() {
+ rm -f ${stripped_core} ${stripped_vendor}
+}
+trap cleanup EXIT
+
+function strip_lib() {
+ ${STRIP_PATH} \
+ -i ${1} \
+ -o ${2} \
+ -d /dev/null \
+ --remove-build-id
+}
+
+strip_lib ${CORE} ${stripped_core}
+strip_lib ${VENDOR} ${stripped_vendor}
+if ! cmp -s ${stripped_core} ${stripped_vendor}; then
+ echo "VNDK library not in vndkMustUseVendorVariantList but has different core and vendor variant: $(basename ${CORE})"
+ echo "If the two variants need to have different runtime behavior, consider using libvndksupport."
+ exit 1
+fi
diff --git a/tools/checkowners.py b/tools/checkowners.py
index 7f03968..d6853d8 100755
--- a/tools/checkowners.py
+++ b/tools/checkowners.py
@@ -52,12 +52,13 @@
noparent = 'set +noparent'
email = '([^@ ]+@[^ @]+|\\*)'
emails = '(%s( *, *%s)*)' % (email, email)
- directive = '(%s|%s)' % (emails, noparent)
+ file_directive = 'file: *([^ :]+ *: *)?[^ ]+'
+ directive = '(%s|%s|%s)' % (emails, noparent, file_directive)
glob = '[a-zA-Z0-9_\\.\\-\\*\\?]+'
globs = '(%s( *, *%s)*)' % (glob, glob)
perfile = 'per-file +' + globs + ' *= *' + directive
include = 'include +([^ :]+ *: *)?[^ ]+'
- pats = '(|%s|%s|%s|%s)$' % (noparent, email, perfile, include)
+ pats = '(|%s|%s|%s|%s|%s)$' % (noparent, email, perfile, include, file_directive)
patterns = re.compile(pats)
address_pattern = re.compile('([^@ ]+@[^ @]+)')
perfile_pattern = re.compile('per-file +.*=(.*)')
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 5132ae7..10aecf9 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -146,11 +146,12 @@
ofile.write(data)
ofile.close()
- arc_name = "SYSTEM/" + fn
- if arc_name in output_zip.namelist():
- OPTIONS.replace_updated_files_list.append(arc_name)
- else:
- common.ZipWrite(output_zip, ofile.name, arc_name)
+ if output_zip:
+ arc_name = "SYSTEM/" + fn
+ if arc_name in output_zip.namelist():
+ OPTIONS.replace_updated_files_list.append(arc_name)
+ else:
+ common.ZipWrite(output_zip, ofile.name, arc_name)
if OPTIONS.rebuild_recovery:
logger.info("Building new recovery patch")
@@ -260,7 +261,7 @@
# AVB-sign the image as needed.
if OPTIONS.info_dict.get("avb_enable") == "true":
- avbtool = os.getenv('AVBTOOL') or OPTIONS.info_dict["avb_avbtool"]
+ avbtool = OPTIONS.info_dict["avb_avbtool"]
part_size = OPTIONS.info_dict["dtbo_size"]
# The AVB hash footer will be replaced if already present.
cmd = [avbtool, "add_hash_footer", "--image", img.name,
@@ -428,7 +429,7 @@
logger.info("%s.img already exists; not rebuilding...", name)
return img.name
- avbtool = os.getenv('AVBTOOL') or OPTIONS.info_dict["avb_avbtool"]
+ avbtool = OPTIONS.info_dict["avb_avbtool"]
cmd = [avbtool, "make_vbmeta_image", "--output", img.name]
common.AppendAVBSigningArgs(cmd, name)
diff --git a/tools/releasetools/apex_utils.py b/tools/releasetools/apex_utils.py
new file mode 100644
index 0000000..d14c94f
--- /dev/null
+++ b/tools/releasetools/apex_utils.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+#
+# 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.
+
+import logging
+import os.path
+import re
+import shlex
+import sys
+
+import common
+
+logger = logging.getLogger(__name__)
+
+
+class ApexInfoError(Exception):
+ """An Exception raised during Apex Information command."""
+
+ def __init__(self, message):
+ Exception.__init__(self, message)
+
+
+class ApexSigningError(Exception):
+ """An Exception raised during Apex Payload signing."""
+
+ def __init__(self, message):
+ Exception.__init__(self, message)
+
+
+def SignApexPayload(payload_file, payload_key_path, payload_key_name, algorithm,
+ salt, signing_args=None):
+ """Signs a given payload_file with the payload key."""
+ # Add the new footer. Old footer, if any, will be replaced by avbtool.
+ cmd = ['avbtool', 'add_hashtree_footer',
+ '--do_not_generate_fec',
+ '--algorithm', algorithm,
+ '--key', payload_key_path,
+ '--prop', 'apex.key:{}'.format(payload_key_name),
+ '--image', payload_file,
+ '--salt', salt]
+ if signing_args:
+ cmd.extend(shlex.split(signing_args))
+
+ try:
+ common.RunAndCheckOutput(cmd)
+ except common.ExternalError as e:
+ raise ApexSigningError, \
+ 'Failed to sign APEX payload {} with {}:\n{}'.format(
+ payload_file, payload_key_path, e), sys.exc_info()[2]
+
+ # Verify the signed payload image with specified public key.
+ logger.info('Verifying %s', payload_file)
+ VerifyApexPayload(payload_file, payload_key_path)
+
+
+def VerifyApexPayload(payload_file, payload_key):
+ """Verifies the APEX payload signature with the given key."""
+ cmd = ['avbtool', 'verify_image', '--image', payload_file,
+ '--key', payload_key]
+ try:
+ common.RunAndCheckOutput(cmd)
+ except common.ExternalError as e:
+ raise ApexSigningError, \
+ 'Failed to validate payload signing for {} with {}:\n{}'.format(
+ payload_file, payload_key, e), sys.exc_info()[2]
+
+
+def ParseApexPayloadInfo(payload_path):
+ """Parses the APEX payload info.
+
+ Args:
+ payload_path: The path to the payload image.
+
+ Raises:
+ ApexInfoError on parsing errors.
+
+ Returns:
+ A dict that contains payload property-value pairs. The dict should at least
+ contain Algorithm, Salt and apex.key.
+ """
+ if not os.path.exists(payload_path):
+ raise ApexInfoError('Failed to find image: {}'.format(payload_path))
+
+ cmd = ['avbtool', 'info_image', '--image', payload_path]
+ try:
+ output = common.RunAndCheckOutput(cmd)
+ except common.ExternalError as e:
+ raise ApexInfoError, \
+ 'Failed to get APEX payload info for {}:\n{}'.format(
+ payload_path, e), sys.exc_info()[2]
+
+ # Extract the Algorithm / Salt / Prop info from payload (i.e. an image signed
+ # with avbtool). For example,
+ # Algorithm: SHA256_RSA4096
+ PAYLOAD_INFO_PATTERN = (
+ r'^\s*(?P<key>Algorithm|Salt|Prop)\:\s*(?P<value>.*?)$')
+ payload_info_matcher = re.compile(PAYLOAD_INFO_PATTERN)
+
+ payload_info = {}
+ for line in output.split('\n'):
+ line_info = payload_info_matcher.match(line)
+ if not line_info:
+ continue
+
+ key, value = line_info.group('key'), line_info.group('value')
+
+ if key == 'Prop':
+ # Further extract the property key-value pair, from a 'Prop:' line. For
+ # example,
+ # Prop: apex.key -> 'com.android.runtime'
+ # Note that avbtool writes single or double quotes around values.
+ PROPERTY_DESCRIPTOR_PATTERN = r'^\s*(?P<key>.*?)\s->\s*(?P<value>.*?)$'
+
+ prop_matcher = re.compile(PROPERTY_DESCRIPTOR_PATTERN)
+ prop = prop_matcher.match(value)
+ if not prop:
+ raise ApexInfoError(
+ 'Failed to parse prop string {}'.format(value))
+
+ prop_key, prop_value = prop.group('key'), prop.group('value')
+ if prop_key == 'apex.key':
+ # avbtool dumps the prop value with repr(), which contains single /
+ # double quotes that we don't want.
+ payload_info[prop_key] = prop_value.strip('\"\'')
+
+ else:
+ payload_info[key] = value
+
+ # Sanity check.
+ for key in ('Algorithm', 'Salt', 'apex.key'):
+ if key not in payload_info:
+ raise ApexInfoError(
+ 'Failed to find {} prop in {}'.format(key, payload_path))
+
+ return payload_info
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 5e3d68a..d2f4e25 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -739,26 +739,6 @@
with open(filename, "w") as f:
f.writelines(["%s=%s" % (key, value) for (key, value) in glob_dict.items()])
-def ExtractSystemOtherAvbKey(in_dir, glob_dict):
- if glob_dict.get("avb_system_extract_system_other_key") != "true":
- return
-
- extract_to = os.path.join(in_dir, "etc/security/avb/system_other.avbpubkey")
- extract_to_dir = os.path.dirname(extract_to)
-
- if os.path.isdir(extract_to_dir):
- shutil.rmtree(extract_to_dir)
- elif os.path.isfile(extract_to_dir):
- os.remove(extract_to_dir)
- os.mkdir(extract_to_dir);
-
- # Extracts the public key used to sign system_other.img, into system.img:
- # /system/etc/security/avb/system_other.avbpubkey.
- avbtool = os.getenv('AVBTOOL') or glob_dict.get("avb_avbtool")
- extract_from = glob_dict.get("avb_system_other_key_path")
- cmd = [avbtool, "extract_public_key", "--key", extract_from,
- "--output", extract_to]
- common.RunAndCheckOutput(cmd, verbose=False)
def main(argv):
if len(argv) < 4 or len(argv) > 5:
@@ -783,7 +763,6 @@
mount_point = ""
if image_filename == "system.img":
mount_point = "system"
- ExtractSystemOtherAvbKey(in_dir, glob_dict)
elif image_filename == "system_other.img":
mount_point = "system_other"
elif image_filename == "userdata.img":
diff --git a/tools/releasetools/build_super_image.py b/tools/releasetools/build_super_image.py
index bb0e641..38ea3d6 100755
--- a/tools/releasetools/build_super_image.py
+++ b/tools/releasetools/build_super_image.py
@@ -24,9 +24,8 @@
- target files package. Same as above, but extracts the archive before
building super image.
- a dictionary file containing input arguments to build. Check
- `dump_dynamic_partitions_info' for details.
+ `dump-super-image-info' for details.
In addition:
- - "ab_update" needs to be true for A/B devices.
- If source images should be included in the output image (for super.img
and super split images), a list of "*_image" should be paths of each
source images.
diff --git a/tools/releasetools/check_target_files_signatures.py b/tools/releasetools/check_target_files_signatures.py
index b9f39a6..9b76954 100755
--- a/tools/releasetools/check_target_files_signatures.py
+++ b/tools/releasetools/check_target_files_signatures.py
@@ -39,6 +39,7 @@
"""
+import logging
import os
import re
import subprocess
@@ -52,6 +53,8 @@
sys.exit(1)
+logger = logging.getLogger(__name__)
+
# Work around a bug in Python's zipfile module that prevents opening of zipfiles
# if any entry has an extra field of between 1 and 3 bytes (which is common with
# zipaligned APKs). This overrides the ZipInfo._decodeExtra() method (which
@@ -415,6 +418,8 @@
common.Usage(__doc__)
sys.exit(1)
+ common.InitLogging()
+
ALL_CERTS.FindLocalCerts()
Push("input target_files:")
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 9cda0bd..780b9c1 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -50,7 +50,8 @@
if base_out_path is None:
base_search_path = "out"
else:
- base_search_path = os.path.join(base_out_path, os.path.basename(os.getcwd()))
+ base_search_path = os.path.join(base_out_path,
+ os.path.basename(os.getcwd()))
platform_search_path = {
"linux2": os.path.join(base_search_path, "host/linux-x86"),
@@ -552,11 +553,7 @@
"""
if key is None:
key = info_dict["avb_" + partition + "_key_path"]
- avbtool = os.getenv('AVBTOOL') or info_dict["avb_avbtool"]
- pubkey_path = MakeTempFile(prefix="avb-", suffix=".pubkey")
- RunAndCheckOutput(
- [avbtool, "extract_public_key", "--key", key, "--output", pubkey_path])
-
+ pubkey_path = ExtractAvbPublicKey(key)
rollback_index_location = info_dict[
"avb_" + partition + "_rollback_index_location"]
return "{}:{}:{}".format(partition, rollback_index_location, pubkey_path)
@@ -707,7 +704,7 @@
# AVB: if enabled, calculate and add hash to boot.img or recovery.img.
if info_dict.get("avb_enable") == "true":
- avbtool = os.getenv('AVBTOOL') or info_dict["avb_avbtool"]
+ avbtool = info_dict["avb_avbtool"]
part_size = info_dict[partition_name + "_size"]
cmd = [avbtool, "add_hash_footer", "--image", img.name,
"--partition_size", str(part_size), "--partition_name",
@@ -2123,6 +2120,21 @@
return pubkey
+def ExtractAvbPublicKey(key):
+ """Extracts the AVB public key from the given public or private key.
+
+ Args:
+ key: The input key file, which should be PEM-encoded public or private key.
+
+ Returns:
+ The path to the extracted AVB public key file.
+ """
+ output = MakeTempFile(prefix='avb-', suffix='.avbpubkey')
+ RunAndCheckOutput(
+ ['avbtool', 'extract_public_key', "--key", key, "--output", output])
+ return output
+
+
def MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img,
info_dict=None):
"""Generates the recovery-from-boot patch and writes the script to output.
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index 2645829..1d62e3b 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -25,12 +25,28 @@
The input target files package containing system bits. This is a zip
archive.
+ --system-item-list system-item-list-file
+ The optional path to a newline-separated config file that replaces the
+ contents of default_system_item_list if provided.
+
+ --system-misc-info-keys system-misc-info-keys-file
+ The optional path to a newline-separated config file that replaces the
+ contents of default_system_misc_info_keys if provided.
+
--other-target-files other-target-files-zip-archive
The input target files package containing other bits. This is a zip
archive.
+ --other-item-list other-item-list-file
+ The optional path to a newline-separated config file that replaces the
+ contents of default_other_item_list if provided.
+
--output-target-files output-target-files-package
The output merged target files package. Also a zip archive.
+
+ --rebuild_recovery
+ Rebuild the recovery patch used by non-A/B devices and write it to the
+ system image.
"""
from __future__ import print_function
@@ -48,16 +64,20 @@
OPTIONS = common.OPTIONS
OPTIONS.verbose = True
OPTIONS.system_target_files = None
+OPTIONS.system_item_list = None
+OPTIONS.system_misc_info_keys = None
OPTIONS.other_target_files = None
+OPTIONS.other_item_list = None
OPTIONS.output_target_files = None
+OPTIONS.rebuild_recovery = False
OPTIONS.keep_tmp = False
-# system_extract_as_is_item_list is a list of items to extract from the partial
+# default_system_item_list is a list of items to extract from the partial
# system target files package as is, meaning these items will land in the
# output target files package exactly as they appear in the input partial
# system target files package.
-system_extract_as_is_item_list = [
+default_system_item_list = [
'META/apkcerts.txt',
'META/filesystem_config.txt',
'META/root_filesystem_config.txt',
@@ -78,10 +98,10 @@
'META/*',
]
-# system_misc_info_keys is a list of keys to obtain from the system instance of
+# default_system_misc_info_keys is a list of keys to obtain from the system instance of
# META/misc_info.txt. The remaining keys from the other instance.
-system_misc_info_keys = [
+default_system_misc_info_keys = [
'avb_system_hashtree_enable',
'avb_system_add_hashtree_footer_args',
'avb_system_key_path',
@@ -98,12 +118,12 @@
'system_size',
]
-# other_extract_as_is_item_list is a list of items to extract from the partial
+# default_other_item_list is a list of items to extract from the partial
# other target files package as is, meaning these items will land in the output
# target files package exactly as they appear in the input partial other target
# files package.
-other_extract_as_is_item_list = [
+default_other_item_list = [
'META/boot_filesystem_config.txt',
'META/otakeys.txt',
'META/releasetools.py',
@@ -119,7 +139,7 @@
'VENDOR/*',
]
-# other_extract_for_merge_item_list is a list of items to extract from the
+# other_extract_special_item_list is a list of items to extract from the
# partial other target files package that need some special processing, such as
# some sort of combination with items from the partial system target files
# package.
@@ -172,6 +192,50 @@
filtered_extract_item_list)
+def read_config_list(config_file_path):
+ """Reads a config file into a list of strings.
+
+ Expects the file to be newline-separated.
+
+ Args:
+ config_file_path: The path to the config file to open and read.
+ """
+ with open(config_file_path) as config_file:
+ return config_file.read().splitlines()
+
+
+def validate_config_lists(system_item_list, other_item_list):
+ """Performs validations on the merge config lists.
+
+ Args:
+ system_item_list: The list of items to extract from the partial
+ system target files package as is.
+
+ other_item_list: The list of items to extract from the partial
+ other target files package as is.
+
+ Returns:
+ False if a validation fails, otherwise true.
+ """
+ default_combined_item_set = set(default_system_item_list)
+ default_combined_item_set.update(default_other_item_list)
+
+ combined_item_set = set(system_item_list)
+ combined_item_set.update(other_item_list)
+
+ # Check that the merge config lists are not missing any item specified
+ # by the default config lists.
+ difference = default_combined_item_set.difference(combined_item_set)
+ if difference:
+ logger.error('Missing merge config items: %s' % list(difference))
+ logger.error('Please ensure missing items are in either the '
+ 'system-item-list or other-item-list files provided to '
+ 'this script.')
+ return False
+
+ return True
+
+
def process_ab_partitions_txt(
system_target_files_temp_dir,
other_target_files_temp_dir,
@@ -223,7 +287,8 @@
def process_misc_info_txt(
system_target_files_temp_dir,
other_target_files_temp_dir,
- output_target_files_temp_dir):
+ output_target_files_temp_dir,
+ system_misc_info_keys):
"""Perform special processing for META/misc_info.txt
This function merges the contents of the META/misc_info.txt files from the
@@ -242,6 +307,9 @@
output_target_files_temp_dir: The name of a directory that will be used
to create the output target files package after all the special cases
are processed.
+
+ system_misc_info_keys: A list of keys to obtain from the system instance
+ of META/misc_info.txt. The remaining keys from the other instance.
"""
def read_helper(d):
@@ -258,8 +326,7 @@
read_helper(other_target_files_temp_dir))
# Replace certain values in merged_info_dict with values from
- # system_info_dict. TODO(b/124467065): This should be more flexible than
- # using the hard-coded system_misc_info_keys.
+ # system_info_dict.
for key in system_misc_info_keys:
merged_info_dict[key] = system_info_dict[key]
@@ -355,7 +422,8 @@
temp_dir,
system_target_files_temp_dir,
other_target_files_temp_dir,
- output_target_files_temp_dir):
+ output_target_files_temp_dir,
+ system_misc_info_keys):
"""Perform special-case processing for certain target files items.
Certain files in the output target files package require special-case
@@ -374,6 +442,9 @@
output_target_files_temp_dir: The name of a directory that will be used
to create the output target files package after all the special cases
are processed.
+
+ system_misc_info_keys: A list of keys to obtain from the system instance
+ of META/misc_info.txt. The remaining keys from the other instance.
"""
process_ab_partitions_txt(
@@ -384,7 +455,8 @@
process_misc_info_txt(
system_target_files_temp_dir=system_target_files_temp_dir,
other_target_files_temp_dir=other_target_files_temp_dir,
- output_target_files_temp_dir=output_target_files_temp_dir)
+ output_target_files_temp_dir=output_target_files_temp_dir,
+ system_misc_info_keys=system_misc_info_keys)
process_file_contexts_bin(
temp_dir=temp_dir,
@@ -394,8 +466,12 @@
def merge_target_files(
temp_dir,
system_target_files,
+ system_item_list,
+ system_misc_info_keys,
other_target_files,
- output_target_files):
+ other_item_list,
+ output_target_files,
+ rebuild_recovery):
"""Merge two target files packages together.
This function takes system and other target files packages as input, performs
@@ -410,13 +486,35 @@
system_target_files: The name of the zip archive containing the system
partial target files package.
+ system_item_list: The list of items to extract from the partial system
+ target files package as is, meaning these items will land in the output
+ target files package exactly as they appear in the input partial system
+ target files package.
+
+ system_misc_info_keys: The list of keys to obtain from the system instance
+ of META/misc_info.txt. The remaining keys from the other instance.
+
other_target_files: The name of the zip archive containing the other
partial target files package.
+ other_item_list: The list of items to extract from the partial other
+ target files package as is, meaning these items will land in the output
+ target files package exactly as they appear in the input partial other
+ target files package.
+
output_target_files: The name of the output zip archive target files
package created by merging system and other.
+
+ rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
+ devices and write it to the system image.
"""
+ logger.info(
+ 'starting: merge system %s and other %s into output %s',
+ system_target_files,
+ other_target_files,
+ output_target_files)
+
# Create directory names that we'll use when we extract files from system,
# and other, and for zipping the final output.
@@ -431,7 +529,7 @@
extract_items(
target_files=system_target_files,
target_files_temp_dir=output_target_files_temp_dir,
- extract_item_list=system_extract_as_is_item_list)
+ extract_item_list=system_item_list)
# Extract "as is" items from the input other partial target files package. We
# extract them directly into the output temporary directory since the items
@@ -440,7 +538,7 @@
extract_items(
target_files=other_target_files,
target_files_temp_dir=output_target_files_temp_dir,
- extract_item_list=other_extract_as_is_item_list)
+ extract_item_list=other_item_list)
# Extract "special" items from the input system partial target files package.
# We extract these items to different directory since they require special
@@ -469,14 +567,15 @@
temp_dir=temp_dir,
system_target_files_temp_dir=system_target_files_temp_dir,
other_target_files_temp_dir=other_target_files_temp_dir,
- output_target_files_temp_dir=output_target_files_temp_dir)
+ output_target_files_temp_dir=output_target_files_temp_dir,
+ system_misc_info_keys=system_misc_info_keys)
# Regenerate IMAGES in the temporary directory.
- add_img_args = [
- '--verbose',
- output_target_files_temp_dir,
- ]
+ add_img_args = ['--verbose']
+ if rebuild_recovery:
+ add_img_args.append('--rebuild_recovery')
+ add_img_args.append(output_target_files_temp_dir)
add_img_to_target_files.main(add_img_args)
@@ -520,25 +619,15 @@
common.RunAndWait(command, verbose=True)
-def merge_target_files_with_temp_dir(
- system_target_files,
- other_target_files,
- output_target_files,
- keep_tmp):
+def call_func_with_temp_dir(func, keep_tmp):
"""Manage the creation and cleanup of the temporary directory.
- This function wraps merge_target_files after first creating a temporary
+ This function calls the given function after first creating a temporary
directory. It also cleans up the temporary directory.
Args:
- system_target_files: The name of the zip archive containing the system
- partial target files package.
-
- other_target_files: The name of the zip archive containing the other
- partial target files package.
-
- output_target_files: The name of the output zip archive target files
- package created by merging system and other.
+ func: The function to call. Should accept one parameter, the path to
+ the temporary directory.
keep_tmp: Keep the temporary directory after processing is complete.
"""
@@ -547,20 +636,10 @@
# we use when we extract items from the input target files packages, and also
# a scratch directory that we use for temporary files.
- logger.info(
- 'starting: merge system %s and other %s into output %s',
- system_target_files,
- other_target_files,
- output_target_files)
-
temp_dir = common.MakeTempDir(prefix='merge_target_files_')
try:
- merge_target_files(
- temp_dir=temp_dir,
- system_target_files=system_target_files,
- other_target_files=other_target_files,
- output_target_files=output_target_files)
+ func(temp_dir)
except:
raise
finally:
@@ -573,7 +652,7 @@
def main():
"""The main function.
- Process command line arguments, then call merge_target_files_with_temp_dir to
+ Process command line arguments, then call merge_target_files to
perform the heavy lifting.
"""
@@ -582,10 +661,18 @@
def option_handler(o, a):
if o == '--system-target-files':
OPTIONS.system_target_files = a
+ elif o == '--system-item-list':
+ OPTIONS.system_item_list = a
+ elif o == '--system-misc-info-keys':
+ OPTIONS.system_misc_info_keys = a
elif o == '--other-target-files':
OPTIONS.other_target_files = a
+ elif o == '--other-item-list':
+ OPTIONS.other_item_list = a
elif o == '--output-target-files':
OPTIONS.output_target_files = a
+ elif o == '--rebuild_recovery':
+ OPTIONS.rebuild_recovery = True
elif o == '--keep_tmp':
OPTIONS.keep_tmp = True
else:
@@ -596,8 +683,12 @@
sys.argv[1:], __doc__,
extra_long_opts=[
'system-target-files=',
+ 'system-item-list=',
+ 'system-misc-info-keys=',
'other-target-files=',
+ 'other-item-list=',
'output-target-files=',
+ 'rebuild_recovery',
"keep_tmp",
],
extra_option_handler=option_handler)
@@ -609,11 +700,37 @@
common.Usage(__doc__)
sys.exit(1)
- merge_target_files_with_temp_dir(
- system_target_files=OPTIONS.system_target_files,
- other_target_files=OPTIONS.other_target_files,
- output_target_files=OPTIONS.output_target_files,
- keep_tmp=OPTIONS.keep_tmp)
+ if OPTIONS.system_item_list:
+ system_item_list = read_config_list(OPTIONS.system_item_list)
+ else:
+ system_item_list = default_system_item_list
+
+ if OPTIONS.system_misc_info_keys:
+ system_misc_info_keys = read_config_list(OPTIONS.system_misc_info_keys)
+ else:
+ system_misc_info_keys = default_system_misc_info_keys
+
+ if OPTIONS.other_item_list:
+ other_item_list = read_config_list(OPTIONS.other_item_list)
+ else:
+ other_item_list = default_other_item_list
+
+ if not validate_config_lists(
+ system_item_list=system_item_list,
+ other_item_list=other_item_list):
+ sys.exit(1)
+
+ call_func_with_temp_dir(
+ lambda temp_dir: merge_target_files(
+ temp_dir=temp_dir,
+ system_target_files=OPTIONS.system_target_files,
+ system_item_list=system_item_list,
+ system_misc_info_keys=system_misc_info_keys,
+ other_target_files=OPTIONS.other_target_files,
+ other_item_list=other_item_list,
+ output_target_files=OPTIONS.output_target_files,
+ rebuild_recovery=OPTIONS.rebuild_recovery),
+ OPTIONS.keep_tmp)
if __name__ == '__main__':
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index a07f67f..75a98fd 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -21,11 +21,17 @@
Usage: sign_target_files_apks [flags] input_target_files output_target_files
-e (--extra_apks) <name,name,...=key>
- Add extra APK name/key pairs as though they appeared in
- apkcerts.txt (so mappings specified by -k and -d are applied).
- Keys specified in -e override any value for that app contained
- in the apkcerts.txt file. Option may be repeated to give
- multiple extra packages.
+ Add extra APK/APEX name/key pairs as though they appeared in apkcerts.txt
+ or apexkeys.txt (so mappings specified by -k and -d are applied). Keys
+ specified in -e override any value for that app contained in the
+ apkcerts.txt file, or the container key for an APEX. Option may be
+ repeated to give multiple extra packages.
+
+ --extra_apex_payload_key <name=key>
+ Add a mapping for APEX package name to payload signing key, which will
+ override the default payload signing key in apexkeys.txt. Note that the
+ container key should be overridden via the `--extra_apks` flag above.
+ Option may be repeated for multiple APEXes.
--skip_apks_with_path_prefix <prefix>
Skip signing an APK if it has the matching prefix in its path. The prefix
@@ -85,12 +91,12 @@
Replace the veritykeyid in BOOT/cmdline of input_target_file_zip
with keyid of the cert pointed by <path_to_X509_PEM_cert_file>.
- --avb_{boot,system,vendor,dtbo,vbmeta}_algorithm <algorithm>
- --avb_{boot,system,vendor,dtbo,vbmeta}_key <key>
+ --avb_{boot,system,system_other,vendor,dtbo,vbmeta}_algorithm <algorithm>
+ --avb_{boot,system,system_other,vendor,dtbo,vbmeta}_key <key>
Use the specified algorithm (e.g. SHA256_RSA4096) and the key to AVB-sign
the specified image. Otherwise it uses the existing values in info dict.
- --avb_{boot,system,vendor,dtbo,vbmeta}_extra_args <args>
+ --avb_{apex,boot,system,system_other,vendor,dtbo,vbmeta}_extra_args <args>
Specify any additional args that are needed to AVB-sign the image
(e.g. "--signing_helper /path/to/helper"). The args will be appended to
the existing ones in info dict.
@@ -102,6 +108,8 @@
import copy
import errno
import gzip
+import itertools
+import logging
import os
import re
import shutil
@@ -113,6 +121,7 @@
from xml.etree import ElementTree
import add_img_to_target_files
+import apex_utils
import common
@@ -121,9 +130,12 @@
sys.exit(1)
+logger = logging.getLogger(__name__)
+
OPTIONS = common.OPTIONS
OPTIONS.extra_apks = {}
+OPTIONS.extra_apex_payload_keys = {}
OPTIONS.skip_apks_with_path_prefix = set()
OPTIONS.key_map = {}
OPTIONS.rebuild_recovery = False
@@ -151,6 +163,43 @@
return certmap
+def GetApexKeys(keys_info, key_map):
+ """Gets APEX payload and container signing keys by applying the mapping rules.
+
+ Presigned payload / container keys will be set accordingly.
+
+ Args:
+ keys_info: A dict that maps from APEX filenames to a tuple of (payload_key,
+ container_key).
+ key_map: A dict that overrides the keys, specified via command-line input.
+
+ Returns:
+ A dict that contains the updated APEX key mapping, which should be used for
+ the current signing.
+ """
+ # Apply all the --extra_apex_payload_key options to override the payload
+ # signing keys in the given keys_info.
+ for apex, key in OPTIONS.extra_apex_payload_keys.items():
+ if not key:
+ key = 'PRESIGNED'
+ keys_info[apex] = (key, keys_info[apex][1])
+
+ # Apply the key remapping to container keys.
+ for apex, (payload_key, container_key) in keys_info.items():
+ keys_info[apex] = (payload_key, key_map.get(container_key, container_key))
+
+ # Apply all the --extra_apks options to override the container keys.
+ for apex, key in OPTIONS.extra_apks.items():
+ # Skip non-APEX containers.
+ if apex not in keys_info:
+ continue
+ if not key:
+ key = 'PRESIGNED'
+ keys_info[apex] = (keys_info[apex][0], key_map.get(key, key))
+
+ return keys_info
+
+
def GetApkFileInfo(filename, compressed_extension, skipped_prefixes):
"""Returns the APK info based on the given filename.
@@ -180,11 +229,8 @@
# skipped_prefixes should be one of set/list/tuple types. Other types such as
# str shouldn't be accepted.
- assert (isinstance(skipped_prefixes, tuple) or
- isinstance(skipped_prefixes, set) or
- isinstance(skipped_prefixes, list)), \
- "Invalid skipped_prefixes input type: {}".format(
- type(skipped_prefixes))
+ assert isinstance(skipped_prefixes, (set, list, tuple)), \
+ "Invalid skipped_prefixes input type: {}".format(type(skipped_prefixes))
compressed_apk_extension = (
".apk" + compressed_extension if compressed_extension else None)
@@ -200,34 +246,72 @@
return (True, is_compressed, should_be_skipped)
-def CheckAllApksSigned(input_tf_zip, apk_key_map, compressed_extension):
- """Checks that all the APKs have keys specified, otherwise errors out.
+def CheckApkAndApexKeysAvailable(input_tf_zip, known_keys,
+ compressed_extension, apex_keys):
+ """Checks that all the APKs and APEXes have keys specified.
Args:
input_tf_zip: An open target_files zip file.
- apk_key_map: A dict of known signing keys key'd by APK names.
+ known_keys: A set of APKs and APEXes that have known signing keys.
compressed_extension: The extension string of compressed APKs, such as
- ".gz", or None if there's no compressed APKs.
+ '.gz', or None if there's no compressed APKs.
+ apex_keys: A dict that contains the key mapping from APEX name to
+ (payload_key, container_key).
Raises:
- AssertionError: On finding unknown APKs.
+ AssertionError: On finding unknown APKs and APEXes.
"""
- unknown_apks = []
+ unknown_files = []
for info in input_tf_zip.infolist():
+ # Handle APEXes first, e.g. SYSTEM/apex/com.android.tzdata.apex.
+ if (info.filename.startswith('SYSTEM/apex') and
+ info.filename.endswith('.apex')):
+ name = os.path.basename(info.filename)
+ if name not in known_keys:
+ unknown_files.append(name)
+ continue
+
+ # And APKs.
(is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
info.filename, compressed_extension, OPTIONS.skip_apks_with_path_prefix)
if not is_apk or should_be_skipped:
continue
+
name = os.path.basename(info.filename)
if is_compressed:
name = name[:-len(compressed_extension)]
- if name not in apk_key_map:
- unknown_apks.append(name)
+ if name not in known_keys:
+ unknown_files.append(name)
- assert not unknown_apks, \
+ assert not unknown_files, \
("No key specified for:\n {}\n"
"Use '-e <apkname>=' to specify a key (which may be an empty string to "
- "not sign this apk).".format("\n ".join(unknown_apks)))
+ "not sign this apk).".format("\n ".join(unknown_files)))
+
+ # For all the APEXes, double check that we won't have an APEX that has only
+ # one of the payload / container keys set.
+ if not apex_keys:
+ return
+
+ invalid_apexes = []
+ for info in input_tf_zip.infolist():
+ if (not info.filename.startswith('SYSTEM/apex') or
+ not info.filename.endswith('.apex')):
+ continue
+
+ name = os.path.basename(info.filename)
+ (payload_key, container_key) = apex_keys[name]
+ if ((payload_key in common.SPECIAL_CERT_STRINGS and
+ container_key not in common.SPECIAL_CERT_STRINGS) or
+ (payload_key not in common.SPECIAL_CERT_STRINGS and
+ container_key in common.SPECIAL_CERT_STRINGS)):
+ invalid_apexes.append(
+ "{}: payload_key {}, container_key {}".format(
+ name, payload_key, container_key))
+
+ assert not invalid_apexes, \
+ "Invalid APEX keys specified:\n {}\n".format(
+ "\n ".join(invalid_apexes))
def SignApk(data, keyname, pw, platform_api_level, codename_to_api_level_map,
@@ -293,9 +377,69 @@
return data
+def SignApex(apex_data, payload_key, container_key, container_pw,
+ codename_to_api_level_map, signing_args=None):
+ """Signs the current APEX with the given payload/container keys.
+
+ Args:
+ apex_data: Raw APEX data.
+ payload_key: The path to payload signing key (w/o extension).
+ container_key: The path to container signing key (w/o extension).
+ container_pw: The matching password of the container_key, or None.
+ codename_to_api_level_map: A dict that maps from codename to API level.
+ signing_args: Additional args to be passed to the payload signer.
+
+ Returns:
+ (signed_apex, payload_key_name): signed_apex is the path to the signed APEX
+ file; payload_key_name is a str of the payload signing key name (e.g.
+ com.android.tzdata).
+ """
+ apex_file = common.MakeTempFile(prefix='apex-', suffix='.apex')
+ with open(apex_file, 'wb') as apex_fp:
+ apex_fp.write(apex_data)
+
+ APEX_PAYLOAD_IMAGE = 'apex_payload.img'
+
+ # Signing an APEX is a two step process.
+ # 1. Extract and sign the APEX_PAYLOAD_IMAGE entry with the given payload_key.
+ payload_dir = common.MakeTempDir(prefix='apex-payload-')
+ with zipfile.ZipFile(apex_file) as apex_fd:
+ payload_file = apex_fd.extract(APEX_PAYLOAD_IMAGE, payload_dir)
+
+ payload_info = apex_utils.ParseApexPayloadInfo(payload_file)
+ apex_utils.SignApexPayload(
+ payload_file,
+ payload_key,
+ payload_info['apex.key'],
+ payload_info['Algorithm'],
+ payload_info['Salt'],
+ signing_args)
+
+ common.ZipDelete(apex_file, APEX_PAYLOAD_IMAGE)
+ apex_zip = zipfile.ZipFile(apex_file, 'a')
+ common.ZipWrite(apex_zip, payload_file, arcname=APEX_PAYLOAD_IMAGE)
+ common.ZipClose(apex_zip)
+
+ # 2. Sign the overall APEX container with container_key.
+ signed_apex = common.MakeTempFile(prefix='apex-container-', suffix='.apex')
+ common.SignFile(
+ apex_file,
+ signed_apex,
+ container_key,
+ container_pw,
+ codename_to_api_level_map=codename_to_api_level_map)
+
+ signed_and_aligned_apex = common.MakeTempFile(
+ prefix='apex-container-', suffix='.apex')
+ common.RunAndCheckOutput(
+ ['zipalign', '-f', '4096', signed_apex, signed_and_aligned_apex])
+
+ return (signed_and_aligned_apex, payload_info['apex.key'])
+
+
def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
- apk_key_map, key_passwords, platform_api_level,
- codename_to_api_level_map,
+ apk_keys, apex_keys, key_passwords,
+ platform_api_level, codename_to_api_level_map,
compressed_extension):
# maxsize measures the maximum filename length, including the ones to be
# skipped.
@@ -304,6 +448,10 @@
if GetApkFileInfo(i.filename, compressed_extension, [])[0]])
system_root_image = misc_info.get("system_root_image") == "true"
+ # A dict of APEX payload public keys that should be updated, i.e. the files
+ # under '/system/etc/security/apex/'.
+ updated_apex_payload_keys = {}
+
for info in input_tf_zip.infolist():
filename = info.filename
if filename.startswith("IMAGES/"):
@@ -331,7 +479,7 @@
if is_compressed:
name = name[:-len(compressed_extension)]
- key = apk_key_map[name]
+ key = apk_keys[name]
if key not in common.SPECIAL_CERT_STRINGS:
print(" signing: %-*s (%s)" % (maxsize, name, key))
signed_data = SignApk(data, key, key_passwords[key], platform_api_level,
@@ -344,6 +492,40 @@
" (skipped due to special cert string)" % (name,))
common.ZipWriteStr(output_tf_zip, out_info, data)
+ # Sign bundled APEX files.
+ elif filename.startswith("SYSTEM/apex") and filename.endswith(".apex"):
+ name = os.path.basename(filename)
+ payload_key, container_key = apex_keys[name]
+
+ # We've asserted not having a case with only one of them PRESIGNED.
+ if (payload_key not in common.SPECIAL_CERT_STRINGS and
+ container_key not in common.SPECIAL_CERT_STRINGS):
+ print(" signing: %-*s container (%s)" % (
+ maxsize, name, container_key))
+ print(" : %-*s payload (%s)" % (
+ maxsize, name, payload_key))
+
+ (signed_apex, payload_key_name) = SignApex(
+ data,
+ payload_key,
+ container_key,
+ key_passwords[container_key],
+ codename_to_api_level_map,
+ OPTIONS.avb_extra_args.get('apex'))
+ common.ZipWrite(output_tf_zip, signed_apex, filename)
+ updated_apex_payload_keys[payload_key_name] = payload_key
+
+ else:
+ print(
+ "NOT signing: %s\n"
+ " (skipped due to special cert string)" % (name,))
+ common.ZipWriteStr(output_tf_zip, out_info, data)
+
+ # AVB public keys for the installed APEXes, which will be updated later.
+ elif (os.path.dirname(filename) == 'SYSTEM/etc/security/apex' and
+ filename != 'SYSTEM/etc/security/apex/'):
+ continue
+
# System properties.
elif filename in ("SYSTEM/build.prop",
"VENDOR/build.prop",
@@ -402,10 +584,48 @@
elif filename == "META/care_map.pb" or filename == "META/care_map.txt":
pass
+ # Updates system_other.avbpubkey in /product/etc/.
+ elif filename in (
+ "PRODUCT/etc/security/avb/system_other.avbpubkey",
+ "SYSTEM/product/etc/security/avb/system_other.avbpubkey"):
+ # Only update system_other's public key, if the corresponding signing
+ # key is specified via --avb_system_other_key.
+ signing_key = OPTIONS.avb_keys.get("system_other")
+ if signing_key:
+ public_key = common.ExtractAvbPublicKey(signing_key)
+ print(" Rewriting AVB public key of system_other in /product")
+ common.ZipWrite(output_tf_zip, public_key, filename)
+
# A non-APK file; copy it verbatim.
else:
common.ZipWriteStr(output_tf_zip, out_info, data)
+ # Update APEX payload public keys.
+ for info in input_tf_zip.infolist():
+ filename = info.filename
+ if (os.path.dirname(filename) != 'SYSTEM/etc/security/apex' or
+ filename == 'SYSTEM/etc/security/apex/'):
+ continue
+
+ name = os.path.basename(filename)
+
+ # Skip PRESIGNED APEXes.
+ if name not in updated_apex_payload_keys:
+ continue
+
+ key_path = updated_apex_payload_keys[name]
+ if not os.path.exists(key_path) and not key_path.endswith('.pem'):
+ key_path = '{}.pem'.format(key_path)
+ assert os.path.exists(key_path), \
+ 'Failed to find public key file {} for APEX {}'.format(
+ updated_apex_payload_keys[name], name)
+
+ print('Replacing APEX payload public key for {} with {}'.format(
+ name, key_path))
+
+ public_key = common.ExtractAvbPublicKey(key_path)
+ common.ZipWrite(output_tf_zip, public_key, arcname=filename)
+
if OPTIONS.replace_ota_keys:
ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info)
@@ -726,6 +946,7 @@
'dtbo' : 'avb_dtbo_add_hash_footer_args',
'recovery' : 'avb_recovery_add_hash_footer_args',
'system' : 'avb_system_add_hashtree_footer_args',
+ 'system_other' : 'avb_system_other_add_hashtree_footer_args',
'vendor' : 'avb_vendor_add_hashtree_footer_args',
'vbmeta' : 'avb_vbmeta_args',
}
@@ -816,11 +1037,72 @@
result = dict()
for codename in codenames:
codename = codename.strip()
- if len(codename) > 0:
+ if codename:
result[codename] = api_level
return result
+def ReadApexKeysInfo(tf_zip):
+ """Parses the APEX keys info from a given target-files zip.
+
+ Given a target-files ZipFile, parses the META/apexkeys.txt entry and returns a
+ dict that contains the mapping from APEX names (e.g. com.android.tzdata) to a
+ tuple of (payload_key, container_key).
+
+ Args:
+ tf_zip: The input target_files ZipFile (already open).
+
+ Returns:
+ (payload_key, container_key): payload_key contains the path to the payload
+ signing key; container_key contains the path to the container signing
+ key.
+ """
+ keys = {}
+ for line in tf_zip.read("META/apexkeys.txt").split("\n"):
+ line = line.strip()
+ if not line:
+ continue
+ matches = re.match(
+ r'^name="(?P<NAME>.*)"\s+'
+ r'public_key="(?P<PAYLOAD_PUBLIC_KEY>.*)"\s+'
+ r'private_key="(?P<PAYLOAD_PRIVATE_KEY>.*)"\s+'
+ r'container_certificate="(?P<CONTAINER_CERT>.*)"\s+'
+ r'container_private_key="(?P<CONTAINER_PRIVATE_KEY>.*)"$',
+ line)
+ if not matches:
+ continue
+
+ name = matches.group('NAME')
+ payload_public_key = matches.group("PAYLOAD_PUBLIC_KEY")
+ payload_private_key = matches.group("PAYLOAD_PRIVATE_KEY")
+
+ def CompareKeys(pubkey, pubkey_suffix, privkey, privkey_suffix):
+ pubkey_suffix_len = len(pubkey_suffix)
+ privkey_suffix_len = len(privkey_suffix)
+ return (pubkey.endswith(pubkey_suffix) and
+ privkey.endswith(privkey_suffix) and
+ pubkey[:-pubkey_suffix_len] == privkey[:-privkey_suffix_len])
+
+ PAYLOAD_PUBLIC_KEY_SUFFIX = '.avbpubkey'
+ PAYLOAD_PRIVATE_KEY_SUFFIX = '.pem'
+ if not CompareKeys(
+ payload_public_key, PAYLOAD_PUBLIC_KEY_SUFFIX,
+ payload_private_key, PAYLOAD_PRIVATE_KEY_SUFFIX):
+ raise ValueError("Failed to parse payload keys: \n{}".format(line))
+
+ container_cert = matches.group("CONTAINER_CERT")
+ container_private_key = matches.group("CONTAINER_PRIVATE_KEY")
+ if not CompareKeys(
+ container_cert, OPTIONS.public_key_suffix,
+ container_private_key, OPTIONS.private_key_suffix):
+ raise ValueError("Failed to parse container keys: \n{}".format(line))
+
+ keys[name] = (payload_private_key,
+ container_cert[:-len(OPTIONS.public_key_suffix)])
+
+ return keys
+
+
def main(argv):
key_mapping_options = []
@@ -831,6 +1113,9 @@
names = names.split(",")
for n in names:
OPTIONS.extra_apks[n] = key
+ elif o == "--extra_apex_payload_key":
+ apex_name, key = a.split("=")
+ OPTIONS.extra_apex_payload_keys[apex_name] = key
elif o == "--skip_apks_with_path_prefix":
# Sanity check the prefix, which must be in all upper case.
prefix = a.split('/')[0]
@@ -881,12 +1166,20 @@
OPTIONS.avb_algorithms['system'] = a
elif o == "--avb_system_extra_args":
OPTIONS.avb_extra_args['system'] = a
+ elif o == "--avb_system_other_key":
+ OPTIONS.avb_keys['system_other'] = a
+ elif o == "--avb_system_other_algorithm":
+ OPTIONS.avb_algorithms['system_other'] = a
+ elif o == "--avb_system_other_extra_args":
+ OPTIONS.avb_extra_args['system_other'] = a
elif o == "--avb_vendor_key":
OPTIONS.avb_keys['vendor'] = a
elif o == "--avb_vendor_algorithm":
OPTIONS.avb_algorithms['vendor'] = a
elif o == "--avb_vendor_extra_args":
OPTIONS.avb_extra_args['vendor'] = a
+ elif o == "--avb_apex_extra_args":
+ OPTIONS.avb_extra_args['apex'] = a
else:
return False
return True
@@ -896,6 +1189,7 @@
extra_opts="e:d:k:ot:",
extra_long_opts=[
"extra_apks=",
+ "extra_apex_payload_key=",
"skip_apks_with_path_prefix=",
"default_key_mappings=",
"key_mapping=",
@@ -904,6 +1198,7 @@
"replace_verity_public_key=",
"replace_verity_private_key=",
"replace_verity_keyid=",
+ "avb_apex_extra_args=",
"avb_vbmeta_algorithm=",
"avb_vbmeta_key=",
"avb_vbmeta_extra_args=",
@@ -916,6 +1211,9 @@
"avb_system_algorithm=",
"avb_system_key=",
"avb_system_extra_args=",
+ "avb_system_other_algorithm=",
+ "avb_system_other_key=",
+ "avb_system_other_extra_args=",
"avb_vendor_algorithm=",
"avb_vendor_key=",
"avb_vendor_extra_args=",
@@ -926,6 +1224,8 @@
common.Usage(__doc__)
sys.exit(1)
+ common.InitLogging()
+
input_zip = zipfile.ZipFile(args[0], "r")
output_zip = zipfile.ZipFile(args[1], "w",
compression=zipfile.ZIP_DEFLATED,
@@ -935,18 +1235,26 @@
BuildKeyMap(misc_info, key_mapping_options)
- certmap, compressed_extension = common.ReadApkCerts(input_zip)
- apk_key_map = GetApkCerts(certmap)
- CheckAllApksSigned(input_zip, apk_key_map, compressed_extension)
+ apk_keys_info, compressed_extension = common.ReadApkCerts(input_zip)
+ apk_keys = GetApkCerts(apk_keys_info)
- key_passwords = common.GetKeyPasswords(set(apk_key_map.values()))
+ apex_keys_info = ReadApexKeysInfo(input_zip)
+ apex_keys = GetApexKeys(apex_keys_info, apk_keys)
+
+ CheckApkAndApexKeysAvailable(
+ input_zip,
+ set(apk_keys.keys()) | set(apex_keys.keys()),
+ compressed_extension,
+ apex_keys)
+
+ key_passwords = common.GetKeyPasswords(
+ set(apk_keys.values()) | set(itertools.chain(*apex_keys.values())))
platform_api_level, _ = GetApiLevelAndCodename(input_zip)
codename_to_api_level_map = GetCodenameToApiLevelMap(input_zip)
ProcessTargetFiles(input_zip, output_zip, misc_info,
- apk_key_map, key_passwords,
- platform_api_level,
- codename_to_api_level_map,
+ apk_keys, apex_keys, key_passwords,
+ platform_api_level, codename_to_api_level_map,
compressed_extension)
common.ZipClose(input_zip)
diff --git a/tools/releasetools/test_apex_utils.py b/tools/releasetools/test_apex_utils.py
new file mode 100644
index 0000000..2f8ee49
--- /dev/null
+++ b/tools/releasetools/test_apex_utils.py
@@ -0,0 +1,87 @@
+#
+# 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.
+#
+
+import os
+import os.path
+
+import apex_utils
+import common
+import test_utils
+
+
+class ApexUtilsTest(test_utils.ReleaseToolsTestCase):
+
+ # echo "foo" | sha256sum
+ SALT = 'b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'
+
+ def setUp(self):
+ self.testdata_dir = test_utils.get_testdata_dir()
+ # The default payload signing key.
+ self.payload_key = os.path.join(self.testdata_dir, 'testkey.key')
+
+ @staticmethod
+ def _GetTestPayload():
+ payload_file = common.MakeTempFile(prefix='apex-', suffix='.img')
+ with open(payload_file, 'wb') as payload_fp:
+ payload_fp.write(os.urandom(8192))
+ return payload_file
+
+ def test_ParseApexPayloadInfo(self):
+ payload_file = self._GetTestPayload()
+ apex_utils.SignApexPayload(
+ payload_file, self.payload_key, 'testkey', 'SHA256_RSA2048', self.SALT)
+ payload_info = apex_utils.ParseApexPayloadInfo(payload_file)
+ self.assertEqual('SHA256_RSA2048', payload_info['Algorithm'])
+ self.assertEqual(self.SALT, payload_info['Salt'])
+ self.assertEqual('testkey', payload_info['apex.key'])
+
+ def test_SignApexPayload(self):
+ payload_file = self._GetTestPayload()
+ apex_utils.SignApexPayload(
+ payload_file, self.payload_key, 'testkey', 'SHA256_RSA2048', self.SALT)
+ apex_utils.VerifyApexPayload(payload_file, self.payload_key)
+
+ def test_SignApexPayload_withSignerHelper(self):
+ payload_file = self._GetTestPayload()
+ payload_signer_args = '--signing_helper_with_files {}'.format(
+ os.path.join(self.testdata_dir, 'signing_helper.sh'))
+ apex_utils.SignApexPayload(
+ payload_file,
+ self.payload_key,
+ 'testkey', 'SHA256_RSA2048', self.SALT,
+ payload_signer_args)
+ apex_utils.VerifyApexPayload(payload_file, self.payload_key)
+
+ def test_SignApexPayload_invalidKey(self):
+ self.assertRaises(
+ apex_utils.ApexSigningError,
+ apex_utils.SignApexPayload,
+ self._GetTestPayload(),
+ os.path.join(self.testdata_dir, 'testkey.x509.pem'),
+ 'testkey',
+ 'SHA256_RSA2048',
+ self.SALT)
+
+ def test_VerifyApexPayload_wrongKey(self):
+ payload_file = self._GetTestPayload()
+ apex_utils.SignApexPayload(
+ payload_file, self.payload_key, 'testkey', 'SHA256_RSA2048', self.SALT)
+ apex_utils.VerifyApexPayload(payload_file, self.payload_key)
+ self.assertRaises(
+ apex_utils.ApexSigningError,
+ apex_utils.VerifyApexPayload,
+ payload_file,
+ os.path.join(self.testdata_dir, 'testkey_with_passwd.key'))
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index cfd070d..8709124 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -491,6 +491,13 @@
wrong_input = os.path.join(self.testdata_dir, 'testkey.pk8')
self.assertRaises(AssertionError, common.ExtractPublicKey, wrong_input)
+ def test_ExtractAvbPublicKey(self):
+ privkey = os.path.join(self.testdata_dir, 'testkey.key')
+ pubkey = os.path.join(self.testdata_dir, 'testkey.pubkey.pem')
+ with open(common.ExtractAvbPublicKey(privkey)) as privkey_fp, \
+ open(common.ExtractAvbPublicKey(pubkey)) as pubkey_fp:
+ self.assertEqual(privkey_fp.read(), pubkey_fp.read())
+
def test_ParseCertificate(self):
cert = os.path.join(self.testdata_dir, 'testkey.x509.pem')
@@ -1218,7 +1225,7 @@
dp_diff.WriteScript(self.script, output_zip, write_verify_script=True)
self.assertNotIn("block_image_update", str(self.script),
- "Removed partition should not be patched.")
+ "Removed partition should not be patched.")
lines = self.get_op_list(self.output_path)
self.assertEqual(lines, ["remove foo"])
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index 18762ee..6082baf 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -21,8 +21,8 @@
import common
import test_utils
from sign_target_files_apks import (
- CheckAllApksSigned, EditTags, GetApkFileInfo, ReplaceCerts,
- ReplaceVerityKeyId, RewriteProps)
+ CheckApkAndApexKeysAvailable, EditTags, GetApkFileInfo, ReadApexKeysInfo,
+ ReplaceCerts, ReplaceVerityKeyId, RewriteProps)
class SignTargetFilesApksTest(test_utils.ReleaseToolsTestCase):
@@ -33,6 +33,11 @@
<signer signature="{}"><seinfo value="media"/></signer>
</policy>"""
+ # pylint: disable=line-too-long
+ APEX_KEYS_TXT = """name="apex.apexd_test.apex" public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package.avbpubkey" private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem" container_certificate="build/target/product/security/testkey.x509.pem" container_private_key="build/target/product/security/testkey.pk8"
+name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem" container_certificate="build/target/product/security/testkey.x509.pem" container_private_key="build/target/product/security/testkey.pk8"
+"""
+
def setUp(self):
self.testdata_dir = test_utils.get_testdata_dir()
@@ -207,7 +212,7 @@
}
self.assertEqual(output_xml, ReplaceCerts(input_xml))
- def test_CheckAllApksSigned(self):
+ def test_CheckApkAndApexKeysAvailable(self):
input_file = common.MakeTempFile(suffix='.zip')
with zipfile.ZipFile(input_file, 'w') as input_zip:
input_zip.writestr('SYSTEM/app/App1.apk', "App1-content")
@@ -219,16 +224,50 @@
'App3.apk' : 'key3',
}
with zipfile.ZipFile(input_file) as input_zip:
- CheckAllApksSigned(input_zip, apk_key_map, None)
- CheckAllApksSigned(input_zip, apk_key_map, '.gz')
+ CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, {})
+ CheckApkAndApexKeysAvailable(input_zip, apk_key_map, '.gz', {})
# 'App2.apk.gz' won't be considered as an APK.
- CheckAllApksSigned(input_zip, apk_key_map, None)
- CheckAllApksSigned(input_zip, apk_key_map, '.xz')
+ CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, {})
+ CheckApkAndApexKeysAvailable(input_zip, apk_key_map, '.xz', {})
del apk_key_map['App2.apk']
self.assertRaises(
- AssertionError, CheckAllApksSigned, input_zip, apk_key_map, '.gz')
+ AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
+ '.gz', {})
+
+ def test_CheckApkAndApexKeysAvailable_invalidApexKeys(self):
+ input_file = common.MakeTempFile(suffix='.zip')
+ with zipfile.ZipFile(input_file, 'w') as input_zip:
+ input_zip.writestr('SYSTEM/apex/Apex1.apex', "Apex1-content")
+ input_zip.writestr('SYSTEM/apex/Apex2.apex', "Apex2-content")
+
+ apk_key_map = {
+ 'Apex1.apex' : 'key1',
+ 'Apex2.apex' : 'key2',
+ 'Apex3.apex' : 'key3',
+ }
+ apex_keys = {
+ 'Apex1.apex' : ('payload-key1', 'container-key1'),
+ 'Apex2.apex' : ('payload-key2', 'container-key2'),
+ }
+ with zipfile.ZipFile(input_file) as input_zip:
+ CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, apex_keys)
+
+ # Fine to have both keys as PRESIGNED.
+ apex_keys['Apex2.apex'] = ('PRESIGNED', 'PRESIGNED')
+ CheckApkAndApexKeysAvailable(input_zip, apk_key_map, None, apex_keys)
+
+ # Having only one of them as PRESIGNED is not allowed.
+ apex_keys['Apex2.apex'] = ('payload-key2', 'PRESIGNED')
+ self.assertRaises(
+ AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
+ None, apex_keys)
+
+ apex_keys['Apex2.apex'] = ('PRESIGNED', 'container-key1')
+ self.assertRaises(
+ AssertionError, CheckApkAndApexKeysAvailable, input_zip, apk_key_map,
+ None, apex_keys)
def test_GetApkFileInfo(self):
(is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
@@ -344,3 +383,58 @@
self.assertRaises(
AssertionError, GetApkFileInfo, "SYSTEM_OTHER/preloads/apps/Chats.apk",
None, None)
+
+ def test_ReadApexKeysInfo(self):
+ target_files = common.MakeTempFile(suffix='.zip')
+ with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+ target_files_zip.writestr('META/apexkeys.txt', self.APEX_KEYS_TXT)
+
+ with zipfile.ZipFile(target_files) as target_files_zip:
+ keys_info = ReadApexKeysInfo(target_files_zip)
+
+ self.assertEqual({
+ 'apex.apexd_test.apex': (
+ 'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
+ 'build/target/product/security/testkey'),
+ 'apex.apexd_test_different_app.apex': (
+ 'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
+ 'build/target/product/security/testkey'),
+ }, keys_info)
+
+ def test_ReadApexKeysInfo_mismatchingKeys(self):
+ # Mismatching payload public / private keys.
+ apex_keys = self.APEX_KEYS_TXT + (
+ 'name="apex.apexd_test_different_app2.apex" '
+ 'public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" '
+ 'private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_3.pem" '
+ 'container_certificate="build/target/product/security/testkey.x509.pem" '
+ 'container_private_key="build/target/product/security/testkey.pk8"')
+ target_files = common.MakeTempFile(suffix='.zip')
+ with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+ target_files_zip.writestr('META/apexkeys.txt', apex_keys)
+
+ with zipfile.ZipFile(target_files) as target_files_zip:
+ self.assertRaises(ValueError, ReadApexKeysInfo, target_files_zip)
+
+ def test_ReadApexKeysInfo_missingPrivateKey(self):
+ # Invalid lines will be skipped.
+ apex_keys = self.APEX_KEYS_TXT + (
+ 'name="apex.apexd_test_different_app2.apex" '
+ 'public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" '
+ 'container_certificate="build/target/product/security/testkey.x509.pem" '
+ 'container_private_key="build/target/product/security/testkey.pk8"')
+ target_files = common.MakeTempFile(suffix='.zip')
+ with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+ target_files_zip.writestr('META/apexkeys.txt', apex_keys)
+
+ with zipfile.ZipFile(target_files) as target_files_zip:
+ keys_info = ReadApexKeysInfo(target_files_zip)
+
+ self.assertEqual({
+ 'apex.apexd_test.apex': (
+ 'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
+ 'build/target/product/security/testkey'),
+ 'apex.apexd_test_different_app.apex': (
+ 'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
+ 'build/target/product/security/testkey'),
+ }, keys_info)
diff --git a/tools/releasetools/testdata/signing_helper.sh b/tools/releasetools/testdata/signing_helper.sh
new file mode 100755
index 0000000..364e023
--- /dev/null
+++ b/tools/releasetools/testdata/signing_helper.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# 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.
+#
+
+tmpfile=$(mktemp)
+cat $3 | openssl rsautl -sign -inkey $2 -raw > $tmpfile
+cat $tmpfile > $3
+rm $tmpfile
diff --git a/tools/releasetools/testdata/testkey_with_passwd.key b/tools/releasetools/testdata/testkey_with_passwd.key
new file mode 100644
index 0000000..2f0a199
--- /dev/null
+++ b/tools/releasetools/testdata/testkey_with_passwd.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCwaAOHPqgkCmqU
+AFRnJW6LrAuSfy9EzWSRHSkltp811ByMIE0N6/Nttu8ZCL456lzArHNKt/zdoBik
+eLB6gN9CTvQ8n4LMdSEmkRl3uXBtOPJuVObJ6ZUILz6L7WofWcr8DT81j2At7nHi
+Wg8SkCsFXbFfpjljOlpqUG3Szt+48X8rcgG82s97BuRwNxUgfK1/8QzOiH9fDbMU
+h6XI2jo2VwuBYOsJadJJWOf6oRRHZonrts0FXpV46CXykpLvLT2u5GXg1Pxd7i1K
+v1P8bxZOzVbEVfkL2DnUCtUBAnP98r9UyjQDd4blk4Mwl+mzB5otPTacNzEGhmNK
+Et+HB/cdAgMBAAECggEATsn2IXa7tHUuivHmwLb4O8vY01KY8xrleubSVPTPAUS+
+h1t57ujerbcR7VV5WPay/J9JUyr/9qClwPfioqRikwQek+EOk3ERIF+YR1/8tdvE
+c8DZ337DQIeRYP/l8SCyx4bHH43tADbKiLV+m+TmQhxJt5XPdeE/NtK7andZdwkv
+xEoG9l2aONE4z9pY1x+c1SdDSsq92/iLHLgSkQJmWo+lrfeh6gshXgQgDY8n6rgY
+GsCgSawLphvd8Tvo86CL04l0pWtY1gEW3s6sdYo1YDkpWQzSRCtGm0GlhEt2fyq5
+coTK2sLHguE7NL5VZo4zlGtM3QBdvRksTO1mJOt6JQKBgQDaT4oGjZp1rtKdObvn
+ElaUo5EOyJjmXkRBBndrbiG3078eOqTJHXx45DJUv8hj9+g6vSULiIeFk1FiiMQD
+vcnsBEaGaSc886wXY6TQgIIzvVfzDHGYTuQydiYQbLClH6S28HLqdlZjUIlHwxb9
+wBm8JwmTiVeAEvO8LTzeEqfkLwKBgQDO3He8Ei8XDeqtIK0lzcZ83yw9OGP23/gK
+8GDaf8J+cOtOyYkDlcV0rBNFvE8+TzIpIUlo47b2RSaART3iPSfRJTaySZjKWCVo
+s2A0/zQcrj7GgD2gaHRrgI9bmnWW1j95a9n/6AUEyEIJ6K8tYK819Vl4GAyhNHEQ
+sRbxa69qcwKBgQC5F8jxx2tXLdM6JLIQtzabLZcWTrN8Vh5Od3oWpriF0EzxB02h
+ipN3OBsISdZQE+dcrfNTtP0aHo5ZGZX/ihFCP1nAKjVvczXMWtppQRujXHzOABXr
+ya+mrQ+Wy2B1j7+qr3DvI0gZSjYqltjOaeon4X04DrEWUHtAZ6Z8rpqUVwKBgQCB
+o8mmI/8/A4m/Vmss9fke6P5gn6aGYXah5GPOi6Loevv9NHCZvpMwu2aYnZtMAXX+
+MM5A3fUcAdpPKRXPY2RAvoG42kbXCMbpBwGUNRwDnW/aFySIEu5jMP6m+fYXwc2l
+2uGUb2Q1ywsYCqs+VQl5V3nquaewn5z8SP+H7WTR4QKBgQCO5CRpyNOjEwMxTPR1
+GYUKAEiVtmzknHAxUE6drTgGEZSquAXiau0B5+7+/G5gwqxCLGpnstMByI+dhkR6
++ybAc/bzb2aoGK4pZf/PuwxQQsHBnG0oaSFU6RZlbVV20j7FZ04+cYnKHwCYkKjN
+DwA1Ae+H+u95raB4vYhk7IzD4A==
+-----END PRIVATE KEY-----