Merge "Use the final APK for dexpreopt when it's not stripped."
diff --git a/CleanSpec.mk b/CleanSpec.mk
index a4b7c26..8058d86 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -519,6 +519,9 @@
 
 $(call add-clean-step, find $(OUT_DIR)/target/product/mainline_arm64/system -type f -name "*.*dex" -print0 | xargs -0 rm -f)
 
+# Clean up aidegen
+$(call add-clean-step, rm -f $(HOST_OUT)/bin/aidegen)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index 6ba2be9..6226d6b 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -2921,7 +2921,12 @@
 endif # BOARD_AVB_ENABLE
 
 # -----------------------------------------------------------------
-# super partition image
+# Check image sizes <= size of super partition
+
+ifeq (,$(TARGET_BUILD_APPS))
+# Do not check for apps-only build
+
+ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION))
 
 # (1): list of items like "system", "vendor", "product", "product_services"
 # return: map each item into a command ( wrapped in $$() ) that reads the size
@@ -2929,75 +2934,10 @@
 $(foreach p,$(1),$(call read-image-prop-dictionary,$($(p)image_intermediates)/generated_$(p)_image_info.txt,$(p)_size))
 endef
 
-ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION))
-
-# BOARD_SUPER_PARTITION_SIZE must be defined to build super image.
-ifneq ($(BOARD_SUPER_PARTITION_SIZE),)
-
 define super-slot-suffix
 $(if $(filter true,$(AB_OTA_UPDATER)),$(if $(filter true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS)),,_a))
 endef
 
-# $(1): slot A suffix (_a or empty)
-# $(2): include images or not (true or empty)
-define build-superimage-target-args
-  $(if $(2), --sparse) \
-  --metadata-size 65536 \
-  --metadata-slots $(if $(filter true,$(AB_OTA_UPDATER)),2,1) \
-  --super-name $(BOARD_SUPER_PARTITION_METADATA_DEVICE) \
-  $(if $(filter true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS)), $(if $(filter true,$(AB_OTA_UPDATER)), --auto-slot-suffixing)) \
-  $(foreach device,$(BOARD_SUPER_PARTITION_BLOCK_DEVICES), \
-    --device $(device):$(BOARD_SUPER_PARTITION_$(call to-upper,$(device))_DEVICE_SIZE)) \
-  $(foreach group,$(BOARD_SUPER_PARTITION_GROUPS), \
-    --group $(group)$(1):$(BOARD_$(call to-upper,$(group))_SIZE) \
-    $(if $(1), --group $(group)_b:$(BOARD_$(call to-upper,$(group))_SIZE)) \
-    $(foreach name,$(BOARD_$(call to-upper,$(group))_PARTITION_LIST), \
-      --partition $(name)$(1):readonly:$(if $(2),$(call read-size-of-partitions,$(name)),0):$(group)$(1) \
-      $(if $(2), --image $(name)$(1)=$(call images-for-partitions,$(name))) \
-      $(if $(1), --partition $(name)_b:readonly:0:$(group)_b) \
-  ))
-endef
-
-# $(1): output image path
-# $(2): slot A suffix (_a or empty)
-# $(3): include images or not (true or empty)
-define build-superimage-target
-  $(LPMAKE) \
-    $(call build-superimage-target-args,$(2),$(3)) \
-    --output $(1)
-endef
-
-# For A/B devices, super partition always contains sub-partitions in the _a slot, because this
-# image should only be used for bootstrapping / initializing the device. When flashing the image,
-# bootloader fastboot should always mark _a slot as bootable.
-
-ifneq (true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS))
-INSTALLED_SUPERIMAGE_TARGET := $(PRODUCT_OUT)/super.img
-$(INSTALLED_SUPERIMAGE_TARGET): $(LPMAKE) $(call images-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))
-	$(call pretty,"Target super fs image: $@")
-	$(call build-superimage-target,$@,$(call super-slot-suffix),true)
-endif
-
-$(call dist-for-goals,dist_files,$(INSTALLED_SUPERIMAGE_TARGET))
-
-INSTALLED_SUPERIMAGE_EMPTY_TARGET := $(PRODUCT_OUT)/super_empty.img
-$(INSTALLED_SUPERIMAGE_EMPTY_TARGET): $(LPMAKE)
-	$(call pretty,"Target empty super fs image: $@")
-	$(call build-superimage-target,$@,$(call super-slot-suffix))
-
-$(call dist-for-goals,dist_files,$(INSTALLED_SUPERIMAGE_EMPTY_TARGET))
-
-endif # BOARD_SUPER_PARTITION_SIZE
-endif # PRODUCT_BUILD_SUPER_PARTITION
-
-# -----------------------------------------------------------------
-# Check image sizes <= size of super partition
-
-ifeq (,$(TARGET_BUILD_APPS))
-# Do not check for apps-only build
-
-ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION))
-
 droid_targets: check-all-partition-sizes
 
 .PHONY: check-all-partition-sizes check-all-partition-sizes-nodeps
@@ -3329,6 +3269,30 @@
 (cd $(1); find . -type d | sed 's,$$,/,'; find . \! -type d) | cut -c 3- | sort | sed 's,^,$(2),' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) -R "$(2)"
 endef
 
+# $(1): file
+define dump-dynamic-partitions-info
+  $(if $(filter true,$(PRODUCT_USE_DYNAMIC_PARTITIONS)), \
+    echo "use_dynamic_partitions=true" >> $(1))
+  $(if $(filter true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS)), \
+    echo "dynamic_partition_retrofit=true" >> $(1))
+  echo "lpmake=$(notdir $(LPMAKE))" >> $(1)
+  $(if $(filter true,$(PRODUCT_BUILD_SUPER_PARTITION)), $(if $(BOARD_SUPER_PARTITION_SIZE), \
+    echo "build_super_partition=true" >> $(1)))
+  echo "super_metadata_device=$(BOARD_SUPER_PARTITION_METADATA_DEVICE)" >> $(1)
+  $(if $(BOARD_SUPER_PARTITION_BLOCK_DEVICES), \
+    echo "super_block_devices=$(BOARD_SUPER_PARTITION_BLOCK_DEVICES)" >> $(1))
+  $(foreach device,$(BOARD_SUPER_PARTITION_BLOCK_DEVICES), \
+    echo "super_$(device)_device_size=$(BOARD_SUPER_PARTITION_$(call to-upper,$(device))_DEVICE_SIZE)" >> $(1);)
+  $(if $(BOARD_SUPER_PARTITION_PARTITION_LIST), \
+    echo "dynamic_partition_list=$(BOARD_SUPER_PARTITION_PARTITION_LIST)" >> $(1))
+  $(if $(BOARD_SUPER_PARTITION_GROUPS),
+    echo "super_partition_groups=$(BOARD_SUPER_PARTITION_GROUPS)" >> $(1))
+  $(foreach group,$(BOARD_SUPER_PARTITION_GROUPS), \
+    echo "super_$(group)_group_size=$(BOARD_$(call to-upper,$(group))_SIZE)" >> $(1); \
+    $(if $(BOARD_$(call to-upper,$(group))_PARTITION_LIST), \
+      echo "super_$(group)_partition_list=$(BOARD_$(call to-upper,$(group))_PARTITION_LIST)" >> $(1);))
+endef
+
 # Depending on the various images guarantees that the underlying
 # directories are up-to-date.
 $(BUILT_TARGET_FILES_PACKAGE): \
