Merge "Fix zsh compatibility issue in build/envsetup.sh"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index ddee654..4e06d80 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -673,6 +673,11 @@
$(call add-clean-step, rm -rf $(HOST_OUT)/fuzz/*)
$(call add-clean-step, rm -rf $(SOONG_OUT_DIR)/host/*/fuzz/*)
+# Change file layout of system_other
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system_other)
+
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/apex)
+
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/core/Makefile b/core/Makefile
index 951761c..c9b478e 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1924,7 +1924,8 @@
ifeq (,$(filter true, $(BOARD_USES_FULL_RECOVERY_IMAGE) $(BOARD_USES_RECOVERY_AS_BOOT) \
$(BOARD_BUILD_SYSTEM_ROOT_IMAGE) $(BOARD_INCLUDE_RECOVERY_DTBO) $(BOARD_INCLUDE_RECOVERY_ACPIO)))
# Named '.dat' so we don't attempt to use imgdiff for patching it.
-RECOVERY_RESOURCE_ZIP := $(TARGET_OUT)/etc/recovery-resource.dat
+RECOVERY_RESOURCE_ZIP := $(TARGET_OUT_VENDOR)/etc/recovery-resource.dat
+ALL_DEFAULT_INSTALLED_MODULES += $(RECOVERY_RESOURCE_ZIP)
else
RECOVERY_RESOURCE_ZIP :=
endif
@@ -2294,8 +2295,7 @@
INTERNAL_SYSTEMIMAGE_FILES := $(sort $(filter $(TARGET_OUT)/%, \
$(ALL_GENERATED_SOURCES) \
$(ALL_DEFAULT_INSTALLED_MODULES) \
- $(PDK_FUSION_SYSIMG_FILES) \
- $(RECOVERY_RESOURCE_ZIP)) \
+ $(PDK_FUSION_SYSIMG_FILES)) \
$(PDK_FUSION_SYMLINK_STAMP))
FULL_SYSTEMIMAGE_DEPS := $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_USERIMAGES_DEPS)
@@ -3893,6 +3893,9 @@
ifeq ($(BOARD_USES_FULL_RECOVERY_IMAGE),true)
$(hide) echo "full_recovery_image=true" >> $@
endif
+ifdef BOARD_USES_VENDORIMAGE
+ $(hide) echo "board_uses_vendorimage=true" >> $@
+endif
ifeq ($(BOARD_AVB_ENABLE),true)
$(hide) echo "avb_enable=true" >> $@
$(hide) echo "avb_vbmeta_key_path=$(BOARD_AVB_KEY_PATH)" >> $@
@@ -4032,6 +4035,18 @@
$(BUILT_TARGET_FILES_PACKAGE): $(TARGET_OUT_OEM)/$(OSRELEASED_DIRECTORY)/product_version
$(BUILT_TARGET_FILES_PACKAGE): $(TARGET_OUT_ETC)/$(OSRELEASED_DIRECTORY)/system_version
endif
+
+ # Not checking in board_config.mk, since AB_OTA_PARTITIONS may be updated in Android.mk (e.g. to
+ # additionally include radio or bootloader partitions).
+ ifeq ($(AB_OTA_PARTITIONS),)
+ $(error AB_OTA_PARTITIONS must be defined when using AB_OTA_UPDATER)
+ endif
+endif
+
+ifneq ($(AB_OTA_PARTITIONS),)
+ ifneq ($(AB_OTA_UPDATER),true)
+ $(error AB_OTA_UPDATER must be true when defining AB_OTA_PARTITIONS)
+ endif
endif
# Run fs_config while creating the target files package
@@ -4299,10 +4314,8 @@
$(zip_root)/META/$(notdir $(PRODUCT_ODM_BASE_FS_PATH))
endif
ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
-ifdef BUILDING_SYSTEM_IMAGE
$(hide) PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH MKBOOTIMG=$(MKBOOTIMG) \
$(MAKE_RECOVERY_PATCH) $(zip_root) $(zip_root)
-endif # BUILDING_SYSTEM_IMAGE
endif
ifeq ($(AB_OTA_UPDATER),true)
@# When using the A/B updater, include the updater config files in the zip.
diff --git a/core/board_config.mk b/core/board_config.mk
index 242012f..3127c19 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -86,6 +86,7 @@
_build_broken_var_list := \
BUILD_BROKEN_DUP_RULES \
+ BUILD_BROKEN_PREBUILT_ELF_FILES \
BUILD_BROKEN_USES_NETWORK \
_build_broken_var_list += \
@@ -583,8 +584,16 @@
# APEXes are by default flattened, i.e. non-updatable.
# It can be unflattened (and updatable) by inheriting from
# updatable_apex.mk
-ifeq (,$(TARGET_FLATTEN_APEX))
-TARGET_FLATTEN_APEX := true
+#
+# APEX flattening can also be forcibly enabled (resp. disabled) by
+# setting OVERRIDE_TARGET_FLATTEN_APEX to true (resp. false), e.g. by
+# setting the OVERRIDE_TARGET_FLATTEN_APEX environment variable.
+ifdef OVERRIDE_TARGET_FLATTEN_APEX
+ TARGET_FLATTEN_APEX := $(OVERRIDE_TARGET_FLATTEN_APEX)
+else
+ ifeq (,$(TARGET_FLATTEN_APEX))
+ TARGET_FLATTEN_APEX := true
+ endif
endif
ifeq (,$(TARGET_BUILD_APPS))
diff --git a/core/check_elf_file.mk b/core/check_elf_file.mk
index 0faaadd..7a5de67 100644
--- a/core/check_elf_file.mk
+++ b/core/check_elf_file.mk
@@ -38,12 +38,18 @@
$<
$(hide) touch $@
-ifneq ($(PRODUCT_CHECK_ELF_FILES)$(CHECK_ELF_FILES),)
ifneq ($(strip $(LOCAL_CHECK_ELF_FILES)),false)
+ifneq ($(strip $(BUILD_BROKEN_PREBUILT_ELF_FILES)),true)
+# TODO(b/141176116): Remove the PRODUCT_CHECK_ELF_FILES condition below and
+# cover `make droid` targets after everything goes well with `make checkbuild`
+# targets.
+ifneq ($(PRODUCT_CHECK_ELF_FILES)$(CHECK_ELF_FILES),)
$(LOCAL_BUILT_MODULE): $(check_elf_files_stamp)
-check-elf-files: $(check_elf_files_stamp)
-endif # LOCAL_CHECK_ELF_FILES
endif # PRODUCT_CHECK_ELF_FILES or CHECK_ELF_FILES
+check-elf-files: $(check_elf_files_stamp)
+endif # BUILD_BROKEN_PREBUILT_ELF_FILES
+endif # LOCAL_CHECK_ELF_FILES
+
endif # SHARED_LIBRARIES, EXECUTABLES, NATIVE_TESTS
endif # !LOCAL_IS_HOST_MODULE
diff --git a/core/cxx_stl_setup.mk b/core/cxx_stl_setup.mk
index 8e4a46c..95b1090 100644
--- a/core/cxx_stl_setup.mk
+++ b/core/cxx_stl_setup.mk
@@ -33,12 +33,6 @@
endif
endif
-# Yes, this is actually what the clang driver does.
-linux_dynamic_gcclibs := -lgcc_s -lgcc -lc -lgcc_s -lgcc
-linux_static_gcclibs := -Wl,--start-group -lgcc -lgcc_eh -lc -Wl,--end-group
-darwin_dynamic_gcclibs := -lc -lSystem
-darwin_static_gcclibs := NO_STATIC_HOST_BINARIES_ON_DARWIN
-
my_link_type := dynamic
ifdef LOCAL_IS_HOST_MODULE
ifneq (,$(BUILD_HOST_static))
@@ -79,8 +73,7 @@
ifdef LOCAL_IS_HOST_MODULE
my_cppflags += -nostdinc++
- my_ldflags += -nodefaultlibs
- my_cxx_ldlibs += $($($(my_prefix)OS)_$(my_link_type)_gcclibs)
+ my_ldflags += -nostdlib++
else
my_static_libraries += libc++demangle
ifeq (arm,$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH))
@@ -99,8 +92,7 @@
else ifeq ($(my_cxx_stl),none)
ifdef LOCAL_IS_HOST_MODULE
my_cppflags += -nostdinc++
- my_ldflags += -nodefaultlibs
- my_cxx_ldlibs += $($($(my_prefix)OS)_$(my_link_type)_gcclibs)
+ my_ldflags += -nostdlib++
endif
else
$(error $(LOCAL_PATH): $(LOCAL_MODULE): $(my_cxx_stl) is not a supported STL.)
diff --git a/core/main.mk b/core/main.mk
index d2cc47b..fa203ca 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -193,17 +193,7 @@
# The pdk (Platform Development Kit) build
include build/make/core/pdk_config.mk
-#
# -----------------------------------------------------------------
-# Enable dynamic linker warnings for userdebug, eng and non-REL builds
-ifneq ($(TARGET_BUILD_VARIANT),user)
- ADDITIONAL_BUILD_PROPERTIES += ro.bionic.ld.warning=1
-else
-# Enable it for user builds as long as they are not final.
-ifneq ($(PLATFORM_VERSION_CODENAME),REL)
- ADDITIONAL_BUILD_PROPERTIES += ro.bionic.ld.warning=1
-endif
-endif
ADDITIONAL_BUILD_PROPERTIES += ro.treble.enabled=${PRODUCT_FULL_TREBLE}
diff --git a/core/soong_cc_prebuilt.mk b/core/soong_cc_prebuilt.mk
index 09eb419..9e3f0d3 100644
--- a/core/soong_cc_prebuilt.mk
+++ b/core/soong_cc_prebuilt.mk
@@ -136,7 +136,7 @@
ifndef LOCAL_IS_HOST_MODULE
ifdef LOCAL_SOONG_UNSTRIPPED_BINARY
- ifneq ($(LOCAL_VNDK_DEPEND_ON_CORE_VARIANT),true)
+ ifneq ($(LOCAL_UNINSTALLABLE_MODULE),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))
diff --git a/envsetup.sh b/envsetup.sh
index 3d5d361..f0c6b9b 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -580,7 +580,7 @@
local i=1
local choice
- for choice in $choices
+ for choice in $(echo $choices)
do
echo " $i. $choice"
i=$(($i+1))
diff --git a/target/board/mainline_arm64/BoardConfig.mk b/target/board/mainline_arm64/BoardConfig.mk
index 70505f4..7cb2609 100644
--- a/target/board/mainline_arm64/BoardConfig.mk
+++ b/target/board/mainline_arm64/BoardConfig.mk
@@ -32,5 +32,11 @@
AB_OTA_UPDATER := true
AB_OTA_PARTITIONS := system
-BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
+
+# Mainline devices support apex
+# TODO: move this to BoardConfigMainlineCommon. Currently, GSI wants flattened
+# apexes, but emulator wants .apex files, preventing this.
+TARGET_FLATTEN_APEX := false
diff --git a/target/board/mainline_x86/BoardConfig.mk b/target/board/mainline_x86/BoardConfig.mk
new file mode 100644
index 0000000..a20d17c
--- /dev/null
+++ b/target/board/mainline_x86/BoardConfig.mk
@@ -0,0 +1,35 @@
+#
+# 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.
+#
+
+TARGET_ARCH := x86
+TARGET_ARCH_VARIANT := x86
+TARGET_CPU_ABI := x86
+
+include build/make/target/board/BoardConfigMainlineCommon.mk
+
+TARGET_NO_KERNEL := true
+
+# Build generic A/B format system-only OTA.
+AB_OTA_UPDATER := true
+AB_OTA_PARTITIONS := system
+
+BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
+
+# Mainline devices support apex
+# TODO: move this to product makefile and use updatable_apex.mk
+TARGET_FLATTEN_APEX := false
diff --git a/target/board/mainline_x86_arm/BoardConfig.mk b/target/board/mainline_x86_arm/BoardConfig.mk
new file mode 100644
index 0000000..6b282c2
--- /dev/null
+++ b/target/board/mainline_x86_arm/BoardConfig.mk
@@ -0,0 +1,40 @@
+#
+# 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.
+#
+
+TARGET_ARCH := x86
+TARGET_ARCH_VARIANT := x86
+TARGET_CPU_ABI := x86
+
+TARGET_NATIVE_BRIDGE_ARCH := arm
+TARGET_NATIVE_BRIDGE_ARCH_VARIANT := armv7-a-neon
+TARGET_NATIVE_BRIDGE_CPU_VARIANT := generic
+TARGET_NATIVE_BRIDGE_ABI := armeabi-v7a armeabi
+
+include build/make/target/board/BoardConfigMainlineCommon.mk
+
+TARGET_NO_KERNEL := true
+
+# Build generic A/B format system-only OTA.
+AB_OTA_UPDATER := true
+AB_OTA_PARTITIONS := system
+
+BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
+
+# Mainline devices support apex
+# TODO: move this to product makefile and use updatable_apex.mk
+TARGET_FLATTEN_APEX := false
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index 174916d..ca4ed2c 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -55,6 +55,8 @@
$(LOCAL_DIR)/gsi_arm64.mk \
$(LOCAL_DIR)/mainline_arm64.mk \
$(LOCAL_DIR)/mainline_system_arm64.mk \
+ $(LOCAL_DIR)/mainline_system_x86.mk \
+ $(LOCAL_DIR)/mainline_system_x86_arm.mk \
$(LOCAL_DIR)/sdk_arm64.mk \
$(LOCAL_DIR)/sdk.mk \
$(LOCAL_DIR)/sdk_phone_arm64.mk \
diff --git a/target/product/aosp_product.mk b/target/product/aosp_product.mk
index 8c87983..aefad82 100644
--- a/target/product/aosp_product.mk
+++ b/target/product/aosp_product.mk
@@ -21,21 +21,6 @@
# Default AOSP sounds
$(call inherit-product-if-exists, frameworks/base/data/sounds/AllAudio.mk)
-# TODO(b/133643923): Clean up the mainline whitelist
-PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST += \
- system/app/messaging/messaging.apk \
- system/app/messaging/oat/% \
- system/app/WAPPushManager/WAPPushManager.apk \
- system/app/WAPPushManager/oat/% \
- system/bin/healthd \
- system/etc/init/healthd.rc \
- system/etc/vintf/manifest/manifest_healthd.xml \
- system/lib/libframesequence.so \
- system/lib/libgiftranscode.so \
- system/lib64/libframesequence.so \
- system/lib64/libgiftranscode.so \
-
-
# Additional settings used in all AOSP builds
PRODUCT_PRODUCT_PROPERTIES += \
ro.config.ringtone=Ring_Synth_04.ogg \
diff --git a/target/product/base_product.mk b/target/product/base_product.mk
index 749d2c2..2ed550c 100644
--- a/target/product/base_product.mk
+++ b/target/product/base_product.mk
@@ -17,7 +17,6 @@
# Base modules and settings for the product partition.
PRODUCT_PACKAGES += \
group_product \
- healthd \
ModuleMetadata \
passwd_product \
product_compatibility_matrix.xml \
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index ec373db..f49218a 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -29,7 +29,6 @@
android.test.mock \
android.test.runner \
apexd \
- applypatch \
appops \
app_process \
appwidget \
@@ -49,6 +48,7 @@
cgroups.json \
charger \
cmd \
+ com.android.apex.cts.shim.v1_prebuilt \
com.android.conscrypt \
com.android.i18n \
com.android.location.provider \
diff --git a/target/product/base_vendor.mk b/target/product/base_vendor.mk
index 9d79e0f..1657e71 100644
--- a/target/product/base_vendor.mk
+++ b/target/product/base_vendor.mk
@@ -75,3 +75,8 @@
# VINTF data for vendor image
PRODUCT_PACKAGES += \
device_compatibility_matrix.xml \
+
+# Packages to update the recovery partition, which will be installed on
+# /vendor. TODO(b/141648565): Don't install these unless they're needed.
+PRODUCT_PACKAGES += \
+ applypatch
diff --git a/target/product/mainline_system.mk b/target/product/mainline_system.mk
index 43bc45f..b8f2838 100644
--- a/target/product/mainline_system.mk
+++ b/target/product/mainline_system.mk
@@ -105,8 +105,7 @@
# Enable dynamic partition size
PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
-PRODUCT_PACKAGES += \
- com.android.apex.cts.shim.v1_prebuilt
+PRODUCT_ENFORCE_RRO_TARGETS := *
PRODUCT_NAME := mainline_system
PRODUCT_BRAND := generic
diff --git a/target/product/mainline_system_x86.mk b/target/product/mainline_system_x86.mk
new file mode 100644
index 0000000..ac33068
--- /dev/null
+++ b/target/product/mainline_system_x86.mk
@@ -0,0 +1,40 @@
+#
+# 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.
+#
+
+#
+# All components inherited here go to system image
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/mainline_system.mk)
+$(call enforce-product-packages-exist,)
+
+# Enable mainline checking
+PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := true
+
+PRODUCT_BUILD_CACHE_IMAGE := false
+PRODUCT_BUILD_ODM_IMAGE := false
+PRODUCT_BUILD_PRODUCT_IMAGE := false
+PRODUCT_BUILD_RAMDISK_IMAGE := false
+PRODUCT_BUILD_SYSTEM_IMAGE := true
+PRODUCT_BUILD_SYSTEM_EXT_IMAGE := false
+PRODUCT_BUILD_SYSTEM_OTHER_IMAGE := false
+PRODUCT_BUILD_USERDATA_IMAGE := false
+PRODUCT_BUILD_VENDOR_IMAGE := false
+
+PRODUCT_NAME := mainline_system_x86
+PRODUCT_DEVICE := mainline_x86
+PRODUCT_BRAND := generic
+PRODUCT_SHIPPING_API_LEVEL := 28
+PRODUCT_RESTRICT_VENDOR_FILES := all
diff --git a/target/product/mainline_system_x86_arm.mk b/target/product/mainline_system_x86_arm.mk
new file mode 100644
index 0000000..0ed86cc
--- /dev/null
+++ b/target/product/mainline_system_x86_arm.mk
@@ -0,0 +1,40 @@
+#
+# 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.
+#
+
+#
+# All components inherited here go to system image
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/mainline_system.mk)
+$(call enforce-product-packages-exist,)
+
+# Enable mainline checking
+PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := true
+
+PRODUCT_BUILD_CACHE_IMAGE := false
+PRODUCT_BUILD_ODM_IMAGE := false
+PRODUCT_BUILD_PRODUCT_IMAGE := false
+PRODUCT_BUILD_RAMDISK_IMAGE := false
+PRODUCT_BUILD_SYSTEM_IMAGE := true
+PRODUCT_BUILD_SYSTEM_EXT_IMAGE := false
+PRODUCT_BUILD_SYSTEM_OTHER_IMAGE := false
+PRODUCT_BUILD_USERDATA_IMAGE := false
+PRODUCT_BUILD_VENDOR_IMAGE := false
+
+PRODUCT_NAME := mainline_system_x86_arm
+PRODUCT_DEVICE := mainline_x86_arm
+PRODUCT_BRAND := generic
+PRODUCT_SHIPPING_API_LEVEL := 28
+PRODUCT_RESTRICT_VENDOR_FILES := all
diff --git a/target/product/updatable_apex.mk b/target/product/updatable_apex.mk
index a9f4baf..bdaf545 100644
--- a/target/product/updatable_apex.mk
+++ b/target/product/updatable_apex.mk
@@ -16,5 +16,7 @@
# Inherit this when the target needs to support updating APEXes
-PRODUCT_PROPERTY_OVERRIDES := ro.apex.updatable=true
-TARGET_FLATTEN_APEX := false
+ifneq ($(OVERRIDE_TARGET_FLATTEN_APEX),true)
+ PRODUCT_PROPERTY_OVERRIDES := ro.apex.updatable=true
+ TARGET_FLATTEN_APEX := false
+endif
diff --git a/tools/releasetools/OWNERS b/tools/releasetools/OWNERS
index 766adb4..a8295d4 100644
--- a/tools/releasetools/OWNERS
+++ b/tools/releasetools/OWNERS
@@ -1,2 +1,3 @@
-tbao@google.com
+nhdo@google.com
xunchang@google.com
+zhaojiac@google.com
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index a5816bc..4ba8643 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -165,9 +165,12 @@
else:
common.ZipWrite(output_zip, output_file, arc_name)
- if (OPTIONS.rebuild_recovery and recovery_img is not None and
- boot_img is not None):
- logger.info("Building new recovery patch")
+ board_uses_vendorimage = OPTIONS.info_dict.get(
+ "board_uses_vendorimage") == "true"
+
+ if (OPTIONS.rebuild_recovery and not board_uses_vendorimage and
+ recovery_img is not None and boot_img is not None):
+ logger.info("Building new recovery patch on system at system/vendor")
common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink, recovery_img,
boot_img, info_dict=OPTIONS.info_dict)
@@ -190,7 +193,7 @@
CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "system_other", img)
-def AddVendor(output_zip):
+def AddVendor(output_zip, recovery_img=None, boot_img=None):
"""Turn the contents of VENDOR into a vendor image and store in it
output_zip."""
@@ -199,6 +202,27 @@
logger.info("vendor.img already exists; no need to rebuild...")
return img.name
+ def output_sink(fn, data):
+ ofile = open(os.path.join(OPTIONS.input_tmp, "VENDOR", fn), "w")
+ ofile.write(data)
+ ofile.close()
+
+ if output_zip:
+ arc_name = "VENDOR/" + 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)
+
+ board_uses_vendorimage = OPTIONS.info_dict.get(
+ "board_uses_vendorimage") == "true"
+
+ if (OPTIONS.rebuild_recovery and board_uses_vendorimage and
+ recovery_img is not None and boot_img is not None):
+ logger.info("Building new recovery patch on vendor")
+ common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink, recovery_img,
+ boot_img, info_dict=OPTIONS.info_dict)
+
block_list = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", "vendor.map")
CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "vendor", img,
block_list=block_list)
@@ -293,11 +317,6 @@
logger.info("creating %s.img...", what)
image_props = build_image.ImagePropFromGlobalDict(info_dict, what)
- fstab = info_dict["fstab"]
- mount_point = "/" + what
- if fstab and mount_point in fstab:
- image_props["fs_type"] = fstab[mount_point].fs_type
-
image_props["timestamp"] = FIXED_FILE_TIMESTAMP
if what == "system":
@@ -382,9 +401,6 @@
else:
user_dir = common.MakeTempDir()
- fstab = OPTIONS.info_dict["fstab"]
- if fstab:
- image_props["fs_type"] = fstab["/data"].fs_type
build_image.BuildImage(user_dir, image_props, img.name)
common.CheckSize(img.name, "userdata.img", OPTIONS.info_dict)
@@ -471,10 +487,6 @@
image_props["timestamp"] = FIXED_FILE_TIMESTAMP
user_dir = common.MakeTempDir()
-
- fstab = OPTIONS.info_dict["fstab"]
- if fstab:
- image_props["fs_type"] = fstab["/cache"].fs_type
build_image.BuildImage(user_dir, image_props, img.name)
common.CheckSize(img.name, "cache.img", OPTIONS.info_dict)
@@ -781,7 +793,8 @@
if has_vendor:
banner("vendor")
- partitions['vendor'] = AddVendor(output_zip)
+ partitions['vendor'] = AddVendor(
+ output_zip, recovery_img=recovery_image, boot_img=boot_image)
if has_product:
banner("product")
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 974d4b0..37c03ab 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -393,37 +393,8 @@
makeint("boot_size")
makeint("fstab_version")
- # We changed recovery.fstab path in Q, from ../RAMDISK/etc/recovery.fstab to
- # ../RAMDISK/system/etc/recovery.fstab. LoadInfoDict() has to handle both
- # cases, since it may load the info_dict from an old build (e.g. when
- # generating incremental OTAs from that build).
- system_root_image = d.get("system_root_image") == "true"
- if d.get("no_recovery") != "true":
- recovery_fstab_path = "RECOVERY/RAMDISK/system/etc/recovery.fstab"
- if isinstance(input_file, zipfile.ZipFile):
- if recovery_fstab_path not in input_file.namelist():
- recovery_fstab_path = "RECOVERY/RAMDISK/etc/recovery.fstab"
- else:
- path = os.path.join(input_file, *recovery_fstab_path.split("/"))
- if not os.path.exists(path):
- recovery_fstab_path = "RECOVERY/RAMDISK/etc/recovery.fstab"
- d["fstab"] = LoadRecoveryFSTab(
- read_helper, d["fstab_version"], recovery_fstab_path, system_root_image)
-
- elif d.get("recovery_as_boot") == "true":
- recovery_fstab_path = "BOOT/RAMDISK/system/etc/recovery.fstab"
- if isinstance(input_file, zipfile.ZipFile):
- if recovery_fstab_path not in input_file.namelist():
- recovery_fstab_path = "BOOT/RAMDISK/etc/recovery.fstab"
- else:
- path = os.path.join(input_file, *recovery_fstab_path.split("/"))
- if not os.path.exists(path):
- recovery_fstab_path = "BOOT/RAMDISK/etc/recovery.fstab"
- d["fstab"] = LoadRecoveryFSTab(
- read_helper, d["fstab_version"], recovery_fstab_path, system_root_image)
-
- else:
- d["fstab"] = None
+ # Load recovery fstab if applicable.
+ d["fstab"] = _FindAndLoadRecoveryFstab(d, input_file, read_helper)
# Tries to load the build props for all partitions with care_map, including
# system and vendor.
@@ -549,6 +520,47 @@
return d
+def _FindAndLoadRecoveryFstab(info_dict, input_file, read_helper):
+ """Finds the path to recovery fstab and loads its contents."""
+ # recovery fstab is only meaningful when installing an update via recovery
+ # (i.e. non-A/B OTA). Skip loading fstab if device used A/B OTA.
+ if info_dict.get('ab_update') == 'true':
+ return None
+
+ # We changed recovery.fstab path in Q, from ../RAMDISK/etc/recovery.fstab to
+ # ../RAMDISK/system/etc/recovery.fstab. This function has to handle both
+ # cases, since it may load the info_dict from an old build (e.g. when
+ # generating incremental OTAs from that build).
+ system_root_image = info_dict.get('system_root_image') == 'true'
+ if info_dict.get('no_recovery') != 'true':
+ recovery_fstab_path = 'RECOVERY/RAMDISK/system/etc/recovery.fstab'
+ if isinstance(input_file, zipfile.ZipFile):
+ if recovery_fstab_path not in input_file.namelist():
+ recovery_fstab_path = 'RECOVERY/RAMDISK/etc/recovery.fstab'
+ else:
+ path = os.path.join(input_file, *recovery_fstab_path.split('/'))
+ if not os.path.exists(path):
+ recovery_fstab_path = 'RECOVERY/RAMDISK/etc/recovery.fstab'
+ return LoadRecoveryFSTab(
+ read_helper, info_dict['fstab_version'], recovery_fstab_path,
+ system_root_image)
+
+ if info_dict.get('recovery_as_boot') == 'true':
+ recovery_fstab_path = 'BOOT/RAMDISK/system/etc/recovery.fstab'
+ if isinstance(input_file, zipfile.ZipFile):
+ if recovery_fstab_path not in input_file.namelist():
+ recovery_fstab_path = 'BOOT/RAMDISK/etc/recovery.fstab'
+ else:
+ path = os.path.join(input_file, *recovery_fstab_path.split('/'))
+ if not os.path.exists(path):
+ recovery_fstab_path = 'BOOT/RAMDISK/etc/recovery.fstab'
+ return LoadRecoveryFSTab(
+ read_helper, info_dict['fstab_version'], recovery_fstab_path,
+ system_root_image)
+
+ return None
+
+
def DumpInfoDict(d):
for k, v in sorted(d.items()):
logger.info("%-25s = (%s) %s", k, type(v).__name__, v)
@@ -629,7 +641,7 @@
cmd.extend(["--salt", avb_salt])
-def GetAvbPartitionArg(partition, image, info_dict = None):
+def GetAvbPartitionArg(partition, image, info_dict=None):
"""Returns the VBMeta arguments for partition.
It sets up the VBMeta argument by including the partition descriptor from the
@@ -2535,13 +2547,25 @@
info_dict = OPTIONS.info_dict
full_recovery_image = info_dict.get("full_recovery_image") == "true"
+ board_uses_vendorimage = info_dict.get("board_uses_vendorimage") == "true"
+
+ if board_uses_vendorimage:
+ # In this case, the output sink is rooted at VENDOR
+ recovery_img_path = "etc/recovery.img"
+ recovery_resource_dat_path = "VENDOR/etc/recovery-resource.dat"
+ sh_dir = "bin"
+ else:
+ # In this case the output sink is rooted at SYSTEM
+ recovery_img_path = "vendor/etc/recovery.img"
+ recovery_resource_dat_path = "SYSTEM/vendor/etc/recovery-resource.dat"
+ sh_dir = "vendor/bin"
if full_recovery_image:
- output_sink("etc/recovery.img", recovery_img.data)
+ output_sink(recovery_img_path, recovery_img.data)
else:
system_root_image = info_dict.get("system_root_image") == "true"
- path = os.path.join(input_dir, "SYSTEM", "etc", "recovery-resource.dat")
+ path = os.path.join(input_dir, recovery_resource_dat_path)
# With system-root-image, boot and recovery images will have mismatching
# entries (only recovery has the ramdisk entry) (Bug: 72731506). Use bsdiff
# to handle such a case.
@@ -2554,7 +2578,7 @@
if os.path.exists(path):
diff_program.append("-b")
diff_program.append(path)
- bonus_args = "--bonus /system/etc/recovery-resource.dat"
+ bonus_args = "--bonus /vendor/etc/recovery-resource.dat"
else:
bonus_args = ""
@@ -2571,10 +2595,16 @@
return
if full_recovery_image:
- sh = """#!/system/bin/sh
+
+ # Note that we use /vendor to refer to the recovery resources. This will
+ # work for a separate vendor partition mounted at /vendor or a
+ # /system/vendor subdirectory on the system partition, for which init will
+ # create a symlink from /vendor to /system/vendor.
+
+ sh = """#!/vendor/bin/sh
if ! applypatch --check %(type)s:%(device)s:%(size)d:%(sha1)s; then
applypatch \\
- --flash /system/etc/recovery.img \\
+ --flash /vendor/etc/recovery.img \\
--target %(type)s:%(device)s:%(size)d:%(sha1)s && \\
log -t recovery "Installing new recovery image: succeeded" || \\
log -t recovery "Installing new recovery image: failed"
@@ -2586,10 +2616,10 @@
'sha1': recovery_img.sha1,
'size': recovery_img.size}
else:
- sh = """#!/system/bin/sh
+ sh = """#!/vendor/bin/sh
if ! applypatch --check %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s; then
applypatch %(bonus_args)s \\
- --patch /system/recovery-from-boot.p \\
+ --patch /vendor/recovery-from-boot.p \\
--source %(boot_type)s:%(boot_device)s:%(boot_size)d:%(boot_sha1)s \\
--target %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s && \\
log -t recovery "Installing new recovery image: succeeded" || \\
@@ -2607,9 +2637,9 @@
'recovery_device': recovery_device,
'bonus_args': bonus_args}
- # The install script location moved from /system/etc to /system/bin
- # in the L release.
- sh_location = "bin/install-recovery.sh"
+ # The install script location moved from /system/etc to /system/bin in the L
+ # release. In the R release it is in VENDOR/bin or SYSTEM/vendor/bin.
+ sh_location = os.path.join(sh_dir, "install-recovery.sh")
logger.info("putting script in %s", sh_location)
diff --git a/tools/releasetools/make_recovery_patch.py b/tools/releasetools/make_recovery_patch.py
index 725b355..1497d69 100644
--- a/tools/releasetools/make_recovery_patch.py
+++ b/tools/releasetools/make_recovery_patch.py
@@ -47,8 +47,17 @@
if not recovery_img or not boot_img:
sys.exit(0)
+ board_uses_vendorimage = OPTIONS.info_dict.get(
+ "board_uses_vendorimage") == "true"
+
+ if board_uses_vendorimage:
+ target_files_dir = "VENDOR"
+ else:
+ target_files_dir = "SYSTEM"
+
def output_sink(fn, data):
- with open(os.path.join(output_dir, "SYSTEM", *fn.split("/")), "wb") as f:
+ with open(os.path.join(output_dir, target_files_dir,
+ *fn.split("/")), "wb") as f:
f.write(data)
common.MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img)
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index ba70986..544f996 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -68,8 +68,7 @@
files package and saves it at this path.
--rebuild_recovery
- Rebuild the recovery patch used by non-A/B devices and write it to the
- system image.
+ Deprecated; does nothing.
--keep-tmp
Keep tempoary files for debugging purposes.
@@ -106,6 +105,7 @@
OPTIONS.output_ota = None
OPTIONS.output_img = None
OPTIONS.output_super_empty = None
+# TODO(b/132730255): Remove this option.
OPTIONS.rebuild_recovery = False
OPTIONS.keep_tmp = False
@@ -372,32 +372,6 @@
write_sorted_data(data=output_ab_partitions, path=output_ab_partitions_txt)
-def append_recovery_to_filesystem_config(output_target_files_temp_dir):
- """Performs special processing for META/filesystem_config.txt.
-
- This function appends recovery information to META/filesystem_config.txt so
- that recovery patch regeneration will succeed.
-
- Args:
- 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. We find filesystem_config.txt here.
- """
-
- filesystem_config_txt = os.path.join(output_target_files_temp_dir, 'META',
- 'filesystem_config.txt')
-
- with open(filesystem_config_txt, 'a') as f:
- # TODO(bpeckham) this data is hard coded. It should be generated
- # programmatically.
- f.write('system/bin/install-recovery.sh 0 0 750 '
- 'selabel=u:object_r:install_recovery_exec:s0 capabilities=0x0\n')
- f.write('system/recovery-from-boot.p 0 0 644 '
- 'selabel=u:object_r:system_file:s0 capabilities=0x0\n')
- f.write('system/etc/recovery.img 0 0 440 '
- 'selabel=u:object_r:install_recovery_exec:s0 capabilities=0x0\n')
-
-
def process_misc_info_txt(framework_target_files_temp_dir,
vendor_target_files_temp_dir,
output_target_files_temp_dir,
@@ -594,7 +568,7 @@
def process_special_cases(framework_target_files_temp_dir,
vendor_target_files_temp_dir,
output_target_files_temp_dir,
- framework_misc_info_keys, rebuild_recovery):
+ framework_misc_info_keys):
"""Performs special-case processing for certain target files items.
Certain files in the output target files package require special-case
@@ -611,8 +585,6 @@
framework_misc_info_keys: A list of keys to obtain from the framework
instance of META/misc_info.txt. The remaining keys from the vendor
instance.
- rebuild_recovery: If true, rebuild the recovery patch used by non-A/B
- devices and write it to the system image.
"""
if 'ab_update' in framework_misc_info_keys:
@@ -621,10 +593,6 @@
vendor_target_files_temp_dir=vendor_target_files_temp_dir,
output_target_files_temp_dir=output_target_files_temp_dir)
- if rebuild_recovery:
- append_recovery_to_filesystem_config(
- output_target_files_temp_dir=output_target_files_temp_dir)
-
copy_file_contexts(
framework_target_files_dir=framework_target_files_temp_dir,
vendor_target_files_dir=vendor_target_files_temp_dir,
@@ -757,8 +725,7 @@
framework_target_files_temp_dir=framework_target_files_temp_dir,
vendor_target_files_temp_dir=vendor_target_files_temp_dir,
output_target_files_temp_dir=output_target_files_temp_dir,
- framework_misc_info_keys=framework_misc_info_keys,
- rebuild_recovery=rebuild_recovery)
+ framework_misc_info_keys=framework_misc_info_keys)
return output_target_files_temp_dir
@@ -779,6 +746,7 @@
add_img_args = ['--verbose']
add_img_args.append('--add_missing')
+ # TODO(b/132730255): Remove this if statement.
if rebuild_recovery:
add_img_args.append('--rebuild_recovery')
add_img_args.append(target_files_dir)
@@ -1016,7 +984,7 @@
OPTIONS.output_img = a
elif o == '--output-super-empty':
OPTIONS.output_super_empty = a
- elif o == '--rebuild_recovery':
+ elif o == '--rebuild_recovery': # TODO(b/132730255): Warn
OPTIONS.rebuild_recovery = True
elif o == '--keep-tmp':
OPTIONS.keep_tmp = True
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index de947f3..3fc3c22 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -731,10 +731,19 @@
script.WriteRawImage("/boot", "recovery.img")
-def HasRecoveryPatch(target_files_zip):
+def HasRecoveryPatch(target_files_zip, info_dict):
+ board_uses_vendorimage = info_dict.get("board_uses_vendorimage") == "true"
+
+ if board_uses_vendorimage:
+ target_files_dir = "VENDOR"
+ else:
+ target_files_dir = "SYSTEM/vendor"
+
+ patch = "%s/recovery-from-boot.p" % target_files_dir
+ img = "%s/etc/recovery.img" %target_files_dir
+
namelist = [name for name in target_files_zip.namelist()]
- return ("SYSTEM/recovery-from-boot.p" in namelist or
- "SYSTEM/etc/recovery.img" in namelist)
+ return (patch in namelist or img in namelist)
def HasPartition(target_files_zip, partition):
@@ -925,7 +934,7 @@
metadata=metadata,
info_dict=OPTIONS.info_dict)
- assert HasRecoveryPatch(input_zip)
+ assert HasRecoveryPatch(input_zip, info_dict=OPTIONS.info_dict)
# Assertions (e.g. downgrade check, device properties check).
ts = target_info.GetBuildProp("ro.build.date.utc")
diff --git a/tools/releasetools/sparse_img.py b/tools/releasetools/sparse_img.py
index 3367896..a249081 100644
--- a/tools/releasetools/sparse_img.py
+++ b/tools/releasetools/sparse_img.py
@@ -249,8 +249,9 @@
with open(fn) as f:
for line in f:
- fn, ranges = line.split(None, 1)
- ranges = rangelib.RangeSet.parse(ranges)
+ fn, ranges_text = line.rstrip().split(None, 1)
+ ranges = rangelib.RangeSet.parse(ranges_text)
+ ranges.extra['text_str'] = ranges_text
if allow_shared_blocks:
# Find the shared blocks that have been claimed by others. If so, tag
@@ -261,9 +262,6 @@
if not non_shared:
continue
- # There shouldn't anything in the extra dict yet.
- assert not ranges.extra, "Non-empty RangeSet.extra"
-
# Put the non-shared RangeSet as the value in the block map, which
# has a copy of the original RangeSet.
non_shared.extra['uses_shared_blocks'] = ranges
diff --git a/tools/releasetools/test_check_target_files_vintf.py b/tools/releasetools/test_check_target_files_vintf.py
index a1328c2..79f9018 100644
--- a/tools/releasetools/test_check_target_files_vintf.py
+++ b/tools/releasetools/test_check_target_files_vintf.py
@@ -78,6 +78,8 @@
for root, _, files in os.walk(test_delta_dir):
rel_root = os.path.relpath(root, test_delta_dir)
for f in files:
+ if not f.endswith('.xml'):
+ continue
output_file = os.path.join(test_dir, rel_root, f)
with open(os.path.join(root, f)) as inp:
write_string_to_file(inp.read(), output_file)
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index ceb023f..cc59cba 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -749,10 +749,12 @@
self.assertNotIn(
'incomplete', sparse_image.file_map['/system/file2'].extra)
- # All other entries should look normal without any tags.
+ # '/system/file1' will only contain one field -- a copy of the input text.
+ self.assertEqual(1, len(sparse_image.file_map['/system/file1'].extra))
+
+ # Meta entries should not have any extra tag.
self.assertFalse(sparse_image.file_map['__COPY'].extra)
self.assertFalse(sparse_image.file_map['__NONZERO-0'].extra)
- self.assertFalse(sparse_image.file_map['/system/file1'].extra)
@test_utils.SkipIfExternalToolsUnavailable()
def test_GetSparseImage_incompleteRanges(self):
@@ -775,7 +777,9 @@
with zipfile.ZipFile(target_files, 'r') as input_zip:
sparse_image = common.GetSparseImage('system', tempdir, input_zip, False)
- self.assertFalse(sparse_image.file_map['/system/file1'].extra)
+ self.assertEqual(
+ '1-5 9-10',
+ sparse_image.file_map['/system/file1'].extra['text_str'])
self.assertTrue(sparse_image.file_map['/system/file2'].extra['incomplete'])
@test_utils.SkipIfExternalToolsUnavailable()
@@ -801,7 +805,9 @@
with zipfile.ZipFile(target_files, 'r') as input_zip:
sparse_image = common.GetSparseImage('system', tempdir, input_zip, False)
- self.assertFalse(sparse_image.file_map['//system/file1'].extra)
+ self.assertEqual(
+ '1-5 9-10',
+ sparse_image.file_map['//system/file1'].extra['text_str'])
self.assertTrue(sparse_image.file_map['//system/file2'].extra['incomplete'])
self.assertTrue(
sparse_image.file_map['/system/app/file3'].extra['incomplete'])
@@ -826,7 +832,9 @@
with zipfile.ZipFile(target_files, 'r') as input_zip:
sparse_image = common.GetSparseImage('system', tempdir, input_zip, False)
- self.assertFalse(sparse_image.file_map['//system/file1'].extra)
+ self.assertEqual(
+ '1-5 9-10',
+ sparse_image.file_map['//system/file1'].extra['text_str'])
self.assertTrue(sparse_image.file_map['//init.rc'].extra['incomplete'])
@test_utils.SkipIfExternalToolsUnavailable()
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index 9825a5e..f7d59da 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -596,7 +596,7 @@
with zipfile.ZipFile(target_file) as verify_zip:
namelist = verify_zip.namelist()
- ab_partitions = verify_zip.read('META/ab_partitions.txt')
+ ab_partitions = verify_zip.read('META/ab_partitions.txt').decode()
self.assertIn('META/ab_partitions.txt', namelist)
self.assertIn('IMAGES/system.img', namelist)
@@ -676,9 +676,9 @@
with zipfile.ZipFile(target_file) as verify_zip:
namelist = verify_zip.namelist()
- updated_misc_info = verify_zip.read('META/misc_info.txt')
+ updated_misc_info = verify_zip.read('META/misc_info.txt').decode()
updated_dynamic_partitions_info = verify_zip.read(
- 'META/dynamic_partitions_info.txt')
+ 'META/dynamic_partitions_info.txt').decode()
self.assertIn('META/ab_partitions.txt', namelist)
self.assertIn('IMAGES/system.img', namelist)
diff --git a/tools/releasetools/test_validate_target_files.py b/tools/releasetools/test_validate_target_files.py
index 9c816eb..6504515 100644
--- a/tools/releasetools/test_validate_target_files.py
+++ b/tools/releasetools/test_validate_target_files.py
@@ -238,14 +238,14 @@
system_root = os.path.join(input_tmp, "SYSTEM")
os.mkdir(system_root)
- # Write the test file that contain multiple blocks of zeros, and these
- # zero blocks will be omitted by kernel. And the test files will occupy one
- # block range each in the final system image.
+ # Write test files that contain multiple blocks of zeros, and these zero
+ # blocks will be omitted by kernel. Each test file will occupy one block in
+ # the final system image.
with open(os.path.join(system_root, 'a'), 'w') as f:
- f.write("aaa")
+ f.write('aaa')
f.write('\0' * 4096 * 3)
with open(os.path.join(system_root, 'b'), 'w') as f:
- f.write("bbb")
+ f.write('bbb')
f.write('\0' * 4096 * 3)
raw_file_map = os.path.join(input_tmp, 'IMAGES', 'raw_system.map')
@@ -254,7 +254,7 @@
# Parse the generated file map and update the block ranges for each file.
file_map_list = {}
image_ranges = RangeSet()
- with open(raw_file_map, 'r') as f:
+ with open(raw_file_map) as f:
for line in f.readlines():
info = line.split()
self.assertEqual(2, len(info))
@@ -265,7 +265,7 @@
mock_shared_block = RangeSet("10-20").subtract(image_ranges).first(1)
with open(os.path.join(input_tmp, 'IMAGES', 'system.map'), 'w') as f:
for key in sorted(file_map_list.keys()):
- line = "{} {}\n".format(
+ line = '{} {}\n'.format(
key, file_map_list[key].union(mock_shared_block))
f.write(line)
@@ -277,9 +277,55 @@
for name in all_entries:
input_zip.write(os.path.join(input_tmp, name), arcname=name)
- input_zip = zipfile.ZipFile(input_file, 'r')
- info_dict = {'extfs_sparse_flag': '-s'}
-
# Expect the validation to pass and both files are skipped due to
# 'incomplete' block range.
- ValidateFileConsistency(input_zip, input_tmp, info_dict)
+ with zipfile.ZipFile(input_file) as input_zip:
+ info_dict = {'extfs_sparse_flag': '-s'}
+ ValidateFileConsistency(input_zip, input_tmp, info_dict)
+
+ @test_utils.SkipIfExternalToolsUnavailable()
+ def test_ValidateFileConsistency_nonMonotonicRanges(self):
+ input_tmp = common.MakeTempDir()
+ os.mkdir(os.path.join(input_tmp, 'IMAGES'))
+ system_image = os.path.join(input_tmp, 'IMAGES', 'system.img')
+ system_root = os.path.join(input_tmp, "SYSTEM")
+ os.mkdir(system_root)
+
+ # Write the test file that contain three blocks of 'a', 'b', 'c'.
+ with open(os.path.join(system_root, 'abc'), 'w') as f:
+ f.write('a' * 4096 + 'b' * 4096 + 'c' * 4096)
+ raw_file_map = os.path.join(input_tmp, 'IMAGES', 'raw_system.map')
+ self._generate_system_image(system_image, system_root, raw_file_map)
+
+ # Parse the generated file map and manipulate the block ranges of 'abc' to
+ # be 'cba'.
+ file_map_list = {}
+ with open(raw_file_map) as f:
+ for line in f.readlines():
+ info = line.split()
+ self.assertEqual(2, len(info))
+ ranges = RangeSet(info[1])
+ self.assertTrue(ranges.monotonic)
+ blocks = reversed(list(ranges.next_item()))
+ file_map_list[info[0]] = ' '.join([str(block) for block in blocks])
+
+ # Update the contents of 'abc' to be 'cba'.
+ with open(os.path.join(system_root, 'abc'), 'w') as f:
+ f.write('c' * 4096 + 'b' * 4096 + 'a' * 4096)
+
+ # Update the system.map.
+ with open(os.path.join(input_tmp, 'IMAGES', 'system.map'), 'w') as f:
+ for key in sorted(file_map_list.keys()):
+ f.write('{} {}\n'.format(key, file_map_list[key]))
+
+ # Get the target zip file.
+ input_file = common.MakeTempFile()
+ all_entries = ['SYSTEM/', 'SYSTEM/abc', 'IMAGES/',
+ 'IMAGES/system.map', 'IMAGES/system.img']
+ with zipfile.ZipFile(input_file, 'w') as input_zip:
+ for name in all_entries:
+ input_zip.write(os.path.join(input_tmp, name), arcname=name)
+
+ with zipfile.ZipFile(input_file) as input_zip:
+ info_dict = {'extfs_sparse_flag': '-s'}
+ ValidateFileConsistency(input_zip, input_tmp, info_dict)
diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py
index c299a48..383ef7b 100755
--- a/tools/releasetools/validate_target_files.py
+++ b/tools/releasetools/validate_target_files.py
@@ -36,20 +36,21 @@
import os.path
import re
import zipfile
+from hashlib import sha1
import common
+import rangelib
def _ReadFile(file_name, unpacked_name, round_up=False):
"""Constructs and returns a File object. Rounds up its size if needed."""
-
assert os.path.exists(unpacked_name)
with open(unpacked_name, 'rb') as f:
file_data = f.read()
file_size = len(file_data)
if round_up:
file_size_rounded_up = common.RoundUpTo4K(file_size)
- file_data += '\0' * (file_size_rounded_up - file_size)
+ file_data += b'\0' * (file_size_rounded_up - file_size)
return common.File(file_name, file_data)
@@ -96,13 +97,15 @@
logging.warning('Skipping %s that has incomplete block list', entry)
continue
- # TODO(b/79951650): Handle files with non-monotonic ranges.
+ # If the file has non-monotonic ranges, read each range in order.
if not file_ranges.monotonic:
- logging.warning(
- 'Skipping %s that has non-monotonic ranges: %s', entry, file_ranges)
- continue
-
- blocks_sha1 = image.RangeSha1(file_ranges)
+ h = sha1()
+ for file_range in file_ranges.extra['text_str'].split(' '):
+ for data in image.ReadRangeSet(rangelib.RangeSet(file_range)):
+ h.update(data)
+ blocks_sha1 = h.hexdigest()
+ else:
+ blocks_sha1 = image.RangeSha1(file_ranges)
# The filename under unpacked directory, such as SYSTEM/bin/sh.
unpacked_name = os.path.join(
@@ -138,7 +141,7 @@
1. full recovery:
...
if ! applypatch --check type:device:size:sha1; then
- applypatch --flash /system/etc/recovery.img \\
+ applypatch --flash /vendor/etc/recovery.img \\
type:device:size:sha1 && \\
...
@@ -146,18 +149,26 @@
...
if ! applypatch --check type:recovery_device:recovery_size:recovery_sha1; then
applypatch [--bonus bonus_args] \\
- --patch /system/recovery-from-boot.p \\
+ --patch /vendor/recovery-from-boot.p \\
--source type:boot_device:boot_size:boot_sha1 \\
--target type:recovery_device:recovery_size:recovery_sha1 && \\
...
- For full recovery, we want to calculate the SHA-1 of /system/etc/recovery.img
+ For full recovery, we want to calculate the SHA-1 of /vendor/etc/recovery.img
and compare it against the one embedded in the script. While for recovery
from boot, we want to check the SHA-1 for both recovery.img and boot.img
under IMAGES/.
"""
- script_path = 'SYSTEM/bin/install-recovery.sh'
+ board_uses_vendorimage = info_dict.get("board_uses_vendorimage") == "true"
+
+ if board_uses_vendorimage:
+ script_path = 'VENDOR/bin/install-recovery.sh'
+ recovery_img = 'VENDOR/etc/recovery.img'
+ else:
+ script_path = 'SYSTEM/vendor/bin/install-recovery.sh'
+ recovery_img = 'SYSTEM/vendor/etc/recovery.img'
+
if not os.path.exists(os.path.join(input_tmp, script_path)):
logging.info('%s does not exist in input_tmp', script_path)
return
@@ -188,7 +199,7 @@
# Validate the SHA-1 of the recovery image.
recovery_sha1 = flash_partition.split(':')[3]
ValidateFileAgainstSha1(
- input_tmp, 'recovery.img', 'SYSTEM/etc/recovery.img', recovery_sha1)
+ input_tmp, 'recovery.img', recovery_img, recovery_sha1)
else:
assert len(lines) == 11, "Invalid line count: {}".format(lines)