Merge "releasetools: RangeSet.monotonic is not an optional attribute."
diff --git a/core/Makefile b/core/Makefile
index c9e64f8..d150ec3 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -406,6 +406,9 @@
$(hide) echo ro.vendor.build.date=`$(DATE_FROM_FILE)`>>$@
$(hide) echo ro.vendor.build.date.utc=`$(DATE_FROM_FILE) +%s`>>$@
$(hide) echo ro.vendor.build.fingerprint="$(BUILD_FINGERPRINT_FROM_FILE)">>$@
+ $(hide) echo ro.vendor.product.cpu.abilist="$(TARGET_CPU_ABI_LIST)">>$@
+ $(hide) echo ro.vendor.product.cpu.abilist32="$(TARGET_CPU_ABI_LIST_32_BIT)">>$@
+ $(hide) echo ro.vendor.product.cpu.abilist64="$(TARGET_CPU_ABI_LIST_64_BIT)">>$@
$(hide) TARGET_DEVICE="$(TARGET_DEVICE)" \
PRODUCT_NAME="$(TARGET_PRODUCT)" \
PRODUCT_BRAND="$(PRODUCT_BRAND)" \
@@ -2374,18 +2377,18 @@
system/extras/verity/build_verity_metadata.py \
system/extras/ext4_utils/mke2fs.conf \
external/avb/test/data/testkey_rsa4096.pem \
- $(shell find system/update_engine/scripts -name \*.pyc -prune -o -type f -print | sort) \
- $(shell find build/target/product/security -type f -name \*.x509.pem -o -name \*.pk8 -o \
- -name verity_key | sort) \
- $(shell find device $(wildcard vendor) -type f -name \*.pk8 -o -name verifiedboot\* -o \
- -name \*.x509.pem -o -name oem\*.prop | sort)
+ $(sort $(shell find system/update_engine/scripts -name \*.pyc -prune -o -type f -print)) \
+ $(sort $(shell find build/target/product/security -type f -name \*.x509.pem -o -name \*.pk8 -o \
+ -name verity_key)) \
+ $(sort $(shell find device $(wildcard vendor) -type f -name \*.pk8 -o -name verifiedboot\* -o \
+ -name \*.x509.pem -o -name oem\*.prop))
OTATOOLS_RELEASETOOLS := \
- $(shell find build/make/tools/releasetools -name \*.pyc -prune -o -type f | sort)
+ $(sort $(shell find build/make/tools/releasetools -name \*.pyc -prune -o -type f))
ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT))
OTATOOLS_DEPS += \
- $(shell find external/vboot_reference/tests/devkeys -type f | sort)
+ $(sort $(shell find external/vboot_reference/tests/devkeys -type f))
endif
$(BUILT_OTATOOLS_PACKAGE): $(OTATOOLS) $(OTATOOLS_DEPS) $(OTATOOLS_RELEASETOOLS) | $(ACP)
diff --git a/core/aux_config.mk b/core/aux_config.mk
index bdae86a..6a5cd63 100644
--- a/core/aux_config.mk
+++ b/core/aux_config.mk
@@ -154,7 +154,7 @@
config_roots := $(wildcard device vendor)
all_configs :=
ifdef config_roots
-all_configs := $(shell find $(config_roots) -maxdepth 4 -name '*$(variant_sfx)' -o -name '*$(os_sfx)' | sort)
+all_configs := $(sort $(shell find $(config_roots) -maxdepth 4 -name '*$(variant_sfx)' -o -name '*$(os_sfx)'))
endif
all_os_configs := $(filter %$(os_sfx),$(all_configs))
all_variant_configs := $(filter %$(variant_sfx),$(all_configs))
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 3ff3bd3..bbcf202 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -654,6 +654,9 @@
ALL_MODULES.$(my_register_name).TARGET_REQUIRED := \
$(strip $(ALL_MODULES.$(my_register_name).TARGET_REQUIRED)\
$(LOCAL_TARGET_REQUIRED_MODULES))
+ALL_MODULES.$(my_register_name).HOST_REQUIRED := \
+ $(strip $(ALL_MODULES.$(my_register_name).HOST_REQUIRED)\
+ $(LOCAL_HOST_REQUIRED_MODULES))
ALL_MODULES.$(my_register_name).EVENT_LOG_TAGS := \
$(ALL_MODULES.$(my_register_name).EVENT_LOG_TAGS) $(event_log_tags)
ALL_MODULES.$(my_register_name).MAKEFILE := \
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 0f700da..c3694ab2 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -98,6 +98,7 @@
LOCAL_GTEST:=true
LOCAL_HAL_STATIC_LIBRARIES:=
LOCAL_HEADER_LIBRARIES:=
+LOCAL_HOST_REQUIRED_MODULES:=
LOCAL_INIT_RC:=
LOCAL_INSTALLED_MODULE:=
LOCAL_INSTALLED_MODULE_STEM:=
diff --git a/core/config.mk b/core/config.mk
index 497c420..e9b5d4c 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -840,6 +840,37 @@
BUILD_NUMBER_FROM_FILE := $$(cat $(OUT_DIR)/build_number.txt)
BUILD_DATETIME_FROM_FILE := $$(cat $(OUT_DIR)/build_date.txt)
+# SEPolicy versions
+
+# PLATFORM_SEPOLICY_VERSION is a number of the form "NN.m" with "NN" mapping to
+# PLATFORM_SDK_VERSION and "m" as a minor number which allows for SELinux
+# changes independent of PLATFORM_SDK_VERSION. This value will be set to
+# 10000.0 to represent tip-of-tree development that is inherently unstable and
+# thus designed not to work with any shipping vendor policy. This is similar in
+# spirit to how DEFAULT_APP_TARGET_SDK is set.
+# The minor version ('m' component) must be updated every time a platform release
+# is made which breaks compatibility with the previous platform sepolicy version,
+# not just on every increase in PLATFORM_SDK_VERSION. The minor version should
+# be reset to 0 on every bump of the PLATFORM_SDK_VERSION.
+sepolicy_major_vers := 27
+sepolicy_minor_vers := 0
+
+ifneq ($(sepolicy_major_vers), $(PLATFORM_SDK_VERSION))
+$(error sepolicy_major_version does not match PLATFORM_SDK_VERSION, please update.)
+endif
+ifneq (REL,$(PLATFORM_VERSION_CODENAME))
+ sepolicy_major_vers := 10000
+ sepolicy_minor_vers := 0
+endif
+PLATFORM_SEPOLICY_VERSION := $(join $(addsuffix .,$(sepolicy_major_vers)), $(sepolicy_minor_vers))
+sepolicy_major_vers :=
+sepolicy_minor_vers :=
+
+# A list of SEPolicy versions, besides PLATFORM_SEPOLICY_VERSION, that the framework supports.
+PLATFORM_SEPOLICY_COMPAT_VERSIONS := \
+ 26.0 \
+ 27.0
+
# ###############################################################
# Set up final options.
# ###############################################################
@@ -922,8 +953,8 @@
$(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/android_system.jar)))) \
$(TARGET_AVAILABLE_SDK_VERSIONS)
-# We don't have prebuilt test_current SDK yet.
-TARGET_AVAILABLE_SDK_VERSIONS := test_current $(TARGET_AVAILABLE_SDK_VERSIONS)
+# We don't have prebuilt test_current and core_current SDK yet.
+TARGET_AVAILABLE_SDK_VERSIONS := test_current core_current $(TARGET_AVAILABLE_SDK_VERSIONS)
TARGET_SDK_VERSIONS_WITHOUT_JAVA_18_SUPPORT := $(call numbers_less_than,24,$(TARGET_AVAILABLE_SDK_VERSIONS))
TARGET_SDK_VERSIONS_WITHOUT_JAVA_19_SUPPORT := $(call numbers_less_than,27,$(TARGET_AVAILABLE_SDK_VERSIONS))
diff --git a/core/dpi_specific_apk.mk b/core/dpi_specific_apk.mk
index e29cde7..f32daf5 100644
--- a/core/dpi_specific_apk.mk
+++ b/core/dpi_specific_apk.mk
@@ -18,7 +18,7 @@
$(built_dpi_apk): PRIVATE_ASSET_DIR := $(LOCAL_ASSET_DIR)
$(built_dpi_apk): PRIVATE_AAPT_INCLUDES := $(all_library_res_package_exports)
$(built_dpi_apk): PRIVATE_RESOURCE_LIST := $(all_res_assets)
-ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
+ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
$(built_dpi_apk): PRIVATE_DEFAULT_APP_TARGET_SDK := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
else
$(built_dpi_apk): PRIVATE_DEFAULT_APP_TARGET_SDK := $(DEFAULT_APP_TARGET_SDK)
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index 176a01d..25b591c 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -71,19 +71,16 @@
else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),test_current)
LOCAL_JAVA_LIBRARIES := android_test_stubs_current $(LOCAL_JAVA_LIBRARIES)
$(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, android_test_stubs_current)
+ else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),core_current)
+ LOCAL_JAVA_LIBRARIES := core.current.stubs $(LOCAL_JAVA_LIBRARIES)
+ $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, core.current.stubs)
else
- ifneq (,$(call has-system-sdk-version,$(LOCAL_SDK_VERSION)))
- ifeq (,$(TARGET_BUILD_APPS))
- LOCAL_JAVA_LIBRARIES := system_sdk_v$(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION)) $(LOCAL_JAVA_LIBRARIES)
- $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, system_sdk_v$(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION)))
- else
- LOCAL_JAVA_LIBRARIES := sdk_v$(LOCAL_SDK_VERSION) $(LOCAL_JAVA_LIBRARIES)
- $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, sdk_v$(LOCAL_SDK_VERSION))
- endif
- else
- LOCAL_JAVA_LIBRARIES := sdk_v$(LOCAL_SDK_VERSION) $(LOCAL_JAVA_LIBRARIES)
- $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, sdk_v$(LOCAL_SDK_VERSION))
- endif
+ # core_<ver> is subset of <ver>. Instead of defining a prebuilt lib for core_<ver>,
+ # use the stub for <ver> when building for apps.
+ _version := $(patsubst core_%,%,$(LOCAL_SDK_VERSION))
+ LOCAL_JAVA_LIBRARIES := sdk_v$(_version) $(LOCAL_JAVA_LIBRARIES)
+ $(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, sdk_v$(_version))
+ _version :=
endif
else
LOCAL_JAVA_LIBRARIES := core-oj core-libart ext framework $(LOCAL_JAVA_LIBRARIES)
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index 1ff9b91..7bae696 100644
--- a/core/host_dalvik_java_library.mk
+++ b/core/host_dalvik_java_library.mk
@@ -193,7 +193,7 @@
endif # !LOCAL_IS_STATIC_JAVA_LIBRARY
-ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
+ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
my_default_app_target_sdk := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
my_sdk_version := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
else
diff --git a/core/java.mk b/core/java.mk
index 6f5dce4..5945fae 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -125,7 +125,7 @@
else
ifneq (,$(LOCAL_SDK_VERSION))
# Set target-api for LOCAL_SDK_VERSIONs other than current.
- ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
+ ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
renderscript_target_api := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
endif
endif # LOCAL_SDK_VERSION is set
@@ -150,7 +150,7 @@
renderscript_flags += $(LOCAL_RENDERSCRIPT_FLAGS)
# prepend the RenderScript system include path
-ifneq ($(filter-out current system_current test_current,$(LOCAL_SDK_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current test_current,$(LOCAL_SDK_VERSION))),)
+ifneq ($(filter-out current system_current test_current core_current,$(LOCAL_SDK_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current test_current,$(LOCAL_SDK_VERSION))),)
# if a numeric LOCAL_SDK_VERSION, or current LOCAL_SDK_VERSION with TARGET_BUILD_APPS
LOCAL_RENDERSCRIPT_INCLUDES := \
$(HISTORICAL_SDK_VERSIONS_ROOT)/renderscript/clang-include \
@@ -266,7 +266,7 @@
aidl_preprocess_import :=
ifdef LOCAL_SDK_VERSION
-ifneq ($(filter current system_current test_current, $(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS)),)
+ifneq ($(filter current system_current test_current core_current, $(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS)),)
# LOCAL_SDK_VERSION is current and no TARGET_BUILD_APPS
aidl_preprocess_import := $(TARGET_OUT_COMMON_INTERMEDIATES)/framework.aidl
else
@@ -610,7 +610,7 @@
my_proguard_sdk_raise :=
ifdef LOCAL_SDK_VERSION
ifdef TARGET_BUILD_APPS
-ifeq (,$(filter current system_current test_current, $(LOCAL_SDK_VERSION)))
+ifeq (,$(filter current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
my_proguard_sdk_raise := $(call java-lib-header-files, sdk_vcurrent)
endif
else
@@ -806,7 +806,7 @@
endif # full_classes_jar is defined
-ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
+ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
my_default_app_target_sdk := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
my_sdk_version := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
else
diff --git a/core/java_common.mk b/core/java_common.mk
index ac8b0d2..3a5c5c6 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -258,17 +258,15 @@
full_java_bootclasspath_libs := $(call java-lib-header-files,android_system_stubs_current)
else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),test_current)
full_java_bootclasspath_libs := $(call java-lib-header-files,android_test_stubs_current)
+ else ifeq ($(LOCAL_SDK_VERSION)$(TARGET_BUILD_APPS),core_current)
+ full_java_bootclasspath_libs := $(call java-lib-header-files,core.current.stubs)
else
- ifneq (,$(call has-system-sdk-version,$(LOCAL_SDK_VERSION)))
- ifeq (,$(TARGET_BUILD_APPS))
- full_java_bootclasspath_libs := $(call java-lib-header-files,system_sdk_v$(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION)))
- else
- full_java_bootclasspath_libs := $(call java-lib-header-files,sdk_v$(LOCAL_SDK_VERSION))
- endif
- else
- full_java_bootclasspath_libs := $(call java-lib-header-files,sdk_v$(LOCAL_SDK_VERSION))
- endif
- endif # current, system_current, system_${VER} or test_current
+ # core_<ver> is subset of <ver>. Instead of defining a prebuilt lib for core_<ver>,
+ # use the stub for <ver> when building for apps.
+ _version := $(patsubst core_%,%,$(LOCAL_SDK_VERSION))
+ full_java_bootclasspath_libs := $(call java-lib-header-files,sdk_v$(_version))
+ _version :=
+ endif # current, system_current, system_${VER}, test_current or core_current
endif # LOCAL_SDK_VERSION
ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
@@ -460,19 +458,23 @@
ifeq ($(LOCAL_SDK_VERSION),system_current)
my_link_type := java:system
my_warn_types := java:platform
-my_allowed_types := java:sdk java:system
+my_allowed_types := java:sdk java:system java:core
else ifneq (,$(call has-system-sdk-version,$(LOCAL_SDK_VERSION)))
my_link_type := java:system
my_warn_types := java:platform
-my_allowed_types := java:sdk java:system
+my_allowed_types := java:sdk java:system java:core
+else ifeq ($(LOCAL_SDK_VERSION),core_current)
+my_link_type := java:core
+my_warn_types :=
+my_allowed_types := java:core
else ifneq ($(LOCAL_SDK_VERSION),)
my_link_type := java:sdk
my_warn_types := java:system java:platform
-my_allowed_types := java:sdk
+my_allowed_types := java:sdk java:core
else
my_link_type := java:platform
my_warn_types :=
-my_allowed_types := java:sdk java:system java:platform
+my_allowed_types := java:sdk java:system java:platform java:core
endif
ifdef LOCAL_AAPT2_ONLY
diff --git a/core/main.mk b/core/main.mk
index 38e9bd1..4d43295 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -610,6 +610,31 @@
endef
$(call add-all-host-to-target-required-modules-deps)
+# Sets up dependencies such that whenever a target module is installed,
+# any host modules listed in $(ALL_MODULES.$(m).HOST_REQUIRED) will also be installed
+define add-all-target-to-host-required-modules-deps
+$(foreach m,$(ALL_MODULES), \
+ $(eval req_mods := $(ALL_MODULES.$(m).HOST_REQUIRED))\
+ $(if $(req_mods), \
+ $(eval req_files := )\
+ $(foreach req_mod,$(req_mods), \
+ $(eval req_file := $(filter $(HOST_OUT)/%, $(call module-installed-files,$(req_mod)))) \
+ $(if $(strip $(req_file)),\
+ ,\
+ $(error $(m).LOCAL_HOST_REQUIRED_MODULES : illegal value $(req_mod) : not a host module. If you want to specify target modules to be required to be installed along with your target module, add those module names to LOCAL_REQUIRED_MODULES instead)\
+ )\
+ $(eval req_files := $(req_files)$(space)$(req_file))\
+ )\
+ $(eval req_files := $(strip $(req_files)))\
+ $(eval mod_files := $(filter $(TARGET_OUT_ROOT)/%, $(call module-installed-files,$(m))))\
+ $(eval mod_files := $(filter-out $(req_files),$(mod_files)))\
+ $(if $(mod_files),\
+ $(eval $(call add-required-deps, $(mod_files),$(req_files))) \
+ )\
+ )\
+)
+endef
+$(call add-all-target-to-host-required-modules-deps)
t_m :=
h_m :=
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 4890966..d7944bb 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -394,7 +394,7 @@
else
ifneq (,$(LOCAL_SDK_VERSION))
# Set target-api for LOCAL_SDK_VERSIONs other than current.
-ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
+ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
renderscript_target_api := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
endif
endif # LOCAL_SDK_VERSION is set
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index ea7fd03..cb1d401 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -546,6 +546,8 @@
my_link_type := java:system
else ifneq (,$(call has-system-sdk-version,$(LOCAL_SDK_VERSION)))
my_link_type := java:system
+else ifeq ($(LOCAL_SDK_VERSION),core_current)
+my_link_type := java:core
else ifneq ($(LOCAL_SDK_VERSION),)
my_link_type := java:sdk
else
diff --git a/core/soong_app_prebuilt.mk b/core/soong_app_prebuilt.mk
index 65aabff..c553c4c 100644
--- a/core/soong_app_prebuilt.mk
+++ b/core/soong_app_prebuilt.mk
@@ -78,15 +78,15 @@
ifeq ($(LOCAL_SDK_VERSION),system_current)
my_link_type := java:system
my_warn_types := java:platform
-my_allowed_types := java:sdk java:system
+my_allowed_types := java:sdk java:system java:core
else ifneq ($(LOCAL_SDK_VERSION),)
my_link_type := java:sdk
my_warn_types := java:system java:platform
-my_allowed_types := java:sdk
+my_allowed_types := java:sdk java:core
else
my_link_type := java:platform
my_warn_types :=
-my_allowed_types := java:sdk java:system java:platform
+my_allowed_types := java:sdk java:system java:platform java:core
endif
my_link_deps :=
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index 5c2d768..f3ed376 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -90,19 +90,23 @@
ifeq ($(LOCAL_SDK_VERSION),system_current)
my_link_type := java:system
my_warn_types := java:platform
-my_allowed_types := java:sdk java:system
+my_allowed_types := java:sdk java:system java:core
else ifneq (,$(call has-system-sdk-version,$(LOCAL_SDK_VERSION)))
my_link_type := java:system
my_warn_types := java:platform
-my_allowed_types := java:sdk java:system
+my_allowed_types := java:sdk java:system java:core
+else ifeq ($(LOCAL_SDK_VERSION),core_current)
+my_link_type := java:core
+my_warn_types :=
+my_allowed_types := java:core
else ifneq ($(LOCAL_SDK_VERSION),)
my_link_type := java:sdk
my_warn_types := java:system java:platform
-my_allowed_types := java:sdk
+my_allowed_types := java:sdk java:core
else
my_link_type := java:platform
my_warn_types :=
-my_allowed_types := java:sdk java:system java:platform
+my_allowed_types := java:sdk java:system java:platform java:core
endif
my_link_deps :=
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index aa1f0fa..c1478f1 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -156,7 +156,7 @@
else
ifneq (,$(LOCAL_SDK_VERSION))
# Set target-api for LOCAL_SDK_VERSIONs other than current.
-ifneq (,$(filter-out current system_current test_current, $(LOCAL_SDK_VERSION)))
+ifneq (,$(filter-out current system_current test_current core_current, $(LOCAL_SDK_VERSION)))
renderscript_target_api := $(call get-numeric-sdk-version,$(LOCAL_SDK_VERSION))
endif
endif # LOCAL_SDK_VERSION is set
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 12b01c4..cd497b2 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -92,6 +92,24 @@
first, so that any changes made to the system partition are done
using the new recovery (new kernel, etc.).
+ --include_secondary
+ Additionally include the payload for secondary slot images (default:
+ False). Only meaningful when generating A/B OTAs.
+
+ By default, an A/B OTA package doesn't contain the images for the
+ secondary slot (e.g. system_other.img). Specifying this flag allows
+ generating a separate payload that will install secondary slot images.
+
+ Such a package needs to be applied in a two-stage manner, with a reboot
+ in-between. During the first stage, the updater applies the primary
+ payload only. Upon finishing, it reboots the device into the newly updated
+ slot. It then continues to install the secondary payload to the inactive
+ slot, but without switching the active slot at the end (needs the matching
+ support in update_engine, i.e. SWITCH_SLOT_ON_REBOOT flag).
+
+ Due to the special install procedure, the secondary payload will be always
+ generated as a full payload.
+
--block
Generate a block-based OTA for non-A/B device. We have deprecated the
support for file-based OTA since O. Block-based OTA will be used by
@@ -159,6 +177,7 @@
if OPTIONS.worker_threads == 0:
OPTIONS.worker_threads = 1
OPTIONS.two_step = False
+OPTIONS.include_secondary = False
OPTIONS.no_signing = False
OPTIONS.block_based = True
OPTIONS.updater_binary = None
@@ -364,6 +383,8 @@
PAYLOAD_BIN = 'payload.bin'
PAYLOAD_PROPERTIES_TXT = 'payload_properties.txt'
+ SECONDARY_PAYLOAD_BIN = 'secondary/payload.bin'
+ SECONDARY_PAYLOAD_PROPERTIES_TXT = 'secondary/payload_properties.txt'
def __init__(self):
# The place where the output from the subprocess should go.
@@ -456,22 +477,31 @@
self.payload_file = signed_payload_file
self.payload_properties = properties_file
- def WriteToZip(self, output_zip):
+ def WriteToZip(self, output_zip, secondary=False):
"""Writes the payload to the given zip.
Args:
output_zip: The output ZipFile instance.
+ secondary: Whether the payload should be packed as secondary payload
+ (default: False).
"""
assert self.payload_file is not None
assert self.payload_properties is not None
+ if secondary:
+ payload_arcname = Payload.SECONDARY_PAYLOAD_BIN
+ payload_properties_arcname = Payload.SECONDARY_PAYLOAD_PROPERTIES_TXT
+ else:
+ payload_arcname = Payload.PAYLOAD_BIN
+ payload_properties_arcname = Payload.PAYLOAD_PROPERTIES_TXT
+
# Add the signed payload file and properties into the zip. In order to
# support streaming, we pack them as ZIP_STORED. So these entries can be
# read directly with the offset and length pairs.
- common.ZipWrite(output_zip, self.payload_file, arcname=Payload.PAYLOAD_BIN,
+ common.ZipWrite(output_zip, self.payload_file, arcname=payload_arcname,
compress_type=zipfile.ZIP_STORED)
common.ZipWrite(output_zip, self.payload_properties,
- arcname=Payload.PAYLOAD_PROPERTIES_TXT,
+ arcname=payload_properties_arcname,
compress_type=zipfile.ZIP_STORED)
@@ -1162,6 +1192,47 @@
WriteMetadata(metadata, output_zip)
+def GetTargetFilesZipForSecondaryImages(input_file):
+ """Returns a target-files.zip file for generating secondary payload.
+
+ Although the original target-files.zip already contains secondary slot
+ images (i.e. IMAGES/system_other.img), we need to rename the files to the
+ ones without _other suffix. Note that we cannot instead modify the names in
+ META/ab_partitions.txt, because there are no matching partitions on device.
+
+ For the partitions that don't have secondary images, the ones for primary
+ slot will be used. This is to ensure that we always have valid boot, vbmeta,
+ bootloader images in the inactive slot.
+
+ Args:
+ input_file: The input target-files.zip file.
+
+ Returns:
+ The filename of the target-files.zip for generating secondary payload.
+ """
+ target_file = common.MakeTempFile(prefix="targetfiles-", suffix=".zip")
+ target_zip = zipfile.ZipFile(target_file, 'w', allowZip64=True)
+
+ input_tmp, input_zip = common.UnzipTemp(input_file, UNZIP_PATTERN)
+ for info in input_zip.infolist():
+ unzipped_file = os.path.join(input_tmp, *info.filename.split('/'))
+ if info.filename == 'IMAGES/system_other.img':
+ common.ZipWrite(target_zip, unzipped_file, arcname='IMAGES/system.img')
+
+ # Primary images and friends need to be skipped explicitly.
+ elif info.filename in ('IMAGES/system.img',
+ 'IMAGES/system.map'):
+ pass
+
+ elif info.filename.startswith(('META/', 'IMAGES/')):
+ common.ZipWrite(target_zip, unzipped_file, arcname=info.filename)
+
+ common.ZipClose(input_zip)
+ common.ZipClose(target_zip)
+
+ return target_file
+
+
def WriteABOTAPackageWithBrilloScript(target_file, output_file,
source_file=None):
"""Generate an Android OTA package that has A/B update payload."""
@@ -1236,11 +1307,23 @@
payload.Generate(target_file, source_file)
# Sign the payload.
- payload.Sign(PayloadSigner())
+ payload_signer = PayloadSigner()
+ payload.Sign(payload_signer)
# Write the payload into output zip.
payload.WriteToZip(output_zip)
+ # Generate and include the secondary payload that installs secondary images
+ # (e.g. system_other.img).
+ if OPTIONS.include_secondary:
+ # We always include a full payload for the secondary slot, even when
+ # building an incremental OTA. See the comments for "--include_secondary".
+ secondary_target_file = GetTargetFilesZipForSecondaryImages(target_file)
+ secondary_payload = Payload()
+ secondary_payload.Generate(secondary_target_file)
+ secondary_payload.Sign(payload_signer)
+ secondary_payload.WriteToZip(output_zip, secondary=True)
+
# If dm-verity is supported for the device, copy contents of care_map
# into A/B OTA package.
target_zip = zipfile.ZipFile(target_file, "r")
@@ -1339,6 +1422,8 @@
"integers are allowed." % (a, o))
elif o in ("-2", "--two_step"):
OPTIONS.two_step = True
+ elif o == "--include_secondary":
+ OPTIONS.include_secondary = True
elif o == "--no_signing":
OPTIONS.no_signing = True
elif o == "--verify":
@@ -1378,6 +1463,7 @@
"extra_script=",
"worker_threads=",
"two_step",
+ "include_secondary",
"no_signing",
"block",
"binary=",
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index 849ca1d..6edf80c 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -23,10 +23,38 @@
import common
import test_utils
from ota_from_target_files import (
- _LoadOemDicts, BuildInfo, GetPackageMetadata, Payload, PayloadSigner,
+ _LoadOemDicts, BuildInfo, GetPackageMetadata,
+ GetTargetFilesZipForSecondaryImages, Payload, PayloadSigner,
WriteFingerprintAssertion)
+def construct_target_files(secondary=False):
+ """Returns a target-files.zip file for generating OTA packages."""
+ target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
+ with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+ # META/update_engine_config.txt
+ target_files_zip.writestr(
+ 'META/update_engine_config.txt',
+ "PAYLOAD_MAJOR_VERSION=2\nPAYLOAD_MINOR_VERSION=4\n")
+
+ # META/ab_partitions.txt
+ ab_partitions = ['boot', 'system', 'vendor']
+ target_files_zip.writestr(
+ 'META/ab_partitions.txt',
+ '\n'.join(ab_partitions))
+
+ # Create dummy images for each of them.
+ for partition in ab_partitions:
+ target_files_zip.writestr('IMAGES/' + partition + '.img',
+ os.urandom(len(partition)))
+
+ if secondary:
+ target_files_zip.writestr('IMAGES/system_other.img',
+ os.urandom(len("system_other")))
+
+ return target_files
+
+
class MockScriptWriter(object):
"""A class that mocks edify_generator.EdifyGenerator.
@@ -500,6 +528,21 @@
},
metadata)
+ def test_GetTargetFilesZipForSecondaryImages(self):
+ input_file = construct_target_files(secondary=True)
+ target_file = GetTargetFilesZipForSecondaryImages(input_file)
+
+ with zipfile.ZipFile(target_file) as verify_zip:
+ namelist = verify_zip.namelist()
+
+ self.assertIn('META/ab_partitions.txt', namelist)
+ self.assertIn('IMAGES/boot.img', namelist)
+ self.assertIn('IMAGES/system.img', namelist)
+ self.assertIn('IMAGES/vendor.img', namelist)
+
+ self.assertNotIn('IMAGES/system_other.img', namelist)
+ self.assertNotIn('IMAGES/system.map', namelist)
+
class PayloadSignerTest(unittest.TestCase):
@@ -598,36 +641,16 @@
common.Cleanup()
@staticmethod
- def _construct_target_files():
- target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
- with zipfile.ZipFile(target_files, 'w') as target_files_zip:
- # META/update_engine_config.txt
- target_files_zip.writestr(
- 'META/update_engine_config.txt',
- "PAYLOAD_MAJOR_VERSION=2\nPAYLOAD_MINOR_VERSION=4\n")
-
- # META/ab_partitions.txt
- ab_partitions = ['boot', 'system', 'vendor']
- target_files_zip.writestr(
- 'META/ab_partitions.txt',
- '\n'.join(ab_partitions))
-
- # Create dummy images for each of them.
- for partition in ab_partitions:
- target_files_zip.writestr('IMAGES/' + partition + '.img',
- os.urandom(len(partition)))
-
- return target_files
-
- def _create_payload_full(self):
- target_file = self._construct_target_files()
+ def _create_payload_full(secondary=False):
+ target_file = construct_target_files(secondary)
payload = Payload()
payload.Generate(target_file)
return payload
- def _create_payload_incremental(self):
- target_file = self._construct_target_files()
- source_file = self._construct_target_files()
+ @staticmethod
+ def _create_payload_incremental():
+ target_file = construct_target_files()
+ source_file = construct_target_files()
payload = Payload()
payload.Generate(target_file, source_file)
return payload
@@ -641,8 +664,8 @@
self.assertTrue(os.path.exists(payload.payload_file))
def test_Generate_additionalArgs(self):
- target_file = self._construct_target_files()
- source_file = self._construct_target_files()
+ target_file = construct_target_files()
+ source_file = construct_target_files()
payload = Payload()
# This should work the same as calling payload.Generate(target_file,
# source_file).
@@ -651,7 +674,7 @@
self.assertTrue(os.path.exists(payload.payload_file))
def test_Generate_invalidInput(self):
- target_file = self._construct_target_files()
+ target_file = construct_target_files()
common.ZipDelete(target_file, 'IMAGES/vendor.img')
payload = Payload()
self.assertRaises(AssertionError, payload.Generate, target_file)
@@ -732,3 +755,25 @@
output_file = common.MakeTempFile(suffix='.zip')
with zipfile.ZipFile(output_file, 'w') as output_zip:
self.assertRaises(AssertionError, payload.WriteToZip, output_zip)
+
+ def test_WriteToZip_secondary(self):
+ payload = self._create_payload_full(secondary=True)
+ payload.Sign(PayloadSigner())
+
+ output_file = common.MakeTempFile(suffix='.zip')
+ with zipfile.ZipFile(output_file, 'w') as output_zip:
+ payload.WriteToZip(output_zip, secondary=True)
+
+ with zipfile.ZipFile(output_file) as verify_zip:
+ # First make sure we have the essential entries.
+ namelist = verify_zip.namelist()
+ self.assertIn(Payload.SECONDARY_PAYLOAD_BIN, namelist)
+ self.assertIn(Payload.SECONDARY_PAYLOAD_PROPERTIES_TXT, namelist)
+
+ # Then assert these entries are stored.
+ for entry_info in verify_zip.infolist():
+ if entry_info.filename not in (
+ Payload.SECONDARY_PAYLOAD_BIN,
+ Payload.SECONDARY_PAYLOAD_PROPERTIES_TXT):
+ continue
+ self.assertEqual(zipfile.ZIP_STORED, entry_info.compress_type)