@@ -3644,6 +3608,7 @@
 endif # BOARD_AVB_DTBO_KEY_PATH
 endif # BOARD_AVB_ENABLE
 endif # BOARD_PREBUILT_DTBOIMAGE
+	$(call dump-dynamic-partitions-info,$(zip_root)/META/misc_info.txt)
 	@# The radio images in BOARD_PACK_RADIOIMAGES will be additionally copied from RADIO/ into
 	@# IMAGES/, which then will be added into <product>-img.zip. Such images must be listed in
 	@# INSTALLED_RADIOIMAGE_TARGET.
@@ -3689,24 +3654,6 @@
 ifdef BUILT_VENDOR_MATRIX
 	$(hide) cp $(BUILT_VENDOR_MATRIX) $(zip_root)/META/vendor_matrix.xml
 endif
-ifeq ($(PRODUCT_USE_DYNAMIC_PARTITIONS),true)
-	$(hide) echo "use_dynamic_partitions=true" >> $(zip_root)/META/misc_info.txt
-endif
-ifeq ($(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS),true)
-	$(hide) echo "dynamic_partition_retrofit=true" >> $(zip_root)/META/misc_info.txt
-endif
-ifneq ($(BOARD_SUPER_PARTITION_SIZE),)
-	$(hide) echo "lpmake=$(notdir $(LPMAKE))" >> $(zip_root)/META/misc_info.txt
-	$(hide) echo -n "lpmake_args=" >> $(zip_root)/META/misc_info.txt
-	$(hide) echo $(call build-superimage-target-args,$(call super-slot-suffix)) \
-	    >> $(zip_root)/META/misc_info.txt
-endif
-ifneq ($(BOARD_SUPER_PARTITION_BLOCK_DEVICES),)
-	$(hide) echo "super_block_devices=$(BOARD_SUPER_PARTITION_BLOCK_DEVICES)" >> $(zip_root)/META/misc_info.txt
-endif
-ifneq ($(BOARD_SUPER_PARTITION_PARTITION_LIST),)
-	$(hide) echo "dynamic_partition_list=$(BOARD_SUPER_PARTITION_PARTITION_LIST)" >> $(zip_root)/META/misc_info.txt
-endif
 ifneq ($(BOARD_SUPER_PARTITION_GROUPS),)
 	$(hide) echo "super_partition_groups=$(BOARD_SUPER_PARTITION_GROUPS)" > $(zip_root)/META/dynamic_partitions_info.txt
 	$(foreach group,$(BOARD_SUPER_PARTITION_GROUPS), \
@@ -3975,6 +3922,41 @@
 endif # TARGET_BUILD_APPS
 
 # -----------------------------------------------------------------
+# super partition image
+
+ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION))
+
+# BOARD_SUPER_PARTITION_SIZE must be defined to build super image.
+ifneq ($(BOARD_SUPER_PARTITION_SIZE),)
+
+ifneq (true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS))
+INSTALLED_SUPERIMAGE_TARGET := $(PRODUCT_OUT)/super.img
+$(INSTALLED_SUPERIMAGE_TARGET): extracted_input_target_files := $(patsubst %.zip,%,$(BUILT_TARGET_FILES_PACKAGE))
+$(INSTALLED_SUPERIMAGE_TARGET): $(LPMAKE) $(BUILT_TARGET_FILES_PACKAGE) $(BUILD_SUPER_IMAGE)
+	$(call pretty,"Target super fs image: $@")
+	$(BUILD_SUPER_IMAGE) -v $(extracted_input_target_files) $@
+endif
+
+$(call dist-for-goals,dist_files,$(INSTALLED_SUPERIMAGE_TARGET))
+
+INSTALLED_SUPERIMAGE_EMPTY_TARGET := $(PRODUCT_OUT)/super_empty.img
+$(INSTALLED_SUPERIMAGE_EMPTY_TARGET): intermediates := $(call intermediates-dir-for,PACKAGING,super_empty)
+$(INSTALLED_SUPERIMAGE_EMPTY_TARGET): $(LPMAKE) $(BUILD_SUPER_IMAGE)
+	$(call pretty,"Target empty super fs image: $@")
+	mkdir -p $(intermediates)
+	rm -rf $(intermediates)/misc_info.txt
+	$(call dump-dynamic-partitions-info,$(intermediates)/misc_info.txt)
+ifeq ($(AB_OTA_UPDATER),true)
+	$(hide) echo "ab_update=true" >> $(intermediates)/misc_info.txt
+endif
+	$(BUILD_SUPER_IMAGE) -v $(intermediates)/misc_info.txt $@
+
+$(call dist-for-goals,dist_files,$(INSTALLED_SUPERIMAGE_EMPTY_TARGET))
+
+endif # BOARD_SUPER_PARTITION_SIZE != ""
+endif # PRODUCT_BUILD_SUPER_PARTITION == "true"
+
+# -----------------------------------------------------------------
 # dalvik something
 .PHONY: dalvikfiles
 dalvikfiles: $(INTERNAL_DALVIK_MODULES)
diff --git a/core/build_rro_package.mk b/core/build_rro_package.mk
index ffefb9c..0b4a0c4 100644
--- a/core/build_rro_package.mk
+++ b/core/build_rro_package.mk
@@ -15,11 +15,23 @@
   $(error runtime resource overlay package should not contain sources)
 endif
 
-ifeq ($(LOCAL_RRO_THEME),)
-  LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/overlay
+partition :=
+ifeq ($(LOCAL_ODM_MODULE),true)
+  partition := $(TARGET_OUT_ODM)
+else ifeq ($(LOCAL_PRODUCT_MODULE),true)
+  partition := $(TARGET_OUT_PRODUCT)
+else ifeq ($(LOCAL_PRODUCT_SERVICES_MODULE),true)
+  partition := $(TARGET_OUT_PRODUCT_SERVICES)
 else
