Merge "releasetools: Clean up test_sign_target_files_apks.py."
diff --git a/core/Makefile b/core/Makefile
index 0d14c85..d020335 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -123,6 +123,24 @@
endif
# -----------------------------------------------------------------
+# FINAL_VENDOR_DEFAULT_PROPERTIES will be installed in vendor/default.prop if
+# property_overrides_split_enabled is true. Otherwise it will be installed in
+# ROOT/default.prop.
+ifdef BOARD_VNDK_VERSION
+ ifeq ($(BOARD_VNDK_VERSION),current)
+ FINAL_VENDOR_DEFAULT_PROPERTIES := ro.vndk.version=$(PLATFORM_VNDK_VERSION)
+ else
+ FINAL_VENDOR_DEFAULT_PROPERTIES := ro.vndk.version=$(BOARD_VNDK_VERSION)
+ endif
+else
+ FINAL_VENDOR_DEFAULT_PROPERTIES :=
+endif
+FINAL_VENDOR_DEFAULT_PROPERTIES += \
+ $(call collapse-pairs, $(PRODUCT_DEFAULT_PROPERTY_OVERRIDES))
+FINAL_VENDOR_DEFAULT_PROPERTIES := $(call uniq-pairs-by-first-component, \
+ $(FINAL_VENDOR_DEFAULT_PROPERTIES),=)
+
+# -----------------------------------------------------------------
# prop.default
ifdef property_overrides_split_enabled
INSTALLED_DEFAULT_PROP_TARGET := $(TARGET_OUT)/etc/prop.default
@@ -139,7 +157,7 @@
$(call collapse-pairs, $(PRODUCT_SYSTEM_DEFAULT_PROPERTIES))
ifndef property_overrides_split_enabled
FINAL_DEFAULT_PROPERTIES += \
- $(call collapse-pairs, $(PRODUCT_DEFAULT_PROPERTY_OVERRIDES))
+ $(call collapse-pairs, $(FINAL_VENDOR_DEFAULT_PROPERTIES))
endif
FINAL_DEFAULT_PROPERTIES := $(call uniq-pairs-by-first-component, \
$(FINAL_DEFAULT_PROPERTIES),=)
@@ -174,20 +192,6 @@
INSTALLED_VENDOR_DEFAULT_PROP_TARGET := $(TARGET_OUT_VENDOR)/default.prop
ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_VENDOR_DEFAULT_PROP_TARGET)
-ifdef BOARD_VNDK_VERSION
- ifeq ($(BOARD_VNDK_VERSION),current)
- FINAL_VENDOR_DEFAULT_PROPERTIES := ro.vndk.version=$(PLATFORM_VNDK_VERSION)
- else
- FINAL_VENDOR_DEFAULT_PROPERTIES := ro.vndk.version=$(BOARD_VNDK_VERSION)
- endif
-else
- FINAL_VENDOR_DEFAULT_PROPERTIES :=
-endif
-FINAL_VENDOR_DEFAULT_PROPERTIES += \
- $(call collapse-pairs, $(PRODUCT_DEFAULT_PROPERTY_OVERRIDES))
-FINAL_VENDOR_DEFAULT_PROPERTIES := $(call uniq-pairs-by-first-component, \
- $(FINAL_VENDOR_DEFAULT_PROPERTIES),=)
-
$(INSTALLED_VENDOR_DEFAULT_PROP_TARGET): $(INSTALLED_DEFAULT_PROP_TARGET)
@echo Target buildinfo: $@
@mkdir -p $(dir $@)
diff --git a/core/base_rules.mk b/core/base_rules.mk
index bbcf202..ff48930 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -494,6 +494,17 @@
endif
endif
+# For modules tagged as tests but lacking a suite tag, set null-suite as the default.
+# We only support adding a default suite to native tests, native benchmarks, and instrumentation tests.
+# This is because they are the only tests we currently auto-generate test configs for.
+ifneq ($(filter $(my_module_tags),tests),)
+ifndef LOCAL_COMPATIBILITY_SUITE
+ifneq ($(filter NATIVE_TESTS NATIVE_BENCHMARK APPS, $(LOCAL_MODULE_CLASS)),)
+LOCAL_COMPATIBILITY_SUITE := null-suite
+endif
+endif
+endif
+
###########################################################
## Compatibility suite files.
###########################################################
diff --git a/core/binary.mk b/core/binary.mk
index e3da7d2..c2fa27c 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -180,7 +180,6 @@
my_ndk_stl_include_path :=
my_ndk_stl_shared_lib_fullpath :=
my_ndk_stl_static_lib :=
- my_ndk_cpp_std_version :=
my_cpu_variant := $(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)
ifeq (mips32r6,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH_VARIANT))
my_cpu_variant := mips32r6
@@ -220,8 +219,6 @@
endif
my_ldlibs += -ldl
-
- my_ndk_cpp_std_version := c++11
else # LOCAL_NDK_STL_VARIANT must be none
# Do nothing.
endif
@@ -381,11 +378,6 @@
my_cpp_std_version := $(DEFAULT_GCC_CPP_STD_VERSION)
endif
-ifdef LOCAL_SDK_VERSION
- # The NDK handles this itself.
- my_cpp_std_version := $(my_ndk_cpp_std_version)
-endif
-
ifdef LOCAL_IS_HOST_MODULE
ifneq ($(my_clang),true)
# The host GCC doesn't support C++14 (and is deprecated, so likely
@@ -617,6 +609,9 @@
my_cc := $(my_cc_wrapper) $(my_cc)
endif
+SYNTAX_TOOLS_PREFIX := \
+ $(LLVM_PREBUILTS_BASE)/$(BUILD_OS)-x86/$(LLVM_PREBUILTS_VERSION)/libexec
+
ifneq ($(LOCAL_NO_STATIC_ANALYZER),true)
my_cc := CCC_CC=$(CLANG) CLANG=$(CLANG) \
$(SYNTAX_TOOLS_PREFIX)/ccc-analyzer
diff --git a/core/clang/versions.mk b/core/clang/versions.mk
deleted file mode 100644
index 1e41f92..0000000
--- a/core/clang/versions.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-## Clang/LLVM release versions.
-
-LLVM_PREBUILTS_VERSION ?= clang-4579689
-LLVM_PREBUILTS_BASE ?= prebuilts/clang/host
diff --git a/core/config.mk b/core/config.mk
index e9b5d4c..4942be7 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -413,33 +413,11 @@
WITH_STATIC_ANALYZER :=
endif
-# define clang/llvm versions and base directory.
-include $(BUILD_SYSTEM)/clang/versions.mk
-
# Unset WITH_TIDY_ONLY if global WITH_TIDY_ONLY is not true nor 1.
ifeq (,$(filter 1 true,$(WITH_TIDY_ONLY)))
WITH_TIDY_ONLY :=
endif
-PATH_TO_CLANG_TIDY := \
- $(LLVM_PREBUILTS_BASE)/$(BUILD_OS)-x86/$(LLVM_PREBUILTS_VERSION)/bin/clang-tidy
-ifeq ($(wildcard $(PATH_TO_CLANG_TIDY)),)
- ifneq (,$(filter 1 true,$(WITH_TIDY)))
- $(warning *** Disable WITH_TIDY because $(PATH_TO_CLANG_TIDY) does not exist)
- endif
- PATH_TO_CLANG_TIDY :=
-endif
-
-# Disable WITH_STATIC_ANALYZER if tool can't be found
-SYNTAX_TOOLS_PREFIX := \
- $(LLVM_PREBUILTS_BASE)/$(BUILD_OS)-x86/$(LLVM_PREBUILTS_VERSION)/tools/scan-build/libexec
-ifneq ($(strip $(WITH_STATIC_ANALYZER)),)
- ifeq ($(wildcard $(SYNTAX_TOOLS_PREFIX)/ccc-analyzer),)
- $(warning *** Disable WITH_STATIC_ANALYZER because $(SYNTAX_TOOLS_PREFIX)/ccc-analyzer does not exist)
- WITH_STATIC_ANALYZER :=
- endif
-endif
-
# Pick a Java compiler.
include $(BUILD_SYSTEM)/combo/javac.mk
@@ -797,6 +775,14 @@
requirements :=
+# BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED can be true only if early-mount of
+# partitions is supported. But the early-mount must be supported for full
+# treble products, and so BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED should be set
+# by default for full treble products.
+ifeq ($(PRODUCT_FULL_TREBLE),true)
+ BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED ?= true
+endif
+
# If PRODUCT_USE_VNDK is true and BOARD_VNDK_VERSION is not defined yet,
# BOARD_VNDK_VERSION will be set to "current" as default.
# PRODUCT_USE_VNDK will be true in Android-P or later launching devices.
@@ -838,7 +824,7 @@
endif
BUILD_NUMBER_FROM_FILE := $$(cat $(OUT_DIR)/build_number.txt)
-BUILD_DATETIME_FROM_FILE := $$(cat $(OUT_DIR)/build_date.txt)
+BUILD_DATETIME_FROM_FILE := $$(cat $(BUILD_DATETIME_FILE))
# SEPolicy versions
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index 0fa4b8c..f289c22 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -90,8 +90,10 @@
# is converted into to boot.art (to match the legacy assumption that boot.art
# exists), and the rest are converted to boot-<name>.art.
# In addition, each .art file has an associated .oat file.
-LIBART_TARGET_BOOT_ART_EXTRA_FILES := $(foreach jar,$(wordlist 2,999,$(LIBART_TARGET_BOOT_JARS)),boot-$(jar).art boot-$(jar).art.rel boot-$(jar).oat boot-$(jar).vdex)
-LIBART_TARGET_BOOT_ART_EXTRA_FILES += boot.art.rel boot.oat boot.vdex
+LIBART_TARGET_BOOT_ART_EXTRA_FILES := $(foreach jar,$(wordlist 2,999,$(LIBART_TARGET_BOOT_JARS)),boot-$(jar).art boot-$(jar).art.rel boot-$(jar).oat)
+LIBART_TARGET_BOOT_ART_EXTRA_FILES += boot.art.rel boot.oat
+LIBART_TARGET_BOOT_ART_VDEX_FILES := $(foreach jar,$(wordlist 2,999,$(LIBART_TARGET_BOOT_JARS)),boot-$(jar).vdex)
+LIBART_TARGET_BOOT_ART_VDEX_FILES += boot.vdex
# If we use a boot image profile.
my_use_profile_for_boot_image := $(PRODUCT_USE_PROFILE_FOR_BOOT_IMAGE)
@@ -133,6 +135,8 @@
endif
+LIBART_TARGET_BOOT_ART_VDEX_INSTALLED_SHARED_FILES := $(addprefix $(PRODUCT_OUT)/$(DEXPREOPT_BOOT_JAR_DIR)/,$(LIBART_TARGET_BOOT_ART_VDEX_FILES))
+
my_2nd_arch_prefix :=
include $(BUILD_SYSTEM)/dex_preopt_libart_boot.mk
@@ -140,10 +144,24 @@
ifdef TARGET_2ND_ARCH
my_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
include $(BUILD_SYSTEM)/dex_preopt_libart_boot.mk
-my_2nd_arch_prefix :=
endif
endif
+# Copy shared vdex to the directory and create corresponding symlinks in primary and secondary arch.
+$(LIBART_TARGET_BOOT_ART_VDEX_INSTALLED_SHARED_FILES) : PRIMARY_ARCH_DIR := $(dir $(DEFAULT_DEX_PREOPT_INSTALLED_IMAGE))
+$(LIBART_TARGET_BOOT_ART_VDEX_INSTALLED_SHARED_FILES) : SECOND_ARCH_DIR := $(dir $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE))
+$(LIBART_TARGET_BOOT_ART_VDEX_INSTALLED_SHARED_FILES) : $(DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME)
+ @echo "Install: $@"
+ @mkdir -p $(dir $@)
+ @rm -f $@
+ $(hide) cp "$(dir $<)$(notdir $@)" "$@"
+ # Make symlink for both the archs. In the case its single arch the symlink will just get overridden.
+ @mkdir -p $(PRIMARY_ARCH_DIR)
+ $(hide) ln -sf /$(DEXPREOPT_BOOT_JAR_DIR)/$(notdir $@) $(PRIMARY_ARCH_DIR)$(notdir $@)
+ @mkdir -p $(SECOND_ARCH_DIR)
+ $(hide) ln -sf /$(DEXPREOPT_BOOT_JAR_DIR)/$(notdir $@) $(SECOND_ARCH_DIR)$(notdir $@)
+
+my_2nd_arch_prefix :=
########################################################################
# For a single jar or APK
diff --git a/core/dex_preopt_libart_boot.mk b/core/dex_preopt_libart_boot.mk
index ad8f18d..8d0539a 100644
--- a/core/dex_preopt_libart_boot.mk
+++ b/core/dex_preopt_libart_boot.mk
@@ -30,6 +30,8 @@
$(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE := $(PRODUCT_OUT)$($(my_2nd_arch_prefix)LIBART_BOOT_IMAGE_FILENAME)
$(my_2nd_arch_prefix)LIBART_TARGET_BOOT_ART_EXTRA_INSTALLED_FILES := $(addprefix $(dir $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE)),\
$(LIBART_TARGET_BOOT_ART_EXTRA_FILES))
+$(my_2nd_arch_prefix)LIBART_TARGET_BOOT_ART_VDEX_INSTALLED_FILES := $(addprefix $(dir $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE)),\
+ $(LIBART_TARGET_BOOT_ART_VDEX_FILES))
# If we have a compiled-classes file, create a parameter.
COMPILED_CLASSES_FLAGS :=
@@ -45,7 +47,7 @@
# The rule to install boot.art
# Depends on installed boot.oat, boot-*.art, boot-*.oat
-$($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE) : $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) | $(ACP) $($(my_2nd_arch_prefix)LIBART_TARGET_BOOT_ART_EXTRA_INSTALLED_FILES)
+$($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE) : $($(my_2nd_arch_prefix)DEFAULT_DEX_PREOPT_BUILT_IMAGE_FILENAME) | $(ACP) $($(my_2nd_arch_prefix)LIBART_TARGET_BOOT_ART_EXTRA_INSTALLED_FILES) $($(my_2nd_arch_prefix)LIBART_TARGET_BOOT_ART_VDEX_INSTALLED_SHARED_FILES)
@echo "Install: $@"
$(copy-file-to-target)
@@ -104,7 +106,7 @@
$(PRODUCT_DEX_PREOPT_BOOT_FLAGS) $(GLOBAL_DEXPREOPT_FLAGS) $(ART_BOOT_IMAGE_EXTRA_ARGS) && \
ANDROID_ROOT=$(PRODUCT_OUT)/system ANDROID_DATA=$(dir $@) $(PATCHOAT) \
--input-image-location=$(PRIVATE_IMAGE_LOCATION) \
- --output-image-relocation-file=$@.rel \
+ --output-image-relocation-directory=$(dir $@) \
--instruction-set=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH) \
--base-offset-delta=0x10000000
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index e337279..3a943bb 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -224,6 +224,12 @@
my_system_server_compiler_filter := speed
endif
+my_default_compiler_filter := $(PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER)
+ifeq (,$(my_default_compiler_filter))
+# If no default compiler filter is specified, default to 'quicken' to save on storage.
+my_default_compiler_filter := quicken
+endif
+
ifeq (,$(filter --compiler-filter=%, $(LOCAL_DEX_PREOPT_FLAGS)))
ifneq (,$(filter $(PRODUCT_SYSTEM_SERVER_JARS),$(LOCAL_MODULE)))
# Jars of system server, use the product option if it is set, speed otherwise.
@@ -238,8 +244,7 @@
# For non system server jars, use speed-profile when we have a profile.
LOCAL_DEX_PREOPT_FLAGS += --compiler-filter=speed-profile
else
- # If no compiler filter is specified, default to 'quicken' to save on storage.
- LOCAL_DEX_PREOPT_FLAGS += --compiler-filter=quicken
+ LOCAL_DEX_PREOPT_FLAGS += --compiler-filter=$(my_default_compiler_filter)
endif
endif
endif
@@ -260,6 +265,10 @@
endif
endif
+# Set the compiler reason to 'prebuilt' to identify the oat files produced
+# during the build, as opposed to compiled on the device.
+LOCAL_DEX_PREOPT_FLAGS += --compilation-reason=prebuilt
+
$(built_odex): PRIVATE_DEX_PREOPT_FLAGS := $(LOCAL_DEX_PREOPT_FLAGS)
$(built_vdex): $(built_odex)
$(built_art): $(built_odex)
diff --git a/core/droiddoc.mk b/core/droiddoc.mk
index 25b591c..8115481 100644
--- a/core/droiddoc.mk
+++ b/core/droiddoc.mk
@@ -83,7 +83,11 @@
_version :=
endif
else
- LOCAL_JAVA_LIBRARIES := core-oj core-libart ext framework $(LOCAL_JAVA_LIBRARIES)
+ ifeq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
+ LOCAL_JAVA_LIBRARIES := core-oj core-libart
+ else
+ LOCAL_JAVA_LIBRARIES := core-oj core-libart ext framework $(LOCAL_JAVA_LIBRARIES)
+ endif
$(full_target): PRIVATE_BOOTCLASSPATH := $(call java-lib-files, core-oj):$(call java-lib-files, core-libart)
endif # LOCAL_SDK_VERSION
LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index 7bae696..43fc780 100644
--- a/core/host_dalvik_java_library.mk
+++ b/core/host_dalvik_java_library.mk
@@ -134,7 +134,7 @@
$(full_static_java_libs) | $(MERGE_ZIPS)
$(if $(PRIVATE_JAR_MANIFEST), $(hide) sed -e "s/%BUILD_NUMBER%/$(BUILD_NUMBER_FROM_FILE)/" \
$(PRIVATE_JAR_MANIFEST) > $(dir $@)/manifest.mf)
- $(MERGE_ZIPS) -j $(if $(PRIVATE_JAR_MANIFEST),-m $(dir $@)/manifest.mf) \
+ $(MERGE_ZIPS) -j --ignore-duplicates $(if $(PRIVATE_JAR_MANIFEST),-m $(dir $@)/manifest.mf) \
$(if $(PRIVATE_DONT_DELETE_JAR_META_INF),,-stripDir META-INF -zipToNotStrip $<) \
$@ $< $(call reverse-list,$(PRIVATE_STATIC_JAVA_LIBRARIES))
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index f34f2f1..5176f37 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -58,11 +58,6 @@
# Run build/make/tools/java-layers.py for more details.
layers_file := $(addprefix $(LOCAL_PATH)/, $(LOCAL_JAVA_LAYERS_FILE))
-# If error prone is enabled then add LOCAL_ERROR_PRONE_FLAGS to LOCAL_JAVACFLAGS
-ifeq ($(RUN_ERROR_PRONE),true)
-LOCAL_JAVACFLAGS += $(LOCAL_ERROR_PRONE_FLAGS)
-endif
-
# List of dependencies for anything that needs all java sources in place
java_sources_deps := \
$(java_sources) \
@@ -99,7 +94,7 @@
$(full_static_java_libs) | $(MERGE_ZIPS)
$(if $(PRIVATE_JAR_MANIFEST), $(hide) sed -e "s/%BUILD_NUMBER%/$(BUILD_NUMBER_FROM_FILE)/" \
$(PRIVATE_JAR_MANIFEST) > $(dir $@)/manifest.mf)
- $(MERGE_ZIPS) -j $(if $(PRIVATE_JAR_MANIFEST),-m $(dir $@)/manifest.mf) \
+ $(MERGE_ZIPS) -j --ignore-duplicates $(if $(PRIVATE_JAR_MANIFEST),-m $(dir $@)/manifest.mf) \
-stripDir META-INF -zipToNotStrip $< $@ $< $(call reverse-list,$(PRIVATE_STATIC_JAVA_LIBRARIES))
# Run jarjar if necessary, otherwise just copy the file.
diff --git a/core/host_java_library_common.mk b/core/host_java_library_common.mk
index 8df4b37..51e2d94 100644
--- a/core/host_java_library_common.mk
+++ b/core/host_java_library_common.mk
@@ -48,3 +48,8 @@
LOCAL_INTERMEDIATE_SOURCE_DIR := $(intermediates.COMMON)/src
LOCAL_JAVA_LIBRARIES := $(sort $(LOCAL_JAVA_LIBRARIES))
+
+# If error prone is enabled then add LOCAL_ERROR_PRONE_FLAGS to LOCAL_JAVACFLAGS
+ifeq ($(RUN_ERROR_PRONE),true)
+LOCAL_JAVACFLAGS += $(LOCAL_ERROR_PRONE_FLAGS)
+endif
diff --git a/core/java.mk b/core/java.mk
index 5945fae..f92cbca 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -517,7 +517,7 @@
$(full_static_java_libs) | $(MERGE_ZIPS)
$(if $(PRIVATE_JAR_MANIFEST), $(hide) sed -e "s/%BUILD_NUMBER%/$(BUILD_NUMBER_FROM_FILE)/" \
$(PRIVATE_JAR_MANIFEST) > $(dir $@)/manifest.mf)
- $(MERGE_ZIPS) -j $(if $(PRIVATE_JAR_MANIFEST),-m $(dir $@)/manifest.mf) \
+ $(MERGE_ZIPS) -j --ignore-duplicates $(if $(PRIVATE_JAR_MANIFEST),-m $(dir $@)/manifest.mf) \
$(if $(PRIVATE_DONT_DELETE_JAR_META_INF),,-stripDir META-INF -zipToNotStrip $<) \
$@ $< $(call reverse-list,$(PRIVATE_STATIC_JAVA_LIBRARIES))
diff --git a/core/main.mk b/core/main.mk
index 4d43295..0c165ca 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -60,8 +60,7 @@
# without changing the command line every time. Avoids rebuilds
# when using ninja.
$(shell mkdir -p $(OUT_DIR) && \
- echo -n $(BUILD_NUMBER) > $(OUT_DIR)/build_number.txt && \
- echo -n $(BUILD_DATETIME) > $(OUT_DIR)/build_date.txt)
+ echo -n $(BUILD_NUMBER) > $(OUT_DIR)/build_number.txt)
ifeq ($(HOST_OS),darwin)
DATE_FROM_FILE := date -r $(BUILD_DATETIME_FROM_FILE)
else
diff --git a/core/ninja_config.mk b/core/ninja_config.mk
index ca2dcee..2256f98 100644
--- a/core/ninja_config.mk
+++ b/core/ninja_config.mk
@@ -19,9 +19,7 @@
boottarball-nodeps \
brillo_tests \
btnod \
- build-art% \
build_kernel-nodeps \
- clean-oat% \
continuous_instrumentation_tests \
continuous_native_tests \
cts \
@@ -47,11 +45,9 @@
systemimage-nodeps \
systemtarball-nodeps \
target-files-package \
- test-art% \
user \
userdataimage \
userdebug \
- valgrind-test-art% \
vts \
win_sdk \
winsdk-tools
diff --git a/core/package_internal.mk b/core/package_internal.mk
index d7944bb..cd3a741 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -464,15 +464,16 @@
endif # need_compile_res
-ifeq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
-# We need to explicitly clear this var so that we don't
-# inherit the value from whomever caused us to be built.
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_INCLUDES :=
-else
+framework_res_package_export :=
+framework_res_package_export_deps :=
+
+ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
# Most packages should link against the resources defined by framework-res.
# Even if they don't have their own resources, they may use framework
# resources.
-ifneq ($(filter-out current system_current test_current,$(LOCAL_SDK_RES_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current test_current,$(LOCAL_SDK_RES_VERSION))),)
+ifeq ($(LOCAL_SDK_RES_VERSION),core_current)
+# core_current doesn't contain any framework resources.
+else ifneq ($(filter-out current system_current test_current,$(LOCAL_SDK_RES_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current test_current,$(LOCAL_SDK_RES_VERSION))),)
# for released sdk versions, the platform resources were built into android.jar.
framework_res_package_export := \
$(HISTORICAL_SDK_VERSIONS_ROOT)/$(LOCAL_SDK_RES_VERSION)/android.jar
@@ -486,6 +487,8 @@
framework_res_package_export_deps := \
$(dir $(framework_res_package_export))src/R.stamp
endif # LOCAL_SDK_RES_VERSION
+endif # LOCAL_NO_STANDARD_LIBRARIES
+
all_library_res_package_exports := \
$(framework_res_package_export) \
$(foreach lib,$(LOCAL_RES_LIBRARIES),\
@@ -502,7 +505,6 @@
ifdef LOCAL_USE_AAPT2
$(my_res_package) : $(all_library_res_package_export_deps)
endif
-endif # LOCAL_NO_STANDARD_LIBRARIES
ifneq ($(full_classes_jar),)
$(LOCAL_BUILT_MODULE): PRIVATE_DEX_FILE := $(built_dex)
diff --git a/core/product.mk b/core/product.mk
index 8095b27..ce14853 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -129,6 +129,7 @@
PRODUCT_PRODUCT_VERITY_PARTITION \
PRODUCT_SYSTEM_SERVER_DEBUG_INFO \
PRODUCT_DEX_PREOPT_MODULE_CONFIGS \
+ PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER \
PRODUCT_DEX_PREOPT_DEFAULT_FLAGS \
PRODUCT_DEX_PREOPT_BOOT_FLAGS \
PRODUCT_DEX_PREOPT_PROFILE_DIR \
diff --git a/core/product_config.mk b/core/product_config.mk
index bf607bb..0c46541 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -392,6 +392,8 @@
PRODUCT_EXTRA_RECOVERY_KEYS := $(sort \
$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_EXTRA_RECOVERY_KEYS))
+PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER := \
+ $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER))
PRODUCT_DEX_PREOPT_DEFAULT_FLAGS := \
$(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEX_PREOPT_DEFAULT_FLAGS))
PRODUCT_DEX_PREOPT_BOOT_FLAGS := \
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index c1478f1..1dc0e71 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -119,10 +119,17 @@
endif
ifdef LOCAL_USE_AAPT2
-$(intermediates.COMMON)/export_proguard_flags: $(addprefix $(LOCAL_PATH)/,$(LOCAL_EXPORT_PROGUARD_FLAG_FILES))
+import_proguard_flag_files := $(strip $(foreach l,$(LOCAL_STATIC_ANDROID_LIBRARIES),\
+ $(call intermediates-dir-for,JAVA_LIBRARIES,$(l),,COMMON)/export_proguard_flags))
+$(intermediates.COMMON)/export_proguard_flags: $(import_proguard_flag_files) $(addprefix $(LOCAL_PATH)/,$(LOCAL_EXPORT_PROGUARD_FLAG_FILES))
@echo "Export proguard flags: $@"
rm -f $@
- cat $+ >$@
+ touch $@
+ for f in $+; do \
+ echo -e "\n# including $$f" >>$@; \
+ cat $$f >>$@; \
+ done
+import_proguard_flag_files :=
endif
# add --non-constant-id to prevent inlining constants.
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index d70dfb4..858384b 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -24,7 +24,6 @@
# DEFAULT_APP_TARGET_SDK
# BUILD_ID
# BUILD_NUMBER
-# BUILD_DATETIME
# PLATFORM_SECURITY_PATCH
# PLATFORM_VNDK_VERSION
# PLATFORM_SYSTEMSDK_VERSIONS
@@ -267,6 +266,11 @@
DATE := date -d @$(BUILD_DATETIME)
endif
+# Everything should be using BUILD_DATETIME_FROM_FILE instead.
+# BUILD_DATETIME and DATE can be removed once BUILD_NUMBER moves
+# to soong_ui.
+BUILD_DATETIME :=
+
ifndef BUILD_NUMBER
# BUILD_NUMBER should be set to the source control value that
# represents the current state of the source code. E.g., a
diff --git a/envsetup.sh b/envsetup.sh
index 372dffb..cf61950 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -741,33 +741,11 @@
fi
}
-# Return driver for "make", if any (eg. static analyzer)
-function getdriver()
-{
- local T="$1"
- test "$WITH_STATIC_ANALYZER" = "0" && unset WITH_STATIC_ANALYZER
- if [ -n "$WITH_STATIC_ANALYZER" ]; then
- # Use scan-build to collect all static analyzer reports into directory
- # /tmp/scan-build-yyyy-mm-dd-hhmmss-*
- # The clang compiler passed by --use-analyzer here is not important.
- # build/make/core/binary.mk will set CLANG_CXX and CLANG before calling
- # c++-analyzer and ccc-analyzer.
- local CLANG_VERSION=$(get_build_var LLVM_PREBUILTS_VERSION)
- local BUILD_OS=$(get_build_var BUILD_OS)
- local CLANG_DIR="$T/prebuilts/clang/host/${BUILD_OS}-x86/${CLANG_VERSION}"
- echo "\
-${CLANG_DIR}/tools/scan-build/bin/scan-build \
---use-analyzer ${CLANG_DIR}/bin/clang \
---status-bugs"
- fi
-}
-
function m()
{
local T=$(gettop)
- local DRV=$(getdriver $T)
if [ "$T" ]; then
- _wrap_build $DRV $T/build/soong/soong_ui.bash --make-mode $@
+ _wrap_build $T/build/soong/soong_ui.bash --make-mode $@
else
echo "Couldn't locate the top of the tree. Try setting TOP."
return 1
@@ -794,11 +772,10 @@
function mm()
{
local T=$(gettop)
- local DRV=$(getdriver $T)
# If we're sitting in the root of the build tree, just do a
# normal build.
if [ -f build/soong/soong_ui.bash ]; then
- _wrap_build $DRV $T/build/soong/soong_ui.bash --make-mode $@
+ _wrap_build $T/build/soong/soong_ui.bash --make-mode $@
else
# Find the closest Android.mk file.
local M=$(findmakefile)
@@ -833,7 +810,7 @@
if [ "1" = "${WITH_TIDY_ONLY}" -o "true" = "${WITH_TIDY_ONLY}" ]; then
MODULES=tidy_only
fi
- ONE_SHOT_MAKEFILE=$M _wrap_build $DRV $T/build/soong/soong_ui.bash --make-mode $MODULES $ARGS
+ ONE_SHOT_MAKEFILE=$M _wrap_build $T/build/soong/soong_ui.bash --make-mode $MODULES $ARGS
fi
fi
}
@@ -841,7 +818,6 @@
function mmm()
{
local T=$(gettop)
- local DRV=$(getdriver $T)
if [ "$T" ]; then
local MAKEFILE=
local MODULES=
@@ -901,7 +877,7 @@
fi
# Convert "/" to "-".
MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
- ONE_SHOT_MAKEFILE="$MAKEFILE" _wrap_build $DRV $T/build/soong/soong_ui.bash --make-mode $DASH_ARGS $MODULES $MODULES_IN_PATHS $ARGS
+ ONE_SHOT_MAKEFILE="$MAKEFILE" _wrap_build $T/build/soong/soong_ui.bash --make-mode $DASH_ARGS $MODULES $MODULES_IN_PATHS $ARGS
else
echo "Couldn't locate the top of the tree. Try setting TOP."
return 1
@@ -911,9 +887,8 @@
function mma()
{
local T=$(gettop)
- local DRV=$(getdriver $T)
if [ -f build/soong/soong_ui.bash ]; then
- _wrap_build $DRV $T/build/soong/soong_ui.bash --make-mode $@
+ _wrap_build $T/build/soong/soong_ui.bash --make-mode $@
else
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP."
@@ -925,14 +900,13 @@
local MODULES_IN_PATHS=MODULES-IN-$(dirname ${M})
# Convert "/" to "-".
MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
- _wrap_build $DRV $T/build/soong/soong_ui.bash --make-mode $@ $MODULES_IN_PATHS
+ _wrap_build $T/build/soong/soong_ui.bash --make-mode $@ $MODULES_IN_PATHS
fi
}
function mmma()
{
local T=$(gettop)
- local DRV=$(getdriver $T)
if [ "$T" ]; then
local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
@@ -963,7 +937,7 @@
done
# Convert "/" to "-".
MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}
- _wrap_build $DRV $T/build/soong/soong_ui.bash --make-mode $DASH_ARGS $ARGS $MODULES_IN_PATHS
+ _wrap_build $T/build/soong/soong_ui.bash --make-mode $DASH_ARGS $ARGS $MODULES_IN_PATHS
else
echo "Couldn't locate the top of the tree. Try setting TOP."
return 1
diff --git a/target/board/generic/sepolicy/hal_fingerprint_default.te b/target/board/generic/sepolicy/hal_fingerprint_default.te
new file mode 100644
index 0000000..e5b06f1
--- /dev/null
+++ b/target/board/generic/sepolicy/hal_fingerprint_default.te
@@ -0,0 +1,5 @@
+# TODO(b/36644492): Remove data_between_core_and_vendor_violators once
+# hal_fingerprint no longer directly accesses fingerprintd_data_file.
+typeattribute hal_fingerprint_default data_between_core_and_vendor_violators;
+allow hal_fingerprint_default fingerprintd_data_file:file create_file_perms;
+allow hal_fingerprint_default fingerprintd_data_file:dir rw_dir_perms;
diff --git a/target/product/embedded.mk b/target/product/embedded.mk
index 18eeb40..3f1d6df 100644
--- a/target/product/embedded.mk
+++ b/target/product/embedded.mk
@@ -51,6 +51,7 @@
libbinder \
libc \
libc_malloc_debug \
+ libc_malloc_hooks \
libcutils \
libdl \
libgui \
diff --git a/target/product/full_base_telephony.mk b/target/product/full_base_telephony.mk
index 375c679..af4097d 100644
--- a/target/product/full_base_telephony.mk
+++ b/target/product/full_base_telephony.mk
@@ -24,7 +24,7 @@
ro.com.android.dataroaming=true
PRODUCT_COPY_FILES := \
- device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
+ device/sample/etc/apns-full-conf.xml:system/etc/apns-conf.xml \
frameworks/native/data/etc/handheld_core_hardware.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/handheld_core_hardware.xml
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base.mk)
diff --git a/tools/docker/.gitignore b/tools/docker/.gitignore
new file mode 100644
index 0000000..df0b367
--- /dev/null
+++ b/tools/docker/.gitignore
@@ -0,0 +1 @@
+gitconfig
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
new file mode 100644
index 0000000..ec65aaf
--- /dev/null
+++ b/tools/docker/Dockerfile
@@ -0,0 +1,25 @@
+FROM ubuntu:14.04
+ARG userid
+ARG groupid
+ARG username
+
+RUN apt-get update && apt-get install -y git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip python openjdk-7-jdk
+
+RUN curl -o jdk8.tgz https://android.googlesource.com/platform/prebuilts/jdk/jdk8/+archive/master.tar.gz \
+ && tar -zxf jdk8.tgz linux-x86 \
+ && mv linux-x86 /usr/lib/jvm/java-8-openjdk-amd64 \
+ && rm -rf jdk8.tgz
+
+RUN curl -o /usr/local/bin/repo https://storage.googleapis.com/git-repo-downloads/repo \
+ && echo "e147f0392686c40cfd7d5e6f332c6ee74c4eab4d24e2694b3b0a0c037bf51dc5 /usr/local/bin/repo" | sha256sum --strict -c - \
+ && chmod a+x /usr/local/bin/repo
+
+RUN groupadd -g $groupid $username \
+ && useradd -m -u $userid -g $groupid $username \
+ && echo $username >/root/username \
+ && echo "export USER="$username >>/home/$username/.gitconfig
+COPY gitconfig /home/$username/.gitconfig
+RUN chown $userid:$groupid /home/$username/.gitconfig
+ENV HOME=/home/$username
+
+ENTRYPOINT chroot --userspec=$(cat /root/username):$(cat /root/username) / /bin/bash -i
diff --git a/tools/docker/README.md b/tools/docker/README.md
new file mode 100644
index 0000000..304fd18
--- /dev/null
+++ b/tools/docker/README.md
@@ -0,0 +1,18 @@
+The Dockerfile in this directory sets up an Ubuntu Trusty image ready to build
+a variety of Android branches (>= Lollipop). It's particulary useful to build
+older branches that required 14.04 if you've upgraded to something newer.
+
+First, build the image:
+```
+# Copy your host gitconfig, or create a stripped down version
+$ cp ~/.gitconfig gitconfig
+$ docker build --build-arg userid=$(id -u) --build-arg groupid=$(id -g) --build-arg username=$(id -un) -t android-build-trusty .
+```
+
+Then you can start up new instances with:
+```
+$ docker run -it --rm -v $ANDROID_BUILD_TOP:/src android-build-trusty
+> cd /src; source build/envsetup.sh
+> lunch aosp_arm-eng
+> m -j50
+```
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index 36dc619..c073eba 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -25,6 +25,7 @@
import common
import test_utils
import validate_target_files
+from rangelib import RangeSet
KiB = 1024
@@ -504,6 +505,147 @@
self.assertEqual(expected, actual)
+class CommonUtilsTest(unittest.TestCase):
+
+ def tearDown(self):
+ common.Cleanup()
+
+ def test_GetSparseImage_emptyBlockMapFile(self):
+ target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
+ with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+ target_files_zip.write(
+ test_utils.construct_sparse_image([
+ (0xCAC1, 6),
+ (0xCAC3, 3),
+ (0xCAC1, 4)]),
+ arcname='IMAGES/system.img')
+ target_files_zip.writestr('IMAGES/system.map', '')
+ target_files_zip.writestr('SYSTEM/file1', os.urandom(4096 * 8))
+ target_files_zip.writestr('SYSTEM/file2', os.urandom(4096 * 3))
+
+ tempdir, input_zip = common.UnzipTemp(target_files)
+ sparse_image = common.GetSparseImage('system', tempdir, input_zip, False)
+ input_zip.close()
+
+ self.assertDictEqual(
+ {
+ '__COPY': RangeSet("0"),
+ '__NONZERO-0': RangeSet("1-5 9-12"),
+ },
+ sparse_image.file_map)
+
+ def test_GetSparseImage_invalidImageName(self):
+ self.assertRaises(
+ AssertionError, common.GetSparseImage, 'system2', None, None, False)
+ self.assertRaises(
+ AssertionError, common.GetSparseImage, 'unknown', None, None, False)
+
+ def test_GetSparseImage_missingBlockMapFile(self):
+ target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
+ with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+ target_files_zip.write(
+ test_utils.construct_sparse_image([
+ (0xCAC1, 6),
+ (0xCAC3, 3),
+ (0xCAC1, 4)]),
+ arcname='IMAGES/system.img')
+ target_files_zip.writestr('SYSTEM/file1', os.urandom(4096 * 8))
+ target_files_zip.writestr('SYSTEM/file2', os.urandom(4096 * 3))
+
+ tempdir, input_zip = common.UnzipTemp(target_files)
+ self.assertRaises(
+ AssertionError, common.GetSparseImage, 'system', tempdir, input_zip,
+ False)
+ input_zip.close()
+
+ def test_GetSparseImage_sharedBlocks_notAllowed(self):
+ """Tests the case of having overlapping blocks but disallowed."""
+ target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
+ with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+ target_files_zip.write(
+ test_utils.construct_sparse_image([(0xCAC2, 16)]),
+ arcname='IMAGES/system.img')
+ # Block 10 is shared between two files.
+ target_files_zip.writestr(
+ 'IMAGES/system.map',
+ '\n'.join([
+ '/system/file1 1-5 9-10',
+ '/system/file2 10-12']))
+ target_files_zip.writestr('SYSTEM/file1', os.urandom(4096 * 7))
+ target_files_zip.writestr('SYSTEM/file2', os.urandom(4096 * 3))
+
+ tempdir, input_zip = common.UnzipTemp(target_files)
+ self.assertRaises(
+ AssertionError, common.GetSparseImage, 'system', tempdir, input_zip,
+ False)
+ input_zip.close()
+
+ def test_GetSparseImage_sharedBlocks_allowed(self):
+ """Tests the case for target using BOARD_EXT4_SHARE_DUP_BLOCKS := true."""
+ target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
+ with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+ # Construct an image with a care_map of "0-5 9-12".
+ target_files_zip.write(
+ test_utils.construct_sparse_image([(0xCAC2, 16)]),
+ arcname='IMAGES/system.img')
+ # Block 10 is shared between two files.
+ target_files_zip.writestr(
+ 'IMAGES/system.map',
+ '\n'.join([
+ '/system/file1 1-5 9-10',
+ '/system/file2 10-12']))
+ target_files_zip.writestr('SYSTEM/file1', os.urandom(4096 * 7))
+ target_files_zip.writestr('SYSTEM/file2', os.urandom(4096 * 3))
+
+ tempdir, input_zip = common.UnzipTemp(target_files)
+ sparse_image = common.GetSparseImage('system', tempdir, input_zip, True)
+ input_zip.close()
+
+ self.assertDictEqual(
+ {
+ '__COPY': RangeSet("0"),
+ '__NONZERO-0': RangeSet("6-8 13-15"),
+ '/system/file1': RangeSet("1-5 9-10"),
+ '/system/file2': RangeSet("11-12"),
+ },
+ sparse_image.file_map)
+
+ # '/system/file2' should be marked with 'uses_shared_blocks', but not with
+ # 'incomplete'.
+ self.assertTrue(
+ sparse_image.file_map['/system/file2'].extra['uses_shared_blocks'])
+ self.assertNotIn(
+ 'incomplete', sparse_image.file_map['/system/file2'].extra)
+
+ # All other entries should look normal without any tags.
+ 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)
+
+ def test_GetSparseImage_incompleteRanges(self):
+ """Tests the case of ext4 images with holes."""
+ target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
+ with zipfile.ZipFile(target_files, 'w') as target_files_zip:
+ target_files_zip.write(
+ test_utils.construct_sparse_image([(0xCAC2, 16)]),
+ arcname='IMAGES/system.img')
+ target_files_zip.writestr(
+ 'IMAGES/system.map',
+ '\n'.join([
+ '/system/file1 1-5 9-10',
+ '/system/file2 11-12']))
+ target_files_zip.writestr('SYSTEM/file1', os.urandom(4096 * 7))
+ # '/system/file2' has less blocks listed (2) than actual (3).
+ target_files_zip.writestr('SYSTEM/file2', os.urandom(4096 * 3))
+
+ tempdir, input_zip = common.UnzipTemp(target_files)
+ sparse_image = common.GetSparseImage('system', tempdir, input_zip, False)
+ input_zip.close()
+
+ self.assertFalse(sparse_image.file_map['/system/file1'].extra)
+ self.assertTrue(sparse_image.file_map['/system/file2'].extra['incomplete'])
+
+
class InstallRecoveryScriptFormatTest(unittest.TestCase):
"""Checks the format of install-recovery.sh.
diff --git a/tools/releasetools/test_utils.py b/tools/releasetools/test_utils.py
index ec53731..e64355b 100644
--- a/tools/releasetools/test_utils.py
+++ b/tools/releasetools/test_utils.py
@@ -18,7 +18,11 @@
Utils for running unittests.
"""
+import os
import os.path
+import struct
+
+import common
def get_testdata_dir():
@@ -26,3 +30,67 @@
# The script dir is the one we want, which could be different from pwd.
current_dir = os.path.dirname(os.path.realpath(__file__))
return os.path.join(current_dir, 'testdata')
+
+
+def construct_sparse_image(chunks):
+ """Returns a sparse image file constructed from the given chunks.
+
+ From system/core/libsparse/sparse_format.h.
+ typedef struct sparse_header {
+ __le32 magic; // 0xed26ff3a
+ __le16 major_version; // (0x1) - reject images with higher major versions
+ __le16 minor_version; // (0x0) - allow images with higer minor versions
+ __le16 file_hdr_sz; // 28 bytes for first revision of the file format
+ __le16 chunk_hdr_sz; // 12 bytes for first revision of the file format
+ __le32 blk_sz; // block size in bytes, must be a multiple of 4 (4096)
+ __le32 total_blks; // total blocks in the non-sparse output image
+ __le32 total_chunks; // total chunks in the sparse input image
+ __le32 image_checksum; // CRC32 checksum of the original data, counting
+ // "don't care" as 0. Standard 802.3 polynomial,
+ // use a Public Domain table implementation
+ } sparse_header_t;
+
+ typedef struct chunk_header {
+ __le16 chunk_type; // 0xCAC1 -> raw; 0xCAC2 -> fill;
+ // 0xCAC3 -> don't care
+ __le16 reserved1;
+ __le32 chunk_sz; // in blocks in output image
+ __le32 total_sz; // in bytes of chunk input file including chunk header
+ // and data
+ } chunk_header_t;
+
+ Args:
+ chunks: A list of chunks to be written. Each entry should be a tuple of
+ (chunk_type, block_number).
+
+ Returns:
+ Filename of the created sparse image.
+ """
+ SPARSE_HEADER_MAGIC = 0xED26FF3A
+ SPARSE_HEADER_FORMAT = "<I4H4I"
+ CHUNK_HEADER_FORMAT = "<2H2I"
+
+ sparse_image = common.MakeTempFile(prefix='sparse-', suffix='.img')
+ with open(sparse_image, 'wb') as fp:
+ fp.write(struct.pack(
+ SPARSE_HEADER_FORMAT, SPARSE_HEADER_MAGIC, 1, 0, 28, 12, 4096,
+ sum(chunk[1] for chunk in chunks),
+ len(chunks), 0))
+
+ for chunk in chunks:
+ data_size = 0
+ if chunk[0] == 0xCAC1:
+ data_size = 4096 * chunk[1]
+ elif chunk[0] == 0xCAC2:
+ data_size = 4
+ elif chunk[0] == 0xCAC3:
+ pass
+ else:
+ assert False, "Unsupported chunk type: {}".format(chunk[0])
+
+ fp.write(struct.pack(
+ CHUNK_HEADER_FORMAT, chunk[0], 0, chunk[1], data_size + 12))
+ if data_size != 0:
+ fp.write(os.urandom(data_size))
+
+ return sparse_image