Merge "Include misc_info.txt for super.img in dist"
diff --git a/core/Makefile b/core/Makefile
index 9636fe3..99b86ee 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -762,30 +762,6 @@
 endif
 
 # -----------------------------------------------------------------
-# package stats
-ifdef BUILDING_SYSTEM_IMAGE
-
-PACKAGE_STATS_FILE := $(PRODUCT_OUT)/package-stats.txt
-PACKAGES_TO_STAT := \
-    $(sort $(filter $(TARGET_OUT)/% $(TARGET_OUT_DATA)/%, \
-	$(filter %.jar %.apk, $(ALL_DEFAULT_INSTALLED_MODULES))))
-$(PACKAGE_STATS_FILE): $(PACKAGES_TO_STAT)
-	@echo Package stats: $@
-	@mkdir -p $(dir $@)
-	$(hide) rm -f $@
-ifeq ($(PACKAGES_TO_STAT),)
-# Create empty package stats file if target builds no jar(s) or apk(s).
-	$(hide) touch $@
-else
-	$(hide) build/make/tools/dump-package-stats $^ > $@
-endif
-
-.PHONY: package-stats
-package-stats: $(PACKAGE_STATS_FILE)
-
-endif # BUILDING_SYSTEM_IMAGE
-
-# -----------------------------------------------------------------
 # Cert-to-package mapping.  Used by the post-build signing tools.
 # Use a macro to add newline to each echo command
 define _apkcerts_write_line
@@ -3396,6 +3372,7 @@
   $(hide) rm -rf $(AVB_CHAIN_KEY_DIR)
 endef
 
+ifdef BUILDING_VBMETA_IMAGE
 INSTALLED_VBMETAIMAGE_TARGET := $(BUILT_VBMETAIMAGE_TARGET)
 $(INSTALLED_VBMETAIMAGE_TARGET): PRIVATE_AVB_VBMETA_SIGNING_ARGS := \
     --algorithm $(BOARD_AVB_ALGORITHM) --key $(BOARD_AVB_KEY_PATH)
@@ -3420,6 +3397,7 @@
 .PHONY: vbmetaimage-nodeps
 vbmetaimage-nodeps:
 	$(build-vbmetaimage-target)
+endif # BUILDING_VBMETA_IMAGE
 
 endif # BOARD_AVB_ENABLE
 
@@ -3621,6 +3599,7 @@
 
 INTERNAL_OTATOOLS_MODULES := \
   aapt \
+  add_img_to_target_files \
   append2simg \
   avbtool \
   blk_alloc_to_base_fs \
@@ -3633,6 +3612,8 @@
   build_verity_metadata \
   build_verity_tree \
   care_map_generator \
+  check_ota_package_signature \
+  check_target_files_signatures \
   checkvintf \
   delta_generator \
   e2fsck \
@@ -3642,11 +3623,13 @@
   fs_config \
   generate_verity_key \
   img2simg \
+  img_from_target_files \
   imgdiff \
   libconscrypt_openjdk_jni \
   lpmake \
   lpunpack \
   make_f2fs \
+  merge_target_files \
   minigzip \
   mk_combined_img \
   mkbootfs \
@@ -3661,11 +3644,14 @@
   sefcontext_compile \
   sgdisk \
   shflags \
+  sign_apex \
+  sign_target_files_apks \
   signapk \
   simg2img \
   sload_f2fs \
   tune2fs \
   update_host_simulator \
+  validate_target_files \
   verity_signer \
   verity_verifier \
   zipalign \
@@ -3705,10 +3691,6 @@
   $(sort $(shell find external/avb/test/data -type f -name "testkey_*.pem" -o \
       -name "atx_metadata.bin"))
 endif
-ifneq (,$(wildcard system/update_engine))
-INTERNAL_OTATOOLS_PACKAGE_FILES += \
-  $(sort $(shell find system/update_engine/scripts -name "*.pyc" -prune -o -type f -print))
-endif
 ifeq (true,$(PRODUCT_SUPPORTS_VBOOT))
 INTERNAL_OTATOOLS_PACKAGE_FILES += \
   $(sort $(shell find external/vboot_reference/tests/devkeys -type f))
@@ -4017,9 +3999,8 @@
 	    $(SOONG_APEX_KEYS_FILE) \
 	    $(SOONG_ZIP) \
 	    $(HOST_OUT_EXECUTABLES)/fs_config \
-	    $(HOST_OUT_EXECUTABLES)/care_map_generator \
+	    $(ADD_IMG_TO_TARGET_FILES) \
 	    $(MAKE_RECOVERY_PATCH) \
-	    $(BUILD_IMAGE_SRCS) \
 	    $(BUILT_ASSEMBLED_FRAMEWORK_MANIFEST) \
 	    $(BUILT_ASSEMBLED_VENDOR_MANIFEST) \
 	    $(BUILT_SYSTEM_MATRIX) \
@@ -4286,7 +4267,7 @@
 endif # BOARD_SUPER_PARTITION_GROUPS
 	@# TODO(b/134525174): Remove `-r` after addressing the issue with recovery patch generation.
 	$(hide) PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH MKBOOTIMG=$(MKBOOTIMG) \
-	    build/make/tools/releasetools/add_img_to_target_files -a -r -v -p $(HOST_OUT) $(zip_root)
+	    $(ADD_IMG_TO_TARGET_FILES) -a -r -v -p $(HOST_OUT) $(zip_root)
 ifeq ($(BUILD_QEMU_IMAGES),true)
 	$(hide) AVBTOOL=$(AVBTOOL) $(MK_VBMETA_BOOT_KERNEL_CMDLINE_SH) $(zip_root)/IMAGES/vbmeta.img \
 	    $(zip_root)/IMAGES/system.img $(zip_root)/IMAGES/VerifiedBootParams.textproto
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 4a0c15b..e3f8a70 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -524,11 +524,11 @@
 
 # Only set up copy rules once, even if another arch variant shares it
 my_vintf_new_pairs := $(filter-out $(ALL_VINTF_MANIFEST_FRAGMENTS_LIST),$(my_vintf_pairs))
-my_vintf_new_installed := $(call copy-many-vintf-manifest-files-checked,$(my_vintf_pairs))
+my_vintf_new_installed := $(call copy-many-vintf-manifest-files-checked,$(my_vintf_new_pairs))
 
 ALL_VINTF_MANIFEST_FRAGMENTS_LIST += $(my_vintf_new_pairs)
 
-$(my_all_targets) : $(my_vintf_installed)
+$(my_all_targets) : $(my_vintf_new_installed)
 endif # LOCAL_VINTF_FRAGMENTS
 endif # !LOCAL_IS_HOST_MODULE
 endif # !LOCAL_UNINSTALLABLE_MODULE
diff --git a/core/binary.mk b/core/binary.mk
index e916164..d9763f9 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -54,6 +54,7 @@
 my_cc := $(LOCAL_CC)
 my_cc_wrapper := $(CC_WRAPPER)
 my_cxx := $(LOCAL_CXX)
+my_cxx_link := $(LOCAL_CXX)
 my_cxx_ldlibs :=
 my_cxx_wrapper := $(CXX_WRAPPER)
 my_c_includes := $(LOCAL_C_INCLUDES)
@@ -1704,13 +1705,20 @@
   my_cxx := $(my_cxx_wrapper) $(CLANG_CXX)
 endif
 
+ifeq ($(strip $(my_cxx_link)),)
+  my_cxx_link := $(CLANG_CXX)
+endif
+
 ifneq ($(LOCAL_NO_STATIC_ANALYZER),true)
   my_cxx := CCC_CXX=$(CLANG_CXX) CLANG_CXX=$(CLANG_CXX) \
             $(SYNTAX_TOOLS_PREFIX)/c++-analyzer