-  LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/overlay/$(LOCAL_RRO_THEME)
+  partition := $(TARGET_OUT_VENDOR)
 endif
 
-include $(BUILD_SYSTEM)/package.mk
+ifeq ($(LOCAL_RRO_THEME),)
+  LOCAL_MODULE_PATH := $(partition)/overlay
+else
+  LOCAL_MODULE_PATH := $(partition)/overlay/$(LOCAL_RRO_THEME)
+endif
 
+partition :=
+
+include $(BUILD_SYSTEM)/package.mk
diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index 4503062..c31906a 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -34,7 +34,7 @@
 endif
 
 KNOWN_ARMv8_CORES := cortex-a53 cortex-a53.a57 cortex-a55 cortex-a73 cortex-a75 cortex-a76
-KNOWN_ARMv8_CORES += kryo denver64 exynos-m1 exynos-m2
+KNOWN_ARMv8_CORES += kryo exynos-m1 exynos-m2
 
 KNOWN_ARMv82a_CORES := cortex-a55 cortex-a75
 
diff --git a/core/config.mk b/core/config.mk
index 73f2a4c..b7c2ed1 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -698,6 +698,7 @@
 FAT16COPY := build/make/tools/fat16copy.py
 CHECK_LINK_TYPE := build/make/tools/check_link_type.py
 LPMAKE := $(HOST_OUT_EXECUTABLES)/lpmake$(HOST_EXECUTABLE_SUFFIX)
+BUILD_SUPER_IMAGE := build/make/tools/releasetools/build_super_image.py
 
 PROGUARD := external/proguard/bin/proguard.sh
 JAVATAGS := build/make/tools/java-event-log-tags.py
@@ -1202,10 +1203,7 @@
 
 INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-public-list.txt
 INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-private-list.txt
-INTERNAL_PLATFORM_HIDDENAPI_WHITELIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-whitelist.txt
-INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-light-greylist.txt
-INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-dark-greylist.txt
-INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-blacklist.txt
+INTERNAL_PLATFORM_HIDDENAPI_FLAGS := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-flags.csv
 INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/hiddenapi-greylist.csv
 
 # Missing optional uses-libraries so that the platform doesn't create build rules that depend on
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index fcf527e..7b4015e 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -176,6 +176,7 @@
 ifneq ($(filter hwaddress,$(my_sanitize)),)
   my_sanitize := $(filter-out address,$(my_sanitize))
   my_sanitize := $(filter-out thread,$(my_sanitize))
+  my_sanitize := $(filter-out cfi,$(my_sanitize))
 endif
 
 ifneq ($(filter hwaddress,$(my_sanitize)),)
@@ -414,3 +415,14 @@
     endif
   endif
 endif
+
+# http://b/119329758, Android core does not boot up with this sanitizer yet.
+# Previously sanitized modules might not pass new implicit-integer-sign-change check.
+# Disable this check unless it has been explicitly specified.
+ifneq ($(findstring fsanitize,$(my_cflags)),)
+  ifneq ($(findstring integer,$(my_cflags)),)
+    ifeq ($(findstring sanitize=implicit-integer-sign-change,$(my_cflags)),)
+      my_cflags += -fno-sanitize=implicit-integer-sign-change
+    endif
+  endif
+endif
diff --git a/core/cxx_stl_setup.mk b/core/cxx_stl_setup.mk
index 3590079..25fd642 100644
--- a/core/cxx_stl_setup.mk
+++ b/core/cxx_stl_setup.mk
@@ -51,8 +51,8 @@
 darwin_dynamic_gcclibs := -lc -lSystem
 darwin_static_gcclibs := NO_STATIC_HOST_BINARIES_ON_DARWIN
 windows_dynamic_gcclibs := \
-    -Wl,--start-group -lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcr110 \
-    -lmsvcrt -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 -lpsapi \
+    -Wl,--start-group -lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex \
+    -lmsvcrt -lucrt -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 -lpsapi \
     -Wl,--end-group
 windows_static_gcclibs := NO_STATIC_HOST_BINARIES_ON_WINDOWS
 
diff --git a/core/definitions.mk b/core/definitions.mk
index 0d4b6c4..50c26d3 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2374,10 +2374,7 @@
 endef
 appcompat-files = \
   art/tools/veridex/appcompat.sh \
-  $(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST) \
-  $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \
-  $(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) \
-  $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST) \
+  $(INTERNAL_PLATFORM_HIDDENAPI_FLAGS) \
   $(HOST_OUT_EXECUTABLES)/veridex \
   $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/core_dex_intermediates/classes.dex \
   $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/oahl_dex_intermediates/classes.dex
@@ -2671,17 +2668,13 @@
 # Java semantics of the result dex bytecode. Use at own risk.
 ifneq ($(UNSAFE_DISABLE_HIDDENAPI_FLAGS),true)
 define hiddenapi-copy-dex-files
-$(2): $(1) $(HIDDENAPI) $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \
-      $(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)
+$(2): $(1) $(HIDDENAPI) $(INTERNAL_PLATFORM_HIDDENAPI_FLAGS)
 	@rm -rf $(dir $(2))
 	@mkdir -p $(dir $(2))
 	for INPUT_DEX in `find $(dir $(1)) -maxdepth 1 -name "classes*.dex" | sort`; do \
 	    echo "--input-dex=$$$${INPUT_DEX}"; \
 	    echo "--output-dex=$(dir $(2))/`basename $$$${INPUT_DEX}`"; \
-	done | xargs $(HIDDENAPI) encode \
-	    --light-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \
-	    --dark-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) \
-	    --blacklist=$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)
+	done | xargs $(HIDDENAPI) encode --api-flags=$(INTERNAL_PLATFORM_HIDDENAPI_FLAGS)
 
 $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): $(1)
 $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST): PRIVATE_DEX_INPUTS := $$(PRIVATE_DEX_INPUTS) $(1)
@@ -2697,27 +2690,20 @@
 endif  # UNSAFE_DISABLE_HIDDENAPI_FLAGS
 
 # Generate a greylist.txt from a classes.jar
-define hiddenapi-generate-greylist-txt
+define hiddenapi-generate-csv
 ifneq (,$(wildcard frameworks/base))
 # Only generate this target if we're in a tree with frameworks/base present.
-$(3): .KATI_IMPLICIT_OUTPUTS := $(2) $(4)
-# For now, write P & Q blacklist to single file until runtime support is finished
+$(2): $(1) $(CLASS2GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST)
+	$(CLASS2GREYLIST) --public-api-list $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) $(1) \
+	    --write-flags-csv $(2)
+
 $(3): $(1) $(CLASS2GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST)
 	$(CLASS2GREYLIST) --public-api-list $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) $(1) \
