Merge "Add new llndk library, libneuralnetworks_shim.so"
diff --git a/core/Makefile b/core/Makefile
index 191c0eb..99df084 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -856,6 +856,23 @@
--os_version $(PLATFORM_VERSION_LAST_STABLE) \
--os_patch_level $(PLATFORM_SECURITY_PATCH)
+ifdef BOARD_GKI_SIGNING_KEY_PATH
+ifndef BOARD_GKI_SIGNING_ALGORITHM
+$(error BOARD_GKI_SIGNING_ALGORITHM should be defined with BOARD_GKI_SIGNING_KEY_PATH)
+endif
+INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS := \
+ --gki_signing_key $(BOARD_GKI_SIGNING_KEY_PATH) \
+ --gki_signing_algorithm $(BOARD_GKI_SIGNING_ALGORITHM) \
+ --gki_signing_avbtool_path $(AVBTOOL)
+endif
+
+# Using double quote to pass BOARD_GKI_SIGNING_SIGNATURE_ARGS as a single string
+# to MKBOOTIMG, although it may contain multiple args.
+ifdef BOARD_GKI_SIGNING_SIGNATURE_ARGS
+INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS += \
+ --gki_signing_signature_args "$(BOARD_GKI_SIGNING_SIGNATURE_ARGS)"
+endif
+
# Define these only if we are building boot
ifdef BUILDING_BOOT_IMAGE
INSTALLED_BOOTIMAGE_TARGET := $(BUILT_BOOTIMAGE_TARGET)
@@ -870,7 +887,8 @@
# $1: boot image target
define build_boot_board_avb_enabled
- $(MKBOOTIMG) --kernel $(call bootimage-to-kernel,$(1)) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1)
+ $(MKBOOTIMG) --kernel $(call bootimage-to-kernel,$(1)) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \
+ $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1)
$(call assert-max-image-size,$(1),$(call get-hash-image-max-size,$(call get-bootimage-partition-size,$(1),boot)))
$(AVBTOOL) add_hash_footer \
--image $(1) \
@@ -879,12 +897,12 @@
$(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)
endef
-$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH)
+$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH) $(BOARD_GKI_SIGNING_KEY_PATH)
$(call pretty,"Target boot image: $@")
$(call build_boot_board_avb_enabled,$@)
.PHONY: bootimage-nodeps
-bootimage-nodeps: $(MKBOOTIMG) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH)
+bootimage-nodeps: $(MKBOOTIMG) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH) $(BOARD_GKI_SIGNING_KEY_PATH)
@echo "make $@: ignoring dependencies"
$(foreach b,$(INSTALLED_BOOTIMAGE_TARGET),$(call build_boot_board_avb_enabled,$(b)))
@@ -2149,8 +2167,8 @@
$(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_RECOVERY_MKBOOTIMG_ARGS) \
--output $(1).unsigned, \
$(MKBOOTIMG) $(if $(strip $(2)),--kernel $(strip $(2))) $(INTERNAL_RECOVERYIMAGE_ARGS) \
- $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_RECOVERY_MKBOOTIMG_ARGS) \
- --output $(1))
+ $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) \
+ $(BOARD_RECOVERY_MKBOOTIMG_ARGS) --output $(1))
$(if $(filter true,$(PRODUCT_SUPPORTS_BOOT_SIGNER)),\
$(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
$(BOOT_SIGNER) /boot $(1) $(PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCT_VERITY_SIGNING_KEY).x509.pem $(1),\
@@ -2178,6 +2196,9 @@
ifeq (true,$(BOARD_AVB_ENABLE))
recoveryimage-deps += $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH)
endif
+ifdef BOARD_GKI_SIGNING_KEY_PATH
+ recoveryimage-deps += $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
+endif
ifdef BOARD_INCLUDE_RECOVERY_DTBO
ifdef BOARD_PREBUILT_RECOVERY_DTBOIMAGE
recoveryimage-deps += $(BOARD_PREBUILT_RECOVERY_DTBOIMAGE)
@@ -2353,17 +2374,18 @@
# $(1): output file
define build-debug-bootimage-target
$(MKBOOTIMG) --kernel $(PRODUCT_OUT)/$(subst .img,,$(subst boot-debug,kernel,$(notdir $(1)))) \
- $(INTERNAL_DEBUG_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $1
+ $(INTERNAL_DEBUG_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \
+ $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $1
$(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$1,boot-debug))
endef
# Depends on original boot.img and ramdisk-debug.img, to build the new boot-debug.img
-$(INSTALLED_DEBUG_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_BOOTIMAGE_TARGET) $(INSTALLED_DEBUG_RAMDISK_TARGET)
+$(INSTALLED_DEBUG_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_BOOTIMAGE_TARGET) $(INSTALLED_DEBUG_RAMDISK_TARGET) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
$(call pretty,"Target boot debug image: $@")
$(call build-debug-bootimage-target, $@)
.PHONY: bootimage_debug-nodeps
-bootimage_debug-nodeps: $(MKBOOTIMG)
+bootimage_debug-nodeps: $(MKBOOTIMG) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
echo "make $@: ignoring dependencies"
$(foreach b,$(INSTALLED_DEBUG_BOOTIMAGE_TARGET),$(call build-debug-bootimage-target,$b))
@@ -2528,17 +2550,19 @@
# $(1): output file
define build-boot-test-harness-target
$(MKBOOTIMG) --kernel $(PRODUCT_OUT)/$(subst .img,,$(subst boot-test-harness,kernel,$(notdir $(1)))) \
- $(INTERNAL_TEST_HARNESS_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
+ $(INTERNAL_TEST_HARNESS_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \
+ $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
$(if $(BOARD_AVB_BOOT_KEY_PATH),$(call test-key-sign-bootimage,$@,boot-test-harness))
endef
# Build the new boot-test-harness.img, based on boot-debug.img and ramdisk-test-harness.img.
-$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_DEBUG_BOOTIMAGE_TARGET) $(INSTALLED_TEST_HARNESS_RAMDISK_TARGET)
+$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INSTALLED_DEBUG_BOOTIMAGE_TARGET) $(INSTALLED_TEST_HARNESS_RAMDISK_TARGET) \
+$(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
$(call pretty,"Target boot test harness image: $@")
$(call build-boot-test-harness-target,$@)
.PHONY: bootimage_test_harness-nodeps
-bootimage_test_harness-nodeps: $(MKBOOTIMG)
+bootimage_test_harness-nodeps: $(MKBOOTIMG) $(BOARD_GKI_SIGNING_KEY_PATH) $(AVBTOOL)
echo "make $@: ignoring dependencies"
$(foreach b,$(INSTALLED_TEST_HARNESS_BOOTIMAGE_TARGET),$(call build-boot-test-harness-target,$b))
@@ -3883,24 +3907,6 @@
endif # check_vintf_vendor_deps
check_vintf_vendor_deps :=
-# -- Check VINTF compatibility of build.
-# Skip partial builds; only check full builds. Only check if:
-# - PRODUCT_ENFORCE_VINTF_MANIFEST is true
-# - system / vendor VINTF metadata exists
-# - Building product / system_ext / odm images if board has product / system_ext / odm images
-ifeq ($(PRODUCT_ENFORCE_VINTF_MANIFEST),true)
-ifeq ($(check_vintf_has_system),true)
-ifeq ($(check_vintf_has_vendor),true)
-ifeq ($(filter true,$(BUILDING_ODM_IMAGE)),$(filter true,$(BOARD_USES_ODMIMAGE)))
-ifeq ($(filter true,$(BUILDING_PRODUCT_IMAGE)),$(filter true,$(BOARD_USES_PRODUCTIMAGE)))
-ifeq ($(filter true,$(BUILDING_SYSTEM_EXT_IMAGE)),$(filter true,$(BOARD_USES_SYSTEM_EXTIMAGE)))
-
-check_vintf_compatible_log := $(intermediates)/check_vintf_compatible.log
-check_vintf_all_deps += $(check_vintf_compatible_log)
-
-check_vintf_compatible_args :=
-check_vintf_compatible_deps := $(check_vintf_common_srcs)
-
# -- Kernel version and configurations.
ifeq ($(PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS),true)
@@ -3954,9 +3960,29 @@
endif # INSTALLED_KERNEL_TARGET
+endif # PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS
+
+# -- Check VINTF compatibility of build.
+# Skip partial builds; only check full builds. Only check if:
+# - PRODUCT_ENFORCE_VINTF_MANIFEST is true
+# - system / vendor VINTF metadata exists
+# - Building product / system_ext / odm images if board has product / system_ext / odm images
+ifeq ($(PRODUCT_ENFORCE_VINTF_MANIFEST),true)
+ifeq ($(check_vintf_has_system),true)
+ifeq ($(check_vintf_has_vendor),true)
+ifeq ($(filter true,$(BUILDING_ODM_IMAGE)),$(filter true,$(BOARD_USES_ODMIMAGE)))
+ifeq ($(filter true,$(BUILDING_PRODUCT_IMAGE)),$(filter true,$(BOARD_USES_PRODUCTIMAGE)))
+ifeq ($(filter true,$(BUILDING_SYSTEM_EXT_IMAGE)),$(filter true,$(BOARD_USES_SYSTEM_EXTIMAGE)))
+
+check_vintf_compatible_log := $(intermediates)/check_vintf_compatible.log
+check_vintf_all_deps += $(check_vintf_compatible_log)
+
+check_vintf_compatible_args :=
+check_vintf_compatible_deps := $(check_vintf_common_srcs)
+
+ifeq ($(PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS),true)
check_vintf_compatible_args += --kernel $(BUILT_KERNEL_VERSION_FILE):$(BUILT_KERNEL_CONFIGS_FILE)
check_vintf_compatible_deps += $(BUILT_KERNEL_CONFIGS_FILE) $(BUILT_KERNEL_VERSION_FILE)
-
endif # PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS
check_vintf_compatible_args += \
@@ -4324,6 +4350,13 @@
$(hide) echo 'mkbootimg_args=$(BOARD_MKBOOTIMG_ARGS)' >> $@
$(hide) echo 'recovery_mkbootimg_args=$(BOARD_RECOVERY_MKBOOTIMG_ARGS)' >> $@
$(hide) echo 'mkbootimg_version_args=$(INTERNAL_MKBOOTIMG_VERSION_ARGS)' >> $@
+ifdef BOARD_GKI_SIGNING_KEY_PATH
+ $(hide) echo 'gki_signing_key_path=$(BOARD_GKI_SIGNING_KEY_PATH)' >> $@
+ $(hide) echo 'gki_signing_algorithm=$(BOARD_GKI_SIGNING_ALGORITHM)' >> $@
+endif
+ifdef BOARD_GKI_SIGNING_SIGNATURE_ARGS
+ $(hide) echo 'gki_signing_signature_args=$(BOARD_GKI_SIGNING_SIGNATURE_ARGS)' >> $@
+endif
$(hide) echo "multistage_support=1" >> $@
$(hide) echo "blockimgdiff_versions=3,4" >> $@
ifeq ($(PRODUCT_BUILD_GENERIC_OTA_PACKAGE),true)
diff --git a/core/app_prebuilt_internal.mk b/core/app_prebuilt_internal.mk
index 829a640..fe04b84 100644
--- a/core/app_prebuilt_internal.mk
+++ b/core/app_prebuilt_internal.mk
@@ -92,55 +92,6 @@
endif
endif
-# Verify LOCAL_USES_LIBRARIES/LOCAL_OPTIONAL_USES_LIBRARIES
-# If LOCAL_ENFORCE_USES_LIBRARIES is not set, default to true if either of LOCAL_USES_LIBRARIES or
-# LOCAL_OPTIONAL_USES_LIBRARIES are specified.
-# Will change the default to true unconditionally in the future.
-ifndef LOCAL_ENFORCE_USES_LIBRARIES
- ifneq (,$(strip $(LOCAL_USES_LIBRARIES)$(LOCAL_OPTIONAL_USES_LIBRARIES)))
- LOCAL_ENFORCE_USES_LIBRARIES := true
- endif
-endif
-
-# Disable verify_uses_libraries check if dexpreopt is globally disabled.
-# Without dexpreopt the check is not necessary, and although it is good to have,
-# it is difficult to maintain on non-linux build platforms where dexpreopt is
-# generally disabled (the check may fail due to various unrelated reasons, such
-# as a failure to get manifest from an APK).
-ifneq ($(WITH_DEXPREOPT),true)
- LOCAL_ENFORCE_USES_LIBRARIES :=
-endif
-
-my_enforced_uses_libraries :=
-ifdef LOCAL_ENFORCE_USES_LIBRARIES
- my_verify_script := build/soong/scripts/manifest_check.py
- my_uses_libs := $(patsubst %,--uses-library %,$(LOCAL_USES_LIBRARIES))
- my_optional_uses_libs := $(patsubst %,--optional-uses-library %, \
- $(LOCAL_OPTIONAL_USES_LIBRARIES))
- my_relax_check := $(if $(filter true,$(RELAX_USES_LIBRARY_CHECK)), \
- --enforce-uses-libraries-relax,)
- my_enforced_uses_libraries := $(intermediates.COMMON)/enforce_uses_libraries.status
- $(my_enforced_uses_libraries): PRIVATE_USES_LIBRARIES := $(my_uses_libs)
- $(my_enforced_uses_libraries): PRIVATE_OPTIONAL_USES_LIBRARIES := $(my_optional_uses_libs)
- $(my_enforced_uses_libraries): PRIVATE_RELAX_CHECK := $(my_relax_check)
- $(my_enforced_uses_libraries): $(AAPT)
- $(my_enforced_uses_libraries): $(my_verify_script)
- $(my_enforced_uses_libraries): $(my_prebuilt_src_file)
- @echo Verifying uses-libraries: $<
- rm -f $@
- $(my_verify_script) \
- --enforce-uses-libraries \
- --enforce-uses-libraries-status $@ \
- --aapt $(AAPT) \
- $(PRIVATE_USES_LIBRARIES) \
- $(PRIVATE_OPTIONAL_USES_LIBRARIES) \
- $(PRIVATE_RELAX_CHECK) \
- $<
- $(built_module) : $(my_enforced_uses_libraries)
-endif
-
-dex_preopt_profile_src_file := $(my_prebuilt_src_file)
-
rs_compatibility_jni_libs :=
include $(BUILD_SYSTEM)/install_jni_libs.mk
@@ -218,6 +169,8 @@
endif
my_dex_jar := $(my_prebuilt_src_file)
+my_manifest_or_apk := $(my_prebuilt_src_file)
+dex_preopt_profile_src_file := $(my_prebuilt_src_file)
#######################################
# defines built_odex along with rule to install odex
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index cbd3069..560a555 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -1,5 +1,6 @@
# dexpreopt_odex_install.mk is used to define odex creation rules for JARs and APKs
# This file depends on variables set in base_rules.mk
+# Input variables: my_manifest_or_apk
# Output variables: LOCAL_DEX_PREOPT, LOCAL_UNCOMPRESS_DEX
ifeq (true,$(LOCAL_USE_EMBEDDED_DEX))
@@ -30,8 +31,9 @@
LOCAL_DEX_PREOPT :=
endif
-# Only enable preopt for non tests.
+# Disable <uses-library> checks and preopt for tests.
ifneq (,$(filter $(LOCAL_MODULE_TAGS),tests))
+ LOCAL_ENFORCE_USES_LIBRARIES := false
LOCAL_DEX_PREOPT :=
endif
@@ -45,8 +47,14 @@
LOCAL_DEX_PREOPT :=
endif
-# Disable preopt if not WITH_DEXPREOPT
+# Disable <uses-library> checks and preopt if not WITH_DEXPREOPT
+#
+# Without dexpreopt the check is not necessary, and although it is good to have,
+# it is difficult to maintain on non-linux build platforms where dexpreopt is
+# generally disabled (the check may fail due to various unrelated reasons, such
+# as a failure to get manifest from an APK).
ifneq (true,$(WITH_DEXPREOPT))
+ LOCAL_ENFORCE_USES_LIBRARIES := false
LOCAL_DEX_PREOPT :=
endif
@@ -54,7 +62,9 @@
LOCAL_DEX_PREOPT :=
endif
-ifeq (,$(strip $(built_dex)$(my_prebuilt_src_file)$(LOCAL_SOONG_DEX_JAR))) # contains no java code
+# Disable <uses-library> checks and preopt if the app contains no java code.
+ifeq (,$(strip $(built_dex)$(my_prebuilt_src_file)$(LOCAL_SOONG_DEX_JAR)))
+ LOCAL_ENFORCE_USES_LIBRARIES := false
LOCAL_DEX_PREOPT :=
endif
@@ -108,6 +118,137 @@
endif
endif
+################################################################################
+# Local module variables and functions used in dexpreopt and manifest_check.
+################################################################################
+
+my_filtered_optional_uses_libraries := $(filter-out $(INTERNAL_PLATFORM_MISSING_USES_LIBRARIES), \
+ $(LOCAL_OPTIONAL_USES_LIBRARIES))
+
+# TODO(b/132357300): This may filter out too much, as PRODUCT_PACKAGES doesn't
+# include all packages (the full list is unknown until reading all Android.mk
+# makefiles). As a consequence, a library may be present but not included in
+# dexpreopt, which will result in class loader context mismatch and a failure
+# to load dexpreopt code on device. We should fix this, either by deferring
+# dependency computation until the full list of product packages is known, or
+# by adding product-specific lists of missing libraries.
+my_filtered_optional_uses_libraries := $(filter $(PRODUCT_PACKAGES), \
+ $(my_filtered_optional_uses_libraries))
+
+ifeq ($(LOCAL_MODULE_CLASS),APPS)
+ # compatibility libraries are added to class loader context of an app only if
+ # targetSdkVersion in the app's manifest is lower than the given SDK version
+
+ my_dexpreopt_libs_compat_28 := \
+ org.apache.http.legacy
+
+ my_dexpreopt_libs_compat_29 := \
+ android.hidl.manager-V1.0-java \
+ android.hidl.base-V1.0-java
+
+ my_dexpreopt_libs_compat_30 := \
+ android.test.base \
+ android.test.mock
+
+ my_dexpreopt_libs_compat := \
+ $(my_dexpreopt_libs_compat_28) \
+ $(my_dexpreopt_libs_compat_29) \
+ $(my_dexpreopt_libs_compat_30)
+else
+ my_dexpreopt_libs_compat :=
+endif
+
+my_dexpreopt_libs := \
+ $(LOCAL_USES_LIBRARIES) \
+ $(my_filtered_optional_uses_libraries)
+
+# Module dexpreopt.config depends on dexpreopt.config files of each
+# <uses-library> dependency, because these libraries may be processed after
+# the current module by Make (there's no topological order), so the dependency
+# information (paths, class loader context) may not be ready yet by the time
+# this dexpreopt.config is generated. So it's necessary to add file-level
+# dependencies between dexpreopt.config files.
+my_dexpreopt_dep_configs := $(foreach lib, \
+ $(filter-out $(my_dexpreopt_libs_compat),$(LOCAL_USES_LIBRARIES) $(my_filtered_optional_uses_libraries)), \
+ $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,)/dexpreopt.config)
+
+# 1: SDK version
+# 2: list of libraries
+#
+# Make does not process modules in topological order wrt. <uses-library>
+# dependencies, therefore we cannot rely on variables to get the information
+# about dependencies (in particular, their on-device path and class loader
+# context). This information is communicated via dexpreopt.config files: each
+# config depends on configs for <uses-library> dependencies of this module,
+# and the dex_preopt_config_merger.py script reads all configs and inserts the
+# missing bits from dependency configs into the module config.
+#
+# By default on-device path is /system/framework/*.jar, and class loader
+# subcontext is empty. These values are correct for compatibility libraries,
+# which are special and not handled by dex_preopt_config_merger.py.
+#
+add_json_class_loader_context = \
+ $(call add_json_array, $(1)) \
+ $(foreach lib, $(2),\
+ $(call add_json_map_anon) \
+ $(call add_json_str, Name, $(lib)) \
+ $(call add_json_str, Host, $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar) \
+ $(call add_json_str, Device, /system/framework/$(lib).jar) \
+ $(call add_json_val, Subcontexts, null) \
+ $(call end_json_map)) \
+ $(call end_json_array)
+
+################################################################################
+# Verify <uses-library> coherence between the build system and the manifest.
+################################################################################
+
+# Verify LOCAL_USES_LIBRARIES/LOCAL_OPTIONAL_USES_LIBRARIES
+# If LOCAL_ENFORCE_USES_LIBRARIES is not set, default to true if either of LOCAL_USES_LIBRARIES or
+# LOCAL_OPTIONAL_USES_LIBRARIES are specified.
+# Will change the default to true unconditionally in the future.
+ifndef LOCAL_ENFORCE_USES_LIBRARIES
+ ifneq (,$(strip $(LOCAL_USES_LIBRARIES)$(LOCAL_OPTIONAL_USES_LIBRARIES)))
+ LOCAL_ENFORCE_USES_LIBRARIES := true
+ endif
+endif
+
+my_enforced_uses_libraries :=
+ifeq (true,$(LOCAL_ENFORCE_USES_LIBRARIES))
+ my_verify_script := build/soong/scripts/manifest_check.py
+ my_uses_libs_args := $(patsubst %,--uses-library %,$(LOCAL_USES_LIBRARIES))
+ my_optional_uses_libs_args := $(patsubst %,--optional-uses-library %, \
+ $(LOCAL_OPTIONAL_USES_LIBRARIES))
+ my_relax_check_arg := $(if $(filter true,$(RELAX_USES_LIBRARY_CHECK)), \
+ --enforce-uses-libraries-relax,)
+ my_dexpreopt_config_args := $(patsubst %,--dexpreopt-config %,$(my_dexpreopt_dep_configs))
+
+ my_enforced_uses_libraries := $(intermediates.COMMON)/enforce_uses_libraries.status
+ $(my_enforced_uses_libraries): PRIVATE_USES_LIBRARIES := $(my_uses_libs_args)
+ $(my_enforced_uses_libraries): PRIVATE_OPTIONAL_USES_LIBRARIES := $(my_optional_uses_libs_args)
+ $(my_enforced_uses_libraries): PRIVATE_DEXPREOPT_CONFIGS := $(my_dexpreopt_config_args)
+ $(my_enforced_uses_libraries): PRIVATE_RELAX_CHECK := $(my_relax_check_arg)
+ $(my_enforced_uses_libraries): $(AAPT)
+ $(my_enforced_uses_libraries): $(my_verify_script)
+ $(my_enforced_uses_libraries): $(my_dexpreopt_dep_configs)
+ $(my_enforced_uses_libraries): $(my_manifest_or_apk)
+ @echo Verifying uses-libraries: $<
+ rm -f $@
+ $(my_verify_script) \
+ --enforce-uses-libraries \
+ --enforce-uses-libraries-status $@ \
+ --aapt $(AAPT) \
+ $(PRIVATE_USES_LIBRARIES) \
+ $(PRIVATE_OPTIONAL_USES_LIBRARIES) \
+ $(PRIVATE_DEXPREOPT_CONFIGS) \
+ $(PRIVATE_RELAX_CHECK) \
+ $<
+ $(built_module) : $(my_enforced_uses_libraries)
+endif
+
+################################################################################
+# Dexpreopt command.
+################################################################################
+
my_dexpreopt_archs :=
my_dexpreopt_images :=
my_dexpreopt_images_deps :=
@@ -186,72 +327,6 @@
my_dexpreopt_image_locations += $(DEXPREOPT_IMAGE_LOCATIONS_$(my_dexpreopt_infix))
- my_filtered_optional_uses_libraries := $(filter-out $(INTERNAL_PLATFORM_MISSING_USES_LIBRARIES), \
- $(LOCAL_OPTIONAL_USES_LIBRARIES))
-
- # TODO(b/132357300): This may filter out too much, as PRODUCT_PACKAGES doesn't
- # include all packages (the full list is unknown until reading all Android.mk
- # makefiles). As a consequence, a library may be present but not included in
- # dexpreopt, which will result in class loader context mismatch and a failure
- # to load dexpreopt code on device. We should fix this, either by deferring
- # dependency computation until the full list of product packages is known, or
- # by adding product-specific lists of missing libraries.
- my_filtered_optional_uses_libraries := $(filter $(PRODUCT_PACKAGES), \
- $(my_filtered_optional_uses_libraries))
-
- ifeq ($(LOCAL_MODULE_CLASS),APPS)
- # compatibility libraries are added to class loader context of an app only if
- # targetSdkVersion in the app's manifest is lower than the given SDK version
-
- my_dexpreopt_libs_compat_28 := \
- org.apache.http.legacy
-
- my_dexpreopt_libs_compat_29 := \
- android.hidl.base-V1.0-java \
- android.hidl.manager-V1.0-java
-
- my_dexpreopt_libs_compat_30 := \
- android.test.base \
- android.test.mock
-
- my_dexpreopt_libs_compat := \
- $(my_dexpreopt_libs_compat_28) \
- $(my_dexpreopt_libs_compat_29) \
- $(my_dexpreopt_libs_compat_30)
- else
- my_dexpreopt_libs_compat :=
- endif
-
- my_dexpreopt_libs := \
- $(LOCAL_USES_LIBRARIES) \
- $(my_filtered_optional_uses_libraries)
-
- # 1: SDK version
- # 2: list of libraries
- #
- # Make does not process modules in topological order wrt. <uses-library>
- # dependencies, therefore we cannot rely on variables to get the information
- # about dependencies (in particular, their on-device path and class loader
- # context). This information is communicated via dexpreopt.config files: each
- # config depends on configs for <uses-library> dependencies of this module,
- # and the dex_preopt_config_merger.py script reads all configs and inserts the
- # missing bits from dependency configs into the module config.
- #
- # By default on-device path is /system/framework/*.jar, and class loader
- # subcontext is empty. These values are correct for compatibility libraries,
- # which are special and not handled by dex_preopt_config_merger.py.
- #
- add_json_class_loader_context = \
- $(call add_json_array, $(1)) \
- $(foreach lib, $(2),\
- $(call add_json_map_anon) \
- $(call add_json_str, Name, $(lib)) \
- $(call add_json_str, Host, $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar) \
- $(call add_json_str, Device, /system/framework/$(lib).jar) \
- $(call add_json_val, Subcontexts, null) \
- $(call end_json_map)) \
- $(call end_json_array)
-
# Record dex-preopt config.
DEXPREOPT.$(LOCAL_MODULE).DEX_PREOPT := $(LOCAL_DEX_PREOPT)
DEXPREOPT.$(LOCAL_MODULE).MULTILIB := $(LOCAL_MULTILIB)
@@ -278,7 +353,7 @@
$(call add_json_list, PreoptFlags, $(LOCAL_DEX_PREOPT_FLAGS))
$(call add_json_str, ProfileClassListing, $(if $(my_process_profile),$(LOCAL_DEX_PREOPT_PROFILE)))
$(call add_json_bool, ProfileIsTextListing, $(my_profile_is_text_listing))
- $(call add_json_str, EnforceUsesLibrariesStatusFile, $(intermediates.COMMON)/enforce_uses_libraries.status)
+ $(call add_json_str, EnforceUsesLibrariesStatusFile, $(my_enforced_uses_libraries))
$(call add_json_bool, EnforceUsesLibraries, $(LOCAL_ENFORCE_USES_LIBRARIES))
$(call add_json_str, ProvidesUsesLibrary, $(firstword $(LOCAL_PROVIDES_USES_LIBRARY) $(LOCAL_MODULE)))
$(call add_json_map, ClassLoaderContexts)
@@ -304,16 +379,6 @@
my_dexpreopt_zip := $(intermediates)/dexpreopt.zip
my_dexpreopt_config_merger := $(BUILD_SYSTEM)/dex_preopt_config_merger.py
- # Module dexpreopt.config depends on dexpreopt.config files of each
- # <uses-library> dependency, because these libraries may be processed after
- # the current module by Make (there's no topological order), so the dependency
- # information (paths, class loader context) may not be ready yet by the time
- # this dexpreopt.config is generated. So it's necessary to add file-level
- # dependencies between dexpreopt.config files.
- my_dexpreopt_dep_configs := $(foreach lib, \
- $(filter-out $(my_dexpreopt_libs_compat),$(LOCAL_USES_LIBRARIES) $(my_filtered_optional_uses_libraries)), \
- $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,)/dexpreopt.config)
-
$(my_dexpreopt_config): $(my_dexpreopt_dep_configs) $(my_dexpreopt_config_merger)
$(my_dexpreopt_config): PRIVATE_MODULE := $(LOCAL_MODULE)
$(my_dexpreopt_config): PRIVATE_CONTENTS := $(json_contents)
diff --git a/core/java.mk b/core/java.mk
index d28c0c4..3f147ba 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -176,7 +176,9 @@
#######################################
# defines built_odex along with rule to install odex
+my_manifest_or_apk := $(full_android_manifest)
include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
+my_manifest_or_apk :=
#######################################
# Make sure there's something to build.
diff --git a/core/java_prebuilt_internal.mk b/core/java_prebuilt_internal.mk
index 279b0e4..990b7d4 100644
--- a/core/java_prebuilt_internal.mk
+++ b/core/java_prebuilt_internal.mk
@@ -33,6 +33,7 @@
ifeq ($(prebuilt_module_is_dex_javalib),true)
my_dex_jar := $(my_prebuilt_src_file)
+my_manifest_or_apk := $(my_prebuilt_src_file)
# This is a target shared library, i.e. a jar with classes.dex.
$(foreach pair,$(PRODUCT_BOOT_JARS), \
@@ -43,7 +44,9 @@
#######################################
# defines built_odex along with rule to install odex
+my_manifest_or_apk := $(my_prebuilt_src_file)
include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
+my_manifest_or_apk :=
#######################################
$(built_module) : $(my_prebuilt_src_file)
$(call copy-file-to-target)
diff --git a/core/main.mk b/core/main.mk
index e2dde2d..56950ec 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1870,7 +1870,7 @@
ndk: $(SOONG_OUT_DIR)/ndk.timestamp
.PHONY: ndk
-# Checks that build/soong/apex/allowed_deps.txt remains up to date
+# Checks that allowed_deps.txt remains up to date
ifneq ($(UNSAFE_DISABLE_APEX_ALLOWED_DEPS_CHECK),true)
droidcore: ${APEX_ALLOWED_DEPS_CHECK}
endif
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 346ca24..9f5a599 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -472,31 +472,6 @@
# Set a actual_partition_tag (calculated in base_rules.mk) for the package.
PACKAGES.$(LOCAL_PACKAGE_NAME).PARTITION := $(actual_partition_tag)
-# Verify LOCAL_USES_LIBRARIES/LOCAL_OPTIONAL_USES_LIBRARIES
-# If LOCAL_ENFORCE_USES_LIBRARIES is not set, default to true if either of LOCAL_USES_LIBRARIES or
-# LOCAL_OPTIONAL_USES_LIBRARIES are specified.
-# Will change the default to true unconditionally in the future.
-ifndef LOCAL_ENFORCE_USES_LIBRARIES
- ifneq (,$(strip $(LOCAL_USES_LIBRARIES)$(LOCAL_OPTIONAL_USES_LIBRARIES)))
- LOCAL_ENFORCE_USES_LIBRARIES := true
- endif
-endif
-
-my_enforced_uses_libraries :=
-ifdef LOCAL_ENFORCE_USES_LIBRARIES
- my_manifest_check := $(intermediates.COMMON)/manifest/AndroidManifest.xml.check
- $(my_manifest_check): $(MANIFEST_CHECK)
- $(my_manifest_check): PRIVATE_USES_LIBRARIES := $(LOCAL_USES_LIBRARIES)
- $(my_manifest_check): PRIVATE_OPTIONAL_USES_LIBRARIES := $(LOCAL_OPTIONAL_USES_LIBRARIES)
- $(my_manifest_check): $(full_android_manifest)
- @echo Checking manifest: $<
- $(MANIFEST_CHECK) --enforce-uses-libraries \
- $(addprefix --uses-library ,$(PRIVATE_USES_LIBRARIES)) \
- $(addprefix --optional-uses-library ,$(PRIVATE_OPTIONAL_USES_LIBRARIES)) \
- $< -o $@
- $(LOCAL_BUILT_MODULE): $(my_manifest_check)
-endif
-
# Define the rule to build the actual package.
# PRIVATE_JNI_SHARED_LIBRARIES is a list of <abi>:<path_of_built_lib>.
$(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries_with_abis)
diff --git a/core/soong_config.mk b/core/soong_config.mk
index b4992fe..597ea78 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -199,6 +199,8 @@
$(call add_json_list, BoardSepolicyM4Defs, $(BOARD_SEPOLICY_M4DEFS))
$(call add_json_str, BoardSepolicyVers, $(BOARD_SEPOLICY_VERS))
+$(call add_json_str, PlatformSepolicyVersion, $(PLATFORM_SEPOLICY_VERSION))
+
$(call add_json_bool, Flatten_apex, $(filter true,$(TARGET_FLATTEN_APEX)))
$(call add_json_bool, ForceApexSymlinkOptimization, $(filter true,$(TARGET_FORCE_APEX_SYMLINK_OPTIMIZATION)))
diff --git a/target/product/OWNERS b/target/product/OWNERS
index 259c8f4..82e6e88 100644
--- a/target/product/OWNERS
+++ b/target/product/OWNERS
@@ -1 +1,5 @@
per-file runtime_libart.mk = calin@google.com, mast@google.com, ngeoffray@google.com, oth@google.com, rpl@google.com, vmarko@google.com
+
+# GSI
+per-file gsi_release.mk = file:/target/product/gsi/OWNERS
+per-file gsi_keys.mk = file:/target/product/gsi/OWNERS
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 09864bc..c87fb73 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -403,6 +403,6 @@
# This property allows enabling Keystore 2.0 selectively for testing.
# TODO Remove when Keystore 2.0 migration is complete. b/171563717
-PRODUCT_SYSTEM_PROPERTIES += persist.android.security.keystore2.enable=false
+PRODUCT_SYSTEM_PROPERTIES += persist.android.security.keystore2.enable=true
$(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
diff --git a/target/product/gsi/OWNERS b/target/product/gsi/OWNERS
index 3fdd5af..39f97de 100644
--- a/target/product/gsi/OWNERS
+++ b/target/product/gsi/OWNERS
@@ -1,3 +1,6 @@
+bowgotsai@google.com
jiyong@google.com
justinyun@google.com
smoreland@google.com
+szuweilin@google.com
+yochiang@google.com
diff --git a/target/product/gsi_release.mk b/target/product/gsi_release.mk
index 25716ce..539dbfa 100644
--- a/target/product/gsi_release.mk
+++ b/target/product/gsi_release.mk
@@ -59,3 +59,9 @@
# Support additional P, Q and R VNDK packages
PRODUCT_EXTRA_VNDK_VERSIONS := 28 29 30
+
+# Do not build non-GSI partition images.
+PRODUCT_BUILD_CACHE_IMAGE := false
+PRODUCT_BUILD_USERDATA_IMAGE := false
+PRODUCT_BUILD_VENDOR_IMAGE := false
+PRODUCT_BUILD_SUPER_PARTITION := false
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 0061819..414ab97 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1339,6 +1339,35 @@
RunAndCheckOutput(verify_cmd)
+def AppendGkiSigningArgs(cmd):
+ """Append GKI signing arguments for mkbootimg."""
+ # e.g., --gki_signing_key path/to/signing_key
+ # --gki_signing_algorithm SHA256_RSA4096"
+
+ key_path = OPTIONS.info_dict.get("gki_signing_key_path")
+ # It's fine that a non-GKI boot.img has no gki_signing_key_path.
+ if not key_path:
+ return
+
+ if not os.path.exists(key_path) and OPTIONS.search_path:
+ new_key_path = os.path.join(OPTIONS.search_path, key_path)
+ if os.path.exists(new_key_path):
+ key_path = new_key_path
+
+ # Checks key_path exists, before appending --gki_signing_* args.
+ if not os.path.exists(key_path):
+ raise ExternalError('gki_signing_key_path: "{}" not found'.format(key_path))
+
+ algorithm = OPTIONS.info_dict.get("gki_signing_algorithm")
+ if key_path and algorithm:
+ cmd.extend(["--gki_signing_key", key_path,
+ "--gki_signing_algorithm", algorithm])
+
+ signature_args = OPTIONS.info_dict.get("gki_signing_signature_args")
+ if signature_args:
+ cmd.extend(["--gki_signing_signature_args", signature_args])
+
+
def BuildVBMeta(image_path, partitions, name, needed_partitions):
"""Creates a VBMeta image.
@@ -1520,6 +1549,8 @@
if has_ramdisk:
cmd.extend(["--ramdisk", ramdisk_img.name])
+ AppendGkiSigningArgs(cmd)
+
img_unsigned = None
if info_dict.get("vboot"):
img_unsigned = tempfile.NamedTemporaryFile()
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 00acd98..3db5559 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -123,6 +123,17 @@
mounted on the partition (e.g. "--signing_helper /path/to/helper"). The
args will be appended to the existing ones in info dict.
+ --gki_signing_algorithm <algorithm>
+ --gki_signing_key <key>
+ Use the specified algorithm (e.g. SHA256_RSA4096) and the key to generate
+ 'boot signature' in a v4 boot.img. Otherwise it uses the existing values
+ in info dict.
+
+ --gki_signing_extra_args <args>
+ Specify any additional args that are needed to generate 'boot signature'
+ (e.g. --prop foo:bar). The args will be appended to the existing ones
+ in info dict.
+
--android_jar_path <path>
Path to the android.jar to repack the apex file.
"""
@@ -174,6 +185,9 @@
OPTIONS.avb_keys = {}
OPTIONS.avb_algorithms = {}
OPTIONS.avb_extra_args = {}
+OPTIONS.gki_signing_key = None
+OPTIONS.gki_signing_algorithm = None
+OPTIONS.gki_signing_extra_args = None
OPTIONS.android_jar_path = None
@@ -677,6 +691,9 @@
if misc_info.get('avb_enable') == 'true':
RewriteAvbProps(misc_info)
+ # Replace the GKI signing key for boot.img, if any.
+ ReplaceGkiSigningKey(misc_info)
+
# Write back misc_info with the latest values.
ReplaceMiscInfoTxt(input_tf_zip, output_tf_zip, misc_info)
@@ -995,6 +1012,28 @@
misc_info[args_key] = result
+def ReplaceGkiSigningKey(misc_info):
+ """Replaces the GKI signing key."""
+
+ key = OPTIONS.gki_signing_key
+ if not key:
+ return
+
+ algorithm = OPTIONS.gki_signing_algorithm
+ if not algorithm:
+ raise ValueError("Missing --gki_signing_algorithm")
+
+ print('Replacing GKI signing key with "%s" (%s)' % (key, algorithm))
+ misc_info["gki_signing_algorithm"] = algorithm
+ misc_info["gki_signing_key_path"] = key
+
+ extra_args = OPTIONS.gki_signing_extra_args
+ if extra_args:
+ print('Setting extra GKI signing args: "%s"' % (extra_args))
+ misc_info["gki_signing_signature_args"] = (
+ misc_info.get("gki_signing_signature_args", '') + ' ' + extra_args)
+
+
def BuildKeyMap(misc_info, key_mapping_options):
for s, d in key_mapping_options:
if s is None: # -d option
@@ -1226,6 +1265,12 @@
# 'oem=--signing_helper_with_files=/tmp/avbsigner.sh'.
partition, extra_args = a.split("=", 1)
OPTIONS.avb_extra_args[partition] = extra_args
+ elif o == "--gki_signing_key":
+ OPTIONS.gki_signing_key = a
+ elif o == "--gki_signing_algorithm":
+ OPTIONS.gki_signing_algorithm = a
+ elif o == "--gki_signing_extra_args":
+ OPTIONS.gki_signing_extra_args = a
else:
return False
return True
@@ -1273,6 +1318,9 @@
"avb_extra_custom_image_key=",
"avb_extra_custom_image_algorithm=",
"avb_extra_custom_image_extra_args=",
+ "gki_signing_key=",
+ "gki_signing_algorithm=",
+ "gki_signing_extra_args=",
],
extra_option_handler=option_handler)
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index ecd759c..a516366 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -1670,6 +1670,127 @@
common.OPTIONS.aftl_key_path]
common.RunAndCheckOutput(verify_cmd)
+ @test_utils.SkipIfExternalToolsUnavailable()
+ def test_AppendGkiSigningArgs_NoSigningKeyPath(self):
+ # A non-GKI boot.img has no gki_signing_key_path.
+ common.OPTIONS.info_dict = {
+ # 'gki_signing_key_path': pubkey,
+ 'gki_signing_algorithm': 'SHA256_RSA4096',
+ 'gki_signing_signature_args': '--prop foo:bar',
+ }
+
+ # Tests no --gki_signing_* args are appended if there is no
+ # gki_signing_key_path.
+ cmd = ['mkbootimg', '--header_version', '4']
+ expected_cmd = ['mkbootimg', '--header_version', '4']
+ common.AppendGkiSigningArgs(cmd)
+ self.assertEqual(cmd, expected_cmd)
+
+ def test_AppendGkiSigningArgs_NoSigningAlgorithm(self):
+ pubkey = os.path.join(self.testdata_dir, 'testkey_gki.pem')
+ with open(pubkey, 'wb') as f:
+ f.write(b'\x00' * 100)
+ self.assertTrue(os.path.exists(pubkey))
+
+ # Tests no --gki_signing_* args are appended if there is no
+ # gki_signing_algorithm.
+ common.OPTIONS.info_dict = {
+ 'gki_signing_key_path': pubkey,
+ # 'gki_signing_algorithm': 'SHA256_RSA4096',
+ 'gki_signing_signature_args': '--prop foo:bar',
+ }
+
+ cmd = ['mkbootimg', '--header_version', '4']
+ expected_cmd = ['mkbootimg', '--header_version', '4']
+ common.AppendGkiSigningArgs(cmd)
+ self.assertEqual(cmd, expected_cmd)
+
+ @test_utils.SkipIfExternalToolsUnavailable()
+ def test_AppendGkiSigningArgs(self):
+ pubkey = os.path.join(self.testdata_dir, 'testkey_gki.pem')
+ with open(pubkey, 'wb') as f:
+ f.write(b'\x00' * 100)
+ self.assertTrue(os.path.exists(pubkey))
+
+ common.OPTIONS.info_dict = {
+ 'gki_signing_key_path': pubkey,
+ 'gki_signing_algorithm': 'SHA256_RSA4096',
+ 'gki_signing_signature_args': '--prop foo:bar',
+ }
+ cmd = ['mkbootimg', '--header_version', '4']
+ common.AppendGkiSigningArgs(cmd)
+
+ expected_cmd = [
+ 'mkbootimg', '--header_version', '4',
+ '--gki_signing_key', pubkey,
+ '--gki_signing_algorithm', 'SHA256_RSA4096',
+ '--gki_signing_signature_args', '--prop foo:bar'
+ ]
+ self.assertEqual(cmd, expected_cmd)
+
+ @test_utils.SkipIfExternalToolsUnavailable()
+ def test_AppendGkiSigningArgs_KeyPathNotFound(self):
+ pubkey = os.path.join(self.testdata_dir, 'no_testkey_gki.pem')
+ self.assertFalse(os.path.exists(pubkey))
+
+ common.OPTIONS.info_dict = {
+ 'gki_signing_key_path': pubkey,
+ 'gki_signing_algorithm': 'SHA256_RSA4096',
+ 'gki_signing_signature_args': '--prop foo:bar',
+ }
+ cmd = ['mkbootimg', '--header_version', '4']
+ self.assertRaises(common.ExternalError, common.AppendGkiSigningArgs, cmd)
+
+ @test_utils.SkipIfExternalToolsUnavailable()
+ def test_AppendGkiSigningArgs_SearchKeyPath(self):
+ pubkey = 'testkey_gki.pem'
+ self.assertFalse(os.path.exists(pubkey))
+
+ # Tests it should replace the pubkey with an existed key under
+ # OPTIONS.search_path, i.e., os.path.join(OPTIONS.search_path, pubkey).
+ search_path_dir = common.MakeTempDir()
+ search_pubkey = os.path.join(search_path_dir, pubkey)
+ with open(search_pubkey, 'wb') as f:
+ f.write(b'\x00' * 100)
+ self.assertTrue(os.path.exists(search_pubkey))
+
+ common.OPTIONS.search_path = search_path_dir
+ common.OPTIONS.info_dict = {
+ 'gki_signing_key_path': pubkey,
+ 'gki_signing_algorithm': 'SHA256_RSA4096',
+ 'gki_signing_signature_args': '--prop foo:bar',
+ }
+ cmd = ['mkbootimg', '--header_version', '4']
+ common.AppendGkiSigningArgs(cmd)
+
+ expected_cmd = [
+ 'mkbootimg', '--header_version', '4',
+ '--gki_signing_key', search_pubkey,
+ '--gki_signing_algorithm', 'SHA256_RSA4096',
+ '--gki_signing_signature_args', '--prop foo:bar'
+ ]
+ self.assertEqual(cmd, expected_cmd)
+
+ @test_utils.SkipIfExternalToolsUnavailable()
+ def test_AppendGkiSigningArgs_SearchKeyPathNotFound(self):
+ pubkey = 'no_testkey_gki.pem'
+ self.assertFalse(os.path.exists(pubkey))
+
+ # Tests it should raise ExternalError if no key found under
+ # OPTIONS.search_path.
+ search_path_dir = common.MakeTempDir()
+ search_pubkey = os.path.join(search_path_dir, pubkey)
+ self.assertFalse(os.path.exists(search_pubkey))
+
+ common.OPTIONS.search_path = search_path_dir
+ common.OPTIONS.info_dict = {
+ 'gki_signing_key_path': pubkey,
+ 'gki_signing_algorithm': 'SHA256_RSA4096',
+ 'gki_signing_signature_args': '--prop foo:bar',
+ }
+ cmd = ['mkbootimg', '--header_version', '4']
+ self.assertRaises(common.ExternalError, common.AppendGkiSigningArgs, cmd)
+
class InstallRecoveryScriptFormatTest(test_utils.ReleaseToolsTestCase):
"""Checks the format of install-recovery.sh.
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index 18e4858..64e27a2 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -23,8 +23,8 @@
import test_utils
from sign_target_files_apks import (
CheckApkAndApexKeysAvailable, EditTags, GetApkFileInfo, ReadApexKeysInfo,
- ReplaceCerts, ReplaceVerityKeyId, RewriteAvbProps, RewriteProps,
- WriteOtacerts)
+ ReplaceCerts, ReplaceGkiSigningKey, ReplaceVerityKeyId, RewriteAvbProps,
+ RewriteProps, WriteOtacerts)
class SignTargetFilesApksTest(test_utils.ReleaseToolsTestCase):
@@ -588,3 +588,52 @@
'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
'build/make/target/product/security/testkey'),
}, keys_info)
+
+ def test_ReplaceGkiSigningKey(self):
+ common.OPTIONS.gki_signing_key = 'release_gki_key'
+ common.OPTIONS.gki_signing_algorithm = 'release_gki_algorithm'
+ common.OPTIONS.gki_signing_extra_args = 'release_gki_signature_extra_args'
+
+ misc_info = {
+ 'gki_signing_key_path': 'default_gki_key',
+ 'gki_signing_algorithm': 'default_gki_algorithm',
+ 'gki_signing_signature_args': 'default_gki_signature_args',
+ }
+ expected_dict = {
+ 'gki_signing_key_path': 'release_gki_key',
+ 'gki_signing_algorithm': 'release_gki_algorithm',
+ 'gki_signing_signature_args': 'default_gki_signature_args release_gki_signature_extra_args',
+ }
+ ReplaceGkiSigningKey(misc_info)
+ self.assertDictEqual(expected_dict, misc_info)
+
+ def test_ReplaceGkiSigningKey_MissingSigningAlgorithm(self):
+ common.OPTIONS.gki_signing_key = 'release_gki_key'
+ common.OPTIONS.gki_signing_algorithm = None
+ common.OPTIONS.gki_signing_extra_args = 'release_gki_signature_extra_args'
+
+ misc_info = {
+ 'gki_signing_key_path': 'default_gki_key',
+ 'gki_signing_algorithm': 'default_gki_algorithm',
+ 'gki_signing_signature_args': 'default_gki_signature_args',
+ }
+ self.assertRaises(ValueError, ReplaceGkiSigningKey, misc_info)
+
+ def test_ReplaceGkiSigningKey_MissingSigningKeyNop(self):
+ common.OPTIONS.gki_signing_key = None
+ common.OPTIONS.gki_signing_algorithm = 'release_gki_algorithm'
+ common.OPTIONS.gki_signing_extra_args = 'release_gki_signature_extra_args'
+
+ # No change to misc_info if common.OPTIONS.gki_signing_key is missing.
+ misc_info = {
+ 'gki_signing_key_path': 'default_gki_key',
+ 'gki_signing_algorithm': 'default_gki_algorithm',
+ 'gki_signing_signature_args': 'default_gki_signature_args',
+ }
+ expected_dict = {
+ 'gki_signing_key_path': 'default_gki_key',
+ 'gki_signing_algorithm': 'default_gki_algorithm',
+ 'gki_signing_signature_args': 'default_gki_signature_args',
+ }
+ ReplaceGkiSigningKey(misc_info)
+ self.assertDictEqual(expected_dict, misc_info)