+  my_cxx_link := CCC_CXX=$(CLANG_CXX) CLANG_CXX=$(CLANG_CXX) \
+                 $(SYNTAX_TOOLS_PREFIX)/c++-analyzer
 endif
 
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_LINKER := $(my_linker)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CXX := $(my_cxx)
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CXX_LINK := $(my_cxx_link)
 
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_YACCFLAGS := $(LOCAL_YACCFLAGS)
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_ASFLAGS := $(my_asflags)
diff --git a/core/board_config.mk b/core/board_config.mk
index db60cee..a6aef87 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -358,6 +358,13 @@
 endif
 .KATI_READONLY := BUILDING_USERDATA_IMAGE
 
+# Are we building a vbmeta image
+BUILDING_VBMETA_IMAGE := true
+ifeq ($(PRODUCT_BUILD_VBMETA_IMAGE),false)
+  BUILDING_VBMETA_IMAGE :=
+endif
+.KATI_READONLY := BUILDING_VBMETA_IMAGE
+
 ###########################################
 # Now we can substitute with the real value of TARGET_COPY_OUT_VENDOR
 ifeq ($(TARGET_COPY_OUT_VENDOR),$(_vendor_path_placeholder))
diff --git a/core/config.mk b/core/config.mk
index 0f9f112..ca8f523 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -605,6 +605,7 @@
 FAT16COPY := build/make/tools/fat16copy.py
 CHECK_ELF_FILE := build/make/tools/check_elf_file.py
 LPMAKE := $(HOST_OUT_EXECUTABLES)/lpmake$(HOST_EXECUTABLE_SUFFIX)
+ADD_IMG_TO_TARGET_FILES := $(HOST_OUT_EXECUTABLES)/add_img_to_target_files$(HOST_EXECUTABLE_SUFFIX)
 BUILD_IMAGE := $(HOST_OUT_EXECUTABLES)/build_image$(HOST_EXECUTABLE_SUFFIX)
 BUILD_SUPER_IMAGE := $(HOST_OUT_EXECUTABLES)/build_super_image$(HOST_EXECUTABLE_SUFFIX)
 MAKE_RECOVERY_PATCH := $(HOST_OUT_EXECUTABLES)/make_recovery_patch$(HOST_EXECUTABLE_SUFFIX)
@@ -616,7 +617,6 @@
 PROGUARD_DEPS := $(PROGUARD) $(PROGUARD_HOME)/lib/proguard.jar
 JAVATAGS := build/make/tools/java-event-log-tags.py
 MERGETAGS := build/make/tools/merge-event-log-tags.py