-	    --write-whitelist $(2) \
-	    --write-greylist none,28:$(3) \
-	    --write-greylist 26:$(4)
+	    --write-metadata-csv $(3)
 
-$(5): $(1) $(CLASS2GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST)
-	$(CLASS2GREYLIST) --public-api-list $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) $(1) \
-	    --write-metadata-csv $(5)
+$(INTERNAL_PLATFORM_HIDDENAPI_FLAGS): $(2)
+$(INTERNAL_PLATFORM_HIDDENAPI_FLAGS): PRIVATE_FLAGS_INPUTS := $$(PRIVATE_FLAGS_INPUTS) $(2)
 
-$(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): $(2) $(3) $(4)
-$(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): \
-    PRIVATE_WHITELIST_INPUTS := $$(PRIVATE_WHITELIST_INPUTS) $(2)
-$(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): \
-    PRIVATE_GREYLIST_INPUTS := $$(PRIVATE_GREYLIST_INPUTS) $(3)
-    PRIVATE_DARKGREYLIST_INPUTS := $$(PRIVATE_DARKGREYLIST_INPUTS) $(4)
 $(INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA): $(5)
 $(INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA): \
     PRIVATE_METADATA_INPUTS := $$(PRIVATE_METADATA_INPUTS) $(5)
@@ -2752,6 +2738,14 @@
 ###########################################################
 ## Commands to call R8
 ###########################################################
+
+# Use --debug flag for eng builds by default
+ifeq (eng,$(TARGET_BUILD_VARIANT))
+R8_DEBUG_MODE := --debug
+else
+R8_DEBUG_MODE :=
+endif
+
 define transform-jar-to-dex-r8
 @echo R8: $@
 $(hide) rm -f $(PRIVATE_PROGUARD_DICTIONARY)
@@ -2759,6 +2753,7 @@
     --min-api $(PRIVATE_MIN_SDK_VERSION) \
     --no-data-resources \
     --force-proguard-compatibility --output $(subst classes.dex,,$@) \
+    $(R8_DEBUG_MODE) \
     $(PRIVATE_PROGUARD_FLAGS) \
     $(addprefix -injars , $(PRIVATE_EXTRA_INPUT_JAR)) \
     $(PRIVATE_DX_FLAGS)
diff --git a/core/java.mk b/core/java.mk
index 30571b7..932a421 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -74,10 +74,8 @@
 built_dex_hiddenapi := $(intermediates.COMMON)/dex-hiddenapi/classes.dex
 full_classes_stubs_jar := $(intermediates.COMMON)/stubs.jar
 java_source_list_file := $(intermediates.COMMON)/java-source-list
-hiddenapi_whitelist_txt := $(intermediates.COMMON)/hiddenapi/whitelist.txt
-hiddenapi_greylist_txt := $(intermediates.COMMON)/hiddenapi/greylist.txt
-hiddenapi_darkgreylist_txt := $(intermediates.COMMON)/hiddenapi/darkgreylist.txt
-hiddenapi_greylist_metadata_csv := $(intermediates.COMMON)/hiddenapi/greylist.csv
+hiddenapi_flags_csv := $(intermediates.COMMON)/hiddenapi/flags.csv
+hiddenapi_metadata_csv := $(intermediates.COMMON)/hiddenapi/greylist.csv
 
 ifeq ($(LOCAL_MODULE_CLASS)$(LOCAL_SRC_FILES)$(LOCAL_STATIC_JAVA_LIBRARIES)$(LOCAL_SOURCE_FILES_ALL_GENERATED),APPS)
 # If this is an apk without any Java code (e.g. framework-res), we should skip compiling Java.
@@ -508,8 +506,8 @@
   # dex later on. The difference is academic currently, as we don't proguard any
   # bootclasspath code at the moment. If we were to do that, we should add keep
   # rules for all members with the @UnsupportedAppUsage annotation.
-  $(eval $(call hiddenapi-generate-greylist-txt, $(full_classes_pre_proguard_jar),$(hiddenapi_whitelist_txt),$(hiddenapi_greylist_txt),$(hiddenapi_darkgreylist_txt),$(hiddenapi_greylist_metadata_csv)))
-  LOCAL_INTERMEDIATE_TARGETS += $(hiddenapi_whitelist_txt) $(hiddenapi_greylist_txt) $(hiddenapi_darkgreylist_txt) $(hiddenapi_greylist_metadata_csv)
+  $(eval $(call hiddenapi-generate-csv, $(full_classes_pre_proguard_jar),$(hiddenapi_flags_csv),$(hiddenapi_metadata_csv)))
+  LOCAL_INTERMEDIATE_TARGETS += $(hiddenapi_flags_csv) $(hiddenapi_metadata_csv)
   $(eval $(call hiddenapi-copy-dex-files,$(built_dex_intermediate),$(built_dex_hiddenapi)))
   built_dex_copy_from := $(built_dex_hiddenapi)
 else # !is_boot_jar
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 48dd228..279a612 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -96,7 +96,6 @@
 $(call add_json_bool, ArtUseReadBarrier,                 $(call invert_bool,$(filter false,$(PRODUCT_ART_USE_READ_BARRIER))))
 $(call add_json_bool, Binder32bit,                       $(BINDER32BIT))
 $(call add_json_str,  BtConfigIncludeDir,                $(BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR))
-$(call add_json_bool, Device_uses_hwc2,                  $(filter true,$(TARGET_USES_HWC2)))
 $(call add_json_list, DeviceKernelHeaders,               $(TARGET_PROJECT_SYSTEM_INCLUDES))
 $(call add_json_bool, DevicePrefer32BitApps,             $(filter true,$(TARGET_PREFER_32_BIT_APPS)))
 $(call add_json_bool, DevicePrefer32BitExecutables,      $(filter true,$(TARGET_PREFER_32_BIT_EXECUTABLES)))
diff --git a/core/soong_java_prebuilt.mk b/core/soong_java_prebuilt.mk
index 3e6b261..1642ba7 100644
--- a/core/soong_java_prebuilt.mk
+++ b/core/soong_java_prebuilt.mk
@@ -19,10 +19,8 @@
 full_classes_pre_proguard_jar := $(intermediates.COMMON)/classes-pre-proguard.jar
 full_classes_header_jar := $(intermediates.COMMON)/classes-header.jar
 common_javalib.jar := $(intermediates.COMMON)/javalib.jar
