Merge "Enable R8 by default (second attempt for Q)"
diff --git a/core/aapt2.mk b/core/aapt2.mk
index c582e30..895bd37 100644
--- a/core/aapt2.mk
+++ b/core/aapt2.mk
@@ -12,6 +12,7 @@
# - proguard_options_file
# - my_generated_res_dirs: Resources generated during the build process and we have to compile them in a single run of aapt2.
# - my_generated_res_dirs_deps: the dependency to use for my_generated_res_dirs.
+# - my_generated_res_zips: Zip files containing resources
# - my_apk_split_configs: The configurations for which to generate splits.
# - built_apk_splits: The paths where AAPT should generate the splits.
#
@@ -35,7 +36,7 @@
$(eval $(call aapt2-compile-one-resource-file-rule,$(r),$(o)))\
$(o))
-my_generated_resources_flata :=
+my_resources_flata :=
# Compile generated resources
ifneq ($(my_generated_res_dirs),)
my_generated_resources_flata := $(my_compiled_res_base_dir)/gen_res.flata
@@ -44,12 +45,23 @@
@echo "AAPT2 compile $@ <- $(PRIVATE_SOURCE_RES_DIRS)"
$(call aapt2-compile-resource-dirs)
-my_generated_resources_flata += $(my_generated_resources_flata)
+my_resources_flata += $(my_generated_resources_flata)
+endif
+
+# Compile zipped resources
+ifneq ($(my_generated_res_zips),)
+my_zipped_resources_flata := $(my_compiled_res_base_dir)/zip_res.flata
+$(my_zipped_resources_flata): PRIVATE_SOURCE_RES_ZIPS := $(my_generated_res_zips)
+$(my_zipped_resources_flata) : $(my_generated_res_deps) $(AAPT2) $(EXTRACT_SRCJARS)
+ @echo "AAPT2 compile $@ <- $(PRIVATE_SOURCE_RES_ZIPS)"
+ $(call aapt2-compile-resource-zips)
+
+my_resources_flata += $(my_zipped_resources_flata)
endif
# Always set --pseudo-localize, it will be stripped out later for release
# builds that don't want it.
-$(my_res_resources_flat) $(my_overlay_resources_flat) $(my_generated_resources_flata): \
+$(my_res_resources_flat) $(my_overlay_resources_flat) $(my_resources_flata): \
PRIVATE_AAPT2_CFLAGS := --pseudo-localize
my_static_library_resources := $(foreach l, $(call reverse-list,$(LOCAL_STATIC_ANDROID_LIBRARIES)),\
@@ -67,7 +79,7 @@
endif
$(my_res_package): PRIVATE_RES_FLAT := $(my_res_resources_flat)
-$(my_res_package): PRIVATE_OVERLAY_FLAT := $(my_static_library_resources) $(my_generated_resources_flata) $(my_overlay_resources_flat)
+$(my_res_package): PRIVATE_OVERLAY_FLAT := $(my_static_library_resources) $(my_resources_flata) $(my_overlay_resources_flat)
$(my_res_package): PRIVATE_SHARED_ANDROID_LIBRARIES := $(my_shared_library_resources)
$(my_res_package): PRIVATE_PROGUARD_OPTIONS_FILE := $(proguard_options_file)
$(my_res_package): PRIVATE_ASSET_DIRS := $(my_asset_dirs)
@@ -95,7 +107,7 @@
$(my_res_package): $(full_android_manifest) $(my_static_library_resources) $(my_shared_library_resources)
$(my_res_package): $(my_full_asset_paths)
$(my_res_package): $(my_res_resources_flat) $(my_overlay_resources_flat) \
- $(my_generated_resources_flata) $(my_static_library_resources) \
+ $(my_resources_flata) $(my_static_library_resources) \
$(AAPT2)
@echo "AAPT2 link $@"
$(call aapt2-link)
@@ -118,3 +130,4 @@
my_apk_split_configs :=
my_generated_res_dirs :=
my_generated_res_dirs_deps :=
+my_generated_res_zips :=
diff --git a/core/aapt_flags.mk b/core/aapt_flags.mk
new file mode 100644
index 0000000..4e3493a
--- /dev/null
+++ b/core/aapt_flags.mk
@@ -0,0 +1,20 @@
+## AAPT Flags
+# aapt doesn't accept multiple --extra-packages flags.
+# We have to collapse them into a single --extra-packages flag here.
+LOCAL_AAPT_FLAGS := $(strip $(LOCAL_AAPT_FLAGS))
+ifdef LOCAL_AAPT_FLAGS
+ ifeq ($(filter 0 1,$(words $(filter --extra-packages,$(LOCAL_AAPT_FLAGS)))),)
+ aapt_flags := $(subst --extra-packages$(space),--extra-packages@,$(LOCAL_AAPT_FLAGS))
+ aapt_flags_extra_packages := $(patsubst --extra-packages@%,%,$(filter --extra-packages@%,$(aapt_flags)))
+ aapt_flags_extra_packages := $(sort $(subst :,$(space),$(aapt_flags_extra_packages)))
+ LOCAL_AAPT_FLAGS := $(filter-out --extra-packages@%,$(aapt_flags)) \
+ --extra-packages $(subst $(space),:,$(aapt_flags_extra_packages))
+ aapt_flags_extra_packages :=
+ aapt_flags :=
+ endif
+endif
+
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_AAPT_CHARACTERISTICS := $(TARGET_AAPT_CHARACTERISTICS)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_PACKAGE_NAME := $(LOCAL_MANIFEST_PACKAGE_NAME)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_INSTRUMENTATION_FOR := $(LOCAL_MANIFEST_INSTRUMENTATION_FOR)
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 8488858..d1ba354 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -7,6 +7,7 @@
LOCAL_AAPT2_ONLY:=
LOCAL_AAPT_FLAGS:=
LOCAL_AAPT_INCLUDE_ALL_RESOURCES:=
+LOCAL_AAPT_NAMESPACES:=
LOCAL_ADDITIONAL_CERTIFICATES:=
LOCAL_ADDITIONAL_DEPENDENCIES:=
LOCAL_ADDITIONAL_HTML_DIR:=
@@ -125,7 +126,6 @@
LOCAL_JAR_PROCESSOR:=
LOCAL_JAR_PROCESSOR_ARGS:=
LOCAL_JAVACFLAGS:=
-LOCAL_JAVAC_SHARD_SIZE:=
LOCAL_JAVA_LANGUAGE_VERSION:=
LOCAL_JAVA_LAYERS_FILE:=
LOCAL_JAVA_LIBRARIES:=
diff --git a/core/definitions.mk b/core/definitions.mk
index b0b92de..bd2afac 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2079,6 +2079,15 @@
$(PRIVATE_AAPT2_CFLAGS) --legacy
endef
+# TODO(b/74574557): use aapt2 compile --zip if it gets implemented
+define aapt2-compile-resource-zips
+@mkdir -p $(dir $@)
+rm -rf $@.contents
+mkdir -p $@.contents
+$(EXTRACT_SRCJARS) $@.contents $@.list $(PRIVATE_SOURCE_RES_ZIPS)
+$(hide) $(AAPT2) compile -o $@ --dir $@.tmp $(PRIVATE_AAPT2_CFLAGS) --legacy
+endef
+
# Set up rule to compile one resource file with aapt2.
# Must be called with $(eval).
# $(1): the source file
@@ -2222,26 +2231,18 @@
$(hide) tr ' ' '\n' < $@.tmp | $(NORMALIZE_PATH) | sort -u > $@
endef
-# $(1): sharding number.
-# $(2): Java source files paths.
-define save-sharded-java-source-list
-$(java_source_list_file).shard.$(1): $(2) $$(NORMALIZE_PATH)
- @echo "shard java source list: $$@"
- rm -f $$@
- $$(call dump-words-to-file,$(2),$$@.tmp)
- $(hide) tr ' ' '\n' < $$@.tmp | $$(NORMALIZE_PATH) | sort -u > $$@
-endef
-
# Common definition to invoke javac on the host and target.
#
# $(1): javac
# $(2): classpath_libs
define compile-java
$(hide) rm -f $@
-$(hide) rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR) $(PRIVATE_ANNO_INTERMEDIATES_DIR)
+$(hide) rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR) $(PRIVATE_ANNO_INTERMEDIATES_DIR) $(if $(PRIVATE_SRCJARS),$(PRIVATE_SRCJAR_INTERMEDIATES_DIR))
$(hide) mkdir -p $(dir $@)
-$(hide) mkdir -p $(PRIVATE_CLASS_INTERMEDIATES_DIR) $(PRIVATE_ANNO_INTERMEDIATES_DIR)
-$(hide) if [ -s $(PRIVATE_JAVA_SOURCE_LIST) ] ; then \
+$(hide) mkdir -p $(PRIVATE_CLASS_INTERMEDIATES_DIR) $(PRIVATE_ANNO_INTERMEDIATES_DIR) $(if $(PRIVATE_SRCJARS),$(PRIVATE_SRCJAR_INTERMEDIATES_DIR))
+$(if $(PRIVATE_SRCJARS),\
+ $(EXTRACT_SRCJARS) $(PRIVATE_SRCJAR_INTERMEDIATES_DIR) $(PRIVATE_SRCJAR_LIST_FILE) $(PRIVATE_SRCJARS))
+$(hide) if [ -s $(PRIVATE_JAVA_SOURCE_LIST) $(if $(PRIVATE_SRCJARS),-o -s $(PRIVATE_SRCJAR_LIST_FILE) )] ; then \
$(SOONG_JAVAC_WRAPPER) $(JAVAC_WRAPPER) $(1) -encoding UTF-8 \
$(if $(findstring true,$(PRIVATE_WARNINGS_ENABLE)),$(xlint_unchecked),) \
$(if $(PRIVATE_USE_SYSTEM_MODULES), \
@@ -2260,6 +2261,7 @@
-d $(PRIVATE_CLASS_INTERMEDIATES_DIR) -s $(PRIVATE_ANNO_INTERMEDIATES_DIR) \
$(PRIVATE_JAVACFLAGS) \
\@$(PRIVATE_JAVA_SOURCE_LIST) \
+ $(if $(PRIVATE_SRCJARS),\@$(PRIVATE_SRCJAR_LIST_FILE)) \
|| ( rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR) ; exit 41 ) \
fi
$(if $(PRIVATE_JAVA_LAYERS_FILE), $(hide) build/make/tools/java-layers.py \
@@ -2280,51 +2282,18 @@
$(if $(PRIVATE_EXTRA_JAR_ARGS),$(call add-java-resources-to,$@))
endef
-# $(1): Javac output jar name.
-# $(2): Java source list file.
-# $(3): Java header libs.
-# $(4): Javac sharding number.
-# $(5): Javac sources deps (the arg may neeed $$ in case of containing '#')
-define create-classes-full-debug.jar
-$(1): PRIVATE_JAVACFLAGS := $$(LOCAL_JAVACFLAGS) $$(annotation_processor_flags)
-$(1): PRIVATE_JAR_EXCLUDE_FILES := $$(LOCAL_JAR_EXCLUDE_FILES)
-$(1): PRIVATE_JAR_PACKAGES := $$(LOCAL_JAR_PACKAGES)
-$(1): PRIVATE_JAR_EXCLUDE_PACKAGES := $$(LOCAL_JAR_EXCLUDE_PACKAGES)
-$(1): PRIVATE_DONT_DELETE_JAR_META_INF := $$(LOCAL_DONT_DELETE_JAR_META_INF)
-$(1): PRIVATE_JAVA_SOURCE_LIST := $(2)
-$(1): PRIVATE_ALL_JAVA_HEADER_LIBRARIES := $(3)
-$(1): PRIVATE_CLASS_INTERMEDIATES_DIR := $(intermediates.COMMON)/classes$(4)
-$(1): PRIVATE_ANNO_INTERMEDIATES_DIR := $(intermediates.COMMON)/anno$(4)
-$(1): \
- $(2) \
- $(3) \
- $(5) \
- $$(full_java_bootclasspath_libs) \
- $$(full_java_system_modules_deps) \
- $$(layers_file) \
- $$(annotation_processor_deps) \
- $$(NORMALIZE_PATH) \
- $$(JAR_ARGS) \
- | $$(SOONG_JAVAC_WRAPPER)
- @echo "Target Java: $$@ ($$(PRIVATE_CLASS_INTERMEDIATES_DIR))"
- $$(call compile-java,$$(TARGET_JAVAC),$$(PRIVATE_ALL_JAVA_HEADER_LIBRARIES))
-endef
-
define transform-java-to-header.jar
@echo "$($(PRIVATE_PREFIX)DISPLAY) Turbine: $(PRIVATE_MODULE)"
@mkdir -p $(dir $@)
@rm -rf $(dir $@)/classes-turbine
@mkdir $(dir $@)/classes-turbine
-$(hide) if [ -s $(PRIVATE_JAVA_SOURCE_LIST) ] ; then \
+$(hide) if [ -s $(PRIVATE_JAVA_SOURCE_LIST) -o -n "$(PRIVATE_SRCJARS)" ] ; then \
$(JAVA) -jar $(TURBINE) \
--output $@.premerged --temp_dir $(dir $@)/classes-turbine \
- --sources \@$(PRIVATE_JAVA_SOURCE_LIST) \
- --javacopts $(PRIVATE_JAVACFLAGS) $(COMMON_JDK_FLAGS) \
- $(addprefix --bootclasspath ,$(strip \
- $(call normalize-path-list,$(PRIVATE_BOOTCLASSPATH)) \
- $(PRIVATE_EMPTY_BOOTCLASSPATH))) \
- $(addprefix --classpath ,$(strip \
- $(call normalize-path-list,$(PRIVATE_ALL_JAVA_HEADER_LIBRARIES)))) \
+ --sources \@$(PRIVATE_JAVA_SOURCE_LIST) --source_jars $(PRIVATE_SRCJARS) \
+ --javacopts $(PRIVATE_JAVACFLAGS) $(COMMON_JDK_FLAGS) -- \
+ $(addprefix --bootclasspath ,$(strip $(PRIVATE_BOOTCLASSPATH))) \
+ $(addprefix --classpath ,$(strip $(PRIVATE_ALL_JAVA_HEADER_LIBRARIES))) \
|| ( rm -rf $(dir $@)/classes-turbine ; exit 41 ) && \
$(MERGE_ZIPS) -j --ignore-duplicates -stripDir META-INF $@.tmp $@.premerged $(call reverse-list,$(PRIVATE_STATIC_JAVA_HEADER_LIBRARIES)) ; \
else \
diff --git a/core/host_dalvik_java_library.mk b/core/host_dalvik_java_library.mk
index 20663d1..fc5b75c 100644
--- a/core/host_dalvik_java_library.mk
+++ b/core/host_dalvik_java_library.mk
@@ -76,6 +76,7 @@
$(java_sources) \
$(java_resource_sources) \
$(proto_java_sources_file_stamp) \
+ $(LOCAL_SRCJARS) \
$(LOCAL_ADDITIONAL_DEPENDENCIES)
$(java_source_list_file): $(java_sources_deps)
@@ -86,6 +87,9 @@
$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_FILES :=
$(full_classes_compiled_jar): PRIVATE_JAR_PACKAGES :=
$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_PACKAGES :=
+$(full_classes_compiled_jar): PRIVATE_SRCJARS := $(LOCAL_SRCJARS)
+$(full_classes_compiled_jar): PRIVATE_SRCJAR_LIST_FILE := $(intermediates.COMMON)/srcjar-list
+$(full_classes_compiled_jar): PRIVATE_SRCJAR_INTERMEDIATES_DIR := $(intermediates.COMMON)/srcjars
$(full_classes_compiled_jar): \
$(java_source_list_file) \
$(java_sources_deps) \
@@ -95,6 +99,7 @@
$(annotation_processor_deps) \
$(NORMALIZE_PATH) \
$(JAR_ARGS) \
+ $(EXTRACT_SRCJARS) \
| $(SOONG_JAVAC_WRAPPER)
$(transform-host-java-to-dalvik-package)
@@ -102,6 +107,7 @@
$(full_classes_turbine_jar): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS) $(annotation_processor_flags)
$(full_classes_turbine_jar): PRIVATE_DONT_DELETE_JAR_META_INF := $(LOCAL_DONT_DELETE_JAR_META_INF)
+$(full_classes_turbine_jar): PRIVATE_SRCJARS := $(LOCAL_SRCJARS)
$(full_classes_turbine_jar): \
$(java_source_list_file) \
$(java_sources_deps) \
diff --git a/core/host_java_library.mk b/core/host_java_library.mk
index 5176f37..47a8b02 100644
--- a/core/host_java_library.mk
+++ b/core/host_java_library.mk
@@ -63,6 +63,7 @@
$(java_sources) \
$(java_resource_sources) \
$(proto_java_sources_file_stamp) \
+ $(LOCAL_SRCJARS) \
$(LOCAL_ADDITIONAL_DEPENDENCIES)
$(java_source_list_file): $(java_sources_deps)
@@ -73,6 +74,9 @@
$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_FILES :=
$(full_classes_compiled_jar): PRIVATE_JAR_PACKAGES :=
$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_PACKAGES :=
+$(full_classes_compiled_jar): PRIVATE_SRCJARS := $(LOCAL_SRCJARS)
+$(full_classes_compiled_jar): PRIVATE_SRCJAR_LIST_FILE := $(intermediates.COMMON)/srcjar-list
+$(full_classes_compiled_jar): PRIVATE_SRCJAR_INTERMEDIATES_DIR := $(intermediates.COMMON)/srcjars
$(full_classes_compiled_jar): \
$(java_source_list_file) \
$(java_sources_deps) \
@@ -82,6 +86,7 @@
$(NORMALIZE_PATH) \
$(ZIPTIME) \
$(JAR_ARGS) \
+ $(EXTRACT_SRCJARS) \
| $(SOONG_JAVAC_WRAPPER)
$(transform-host-java-to-package)
$(remove-timestamps-from-package)
diff --git a/core/java.mk b/core/java.mk
index 097f52c..907825c 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -108,9 +108,8 @@
###############################################################
## .rs files: RenderScript sources to .java files and .bc files
-## .fs files: Filterscript sources to .java files and .bc files
###############################################################
-renderscript_sources := $(filter %.rs %.fs,$(LOCAL_SRC_FILES))
+renderscript_sources := $(filter %.rs,$(LOCAL_SRC_FILES))
# Because names of the java files from RenderScript are unknown until the
# .rs file(s) are compiled, we have to depend on a timestamp file.
RenderScript_file_stamp :=
@@ -171,7 +170,7 @@
LOCAL_RENDERSCRIPT_INCLUDES := $(LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE)
endif
-bc_files := $(patsubst %.fs,%.bc, $(patsubst %.rs,%.bc, $(notdir $(renderscript_sources))))
+bc_files := $(patsubst %.rs,%.bc, $(notdir $(renderscript_sources)))
bc_dep_files := $(addprefix $(renderscript_intermediate.COMMON)/,$(patsubst %.bc,%.d,$(bc_files)))
$(RenderScript_file_stamp): PRIVATE_RS_INCLUDES := $(LOCAL_RENDERSCRIPT_INCLUDES)
@@ -331,34 +330,6 @@
java_intermediate_sources := $(addprefix $(TARGET_OUT_COMMON_INTERMEDIATES)/, $(filter %.java,$(LOCAL_INTERMEDIATE_SOURCES)))
all_java_sources := $(java_sources) $(java_intermediate_sources)
-enable_sharding :=
-ifneq ($(TURBINE_ENABLED),false)
-ifneq ($(LOCAL_JAVAC_SHARD_SIZE),)
-ifneq ($(LOCAL_JAR_PROCESSOR),)
-$(call pretty-error,Cannot set both LOCAL_JAVAC_SHARD_SIZE and LOCAL_JAR_PROCESSOR!)
-endif # LOCAL_JAR_PROCESSOR is not empty
-enable_sharding := true
-
-num_shards := $(call int_divide,$(words $(java_sources)),$(LOCAL_JAVAC_SHARD_SIZE))
-ifneq ($(words $(java_sources)),$(call int_multiply,$(LOCAL_JAVAC_SHARD_SIZE),$(num_shards)))
-# increment number of shards by 1.
-num_shards := $(call int_plus,$(num_shards),1)
-endif
-
-shard_idx_list := $(call int_range_list,1,$(num_shards))
-sharded_java_source_list_files += $(foreach x,$(shard_idx_list),$(java_source_list_file).shard.$(x))
-sharded_jar_list += $(foreach x,$(shard_idx_list),$(full_classes_compiled_jar).shard.$(x))
-
-# always put dynamically-located .java files (generated by Proto/resource, etc) in a new final shard.
-# increment number of shards by 1.
-num_shards := $(call int_plus,$(num_shards),1)
-sharded_java_source_list_files += $(java_source_list_file).shard.$(num_shards)
-sharded_jar_list += $(full_classes_compiled_jar).shard.$(num_shards)
-LOCAL_INTERMEDIATE_TARGETS += $(sharded_java_source_list_files)
-LOCAL_INTERMEDIATE_TARGETS += $(sharded_jar_list)
-endif # LOCAL_JAVAC_SHARD_SIZE is not empty
-endif # TURBINE_ENABLED != false
-
include $(BUILD_SYSTEM)/java_common.mk
include $(BUILD_SYSTEM)/sdk_check.mk
@@ -434,56 +405,16 @@
$(java_resource_sources) \
$(RenderScript_file_stamp) \
$(proto_java_sources_file_stamp) \
+ $(LOCAL_SRCJARS) \
$(LOCAL_ADDITIONAL_DEPENDENCIES)
$(java_source_list_file): $(java_sources_deps)
$(write-java-source-list)
-ifdef enable_sharding
-$(foreach x,$(shard_idx_list),\
- $(eval $(call save-sharded-java-source-list,$(x),\
- $(wordlist $(call int_plus,1,$(call int_multiply,$(LOCAL_JAVAC_SHARD_SIZE),$(call int_subtract,$(x),1))),\
- $(call int_multiply,$(LOCAL_JAVAC_SHARD_SIZE),$(x)),$(sort $(java_sources))))))
-
-# always put dynamically-located .java files (generated by Proto/resource, etc) in a new final shard.
-$(java_source_list_file).shard.$(num_shards): PRIVATE_JAVA_INTERMEDIATE_SOURCES := $(java_intermediate_sources)
-$(java_source_list_file).shard.$(num_shards): $(java_resource_sources) \
- $(RenderScript_file_stamp) \
- $(proto_java_sources_file_stamp) \
- $(LOCAL_ADDITIONAL_DEPENDENCIES) \
- $(NORMALIZE_PATH)
- $(hide) rm -f $@
- $(call dump-words-to-file,$(PRIVATE_JAVA_INTERMEDIATE_SOURCES),$@.tmp)
- $(call fetch-additional-java-source,$@.tmp)
- $(hide) tr ' ' '\n' < $@.tmp | $(NORMALIZE_PATH) | sort -u > $@
-
-# Javac sharding with header libs including its own header jar as one of dependency.
-$(foreach x,$(shard_idx_list),\
- $(eval $(call create-classes-full-debug.jar,$(full_classes_compiled_jar).shard.$(x),\
- $(java_source_list_file).shard.$(x),\
- $(full_java_header_libs) $(full_classes_header_jar),$(x),\
- $(wordlist $(call int_plus,1,$(call int_multiply,$(LOCAL_JAVAC_SHARD_SIZE),$(call int_subtract,$(x),1))),\
- $(call int_multiply,$(LOCAL_JAVAC_SHARD_SIZE),$(x)),$(sort $(java_sources))))))
-
-# Javac sharding for last shard with additional Java dependencies.
-$(eval $(call create-classes-full-debug.jar,$(full_classes_compiled_jar).shard.$(num_shards),\
- $(java_source_list_file).shard.$(num_shards),$(full_java_header_libs) $(full_classes_header_jar),$(strip \
- $(num_shards)),$$(java_resource_sources) $$(RenderScript_file_stamp) \
- $$(proto_java_sources_file_stamp) $$(LOCAL_ADDITIONAL_DEPENDENCIES)))
-
-$(full_classes_compiled_jar): PRIVATE_SHARDED_JAR_LIST := $(sharded_jar_list)
-$(full_classes_compiled_jar): $(sharded_jar_list) | $(MERGE_ZIPS)
- $(MERGE_ZIPS) -j $@ $(PRIVATE_SHARDED_JAR_LIST)
-else
-# we can't use single $ for java_sources_deps since it may contain hash '#' sign.
-$(eval $(call create-classes-full-debug.jar,$(full_classes_compiled_jar),\
- $(java_source_list_file),$(full_java_header_libs),,$$(java_sources_deps)))
-
-endif # ifdef enable_sharding
-
ifneq ($(TURBINE_ENABLED),false)
$(full_classes_turbine_jar): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS) $(annotation_processor_flags)
+$(full_classes_turbine_jar): PRIVATE_SRCJARS := $(LOCAL_SRCJARS)
$(full_classes_turbine_jar): PRIVATE_DONT_DELETE_JAR_META_INF := $(LOCAL_DONT_DELETE_JAR_META_INF)
$(full_classes_turbine_jar): \
$(java_source_list_file) \
@@ -514,6 +445,31 @@
endif # TURBINE_ENABLED != false
+$(full_classes_compiled_jar): PRIVATE_JAVACFLAGS := $(LOCAL_JAVACFLAGS) $(annotation_processor_flags)
+$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_FILES := $(LOCAL_JAR_EXCLUDE_FILES)
+$(full_classes_compiled_jar): PRIVATE_JAR_PACKAGES := $(LOCAL_JAR_PACKAGES)
+$(full_classes_compiled_jar): PRIVATE_JAR_EXCLUDE_PACKAGES := $(LOCAL_JAR_EXCLUDE_PACKAGES)
+$(full_classes_compiled_jar): PRIVATE_DONT_DELETE_JAR_META_INF := $(LOCAL_DONT_DELETE_JAR_META_INF)
+$(full_classes_compiled_jar): PRIVATE_JAVA_SOURCE_LIST := $(java_source_list_file)
+$(full_classes_compiled_jar): PRIVATE_ALL_JAVA_HEADER_LIBRARIES := $(full_java_header_libs)
+$(full_classes_compiled_jar): PRIVATE_SRCJARS := $(LOCAL_SRCJARS)
+$(full_classes_compiled_jar): PRIVATE_SRCJAR_LIST_FILE := $(intermediates.COMMON)/srcjar-list
+$(full_classes_compiled_jar): PRIVATE_SRCJAR_INTERMEDIATES_DIR := $(intermediates.COMMON)/srcjars
+$(full_classes_compiled_jar): \
+ $(java_source_list_file) \
+ $(full_java_header_libs) \
+ $(java_sources_deps) \
+ $(full_java_bootclasspath_libs) \
+ $(full_java_system_modules_deps) \
+ $(layers_file) \
+ $(annotation_processor_deps) \
+ $(NORMALIZE_PATH) \
+ $(JAR_ARGS) \
+ $(EXTRACT_SRCJARS) \
+ | $(SOONG_JAVAC_WRAPPER)
+ @echo "Target Java: $@
+ $(call compile-java,$(TARGET_JAVAC),$(PRIVATE_ALL_JAVA_HEADER_LIBRARIES))
+
javac-check : $(full_classes_compiled_jar)
javac-check-$(LOCAL_MODULE) : $(full_classes_compiled_jar)
diff --git a/core/java_common.mk b/core/java_common.mk
index b94effa..dea0435 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -177,7 +177,7 @@
#####################################
## Warn if there is unrecognized file in LOCAL_SRC_FILES.
my_unknown_src_files := $(filter-out \
- %.java %.aidl %.proto %.logtags %.fs %.rs, \
+ %.java %.aidl %.proto %.logtags %.rs, \
$(LOCAL_SRC_FILES) $(LOCAL_INTERMEDIATE_SOURCES) $(LOCAL_GENERATED_SOURCES))
ifneq ($(my_unknown_src_files),)
$(warning $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Unused source files: $(my_unknown_src_files))
@@ -188,7 +188,7 @@
# LOCAL_SOURCE_FILES_ALL_GENERATED is set only if the module does not have static source files,
# but generated source files in its LOCAL_INTERMEDIATE_SOURCE_DIR.
# You have to set up the dependency in some other way.
-need_compile_java := $(strip $(all_java_sources)$(all_res_assets)$(java_resource_sources))$(LOCAL_STATIC_JAVA_LIBRARIES)$(filter true,$(LOCAL_SOURCE_FILES_ALL_GENERATED))
+need_compile_java := $(strip $(all_java_sources)$(LOCAL_SRCJARS)$(all_res_assets)$(java_resource_sources))$(LOCAL_STATIC_JAVA_LIBRARIES)$(filter true,$(LOCAL_SOURCE_FILES_ALL_GENERATED))
ifdef need_compile_java
annotation_processor_flags :=
@@ -411,35 +411,6 @@
endif
##########################################################
-ifndef LOCAL_IS_HOST_MODULE
-## AAPT Flags
-# aapt doesn't accept multiple --extra-packages flags.
-# We have to collapse them into a single --extra-packages flag here.
-LOCAL_AAPT_FLAGS := $(strip $(LOCAL_AAPT_FLAGS))
-ifdef LOCAL_AAPT_FLAGS
-ifeq ($(filter 0 1,$(words $(filter --extra-packages,$(LOCAL_AAPT_FLAGS)))),)
-aapt_flags := $(subst --extra-packages$(space),--extra-packages@,$(LOCAL_AAPT_FLAGS))
-aapt_flags_extra_packages := $(patsubst --extra-packages@%,%,$(filter --extra-packages@%,$(aapt_flags)))
-aapt_flags_extra_packages := $(sort $(subst :,$(space),$(aapt_flags_extra_packages)))
-LOCAL_AAPT_FLAGS := $(filter-out --extra-packages@%,$(aapt_flags)) \
- --extra-packages $(subst $(space),:,$(aapt_flags_extra_packages))
-aapt_flags_extra_packages :=
-aapt_flags :=
-endif
-endif
-
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_AAPT_CHARACTERISTICS := $(TARGET_AAPT_CHARACTERISTICS)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_PACKAGE_NAME := $(LOCAL_MANIFEST_PACKAGE_NAME)
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_MANIFEST_INSTRUMENTATION_FOR := $(LOCAL_MANIFEST_INSTRUMENTATION_FOR)
-
-ifdef aidl_sources
-ALL_MODULES.$(my_register_name).AIDL_FILES := $(aidl_sources)
-endif
-ifdef renderscript_sources
-ALL_MODULES.$(my_register_name).RS_FILES := $(renderscript_sources_fullpath)
-endif
-endif # !LOCAL_IS_HOST_MODULE
full_java_libs := $(full_shared_java_libs) $(full_static_java_libs) $(LOCAL_CLASSPATH)
full_java_header_libs := $(full_shared_java_header_libs) $(full_static_java_header_libs)
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 0938c99..858a1bf 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -274,7 +274,7 @@
ifeq (true,$(LOCAL_EMMA_INSTRUMENT))
ifeq (true,$(EMMA_INSTRUMENT_STATIC))
-ifneq ($(LOCAL_SRC_FILES)$(LOCAL_STATIC_JAVA_LIBRARIES)$(LOCAL_SOURCE_FILES_ALL_GENERATED),)
+ifneq ($(LOCAL_SRC_FILES)$(LOCAL_SRCJARS)$(LOCAL_STATIC_JAVA_LIBRARIES)$(LOCAL_SOURCE_FILES_ALL_GENERATED),)
# Only add jacocoagent if the package contains some java code
LOCAL_STATIC_JAVA_LIBRARIES += jacocoagent
# Exclude jacoco classes from proguard
@@ -361,12 +361,13 @@
# Make sure the data-binding process happens before javac and generation of R.java.
$(R_file_stamp): $(data_binding_stamp)
$(java_source_list_file): $(data_binding_stamp)
-$(foreach x,$(sharded_java_source_list_files),$(eval $(x): $(data_binding_stamp)))
$(full_classes_compiled_jar): $(data_binding_stamp)
endif # LOCAL_DATA_BINDING
resource_export_package :=
+include $(BUILD_SYSTEM)/aapt_flags.mk
+
ifeq ($(need_compile_res),true)
###############################
@@ -407,8 +408,13 @@
endif # renderscript_target_api is set
my_asset_dirs := $(LOCAL_ASSET_DIR)
my_full_asset_paths := $(all_assets)
+
# Add AAPT2 link specific flags.
-$(my_res_package): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) --no-static-lib-packages
+$(my_res_package): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS)
+ifndef LOCAL_AAPT_NAMESPACES
+ $(my_res_package): PRIVATE_AAPT_FLAGS += --no-static-lib-packages
+endif
+
include $(BUILD_SYSTEM)/aapt2.mk
else # LOCAL_USE_AAPT2
@@ -460,7 +466,6 @@
# The R.java file must exist by the time the java source
# list is generated
$(java_source_list_file): $(R_file_stamp)
-$(foreach x,$(sharded_java_source_list_files),$(eval $(x): $(R_file_stamp)))
endif # need_compile_res
diff --git a/core/static_java_library.mk b/core/static_java_library.mk
index 77bb498..64e16c2 100644
--- a/core/static_java_library.mk
+++ b/core/static_java_library.mk
@@ -128,10 +128,15 @@
import_proguard_flag_files :=
endif
+include $(BUILD_SYSTEM)/aapt_flags.mk
+
# add --non-constant-id to prevent inlining constants.
# AAR needs text symbol file R.txt.
ifdef LOCAL_USE_AAPT2
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) --static-lib --no-static-lib-packages
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS := $(LOCAL_AAPT_FLAGS) --static-lib
+ifndef LOCAL_AAPT_NAMESPACES
+ $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_AAPT_FLAGS += --no-static-lib-packages
+endif
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_PRODUCT_AAPT_CONFIG :=
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_PRODUCT_AAPT_PREF_CONFIG :=
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_AAPT_CHARACTERISTICS :=
@@ -182,7 +187,6 @@
$(LOCAL_BUILT_MODULE): $(R_file_stamp)
$(java_source_list_file): $(R_file_stamp)
-$(foreach x,$(sharded_java_source_list_files),$(eval $(x): $(R_file_stamp)))
$(full_classes_compiled_jar): $(R_file_stamp)
$(full_classes_turbine_jar): $(R_file_stamp)
diff --git a/target/board/generic/BoardConfig.mk b/target/board/generic/BoardConfig.mk
index 67d019f..70c78a8 100644
--- a/target/board/generic/BoardConfig.mk
+++ b/target/board/generic/BoardConfig.mk
@@ -68,3 +68,5 @@
# Enable A/B update
TARGET_NO_RECOVERY := true
BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
+
+BOARD_VNDK_VERSION := current
\ No newline at end of file
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index e066e3a..be8ea39 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -99,3 +99,5 @@
# Enable A/B update
TARGET_NO_RECOVERY := true
BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
+
+BOARD_VNDK_VERSION := current
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 3a0a788..7ce1ec8 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -159,6 +159,7 @@
import os.path
import shlex
import shutil
+import struct
import subprocess
import sys
import tempfile
@@ -955,8 +956,15 @@
return metadata
-class StreamingPropertyFiles(object):
- """Computes the ota-streaming-property-files string for streaming A/B OTA.
+class PropertyFiles(object):
+ """A class that computes the property-files string for an OTA package.
+
+ A property-files string is a comma-separated string that contains the
+ offset/size info for an OTA package. The entries, which must be ZIP_STORED,
+ can be fetched directly with the package URL along with the offset/size info.
+ These strings can be used for streaming A/B OTAs, or allowing an updater to
+ download package metadata entry directly, without paying the cost of
+ downloading entire package.
Computing the final property-files string requires two passes. Because doing
the whole package signing (with signapk.jar) will possibly reorder the ZIP
@@ -966,7 +974,7 @@
This class provides functions to be called for each pass. The general flow is
as follows.
- property_files = StreamingPropertyFiles()
+ property_files = PropertyFiles()
# The first pass, which writes placeholders before doing initial signing.
property_files.Compute()
SignOutput()
@@ -981,17 +989,9 @@
"""
def __init__(self):
- self.required = (
- # payload.bin and payload_properties.txt must exist.
- 'payload.bin',
- 'payload_properties.txt',
- )
- self.optional = (
- # care_map.txt is available only if dm-verity is enabled.
- 'care_map.txt',
- # compatibility.zip is available only if target supports Treble.
- 'compatibility.zip',
- )
+ self.name = None
+ self.required = ()
+ self.optional = ()
def Compute(self, input_zip):
"""Computes and returns a property-files string with placeholders.
@@ -1064,6 +1064,7 @@
return '%s:%d:%d' % (os.path.basename(name), offset, size)
tokens = []
+ tokens.extend(self._GetPrecomputed(zip_file))
for entry in self.required:
tokens.append(ComputeEntryOffsetSize(entry))
for entry in self.optional:
@@ -1082,8 +1083,127 @@
return ','.join(tokens)
+ def _GetPrecomputed(self, input_zip):
+ """Computes the additional tokens to be included into the property-files.
-def FinalizeMetadata(metadata, input_file, output_file):
+ This applies to tokens without actual ZIP entries, such as
+ payload_metadadata.bin. We want to expose the offset/size to updaters, so
+ that they can download the payload metadata directly with the info.
+
+ Args:
+ input_zip: The input zip file.
+
+ Returns:
+ A list of strings (tokens) to be added to the property-files string.
+ """
+ # pylint: disable=no-self-use
+ # pylint: disable=unused-argument
+ return []
+
+
+class StreamingPropertyFiles(PropertyFiles):
+ """A subclass for computing the property-files for streaming A/B OTAs."""
+
+ def __init__(self):
+ super(StreamingPropertyFiles, self).__init__()
+ self.name = 'ota-streaming-property-files'
+ self.required = (
+ # payload.bin and payload_properties.txt must exist.
+ 'payload.bin',
+ 'payload_properties.txt',
+ )
+ self.optional = (
+ # care_map.txt is available only if dm-verity is enabled.
+ 'care_map.txt',
+ # compatibility.zip is available only if target supports Treble.
+ 'compatibility.zip',
+ )
+
+
+class AbOtaPropertyFiles(StreamingPropertyFiles):
+ """The property-files for A/B OTA that includes payload_metadata.bin info.
+
+ Since P, we expose one more token (aka property-file), in addition to the ones
+ for streaming A/B OTA, for a virtual entry of 'payload_metadata.bin'.
+ 'payload_metadata.bin' is the header part of a payload ('payload.bin'), which
+ doesn't exist as a separate ZIP entry, but can be used to verify if the
+ payload can be applied on the given device.
+
+ For backward compatibility, we keep both of the 'ota-streaming-property-files'
+ and the newly added 'ota-property-files' in P. The new token will only be
+ available in 'ota-property-files'.
+ """
+
+ def __init__(self):
+ super(AbOtaPropertyFiles, self).__init__()
+ self.name = 'ota-property-files'
+
+ def _GetPrecomputed(self, input_zip):
+ offset, size = self._GetPayloadMetadataOffsetAndSize(input_zip)
+ return ['payload_metadata.bin:{}:{}'.format(offset, size)]
+
+ @staticmethod
+ def _GetPayloadMetadataOffsetAndSize(input_zip):
+ """Computes the offset and size of the payload metadata for a given package.
+
+ (From system/update_engine/update_metadata.proto)
+ A delta update file contains all the deltas needed to update a system from
+ one specific version to another specific version. The update format is
+ represented by this struct pseudocode:
+
+ struct delta_update_file {
+ char magic[4] = "CrAU";
+ uint64 file_format_version;
+ uint64 manifest_size; // Size of protobuf DeltaArchiveManifest
+
+ // Only present if format_version > 1:
+ uint32 metadata_signature_size;
+
+ // The Bzip2 compressed DeltaArchiveManifest
+ char manifest[metadata_signature_size];
+
+ // The signature of the metadata (from the beginning of the payload up to
+ // this location, not including the signature itself). This is a
+ // serialized Signatures message.
+ char medatada_signature_message[metadata_signature_size];
+
+ // Data blobs for files, no specific format. The specific offset
+ // and length of each data blob is recorded in the DeltaArchiveManifest.
+ struct {
+ char data[];
+ } blobs[];
+
+ // These two are not signed:
+ uint64 payload_signatures_message_size;
+ char payload_signatures_message[];
+ };
+
+ 'payload-metadata.bin' contains all the bytes from the beginning of the
+ payload, till the end of 'medatada_signature_message'.
+ """
+ payload_info = input_zip.getinfo('payload.bin')
+ payload_offset = payload_info.header_offset + len(payload_info.FileHeader())
+ payload_size = payload_info.file_size
+
+ with input_zip.open('payload.bin', 'r') as payload_fp:
+ header_bin = payload_fp.read(24)
+
+ # network byte order (big-endian)
+ header = struct.unpack("!IQQL", header_bin)
+
+ # 'CrAU'
+ magic = header[0]
+ assert magic == 0x43724155, "Invalid magic: {:x}".format(magic)
+
+ manifest_size = header[2]
+ metadata_signature_size = header[3]
+ metadata_total = 24 + manifest_size + metadata_signature_size
+ assert metadata_total < payload_size
+
+ return (payload_offset, metadata_total)
+
+
+def FinalizeMetadata(metadata, input_file, output_file, needed_property_files):
"""Finalizes the metadata and signs an A/B OTA package.
In order to stream an A/B OTA package, we need 'ota-streaming-property-files'
@@ -1101,14 +1221,14 @@
input_file: The input ZIP filename that doesn't contain the package METADATA
entry yet.
output_file: The final output ZIP filename.
+ needed_property_files: The list of PropertyFiles' to be generated.
"""
output_zip = zipfile.ZipFile(
input_file, 'a', compression=zipfile.ZIP_DEFLATED)
- property_files = StreamingPropertyFiles()
-
# Write the current metadata entry with placeholders.
- metadata['ota-streaming-property-files'] = property_files.Compute(output_zip)
+ for property_files in needed_property_files:
+ metadata[property_files.name] = property_files.Compute(output_zip)
WriteMetadata(metadata, output_zip)
common.ZipClose(output_zip)
@@ -1122,14 +1242,14 @@
# Open the signed zip. Compute the final metadata that's needed for streaming.
with zipfile.ZipFile(prelim_signing, 'r') as prelim_signing_zip:
- expected_length = len(metadata['ota-streaming-property-files'])
- metadata['ota-streaming-property-files'] = property_files.Finalize(
- prelim_signing_zip, expected_length)
+ for property_files in needed_property_files:
+ metadata[property_files.name] = property_files.Finalize(
+ prelim_signing_zip, len(metadata[property_files.name]))
# Replace the METADATA entry.
common.ZipDelete(prelim_signing, METADATA_NAME)
- output_zip = zipfile.ZipFile(prelim_signing, 'a',
- compression=zipfile.ZIP_DEFLATED)
+ output_zip = zipfile.ZipFile(
+ prelim_signing, 'a', compression=zipfile.ZIP_DEFLATED)
WriteMetadata(metadata, output_zip)
common.ZipClose(output_zip)
@@ -1138,8 +1258,8 @@
# Reopen the final signed zip to double check the streaming metadata.
with zipfile.ZipFile(output_file, 'r') as output_zip:
- property_files.Verify(
- output_zip, metadata['ota-streaming-property-files'].strip())
+ for property_files in needed_property_files:
+ property_files.Verify(output_zip, metadata[property_files.name].strip())
def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
@@ -1555,7 +1675,15 @@
# FinalizeMetadata().
common.ZipClose(output_zip)
- FinalizeMetadata(metadata, staging_file, output_file)
+ # AbOtaPropertyFiles intends to replace StreamingPropertyFiles, as it covers
+ # all the info of the latter. However, system updaters and OTA servers need to
+ # take time to switch to the new flag. We keep both of the flags for
+ # P-timeframe, and will remove StreamingPropertyFiles in later release.
+ needed_property_files = (
+ AbOtaPropertyFiles(),
+ StreamingPropertyFiles(),
+ )
+ FinalizeMetadata(metadata, staging_file, output_file, needed_property_files)
def main(argv):
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index c8e87bf..4c0b890 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -17,17 +17,18 @@
import copy
import os
import os.path
+import subprocess
import unittest
import zipfile
import common
import test_utils
from ota_from_target_files import (
- _LoadOemDicts, BuildInfo, GetPackageMetadata,
+ _LoadOemDicts, AbOtaPropertyFiles, BuildInfo, GetPackageMetadata,
GetTargetFilesZipForSecondaryImages,
GetTargetFilesZipWithoutPostinstallConfig,
- Payload, PayloadSigner, POSTINSTALL_CONFIG, StreamingPropertyFiles,
- WriteFingerprintAssertion)
+ Payload, PayloadSigner, POSTINSTALL_CONFIG, PropertyFiles,
+ StreamingPropertyFiles, WriteFingerprintAssertion)
def construct_target_files(secondary=False):
@@ -590,7 +591,23 @@
self.assertNotIn(POSTINSTALL_CONFIG, verify_zip.namelist())
-class StreamingPropertyFilesTest(unittest.TestCase):
+class TestPropertyFiles(PropertyFiles):
+ """A class that extends PropertyFiles for testing purpose."""
+
+ def __init__(self):
+ super(TestPropertyFiles, self).__init__()
+ self.name = 'ota-test-property-files'
+ self.required = (
+ 'required-entry1',
+ 'required-entry2',
+ )
+ self.optional = (
+ 'optional-entry1',
+ 'optional-entry2',
+ )
+
+
+class PropertyFilesTest(unittest.TestCase):
def tearDown(self):
common.Cleanup()
@@ -607,7 +624,7 @@
return zip_file
@staticmethod
- def _parse_streaming_metadata_string(data):
+ def _parse_property_files_string(data):
result = {}
for token in data.split(','):
name, info = token.split(':', 1)
@@ -627,47 +644,57 @@
def test_Compute(self):
entries = (
- 'payload.bin',
- 'payload_properties.txt',
+ 'required-entry1',
+ 'required-entry2',
)
zip_file = self._construct_zip_package(entries)
- property_files = StreamingPropertyFiles()
+ property_files = TestPropertyFiles()
with zipfile.ZipFile(zip_file, 'r') as zip_fp:
- streaming_metadata = property_files.Compute(zip_fp)
+ property_files_string = property_files.Compute(zip_fp)
- tokens = self._parse_streaming_metadata_string(streaming_metadata)
+ tokens = self._parse_property_files_string(property_files_string)
self.assertEqual(3, len(tokens))
self._verify_entries(zip_file, tokens, entries)
- def test_Compute_withCareMapTxtAndCompatibilityZip(self):
+ def test_Compute_withOptionalEntries(self):
entries = (
- 'payload.bin',
- 'payload_properties.txt',
- 'care_map.txt',
- 'compatibility.zip',
+ 'required-entry1',
+ 'required-entry2',
+ 'optional-entry1',
+ 'optional-entry2',
)
zip_file = self._construct_zip_package(entries)
- property_files = StreamingPropertyFiles()
+ property_files = TestPropertyFiles()
with zipfile.ZipFile(zip_file, 'r') as zip_fp:
- streaming_metadata = property_files.Compute(zip_fp)
+ property_files_string = property_files.Compute(zip_fp)
- tokens = self._parse_streaming_metadata_string(streaming_metadata)
+ tokens = self._parse_property_files_string(property_files_string)
self.assertEqual(5, len(tokens))
self._verify_entries(zip_file, tokens, entries)
+ def test_Compute_missingRequiredEntry(self):
+ entries = (
+ 'required-entry2',
+ )
+ zip_file = self._construct_zip_package(entries)
+ property_files = TestPropertyFiles()
+ with zipfile.ZipFile(zip_file, 'r') as zip_fp:
+ self.assertRaises(KeyError, property_files.Compute, zip_fp)
+
def test_Finalize(self):
entries = [
- 'payload.bin',
- 'payload_properties.txt',
+ 'required-entry1',
+ 'required-entry2',
'META-INF/com/android/metadata',
]
zip_file = self._construct_zip_package(entries)
- property_files = StreamingPropertyFiles()
+ property_files = TestPropertyFiles()
with zipfile.ZipFile(zip_file, 'r') as zip_fp:
+ # pylint: disable=protected-access
raw_metadata = property_files._GetPropertyFilesString(
zip_fp, reserve_space=False)
streaming_metadata = property_files.Finalize(zip_fp, len(raw_metadata))
- tokens = self._parse_streaming_metadata_string(streaming_metadata)
+ tokens = self._parse_property_files_string(streaming_metadata)
self.assertEqual(3, len(tokens))
# 'META-INF/com/android/metadata' will be key'd as 'metadata' in the
@@ -677,15 +704,17 @@
def test_Finalize_assertReservedLength(self):
entries = (
- 'payload.bin',
- 'payload_properties.txt',
- 'care_map.txt',
+ 'required-entry1',
+ 'required-entry2',
+ 'optional-entry1',
+ 'optional-entry2',
'META-INF/com/android/metadata',
)
zip_file = self._construct_zip_package(entries)
- property_files = StreamingPropertyFiles()
+ property_files = TestPropertyFiles()
with zipfile.ZipFile(zip_file, 'r') as zip_fp:
# First get the raw metadata string (i.e. without padding space).
+ # pylint: disable=protected-access
raw_metadata = property_files._GetPropertyFilesString(
zip_fp, reserve_space=False)
raw_length = len(raw_metadata)
@@ -710,15 +739,17 @@
def test_Verify(self):
entries = (
- 'payload.bin',
- 'payload_properties.txt',
- 'care_map.txt',
+ 'required-entry1',
+ 'required-entry2',
+ 'optional-entry1',
+ 'optional-entry2',
'META-INF/com/android/metadata',
)
zip_file = self._construct_zip_package(entries)
- property_files = StreamingPropertyFiles()
+ property_files = TestPropertyFiles()
with zipfile.ZipFile(zip_file, 'r') as zip_fp:
# First get the raw metadata string (i.e. without padding space).
+ # pylint: disable=protected-access
raw_metadata = property_files._GetPropertyFilesString(
zip_fp, reserve_space=False)
@@ -730,6 +761,235 @@
AssertionError, property_files.Verify, zip_fp, raw_metadata + 'x')
+class StreamingPropertyFilesTest(PropertyFilesTest):
+ """Additional sanity checks specialized for StreamingPropertyFiles."""
+
+ def test_init(self):
+ property_files = StreamingPropertyFiles()
+ self.assertEqual('ota-streaming-property-files', property_files.name)
+ self.assertEqual(
+ (
+ 'payload.bin',
+ 'payload_properties.txt',
+ ),
+ property_files.required)
+ self.assertEqual(
+ (
+ 'care_map.txt',
+ 'compatibility.zip',
+ ),
+ property_files.optional)
+
+ def test_Compute(self):
+ entries = (
+ 'payload.bin',
+ 'payload_properties.txt',
+ 'care_map.txt',
+ 'compatibility.zip',
+ )
+ zip_file = self._construct_zip_package(entries)
+ property_files = StreamingPropertyFiles()
+ with zipfile.ZipFile(zip_file, 'r') as zip_fp:
+ property_files_string = property_files.Compute(zip_fp)
+
+ tokens = self._parse_property_files_string(property_files_string)
+ self.assertEqual(5, len(tokens))
+ self._verify_entries(zip_file, tokens, entries)
+
+ def test_Finalize(self):
+ entries = [
+ 'payload.bin',
+ 'payload_properties.txt',
+ 'care_map.txt',
+ 'compatibility.zip',
+ 'META-INF/com/android/metadata',
+ ]
+ zip_file = self._construct_zip_package(entries)
+ property_files = StreamingPropertyFiles()
+ with zipfile.ZipFile(zip_file, 'r') as zip_fp:
+ # pylint: disable=protected-access
+ raw_metadata = property_files._GetPropertyFilesString(
+ zip_fp, reserve_space=False)
+ streaming_metadata = property_files.Finalize(zip_fp, len(raw_metadata))
+ tokens = self._parse_property_files_string(streaming_metadata)
+
+ self.assertEqual(5, len(tokens))
+ # 'META-INF/com/android/metadata' will be key'd as 'metadata' in the
+ # streaming metadata.
+ entries[4] = 'metadata'
+ self._verify_entries(zip_file, tokens, entries)
+
+ def test_Verify(self):
+ entries = (
+ 'payload.bin',
+ 'payload_properties.txt',
+ 'care_map.txt',
+ 'compatibility.zip',
+ 'META-INF/com/android/metadata',
+ )
+ zip_file = self._construct_zip_package(entries)
+ property_files = StreamingPropertyFiles()
+ with zipfile.ZipFile(zip_file, 'r') as zip_fp:
+ # First get the raw metadata string (i.e. without padding space).
+ # pylint: disable=protected-access
+ raw_metadata = property_files._GetPropertyFilesString(
+ zip_fp, reserve_space=False)
+
+ # Should pass the test if verification passes.
+ property_files.Verify(zip_fp, raw_metadata)
+
+ # Or raise on verification failure.
+ self.assertRaises(
+ AssertionError, property_files.Verify, zip_fp, raw_metadata + 'x')
+
+
+class AbOtaPropertyFilesTest(PropertyFilesTest):
+ """Additional sanity checks specialized for AbOtaPropertyFiles."""
+
+ # The size for payload and metadata signature size.
+ SIGNATURE_SIZE = 256
+
+ def setUp(self):
+ self.testdata_dir = test_utils.get_testdata_dir()
+ self.assertTrue(os.path.exists(self.testdata_dir))
+
+ common.OPTIONS.wipe_user_data = False
+ common.OPTIONS.payload_signer = None
+ common.OPTIONS.payload_signer_args = None
+ common.OPTIONS.package_key = os.path.join(self.testdata_dir, 'testkey')
+ common.OPTIONS.key_passwords = {
+ common.OPTIONS.package_key : None,
+ }
+
+ def test_init(self):
+ property_files = AbOtaPropertyFiles()
+ self.assertEqual('ota-property-files', property_files.name)
+ self.assertEqual(
+ (
+ 'payload.bin',
+ 'payload_properties.txt',
+ ),
+ property_files.required)
+ self.assertEqual(
+ (
+ 'care_map.txt',
+ 'compatibility.zip',
+ ),
+ property_files.optional)
+
+ def test_GetPayloadMetadataOffsetAndSize(self):
+ target_file = construct_target_files()
+ payload = Payload()
+ payload.Generate(target_file)
+
+ payload_signer = PayloadSigner()
+ payload.Sign(payload_signer)
+
+ output_file = common.MakeTempFile(suffix='.zip')
+ with zipfile.ZipFile(output_file, 'w') as output_zip:
+ payload.WriteToZip(output_zip)
+
+ # Find out the payload metadata offset and size.
+ property_files = AbOtaPropertyFiles()
+ with zipfile.ZipFile(output_file) as input_zip:
+ # pylint: disable=protected-access
+ payload_offset, metadata_total = (
+ property_files._GetPayloadMetadataOffsetAndSize(input_zip))
+
+ # Read in the metadata signature directly.
+ with open(output_file, 'rb') as verify_fp:
+ verify_fp.seek(payload_offset + metadata_total - self.SIGNATURE_SIZE)
+ metadata_signature = verify_fp.read(self.SIGNATURE_SIZE)
+
+ # Now we extract the metadata hash via brillo_update_payload script, which
+ # will serve as the oracle result.
+ payload_sig_file = common.MakeTempFile(prefix="sig-", suffix=".bin")
+ metadata_sig_file = common.MakeTempFile(prefix="sig-", suffix=".bin")
+ cmd = ['brillo_update_payload', 'hash',
+ '--unsigned_payload', payload.payload_file,
+ '--signature_size', str(self.SIGNATURE_SIZE),
+ '--metadata_hash_file', metadata_sig_file,
+ '--payload_hash_file', payload_sig_file]
+ proc = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ stdoutdata, _ = proc.communicate()
+ self.assertEqual(
+ 0, proc.returncode,
+ 'Failed to run brillo_update_payload: {}'.format(stdoutdata))
+
+ signed_metadata_sig_file = payload_signer.Sign(metadata_sig_file)
+
+ # Finally we can compare the two signatures.
+ with open(signed_metadata_sig_file, 'rb') as verify_fp:
+ self.assertEqual(verify_fp.read(), metadata_signature)
+
+ @staticmethod
+ def _construct_zip_package_withValidPayload(with_metadata=False):
+ # Cannot use _construct_zip_package() since we need a "valid" payload.bin.
+ target_file = construct_target_files()
+ payload = Payload()
+ payload.Generate(target_file)
+
+ payload_signer = PayloadSigner()
+ payload.Sign(payload_signer)
+
+ zip_file = common.MakeTempFile(suffix='.zip')
+ with zipfile.ZipFile(zip_file, 'w') as zip_fp:
+ # 'payload.bin',
+ payload.WriteToZip(zip_fp)
+
+ # Other entries.
+ entries = ['care_map.txt', 'compatibility.zip']
+
+ # Put META-INF/com/android/metadata if needed.
+ if with_metadata:
+ entries.append('META-INF/com/android/metadata')
+
+ for entry in entries:
+ zip_fp.writestr(
+ entry, entry.replace('.', '-').upper(), zipfile.ZIP_STORED)
+
+ return zip_file
+
+ def test_Compute(self):
+ zip_file = self._construct_zip_package_withValidPayload()
+ property_files = AbOtaPropertyFiles()
+ with zipfile.ZipFile(zip_file, 'r') as zip_fp:
+ property_files_string = property_files.Compute(zip_fp)
+
+ tokens = self._parse_property_files_string(property_files_string)
+ # "6" indcludes the four entries above, one metadata entry, and one entry
+ # for payload-metadata.bin.
+ self.assertEqual(6, len(tokens))
+ self._verify_entries(
+ zip_file, tokens, ('care_map.txt', 'compatibility.zip'))
+
+ def test_Finalize(self):
+ zip_file = self._construct_zip_package_withValidPayload(with_metadata=True)
+ property_files = AbOtaPropertyFiles()
+ with zipfile.ZipFile(zip_file, 'r') as zip_fp:
+ # pylint: disable=protected-access
+ raw_metadata = property_files._GetPropertyFilesString(
+ zip_fp, reserve_space=False)
+ property_files_string = property_files.Finalize(zip_fp, len(raw_metadata))
+
+ tokens = self._parse_property_files_string(property_files_string)
+ # "6" indcludes the four entries above, one metadata entry, and one entry
+ # for payload-metadata.bin.
+ self.assertEqual(6, len(tokens))
+ self._verify_entries(
+ zip_file, tokens, ('care_map.txt', 'compatibility.zip'))
+
+ def test_Verify(self):
+ zip_file = self._construct_zip_package_withValidPayload(with_metadata=True)
+ property_files = AbOtaPropertyFiles()
+ with zipfile.ZipFile(zip_file, 'r') as zip_fp:
+ # pylint: disable=protected-access
+ raw_metadata = property_files._GetPropertyFilesString(
+ zip_fp, reserve_space=False)
+
+ property_files.Verify(zip_fp, raw_metadata)
+
+
class PayloadSignerTest(unittest.TestCase):
SIGFILE = 'sigfile.bin'