-BUILD_IMAGE_SRCS := $(wildcard build/make/tools/releasetools/*.py)
 APPEND2SIMG := $(HOST_OUT_EXECUTABLES)/append2simg
 VERITY_SIGNER := $(HOST_OUT_EXECUTABLES)/verity_signer
 BUILD_VERITY_METADATA := $(HOST_OUT_EXECUTABLES)/build_verity_metadata
@@ -785,6 +785,13 @@
 endif
 .KATI_READONLY := DEFAULT_SYSTEM_DEV_CERTIFICATE
 
+# Certificate for the NetworkStack sepolicy context
+ifdef PRODUCT_MAINLINE_SEPOLICY_DEV_CERTIFICATES
+  MAINLINE_SEPOLICY_DEV_CERTIFICATES := $(PRODUCT_MAINLINE_SEPOLICY_DEV_CERTIFICATES)
+else
+  MAINLINE_SEPOLICY_DEV_CERTIFICATES := $(dir $(DEFAULT_SYSTEM_DEV_CERTIFICATE))
+endif
+
 BUILD_NUMBER_FROM_FILE := $$(cat $(OUT_DIR)/build_number.txt)
 BUILD_DATETIME_FROM_FILE := $$(cat $(BUILD_DATETIME_FILE))
 
diff --git a/core/cxx_stl_setup.mk b/core/cxx_stl_setup.mk
index 7d3ca5c..55c4975 100644
--- a/core/cxx_stl_setup.mk
+++ b/core/cxx_stl_setup.mk
@@ -84,6 +84,7 @@
         my_ldflags += -nodefaultlibs
         my_cxx_ldlibs += $($($(my_prefix)OS)_$(my_link_type)_gcclibs)
     else
+        my_static_libraries += libc++demangle
         ifeq (arm,$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH))
             my_static_libraries += libunwind_llvm
             my_ldflags += -Wl,--exclude-libs,libunwind_llvm.a
diff --git a/core/definitions.mk b/core/definitions.mk
index f32a995..a93979a 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -951,7 +951,7 @@
 $(hide) mkdir -p $(dir $@)
 $(hide) $(BCC_COMPAT) -O3 -o $(dir $@)/$(notdir $(<:.bc=.o)) -fPIC -shared \
   -rt-path $(RS_PREBUILT_CLCORE) -mtriple $(RS_COMPAT_TRIPLE) $<
-$(hide) $(PRIVATE_CXX) -shared -Wl,-soname,$(notdir $@) -nostdlib \
+$(hide) $(PRIVATE_CXX_LINK) -shared -Wl,-soname,$(notdir $@) -nostdlib \
   -Wl,-rpath,\$$ORIGIN/../lib \
   $(dir $@)/$(notdir $(<:.bc=.o)) \
   $(RS_PREBUILT_COMPILER_RT) \
@@ -1533,7 +1533,7 @@
 endef
 
 define transform-o-to-aux-executable-inner
-$(hide) $(PRIVATE_CXX) -pie \
+$(hide) $(PRIVATE_CXX_LINK) -pie \
   -Bdynamic \
   -Wl,--gc-sections \
   $(PRIVATE_ALL_OBJECTS) \
@@ -1552,7 +1552,7 @@
 endef
 
 define transform-o-to-aux-static-executable-inner
-$(hide) $(PRIVATE_CXX) \
+$(hide) $(PRIVATE_CXX_LINK) \
   -Bstatic \
   -Wl,--gc-sections \
   $(PRIVATE_ALL_OBJECTS) \
@@ -1653,7 +1653,7 @@
 # it to be overriden en-masse see combo/linux-arm.make for an example.
 ifneq ($(HOST_CUSTOM_LD_COMMAND),true)
 define transform-host-o-to-shared-lib-inner
-$(hide) $(PRIVATE_CXX) \
+$(hide) $(PRIVATE_CXX_LINK) \
   -Wl,-rpath,\$$ORIGIN/../$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OUT_SHARED_LIBRARIES)) \
   -Wl,-rpath,\$$ORIGIN/$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)OUT_SHARED_LIBRARIES)) \
   -shared -Wl,-soname,$(notdir $@) \
@@ -1694,7 +1694,7 @@
 ###########################################################
 
 define transform-o-to-shared-lib-inner
-$(hide) $(PRIVATE_CXX) \
+$(hide) $(PRIVATE_CXX_LINK) \
   -nostdlib -Wl,-soname,$(notdir $@) \
   -Wl,--gc-sections \
   -shared \
@@ -1729,7 +1729,7 @@
 ###########################################################
 
 define transform-o-to-executable-inner
-$(hide) $(PRIVATE_CXX) -pie \
+$(hide) $(PRIVATE_CXX_LINK) -pie \
   -nostdlib -Bdynamic \
   -Wl,-dynamic-linker,$(PRIVATE_LINKER) \
   -Wl,--gc-sections \
@@ -1772,7 +1772,7 @@
 ###########################################################
 
 define transform-o-to-static-executable-inner
-$(hide) $(PRIVATE_CXX) \
+$(hide) $(PRIVATE_CXX_LINK) \
   -nostdlib -Bstatic \
   $(if $(filter $(PRIVATE_LDFLAGS),-shared),,-static) \
   -Wl,--gc-sections \
@@ -1810,7 +1810,7 @@
 
 ifneq ($(HOST_CUSTOM_LD_COMMAND),true)
 define transform-host-o-to-executable-inner
-$(hide) $(PRIVATE_CXX) \
+$(hide) $(PRIVATE_CXX_LINK) \
   $(PRIVATE_ALL_OBJECTS) \
   -Wl,--whole-archive \
   $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
diff --git a/core/envsetup.mk b/core/envsetup.mk
index be22ff7..8a7aca0 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -817,7 +817,16 @@
 TARGET_OUT_SYSTEM_EXT_APPS := $(target_out_system_ext_app_base)/app
 TARGET_OUT_SYSTEM_EXT_APPS_PRIVILEGED := $(target_out_system_ext_app_base)/priv-app
 TARGET_OUT_SYSTEM_EXT_ETC := $(TARGET_OUT_SYSTEM_EXT)/etc
+TARGET_OUT_SYSTEM_EXT_EXECUTABLES := $(TARGET_OUT_SYSTEM_EXT)/bin
+.KATI_READONLY := \
+  TARGET_OUT_SYSTEM_EXT_EXECUTABLES \
+  TARGET_OUT_SYSTEM_EXT_SHARED_LIBRARIES \
+  TARGET_OUT_SYSTEM_EXT_JAVA_LIBRARIES \
+  TARGET_OUT_SYSTEM_EXT_APPS \
+  TARGET_OUT_SYSTEM_EXT_APPS_PRIVILEGED \
+  TARGET_OUT_SYSTEM_EXT_ETC
 
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_EXT_EXECUTABLES := $(TARGET_OUT_SYSTEM_EXT_EXECUTABLES)
 ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_EXT_SHARED_LIBRARIES := $(target_out_system_ext_shared_libraries_base)/lib/$(TARGET_2ND_ARCH)
 else
@@ -825,6 +834,11 @@
 endif
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_EXT_APPS := $(TARGET_OUT_SYSTEM_EXT_APPS)
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_EXT_APPS_PRIVILEGED := $(TARGET_OUT_SYSTEM_EXT_APPS_PRIVILEGED)
+.KATI_READONLY := \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_EXT_EXECUTABLES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_EXT_SHARED_LIBRARIES \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_EXT_APPS \
+  $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_EXT_APPS_PRIVILEGED
 
 TARGET_OUT_BREAKPAD := $(PRODUCT_OUT)/breakpad
 .KATI_READONLY := TARGET_OUT_BREAKPAD
diff --git a/core/java_common.mk b/core/java_common.mk
index cb88a9e..a23d92d 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -81,19 +81,17 @@
 $(proto_java_srcjar): PRIVATE_PROTO_JAVA_OUTPUT_DIR := $(proto_java_sources_dir)
 $(proto_java_srcjar): PRIVATE_PROTOC_FLAGS := $(LOCAL_PROTOC_FLAGS)
 ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),micro)
-$(proto_java_srcjar): PRIVATE_PROTO_JAVA_OUTPUT_OPTION := --javamicro_out
+  $(proto_java_srcjar): PRIVATE_PROTO_JAVA_OUTPUT_OPTION := --javamicro_out
+  $(proto_java_srcjar): PRIVATE_PROTOC_FLAGS += --plugin=$(HOST_OUT_EXECUTABLES)/protoc-gen-javamicro
+  $(proto_java_srcjar): $(HOST_OUT_EXECUTABLES)/protoc-gen-javamicro
+else ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),nano)
+  $(proto_java_srcjar): PRIVATE_PROTO_JAVA_OUTPUT_OPTION := --javanano_out
+else ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),stream)
+  $(proto_java_srcjar): PRIVATE_PROTO_JAVA_OUTPUT_OPTION := --javastream_out
+  $(proto_java_srcjar): PRIVATE_PROTOC_FLAGS += --plugin=$(HOST_OUT_EXECUTABLES)/protoc-gen-javastream
+  $(proto_java_srcjar): $(HOST_OUT_EXECUTABLES)/protoc-gen-javastream
 else
-  ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),nano)
-$(proto_java_srcjar): PRIVATE_PROTO_JAVA_OUTPUT_OPTION := --javanano_out
-  else
-    ifeq ($(LOCAL_PROTOC_OPTIMIZE_TYPE),stream)
-$(proto_java_srcjar): PRIVATE_PROTO_JAVA_OUTPUT_OPTION := --javastream_out
-$(proto_java_srcjar): PRIVATE_PROTOC_FLAGS += --plugin=$(HOST_OUT_EXECUTABLES)/protoc-gen-javastream
-$(proto_java_srcjar): $(HOST_OUT_EXECUTABLES)/protoc-gen-javastream
-    else
-$(proto_java_srcjar): PRIVATE_PROTO_JAVA_OUTPUT_OPTION := --java_out
-    endif
-  endif
+  $(proto_java_srcjar): PRIVATE_PROTO_JAVA_OUTPUT_OPTION := --java_out
 endif
 $(proto_java_srcjar): PRIVATE_PROTO_JAVA_OUTPUT_PARAMS := $(if $(filter lite,$(LOCAL_PROTOC_OPTIMIZE_TYPE)),lite$(if $(LOCAL_PROTO_JAVA_OUTPUT_PARAMS),:,),)$(LOCAL_PROTO_JAVA_OUTPUT_PARAMS)
 $(proto_java_srcjar) : $(proto_sources_fullpath) $(PROTOC) $(SOONG_ZIP)
diff --git a/core/java_renderscript.mk b/core/java_renderscript.mk
index 820967a..672863b 100644
--- a/core/java_renderscript.mk
+++ b/core/java_renderscript.mk
@@ -139,6 +139,7 @@
     $(rs_support_lib) $(rs_support_io_lib) $(rs_jni_lib) $(rs_compiler_rt)
 $(rs_compatibility_jni_libs): $(BCC_COMPAT)
 $(rs_compatibility_jni_libs): PRIVATE_CXX := $(CXX_WRAPPER) $(CLANG_CXX)
+$(rs_compatibility_jni_libs): PRIVATE_CXX_LINK := $(CLANG_CXX)
 $(rs_compatibility_jni_libs): PRIVATE_SDK_VERSION := $(my_min_sdk_version)
 $(rs_compatibility_jni_libs): $(renderscript_intermediate)/librs.%.so: \
     $(renderscript_intermediate.bc_folder)%.bc \
diff --git a/core/main.mk b/core/main.mk
index 5e25af4..f99f16d 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1694,7 +1694,6 @@
     $(call dist-for-goals, droidcore, \
       $(APPS_ZIP) \
       $(INTERNAL_EMULATOR_PACKAGE_TARGET) \
-      $(PACKAGE_STATS_FILE) \
     )
   endif
   endif
@@ -1778,12 +1777,13 @@
 LSDUMP_PATHS_FILE := $(PRODUCT_OUT)/lsdump_paths.txt
 
 .PHONY: findlsdumps
-findlsdumps: $(LSDUMP_PATHS_FILE) $(LSDUMP_PATHS)
+# LSDUMP_PATHS is a list of tag:path.
+findlsdumps: $(LSDUMP_PATHS_FILE) $(foreach p,$(LSDUMP_PATHS),$(call word-colon,2,$(p)))
 
 $(LSDUMP_PATHS_FILE): PRIVATE_LSDUMP_PATHS := $(LSDUMP_PATHS)
 $(LSDUMP_PATHS_FILE):
 	@echo "Generate $@"
-	@rm -rf $@ && echo "$(PRIVATE_LSDUMP_PATHS)" | sed -e 's/ /\n/g' > $@
+	@rm -rf $@ && echo -e "$(subst :,:$(space),$(subst $(space),\n,$(PRIVATE_LSDUMP_PATHS)))" > $@
 
 .PHONY: check-elf-files
 check-elf-files:
diff --git a/core/product-graph.mk b/core/product-graph.mk
index 9fc8e57..b97a69d 100644
--- a/core/product-graph.mk
+++ b/core/product-graph.mk
@@ -131,6 +131,7 @@
 	$(hide) echo 'PRODUCT_SDK_ADDON_DOC_MODULES=$$(PRODUCTS.$(strip $(1)).PRODUCT_SDK_ADDON_DOC_MODULES)' >> $$@
 	$(hide) echo 'PRODUCT_DEFAULT_WIFI_CHANNELS=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEFAULT_WIFI_CHANNELS)' >> $$@
 	$(hide) echo 'PRODUCT_DEFAULT_DEV_CERTIFICATE=$$(PRODUCTS.$(strip $(1)).PRODUCT_DEFAULT_DEV_CERTIFICATE)' >> $$@
+	$(hide) echo 'PRODUCT_MAINLINE_SEPOLICY_DEV_CERTIFICATES=$$(PRODUCTS.$(strip $(1)).PRODUCT_MAINLINE_SEPOLICY_DEV_CERTIFICATES)' >> $$@
 	$(hide) echo 'PRODUCT_RESTRICT_VENDOR_FILES=$$(PRODUCTS.$(strip $(1)).PRODUCT_RESTRICT_VENDOR_FILES)' >> $$@
 	$(hide) echo 'PRODUCT_VENDOR_KERNEL_HEADERS=$$(PRODUCTS.$(strip $(1)).PRODUCT_VENDOR_KERNEL_HEADERS)' >> $$@
 
diff --git a/core/product.mk b/core/product.mk
index 3d54719..2c89fab 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -205,6 +205,7 @@
 
 _product_list_vars += PRODUCT_DEFAULT_WIFI_CHANNELS
 _product_list_vars += PRODUCT_DEFAULT_DEV_CERTIFICATE
+_product_list_vars += PRODUCT_MAINLINE_SEPOLICY_DEV_CERTIFICATES
 _product_list_vars += PRODUCT_RESTRICT_VENDOR_FILES
 
 # The list of product-specific kernel header dirs
@@ -361,6 +362,7 @@
 _product_single_value_vars += PRODUCT_BUILD_USERDATA_IMAGE
 _product_single_value_vars += PRODUCT_BUILD_RECOVERY_IMAGE
 _product_single_value_vars += PRODUCT_BUILD_BOOT_IMAGE
+_product_single_value_vars += PRODUCT_BUILD_VBMETA_IMAGE
 
 _product_list_vars += PRODUCT_UPDATABLE_BOOT_MODULES
 _product_list_vars += PRODUCT_UPDATABLE_BOOT_LOCATIONS
diff --git a/core/rbe.mk b/core/rbe.mk
index 766b121..fb39d51 100644
--- a/core/rbe.mk
+++ b/core/rbe.mk
@@ -21,7 +21,7 @@
   else
     rbe_dir := $(HOME)/rbe
   endif
-  RBE_WRAPPER := $(rbe_dir)/rewrapper
+  RBE_WRAPPER := $(rbe_dir)/rewrapper --labels=type=compile,lang=cpp,compiler=clang
 
   # Append rewrapper to existing *_WRAPPER variables so it's possible to
   # use both ccache and rewrapper.
diff --git a/core/soong_config.mk b/core/soong_config.mk
index d60cad0..bcd025b 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -164,7 +164,7 @@
 $(call add_json_list, BoardPlatPrivateSepolicyDirs,      $(BOARD_PLAT_PRIVATE_SEPOLICY_DIR))
 $(call add_json_list, BoardSepolicyM4Defs,               $(BOARD_SEPOLICY_M4DEFS))
 
-$(call add_json_bool, FlattenApex,                       $(filter true,$(TARGET_FLATTEN_APEX)))
+$(call add_json_bool, Flatten_apex,                      $(filter true,$(TARGET_FLATTEN_APEX)))
 
 $(call add_json_str,  DexpreoptGlobalConfig,             $(DEX_PREOPT_CONFIG))
 
diff --git a/core/tasks/tools/compatibility.mk b/core/tasks/tools/compatibility.mk
index f480300..b6dd39e 100644
--- a/core/tasks/tools/compatibility.mk
+++ b/core/tasks/tools/compatibility.mk
@@ -55,7 +55,7 @@
 # Copy tools
 	$(hide) cp $(PRIVATE_TOOLS) $(PRIVATE_OUT_DIR)/tools
 	$(if $(PRIVATE_DYNAMIC_CONFIG),$(hide) cp $(PRIVATE_DYNAMIC_CONFIG) $(PRIVATE_OUT_DIR)/testcases/$(PRIVATE_SUITE_NAME).dynamic)
-	$(hide) find $(dir $@)/$(PRIVATE_NAME) | sort >$@.list
+	$(hide) find $(PRIVATE_OUT_DIR)/tools $(PRIVATE_OUT_DIR)/testcases | sort >$@.list
 	$(hide) $(SOONG_ZIP) -d -o $@ -C $(dir $@) -l $@.list
 
 # Reset all input variables
diff --git a/core/tasks/vts-core-tests.mk b/core/tasks/vts-core-tests.mk
index 919354c..fb1e1c6 100644
--- a/core/tasks/vts-core-tests.mk
+++ b/core/tasks/vts-core-tests.mk
@@ -45,3 +45,5 @@
 
 vts-core: $(vts-core-zip)
 $(call dist-for-goals, vts-core, $(vts-core-zip) $(vts-core-list-zip) $(vts-core-configs-zip))
+
+tests: vts-core
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index efaacf5..f949b05 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -252,7 +252,7 @@
     #  It must be of the form "YYYY-MM-DD" on production devices.
     #  It must match one of the Android Security Patch Level strings of the Public Security Bulletins.
     #  If there is no $PLATFORM_SECURITY_PATCH set, keep it empty.
-      PLATFORM_SECURITY_PATCH := 2019-07-05
+      PLATFORM_SECURITY_PATCH := 2019-08-01
 endif
 .KATI_READONLY := PLATFORM_SECURITY_PATCH
 
diff --git a/envsetup.sh b/envsetup.sh
index 0392e86..40f7705 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -23,6 +23,7 @@
 - resgrep:    Greps on all local res/*.xml files.
 - mangrep:    Greps on all local AndroidManifest.xml files.
 - mgrep:      Greps on all local Makefiles and *.bp files.
+- owngrep:    Greps on all local OWNERS files.
 - sepgrep:    Greps on all local sepolicy files.
 - sgrep:      Greps on all local source files.
 - godir:      Go to the directory containing a file.
@@ -995,6 +996,12 @@
         -exec grep --color -n "$@" {} +
 }
 
+function owngrep()
+{
+    find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -type f -name 'OWNERS' \
+        -exec grep --color -n "$@" {} +
+}
+
 function sepgrep()
 {
     find . -name .repo -prune -o -name .git -prune -o -path ./out -prune -o -name sepolicy -type d \
diff --git a/target/product/base_vendor.mk b/target/product/base_vendor.mk
index c57cc3f..e3c600f 100644
--- a/target/product/base_vendor.mk
+++ b/target/product/base_vendor.mk
@@ -48,6 +48,7 @@
     fs_config_dirs_nonsystem \
     gralloc.default \
     group_odm \
+    group_system_ext \
     group_vendor \
     init_vendor \
     libashmemd_hidl_client \
@@ -64,6 +65,7 @@
     libril \
     libvisualizer \
     passwd_odm \
+    passwd_system_ext \
     passwd_vendor \
     selinux_policy_nonsystem \
     shell_and_utilities_vendor \
diff --git a/target/product/gsi/Android.mk b/target/product/gsi/Android.mk
index 1ef124b..c93e4ca 100644
--- a/target/product/gsi/Android.mk
+++ b/target/product/gsi/Android.mk
@@ -120,13 +120,13 @@
 
 $(check-vndk-abi-dump-list-timestamp): $(VNDK_ABI_DUMPS) $(NDK_ABI_DUMPS)
 	$(eval added_vndk_abi_dumps := $(strip $(sort $(filter-out \
-	  $(addsuffix .so.lsdump,$(VNDK_SAMEPROCESS_LIBRARIES) $(VNDK_CORE_LIBRARIES)), \
+	  $(addsuffix .so.lsdump,$(filter-out $(NDK_MIGRATED_LIBS) $(VNDK_PRIVATE_LIBRARIES),$(LLNDK_LIBRARIES) $(VNDK_SAMEPROCESS_LIBRARIES) $(VNDK_CORE_LIBRARIES))), \
 	  $(notdir $(VNDK_ABI_DUMPS))))))
 	$(if $(added_vndk_abi_dumps), \
 	  echo -e "Found ABI reference dumps for non-VNDK libraries. Run \`find \$${ANDROID_BUILD_TOP}/$(VNDK_ABI_DUMP_DIR) '(' -name $(subst $(space), -or -name ,$(added_vndk_abi_dumps)) ')' -delete\` to delete the dumps.")
 
 	$(eval added_ndk_abi_dumps := $(strip $(sort $(filter-out \
-	  $(addsuffix .so.lsdump,$(NDK_MIGRATED_LIBS) $(LLNDK_LIBRARIES)), \
+	  $(addsuffix .so.lsdump,$(NDK_MIGRATED_LIBS)), \
 	  $(notdir $(NDK_ABI_DUMPS))))))
 	$(if $(added_ndk_abi_dumps), \
 	  echo -e "Found ABI reference dumps for non-NDK libraries. Run \`find \$${ANDROID_BUILD_TOP}/$(NDK_ABI_DUMP_DIR) '(' -name $(subst $(space), -or -name ,$(added_ndk_abi_dumps)) ')' -delete\` to delete the dumps.")
diff --git a/target/product/mainline_arm64.mk b/target/product/mainline_arm64.mk
index c098c9f..a32bb16 100644
--- a/target/product/mainline_arm64.mk
+++ b/target/product/mainline_arm64.mk
@@ -31,43 +31,8 @@
   system/etc/seccomp_policy/crash_dump.arm.policy \
   system/etc/seccomp_policy/mediacodec.policy \
 
-# Modules that are to be moved to /product
+# Modules that should probably be moved to /product
 PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST += \
-  system/app/Browser2/Browser2.apk \
-  system/app/Calendar/Calendar.apk \
-  system/app/Camera2/Camera2.apk \
-  system/app/DeskClock/DeskClock.apk \
-  system/app/DeskClock/oat/arm64/DeskClock.odex \
-  system/app/DeskClock/oat/arm64/DeskClock.vdex \
-  system/app/Email/Email.apk \
-  system/app/Gallery2/Gallery2.apk \
-  system/app/LatinIME/LatinIME.apk \
-  system/app/LatinIME/oat/arm64/LatinIME.odex \
-  system/app/LatinIME/oat/arm64/LatinIME.vdex \
-  system/app/Music/Music.apk \
-  system/app/QuickSearchBox/QuickSearchBox.apk \
-  system/app/webview/webview.apk \
   system/bin/healthd \
   system/etc/init/healthd.rc \
   system/etc/vintf/manifest/manifest_healthd.xml \
-  system/lib64/libjni_eglfence.so \
-  system/lib64/libjni_filtershow_filters.so \
-  system/lib64/libjni_jpegstream.so \
-  system/lib64/libjni_jpegutil.so \
-  system/lib64/libjni_latinime.so \
-  system/lib64/libjni_tinyplanet.so \
-  system/priv-app/CarrierConfig/CarrierConfig.apk \
-  system/priv-app/CarrierConfig/oat/arm64/CarrierConfig.odex \
-  system/priv-app/CarrierConfig/oat/arm64/CarrierConfig.vdex \
-  system/priv-app/Contacts/Contacts.apk \
-  system/priv-app/Dialer/Dialer.apk \
-  system/priv-app/Launcher3QuickStep/Launcher3QuickStep.apk \
-  system/priv-app/OneTimeInitializer/OneTimeInitializer.apk \
-  system/priv-app/Provision/Provision.apk \
-  system/priv-app/Settings/Settings.apk \
-  system/priv-app/SettingsIntelligence/SettingsIntelligence.apk \
-  system/priv-app/StorageManager/StorageManager.apk \
-  system/priv-app/SystemUI/SystemUI.apk \
-  system/priv-app/SystemUI/oat/arm64/SystemUI.odex \
-  system/priv-app/SystemUI/oat/arm64/SystemUI.vdex \
-  system/priv-app/WallpaperCropper/WallpaperCropper.apk \
diff --git a/tools/dump-package-stats b/tools/dump-package-stats
deleted file mode 100755
index 7814368..0000000
--- a/tools/dump-package-stats
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 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.
-#
-
-PROGNAME=`basename $0`
-
-function fail ()
-{
-    if [ ! -z "$@" ]
-    then
-        echo "$PROGNAME: ERROR: $@" >&2
-    fi
-    echo "$PROGNAME: ERROR: failed." >&2
-    exit 1
-}
-
-function usage ()
-{
-    cat << HERE
-usage: $PROGNAME <.jar/.apk-file-list>
-    Dumps a summary of the compressed and uncompressed sizes of various
-    types of files in each package.  Emits one line per package.
-    Packages must be zipfiles, readable using "unzip".
-
-    Example output line:
-
-        filesize=642684 all=603288/919304 dex=119529/353815 name="out/App.apk"
-
-    filesize: the size of the package on disk
-    name: the name of the package as passed to $PROGNAME
-
-    These fields are presented as <uncompressed bytes>/<compressed bytes>:
-
-        all: the sum of all entries in the package
-        dex: the sum of all "*.dex" entries in the package
-HERE
-    exit 1
-}
-
-if [ $# -lt 1 ]
-then
-    usage
-fi
-
-UNAME=`uname`
-if [ "x$UNAME" = "xDarwin" ]
-then
-    statArgs="-f %z"
-elif [ "x$UNAME" = "xLinux" ]
-then
-    statArgs="-c %s"
-else
-    fail "Unknown uname $UNAME"
-fi
-
-function printFileSize ()
-{
-    stat $statArgs $1
-}
-
-for file
-do
-    if [ ! -f "$file" ]
-    then
-        fail "$file doesn't exist or isn't a file"
-    fi
-    unzip -lvq "$file" | awk '
-        BEGIN {
-          total_compressed = 0;
-          total_uncompressed = 0;
-          dex_compressed = 0;
-          dex_uncompressed = 0;
-        }
-
-        # Make sure the output of unzip -lv looks like something we expect.
-        #
-        NR == "1" {
-            if (NF != "8" ||
-                $1 != "Length" ||
-                $2 != "Method" ||
-                $3 != "Size" ||
-                ($4 != "Ratio" && $4 != "Cmpr") ||
-                $5 != "Date" ||
-                $6 != "Time" ||
-                $7 != "CRC-32" ||
-                $8 != "Name")
-            {
-                print "'$PROGNAME': ERROR: Unexpected zip listing format" > \
-                        "/dev/stderr";
-                print "'$PROGNAME': ERROR: Line 2 is \"" $0 "\"" > \
-                        "/dev/stderr";
-                failed = 1;
-                exit 1;
-            } else {
-                saw_listing = 1;
-            }
-        }
-
-        # Only look for lines where the ratio is the fourth column;
-        # this filters out the header and footer.
-        #
-        $4 ~ /%$/ {
-            uncompressed = $1;
-            compressed = $3;
-            if ($0 ~ /.dex$/) {
-                dex_compressed += compressed;
-                dex_uncompressed += uncompressed;
-            }
-            total_compressed += compressed;
-            total_uncompressed += uncompressed;
-        }
-        { next }
-
-        END {
-            if (!failed && saw_listing) {
-                print "filesize='$(printFileSize "$file")'",
-                      "all=" total_compressed "/" total_uncompressed,
-                      "dex=" dex_compressed "/" dex_uncompressed,
-                      "name=\"'"$file"'\"";
-            } else {
-                exit 1;
-            }
-        }
-    '
-    if [ $? -ne 0 ]
-    then
-        fail "Could not get stats for $file"
-    fi
-done
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 3732b78..0302856 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -12,6 +12,89 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//
+// Module-specific defaults.
+//
+// For module X, if we need to build it both as a library and an executable:
+//  - A default rule `releasetools_X_defaults` is created, which lists `srcs`, `libs` and
+//    `required` properties.
+//  - `python_library_host` and `python_binary_host` are created by listing
+//    `releasetools_X_defaults` in their defaults.
+//
+
+python_defaults {
+    name: "releasetools_add_img_to_target_files_defaults",
+    srcs: [
+        "add_img_to_target_files.py",
+    ],
+    libs: [
+        "releasetools_build_image",
+        "releasetools_build_super_image",
+        "releasetools_common",
+    ],
+    required: [
+        "care_map_generator",
+    ],
+}
+
+python_defaults {
+    name: "releasetools_build_image_defaults",
+    srcs: [
+        "build_image.py",
+    ],
+    libs: [
+        "releasetools_common",
+        "releasetools_verity_utils",
+    ],
+    required: [
+        "blk_alloc_to_base_fs",
+        "e2fsck",
+        "simg2img",
+        "tune2fs",
+    ],
+}
+
+python_defaults {
+    name: "releasetools_build_super_image_defaults",
+    srcs: [
+        "build_super_image.py",
+    ],
+    libs: [
+        "releasetools_common",
+    ],
+}
+
+python_defaults {
+    name: "releasetools_img_from_target_files_defaults",
+    srcs: [
+        "img_from_target_files.py",
+    ],
+    libs: [
+        "releasetools_build_super_image",
+        "releasetools_common",
+    ],
+}
+
+python_defaults {
+    name: "releasetools_ota_from_target_files_defaults",
+    srcs: [
+        "edify_generator.py",
+        "ota_from_target_files.py",
+        "target_files_diff.py",
+    ],
+    libs: [
+        "releasetools_common",
+        "releasetools_verity_utils",
+    ],
+    required: [
+        "brillo_update_payload",
+    ],
+}
+
+//
+// Host libraries.
+//
+
 python_defaults {
     name: "releasetools_library_defaults",
     version: {
@@ -25,10 +108,37 @@
 }
 
 python_library_host {
-    name: "releasetools_build_super_image",
+    name: "releasetools_add_img_to_target_files",
+    defaults: [
+        "releasetools_library_defaults",
+        "releasetools_add_img_to_target_files_defaults",
+    ],
+}
+
+python_library_host {
+    name: "releasetools_apex_utils",
     defaults: ["releasetools_library_defaults"],
     srcs: [
-        "build_super_image.py",
+        "apex_utils.py",
+    ],
+    libs: [
+        "releasetools_common",
+    ],
+}
+
+python_library_host {
+    name: "releasetools_build_image",
+    defaults: [
+        "releasetools_library_defaults",
+        "releasetools_build_image_defaults",
+    ],
+}
+
+python_library_host {
+    name: "releasetools_build_super_image",
+    defaults: [
+        "releasetools_library_defaults",
+        "releasetools_build_super_image_defaults",
     ],
 }
 
@@ -56,6 +166,22 @@
 }
 
 python_library_host {
+    name: "releasetools_img_from_target_files",
+    defaults: [
+        "releasetools_library_defaults",
+        "releasetools_img_from_target_files_defaults",
+    ],
+}
+
+python_library_host {
+    name: "releasetools_ota_from_target_files",
+    defaults: [
+        "releasetools_library_defaults",
+        "releasetools_ota_from_target_files_defaults",
+    ],
+}
+
+python_library_host {
     name: "releasetools_verity_utils",
     defaults: ["releasetools_library_defaults"],
     srcs: [
@@ -69,6 +195,10 @@
     ],
 }
 
+//
+// Host binaries.
+//
+
 python_defaults {
     name: "releasetools_binary_defaults",
     version: {
@@ -84,34 +214,63 @@
 }
 
 python_binary_host {
+    name: "add_img_to_target_files",
+    defaults: [
+        "releasetools_binary_defaults",
+        "releasetools_add_img_to_target_files_defaults",
+    ],
+}
+
+python_binary_host {
     name: "build_image",
-    defaults: ["releasetools_binary_defaults"],
-    srcs: [
-        "build_image.py",
-    ],
-    main: "build_image.py",
-    libs: [
-        "releasetools_common",
-        "releasetools_verity_utils",
-    ],
-    required: [
-        "blk_alloc_to_base_fs",
-        "e2fsck",
-        "simg2img",
-        "tune2fs",
+    defaults: [
+        "releasetools_binary_defaults",
+        "releasetools_build_image_defaults",
     ],
 }
 
 python_binary_host {
     name: "build_super_image",
+    defaults: [
+        "releasetools_binary_defaults",
+        "releasetools_build_super_image_defaults",
+    ],
+}
+
+python_binary_host {
+    name: "check_ota_package_signature",
     defaults: ["releasetools_binary_defaults"],
     srcs: [
-        "build_super_image.py",
+        "check_ota_package_signature.py",
     ],
-    main: "build_super_image.py",
     libs: [
         "releasetools_common",
     ],
+    required: [
+        "delta_generator",
+    ],
+}
+
+python_binary_host {
+    name: "check_target_files_signatures",
+    defaults: ["releasetools_binary_defaults"],
+    srcs: [
+        "check_target_files_signatures.py",
+    ],
+    libs: [
+        "releasetools_common",
+    ],
+    required: [
+        "aapt",
+    ],
+}
+
+python_binary_host {
+    name: "img_from_target_files",
+    defaults: [
+        "releasetools_binary_defaults",
+        "releasetools_img_from_target_files_defaults",
+    ],
 }
 
 python_binary_host {
@@ -131,7 +290,6 @@
     srcs: [
         "merge_builds.py",
     ],
-    main: "merge_builds.py",
     libs: [
         "releasetools_build_super_image",
         "releasetools_common",
@@ -139,20 +297,34 @@
 }
 
 python_binary_host {
-    name: "ota_from_target_files",
+    name: "merge_target_files",
     defaults: ["releasetools_binary_defaults"],
     srcs: [
-        "edify_generator.py",
-        "ota_from_target_files.py",
-        "target_files_diff.py",
+        "merge_target_files.py",
     ],
-    main: "ota_from_target_files.py",
     libs: [
+        "releasetools_add_img_to_target_files",
+        "releasetools_build_super_image",
         "releasetools_common",
-        "releasetools_verity_utils",
+        "releasetools_img_from_target_files",
+        "releasetools_ota_from_target_files",
     ],
-    required: [
-        "brillo_update_payload",
+}
+
+python_binary_host {
+    name: "ota_from_target_files",
+    defaults: [
+        "releasetools_binary_defaults",
+        "releasetools_ota_from_target_files_defaults",
+    ],
+}
+
+python_binary_host {
+    name: "ota_package_parser",
+    defaults: ["releasetools_binary_defaults"],
+    srcs: [
+        "ota_package_parser.py",
+        "rangelib.py",
     ],
 }
 
@@ -163,33 +335,70 @@
         "rangelib.py",
         "sparse_img.py",
     ],
-    main: "sparse_img.py",
 }
 
+python_binary_host {
+    name: "sign_apex",
+    defaults: ["releasetools_binary_defaults"],
+    srcs: [
+        "sign_apex.py",
+    ],
+    libs: [
+        "releasetools_apex_utils",
+        "releasetools_common",
+    ],
+}
+
+python_binary_host {
+    name: "sign_target_files_apks",
+    defaults: ["releasetools_binary_defaults"],
+    srcs: [
+        "sign_target_files_apks.py",
+    ],
+    libs: [
+        "releasetools_add_img_to_target_files",
+        "releasetools_apex_utils",
+        "releasetools_common",
+    ],
+}
+
+python_binary_host {
+    name: "validate_target_files",
+    defaults: ["releasetools_binary_defaults"],
+    srcs: [
+        "validate_target_files.py",
+    ],
+    libs: [
+        "releasetools_common",
+    ],
+}
+
+//
+// Tests.
+//
+
 python_defaults {
     name: "releasetools_test_defaults",
     srcs: [
-        "add_img_to_target_files.py",
-        "apex_utils.py",
-        "build_image.py",
         "check_ota_package_signature.py",
         "check_target_files_signatures.py",
-        "edify_generator.py",
-        "img_from_target_files.py",
         "make_recovery_patch.py",
         "merge_target_files.py",
-        "ota_from_target_files.py",
         "ota_package_parser.py",
         "sign_apex.py",
         "sign_target_files_apks.py",
-        "target_files_diff.py",
         "validate_target_files.py",
 
         "test_*.py",
     ],
     libs: [
+        "releasetools_add_img_to_target_files",
+        "releasetools_apex_utils",
+        "releasetools_build_image",
         "releasetools_build_super_image",
         "releasetools_common",
+        "releasetools_img_from_target_files",
+        "releasetools_ota_from_target_files",
         "releasetools_verity_utils",
     ],
     data: [
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index cfffbc7..b7ed645 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -781,6 +781,7 @@
   # Regenerate IMAGES in the target directory.
 
   add_img_args = ['--verbose']
+  add_img_args.append('--add_missing')
   if rebuild_recovery:
     add_img_args.append('--rebuild_recovery')
   add_img_args.append(target_files_dir)
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 9715aa1..c6c859c 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -181,6 +181,7 @@
 
 from __future__ import print_function
 
+import collections
 import logging
 import multiprocessing
 import os.path
@@ -859,6 +860,94 @@
                           vendor_updated or odm_updated)
 
 
+def GetBlockDifferences(target_zip, source_zip, target_info, source_info,
+                        device_specific):
+  """Returns a ordered dict of block differences with partition name as key."""
+
+  def GetIncrementalBlockDifferenceForPartition(name):
+    if not HasPartition(source_zip, name):
+      raise RuntimeError("can't generate incremental that adds {}".format(name))
+
+    partition_src = common.GetUserImage(name, OPTIONS.source_tmp, source_zip,
+                                        info_dict=source_info,
+                                        allow_shared_blocks=allow_shared_blocks)
+
+    hashtree_info_generator = verity_utils.CreateHashtreeInfoGenerator(
+        name, 4096, target_info)
+    partition_tgt = common.GetUserImage(name, OPTIONS.target_tmp, target_zip,
+                                        info_dict=target_info,
+                                        allow_shared_blocks=allow_shared_blocks,
+                                        hashtree_info_generator=
+                                        hashtree_info_generator)
+
+    # Check the first block of the source system partition for remount R/W only
+    # if the filesystem is ext4.
+    partition_source_info = source_info["fstab"]["/" + name]
+    check_first_block = partition_source_info.fs_type == "ext4"
+    # Disable using imgdiff for squashfs. 'imgdiff -z' expects input files to be
+    # in zip formats. However with squashfs, a) all files are compressed in LZ4;
+    # b) the blocks listed in block map may not contain all the bytes for a
+    # given file (because they're rounded to be 4K-aligned).
+    partition_target_info = target_info["fstab"]["/" + name]
+    disable_imgdiff = (partition_source_info.fs_type == "squashfs" or
+                       partition_target_info.fs_type == "squashfs")
+    return common.BlockDifference(name, partition_src, partition_tgt,
+                                  check_first_block,
+                                  version=blockimgdiff_version,
+                                  disable_imgdiff=disable_imgdiff)
+
+  if source_zip:
+    # See notes in common.GetUserImage()
+    allow_shared_blocks = (source_info.get('ext4_share_dup_blocks') == "true" or
+                           target_info.get('ext4_share_dup_blocks') == "true")
+    blockimgdiff_version = max(
+        int(i) for i in target_info.get(
+            "blockimgdiff_versions", "1").split(","))
+    assert blockimgdiff_version >= 3
+
+  block_diff_dict = collections.OrderedDict()
+  partition_names = ["system", "vendor", "product", "odm", "system_ext"]
+  for partition in partition_names:
+    if not HasPartition(target_zip, partition):
+      continue
+    # Full OTA update.
+    if not source_zip:
+      tgt = common.GetUserImage(partition, OPTIONS.input_tmp, target_zip,
+                                info_dict=target_info,
+                                reset_file_map=True)
+      block_diff_dict[partition] = common.BlockDifference(partition, tgt,
+                                                          src=None)
+    # Incremental OTA update.
+    else:
+      block_diff_dict[partition] = GetIncrementalBlockDifferenceForPartition(
+          partition)
+  assert "system" in block_diff_dict
+
+  # Get the block diffs from the device specific script. If there is a
+  # duplicate block diff for a partition, ignore the diff in the generic script
+  # and use the one in the device specific script instead.
+  if source_zip:
+    device_specific_diffs = device_specific.IncrementalOTA_GetBlockDifferences()
+    function_name = "IncrementalOTA_GetBlockDifferences"
+  else:
+    device_specific_diffs = device_specific.FullOTA_GetBlockDifferences()
+    function_name = "FullOTA_GetBlockDifferences"
+
+  if device_specific_diffs:
+    assert all(isinstance(diff, common.BlockDifference)
+               for diff in device_specific_diffs), \
+        "{} is not returning a list of BlockDifference objects".format(
+            function_name)
+    for diff in device_specific_diffs:
+      if diff.partition in block_diff_dict:
+        logger.warning("Duplicate block difference found. Device specific block"
+                       " diff for partition '%s' overrides the one in generic"
+                       " script.", diff.partition)
+      block_diff_dict[diff.partition] = diff
+
+  return block_diff_dict
+
+
 def WriteFullOTAPackage(input_zip, output_file):
   target_info = BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
 
@@ -900,6 +989,11 @@
   target_info.WriteDeviceAssertions(script, OPTIONS.oem_no_mount)
   device_specific.FullOTA_Assertions()
 
+  block_diff_dict = GetBlockDifferences(target_zip=input_zip, source_zip=None,
+                                        target_info=target_info,
+                                        source_info=None,
+                                        device_specific=device_specific)
+
   # Two-step package strategy (in chronological order, which is *not*
   # the order in which the generated script has things):
   #
@@ -951,52 +1045,25 @@
 
   device_specific.FullOTA_InstallBegin()
 
-  system_progress = 0.75
-
+  # All other partitions as well as the data wipe use 10% of the progress, and
+  # the update of the system partition takes the remaining progress.
+  system_progress = 0.9 - (len(block_diff_dict) - 1) * 0.1
   if OPTIONS.wipe_user_data:
     system_progress -= 0.1
-  if HasVendorPartition(input_zip):
-    system_progress -= 0.1
-
-  script.ShowProgress(system_progress, 0)
-
-  def GetBlockDifference(partition):
-    # Full OTA is done as an "incremental" against an empty source image. This
-    # has the effect of writing new data from the package to the entire
-    # partition, but lets us reuse the updater code that writes incrementals to
-    # do it.
-    tgt = common.GetUserImage(partition, OPTIONS.input_tmp, input_zip,
-                              info_dict=target_info,
-                              reset_file_map=True)
-    diff = common.BlockDifference(partition, tgt, src=None)
-    return diff
-
-  device_specific_diffs = device_specific.FullOTA_GetBlockDifferences()
-  if device_specific_diffs:
-    assert all(isinstance(diff, common.BlockDifference)
-               for diff in device_specific_diffs), \
-        "FullOTA_GetBlockDifferences is not returning a list of " \
-        "BlockDifference objects"
-
-  progress_dict = dict()
-  block_diffs = [GetBlockDifference("system")]
-  if HasVendorPartition(input_zip):
-    block_diffs.append(GetBlockDifference("vendor"))
-    progress_dict["vendor"] = 0.1
-  if device_specific_diffs:
-    block_diffs += device_specific_diffs
+  progress_dict = {partition: 0.1 for partition in block_diff_dict}
+  progress_dict["system"] = system_progress
 
   if target_info.get('use_dynamic_partitions') == "true":
     # Use empty source_info_dict to indicate that all partitions / groups must
     # be re-added.
     dynamic_partitions_diff = common.DynamicPartitionsDifference(
         info_dict=OPTIONS.info_dict,
-        block_diffs=block_diffs,
+        block_diffs=block_diff_dict.values(),
         progress_dict=progress_dict)
     dynamic_partitions_diff.WriteScript(script, output_zip,
                                         write_verify_script=OPTIONS.verify)
   else:
-    for block_diff in block_diffs:
+    for block_diff in block_diff_dict.values():
       block_diff.WriteScript(script, output_zip,
                              progress=progress_dict.get(block_diff.partition),
                              write_verify_script=OPTIONS.verify)
@@ -1008,10 +1075,9 @@
   common.CheckSize(boot_img.data, "boot.img", target_info)
   common.ZipWriteStr(output_zip, "boot.img", boot_img.data)
 
-  script.ShowProgress(0.05, 5)
   script.WriteRawImage("/boot", "boot.img")
 
-  script.ShowProgress(0.2, 10)
+  script.ShowProgress(0.1, 10)
   device_specific.FullOTA_InstallEnd()
 
   if OPTIONS.extra_script is not None:
@@ -1571,66 +1637,11 @@
   target_recovery = common.GetBootableImage(
       "/tmp/recovery.img", "recovery.img", OPTIONS.target_tmp, "RECOVERY")
 
-  # See notes in common.GetUserImage()
-  allow_shared_blocks = (source_info.get('ext4_share_dup_blocks') == "true" or
-                         target_info.get('ext4_share_dup_blocks') == "true")
-  system_src = common.GetUserImage("system", OPTIONS.source_tmp, source_zip,
-                                   info_dict=source_info,
-                                   allow_shared_blocks=allow_shared_blocks)
-
-  hashtree_info_generator = verity_utils.CreateHashtreeInfoGenerator(
-      "system", 4096, target_info)
-  system_tgt = common.GetUserImage("system", OPTIONS.target_tmp, target_zip,
-                                   info_dict=target_info,
-                                   allow_shared_blocks=allow_shared_blocks,
-                                   hashtree_info_generator=
-                                   hashtree_info_generator)
-
-  blockimgdiff_version = max(
-      int(i) for i in target_info.get("blockimgdiff_versions", "1").split(","))
-  assert blockimgdiff_version >= 3
-
-  # Check the first block of the source system partition for remount R/W only
-  # if the filesystem is ext4.
-  system_src_partition = source_info["fstab"]["/system"]
-  check_first_block = system_src_partition.fs_type == "ext4"
-  # Disable using imgdiff for squashfs. 'imgdiff -z' expects input files to be
-  # in zip formats. However with squashfs, a) all files are compressed in LZ4;
-  # b) the blocks listed in block map may not contain all the bytes for a given
-  # file (because they're rounded to be 4K-aligned).
-  system_tgt_partition = target_info["fstab"]["/system"]
-  disable_imgdiff = (system_src_partition.fs_type == "squashfs" or
-                     system_tgt_partition.fs_type == "squashfs")
-  system_diff = common.BlockDifference("system", system_tgt, system_src,
-                                       check_first_block,
-                                       version=blockimgdiff_version,
-                                       disable_imgdiff=disable_imgdiff)
-
-  if HasVendorPartition(target_zip):
-    if not HasVendorPartition(source_zip):
-      raise RuntimeError("can't generate incremental that adds /vendor")
-    vendor_src = common.GetUserImage("vendor", OPTIONS.source_tmp, source_zip,
-                                     info_dict=source_info,
-                                     allow_shared_blocks=allow_shared_blocks)
-    hashtree_info_generator = verity_utils.CreateHashtreeInfoGenerator(
-        "vendor", 4096, target_info)
-    vendor_tgt = common.GetUserImage(
-        "vendor", OPTIONS.target_tmp, target_zip,
-        info_dict=target_info,
-        allow_shared_blocks=allow_shared_blocks,
-        hashtree_info_generator=hashtree_info_generator)
-
-    # Check first block of vendor partition for remount R/W only if
-    # disk type is ext4
-    vendor_partition = source_info["fstab"]["/vendor"]
-    check_first_block = vendor_partition.fs_type == "ext4"
-    disable_imgdiff = vendor_partition.fs_type == "squashfs"
-    vendor_diff = common.BlockDifference("vendor", vendor_tgt, vendor_src,
-                                         check_first_block,
-                                         version=blockimgdiff_version,
-                                         disable_imgdiff=disable_imgdiff)
-  else:
-    vendor_diff = None
+  block_diff_dict = GetBlockDifferences(target_zip=target_zip,
+                                        source_zip=source_zip,
+                                        target_info=target_info,
+                                        source_info=source_info,
+                                        device_specific=device_specific)
 
   AddCompatibilityArchiveIfTrebleEnabled(
       target_zip, output_zip, target_info, source_info)
@@ -1697,12 +1708,8 @@
   WriteFingerprintAssertion(script, target_info, source_info)
 
   # Check the required cache size (i.e. stashed blocks).
-  size = []
-  if system_diff:
-    size.append(system_diff.required_cache)
-  if vendor_diff:
-    size.append(vendor_diff.required_cache)
-
+  required_cache_sizes = [diff.required_cache for diff in
+                          block_diff_dict.values()]
   if updating_boot:
     boot_type, boot_device = common.GetTypeAndDevice("/boot", source_info)
     d = common.Difference(target_boot, source_boot)
@@ -1725,10 +1732,14 @@
           "{}:{}:{}:{}".format(
               boot_type, boot_device, source_boot.size, source_boot.sha1))
 
-      size.append(target_boot.size)
+      required_cache_sizes.append(target_boot.size)
 
-  if size:
-    script.CacheFreeSpaceCheck(max(size))
+  if required_cache_sizes:
+    script.CacheFreeSpaceCheck(max(required_cache_sizes))
+
+  # Verify the existing partitions.
+  for diff in block_diff_dict.values():
+    diff.WriteVerifyScript(script, touched_blocks_only=True)
 
   device_specific.IncrementalOTA_VerifyEnd()
 
@@ -1745,30 +1756,12 @@
     # Stage 3/3: Make changes.
     script.Comment("Stage 3/3")
 
-  # Verify the existing partitions.
-  system_diff.WriteVerifyScript(script, touched_blocks_only=True)
-  if vendor_diff:
-    vendor_diff.WriteVerifyScript(script, touched_blocks_only=True)
-  device_specific_diffs = device_specific.IncrementalOTA_GetBlockDifferences()
-  if device_specific_diffs:
-    assert all(isinstance(diff, common.BlockDifference)
-               for diff in device_specific_diffs), \
-        "IncrementalOTA_GetBlockDifferences is not returning a list of " \
-        "BlockDifference objects"
-    for diff in device_specific_diffs:
-      diff.WriteVerifyScript(script, touched_blocks_only=True)
-
   script.Comment("---- start making changes here ----")
 
   device_specific.IncrementalOTA_InstallBegin()
 
-  block_diffs = [system_diff]
-  progress_dict = {"system": 0.8 if vendor_diff else 0.9}
-  if vendor_diff:
-    block_diffs.append(vendor_diff)
-    progress_dict["vendor"] = 0.1
-  if device_specific_diffs:
-    block_diffs += device_specific_diffs
+  progress_dict = {partition: 0.1 for partition in block_diff_dict}
+  progress_dict["system"] = 1 - len(block_diff_dict) * 0.1
 
   if OPTIONS.source_info_dict.get("use_dynamic_partitions") == "true":
     if OPTIONS.target_info_dict.get("use_dynamic_partitions") != "true":
@@ -1777,12 +1770,12 @@
     dynamic_partitions_diff = common.DynamicPartitionsDifference(
         info_dict=OPTIONS.target_info_dict,
         source_info_dict=OPTIONS.source_info_dict,
-        block_diffs=block_diffs,
+        block_diffs=block_diff_dict.values(),
         progress_dict=progress_dict)
     dynamic_partitions_diff.WriteScript(
         script, output_zip, write_verify_script=OPTIONS.verify)
   else:
-    for block_diff in block_diffs:
+    for block_diff in block_diff_dict.values():
       block_diff.WriteScript(script, output_zip,
                              progress=progress_dict.get(block_diff.partition),
                              write_verify_script=OPTIONS.verify)