-hiddenapi_whitelist_txt := $(intermediates.COMMON)/hiddenapi/whitelist.txt
-hiddenapi_greylist_txt := $(intermediates.COMMON)/hiddenapi/greylist.txt
-hiddenapi_darkgreylist_txt := $(intermediates.COMMON)/hiddenapi/darkgreylist.txt
-hiddenapi_greylist_metadata_csv := $(intermediates.COMMON)/hiddenapi/greylist.csv
+hiddenapi_flags_csv := $(intermediates.COMMON)/hiddenapi/flags.csv
+hiddenapi_metadata_csv := $(intermediates.COMMON)/hiddenapi/greylist.csv
 
 $(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(full_classes_jar)))
 $(eval $(call copy-one-file,$(LOCAL_PREBUILT_MODULE_FILE),$(full_classes_pre_proguard_jar)))
@@ -80,7 +78,7 @@
         # We use full_classes_jar here, which is the post-proguard jar (on the basis that we also
         # have a full_classes_pre_proguard_jar). This is consistent with the equivalent code in
         # java.mk.
-        $(eval $(call hiddenapi-generate-greylist-txt,$(full_classes_jar),$(hiddenapi_whitelist_txt),$(hiddenapi_greylist_txt),$(hiddenapi_darkgreylist_txt),$(hiddenapi_greylist_metadata_csv)))
+        $(eval $(call hiddenapi-generate-csv,$(full_classes_jar),$(hiddenapi_flags_csv),$(hiddenapi_metadata_csv)))
         $(eval $(call hiddenapi-copy-soong-jar,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
       else # !is_boot_jar
         $(eval $(call copy-one-file,$(LOCAL_SOONG_DEX_JAR),$(common_javalib.jar)))
@@ -126,7 +124,7 @@
       # We use full_classes_jar here, which is the post-proguard jar (on the basis that we also
       # have a full_classes_pre_proguard_jar). This is consistent with the equivalent code in
       # java.mk.
-      $(eval $(call hiddenapi-generate-greylist-txt,$(full_classes_jar),$(hiddenapi_whitelist_txt),$(hiddenapi_greylist_txt),$(hiddenapi_darkgreylist_txt),$(hiddenapi_greylist_metadata_csv)))
+      $(eval $(call hiddenapi-generate-csv,$(full_classes_jar),$(hiddenapi_flags_csv),$(hiddenapi_metadata_csv)))
     endif
 
     $(eval $(call copy-one-file,$(full_classes_jar),$(LOCAL_BUILT_MODULE)))
diff --git a/envsetup.sh b/envsetup.sh
index 400e7f0..7e94748 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -1625,6 +1625,19 @@
     esac
 }
 
+function aidegen()
+{
+    # Always use the prebuilt version.
+    local host_os_arch=$(get_build_var HOST_PREBUILT_TAG)
+    case $host_os_arch in
+        linux-x86) "$(gettop)"/prebuilts/asuite/aidegen/linux-x86/aidegen "$@"
+        ;;
+    *)
+        echo "aidegen is not supported on your host arch: $host_os_arch"
+        ;;
+    esac
+}
+
 # Execute the contents of any vendorsetup.sh files we can find.
 function source_vendorsetup() {
     for dir in device vendor product; do
diff --git a/target/board/BoardConfigEmuCommon.mk b/target/board/BoardConfigEmuCommon.mk
index 69ae6f0..38f79fd 100644
--- a/target/board/BoardConfigEmuCommon.mk
+++ b/target/board/BoardConfigEmuCommon.mk
@@ -10,7 +10,6 @@
 # no hardware camera
 USE_CAMERA_STUB := true
 
-TARGET_USES_HWC2 := true
 NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
 
 # Build OpenGLES emulation guest and host libraries
diff --git a/target/board/BoardConfigGsiCommon.mk b/target/board/BoardConfigGsiCommon.mk
index dfa103a..73af020 100644
--- a/target/board/BoardConfigGsiCommon.mk
+++ b/target/board/BoardConfigGsiCommon.mk
@@ -1,14 +1,14 @@
 # BoardConfigGsiCommon.mk
 #
 # Common compile-time definitions for GSI
+# Builds upon the mainline config.
 #
 
-# The generic product target doesn't have any hardware-specific pieces.
-TARGET_NO_BOOTLOADER := true
-TARGET_NO_KERNEL := true
+include build/make/target/board/BoardConfigMainlineCommon.mk
 
-# GSIs always use ext4.
-TARGET_USERIMAGES_USE_EXT4 := true
+# This flag is set by mainline but isn't desired for GSI.
+BOARD_USES_SYSTEM_OTHER_ODEX :=
+
 # GSIs are historically released in sparse format.
 # Some vendors' bootloaders don't work properly with raw format images. So
 # we explicit specify this need below (even though it's the current default).
@@ -18,15 +18,12 @@
 BOARD_SYSTEMIMAGE_PARTITION_RESERVED_SIZE := 67108864
 
 # Android Verified Boot (AVB):
-#   1) Sets BOARD_AVB_ENABLE to sign the GSI image.
-#   2) Sets AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED (--flag 2) in
-#      vbmeta.img to disable AVB verification.
+#   Set AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED (--flag 2) in
+#   vbmeta.img to disable AVB verification.
 #
 # To disable AVB for GSI, use the vbmeta.img and the GSI together.
 # To enable AVB for GSI, include the GSI public key into the device-specific
 # vbmeta.img.
-BOARD_AVB_ENABLE := true
-BOARD_AVB_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
 BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --flag 2
 
 # Enable chain partition for system.
@@ -40,14 +37,6 @@
 # over those set by the vendor.
 TARGET_SYSTEM_PROP := build/make/target/board/gsi_system.prop
 endif
-BOARD_VNDK_VERSION := current
-
-# system-as-root is mandatory from Android P
-TARGET_NO_RECOVERY := true
-BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
-
-# 64 bits binder interface is mandatory from Android P
-TARGET_USES_64_BIT_BINDER := true
 
 # Android generic system image always create metadata partition
 BOARD_USES_METADATA_PARTITION := true
@@ -56,6 +45,3 @@
 # The partition size doesn't matter, just to make build pass.
 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_CACHEIMAGE_PARTITION_SIZE := 16777216
-
-# Audio: must using XML format for Treblized devices
-USE_XML_AUDIO_POLICY_CONF := 1
diff --git a/target/board/BoardConfigMainlineCommon.mk b/target/board/BoardConfigMainlineCommon.mk
new file mode 100644
index 0000000..ec3c74f
--- /dev/null
+++ b/target/board/BoardConfigMainlineCommon.mk
@@ -0,0 +1,28 @@
+# BoardConfigMainlineCommon.mk
+#
+# Common compile-time definitions for mainline images.
+
+# The generic product target doesn't have any hardware-specific pieces.
+TARGET_NO_BOOTLOADER := true
+TARGET_NO_KERNEL := true
+
+TARGET_USERIMAGES_USE_EXT4 := true
+
+# system-as-root is mandatory from Android P
+TARGET_NO_RECOVERY := true
+BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
+
+BOARD_VNDK_VERSION := current
+
+# Required flag for non-64 bit devices from P.
+TARGET_USES_64_BIT_BINDER := true
+
+# Puts odex files on system_other, as well as causing dex files not to get
+# stripped from APKs.
+BOARD_USES_SYSTEM_OTHER_ODEX := true
+
+# Audio: must using XML format for Treblized devices
+USE_XML_AUDIO_POLICY_CONF := 1
+
+BOARD_AVB_ENABLE := true
+BOARD_AVB_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
diff --git a/target/board/mainline_arm64/BoardConfig.mk b/target/board/mainline_arm64/BoardConfig.mk
index 936c5a0..521d976 100644
--- a/target/board/mainline_arm64/BoardConfig.mk
+++ b/target/board/mainline_arm64/BoardConfig.mk
@@ -24,8 +24,4 @@
 TARGET_2ND_CPU_ABI2 := armeabi
 TARGET_2ND_CPU_VARIANT := generic
 
-# Puts odex files on system_other, as well as causing dex files not to get
-# stripped from APKs.
-BOARD_USES_SYSTEM_OTHER_ODEX := true
-
-include build/make/target/board/BoardConfigGsiCommon.mk
+include build/make/target/board/BoardConfigMainlineCommon.mk
diff --git a/target/board/treble_common.mk b/target/board/treble_common.mk
index 9413a75..eda5b37 100644
--- a/target/board/treble_common.mk
+++ b/target/board/treble_common.mk
@@ -44,8 +44,6 @@
 # Android generic system image always create metadata partition
 BOARD_USES_METADATA_PARTITION := true
 
-# Generic AOSP image does NOT support HWC1
-TARGET_USES_HWC2 := true
 # Set emulator framebuffer display device buffer count to 3
 NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
 
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 2c53a6e..3d5c512 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -314,6 +314,8 @@
     adb_keys \
     apex.test.key \
     arping \
+    com.android.apex.test_package.key \
+    com.android.apex.test_package.preinstall.key \
     iotop \
     iw \
     logpersist.start \
diff --git a/target/product/mainline_system.mk b/target/product/mainline_system.mk
index e586f3c..c41e1d7 100644
--- a/target/product/mainline_system.mk
+++ b/target/product/mainline_system.mk
@@ -33,18 +33,19 @@
     Stk \
     TimeZoneUpdater \
 
+# Binaries
+PRODUCT_PACKAGES += llkd
+
 # OTA support
 PRODUCT_PACKAGES += \
     update_engine \
     update_verifier \
 
 # Wrapped net utils for /vendor access.
-PRODUCT_PACKAGES += \
-    netutils-wrapper-1.0 \
+PRODUCT_PACKAGES += netutils-wrapper-1.0
 
 # Charger images
-PRODUCT_PACKAGES += \
-    charger_res_images \
+PRODUCT_PACKAGES += charger_res_images
 
 # system_other support
 PRODUCT_PACKAGES += \
diff --git a/target/product/vndk/current.txt b/target/product/vndk/current.txt
index 47c2d41..e8f61a4 100644
--- a/target/product/vndk/current.txt
+++ b/target/product/vndk/current.txt
@@ -58,10 +58,13 @@
 VNDK-core: android.hardware.audio.common@2.0-util.so
 VNDK-core: android.hardware.audio.common@4.0.so
 VNDK-core: android.hardware.audio.common@4.0-util.so
+VNDK-core: android.hardware.audio.common@5.0.so
 VNDK-core: android.hardware.audio.effect@2.0.so
 VNDK-core: android.hardware.audio.effect@4.0.so
+VNDK-core: android.hardware.audio.effect@5.0.so
 VNDK-core: android.hardware.audio@2.0.so
 VNDK-core: android.hardware.audio@4.0.so
+VNDK-core: android.hardware.audio@5.0.so
 VNDK-core: android.hardware.authsecret@1.0.so
 VNDK-core: android.hardware.automotive.audiocontrol@1.0.so
 VNDK-core: android.hardware.automotive.evs@1.0.so
diff --git a/tools/fs_config/fs_config_generator.py b/tools/fs_config/fs_config_generator.py
index cd534ec..f7e3eb2 100755
--- a/tools/fs_config/fs_config_generator.py
+++ b/tools/fs_config/fs_config_generator.py
@@ -1108,9 +1108,14 @@
 
     _INCLUDE = '#include <private/android_filesystem_config.h>'
 
+    # Note that the android_id name field is of type 'const char[]' instead of
+    # 'const char*'.  While this seems less straightforward as we need to
+    # calculate the max length of all names, this allows the entire android_ids
+    # table to be placed in .rodata section instead of .data.rel.ro section,
+    # resulting in less memory pressure.
     _STRUCT_FS_CONFIG = textwrap.dedent("""
                          struct android_id_info {
-                             const char *name;
+                             const char name[%d];
                              unsigned aid;
                          };""")
 
@@ -1132,12 +1137,13 @@
     def __call__(self, args):
 
         hdr = AIDHeaderParser(args['hdrfile'])
+        max_name_length = max(len(aid.friendly) + 1 for aid in hdr.aids)
 
         print AIDArrayGen._GENERATED
         print
         print AIDArrayGen._INCLUDE
         print
-        print AIDArrayGen._STRUCT_FS_CONFIG
+        print AIDArrayGen._STRUCT_FS_CONFIG % max_name_length
         print
         print AIDArrayGen._OPEN_ID_ARRAY
 
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 139d257..669d87b 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -55,6 +55,7 @@
 import zipfile
 
 import build_image
+import build_super_image
 import common
 import rangelib
 import sparse_img
@@ -648,64 +649,15 @@
   """Create a super_empty.img and store it in output_zip."""
 
   img = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", "super_empty.img")
-  cmd = [OPTIONS.info_dict['lpmake']]
-  cmd += shlex.split(OPTIONS.info_dict['lpmake_args'].strip())
-  cmd += ['--output', img.name]
-  common.RunAndCheckOutput(cmd)
-
+  build_super_image.BuildSuperImage(OPTIONS.info_dict, img.name)
   img.Write()
 
 
 def AddSuperSplit(output_zip):
   """Create split super_*.img and store it in output_zip."""
 
-  def GetPartitionSizeFromImage(img):
-    try:
-      simg = sparse_img.SparseImage(img)
-      return simg.blocksize * simg.total_blocks
-    except ValueError:
-      return os.path.getsize(img)
-
-  def TransformPartitionArg(arg):
-    lst = arg.split(':')
-    # Because --auto-slot-suffixing for A/B, there is no need to remove suffix.
-    name = lst[0]
-    if name + '_size' in OPTIONS.info_dict:
-      size = str(OPTIONS.info_dict[name + '_size'])
-      logger.info("Using %s_size = %s", name, size)
-    else:
-      size = str(GetPartitionSizeFromImage(
-          os.path.join(OPTIONS.input_tmp, "IMAGES", '{}.img'.format(name))))
-      logger.info("Using size of prebuilt %s = %s", name, size)
-    lst[2] = size
-    return ':'.join(lst)
-
-  def GetLpmakeArgsWithSizes():
-    lpmake_args = shlex.split(OPTIONS.info_dict['lpmake_args'].strip())
-
-    for i, arg in enumerate(lpmake_args):
-      if arg == '--partition':
-        assert i + 1 < len(lpmake_args), \
-          'lpmake_args has --partition without value'
-        lpmake_args[i + 1] = TransformPartitionArg(lpmake_args[i + 1])
-
-    return lpmake_args
-
-  outdir = OutputFile(output_zip, OPTIONS.input_tmp, "OTA", "")
-  cmd = [OPTIONS.info_dict['lpmake']]
-  cmd += GetLpmakeArgsWithSizes()
-
-  source = OPTIONS.info_dict.get('dynamic_partition_list', '').strip()
-  if source:
-    cmd.append('--sparse')
-    for name in shlex.split(source):
-      img = os.path.join(OPTIONS.input_tmp, "IMAGES", '{}.img'.format(name))
-      # Because --auto-slot-suffixing for A/B, there is no need to add suffix.
-      cmd += ['--image', '{}={}'.format(name, img)]
-
-  cmd += ['--output', outdir.name]
-
-  common.RunAndCheckOutput(cmd)
+  outdir = os.path.join(OPTIONS.input_tmp, "OTA")
+  build_super_image.BuildSuperImage(OPTIONS.input_tmp, outdir)
 
   for dev in OPTIONS.info_dict['super_block_devices'].strip().split():
     img = OutputFile(output_zip, OPTIONS.input_tmp, "OTA",
@@ -906,14 +858,13 @@
     banner("vbmeta")
     AddVBMeta(output_zip, partitions, "vbmeta", vbmeta_partitions)
 
-  if OPTIONS.info_dict.get("lpmake_args"):
+  if OPTIONS.info_dict.get("build_super_partition"):
     banner("super_empty")
     AddSuperEmpty(output_zip)
 
     if OPTIONS.info_dict.get("dynamic_partition_retrofit") == "true":
       banner("super split images")
       AddSuperSplit(output_zip)
-    # TODO(b/119322123): Add super.img to target_files for non-retrofit
 
   banner("radio")
   ab_partitions_txt = os.path.join(OPTIONS.input_tmp, "META",
diff --git a/tools/releasetools/build_super_image.py b/tools/releasetools/build_super_image.py
new file mode 100755
index 0000000..6efd3f4
--- /dev/null
+++ b/tools/releasetools/build_super_image.py
@@ -0,0 +1,202 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2018 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.
+
+"""
+Usage: build_super_image input_file output_dir_or_file
+
+input_file: one of the following:
+  - directory containing extracted target files. It will load info from
+    META/misc_info.txt and build full super image / split images using source
+    images from IMAGES/.
+  - target files package. Same as above, but extracts the archive before
+    building super image.
+  - a dictionary file containing input arguments to build. Check
+    `dump_dynamic_partitions_info' for details.
+    In addition:
+    - "ab_update" needs to be true for A/B devices.
+    - If source images should be included in the output image (for super.img
+      and super split images), a list of "*_image" should be paths of each
+      source images.
+
+output_dir_or_file:
+    If a single super image is built (for super_empty.img, or super.img for
+    launch devices), this argument is the output file.
+    If a collection of split images are built (for retrofit devices), this
+    argument is the output directory.
+"""
+
+from __future__ import print_function
+
+import logging
+import os.path
+import shlex
+import sys
+import zipfile
+
+import common
+import sparse_img
+
+if sys.hexversion < 0x02070000:
+  print("Python 2.7 or newer is required.", file=sys.stderr)
+  sys.exit(1)
+
+logger = logging.getLogger(__name__)
+
+
+UNZIP_PATTERN = ["IMAGES/*", "META/*"]
+
+
+def GetPartitionSizeFromImage(img):
+  try:
+    simg = sparse_img.SparseImage(img)
+    return simg.blocksize * simg.total_blocks
+  except ValueError:
+    return os.path.getsize(img)
+
+
+def BuildSuperImageFromDict(info_dict, output):
+
+  cmd = [info_dict["lpmake"],
+         "--metadata-size", "65536",
+         "--super-name", info_dict["super_metadata_device"]]
+
+  ab_update = info_dict.get("ab_update") == "true"
+  retrofit = info_dict.get("dynamic_partition_retrofit") == "true"
+  block_devices = shlex.split(info_dict.get("super_block_devices", "").strip())
+  groups = shlex.split(info_dict.get("super_partition_groups", "").strip())
+
+  if ab_update:
+    cmd += ["--metadata-slots", "2"]
+  else:
+    cmd += ["--metadata-slots", "1"]
+
+  if ab_update and retrofit:
+    cmd.append("--auto-slot-suffixing")
+
+  for device in block_devices:
+    size = info_dict["super_{}_device_size".format(device)]
+    cmd += ["--device", "{}:{}".format(device, size)]
+
+  append_suffix = ab_update and not retrofit
+  has_image = False
+  for group in groups:
+    group_size = info_dict["super_{}_group_size".format(group)]
+    if append_suffix:
+      cmd += ["--group", "{}_a:{}".format(group, group_size),
+              "--group", "{}_b:{}".format(group, group_size)]
+    else:
+      cmd += ["--group", "{}:{}".format(group, group_size)]
+
+    partition_list = shlex.split(
+        info_dict["super_{}_partition_list".format(group)].strip())
+
+    for partition in partition_list:
+      image = info_dict.get("{}_image".format(partition))
+      image_size = 0
+      if image:
+        image_size = GetPartitionSizeFromImage(image)
+        has_image = True
+      if append_suffix:
+        cmd += ["--partition",
+                "{}_a:readonly:{}:{}_a".format(partition, image_size, group),
+                "--partition",
+                "{}_b:readonly:0:{}_b".format(partition, group)]
+        if image:
+          # For A/B devices, super partition always contains sub-partitions in
+          # the _a slot, because this image should only be used for
+          # bootstrapping / initializing the device. When flashing the image,
+          # bootloader fastboot should always mark _a slot as bootable.
+          cmd += ["--image", "{}_a={}".format(partition, image)]
+      else:
+        cmd += ["--partition",
+                "{}:readonly:{}:{}".format(partition, image_size, group)]
+        if image:
+          cmd += ["--image", "{}={}".format(partition, image)]
+
+  if has_image:
+    cmd.append("--sparse")
+
+  cmd += ["--output", output]
+
+  common.RunAndCheckOutput(cmd)
+
+  if retrofit and has_image:
+    logger.info("Done writing images to directory %s", output)
+  else:
+    logger.info("Done writing image %s", output)
+
+
+def BuildSuperImageFromExtractedTargetFiles(inp, out):
+  info_dict = common.LoadInfoDict(inp)
+  partition_list = shlex.split(
+      info_dict.get("dynamic_partition_list", "").strip())
+  for partition in partition_list:
+    info_dict["{}_image".format(partition)] = os.path.join(
+        inp, "IMAGES", "{}.img".format(partition))
+  return BuildSuperImageFromDict(info_dict, out)
+
+
+def BuildSuperImageFromTargetFiles(inp, out):
+  input_tmp = common.UnzipTemp(inp, UNZIP_PATTERN)
+  return BuildSuperImageFromExtractedTargetFiles(input_tmp, out)
+
+
+def BuildSuperImage(inp, out):
+
+  if isinstance(inp, dict):
+    logger.info("Building super image from info dict...")
+    return BuildSuperImageFromDict(inp, out)
+
+  if isinstance(inp, str):
+    if os.path.isdir(inp):
+      logger.info("Building super image from extracted target files...")
+      return BuildSuperImageFromExtractedTargetFiles(inp, out)
+
+    if zipfile.is_zipfile(inp):
+      logger.info("Building super image from target files...")
+      return BuildSuperImageFromTargetFiles(inp, out)
+
+    if os.path.isfile(inp):
+      with open(inp) as f:
+        lines = f.read()
+      logger.info("Building super image from info dict...")
+      return BuildSuperImageFromDict(common.LoadDictionaryFromLines(lines.split("\n")), out)
+
+  raise ValueError("{} is not a dictionary or a valid path".format(inp))
+
+
+def main(argv):
+
+  args = common.ParseOptions(argv, __doc__)
+
+  if len(args) != 2:
+    common.Usage(__doc__)
+    sys.exit(1)
+
+  common.InitLogging()
+
+  BuildSuperImage(args[0], args[1])
+
+
+if __name__ == "__main__":
+  try:
+    common.CloseInheritedPipes()
+    main(sys.argv[1:])
+  except common.ExternalError:
+    logger.exception("\n   ERROR:\n")
+    sys.exit(1)
+  finally:
+    common.Cleanup()
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index fe63458..4c452ad 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -827,10 +827,10 @@
     ranges = image.file_map[entry]
 
     # If a RangeSet has been tagged as using shared blocks while loading the
-    # image, its block list must be already incomplete due to that reason. Don't
-    # give it 'incomplete' tag to avoid messing up the imgdiff stats.
+    # image, check the original block list to determine its completeness. Note
+    # that the 'incomplete' flag would be tagged to the original RangeSet only.
     if ranges.extra.get('uses_shared_blocks'):
-      continue
+      ranges = ranges.extra['uses_shared_blocks']
 
     if RoundUpTo4K(info.file_size) > ranges.size() * 4096:
       ranges.extra['incomplete'] = True
diff --git a/tools/releasetools/sparse_img.py b/tools/releasetools/sparse_img.py
index 5ebb1f0..7919ba4 100644
--- a/tools/releasetools/sparse_img.py
+++ b/tools/releasetools/sparse_img.py
@@ -248,15 +248,21 @@
         ranges = rangelib.RangeSet.parse(ranges)
 
         if allow_shared_blocks:
-          # Find the shared blocks that have been claimed by others.
+          # Find the shared blocks that have been claimed by others. If so, tag
+          # the entry so that we can skip applying imgdiff on this file.
           shared_blocks = ranges.subtract(remaining)
           if shared_blocks:
-            ranges = ranges.subtract(shared_blocks)
-            if not ranges:
+            non_shared = ranges.subtract(shared_blocks)
+            if not non_shared:
               continue
 
-            # Tag the entry so that we can skip applying imgdiff on this file.
-            ranges.extra['uses_shared_blocks'] = True
+            # 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
+            ranges = non_shared
 
         out[fn] = ranges
         assert ranges.size() == ranges.intersect(remaining).size()
diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py
index ae8253d..eeb802b 100755
--- a/tools/releasetools/validate_target_files.py
+++ b/tools/releasetools/validate_target_files.py
@@ -89,13 +89,20 @@
         logging.warning('Skipping %s that has incomplete block list', entry)
         continue
 
+      # Use the original RangeSet if applicable, which includes the shared
+      # blocks. And this needs to happen before checking the monotonicity flag.
+      if ranges.extra.get('uses_shared_blocks'):
+        file_ranges = ranges.extra['uses_shared_blocks']
+      else:
+        file_ranges = ranges
+
       # TODO(b/79951650): Handle files with non-monotonic ranges.
-      if not ranges.monotonic:
+      if not file_ranges.monotonic:
         logging.warning(
-            'Skipping %s that has non-monotonic ranges: %s', entry, ranges)
+            'Skipping %s that has non-monotonic ranges: %s', entry, file_ranges)
         continue
 
-      blocks_sha1 = image.RangeSha1(ranges)
+      blocks_sha1 = image.RangeSha1(file_ranges)
 
       # The filename under unpacked directory, such as SYSTEM/bin/sh.
       unpacked_name = os.path.join(
@@ -104,7 +111,7 @@
       file_sha1 = unpacked_file.sha1
       assert blocks_sha1 == file_sha1, \
           'file: %s, range: %s, blocks_sha1: %s, file_sha1: %s' % (
-              entry, ranges, blocks_sha1, file_sha1)
+              entry, file_ranges, blocks_sha1, file_sha1)
 
   logging.info('Validating file consistency.')
 
@@ -311,9 +318,9 @@
   if info_dict.get("avb_enable") == "true":
     logging.info('Verifying Verified Boot 2.0 (AVB) images...')
 
-    # Temporarily disable the verification for AVB-signed images, due to the
-    # dependency on PyCrypto in `avbtool verify_image` (Bug: 119624011).
-    logging.info('Temporarily disabled due to b/119624011')
+    # TODO(b/120517892): Temporarily disable the verification for AVB-signed
+    # images. Needing supporting changes in caller to pass in the desired keys.
+    logging.info('Temporarily disabled due to b/120517892')
 
 
 def main():