Merge "Change emulator system image to unsparse format"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 76bc0c5..757c513 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -615,6 +615,11 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/security/avb/)
 
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/super.img)
+
+$(call add-clean-step, find $(PRODUCT_OUT) -type f -name "generated_*_image_info.txt" -print0 | xargs -0 rm -f)
+
+# Clean up libicuuc.so and libicui18n.so
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib*/libicu*)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/Makefile b/core/Makefile
index 97bbebe..78ef81f 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -280,10 +280,6 @@
 	        echo "#" >> $@;
 	$(hide) $(foreach line,$(FINAL_DEFAULT_PROPERTIES), \
 	    echo "$(line)" >> $@;)
-	$(hide) echo "#" >> $@; \
-	        echo "# BOOTIMAGE_BUILD_PROPERTIES" >> $@; \
-	        echo "#" >> $@;
-	$(hide) $(call generate-common-build-props,bootimage,$@)
 	$(hide) build/make/tools/post_process_props.py $@
 ifdef property_overrides_split_enabled
 	$(hide) mkdir -p $(TARGET_ROOT_OUT)
@@ -329,7 +325,7 @@
 # non-default dev keys (usually private keys from a vendor directory).
 # Both of these tags will be removed and replaced with "release-keys"
 # when the target-files is signed in a post-build step.
-ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),build/target/product/security/testkey)
+ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),build/make/target/product/security/testkey)
 BUILD_KEYS := test-keys
 else
 BUILD_KEYS := dev-keys
@@ -487,7 +483,6 @@
 	            echo "#" >> $@; )
 	$(hide) $(foreach line,$(FINAL_BUILD_PROPERTIES), \
 	    echo "$(line)" >> $@;)
-	$(hide) cat $(INSTALLED_ANDROID_INFO_TXT_TARGET) | grep 'require version-' | sed -e 's/require version-/ro.build.expect./g' >> $@
 	$(hide) build/make/tools/post_process_props.py $@ $(PRODUCT_SYSTEM_PROPERTY_BLACKLIST)
 
 build_desc :=
@@ -528,10 +523,15 @@
 	$(hide) echo ro.product.board="$(TARGET_BOOTLOADER_BOARD_NAME)">>$@
 	$(hide) echo ro.board.platform="$(TARGET_BOARD_PLATFORM)">>$@
 	$(hide) $(call generate-common-build-props,vendor,$@)
-ifdef property_overrides_split_enabled
+	$(hide) echo "#" >> $@; \
+	        echo "# BOOTIMAGE_BUILD_PROPERTIES" >> $@; \
+	        echo "#" >> $@;
+	$(hide) $(call generate-common-build-props,bootimage,$@)
 	$(hide) echo "#" >> $@; \
 	        echo "# ADDITIONAL VENDOR BUILD PROPERTIES" >> $@; \
 	        echo "#" >> $@;
+	$(hide) cat $(INSTALLED_ANDROID_INFO_TXT_TARGET) | grep 'require version-' | sed -e 's/require version-/ro.build.expect./g' >> $@
+ifdef property_overrides_split_enabled
 	$(hide) $(foreach line,$(FINAL_VENDOR_BUILD_PROPERTIES), \
 	    echo "$(line)" >> $@;)
 endif  # property_overrides_split_enabled
@@ -2238,7 +2238,6 @@
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       build/make/tools/releasetools/build_image.py \
       $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) $(TARGET_OUT) \
-      $(systemimage_intermediates)/generated_system_image_info.txt \
       || ( mkdir -p $${DIST_DIR}; cp $(INSTALLED_FILES_FILE) $${DIST_DIR}/installed-files-rescued.txt; \
            exit 1 )
 endef
@@ -2286,22 +2285,7 @@
 $(INSTALLED_SYSTEMIMAGE_TARGET): $(BUILT_SYSTEMIMAGE) $(RECOVERY_FROM_BOOT_PATCH)
 	@echo "Install system fs image: $@"
 	$(copy-file-to-target)
-ifdef RECOVERY_FROM_BOOT_PATCH
-ifeq ($(PRODUCT_USE_DYNAMIC_PARTITION_SIZE),true)
-ifeq ($(BOARD_SYSTEMIMAGE_PARTITION_SIZE),)
-	# system image size is dynamic, hence system_size in generated_system_image_info.txt does not
-	# have room for recovery from boot patch. Increase system_size so that check-all-partition-sizes
-	# accounts for the size of the patch.
-	sed -i'.bak' -e 's/^system_size=.*$$/system_size='"$$(( \
-	      $(call read-image-prop-dictionary,$(systemimage_intermediates)/generated_system_image_info.txt,system_size) + \
-	      $$($(call get-file-size,$(RECOVERY_FROM_BOOT_PATCH))) ))"'/' \
-	    $(systemimage_intermediates)/generated_system_image_info.txt
-endif
-endif
-endif
-	$(hide) $(call assert-max-image-size,$@ $(RECOVERY_FROM_BOOT_PATCH),\
-	    $(call read-image-prop-dictionary,\
-	        $(systemimage_intermediates)/generated_system_image_info.txt,system_size))
+	$(hide) $(call assert-max-image-size,$@ $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
 
 systemimage: $(INSTALLED_SYSTEMIMAGE_TARGET)
 
@@ -2310,9 +2294,7 @@
 	            | $(INTERNAL_USERIMAGES_DEPS)
 	@echo "make $@: ignoring dependencies"
 	$(call build-systemimage-target,$(INSTALLED_SYSTEMIMAGE_TARGET))
-	$(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMIMAGE_TARGET),\
-	    $(call read-image-prop-dictionary,\
-	        $(systemimage_intermediates)/generated_system_image_info.txt,system_size))
+	$(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMIMAGE_TARGET),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
 
 ifneq (,$(filter systemimage-nodeps snod, $(MAKECMDGOALS)))
 ifeq (true,$(WITH_DEXPREOPT))
@@ -2678,11 +2660,8 @@
   $(call generate-image-prop-dictionary, $(systemotherimage_intermediates)/system_other_image_info.txt,system,skip_fsck=true)
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       build/make/tools/releasetools/build_image.py \
-      $(TARGET_OUT_SYSTEM_OTHER) $(systemotherimage_intermediates)/system_other_image_info.txt $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) $(TARGET_OUT)\
-      $(systemotherimage_intermediates)/generated_system_other_image_info.txt
-  $(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),\
-    $(call read-image-prop-dictionary,\
-      $(systemotherimage_intermediates)/generated_system_other_image_info.txt,system_other_size))
+      $(TARGET_OUT_SYSTEM_OTHER) $(systemotherimage_intermediates)/system_other_image_info.txt $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) $(TARGET_OUT)
+  $(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
 endef
 
 # We just build this directly to the install location.
@@ -2821,11 +2800,8 @@
     $(call build-image-kernel-modules,$(BOARD_VENDOR_KERNEL_MODULES),$(TARGET_OUT_VENDOR),vendor/,$(call intermediates-dir-for,PACKAGING,depmod_vendor)))
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       build/make/tools/releasetools/build_image.py \
-      $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt $(INSTALLED_VENDORIMAGE_TARGET) $(TARGET_OUT) \
-      $(vendorimage_intermediates)/generated_vendor_image_info.txt
-  $(hide) $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET),\
-      $(call read-image-prop-dictionary,\
-          $(vendorimage_intermediates)/generated_vendor_image_info.txt,vendor_size))
+      $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt $(INSTALLED_VENDORIMAGE_TARGET) $(TARGET_OUT)
+  $(hide) $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET),$(BOARD_VENDORIMAGE_PARTITION_SIZE))
 endef
 
 # We just build this directly to the install location.
@@ -2879,11 +2855,8 @@
   $(call generate-image-prop-dictionary, $(productimage_intermediates)/product_image_info.txt,product,skip_fsck=true)
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       ./build/tools/releasetools/build_image.py \
-      $(TARGET_OUT_PRODUCT) $(productimage_intermediates)/product_image_info.txt $(INSTALLED_PRODUCTIMAGE_TARGET) $(TARGET_OUT) \
-      $(productimage_intermediates)/generated_product_image_info.txt
-  $(hide) $(call assert-max-image-size,$(INSTALLED_PRODUCTIMAGE_TARGET),\
-      $(call read-image-prop-dictionary,\
-          $(productimage_intermediates)/generated_product_image_info.txt,product_size))
+      $(TARGET_OUT_PRODUCT) $(productimage_intermediates)/product_image_info.txt $(INSTALLED_PRODUCTIMAGE_TARGET) $(TARGET_OUT)
+  $(hide) $(call assert-max-image-size,$(INSTALLED_PRODUCTIMAGE_TARGET),$(BOARD_PRODUCTIMAGE_PARTITION_SIZE))
 endef
 
 # We just build this directly to the install location.
@@ -2934,11 +2907,8 @@
   $(call generate-image-prop-dictionary, $(product_servicesimage_intermediates)/product_services_image_info.txt,product_services, skip_fsck=true)
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       ./build/tools/releasetools/build_image.py \
-      $(TARGET_OUT_PRODUCT_SERVICES) $(product_servicesimage_intermediates)/product_services_image_info.txt $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) $(TARGET_OUT) \
-      $(product_servicesimage_intermediates)/generated_product_services_image_info.txt
-  $(hide) $(call assert-max-image-size,$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET),\
-      $(call read-image-prop-dictionary,\
-          $(product_servicesimage_intermediates)/generated_product_services_image_info.txt,product_services_size))
+      $(TARGET_OUT_PRODUCT_SERVICES) $(product_servicesimage_intermediates)/product_services_image_info.txt $(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET) $(TARGET_OUT)
+  $(hide) $(call assert-max-image-size,$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET),$(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE))
 endef
 
 # We just build this directly to the install location.
@@ -2990,11 +2960,8 @@
     $(call build-image-kernel-modules,$(BOARD_ODM_KERNEL_MODULES),$(TARGET_OUT_ODM),odm/,$(call intermediates-dir-for,PACKAGING,depmod_odm)))
   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
       ./build/tools/releasetools/build_image.py \
-      $(TARGET_OUT_ODM) $(odmimage_intermediates)/odm_image_info.txt $(INSTALLED_ODMIMAGE_TARGET) $(TARGET_OUT) \
-	  $(odmimage_intermediates)/generated_odm_image_info.txt
-  $(hide) $(call assert-max-image-size,$(INSTALLED_ODMIMAGE_TARGET),\
-      $(call read-image-prop-dictionary,\
-          $(odmimage_intermediates)/generated_odm_image_info.txt,odm_size))
+      $(TARGET_OUT_ODM) $(odmimage_intermediates)/odm_image_info.txt $(INSTALLED_ODMIMAGE_TARGET) $(TARGET_OUT)
+  $(hide) $(call assert-max-image-size,$(INSTALLED_ODMIMAGE_TARGET),$(BOARD_ODMIMAGE_PARTITION_SIZE))
 endef
 
 # We just build this directly to the install location.
@@ -3364,7 +3331,8 @@
 # (1): list of items like "system", "vendor", "product", "product_services"
 # return: map each item into a command ( wrapped in $$() ) that reads the size
 define read-size-of-partitions
-$(foreach p,$(1),$(call read-image-prop-dictionary,$($(p)image_intermediates)/generated_$(p)_image_info.txt,$(p)_size))
+$(foreach image,$(call images-for-partitions,$(1)),$$( \
+    build/make/tools/releasetools/sparse_img.py --get_partition_size $(image)))
 endef
 
 # round result to BOARD_SUPER_PARTITION_ALIGNMENT
@@ -3388,7 +3356,9 @@
 .PHONY: check-all-partition-sizes check-all-partition-sizes-nodeps
 
 # Add image dependencies so that generated_*_image_info.txt are written before checking.
-check-all-partition-sizes: $(call images-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))
+check-all-partition-sizes: \
+    build/make/tools/releasetools/sparse_img.py \
+    $(call images-for-partitions,$(BOARD_SUPER_PARTITION_PARTITION_LIST))
 
 ifeq ($(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS),true)
 # Check sum(super partition block devices) == super partition
@@ -3475,7 +3445,7 @@
   build_ota_package := false
   build_otatools_package := false
 else
-  # set build_ota_package, and allow opt-out below
+  # Set build_ota_package, and allow opt-out below.
   build_ota_package := true
   ifeq ($(TARGET_SKIP_OTA_PACKAGE),true)
     build_ota_package := false
@@ -3486,20 +3456,22 @@
   ifeq ($(TARGET_PRODUCT),sdk)
     build_ota_package := false
   endif
-  ifneq ($(filter generic%,$(TARGET_DEVICE)),)
-    build_ota_package := false
-  endif
-  ifeq ($(TARGET_NO_KERNEL),true)
-    build_ota_package := false
-  endif
-  ifeq ($(recovery_fstab),)
-    build_ota_package := false
-  endif
   ifeq ($(TARGET_BUILD_PDK),true)
     build_ota_package := false
   endif
+  ifneq ($(PRODUCT_BUILD_GENERIC_OTA_PACKAGE),true)
+    ifneq ($(filter generic%,$(TARGET_DEVICE)),)
+      build_ota_package := false
+    endif
+    ifeq ($(TARGET_NO_KERNEL),true)
+      build_ota_package := false
+    endif
+    ifeq ($(recovery_fstab),)
+      build_ota_package := false
+    endif
+  endif # PRODUCT_BUILD_GENERIC_OTA_PACKAGE
 
-  # set build_otatools_package, and allow opt-out below
+  # Set build_otatools_package, and allow opt-out below.
   build_otatools_package := true
   ifeq ($(TARGET_SKIP_OTATOOLS_PACKAGE),true)
     build_otatools_package := false
@@ -3599,7 +3571,7 @@
 
 OTATOOLS_DEPS := \
   system/extras/ext4_utils/mke2fs.conf \
-  $(sort $(shell find build/target/product/security -type f -name "*.x509.pem" -o -name "*.pk8" -o \
+  $(sort $(shell find build/make/target/product/security -type f -name "*.x509.pem" -o -name "*.pk8" -o \
       -name verity_key))
 
 ifneq (,$(wildcard device))
@@ -3745,6 +3717,8 @@
     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);))
+  $(if $(filter true,$(TARGET_USERIMAGES_SPARSE_EXT_DISABLED)), \
+    echo "build_non_sparse_super_partition=true" >> $(1))
 endef
 
 # Depending on the various images guarantees that the underlying
@@ -3953,6 +3927,9 @@
 	$(hide) echo 'mkbootimg_version_args=$(INTERNAL_MKBOOTIMG_VERSION_ARGS)' >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "multistage_support=1" >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "blockimgdiff_versions=3,4" >> $(zip_root)/META/misc_info.txt
+ifeq ($(PRODUCT_BUILD_GENERIC_OTA_PACKAGE),true)
+	$(hide) echo "build_generic_ota_package=true" >> $(zip_root)/META/misc_info.txt
+endif
 ifneq ($(OEM_THUMBPRINT_PROPERTIES),)
 	# OTA scripts are only interested in fingerprint related properties
 	$(hide) echo "oem_fingerprint_properties=$(OEM_THUMBPRINT_PROPERTIES)" >> $(zip_root)/META/misc_info.txt
@@ -4445,6 +4422,7 @@
 	$(call dump-super-image-info,$(intermediates)/misc_info.txt)
 	$(foreach p,$(BOARD_SUPER_PARTITION_PARTITION_LIST), \
 	  echo "$(p)_image=$(INSTALLED_$(call to-upper,$(p))IMAGE_TARGET)" >> $(intermediates)/misc_info.txt;)
+	mkdir -p $(dir $(INSTALLED_SUPERIMAGE_TARGET))
 	PATH=$(dir $(LPMAKE)):$$PATH \
 	  $(BUILD_SUPER_IMAGE) -v $(intermediates)/misc_info.txt $(INSTALLED_SUPERIMAGE_TARGET)
 
diff --git a/core/base_rules.mk b/core/base_rules.mk
index f477eda..94aa1e4 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -224,15 +224,15 @@
 ifdef LOCAL_IS_HOST_MODULE
   partition_tag :=
 else
-ifeq (true,$(LOCAL_VENDOR_MODULE))
+ifeq (true,$(strip $(LOCAL_VENDOR_MODULE)))
   partition_tag := _VENDOR
-else ifeq (true,$(LOCAL_OEM_MODULE))
+else ifeq (true,$(strip $(LOCAL_OEM_MODULE)))
   partition_tag := _OEM
-else ifeq (true,$(LOCAL_ODM_MODULE))
+else ifeq (true,$(strip $(LOCAL_ODM_MODULE)))
   partition_tag := _ODM
-else ifeq (true,$(LOCAL_PRODUCT_MODULE))
+else ifeq (true,$(strip $(LOCAL_PRODUCT_MODULE)))
   partition_tag := _PRODUCT
-else ifeq (true,$(LOCAL_PRODUCT_SERVICES_MODULE))
+else ifeq (true,$(strip $(LOCAL_PRODUCT_SERVICES_MODULE)))
   partition_tag := _PRODUCT_SERVICES
 else ifeq (NATIVE_TESTS,$(LOCAL_MODULE_CLASS))
   partition_tag := _DATA
@@ -760,6 +760,18 @@
 ## Register with ALL_MODULES
 ###########################################################
 
+ifeq ($(filter $(my_register_name),$(ALL_MODULES)),)
+    # These keys are no longer used, they've been replaced by keys that specify
+    # target/host/host_cross (REQUIRED_FROM_TARGET / REQUIRED_FROM_HOST) and similar.
+    #
+    # Marking them obsolete to ensure that anyone using these internal variables looks for
+    # alternates.
+    $(KATI_obsolete_var ALL_MODULES.$(my_register_name).REQUIRED)
+    $(KATI_obsolete_var ALL_MODULES.$(my_register_name).EXPLICITLY_REQUIRED)
+    $(KATI_obsolete_var ALL_MODULES.$(my_register_name).HOST_REQUIRED)
+    $(KATI_obsolete_var ALL_MODULES.$(my_register_name).TARGET_REQUIRED)
+endif
+
 ALL_MODULES += $(my_register_name)
 
 # Don't use += on subvars, or else they'll end up being
@@ -820,17 +832,42 @@
   endif
 endif
 
-ALL_MODULES.$(my_register_name).REQUIRED := \
-    $(strip $(ALL_MODULES.$(my_register_name).REQUIRED) $(my_required_modules))
-ALL_MODULES.$(my_register_name).EXPLICITLY_REQUIRED := \
-    $(strip $(ALL_MODULES.$(my_register_name).EXPLICITLY_REQUIRED)\
-        $(my_required_modules))
-ALL_MODULES.$(my_register_name).TARGET_REQUIRED := \
-    $(strip $(ALL_MODULES.$(my_register_name).TARGET_REQUIRED)\
-        $(LOCAL_TARGET_REQUIRED_MODULES))
-ALL_MODULES.$(my_register_name).HOST_REQUIRED := \
-    $(strip $(ALL_MODULES.$(my_register_name).HOST_REQUIRED)\
-        $(LOCAL_HOST_REQUIRED_MODULES))
+ifdef LOCAL_IS_HOST_MODULE
+    ifneq ($(my_host_cross),true)
+        ALL_MODULES.$(my_register_name).REQUIRED_FROM_HOST := \
+            $(strip $(ALL_MODULES.$(my_register_name).REQUIRED_FROM_HOST) $(my_required_modules))
+        ALL_MODULES.$(my_register_name).EXPLICITLY_REQUIRED_FROM_HOST := \
+            $(strip $(ALL_MODULES.$(my_register_name).EXPLICITLY_REQUIRED_FROM_HOST)\
+                $(my_required_modules))
+        ALL_MODULES.$(my_register_name).TARGET_REQUIRED_FROM_HOST := \
+            $(strip $(ALL_MODULES.$(my_register_name).TARGET_REQUIRED_FROM_HOST)\
+                $(LOCAL_TARGET_REQUIRED_MODULES))
+    else
+        ALL_MODULES.$(my_register_name).REQUIRED_FROM_HOST_CROSS := \
+            $(strip $(ALL_MODULES.$(my_register_name).REQUIRED_FROM_HOST_CROSS) $(my_required_modules))
+        ALL_MODULES.$(my_register_name).EXPLICITLY_REQUIRED_FROM_HOST_CROSS := \
+            $(strip $(ALL_MODULES.$(my_register_name).EXPLICITLY_REQUIRED_FROM_HOST_CROSS)\
+                $(my_required_modules))
+        ifdef LOCAL_TARGET_REQUIRED_MODULES
+            $(call pretty-error,LOCAL_TARGET_REQUIRED_MODULES may not be used from host_cross modules)
+        endif
+    endif
+    ifdef LOCAL_HOST_REQUIRED_MODULES
+        $(call pretty-error,LOCAL_HOST_REQUIRED_MODULES may not be used from host modules. Use LOCAL_REQUIRED_MODULES instead)
+    endif
+else
+    ALL_MODULES.$(my_register_name).REQUIRED_FROM_TARGET := \
+        $(strip $(ALL_MODULES.$(my_register_name).REQUIRED_FROM_TARGET) $(my_required_modules))
+    ALL_MODULES.$(my_register_name).EXPLICITLY_REQUIRED_FROM_TARGET := \
+        $(strip $(ALL_MODULES.$(my_register_name).EXPLICITLY_REQUIRED_FROM_TARGET)\
+            $(my_required_modules))
+    ALL_MODULES.$(my_register_name).HOST_REQUIRED_FROM_TARGET := \
+        $(strip $(ALL_MODULES.$(my_register_name).HOST_REQUIRED_FROM_TARGET)\
+            $(LOCAL_HOST_REQUIRED_MODULES))
+    ifdef LOCAL_TARGET_REQUIRED_MODULES
+        $(call pretty-error,LOCAL_TARGET_REQUIRED_MODULES may not be used from target modules. Use LOCAL_REQUIRED_MODULES instead)
+    endif
+endif
 ALL_MODULES.$(my_register_name).EVENT_LOG_TAGS := \
     $(ALL_MODULES.$(my_register_name).EVENT_LOG_TAGS) $(event_log_tags)
 ALL_MODULES.$(my_register_name).MAKEFILE := \
diff --git a/core/binary.mk b/core/binary.mk
index da188ae..f3a50f1 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1538,11 +1538,10 @@
 
 # Add dependency of clang-tidy and clang-tidy.sh
 ifneq ($(my_tidy_checks),)
-  my_clang_tidy_programs := $(PATH_TO_CLANG_TIDY) $(PATH_TO_CLANG_TIDY_SHELL)
-  $(cpp_objects): $(intermediates)/%.o: $(my_clang_tidy_programs)
-  $(c_objects): $(intermediates)/%.o: $(my_clang_tidy_programs)
-  $(gen_cpp_objects): $(intermediates)/%.o: $(my_clang_tidy_programs)
-  $(gen_c_objects): $(intermediates)/%.o: $(my_clang_tidy_programs)
+  $(cpp_objects): $(intermediates)/%.o: $(PATH_TO_CLANG_TIDY)
+  $(c_objects): $(intermediates)/%.o: $(PATH_TO_CLANG_TIDY)
+  $(gen_cpp_objects): $(intermediates)/%.o: $(PATH_TO_CLANG_TIDY)
+  $(gen_c_objects): $(intermediates)/%.o: $(PATH_TO_CLANG_TIDY)
 endif
 
 # Move -l* entries from ldflags to ldlibs, and everything else to ldflags
diff --git a/core/board_config.mk b/core/board_config.mk
index ed741c3..d32e301 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -44,6 +44,7 @@
   TARGET_BOARD_PLATFORM \
   TARGET_BOARD_PLATFORM_GPU \
   TARGET_BOOTLOADER_BOARD_NAME \
+  TARGET_FS_CONFIG_GEN \
   TARGET_NO_BOOTLOADER \
   TARGET_NO_KERNEL \
   TARGET_NO_RECOVERY \
@@ -89,6 +90,7 @@
   BUILD_BROKEN_DUP_RULES \
   BUILD_BROKEN_PHONY_TARGETS \
   BUILD_BROKEN_ENG_DEBUG_TAGS \
+  BUILD_BROKEN_USES_NETWORK \
 
 _board_true_false_vars := $(_build_broken_var_list)
 _board_strip_readonly_list += $(_build_broken_var_list)
@@ -101,11 +103,7 @@
 # ###############################################################
 # Broken build defaults
 # ###############################################################
-BUILD_BROKEN_ANDROIDMK_EXPORTS :=
-BUILD_BROKEN_DUP_COPY_HEADERS :=
-BUILD_BROKEN_DUP_RULES :=
-BUILD_BROKEN_PHONY_TARGETS :=
-BUILD_BROKEN_ENG_DEBUG_TAGS :=
+$(foreach v,$(_build_broken_var_list),$(eval $(v) :=))
 
 # Boards may be defined under $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)
 # or under vendor/*/$(TARGET_DEVICE).  Search in both places, but
@@ -478,6 +476,13 @@
   endif
 endif
 
+# Sanity check for building generic OTA packages. Currently it only supports A/B OTAs.
+ifeq ($(PRODUCT_BUILD_GENERIC_OTA_PACKAGE),true)
+  ifneq ($(AB_OTA_UPDATER),true)
+    $(error PRODUCT_BUILD_GENERIC_OTA_PACKAGE with 'AB_OTA_UPDATER != true' is not supported)
+  endif
+endif
+
 # Check BOARD_VNDK_VERSION
 define check_vndk_version
   $(eval vndk_path := prebuilts/vndk/v$(1)) \
diff --git a/core/build_rro_package.mk b/core/build_rro_package.mk
index c3daf6e..a6921d5 100644
--- a/core/build_rro_package.mk
+++ b/core/build_rro_package.mk
@@ -16,11 +16,11 @@
 endif
 
 partition :=
-ifeq ($(LOCAL_ODM_MODULE),true)
+ifeq ($(strip $(LOCAL_ODM_MODULE)),true)
   partition := $(TARGET_OUT_ODM)
-else ifeq ($(LOCAL_VENDOR_MODULE),true)
+else ifeq ($(strip $(LOCAL_VENDOR_MODULE)),true)
   partition := $(TARGET_OUT_VENDOR)
-else ifeq ($(LOCAL_PRODUCT_SERVICES_MODULE),true)
+else ifeq ($(strip $(LOCAL_PRODUCT_SERVICES_MODULE)),true)
   partition := $(TARGET_OUT_PRODUCT_SERVICES)
 else
   partition := $(TARGET_OUT_PRODUCT)
diff --git a/core/cc_prebuilt_internal.mk b/core/cc_prebuilt_internal.mk
new file mode 100644
index 0000000..b936bd7
--- /dev/null
+++ b/core/cc_prebuilt_internal.mk
@@ -0,0 +1,197 @@
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+############################################################
+# Internal build rules for native prebuilt modules
+############################################################
+
+my_strip_module := $(firstword \
+  $(LOCAL_STRIP_MODULE_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) \
+  $(LOCAL_STRIP_MODULE))
+
+ifeq (SHARED_LIBRARIES,$(LOCAL_MODULE_CLASS))
+  ifeq ($(LOCAL_IS_HOST_MODULE)$(my_strip_module),)
+    # Strip but not try to add debuglink
+    my_strip_module := no_debuglink
+  endif
+endif
+
+ifneq ($(filter STATIC_LIBRARIES SHARED_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
+  prebuilt_module_is_a_library := true
+else
+  prebuilt_module_is_a_library :=
+endif
+
+# Don't install static libraries by default.
+ifndef LOCAL_UNINSTALLABLE_MODULE
+ifeq (STATIC_LIBRARIES,$(LOCAL_MODULE_CLASS))
+  LOCAL_UNINSTALLABLE_MODULE := true
+endif
+endif
+
+my_check_elf_file_shared_lib_files :=
+
+ifneq ($(filter true keep_symbols no_debuglink mini-debug-info,$(my_strip_module)),)
+  ifdef LOCAL_IS_HOST_MODULE
+    $(call pretty-error,Cannot strip/pack host module)
+  endif
+  ifeq ($(filter SHARED_LIBRARIES EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
+    $(call pretty-error,Can strip/pack only shared libraries or executables)
+  endif
+  ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
+    $(call pretty-error,Cannot strip/pack scripts)
+  endif
+  # Set the arch-specific variables to set up the strip rules
+  LOCAL_STRIP_MODULE_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH) := $(my_strip_module)
+  include $(BUILD_SYSTEM)/dynamic_binary.mk
+  built_module := $(linked_module)
+
+  ifneq ($(LOCAL_SDK_VERSION),)
+    # binary.mk filters out NDK_MIGRATED_LIBS from my_shared_libs, thus those NDK libs are not added
+    # to DEPENDENCIES_ON_SHARED_LIBRARIES. Assign $(my_ndk_shared_libraries_fullpath) to
+    # my_check_elf_file_shared_lib_files so that check_elf_file.py can see those NDK stub libs.
+    my_check_elf_file_shared_lib_files := $(my_ndk_shared_libraries_fullpath)
+  endif
+else  # my_strip_module not true
+  include $(BUILD_SYSTEM)/base_rules.mk
+  built_module := $(LOCAL_BUILT_MODULE)
+
+ifdef prebuilt_module_is_a_library
+export_includes := $(intermediates)/export_includes
+export_cflags := $(foreach d,$(LOCAL_EXPORT_C_INCLUDE_DIRS),-I $(d))
+$(export_includes): PRIVATE_EXPORT_CFLAGS := $(export_cflags)
+$(export_includes): $(LOCAL_EXPORT_C_INCLUDE_DEPS)
+	@echo Export includes file: $< -- $@
+	$(hide) mkdir -p $(dir $@) && rm -f $@
+ifdef export_cflags
+	$(hide) echo "$(PRIVATE_EXPORT_CFLAGS)" >$@
+else
+	$(hide) touch $@
+endif
+export_cflags :=
+
+include $(BUILD_SYSTEM)/allowed_ndk_types.mk
+
+ifdef LOCAL_SDK_VERSION
+my_link_type := native:ndk:$(my_ndk_stl_family):$(my_ndk_stl_link_type)
+else ifdef LOCAL_USE_VNDK
+    _name := $(patsubst %.vendor,%,$(LOCAL_MODULE))
+    ifneq ($(filter $(_name),$(VNDK_CORE_LIBRARIES) $(VNDK_SAMEPROCESS_LIBRARIES) $(LLNDK_LIBRARIES)),)
+        ifeq ($(filter $(_name),$(VNDK_PRIVATE_LIBRARIES)),)
+            my_link_type := native:vndk
+        else
+            my_link_type := native:vndk_private
+        endif
+    else
+        my_link_type := native:vendor
+    endif
+else ifneq ($(filter $(TARGET_RECOVERY_OUT)/%,$(LOCAL_MODULE_PATH)),)
+my_link_type := native:recovery
+else
+my_link_type := native:platform
+endif
+
+# TODO: check dependencies of prebuilt files
+my_link_deps :=
+
+my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+my_common :=
+include $(BUILD_SYSTEM)/link_type.mk
+endif  # prebuilt_module_is_a_library
+
+# The real dependency will be added after all Android.mks are loaded and the install paths
+# of the shared libraries are determined.
+ifdef LOCAL_INSTALLED_MODULE
+ifdef LOCAL_IS_HOST_MODULE
+    ifeq ($(LOCAL_SYSTEM_SHARED_LIBRARIES),none)
+        my_system_shared_libraries :=
+    else
+        my_system_shared_libraries := $(LOCAL_SYSTEM_SHARED_LIBRARIES)
+    endif
+else
+    ifeq ($(LOCAL_SYSTEM_SHARED_LIBRARIES),none)
+        my_system_shared_libraries := libc libm libdl
+    else
+        my_system_shared_libraries := $(LOCAL_SYSTEM_SHARED_LIBRARIES)
+        my_system_shared_libraries := $(patsubst libc,libc libdl,$(my_system_shared_libraries))
+    endif
+endif
+
+my_shared_libraries := \
+    $(filter-out $(my_system_shared_libraries),$(LOCAL_SHARED_LIBRARIES)) \
+    $(my_system_shared_libraries)
+
+ifdef my_shared_libraries
+# Extra shared libraries introduced by LOCAL_CXX_STL.
+include $(BUILD_SYSTEM)/cxx_stl_setup.mk
+ifdef LOCAL_USE_VNDK
+  my_shared_libraries := $(foreach l,$(my_shared_libraries),\
+    $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
+endif
+$(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)DEPENDENCIES_ON_SHARED_LIBRARIES += \
+  $(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(my_shared_libraries))
+endif
+endif  # my_shared_libraries
+
+# We need to enclose the above export_includes and my_built_shared_libraries in
+# "my_strip_module not true" because otherwise the rules are defined in dynamic_binary.mk.
+endif  # my_strip_module not true
+
+
+# Check prebuilt ELF binaries.
+include $(BUILD_SYSTEM)/check_elf_file.mk
+
+ifeq ($(NATIVE_COVERAGE),true)
+ifneq (,$(strip $(LOCAL_PREBUILT_COVERAGE_ARCHIVE)))
+  $(eval $(call copy-one-file,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(intermediates)/$(LOCAL_MODULE).gcnodir))
+  ifneq ($(LOCAL_UNINSTALLABLE_MODULE),true)
+    ifdef LOCAL_IS_HOST_MODULE
+      my_coverage_path := $($(my_prefix)OUT_COVERAGE)/$(patsubst $($(my_prefix)OUT)/%,%,$(my_module_path))
+    else
+      my_coverage_path := $(TARGET_OUT_COVERAGE)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_module_path))
+    endif
+    my_coverage_path := $(my_coverage_path)/$(patsubst %.so,%,$(my_installed_module_stem)).gcnodir
+    $(eval $(call copy-one-file,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(my_coverage_path)))
+    $(LOCAL_BUILT_MODULE): $(my_coverage_path)
+  endif
+else
+# Coverage information is needed when static lib is a dependency of another
+# coverage-enabled module.
+ifeq (STATIC_LIBRARIES, $(LOCAL_MODULE_CLASS))
+GCNO_ARCHIVE := $(LOCAL_MODULE).gcnodir
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_ALL_OBJECTS :=
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_ALL_WHOLE_STATIC_LIBRARIES :=
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_PREFIX := $(my_prefix)
+$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_2ND_ARCH_VAR_PREFIX := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+$(intermediates)/$(GCNO_ARCHIVE) :
+	$(transform-o-to-static-lib)
+endif
+endif
+endif
+
+ifneq ($(filter init%rc,$(notdir $(LOCAL_INSTALLED_MODULE)))$(filter %/etc/init,$(dir $(LOCAL_INSTALLED_MODULE))),)
+  $(eval $(call copy-init-script-file-checked,$(my_prebuilt_src_file),$(built_module)))
+else ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
+$(built_module) : $(my_prebuilt_src_file)
+	$(transform-prebuilt-to-target-strip-comments)
+else
+$(built_module) : $(my_prebuilt_src_file)
+	$(transform-prebuilt-to-target)
+endif
+ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
+	$(hide) chmod +x $@
+endif
+
diff --git a/core/config.mk b/core/config.mk
index 2e3e31f..3788721 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -105,7 +105,7 @@
 
 UNAME := $(shell uname -sm)
 
-SRC_TARGET_DIR := $(TOPDIR)build/target
+SRC_TARGET_DIR := $(TOPDIR)build/make/target
 
 # Some specific paths to tools
 SRC_DROIDDOC_DIR := $(TOPDIR)build/make/tools/droiddoc
@@ -605,7 +605,7 @@
 FEC := $(HOST_OUT_EXECUTABLES)/fec
 BRILLO_UPDATE_PAYLOAD := $(HOST_OUT_EXECUTABLES)/brillo_update_payload
 
-DEXDUMP := $(HOST_OUT_EXECUTABLES)/dexdump2$(BUILD_EXECUTABLE_SUFFIX)
+DEXDUMP := $(HOST_OUT_EXECUTABLES)/dexdump$(BUILD_EXECUTABLE_SUFFIX)
 PROFMAN := $(HOST_OUT_EXECUTABLES)/profman
 
 FINDBUGS_DIR := external/owasp/sanitizer/tools/findbugs/bin
@@ -615,8 +615,6 @@
 
 EXTRACT_KERNEL := build/make/tools/extract_kernel.py
 
-COLUMN:= column
-
 USE_OPENJDK9 := true
 
 ifeq ($(EXPERIMENTAL_USE_OPENJDK9),)
@@ -764,7 +762,7 @@
 ifdef PRODUCT_DEFAULT_DEV_CERTIFICATE
   DEFAULT_SYSTEM_DEV_CERTIFICATE := $(PRODUCT_DEFAULT_DEV_CERTIFICATE)
 else
-  DEFAULT_SYSTEM_DEV_CERTIFICATE := build/target/product/security/testkey
+  DEFAULT_SYSTEM_DEV_CERTIFICATE := build/make/target/product/security/testkey
 endif
 .KATI_READONLY := DEFAULT_SYSTEM_DEV_CERTIFICATE
 
diff --git a/core/definitions.mk b/core/definitions.mk
index bb26de6..7e44a47 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -1137,10 +1137,9 @@
 	$(PRIVATE_CPPFLAGS_NO_OVERRIDE)
 endef
 
-# PATH_TO_CLANG_TIDY_SHELL is defined in build/soong
+# PATH_TO_CLANG_TIDY is defined in build/soong
 define call-clang-tidy
-CLANG_TIDY=$(PATH_TO_CLANG_TIDY) \
-  $(PATH_TO_CLANG_TIDY_SHELL) \
+$(PATH_TO_CLANG_TIDY) \
   $(PRIVATE_TIDY_FLAGS) \
   -checks=$(PRIVATE_TIDY_CHECKS)
 endef
@@ -3334,7 +3333,7 @@
   $(eval enforce_rro_source_overlays := $(subst :, ,$(word 5,$(_o)))) \
   $(eval enforce_rro_partition := $(word 6,$(_o))) \
   $(eval include $(BUILD_SYSTEM)/generate_enforce_rro.mk) \
-  $(eval ALL_MODULES.$$(enforce_rro_source_module).REQUIRED += $$(LOCAL_PACKAGE_NAME)) \
+  $(eval ALL_MODULES.$$(enforce_rro_source_module).REQUIRED_FROM_TARGET += $$(LOCAL_PACKAGE_NAME)) \
 )
 endef
 
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index d43158e..8017486 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -13,6 +13,10 @@
 install-on-system-other = $(filter-out $(PRODUCT_DEXPREOPT_SPEED_APPS) $(PRODUCT_SYSTEM_SERVER_APPS),$(basename $(notdir $(filter $(foreach f,$(SYSTEM_OTHER_ODEX_FILTER),$(TARGET_OUT)/$(f)),$(1)))))
 endif
 
+# We want to install the profile even if we are not using preopt since it is required to generate
+# the image on the device.
+ALL_DEFAULT_INSTALLED_MODULES += $(call copy-many-files,$(DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED),$(PRODUCT_OUT))
+
 # Install boot images. Note that there can be multiple.
 DEFAULT_DEX_PREOPT_INSTALLED_IMAGE :=
 $(TARGET_2ND_ARCH_VAR_PREFIX)DEFAULT_DEX_PREOPT_INSTALLED_IMAGE :=
diff --git a/core/dex_preopt_config.mk b/core/dex_preopt_config.mk
index 13e4634..a494991 100644
--- a/core/dex_preopt_config.mk
+++ b/core/dex_preopt_config.mk
@@ -91,6 +91,7 @@
   $(call add_json_list, DisablePreoptModules,               $(DEXPREOPT_DISABLED_MODULES))
   $(call add_json_bool, OnlyPreoptBootImageAndSystemServer, $(filter true,$(WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY)))
   $(call add_json_bool, GenerateApexImage,                  $(filter true,$(DEXPREOPT_GENERATE_APEX_IMAGE)))
+  $(call add_json_bool, UseApexImage,                       $(filter true,$(DEXPREOPT_USE_APEX_IMAGE)))
   $(call add_json_bool, DontUncompressPrivAppsDex,          $(filter true,$(DONT_UNCOMPRESS_PRIV_APPS_DEXS)))
   $(call add_json_list, ModulesLoadedByPrivilegedModules,   $(PRODUCT_LOADED_BY_PRIVILEGED_MODULES))
   $(call add_json_bool, HasSystemOther,                     $(BOARD_USES_SYSTEM_OTHER_ODEX))
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index edd82df..85f2f3b 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -5,11 +5,6 @@
 #
 ####################################
 
-# We want to install the profile even if we are not using preopt since it is required to generate
-# the image on the device.
-my_installed := $(call copy-many-files,$(DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED),$(PRODUCT_OUT))
-ALL_DEFAULT_INSTALLED_MODULES += $(my_installed)
-
 # Install primary arch vdex files into a shared location, and then symlink them to both the primary
 # and secondary arch directories.
 my_vdex_copy_pairs := $(DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_$(my_boot_image_name)_$(TARGET_ARCH))
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 1704daf..f4be2c7 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -25,11 +25,13 @@
 #$(warning $(call find_and_earlier,A B C,D))
 
 define version-list
-$(1)PR1 $(1)PD1 $(1)PD2 $(1)PM1 $(1)PM2
+$(1)P1A $(1)P1B $(1)P2A $(1)P2B $(1)D1A $(1)D1B $(1)D2A $(1)D2B $(1)Q1A $(1)Q1B $(1)Q2A $(1)Q2B $(1)Q3A $(1)Q3B
 endef
 
-ALL_VERSIONS := O P Q R S T U V W X Y Z
-ALL_VERSIONS := $(foreach v,$(ALL_VERSIONS),$(call version-list,$(v)))
+PREV_VERSIONS := OPR1 OPD1 OPD2 OPM1 OPM2 PPR1 PPD1 PPD2 PPM1 PPM2 QPR1
+ALL_VERSIONS := Q R S T U V W X Y Z
+ALL_VERSIONS := $(PREV_VERSIONS) $(foreach v,$(ALL_VERSIONS),$(call version-list,$(v)))
+PREV_VERSIONS :=
 
 # Filters ALL_VERSIONS down to the range [$1, $2], and errors if $1 > $2 or $3 is
 # not in [$1, $2]
diff --git a/core/install_jni_libs.mk b/core/install_jni_libs.mk
index 01f7f10..515d34f 100644
--- a/core/install_jni_libs.mk
+++ b/core/install_jni_libs.mk
@@ -13,10 +13,10 @@
 
 my_embed_jni :=
 ifneq ($(TARGET_BUILD_APPS),)
-my_embed_jni := true
+  my_embed_jni := true
 endif
 ifneq ($(filter tests samples, $(LOCAL_MODULE_TAGS)),)
-my_embed_jni := true
+  my_embed_jni := true
 endif
 
 # If the APK is not installed in one of the following partitions, force its libraries
@@ -29,13 +29,13 @@
     $(TARGET_OUT_PRODUCT_SERVICES)/% \
 
 ifeq ($(filter $(supported_partition_patterns),$(my_module_path)),)
-    my_embed_jni := true
+  my_embed_jni := true
 endif
 
 # If we're installing this APP as a compressed module, we include all JNI libraries
 # in the compressed artifact, rather than as separate files on the partition in question.
 ifdef LOCAL_COMPRESSED_MODULE
-my_embed_jni := true
+  my_embed_jni := true
 endif
 
 jni_shared_libraries :=
@@ -50,56 +50,56 @@
 my_add_jni :=
 # The module is built for TARGET_ARCH
 ifeq ($(my_2nd_arch_prefix),$(LOCAL_2ND_ARCH_VAR_PREFIX))
-my_add_jni := true
+  my_add_jni := true
 endif
 # Or it explicitly requires both
 ifeq ($(my_module_multilib),both)
-my_add_jni := true
+  my_add_jni := true
 endif
 ifeq ($(my_add_jni),true)
-my_prebuilt_jni_libs := $(LOCAL_PREBUILT_JNI_LIBS_$(TARGET_ARCH))
-ifndef my_prebuilt_jni_libs
-my_prebuilt_jni_libs := $(LOCAL_PREBUILT_JNI_LIBS)
-endif
-include $(BUILD_SYSTEM)/install_jni_libs_internal.mk
-jni_shared_libraries += $(my_jni_shared_libraries)
-jni_shared_libraries_abis += $(my_jni_shared_libraries_abi)
-jni_shared_libraries_with_abis += $(addprefix $(my_jni_shared_libraries_abi):,\
-    $(my_jni_shared_libraries))
-embedded_prebuilt_jni_libs += $(my_embedded_prebuilt_jni_libs)
+  my_prebuilt_jni_libs := $(LOCAL_PREBUILT_JNI_LIBS_$(TARGET_ARCH))
+  ifndef my_prebuilt_jni_libs
+    my_prebuilt_jni_libs := $(LOCAL_PREBUILT_JNI_LIBS)
+  endif
+  include $(BUILD_SYSTEM)/install_jni_libs_internal.mk
+  jni_shared_libraries += $(my_jni_shared_libraries)
+  jni_shared_libraries_abis += $(my_jni_shared_libraries_abi)
+  jni_shared_libraries_with_abis += $(addprefix $(my_jni_shared_libraries_abi):,\
+      $(my_jni_shared_libraries))
+  embedded_prebuilt_jni_libs += $(my_embedded_prebuilt_jni_libs)
 
-# Include RS dynamically-generated libraries as well
-# TODO: Add multilib support once RS supports generating multilib libraries.
-jni_shared_libraries += $(rs_compatibility_jni_libs)
-jni_shared_libraries_with_abis += $(addprefix $(my_jni_shared_libraries_abi):,\
-    $(rs_compatibility_jni_libs))
+  # Include RS dynamically-generated libraries as well
+  # TODO: Add multilib support once RS supports generating multilib libraries.
+  jni_shared_libraries += $(rs_compatibility_jni_libs)
+  jni_shared_libraries_with_abis += $(addprefix $(my_jni_shared_libraries_abi):,\
+      $(rs_compatibility_jni_libs))
 endif  # my_add_jni
 
 #######################################
 # For TARGET_2ND_ARCH
 ifdef TARGET_2ND_ARCH
-my_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
-my_add_jni :=
-# The module is built for TARGET_2ND_ARCH
-ifeq ($(my_2nd_arch_prefix),$(LOCAL_2ND_ARCH_VAR_PREFIX))
-my_add_jni := true
-endif
-# Or it explicitly requires both
-ifeq ($(my_module_multilib),both)
-my_add_jni := true
-endif
-ifeq ($(my_add_jni),true)
-my_prebuilt_jni_libs := $(LOCAL_PREBUILT_JNI_LIBS_$(TARGET_2ND_ARCH))
-ifndef my_prebuilt_jni_libs
-my_prebuilt_jni_libs := $(LOCAL_PREBUILT_JNI_LIBS)
-endif
-include $(BUILD_SYSTEM)/install_jni_libs_internal.mk
-jni_shared_libraries += $(my_jni_shared_libraries)
-jni_shared_libraries_abis += $(my_jni_shared_libraries_abi)
-jni_shared_libraries_with_abis += $(addprefix $(my_jni_shared_libraries_abi):,\
-    $(my_jni_shared_libraries))
-embedded_prebuilt_jni_libs += $(my_embedded_prebuilt_jni_libs)
-endif  # my_add_jni
+  my_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
+  my_add_jni :=
+  # The module is built for TARGET_2ND_ARCH
+  ifeq ($(my_2nd_arch_prefix),$(LOCAL_2ND_ARCH_VAR_PREFIX))
+    my_add_jni := true
+  endif
+  # Or it explicitly requires both
+  ifeq ($(my_module_multilib),both)
+    my_add_jni := true
+  endif
+  ifeq ($(my_add_jni),true)
+    my_prebuilt_jni_libs := $(LOCAL_PREBUILT_JNI_LIBS_$(TARGET_2ND_ARCH))
+    ifndef my_prebuilt_jni_libs
+      my_prebuilt_jni_libs := $(LOCAL_PREBUILT_JNI_LIBS)
+    endif
+    include $(BUILD_SYSTEM)/install_jni_libs_internal.mk
+    jni_shared_libraries += $(my_jni_shared_libraries)
+    jni_shared_libraries_abis += $(my_jni_shared_libraries_abi)
+    jni_shared_libraries_with_abis += $(addprefix $(my_jni_shared_libraries_abi):,\
+        $(my_jni_shared_libraries))
+    embedded_prebuilt_jni_libs += $(my_embedded_prebuilt_jni_libs)
+  endif  # my_add_jni
 endif  # TARGET_2ND_ARCH
 
 jni_shared_libraries := $(strip $(jni_shared_libraries))
diff --git a/core/install_jni_libs_internal.mk b/core/install_jni_libs_internal.mk
index a79a49a..eac0414 100644
--- a/core/install_jni_libs_internal.mk
+++ b/core/install_jni_libs_internal.mk
@@ -12,117 +12,117 @@
 #   my_embedded_prebuilt_jni_libs, prebuilt jni libs embedded in prebuilt apk.
 #
 
-my_jni_shared_libraries := \
+my_jni_shared_libraries := $(strip \
     $(foreach lib,$(LOCAL_JNI_SHARED_LIBRARIES), \
-      $(call intermediates-dir-for,SHARED_LIBRARIES,$(lib),,,$(my_2nd_arch_prefix))/$(lib).so)
+      $(call intermediates-dir-for,SHARED_LIBRARIES,$(lib),,,$(my_2nd_arch_prefix))/$(lib).so))
 
 # App-specific lib path.
 my_app_lib_path := $(dir $(LOCAL_INSTALLED_MODULE))lib/$(TARGET_$(my_2nd_arch_prefix)ARCH)
 my_embedded_prebuilt_jni_libs :=
 
 ifdef my_embed_jni
-# App explicitly requires the prebuilt NDK stl shared libraies.
-# The NDK stl shared libraries should never go to the system image.
-ifeq ($(LOCAL_NDK_STL_VARIANT),c++_shared)
-ifndef LOCAL_SDK_VERSION
-$(error LOCAL_SDK_VERSION must be defined with LOCAL_NDK_STL_VARIANT, \
-    LOCAL_PACKAGE_NAME=$(LOCAL_PACKAGE_NAME))
-endif
-my_jni_shared_libraries += \
-    $(HISTORICAL_NDK_VERSIONS_ROOT)/$(LOCAL_NDK_VERSION)/sources/cxx-stl/llvm-libc++/libs/$(TARGET_$(my_2nd_arch_prefix)CPU_ABI)/libc++_shared.so
-endif
+  # App explicitly requires the prebuilt NDK stl shared libraies.
+  # The NDK stl shared libraries should never go to the system image.
+  ifeq ($(LOCAL_NDK_STL_VARIANT),c++_shared)
+    ifndef LOCAL_SDK_VERSION
+      $(error LOCAL_SDK_VERSION must be defined with LOCAL_NDK_STL_VARIANT, \
+          LOCAL_PACKAGE_NAME=$(LOCAL_PACKAGE_NAME))
+    endif
+    my_jni_shared_libraries += \
+        $(HISTORICAL_NDK_VERSIONS_ROOT)/$(LOCAL_NDK_VERSION)/sources/cxx-stl/llvm-libc++/libs/$(TARGET_$(my_2nd_arch_prefix)CPU_ABI)/libc++_shared.so
+  endif
 
-# Set the abi directory used by the local JNI shared libraries.
-# (Doesn't change how the local shared libraries are compiled, just
-# sets where they are stored in the apk.)
-ifeq ($(LOCAL_JNI_SHARED_LIBRARIES_ABI),)
+  # Set the abi directory used by the local JNI shared libraries.
+  # (Doesn't change how the local shared libraries are compiled, just
+  # sets where they are stored in the apk.)
+  ifeq ($(LOCAL_JNI_SHARED_LIBRARIES_ABI),)
     my_jni_shared_libraries_abi := $(TARGET_$(my_2nd_arch_prefix)CPU_ABI)
-else
+  else
     my_jni_shared_libraries_abi := $(LOCAL_JNI_SHARED_LIBRARIES_ABI)
-endif
+  endif
 
-else  # not my_embed_jni
+else ifneq ($(my_jni_shared_libraries),) # not my_embed_jni
 
-my_jni_shared_libraries := $(strip $(my_jni_shared_libraries))
-ifneq ($(my_jni_shared_libraries),)
-# The jni libaries will be installed to the system.img.
-my_jni_filenames := $(notdir $(my_jni_shared_libraries))
-# Make sure the JNI libraries get installed
-my_shared_library_path := $(call get_non_asan_path,\
-  $($(my_2nd_arch_prefix)TARGET_OUT$(partition_tag)_SHARED_LIBRARIES))
-# Do not use order-only dependency, because we want to rebuild the image if an jni is updated.
-my_installed_library := $(addprefix $(my_shared_library_path)/, $(my_jni_filenames))
-$(LOCAL_INSTALLED_MODULE) : $(my_installed_library)
-ALL_MODULES.$(LOCAL_MODULE).INSTALLED += $(my_installed_library)
+  # The jni libaries will be installed to the system.img.
+  my_jni_filenames := $(notdir $(my_jni_shared_libraries))
+  # Make sure the JNI libraries get installed
+  my_shared_library_path := $(call get_non_asan_path,\
+      $($(my_2nd_arch_prefix)TARGET_OUT$(partition_tag)_SHARED_LIBRARIES))
+  my_installed_library := $(addprefix $(my_shared_library_path)/, $(my_jni_filenames))
+  # Do not use order-only dependency, because we want to rebuild the image if an jni is updated.
+  $(LOCAL_INSTALLED_MODULE) : $(my_installed_library)
 
-# Create symlink in the app specific lib path
-# Skip creating this symlink when running the second part of a target sanitization build.
-ifeq ($(filter address,$(SANITIZE_TARGET)),)
-ifdef LOCAL_POST_INSTALL_CMD
-# Add a shell command separator
-LOCAL_POST_INSTALL_CMD += ;
-endif
+  ALL_MODULES.$(LOCAL_MODULE).INSTALLED += $(my_installed_library)
 
-my_symlink_target_dir := $(patsubst $(PRODUCT_OUT)%,%,\
-    $(my_shared_library_path))
-LOCAL_POST_INSTALL_CMD += \
-  mkdir -p $(my_app_lib_path) \
-  $(foreach lib, $(my_jni_filenames), ;ln -sf $(my_symlink_target_dir)/$(lib) $(my_app_lib_path)/$(lib))
-$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
-else
-ifdef LOCAL_POST_INSTALL_CMD
-$(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
-endif
-endif
+  # Create symlink in the app specific lib path
+  # Skip creating this symlink when running the second part of a target sanitization build.
+  ifeq ($(filter address,$(SANITIZE_TARGET)),)
+    ifdef LOCAL_POST_INSTALL_CMD
+      # Add a shell command separator
+      LOCAL_POST_INSTALL_CMD += ;
+    endif
 
-# Clear jni_shared_libraries to not embed it into the apk.
-my_jni_shared_libraries :=
-endif  # $(my_jni_shared_libraries) not empty
+    my_symlink_target_dir := $(patsubst $(PRODUCT_OUT)%,%,\
+        $(my_shared_library_path))
+    LOCAL_POST_INSTALL_CMD += \
+        mkdir -p $(my_app_lib_path) \
+        $(foreach lib, $(my_jni_filenames), ;ln -sf $(my_symlink_target_dir)/$(lib) $(my_app_lib_path)/$(lib))
+    $(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
+  else
+    ifdef LOCAL_POST_INSTALL_CMD
+      $(LOCAL_INSTALLED_MODULE): PRIVATE_POST_INSTALL_CMD := $(LOCAL_POST_INSTALL_CMD)
+    endif
+  endif
+
+  # Clear jni_shared_libraries to not embed it into the apk.
+  my_jni_shared_libraries :=
 endif  # my_embed_jni
 
 ifdef my_prebuilt_jni_libs
-# Files like @lib/<abi>/libfoo.so (path inside the apk) are JNI libs embedded prebuilt apk;
-# Files like path/to/libfoo.so (path relative to LOCAL_PATH) are prebuilts in the source tree.
-my_embedded_prebuilt_jni_libs := $(patsubst @%,%, \
-    $(filter @%, $(my_prebuilt_jni_libs)))
+  # Files like @lib/<abi>/libfoo.so (path inside the apk) are JNI libs embedded prebuilt apk;
+  # Files like path/to/libfoo.so (path relative to LOCAL_PATH) are prebuilts in the source tree.
+  my_embedded_prebuilt_jni_libs := $(patsubst @%,%, \
+      $(filter @%, $(my_prebuilt_jni_libs)))
 
-# prebuilt JNI exsiting as separate source files.
-my_prebuilt_jni_libs := $(addprefix $(LOCAL_PATH)/, \
-    $(filter-out @%, $(my_prebuilt_jni_libs)))
-ifdef my_prebuilt_jni_libs
-ifdef my_embed_jni
-# Embed my_prebuilt_jni_libs to the apk
-my_jni_shared_libraries += $(my_prebuilt_jni_libs)
-else # not my_embed_jni
-# Install my_prebuilt_jni_libs as separate files.
-$(foreach lib, $(my_prebuilt_jni_libs), \
-    $(eval $(call copy-one-file, $(lib), $(my_app_lib_path)/$(notdir $(lib)))))
+  # prebuilt JNI exsiting as separate source files.
+  my_prebuilt_jni_libs := $(addprefix $(LOCAL_PATH)/, \
+      $(filter-out @%, $(my_prebuilt_jni_libs)))
+  ifdef my_prebuilt_jni_libs
+    ifdef my_embed_jni
+      # Embed my_prebuilt_jni_libs to the apk
+      my_jni_shared_libraries += $(my_prebuilt_jni_libs)
+    else # not my_embed_jni
+      # Install my_prebuilt_jni_libs as separate files.
+      $(foreach lib, $(my_prebuilt_jni_libs), \
+          $(eval $(call copy-one-file, $(lib), $(my_app_lib_path)/$(notdir $(lib)))))
 
-my_installed_library := $(addprefix $(my_app_lib_path)/, $(notdir $(my_prebuilt_jni_libs)))
-$(LOCAL_INSTALLED_MODULE) : $(my_installed_library)
-ALL_MODULES.$(LOCAL_MODULE).INSTALLED += $(my_installed_library)
-endif  # my_embed_jni
-endif  # inner my_prebuilt_jni_libs
+      my_installed_library := $(addprefix $(my_app_lib_path)/, $(notdir $(my_prebuilt_jni_libs)))
+      $(LOCAL_INSTALLED_MODULE) : $(my_installed_library)
+
+      ALL_MODULES.$(LOCAL_MODULE).INSTALLED += $(my_installed_library)
+    endif  # my_embed_jni
+  endif  # inner my_prebuilt_jni_libs
 endif  # outer my_prebuilt_jni_libs
 
 # Verify that all included libraries are built against the NDK
 include $(BUILD_SYSTEM)/allowed_ndk_types.mk
+
 ifneq ($(strip $(LOCAL_JNI_SHARED_LIBRARIES)),)
-ifneq ($(LOCAL_SDK_VERSION),)
-my_link_type := app:sdk
-my_warn_types := native:platform $(my_warn_ndk_types)
-my_allowed_types := $(my_allowed_ndk_types)
+  ifneq ($(LOCAL_SDK_VERSION),)
+    my_link_type := app:sdk
+    my_warn_types := native:platform $(my_warn_ndk_types)
+    my_allowed_types := $(my_allowed_ndk_types)
     ifneq (,$(filter true,$(LOCAL_VENDOR_MODULE) $(LOCAL_ODM_MODULE) $(LOCAL_PROPRIETARY_MODULE)))
-        my_allowed_types += native:vendor native:vndk native:platform_vndk
+      my_allowed_types += native:vendor native:vndk native:platform_vndk
     endif
-else
-my_link_type := app:platform
-my_warn_types := $(my_warn_ndk_types)
-my_allowed_types := $(my_allowed_ndk_types) native:platform native:vendor native:vndk native:vndk_private native:platform_vndk
-endif
+  else
+    my_link_type := app:platform
+    my_warn_types := $(my_warn_ndk_types)
+    my_allowed_types := $(my_allowed_ndk_types) native:platform native:vendor native:vndk native:vndk_private native:platform_vndk
+  endif
 
-my_link_deps := $(addprefix SHARED_LIBRARIES:,$(LOCAL_JNI_SHARED_LIBRARIES))
+  my_link_deps := $(addprefix SHARED_LIBRARIES:,$(LOCAL_JNI_SHARED_LIBRARIES))
 
-my_common :=
-include $(BUILD_SYSTEM)/link_type.mk
+  my_common :=
+  include $(BUILD_SYSTEM)/link_type.mk
 endif
diff --git a/core/java.mk b/core/java.mk
index fc5a8bc..c3787ae 100644
--- a/core/java.mk
+++ b/core/java.mk
@@ -395,6 +395,13 @@
   # that would break apps that use APIs removed from the current SDK.
   my_proguard_sdk_raise := $(call java-lib-header-files,$(TARGET_DEFAULT_BOOTCLASSPATH_LIBRARIES) $(TARGET_DEFAULT_JAVA_LIBRARIES))
 endif
+ifdef BOARD_SYSTEMSDK_VERSIONS
+ifneq (,$(filter true,$(LOCAL_VENDOR_MODULE) $(LOCAL_ODM_MODULE) $(LOCAL_PROPRIETARY_MODULE)))
+  # But for vendor or odm apks, don't raise SDK as the apks are required to
+  # use SDK APIs only
+  my_proguard_sdk_raise :=
+endif
+endif
 endif
 
 legacy_proguard_flags := $(addprefix -libraryjars ,$(my_proguard_sdk_raise) \
diff --git a/core/java_prebuilt_internal.mk b/core/java_prebuilt_internal.mk
new file mode 100644
index 0000000..8a919ff
--- /dev/null
+++ b/core/java_prebuilt_internal.mk
@@ -0,0 +1,247 @@
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+############################################################
+# Internal build rules for JAVA_LIBRARIES prebuilt modules
+############################################################
+
+ifneq (JAVA_LIBRARIES,$(LOCAL_MODULE_CLASS))
+$(call pretty-error,java_prebuilt_internal.mk is for JAVA_LIBRARIES modules only)
+endif
+
+include $(BUILD_SYSTEM)/base_rules.mk
+built_module := $(LOCAL_BUILT_MODULE)
+
+ifeq (,$(LOCAL_IS_HOST_MODULE)$(filter true,$(LOCAL_UNINSTALLABLE_MODULE)))
+  prebuilt_module_is_dex_javalib := true
+else
+  prebuilt_module_is_dex_javalib :=
+endif
+
+ifeq ($(prebuilt_module_is_dex_javalib),true)
+my_dex_jar := $(my_prebuilt_src_file)
+# This is a target shared library, i.e. a jar with classes.dex.
+
+ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_BOOT_JARS)),)
+  $(call pretty-error,Modules in PRODUCT_BOOT_JARS must be defined in Android.bp files)
+endif
+
+#######################################
+# defines built_odex along with rule to install odex
+include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
+#######################################
+ifdef LOCAL_DEX_PREOPT
+
+$(built_module): PRIVATE_STRIP_SCRIPT := $(intermediates)/strip.sh
+$(built_module): $(intermediates)/strip.sh
+$(built_module): | $(DEXPREOPT_STRIP_DEPS)
+$(built_module): .KATI_DEPFILE := $(built_module).d
+$(built_module): $(my_prebuilt_src_file)
+	$(PRIVATE_STRIP_SCRIPT) $< $@
+
+else # ! LOCAL_DEX_PREOPT
+$(built_module) : $(my_prebuilt_src_file)
+	$(call copy-file-to-target)
+endif # LOCAL_DEX_PREOPT
+
+else  # ! prebuilt_module_is_dex_javalib
+$(built_module) : $(my_prebuilt_src_file)
+	$(transform-prebuilt-to-target)
+endif # ! prebuilt_module_is_dex_javalib
+
+my_src_jar := $(my_prebuilt_src_file)
+
+ifdef LOCAL_IS_HOST_MODULE
+# for host java libraries deps should be in the common dir, so we make a copy in
+# the common dir.
+common_classes_jar := $(intermediates.COMMON)/classes.jar
+common_header_jar := $(intermediates.COMMON)/classes-header.jar
+
+$(common_classes_jar): PRIVATE_MODULE := $(LOCAL_MODULE)
+$(common_classes_jar): PRIVATE_PREFIX := $(my_prefix)
+
+$(common_classes_jar) : $(my_src_jar)
+	$(transform-prebuilt-to-target)
+
+ifneq ($(TURBINE_ENABLED),false)
+$(common_header_jar) : $(my_src_jar)
+	$(transform-prebuilt-to-target)
+endif
+
+else # !LOCAL_IS_HOST_MODULE
+# for target java libraries, the LOCAL_BUILT_MODULE is in a product-specific dir,
+# while the deps should be in the common dir, so we make a copy in the common dir.
+common_classes_jar := $(intermediates.COMMON)/classes.jar
+common_header_jar := $(intermediates.COMMON)/classes-header.jar
+common_classes_pre_proguard_jar := $(intermediates.COMMON)/classes-pre-proguard.jar
+common_javalib_jar := $(intermediates.COMMON)/javalib.jar
+
+$(common_classes_jar) $(common_classes_pre_proguard_jar) $(common_javalib_jar): PRIVATE_MODULE := $(LOCAL_MODULE)
+$(common_classes_jar) $(common_classes_pre_proguard_jar) $(common_javalib_jar): PRIVATE_PREFIX := $(my_prefix)
+
+ifeq ($(LOCAL_SDK_VERSION),system_current)
+my_link_type := java:system
+else ifneq (,$(call has-system-sdk-version,$(LOCAL_SDK_VERSION)))
+my_link_type := java:system
+else ifeq ($(LOCAL_SDK_VERSION),core_current)
+my_link_type := java:core
+else ifneq ($(LOCAL_SDK_VERSION),)
+my_link_type := java:sdk
+else
+my_link_type := java:platform
+endif
+
+# TODO: check dependencies of prebuilt files
+my_link_deps :=
+
+my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
+my_common := COMMON
+include $(BUILD_SYSTEM)/link_type.mk
+
+ifeq ($(prebuilt_module_is_dex_javalib),true)
+# For prebuilt shared Java library we don't have classes.jar.
+$(common_javalib_jar) : $(my_src_jar)
+	$(transform-prebuilt-to-target)
+
+else  # ! prebuilt_module_is_dex_javalib
+
+my_src_aar := $(filter %.aar, $(my_prebuilt_src_file))
+ifneq ($(my_src_aar),)
+# This is .aar file, archive of classes.jar and Android resources.
+
+# run Jetifier if needed
+LOCAL_JETIFIER_INPUT_FILE := $(my_src_aar)
+include $(BUILD_SYSTEM)/jetifier.mk
+my_src_aar := $(LOCAL_JETIFIER_OUTPUT_FILE)
+
+my_src_jar := $(intermediates.COMMON)/aar/classes.jar
+my_src_proguard_options := $(intermediates.COMMON)/aar/proguard.txt
+my_src_android_manifest := $(intermediates.COMMON)/aar/AndroidManifest.xml
+
+$(my_src_jar) : .KATI_IMPLICIT_OUTPUTS := $(my_src_proguard_options)
+$(my_src_jar) : .KATI_IMPLICIT_OUTPUTS += $(my_src_android_manifest)
+$(my_src_jar) : $(my_src_aar)
+	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@) $(dir $@)/res
+	$(hide) unzip -qo -d $(dir $@) $<
+	# Make sure the extracted classes.jar has a new timestamp.
+	$(hide) touch $@
+	# Make sure the proguard and AndroidManifest.xml files exist
+	# and have a new timestamp.
+	$(hide) touch $(dir $@)/proguard.txt
+	$(hide) touch $(dir $@)/AndroidManifest.xml
+
+my_prebuilt_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml
+$(eval $(call copy-one-file,$(my_src_android_manifest),$(my_prebuilt_android_manifest)))
+$(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_prebuilt_android_manifest))
+
+else
+
+# run Jetifier if needed
+LOCAL_JETIFIER_INPUT_FILE := $(my_src_jar)
+include $(BUILD_SYSTEM)/jetifier.mk
+my_src_jar := $(LOCAL_JETIFIER_OUTPUT_FILE)
+
+endif
+
+$(common_classes_jar) : $(my_src_jar)
+	$(transform-prebuilt-to-target)
+
+ifneq ($(TURBINE_ENABLED),false)
+$(common_header_jar) : $(my_src_jar)
+	$(transform-prebuilt-to-target)
+endif
+
+$(common_classes_pre_proguard_jar) : $(my_src_jar)
+	$(transform-prebuilt-to-target)
+
+$(common_javalib_jar) : $(common_classes_jar)
+	$(transform-prebuilt-to-target)
+
+include $(BUILD_SYSTEM)/force_aapt2.mk
+
+ifdef LOCAL_AAPT2_ONLY
+LOCAL_USE_AAPT2 := true
+endif
+
+ifeq ($(LOCAL_USE_AAPT2),true)
+ifneq ($(my_src_aar),)
+
+$(intermediates.COMMON)/export_proguard_flags : $(my_src_proguard_options)
+	$(transform-prebuilt-to-target)
+
+LOCAL_SDK_RES_VERSION:=$(strip $(LOCAL_SDK_RES_VERSION))
+ifeq ($(LOCAL_SDK_RES_VERSION),)
+  LOCAL_SDK_RES_VERSION:=$(LOCAL_SDK_VERSION)
+endif
+
+framework_res_package_export :=
+# Please refer to package.mk
+ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
+ifneq ($(filter-out current system_current test_current,$(LOCAL_SDK_RES_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current test_current,$(LOCAL_SDK_RES_VERSION))),)
+framework_res_package_export := \
+    $(call resolve-prebuilt-sdk-jar-path,$(LOCAL_SDK_RES_VERSION))
+else
+framework_res_package_export := \
+    $(call intermediates-dir-for,APPS,framework-res,,COMMON)/package-export.apk
+endif
+endif
+
+my_res_package := $(intermediates.COMMON)/package-res.apk
+
+# We needed only very few PRIVATE variables and aapt2.mk input variables. Reset the unnecessary ones.
+$(my_res_package): PRIVATE_AAPT2_CFLAGS :=
+$(my_res_package): PRIVATE_AAPT_FLAGS := --static-lib --no-static-lib-packages --auto-add-overlay
+$(my_res_package): PRIVATE_ANDROID_MANIFEST := $(my_src_android_manifest)
+$(my_res_package): PRIVATE_AAPT_INCLUDES := $(framework_res_package_export)
+$(my_res_package): PRIVATE_SOURCE_INTERMEDIATES_DIR :=
+$(my_res_package): PRIVATE_PROGUARD_OPTIONS_FILE :=
+$(my_res_package): PRIVATE_DEFAULT_APP_TARGET_SDK :=
+$(my_res_package): PRIVATE_DEFAULT_APP_TARGET_SDK :=
+$(my_res_package): PRIVATE_PRODUCT_AAPT_CONFIG :=
+$(my_res_package): PRIVATE_PRODUCT_AAPT_PREF_CONFIG :=
+$(my_res_package): PRIVATE_TARGET_AAPT_CHARACTERISTICS :=
+$(my_res_package) : $(framework_res_package_export)
+$(my_res_package) : $(my_src_android_manifest)
+
+full_android_manifest :=
+my_res_resources :=
+my_overlay_resources :=
+my_compiled_res_base_dir := $(intermediates.COMMON)/flat-res
+R_file_stamp :=
+proguard_options_file :=
+my_generated_res_dirs := $(intermediates.COMMON)/aar/res
+my_generated_res_dirs_deps := $(my_src_jar)
+include $(BUILD_SYSTEM)/aapt2.mk
+
+# Make sure my_res_package is created when you run mm/mmm.
+$(built_module) : $(my_res_package)
+endif  # $(my_src_aar)
+endif  # LOCAL_USE_AAPT2
+# make sure the classes.jar and javalib.jar are built before $(LOCAL_BUILT_MODULE)
+$(built_module) : $(common_javalib_jar)
+
+my_exported_sdk_libs_file := $(intermediates.COMMON)/exported-sdk-libs
+$(my_exported_sdk_libs_file): PRIVATE_EXPORTED_SDK_LIBS := $(LOCAL_EXPORT_SDK_LIBRARIES)
+$(my_exported_sdk_libs_file):
+	@echo "Export SDK libs $@"
+	$(hide) mkdir -p $(dir $@) && rm -f $@
+	$(if $(PRIVATE_EXPORTED_SDK_LIBS),\
+		$(hide) echo $(PRIVATE_EXPORTED_SDK_LIBS) | tr ' ' '\n' > $@,\
+		$(hide) touch $@)
+
+endif # ! prebuilt_module_is_dex_javalib
+endif # LOCAL_IS_HOST_MODULE is not set
+
diff --git a/core/main.mk b/core/main.mk
index 990d255..3ff2fcd 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -595,12 +595,10 @@
 # Otherwise if the module is an executable or shared library,
 #   the required modules must be 64-bit;
 #   otherwise we require both 64-bit and 32-bit variant, if one exists.
-define select-bitness-of-required-modules
+define target-select-bitness-of-required-modules
 $(foreach m,$(ALL_MODULES),\
-  $(eval r := $(ALL_MODULES.$(m).REQUIRED))\
+  $(eval r := $(ALL_MODULES.$(m).REQUIRED_FROM_TARGET))\
   $(if $(r),\
-    $(if $(ALL_MODULES.$(m).FOR_HOST_CROSS),\
-      $(eval r := $(addprefix host_cross_,$(r))))\
     $(if $(ALL_MODULES.$(m).FOR_2ND_ARCH),\
       $(eval r_r := $(call get-32-bit-modules-if-we-can,$(r))),\
       $(if $(filter EXECUTABLES SHARED_LIBRARIES NATIVE_TESTS,$(ALL_MODULES.$(m).CLASS)),\
@@ -608,11 +606,47 @@
         $(eval r_r := $(r) $(call get-32-bit-modules,$(r)))\
        )\
      )\
-     $(eval ALL_MODULES.$(m).REQUIRED := $(strip $(r_r)))\
+     $(eval ALL_MODULES.$(m).REQUIRED_FROM_TARGET := $(strip $(r_r)))\
   )\
 )
 endef
-$(call select-bitness-of-required-modules)
+$(call target-select-bitness-of-required-modules)
+
+define host-select-bitness-of-required-modules
+$(foreach m,$(ALL_MODULES),\
+  $(eval r := $(ALL_MODULES.$(m).REQUIRED_FROM_HOST))\
+  $(if $(r),\
+    $(if $(ALL_MODULES.$(m).FOR_2ND_ARCH),\
+      $(eval r_r := $(call get-host-32-bit-modules-if-we-can,$(r))),\
+      $(if $(filter EXECUTABLES SHARED_LIBRARIES NATIVE_TESTS,$(ALL_MODULES.$(m).CLASS)),\
+        $(eval r_r := $(r)),\
+        $(eval r_r := $(r) $(call get-host-32-bit-modules,$(r)))\
+       )\
+     )\
+     $(eval ALL_MODULES.$(m).REQUIRED_FROM_HOST := $(strip $(r_r)))\
+  )\
+)
+endef
+$(call host-select-bitness-of-required-modules)
+
+define host-cross-select-bitness-of-required-modules
+$(foreach m,$(ALL_MODULES),\
+  $(eval r := $(ALL_MODULES.$(m).REQUIRED_FROM_HOST_CROSS))\
+  $(if $(r),\
+    $(if $(ALL_MODULES.$(m).FOR_HOST_CROSS),,$(error Only expected REQUIRED_FROM_HOST_CROSS on FOR_HOST_CROSS modules - $(m)))\
+    $(eval r := $(addprefix host_cross_,$(r)))\
+    $(if $(ALL_MODULES.$(m).FOR_2ND_ARCH),\
+      $(eval r_r := $(call get-host-32-bit-modules-if-we-can,$(r))),\
+      $(if $(filter EXECUTABLES SHARED_LIBRARIES NATIVE_TESTS,$(ALL_MODULES.$(m).CLASS)),\
+        $(eval r_r := $(r)),\
+        $(eval r_r := $(r) $(call get-host-32-bit-modules,$(r)))\
+       )\
+     )\
+     $(eval ALL_MODULES.$(m).REQUIRED_FROM_HOST_CROSS := $(strip $(r_r)))\
+  )\
+)
+endef
+$(call host-cross-select-bitness-of-required-modules)
 r_r :=
 
 define add-required-deps
@@ -628,30 +662,42 @@
 endef
 
 # Sets up dependencies such that whenever a host module is installed,
-# any other host modules listed in $(ALL_MODULES.$(m).REQUIRED) will also be installed
+# any other host modules listed in $(ALL_MODULES.$(m).REQUIRED_FROM_HOST) will also be installed
 define add-all-host-to-host-required-modules-deps
 $(foreach m,$(ALL_MODULES), \
-  $(eval r := $(ALL_MODULES.$(m).REQUIRED)) \
+  $(eval r := $(ALL_MODULES.$(m).REQUIRED_FROM_HOST)) \
   $(if $(r), \
     $(eval r := $(call module-installed-files,$(r))) \
     $(eval h_m := $(filter $(HOST_OUT)/%, $(ALL_MODULES.$(m).INSTALLED))) \
-    $(eval hc_m := $(filter $(HOST_CROSS_OUT)/%, $(ALL_MODULES.$(m).INSTALLED))) \
     $(eval h_r := $(filter $(HOST_OUT)/%, $(r))) \
-    $(eval hc_r := $(filter $(HOST_CROSS_OUT)/%, $(r))) \
     $(eval h_m := $(filter-out $(h_r), $(h_m))) \
-    $(eval hc_m := $(filter-out $(hc_r), $(hc_m))) \
     $(if $(h_m), $(eval $(call add-required-deps, $(h_m),$(h_r)))) \
-    $(if $(hc_m), $(eval $(call add-required-deps, $(hc_m),$(hc_r)))) \
   ) \
 )
 endef
 $(call add-all-host-to-host-required-modules-deps)
 
+# Sets up dependencies such that whenever a host cross module is installed,
+# any other host cross modules listed in $(ALL_MODULES.$(m).REQUIRED_FROM_HOST_CROSS) will also be installed
+define add-all-host-cross-to-host-cross-required-modules-deps
+$(foreach m,$(ALL_MODULES), \
+  $(eval r := $(ALL_MODULES.$(m).REQUIRED_FROM_HOST_CROSS)) \
+  $(if $(r), \
+    $(eval r := $(call module-installed-files,$(r))) \
+    $(eval hc_m := $(filter $(HOST_CROSS_OUT)/%, $(ALL_MODULES.$(m).INSTALLED))) \
+    $(eval hc_r := $(filter $(HOST_CROSS_OUT)/%, $(r))) \
+    $(eval hc_m := $(filter-out $(hc_r), $(hc_m))) \
+    $(if $(hc_m), $(eval $(call add-required-deps, $(hc_m),$(hc_r)))) \
+  ) \
+)
+endef
+$(call add-all-host-cross-to-host-cross-required-modules-deps)
+
 # Sets up dependencies such that whenever a target module is installed,
-# any other target modules listed in $(ALL_MODULES.$(m).REQUIRED) will also be installed
+# any other target modules listed in $(ALL_MODULES.$(m).REQUIRED_FROM_TARGET) will also be installed
 define add-all-target-to-target-required-modules-deps
 $(foreach m,$(ALL_MODULES), \
-  $(eval r := $(ALL_MODULES.$(m).REQUIRED)) \
+  $(eval r := $(ALL_MODULES.$(m).REQUIRED_FROM_TARGET)) \
   $(if $(r), \
     $(eval r := $(call module-installed-files,$(r))) \
     $(eval t_m := $(filter $(TARGET_OUT_ROOT)/%, $(ALL_MODULES.$(m).INSTALLED))) \
@@ -664,10 +710,10 @@
 $(call add-all-target-to-target-required-modules-deps)
 
 # Sets up dependencies such that whenever a host module is installed,
-# any target modules listed in $(ALL_MODULES.$(m).TARGET_REQUIRED) will also be installed
+# any target modules listed in $(ALL_MODULES.$(m).TARGET_REQUIRED_FROM_HOST) will also be installed
 define add-all-host-to-target-required-modules-deps
 $(foreach m,$(ALL_MODULES), \
-  $(eval req_mods := $(ALL_MODULES.$(m).TARGET_REQUIRED))\
+  $(eval req_mods := $(ALL_MODULES.$(m).TARGET_REQUIRED_FROM_HOST))\
   $(if $(req_mods), \
     $(eval req_files := )\
     $(foreach req_mod,$(req_mods), \
@@ -690,10 +736,10 @@
 $(call add-all-host-to-target-required-modules-deps)
 
 # Sets up dependencies such that whenever a target module is installed,
-# any host modules listed in $(ALL_MODULES.$(m).HOST_REQUIRED) will also be installed
+# any host modules listed in $(ALL_MODULES.$(m).HOST_REQUIRED_FROM_TARGET) will also be installed
 define add-all-target-to-host-required-modules-deps
 $(foreach m,$(ALL_MODULES), \
-  $(eval req_mods := $(ALL_MODULES.$(m).HOST_REQUIRED))\
+  $(eval req_mods := $(ALL_MODULES.$(m).HOST_REQUIRED_FROM_TARGET))\
   $(if $(req_mods), \
     $(eval req_files := )\
     $(foreach req_mod,$(req_mods), \
@@ -723,7 +769,7 @@
 hc_r :=
 
 # Establish the dependencies on the shared libraries.
-# It also adds the shared library module names to ALL_MODULES.$(m).REQUIRED,
+# It also adds the shared library module names to ALL_MODULES.$(m).REQUIRED_FROM_(TARGET|HOST|HOST_CROSS),
 # so they can be expanded to product_MODULES later.
 # $(1): TARGET_ or HOST_ or HOST_CROSS_.
 # $(2): non-empty for 2nd arch.
@@ -743,7 +789,7 @@
     $(eval ALL_MODULES.$(mod).HOST_SHARED_LIBRARIES := $$(ALL_MODULES.$(mod).HOST_SHARED_LIBRARIES) $(deps))\
     $(eval $(call add-required-host-so-deps,$(word 2,$(p)),$(r))),\
     $(eval $(call add-required-deps,$(word 2,$(p)),$(r))))\
-  $(eval ALL_MODULES.$(mod).REQUIRED += $(deps)))
+  $(eval ALL_MODULES.$(mod).REQUIRED_FROM_$(patsubst %_,%,$(1)) += $(deps)))
 endef
 
 # Recursively resolve host shared library dependency for a given module.
@@ -1025,7 +1071,7 @@
 # $(3): The list of overridden modules.
 # Returns empty string (maybe with some whitespaces).
 define expand-required-modules
-$(eval _erm_req := $(foreach m,$(2),$(ALL_MODULES.$(m).REQUIRED))) \
+$(eval _erm_req := $(foreach m,$(2),$(ALL_MODULES.$(m).REQUIRED_FROM_TARGET))) \
 $(eval _erm_new_modules := $(sort $(filter-out $($(1)),$(_erm_req)))) \
 $(eval _erm_new_overrides := $(call module-overrides,$(_erm_new_modules))) \
 $(eval _erm_all_overrides := $(3) $(_erm_new_overrides)) \
@@ -1038,12 +1084,17 @@
 
 # Same as expand-required-modules above, but does not handle module overrides, as
 # we don't intend to support them on the host.
+# $(1): The variable name that holds the initial module name list.
+#       the variable will be modified to hold the expanded results.
+# $(2): The initial module name list.
+# $(3): HOST or HOST_CROSS depending on whether we're expanding host or host cross modules
+# Returns empty string (maybe with some whitespaces).
 define expand-required-host-modules
-$(eval _erm_req := $(foreach m,$(2),$(ALL_MODULES.$(m).REQUIRED))) \
+$(eval _erm_req := $(foreach m,$(2),$(ALL_MODULES.$(m).REQUIRED_FROM_$(3)))) \
 $(eval _erm_new_modules := $(sort $(filter-out $($(1)),$(_erm_req)))) \
 $(eval $(1) += $(_erm_new_modules)) \
 $(if $(_erm_new_modules),\
-  $(call expand-required-host-modules,$(1),$(_erm_new_modules)))
+  $(call expand-required-host-modules,$(1),$(_erm_new_modules),$(3)))
 endef
 
 # Transforms paths relative to PRODUCT_OUT to absolute paths.
@@ -1124,8 +1175,13 @@
   $(eval ### For the rest we add both) \
   $(eval _hif_modules += $(call get-host-32-bit-modules, $(_hif_modules_rest))) \
   $(eval _hif_modules += $(_hif_modules_rest)) \
-  $(call expand-required-host-modules,_hif_modules,$(_hif_modules)) \
-  $(filter $(HOST_OUT_ROOT)/%,$(call module-installed-files, $(_hif_modules)))
+  $(eval ### Split host vs host cross modules) \
+  $(eval _hcif_modules := $(filter host_cross_%,$(_hif_modules))) \
+  $(eval _hif_modules := $(filter-out host_cross_%,$(_hif_modules))) \
+  $(call expand-required-host-modules,_hif_modules,$(_hif_modules),HOST) \
+  $(call expand-required-host-modules,_hcif_modules,$(_hcif_modules),HOST_CROSS) \
+  $(filter $(HOST_OUT)/%,$(call module-installed-files, $(_hif_modules))) \
+  $(filter $(HOST_CROSS_OUT)/%,$(call module-installed-files, $(_hcif_modules)))
 endef
 
 # Fails the build if the given list is non-empty, and prints it entries (stripping PRODUCT_OUT).
@@ -1164,7 +1220,7 @@
     ifneq ($(HOST_OS),darwin)
       _modules := $(PRODUCT_HOST_PACKAGES)
       _nonexistant_modules := $(foreach m,$(_modules),\
-        $(if $(filter FAKE,$(ALL_MODULES.$(m).CLASS))$(filter $(HOST_OUT_ROOT)/%,$(ALL_MODULES.$(m).INSTALLED)),,$(m)))
+        $(if $(ALL_MODULES.$(m).REQUIRED_FROM_HOST)$(filter $(HOST_OUT_ROOT)/%,$(ALL_MODULES.$(m).INSTALLED)),,$(m)))
       $(call maybe-print-list-and-error,$(_nonexistant_modules),\
         $(INTERNAL_PRODUCT) includes non-existant modules in PRODUCT_HOST_PACKAGES)
     endif
@@ -1668,7 +1724,7 @@
 modules:
 	@echo "Available sub-modules:"
 	@echo "$(call module-names-for-tag-list,$(ALL_MODULE_TAGS))" | \
-	      tr -s ' ' '\n' | sort -u | $(COLUMN)
+	      tr -s ' ' '\n' | sort -u
 
 .PHONY: dump-files
 dump-files:
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index e505945..f5b92fe 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -32,421 +32,27 @@
   my_prebuilt_src_file := $(LOCAL_PATH)/$(LOCAL_SRC_FILES)
   LOCAL_SRC_FILES :=
 else ifdef LOCAL_REPLACE_PREBUILT_APK_INSTALLED
-  # This is handled specially below
+  # This is handled specially in app_prebuilt_internal.mk
 else
   $(call pretty-error,No source files specified)
 endif
 
 LOCAL_CHECKED_MODULE := $(my_prebuilt_src_file)
 
-ifeq (APPS,$(LOCAL_MODULE_CLASS))
-include $(BUILD_SYSTEM)/app_prebuilt_internal.mk
-else
-#
-# Non-APPS prebuilt modules handling almost to the end of the file
-#
-
-my_strip_module := $(firstword \
-  $(LOCAL_STRIP_MODULE_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)) \
-  $(LOCAL_STRIP_MODULE))
-
-ifeq (SHARED_LIBRARIES,$(LOCAL_MODULE_CLASS))
-  ifeq ($(LOCAL_IS_HOST_MODULE)$(my_strip_module),)
-    # Strip but not try to add debuglink
-    my_strip_module := no_debuglink
-  endif
-endif
-
-ifneq ($(filter STATIC_LIBRARIES SHARED_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
-  prebuilt_module_is_a_library := true
-else
-  prebuilt_module_is_a_library :=
-endif
-
-# Don't install static libraries by default.
-ifndef LOCAL_UNINSTALLABLE_MODULE
-ifeq (STATIC_LIBRARIES,$(LOCAL_MODULE_CLASS))
-  LOCAL_UNINSTALLABLE_MODULE := true
-endif
-endif
-
-ifeq (JAVA_LIBRARIES,$(LOCAL_IS_HOST_MODULE)$(LOCAL_MODULE_CLASS)$(filter true,$(LOCAL_UNINSTALLABLE_MODULE)))
-  prebuilt_module_is_dex_javalib := true
-else
-  prebuilt_module_is_dex_javalib :=
-endif
-
+ifneq (APPS,$(LOCAL_MODULE_CLASS))
 ifdef LOCAL_COMPRESSED_MODULE
 $(error $(LOCAL_MODULE) : LOCAL_COMPRESSED_MODULE can only be defined for module class APPS)
 endif  # LOCAL_COMPRESSED_MODULE
+endif  # APPS
 
-my_check_elf_file_shared_lib_files :=
-
-ifneq ($(filter true keep_symbols no_debuglink mini-debug-info,$(my_strip_module)),)
-  ifdef LOCAL_IS_HOST_MODULE
-    $(call pretty-error,Cannot strip/pack host module)
-  endif
-  ifeq ($(filter SHARED_LIBRARIES EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
-    $(call pretty-error,Can strip/pack only shared libraries or executables)
-  endif
-  ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
-    $(call pretty-error,Cannot strip/pack scripts)
-  endif
-  # Set the arch-specific variables to set up the strip rules
-  LOCAL_STRIP_MODULE_$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH) := $(my_strip_module)
-  include $(BUILD_SYSTEM)/dynamic_binary.mk
-  built_module := $(linked_module)
-
-  ifneq ($(LOCAL_SDK_VERSION),)
-    # binary.mk filters out NDK_MIGRATED_LIBS from my_shared_libs, thus those NDK libs are not added
-    # to DEPENDENCIES_ON_SHARED_LIBRARIES. Assign $(my_ndk_shared_libraries_fullpath) to
-    # my_check_elf_file_shared_lib_files so that check_elf_file.py can see those NDK stub libs.
-    my_check_elf_file_shared_lib_files := $(my_ndk_shared_libraries_fullpath)
-  endif
-else  # my_strip_module not true
-  include $(BUILD_SYSTEM)/base_rules.mk
-  built_module := $(LOCAL_BUILT_MODULE)
-
-ifdef prebuilt_module_is_a_library
-export_includes := $(intermediates)/export_includes
-export_cflags := $(foreach d,$(LOCAL_EXPORT_C_INCLUDE_DIRS),-I $(d))
-$(export_includes): PRIVATE_EXPORT_CFLAGS := $(export_cflags)
-$(export_includes): $(LOCAL_EXPORT_C_INCLUDE_DEPS)
-	@echo Export includes file: $< -- $@
-	$(hide) mkdir -p $(dir $@) && rm -f $@
-ifdef export_cflags
-	$(hide) echo "$(PRIVATE_EXPORT_CFLAGS)" >$@
+ifeq (APPS,$(LOCAL_MODULE_CLASS))
+  include $(BUILD_SYSTEM)/app_prebuilt_internal.mk
+else ifeq (JAVA_LIBRARIES,$(LOCAL_MODULE_CLASS))
+  include $(BUILD_SYSTEM)/java_prebuilt_internal.mk
 else
-	$(hide) touch $@
+  # TODO(jungjw): Check LOCAL_MODULE_CLASS value and generate an error for unexpected ones.
+  include $(BUILD_SYSTEM)/cc_prebuilt_internal.mk
 endif
-export_cflags :=
-
-include $(BUILD_SYSTEM)/allowed_ndk_types.mk
-
-ifdef LOCAL_SDK_VERSION
-my_link_type := native:ndk:$(my_ndk_stl_family):$(my_ndk_stl_link_type)
-else ifdef LOCAL_USE_VNDK
-    _name := $(patsubst %.vendor,%,$(LOCAL_MODULE))
-    ifneq ($(filter $(_name),$(VNDK_CORE_LIBRARIES) $(VNDK_SAMEPROCESS_LIBRARIES) $(LLNDK_LIBRARIES)),)
-        ifeq ($(filter $(_name),$(VNDK_PRIVATE_LIBRARIES)),)
-            my_link_type := native:vndk
-        else
-            my_link_type := native:vndk_private
-        endif
-    else
-        my_link_type := native:vendor
-    endif
-else ifneq ($(filter $(TARGET_RECOVERY_OUT)/%,$(LOCAL_MODULE_PATH)),)
-my_link_type := native:recovery
-else
-my_link_type := native:platform
-endif
-
-# TODO: check dependencies of prebuilt files
-my_link_deps :=
-
-my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
-my_common :=
-include $(BUILD_SYSTEM)/link_type.mk
-endif  # prebuilt_module_is_a_library
-
-# The real dependency will be added after all Android.mks are loaded and the install paths
-# of the shared libraries are determined.
-ifdef LOCAL_INSTALLED_MODULE
-ifdef LOCAL_IS_HOST_MODULE
-    ifeq ($(LOCAL_SYSTEM_SHARED_LIBRARIES),none)
-        my_system_shared_libraries :=
-    else
-        my_system_shared_libraries := $(LOCAL_SYSTEM_SHARED_LIBRARIES)
-    endif
-else
-    ifeq ($(LOCAL_SYSTEM_SHARED_LIBRARIES),none)
-        my_system_shared_libraries := libc libm libdl
-    else
-        my_system_shared_libraries := $(LOCAL_SYSTEM_SHARED_LIBRARIES)
-        my_system_shared_libraries := $(patsubst libc,libc libdl,$(my_system_shared_libraries))
-    endif
-endif
-
-my_shared_libraries := \
-    $(filter-out $(my_system_shared_libraries),$(LOCAL_SHARED_LIBRARIES)) \
-    $(my_system_shared_libraries)
-
-ifdef my_shared_libraries
-# Extra shared libraries introduced by LOCAL_CXX_STL.
-include $(BUILD_SYSTEM)/cxx_stl_setup.mk
-ifdef LOCAL_USE_VNDK
-  my_shared_libraries := $(foreach l,$(my_shared_libraries),\
-    $(if $(SPLIT_VENDOR.SHARED_LIBRARIES.$(l)),$(l).vendor,$(l)))
-endif
-$(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)DEPENDENCIES_ON_SHARED_LIBRARIES += \
-  $(my_register_name):$(LOCAL_INSTALLED_MODULE):$(subst $(space),$(comma),$(my_shared_libraries))
-endif
-endif  # my_shared_libraries
-
-# We need to enclose the above export_includes and my_built_shared_libraries in
-# "my_strip_module not true" because otherwise the rules are defined in dynamic_binary.mk.
-endif  # my_strip_module not true
-
-# Check prebuilt ELF binaries.
-include $(BUILD_SYSTEM)/check_elf_file.mk
-
-ifeq ($(NATIVE_COVERAGE),true)
-ifneq (,$(strip $(LOCAL_PREBUILT_COVERAGE_ARCHIVE)))
-  $(eval $(call copy-one-file,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(intermediates)/$(LOCAL_MODULE).gcnodir))
-  ifneq ($(LOCAL_UNINSTALLABLE_MODULE),true)
-    ifdef LOCAL_IS_HOST_MODULE
-      my_coverage_path := $($(my_prefix)OUT_COVERAGE)/$(patsubst $($(my_prefix)OUT)/%,%,$(my_module_path))
-    else
-      my_coverage_path := $(TARGET_OUT_COVERAGE)/$(patsubst $(PRODUCT_OUT)/%,%,$(my_module_path))
-    endif
-    my_coverage_path := $(my_coverage_path)/$(patsubst %.so,%,$(my_installed_module_stem)).gcnodir
-    $(eval $(call copy-one-file,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(my_coverage_path)))
-    $(LOCAL_BUILT_MODULE): $(my_coverage_path)
-  endif
-else
-# Coverage information is needed when static lib is a dependency of another
-# coverage-enabled module.
-ifeq (STATIC_LIBRARIES, $(LOCAL_MODULE_CLASS))
-GCNO_ARCHIVE := $(LOCAL_MODULE).gcnodir
-$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_ALL_OBJECTS :=
-$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_ALL_WHOLE_STATIC_LIBRARIES :=
-$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_PREFIX := $(my_prefix)
-$(intermediates)/$(GCNO_ARCHIVE) : PRIVATE_2ND_ARCH_VAR_PREFIX := $(LOCAL_2ND_ARCH_VAR_PREFIX)
-$(intermediates)/$(GCNO_ARCHIVE) :
-	$(transform-o-to-static-lib)
-endif
-endif
-endif
-
-ifeq ($(prebuilt_module_is_dex_javalib),true)
-my_dex_jar := $(my_prebuilt_src_file)
-# This is a target shared library, i.e. a jar with classes.dex.
-
-ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_BOOT_JARS)),)
-  $(call pretty-error,Modules in PRODUCT_BOOT_JARS must be defined in Android.bp files)
-endif
-
-#######################################
-# defines built_odex along with rule to install odex
-include $(BUILD_SYSTEM)/dex_preopt_odex_install.mk
-#######################################
-ifdef LOCAL_DEX_PREOPT
-
-$(built_module): PRIVATE_STRIP_SCRIPT := $(intermediates)/strip.sh
-$(built_module): $(intermediates)/strip.sh
-$(built_module): | $(DEXPREOPT_STRIP_DEPS)
-$(built_module): .KATI_DEPFILE := $(built_module).d
-$(built_module): $(my_prebuilt_src_file)
-	$(PRIVATE_STRIP_SCRIPT) $< $@
-
-else # ! LOCAL_DEX_PREOPT
-$(built_module) : $(my_prebuilt_src_file)
-	$(call copy-file-to-target)
-endif # LOCAL_DEX_PREOPT
-
-else  # ! prebuilt_module_is_dex_javalib
-ifneq ($(filter init%rc,$(notdir $(LOCAL_INSTALLED_MODULE)))$(filter %/etc/init,$(dir $(LOCAL_INSTALLED_MODULE))),)
-  $(eval $(call copy-init-script-file-checked,$(my_prebuilt_src_file),$(built_module)))
-else ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
-$(built_module) : $(my_prebuilt_src_file)
-	$(transform-prebuilt-to-target-strip-comments)
-else
-$(built_module) : $(my_prebuilt_src_file)
-	$(transform-prebuilt-to-target)
-endif
-ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
-	$(hide) chmod +x $@
-endif
-endif # ! prebuilt_module_is_dex_javalib
-
-ifeq ($(LOCAL_MODULE_CLASS),JAVA_LIBRARIES)
-my_src_jar := $(my_prebuilt_src_file)
-
-ifdef LOCAL_IS_HOST_MODULE
-# for host java libraries deps should be in the common dir, so we make a copy in
-# the common dir.
-common_classes_jar := $(intermediates.COMMON)/classes.jar
-common_header_jar := $(intermediates.COMMON)/classes-header.jar
-
-$(common_classes_jar): PRIVATE_MODULE := $(LOCAL_MODULE)
-$(common_classes_jar): PRIVATE_PREFIX := $(my_prefix)
-
-$(common_classes_jar) : $(my_src_jar)
-	$(transform-prebuilt-to-target)
-
-ifneq ($(TURBINE_ENABLED),false)
-$(common_header_jar) : $(my_src_jar)
-	$(transform-prebuilt-to-target)
-endif
-
-else # !LOCAL_IS_HOST_MODULE
-# for target java libraries, the LOCAL_BUILT_MODULE is in a product-specific dir,
-# while the deps should be in the common dir, so we make a copy in the common dir.
-common_classes_jar := $(intermediates.COMMON)/classes.jar
-common_header_jar := $(intermediates.COMMON)/classes-header.jar
-common_classes_pre_proguard_jar := $(intermediates.COMMON)/classes-pre-proguard.jar
-common_javalib_jar := $(intermediates.COMMON)/javalib.jar
-
-$(common_classes_jar) $(common_classes_pre_proguard_jar) $(common_javalib_jar): PRIVATE_MODULE := $(LOCAL_MODULE)
-$(common_classes_jar) $(common_classes_pre_proguard_jar) $(common_javalib_jar): PRIVATE_PREFIX := $(my_prefix)
-
-ifeq ($(LOCAL_SDK_VERSION),system_current)
-my_link_type := java:system
-else ifneq (,$(call has-system-sdk-version,$(LOCAL_SDK_VERSION)))
-my_link_type := java:system
-else ifeq ($(LOCAL_SDK_VERSION),core_current)
-my_link_type := java:core
-else ifneq ($(LOCAL_SDK_VERSION),)
-my_link_type := java:sdk
-else
-my_link_type := java:platform
-endif
-
-# TODO: check dependencies of prebuilt files
-my_link_deps :=
-
-my_2nd_arch_prefix := $(LOCAL_2ND_ARCH_VAR_PREFIX)
-my_common := COMMON
-include $(BUILD_SYSTEM)/link_type.mk
-
-ifeq ($(prebuilt_module_is_dex_javalib),true)
-# For prebuilt shared Java library we don't have classes.jar.
-$(common_javalib_jar) : $(my_src_jar)
-	$(transform-prebuilt-to-target)
-
-else  # ! prebuilt_module_is_dex_javalib
-
-my_src_aar := $(filter %.aar, $(my_prebuilt_src_file))
-ifneq ($(my_src_aar),)
-# This is .aar file, archive of classes.jar and Android resources.
-
-# run Jetifier if needed
-LOCAL_JETIFIER_INPUT_FILE := $(my_src_aar)
-include $(BUILD_SYSTEM)/jetifier.mk
-my_src_aar := $(LOCAL_JETIFIER_OUTPUT_FILE)
-
-my_src_jar := $(intermediates.COMMON)/aar/classes.jar
-my_src_proguard_options := $(intermediates.COMMON)/aar/proguard.txt
-my_src_android_manifest := $(intermediates.COMMON)/aar/AndroidManifest.xml
-
-$(my_src_jar) : .KATI_IMPLICIT_OUTPUTS := $(my_src_proguard_options)
-$(my_src_jar) : .KATI_IMPLICIT_OUTPUTS += $(my_src_android_manifest)
-$(my_src_jar) : $(my_src_aar)
-	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@) $(dir $@)/res
-	$(hide) unzip -qo -d $(dir $@) $<
-	# Make sure the extracted classes.jar has a new timestamp.
-	$(hide) touch $@
-	# Make sure the proguard and AndroidManifest.xml files exist
-	# and have a new timestamp.
-	$(hide) touch $(dir $@)/proguard.txt
-	$(hide) touch $(dir $@)/AndroidManifest.xml
-
-my_prebuilt_android_manifest := $(intermediates.COMMON)/manifest/AndroidManifest.xml
-$(eval $(call copy-one-file,$(my_src_android_manifest),$(my_prebuilt_android_manifest)))
-$(call add-dependency,$(LOCAL_BUILT_MODULE),$(my_prebuilt_android_manifest))
-
-else
-
-# run Jetifier if needed
-LOCAL_JETIFIER_INPUT_FILE := $(my_src_jar)
-include $(BUILD_SYSTEM)/jetifier.mk
-my_src_jar := $(LOCAL_JETIFIER_OUTPUT_FILE)
-
-endif
-
-$(common_classes_jar) : $(my_src_jar)
-	$(transform-prebuilt-to-target)
-
-ifneq ($(TURBINE_ENABLED),false)
-$(common_header_jar) : $(my_src_jar)
-	$(transform-prebuilt-to-target)
-endif
-
-$(common_classes_pre_proguard_jar) : $(my_src_jar)
-	$(transform-prebuilt-to-target)
-
-$(common_javalib_jar) : $(common_classes_jar)
-	$(transform-prebuilt-to-target)
-
-include $(BUILD_SYSTEM)/force_aapt2.mk
-
-ifdef LOCAL_AAPT2_ONLY
-LOCAL_USE_AAPT2 := true
-endif
-
-ifeq ($(LOCAL_USE_AAPT2),true)
-ifneq ($(my_src_aar),)
-
-$(intermediates.COMMON)/export_proguard_flags : $(my_src_proguard_options)
-	$(transform-prebuilt-to-target)
-
-LOCAL_SDK_RES_VERSION:=$(strip $(LOCAL_SDK_RES_VERSION))
-ifeq ($(LOCAL_SDK_RES_VERSION),)
-  LOCAL_SDK_RES_VERSION:=$(LOCAL_SDK_VERSION)
-endif
-
-framework_res_package_export :=
-# Please refer to package.mk
-ifneq ($(LOCAL_NO_STANDARD_LIBRARIES),true)
-ifneq ($(filter-out current system_current test_current,$(LOCAL_SDK_RES_VERSION))$(if $(TARGET_BUILD_APPS),$(filter current system_current test_current,$(LOCAL_SDK_RES_VERSION))),)
-framework_res_package_export := \
-    $(call resolve-prebuilt-sdk-jar-path,$(LOCAL_SDK_RES_VERSION))
-else
-framework_res_package_export := \
-    $(call intermediates-dir-for,APPS,framework-res,,COMMON)/package-export.apk
-endif
-endif
-
-my_res_package := $(intermediates.COMMON)/package-res.apk
-
-# We needed only very few PRIVATE variables and aapt2.mk input variables. Reset the unnecessary ones.
-$(my_res_package): PRIVATE_AAPT2_CFLAGS :=
-$(my_res_package): PRIVATE_AAPT_FLAGS := --static-lib --no-static-lib-packages --auto-add-overlay
-$(my_res_package): PRIVATE_ANDROID_MANIFEST := $(my_src_android_manifest)
-$(my_res_package): PRIVATE_AAPT_INCLUDES := $(framework_res_package_export)
-$(my_res_package): PRIVATE_SOURCE_INTERMEDIATES_DIR :=
-$(my_res_package): PRIVATE_PROGUARD_OPTIONS_FILE :=
-$(my_res_package): PRIVATE_DEFAULT_APP_TARGET_SDK :=
-$(my_res_package): PRIVATE_DEFAULT_APP_TARGET_SDK :=
-$(my_res_package): PRIVATE_PRODUCT_AAPT_CONFIG :=
-$(my_res_package): PRIVATE_PRODUCT_AAPT_PREF_CONFIG :=
-$(my_res_package): PRIVATE_TARGET_AAPT_CHARACTERISTICS :=
-$(my_res_package) : $(framework_res_package_export)
-$(my_res_package) : $(my_src_android_manifest)
-
-full_android_manifest :=
-my_res_resources :=
-my_overlay_resources :=
-my_compiled_res_base_dir := $(intermediates.COMMON)/flat-res
-R_file_stamp :=
-proguard_options_file :=
-my_generated_res_dirs := $(intermediates.COMMON)/aar/res
-my_generated_res_dirs_deps := $(my_src_jar)
-include $(BUILD_SYSTEM)/aapt2.mk
-
-# Make sure my_res_package is created when you run mm/mmm.
-$(built_module) : $(my_res_package)
-endif  # $(my_src_aar)
-endif  # LOCAL_USE_AAPT2
-# make sure the classes.jar and javalib.jar are built before $(LOCAL_BUILT_MODULE)
-$(built_module) : $(common_javalib_jar)
-
-my_exported_sdk_libs_file := $(intermediates.COMMON)/exported-sdk-libs
-$(my_exported_sdk_libs_file): PRIVATE_EXPORTED_SDK_LIBS := $(LOCAL_EXPORT_SDK_LIBRARIES)
-$(my_exported_sdk_libs_file):
-	@echo "Export SDK libs $@"
-	$(hide) mkdir -p $(dir $@) && rm -f $@
-	$(if $(PRIVATE_EXPORTED_SDK_LIBS),\
-		$(hide) echo $(PRIVATE_EXPORTED_SDK_LIBS) | tr ' ' '\n' > $@,\
-		$(hide) touch $@)
-
-endif # ! prebuilt_module_is_dex_javalib
-endif # LOCAL_IS_HOST_MODULE is not set
-
-endif # JAVA_LIBRARIES
-
-endif # APPS
 
 $(built_module) : $(LOCAL_ADDITIONAL_DEPENDENCIES)
 
diff --git a/core/product.mk b/core/product.mk
index 29bd1d1..777d2bc 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -322,6 +322,11 @@
 # set this variable to prevent OTA failures.
 _product_var_list += PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS
 
+# If set to true, this product builds a generic OTA package, which installs generic system images
+# onto matching devices. The product may only build a subset of system images (e.g. only
+# system.img), so devices need to install the package in a system-only OTA manner.
+_product_var_list += PRODUCT_BUILD_GENERIC_OTA_PACKAGE
+
 # Whether any paths are excluded from being set XOM when ENABLE_XOM=true
 _product_var_list += PRODUCT_XOM_EXCLUDE_PATHS
 _product_var_list += PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES
diff --git a/core/soong_cc_prebuilt.mk b/core/soong_cc_prebuilt.mk
index 679d5b8..31b0e63 100644
--- a/core/soong_cc_prebuilt.mk
+++ b/core/soong_cc_prebuilt.mk
@@ -96,9 +96,11 @@
 endif
 
 # Check prebuilt ELF binaries.
-ifneq ($(LOCAL_CHECK_ELF_FILES),)
-my_prebuilt_src_file := $(LOCAL_PREBUILT_MODULE_FILE)
-include $(BUILD_SYSTEM)/check_elf_file.mk
+ifdef LOCAL_INSTALLED_MODULE
+  ifneq ($(LOCAL_CHECK_ELF_FILES),)
+    my_prebuilt_src_file := $(LOCAL_PREBUILT_MODULE_FILE)
+    include $(BUILD_SYSTEM)/check_elf_file.mk
+  endif
 endif
 
 # The real dependency will be added after all Android.mks are loaded and the install paths
diff --git a/core/soong_config.mk b/core/soong_config.mk
index baba31b..c01fc98 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -33,6 +33,11 @@
 $(call add_json_bool, Platform_sdk_final,                $(filter REL,$(PLATFORM_VERSION_CODENAME)))
 $(call add_json_csv,  Platform_version_active_codenames, $(PLATFORM_VERSION_ALL_CODENAMES))
 $(call add_json_csv,  Platform_version_future_codenames, $(PLATFORM_VERSION_FUTURE_CODENAMES))
+$(call add_json_str,  Platform_security_patch,           $(PLATFORM_SECURITY_PATCH))
+$(call add_json_str,  Platform_preview_sdk_version,      $(PLATFORM_PREVIEW_SDK_VERSION))
+$(call add_json_str,  Platform_base_os,                  $(PLATFORM_BASE_OS))
+
+$(call add_json_str,  Platform_min_supported_target_sdk_version, $(PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION))
 
 $(call add_json_bool, Allow_missing_dependencies,        $(ALLOW_MISSING_DEPENDENCIES))
 $(call add_json_bool, Unbundled_build,                   $(TARGET_BUILD_APPS))
@@ -160,6 +165,8 @@
 $(call add_json_list, ProductHiddenAPIStubsSystem,       $(PRODUCT_HIDDENAPI_STUBS_SYSTEM))
 $(call add_json_list, ProductHiddenAPIStubsTest,         $(PRODUCT_HIDDENAPI_STUBS_TEST))
 
+$(call add_json_str,  TargetFSConfigGen,                 $(TARGET_FS_CONFIG_GEN))
+
 $(call add_json_map, VendorVars)
 $(foreach namespace,$(SOONG_CONFIG_NAMESPACES),\
   $(call add_json_map, $(namespace))\
diff --git a/core/tasks/tools/package-modules.mk b/core/tasks/tools/package-modules.mk
index 82b4c6a..d7b3010 100644
--- a/core/tasks/tools/package-modules.mk
+++ b/core/tasks/tools/package-modules.mk
@@ -21,8 +21,8 @@
 my_modules_and_deps := $(my_modules)
 $(foreach m,$(my_modules),\
   $(eval _explicitly_required := \
-    $(strip $(ALL_MODULES.$(m).EXPLICITLY_REQUIRED)\
-    $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).EXPLICITLY_REQUIRED)))\
+    $(strip $(ALL_MODULES.$(m).EXPLICITLY_REQUIRED_FROM_TARGET)\
+    $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).EXPLICITLY_REQUIRED_FROM_TARGET)))\
   $(eval my_modules_and_deps += $(_explicitly_required))\
 )
 
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 6923698..a392924 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -39,9 +39,9 @@
   include $(INTERNAL_BUILD_ID_MAKEFILE)
 endif
 
-DEFAULT_PLATFORM_VERSION := QPR1
-MIN_PLATFORM_VERSION := QPR1
-MAX_PLATFORM_VERSION := QPR1
+DEFAULT_PLATFORM_VERSION := QP1A
+MIN_PLATFORM_VERSION := QP1A
+MAX_PLATFORM_VERSION := QP1A
 
 ALLOWED_VERSIONS := $(call allowed-platform-versions,\
   $(MIN_PLATFORM_VERSION),\
@@ -82,11 +82,11 @@
 # please add that PLATFORM_VERSION as well as clean up obsolete PLATFORM_VERSION's
 # in the following text file:
 # cts/tests/tests/os/assets/platform_versions.txt
-PLATFORM_VERSION.QPR1 := Q
+PLATFORM_VERSION.QP1A := Q
 
 # These are the current development codenames, if the build is not a final
 # release build.  If this is a final release build, it is simply "REL".
-PLATFORM_VERSION_CODENAME.QPR1 := Q
+PLATFORM_VERSION_CODENAME.QP1A := Q
 
 ifndef PLATFORM_VERSION
   PLATFORM_VERSION := $(PLATFORM_VERSION.$(TARGET_PLATFORM_VERSION))
@@ -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-03-05
+      PLATFORM_SECURITY_PATCH := 2019-04-05
 endif
 .KATI_READONLY := PLATFORM_SECURITY_PATCH
 
diff --git a/target/board/BoardConfigGsiCommon.mk b/target/board/BoardConfigGsiCommon.mk
index 58cf9c6..d4025c3 100644
--- a/target/board/BoardConfigGsiCommon.mk
+++ b/target/board/BoardConfigGsiCommon.mk
@@ -6,6 +6,8 @@
 
 include build/make/target/board/BoardConfigMainlineCommon.mk
 
+TARGET_NO_KERNEL := true
+
 # This flag is set by mainline but isn't desired for GSI.
 BOARD_USES_SYSTEM_OTHER_ODEX :=
 
diff --git a/target/board/BoardConfigMainlineCommon.mk b/target/board/BoardConfigMainlineCommon.mk
index acbd11d..6c56671 100644
--- a/target/board/BoardConfigMainlineCommon.mk
+++ b/target/board/BoardConfigMainlineCommon.mk
@@ -4,17 +4,13 @@
 
 # The generic product target doesn't have any hardware-specific pieces.
 TARGET_NO_BOOTLOADER := true
-TARGET_NO_KERNEL := true
 TARGET_NO_RECOVERY := true
 
 TARGET_USERIMAGES_USE_EXT4 := true
 
 # Mainline devices must have /vendor and /product partitions.
 TARGET_COPY_OUT_VENDOR := vendor
-BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
-
 TARGET_COPY_OUT_PRODUCT := product
-BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE := ext4
 
 BOARD_VNDK_VERSION := current
 
@@ -42,7 +38,9 @@
 
 # Enable A/B update
 AB_OTA_UPDATER := true
-AB_OTA_PARTITIONS := system
 
 # Enable system property split for Treble
 BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
+
+# Generate an APEX image for experiment b/119800099.
+DEXPREOPT_GENERATE_APEX_IMAGE := true
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 3f83edb..7d92b7d 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -67,7 +67,7 @@
 
 # TODO(b/36764215): remove this setting when the generic system image
 # no longer has QCOM-specific directories under /.
-BOARD_SEPOLICY_DIRS += build/target/board/generic_arm64_ab/sepolicy
+BOARD_SEPOLICY_DIRS += build/make/target/board/generic_arm64_ab/sepolicy
 
 # Wifi.
 BOARD_WLAN_DEVICE           := emulator
diff --git a/target/board/generic_arm64_ab/BoardConfig.mk b/target/board/generic_arm64_ab/BoardConfig.mk
index 6e54d81..28140ce 100644
--- a/target/board/generic_arm64_ab/BoardConfig.mk
+++ b/target/board/generic_arm64_ab/BoardConfig.mk
@@ -36,4 +36,4 @@
 
 # TODO(b/36764215): remove this setting when the generic system image
 # no longer has QCOM-specific directories under /.
-BOARD_SEPOLICY_DIRS += build/target/board/generic_arm64_ab/sepolicy
+BOARD_SEPOLICY_DIRS += build/make/target/board/generic_arm64_ab/sepolicy
diff --git a/target/board/generic_arm_ab/BoardConfig.mk b/target/board/generic_arm_ab/BoardConfig.mk
index 9100094..bcb4cc5 100644
--- a/target/board/generic_arm_ab/BoardConfig.mk
+++ b/target/board/generic_arm_ab/BoardConfig.mk
@@ -33,4 +33,4 @@
 
 # TODO(b/36764215): remove this setting when the generic system image
 # no longer has QCOM-specific directories under /.
-BOARD_SEPOLICY_DIRS += build/target/board/generic_arm64_ab/sepolicy
+BOARD_SEPOLICY_DIRS += build/make/target/board/generic_arm64_ab/sepolicy
diff --git a/target/board/gsi_arm64/BoardConfig.mk b/target/board/gsi_arm64/BoardConfig.mk
index 90ddd0d..571d623 100644
--- a/target/board/gsi_arm64/BoardConfig.mk
+++ b/target/board/gsi_arm64/BoardConfig.mk
@@ -34,4 +34,4 @@
 
 # TODO(b/36764215): remove this setting when the generic system image
 # no longer has QCOM-specific directories under /.
-BOARD_SEPOLICY_DIRS += build/target/board/generic_arm64_ab/sepolicy
+BOARD_SEPOLICY_DIRS += build/make/target/board/generic_arm64_ab/sepolicy
diff --git a/target/board/mainline_arm64/BoardConfig.mk b/target/board/mainline_arm64/BoardConfig.mk
index 521d976..8bb6212 100644
--- a/target/board/mainline_arm64/BoardConfig.mk
+++ b/target/board/mainline_arm64/BoardConfig.mk
@@ -25,3 +25,10 @@
 TARGET_2ND_CPU_VARIANT := generic
 
 include build/make/target/board/BoardConfigMainlineCommon.mk
+
+TARGET_NO_KERNEL := true
+
+AB_OTA_PARTITIONS := system
+
+BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE := ext4
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index ec463f7..46bf350 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -274,7 +274,6 @@
 PRODUCT_HOST_PACKAGES += \
     BugReport \
     adb \
-    adbd \
     art-tools \
     atest \
     bcc \
@@ -290,9 +289,7 @@
     minigzip \
     mke2fs \
     resize2fs \
-    selinux_policy_system \
     sgdisk \
-    shell_and_utilities_system \
     sqlite3 \
     tinyplay \
     tune2fs \
@@ -311,11 +308,11 @@
 $(error TARGET_CORE_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
 endif
 
-# The order matters
+# The order matters for runtime class lookup performance.
 PRODUCT_BOOT_JARS := \
     $(TARGET_CORE_JARS) \
-    ext \
     framework \
+    ext \
     telephony-common \
     voip-common \
     ims-common
@@ -332,7 +329,8 @@
 
 # Add the compatibility library that is needed when android.test.base
 # is removed from the bootclasspath.
-ifeq ($(REMOVE_ATB_FROM_BCP),true)
+# Default to excluding android.test.base from the bootclasspath.
+ifneq ($(REMOVE_ATB_FROM_BCP),false)
 PRODUCT_PACKAGES += framework-atb-backward-compatibility
 PRODUCT_BOOT_JARS += framework-atb-backward-compatibility
 else
@@ -358,6 +356,7 @@
     showmap \
     sqlite3 \
     ss \
+    start_with_lockagent \
     strace \
     su \
     sanitizer-status \
diff --git a/target/product/go_defaults.mk b/target/product/go_defaults.mk
index faa1852..cb9383f 100644
--- a/target/product/go_defaults.mk
+++ b/target/product/go_defaults.mk
@@ -15,5 +15,5 @@
 #
 
 # Inherit common Android Go defaults.
-$(call inherit-product, build/target/product/go_defaults_common.mk)
+$(call inherit-product, build/make/target/product/go_defaults_common.mk)
 
diff --git a/target/product/go_defaults_512.mk b/target/product/go_defaults_512.mk
index 56ab29b..985912f 100644
--- a/target/product/go_defaults_512.mk
+++ b/target/product/go_defaults_512.mk
@@ -15,7 +15,7 @@
 #
 
 # Inherit common Android Go defaults.
-$(call inherit-product, build/target/product/go_defaults_common.mk)
+$(call inherit-product, build/make/target/product/go_defaults_common.mk)
 
 # 512MB specific properties.
 
diff --git a/target/product/gsi/current.txt b/target/product/gsi/current.txt
index 2716d2c..584a0ca 100644
--- a/target/product/gsi/current.txt
+++ b/target/product/gsi/current.txt
@@ -5,6 +5,7 @@
 LLNDK: libRS.so
 LLNDK: libandroid_net.so
 LLNDK: libc.so
+LLNDK: libcgrouprc.so
 LLNDK: libdl.so
 LLNDK: libft2.so
 LLNDK: liblog.so
diff --git a/target/product/gsi_common.mk b/target/product/gsi_common.mk
index 5e73e63..2c978ab 100644
--- a/target/product/gsi_common.mk
+++ b/target/product/gsi_common.mk
@@ -31,7 +31,6 @@
 # The mainline checking whitelist, should be clean up
 PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST += \
     system/app/messaging/messaging.apk \
-    system/app/PhotoTable/PhotoTable.apk \
     system/app/WAPPushManager/WAPPushManager.apk \
     system/bin/healthd \
     system/etc/init/healthd.rc \
diff --git a/target/product/mainline.mk b/target/product/mainline.mk
index 59bad98..7900cdf 100644
--- a/target/product/mainline.mk
+++ b/target/product/mainline.mk
@@ -14,10 +14,24 @@
 # limitations under the License.
 #
 
-# Makefile including the mainline system image, and the relevant AOSP portions
-# for the other partitions.
+# This makefile is intended to serve as a base for completely AOSP based
+# mainline devices, It contain the mainline system partition and sensible
+# defaults for the product and vendor partition.
 $(call inherit-product, $(SRC_TARGET_DIR)/product/mainline_system.mk)
+
 $(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_vendor.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_product.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_vendor.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_product.mk)
+
+$(call inherit-product, frameworks/base/data/sounds/AllAudio.mk)
+
+PRODUCT_PROPERTY_OVERRIDES += \
+    ro.config.ringtone=Ring_Synth_04.ogg \
+    ro.com.android.dataroaming=true \
+
+PRODUCT_PACKAGES += \
+    PhotoTable \
+    WallpaperPicker \
+
+PRODUCT_COPY_FILES += device/sample/etc/apns-full-conf.xml:$(TARGET_COPY_OUT_PRODUCT)/etc/apns-conf.xml
diff --git a/target/product/mainline_system.mk b/target/product/mainline_system.mk
index ecd5691..d75809c 100644
--- a/target/product/mainline_system.mk
+++ b/target/product/mainline_system.mk
@@ -76,6 +76,7 @@
     android.hardware.secure_element@1.0 \
     android.hardware.wifi@1.0 \
     libaudio-resampler \
+    libdrm \
     liblogwrap \
     liblz4 \
     libminui \
diff --git a/target/product/profile_boot_common.mk b/target/product/profile_boot_common.mk
index 4147dfa..fc19954 100644
--- a/target/product/profile_boot_common.mk
+++ b/target/product/profile_boot_common.mk
@@ -19,7 +19,7 @@
 # remove classes that are no longer in use.
 # Ideally we would just generate an empty boot.art but we don't have the build
 # support to separate the image from the compile code.
-PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION := build/target/product/empty-profile
+PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION := build/make/target/product/empty-profile
 PRODUCT_DEX_PREOPT_BOOT_FLAGS := --count-hotness-in-compiled-code
 DEX_PREOPT_DEFAULT := nostripping
 
@@ -28,7 +28,7 @@
 
 # Use an empty preloaded-classes list.
 PRODUCT_COPY_FILES += \
-    build/target/product/empty-preloaded-classes:system/etc/preloaded-classes
+    build/make/target/product/empty-preloaded-classes:system/etc/preloaded-classes
 
 # Boot image property overrides.
 PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index 412d8cf..e08b56b 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -33,11 +33,6 @@
 PRODUCT_PACKAGES += \
     ext \
 
-# Libcore ICU. TODO(b/124218500): Remove them explicitly when the bug is resolved.
-PRODUCT_PACKAGES += \
-    libicui18n \
-    libicuuc \
-
 # Android Runtime APEX module.
 PRODUCT_PACKAGES += com.android.runtime
 PRODUCT_HOST_PACKAGES += com.android.runtime
@@ -88,6 +83,10 @@
 PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
     dalvik.vm.dex2oat-resolve-startup-strings=true
 
+# Specify default block size of 512K to enable parallel image decompression.
+PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
+    dalvik.vm.dex2oat-max-image-block-size=524288
+
 # Enable minidebuginfo generation unless overridden.
 PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
     dalvik.vm.minidebuginfo=true \
diff --git a/target/product/security/README b/target/product/security/README
index 6a6e62d..6e75e4d 100644
--- a/target/product/security/README
+++ b/target/product/security/README
@@ -31,7 +31,7 @@
 dumpkey.jar is a Java tool that takes an x.509 certificate in PEM format as
 input and prints a C structure to standard output:
 
-    $ java -jar out/host/linux-x86/framework/dumpkey.jar build/target/product/security/testkey.x509.pem
+    $ java -jar out/host/linux-x86/framework/dumpkey.jar build/make/target/product/security/testkey.x509.pem
     {64,0xc926ad21,{1795090719,2141396315,950055447,2581568430,4268923165,1920809988,546586521,3498997798,1776797858,3740060814,1805317999,1429410244,129622599,1422441418,1783893377,1222374759,2563319927,323993566,28517732,609753416,1826472888,215237850,4261642700,4049082591,3228462402,774857746,154822455,2497198897,2758199418,3019015328,2794777644,87251430,2534927978,120774784,571297800,3695899472,2479925187,3811625450,3401832990,2394869647,3267246207,950095497,555058928,414729973,1136544882,3044590084,465547824,4058146728,2731796054,1689838846,3890756939,1048029507,895090649,247140249,178744550,3547885223,3165179243,109881576,3944604415,1044303212,3772373029,2985150306,3737520932,3599964420},{3437017481,3784475129,2800224972,3086222688,251333580,2131931323,512774938,325948880,2657486437,2102694287,3820568226,792812816,1026422502,2053275343,2800889200,3113586810,165549746,4273519969,4065247892,1902789247,772932719,3941848426,3652744109,216871947,3164400649,1942378755,3996765851,1055777370,964047799,629391717,2232744317,3910558992,191868569,2758883837,3682816752,2997714732,2702529250,3570700455,3776873832,3924067546,3555689545,2758825434,1323144535,61311905,1997411085,376844204,213777604,4077323584,9135381,1625809335,2804742137,2952293945,1117190829,4237312782,1825108855,3013147971,1111251351,2568837572,1684324211,2520978805,367251975,810756730,2353784344,1175080310}}
 
 This is called by build/make/core/Makefile to incorporate the OTA signing keys
diff --git a/target/product/verity.mk b/target/product/verity.mk
index d954159..5f09283 100644
--- a/target/product/verity.mk
+++ b/target/product/verity.mk
@@ -23,7 +23,7 @@
 # The dev key is used to sign boot and recovery images, and the verity
 # metadata table. Actual product deliverables will be re-signed by hand.
 # We expect this file to exist with the suffixes ".x509.pem" and ".pk8".
-PRODUCT_VERITY_SIGNING_KEY := build/target/product/security/verity
+PRODUCT_VERITY_SIGNING_KEY := build/make/target/product/security/verity
 
 PRODUCT_PACKAGES += \
         verity_key
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index 8a4ab94..3856ab9 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -11,7 +11,7 @@
  && rm -rf jdk8.tgz
 
 RUN curl -o /usr/local/bin/repo https://storage.googleapis.com/git-repo-downloads/repo \
- && echo "e147f0392686c40cfd7d5e6f332c6ee74c4eab4d24e2694b3b0a0c037bf51dc5  /usr/local/bin/repo" | sha256sum --strict -c - \
+ && echo "d06f33115aea44e583c8669375b35aad397176a411de3461897444d247b6c220  /usr/local/bin/repo" | sha256sum --strict -c - \
  && chmod a+x /usr/local/bin/repo
 
 RUN groupadd -g $groupid $username \
diff --git a/tools/fs_config/Android.bp b/tools/fs_config/Android.bp
index 19a4624..d6fae2d 100644
--- a/tools/fs_config/Android.bp
+++ b/tools/fs_config/Android.bp
@@ -12,6 +12,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+bootstrap_go_package {
+    name: "soong-fs_config",
+    pkgPath: "android/soong/fs_config",
+    deps: [
+        "soong-android",
+        "soong-genrule",
+    ],
+    srcs: [
+        "fs_config.go"
+    ],
+    pluginFor: ["soong_build"],
+}
+
 cc_binary_host {
     name: "fs_config",
     srcs: ["fs_config.c"],
@@ -21,3 +34,64 @@
     ],
     cflags: ["-Werror"],
 }
+
+target_fs_config_gen_filegroup {
+    name: "target_fs_config_gen",
+}
+
+genrule {
+    name: "oemaids_header_gen",
+    tool_files: ["fs_config_generator.py"],
+    cmd: "$(location fs_config_generator.py) oemaid --aid-header=$(location :android_filesystem_config_header) $(location :target_fs_config_gen) >$(out)",
+    srcs: [
+        ":target_fs_config_gen",
+        ":android_filesystem_config_header",
+    ],
+    out: ["generated_oem_aid.h"],
+}
+
+cc_library_headers {
+    name: "oemaids_headers",
+    generated_headers: ["oemaids_header_gen"],
+    export_generated_headers: ["oemaids_header_gen"],
+}
+
+// Generate the vendor/etc/passwd text file for the target
+// This file may be empty if no AIDs are defined in
+// TARGET_FS_CONFIG_GEN files.
+genrule {
+    name: "passwd_gen",
+    tool_files: ["fs_config_generator.py"],
+    cmd: "$(location fs_config_generator.py) passwd --required-prefix=vendor_ --aid-header=$(location :android_filesystem_config_header) $(location :target_fs_config_gen) >$(out)",
+    srcs: [
+        ":target_fs_config_gen",
+        ":android_filesystem_config_header",
+    ],
+    out: ["passwd"],
+}
+
+prebuilt_etc {
+    name: "passwd",
+    vendor: true,
+    src: ":passwd_gen",
+}
+
+// Generate the vendor/etc/group text file for the target
+// This file may be empty if no AIDs are defined in
+// TARGET_FS_CONFIG_GEN files.
+genrule {
+    name: "group_gen",
+    tool_files: ["fs_config_generator.py"],
+    cmd: "$(location fs_config_generator.py) group --required-prefix=vendor_ --aid-header=$(location :android_filesystem_config_header) $(location :target_fs_config_gen) >$(out)",
+    srcs: [
+        ":target_fs_config_gen",
+        ":android_filesystem_config_header",
+    ],
+    out: ["group"],
+}
+
+prebuilt_etc {
+    name: "group",
+    vendor: true,
+    src: ":group_gen",
+}
diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk
index 0e0b1da..96db0f3 100644
--- a/tools/fs_config/Android.mk
+++ b/tools/fs_config/Android.mk
@@ -382,67 +382,6 @@
 	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
 endif
 
-##################################
-# Build the oemaid header library when fs config files are present.
-# Intentionally break build if you require generated AIDs
-# header file, but are not using any fs config files.
-ifneq ($(TARGET_FS_CONFIG_GEN),)
-include $(CLEAR_VARS)
-LOCAL_MODULE := oemaids_headers
-
-LOCAL_MODULE_CLASS := ETC
-
-# Generate the "generated_oem_aid.h" file
-oem := $(local-generated-sources-dir)/generated_oem_aid.h
-$(oem): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
-$(oem): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(oem): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(oem): PRIVATE_CUSTOM_TOOL = $(PRIVATE_LOCAL_PATH)/fs_config_generator.py oemaid --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(PRIVATE_TARGET_FS_CONFIG_GEN) > $@
-$(oem): $(TARGET_FS_CONFIG_GEN) $(LOCAL_PATH)/fs_config_generator.py
-	$(transform-generated-source)
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(dir $(oem))
-LOCAL_EXPORT_C_INCLUDE_DEPS := $(oem)
-
-include $(BUILD_HEADER_LIBRARY)
-endif
-
-##################################
-# Generate the vendor/etc/passwd text file for the target
-# This file may be empty if no AIDs are defined in
-# TARGET_FS_CONFIG_GEN files.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := passwd
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config)
-	@mkdir -p $(dir $@)
-	$(hide) $< passwd --required-prefix=vendor_ --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) > $@
-
-##################################
-# Generate the vendor/etc/group text file for the target
-# This file may be empty if no AIDs are defined in
-# TARGET_FS_CONFIG_GEN files.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := group
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config)
-	@mkdir -p $(dir $@)
-	$(hide) $< group --required-prefix=vendor_ --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) > $@
-
 system_android_filesystem_config :=
 system_capability_header :=
 fs_config_generate_extra_partition_list :=
diff --git a/tools/fs_config/fs_config.go b/tools/fs_config/fs_config.go
new file mode 100644
index 0000000..869cb3d
--- /dev/null
+++ b/tools/fs_config/fs_config.go
@@ -0,0 +1,60 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package fs_config
+
+import (
+	"android/soong/android"
+)
+
+var pctx = android.NewPackageContext("android/soong/fs_config")
+
+func init() {
+	android.RegisterModuleType("target_fs_config_gen_filegroup", targetFSConfigGenFactory)
+}
+
+// target_fs_config_gen_filegroup is used to expose the file pointed to by TARGET_FS_CONFIG_GEN to
+// genrules in Soong. If TARGET_FS_CONFIG_GEN is empty, it will export an empty file instead.
+func targetFSConfigGenFactory() android.Module {
+	module := &targetFSConfigGen{}
+	android.InitAndroidModule(module)
+	return module
+}
+
+var _ android.SourceFileProducer = (*targetFSConfigGen)(nil)
+
+type targetFSConfigGen struct {
+	android.ModuleBase
+	path android.Path
+}
+
+func (targetFSConfigGen) DepsMutator(ctx android.BottomUpMutatorContext) {}
+
+func (t *targetFSConfigGen) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	if ret := ctx.DeviceConfig().TargetFSConfigGen(); ret != nil && *ret != "" {
+		t.path = android.PathForSource(ctx, *ret)
+	} else {
+		path := android.PathForModuleGen(ctx, "empty")
+		t.path = path
+
+		rule := android.NewRuleBuilder()
+		rule.Command().Text("rm -rf").Output(path)
+		rule.Command().Text("touch").Output(path)
+		rule.Build(pctx, ctx, "fs_config_empty", "create empty file")
+	}
+}
+
+func (t *targetFSConfigGen) Srcs() android.Paths {
+	return android.Paths{t.path}
+}
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
new file mode 100644
index 0000000..b5ae009
--- /dev/null
+++ b/tools/releasetools/Android.bp
@@ -0,0 +1,72 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+python_defaults {
+    name: "releasetools_test_defaults",
+    version: {
+        py2: {
+            enabled: true,
+            embedded_launcher: false,
+        },
+        py3: {
+            enabled: false,
+        },
+    },
+}
+
+python_library_host {
+    name: "releasetools_lib",
+    defaults: ["releasetools_test_defaults"],
+    srcs: [
+        "add_img_to_target_files.py",
+        "apex_utils.py",
+        "blockimgdiff.py",
+        "build_image.py",
+        "build_super_image.py",
+        "check_ota_package_signature.py",
+        "check_target_files_signatures.py",
+        "common.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",
+        "rangelib.py",
+        "sign_target_files_apks.py",
+        "sparse_img.py",
+        "target_files_diff.py",
+        "validate_target_files.py",
+        "verity_utils.py",
+    ],
+}
+
+python_test_host {
+    name: "releasetools_test",
+    defaults: ["releasetools_test_defaults"],
+    main: "test_utils.py",
+    srcs: [
+        "test_*.py",
+    ],
+    libs: [
+        "releasetools_lib",
+    ],
+    data: [
+        "testdata/*",
+    ],
+    required: [
+        "otatools",
+    ],
+    test_suites: ["general-tests"],
+}
diff --git a/tools/releasetools/TEST_MAPPING b/tools/releasetools/TEST_MAPPING
new file mode 100644
index 0000000..77cef07
--- /dev/null
+++ b/tools/releasetools/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+  "presubmit": [
+    {
+      "name": "releasetools_test",
+      "host": true
+    }
+  ]
+}
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index e5a9050..b23eef1 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -174,7 +174,7 @@
     return h.hexdigest()
 
   def ReadRangeSet(self, ranges):
-    return [self._GetRangeData(ranges)]
+    return list(self._GetRangeData(ranges))
 
   def TotalSha1(self, include_clobbered_blocks=False):
     if not include_clobbered_blocks:
@@ -187,6 +187,83 @@
       fd.write(data)
 
 
+class FileImage(Image):
+  """An image wrapped around a raw image file."""
+
+  def __init__(self, path, hashtree_info_generator=None):
+    self.path = path
+    self.blocksize = 4096
+    self._file_size = os.path.getsize(self.path)
+    self._file = open(self.path, 'r')
+
+    if self._file_size % self.blocksize != 0:
+      raise ValueError("Size of file %s must be multiple of %d bytes, but is %d"
+                       % self.path, self.blocksize, self._file_size)
+
+    self.total_blocks = self._file_size / self.blocksize
+    self.care_map = RangeSet(data=(0, self.total_blocks))
+    self.clobbered_blocks = RangeSet()
+    self.extended = RangeSet()
+
+    self.generator_lock = threading.Lock()
+
+    self.hashtree_info = None
+    if hashtree_info_generator:
+      self.hashtree_info = hashtree_info_generator.Generate(self)
+
+    zero_blocks = []
+    nonzero_blocks = []
+    reference = '\0' * self.blocksize
+
+    for i in range(self.total_blocks):
+      d = self._file.read(self.blocksize)
+      if d == reference:
+        zero_blocks.append(i)
+        zero_blocks.append(i+1)
+      else:
+        nonzero_blocks.append(i)
+        nonzero_blocks.append(i+1)
+
+    assert zero_blocks or nonzero_blocks
+
+    self.file_map = {}
+    if zero_blocks:
+      self.file_map["__ZERO"] = RangeSet(data=zero_blocks)
+    if nonzero_blocks:
+      self.file_map["__NONZERO"] = RangeSet(data=nonzero_blocks)
+    if self.hashtree_info:
+      self.file_map["__HASHTREE"] = self.hashtree_info.hashtree_range
+
+  def __del__(self):
+    self._file.close()
+
+  def _GetRangeData(self, ranges):
+    # Use a lock to protect the generator so that we will not run two
+    # instances of this generator on the same object simultaneously.
+    with self.generator_lock:
+      for s, e in ranges:
+        self._file.seek(s * self.blocksize)
+        for _ in range(s, e):
+          yield self._file.read(self.blocksize)
+
+  def RangeSha1(self, ranges):
+    h = sha1()
+    for data in self._GetRangeData(ranges): # pylint: disable=not-an-iterable
+      h.update(data)
+    return h.hexdigest()
+
+  def ReadRangeSet(self, ranges):
+    return list(self._GetRangeData(ranges))
+
+  def TotalSha1(self, include_clobbered_blocks=False):
+    assert not self.clobbered_blocks
+    return self.RangeSha1(self.care_map)
+
+  def WriteRangeDataToFd(self, ranges, fd):
+    for data in self._GetRangeData(ranges): # pylint: disable=not-an-iterable
+      fd.write(data)
+
+
 class Transfer(object):
   def __init__(self, tgt_name, src_name, tgt_ranges, src_ranges, tgt_sha1,
                src_sha1, style, by_id):
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index d2f4e25..4136ed4 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -18,10 +18,8 @@
 Builds output_image from the given input_directory, properties_file,
 and writes the image to target_output_directory.
 
-If argument generated_prop_file exists, write additional properties to the file.
-
 Usage:  build_image.py input_directory properties_file output_image \\
-            target_output_directory [generated_prop_file]
+            target_output_directory
 """
 
 from __future__ import print_function
@@ -735,13 +733,8 @@
   return d
 
 
-def SaveGlobalDict(filename, glob_dict):
-  with open(filename, "w") as f:
-    f.writelines(["%s=%s" % (key, value) for (key, value) in glob_dict.items()])
-
-
 def main(argv):
-  if len(argv) < 4 or len(argv) > 5:
+  if len(argv) != 4:
     print(__doc__)
     sys.exit(1)
 
@@ -751,7 +744,6 @@
   glob_dict_file = argv[1]
   out_file = argv[2]
   target_out = argv[3]
-  prop_file_out = argv[4] if len(argv) >= 5 else None
 
   glob_dict = LoadGlobalDict(glob_dict_file)
   if "mount_point" in glob_dict:
@@ -791,10 +783,6 @@
     logger.error("Failed to build %s from %s", out_file, in_dir)
     raise
 
-  if prop_file_out:
-    glob_dict_out = GlobalDictFromImageProp(image_properties, mount_point)
-    SaveGlobalDict(prop_file_out, glob_dict_out)
-
 
 if __name__ == '__main__':
   try:
diff --git a/tools/releasetools/build_super_image.py b/tools/releasetools/build_super_image.py
index 38ea3d6..045ad55 100755
--- a/tools/releasetools/build_super_image.py
+++ b/tools/releasetools/build_super_image.py
@@ -58,16 +58,8 @@
 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 GetArgumentsForImage(partition, group, image=None):
-  image_size = GetPartitionSizeFromImage(image) if image else 0
+  image_size = sparse_img.GetImagePartitionSize(image) if image else 0
 
   cmd = ["--partition",
          "{}:readonly:{}:{}".format(partition, image_size, group)]
@@ -135,7 +127,7 @@
 
       cmd += GetArgumentsForImage(partition + "_b", group + "_b", other_image)
 
-  if has_image:
+  if info_dict.get("build_non_sparse_super_partition") != "true":
     cmd.append("--sparse")
 
   cmd += ["--output", output]
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 632c1e2..3e2a113 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -824,6 +824,77 @@
   return tmp
 
 
+def GetUserImage(which, tmpdir, input_zip,
+                 info_dict=None,
+                 allow_shared_blocks=None,
+                 hashtree_info_generator=None,
+                 reset_file_map=False):
+  """Returns an Image object suitable for passing to BlockImageDiff.
+
+  This function loads the specified image from the given path. If the specified
+  image is sparse, it also performs additional processing for OTA purpose. For
+  example, it always adds block 0 to clobbered blocks list. It also detects
+  files that cannot be reconstructed from the block list, for whom we should
+  avoid applying imgdiff.
+
+  Args:
+    which: The partition name.
+    tmpdir: The directory that contains the prebuilt image and block map file.
+    input_zip: The target-files ZIP archive.
+    info_dict: The dict to be looked up for relevant info.
+    allow_shared_blocks: If image is sparse, whether having shared blocks is
+        allowed. If none, it is looked up from info_dict.
+    hashtree_info_generator: If present and image is sparse, generates the
+        hashtree_info for this sparse image.
+    reset_file_map: If true and image is sparse, reset file map before returning
+        the image.
+  Returns:
+    A Image object. If it is a sparse image and reset_file_map is False, the
+    image will have file_map info loaded.
+  """
+  if info_dict == None:
+    info_dict = LoadInfoDict(input_zip)
+
+  is_sparse = info_dict.get("extfs_sparse_flag")
+
+  # When target uses 'BOARD_EXT4_SHARE_DUP_BLOCKS := true', images may contain
+  # shared blocks (i.e. some blocks will show up in multiple files' block
+  # list). We can only allocate such shared blocks to the first "owner", and
+  # disable imgdiff for all later occurrences.
+  if allow_shared_blocks is None:
+    allow_shared_blocks = info_dict.get("ext4_share_dup_blocks") == "true"
+
+  if is_sparse:
+    img = GetSparseImage(which, tmpdir, input_zip, allow_shared_blocks,
+                         hashtree_info_generator)
+    if reset_file_map:
+      img.ResetFileMap()
+    return img
+  else:
+    return GetNonSparseImage(which, tmpdir, hashtree_info_generator)
+
+
+def GetNonSparseImage(which, tmpdir, hashtree_info_generator=None):
+  """Returns a Image object suitable for passing to BlockImageDiff.
+
+  This function loads the specified non-sparse image from the given path.
+
+  Args:
+    which: The partition name.
+    tmpdir: The directory that contains the prebuilt image and block map file.
+  Returns:
+    A Image object.
+  """
+  path = os.path.join(tmpdir, "IMAGES", which + ".img")
+  mappath = os.path.join(tmpdir, "IMAGES", which + ".map")
+
+  # The image and map files must have been created prior to calling
+  # ota_from_target_files.py (since LMP).
+  assert os.path.exists(path) and os.path.exists(mappath)
+
+  return blockimgdiff.FileImage(path, hashtree_info_generator=
+                                hashtree_info_generator)
+
 def GetSparseImage(which, tmpdir, input_zip, allow_shared_blocks,
                    hashtree_info_generator=None):
   """Returns a SparseImage object suitable for passing to BlockImageDiff.
@@ -834,7 +905,7 @@
   reconstructed from the block list, for whom we should avoid applying imgdiff.
 
   Args:
-    which: The partition name, which must be "system" or "vendor".
+    which: The partition name, e.g. "system", "vendor".
     tmpdir: The directory that contains the prebuilt image and block map file.
     input_zip: The target-files ZIP archive.
     allow_shared_blocks: Whether having shared blocks is allowed.
@@ -843,8 +914,6 @@
   Returns:
     A SparseImage object, with file_map info loaded.
   """
-  assert which in ("system", "vendor")
-
   path = os.path.join(tmpdir, "IMAGES", which + ".img")
   mappath = os.path.join(tmpdir, "IMAGES", which + ".map")
 
@@ -2070,7 +2139,7 @@
 
 
 DataImage = blockimgdiff.DataImage
-
+EmptyImage = blockimgdiff.EmptyImage
 
 # map recovery.fstab's fs_types to mount/format "partition types"
 PARTITION_TYPES = {
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 37f4e38..dd3e190 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -38,7 +38,7 @@
   -k  (--package_key) <key>
       Key to use to sign the package (default is the value of
       default_system_dev_certificate from the input target-files's
-      META/misc_info.txt, or "build/target/product/security/testkey" if that
+      META/misc_info.txt, or "build/make/target/product/security/testkey" if that
       value is not specified).
 
       For incremental OTAs, the default value is based on the source
@@ -168,6 +168,9 @@
   --payload_signer_args <args>
       Specify the arguments needed for payload signer.
 
+  --payload_signer_key_size <key_size>
+      Specify the key size in bytes of the payload signer.
+
   --skip_postinstall
       Skip the postinstall hooks when generating an A/B OTA package (default:
       False). Note that this discards ALL the hooks, including non-optional
@@ -224,6 +227,7 @@
 OPTIONS.log_diff = None
 OPTIONS.payload_signer = None
 OPTIONS.payload_signer_args = []
+OPTIONS.payload_signer_key_size = None
 OPTIONS.extracted_input = None
 OPTIONS.key_passwords = []
 OPTIONS.skip_postinstall = False
@@ -468,9 +472,35 @@
       self.signer = "openssl"
       self.signer_args = ["pkeyutl", "-sign", "-inkey", signing_key,
                           "-pkeyopt", "digest:sha256"]
+      self.key_size = self._GetKeySizeInBytes(signing_key)
     else:
       self.signer = OPTIONS.payload_signer
       self.signer_args = OPTIONS.payload_signer_args
+      if OPTIONS.payload_signer_key_size:
+        self.key_size = int(OPTIONS.payload_signer_key_size)
+        assert self.key_size == 256 or self.key_size == 512, \
+            "Unsupported key size {}".format(OPTIONS.payload_signer_key_size)
+      else:
+        self.key_size = 256
+
+  @staticmethod
+  def _GetKeySizeInBytes(signing_key):
+    modulus_file = common.MakeTempFile(prefix="modulus-")
+    cmd = ["openssl", "rsa", "-inform", "PEM", "-in", signing_key, "-modulus",
+           "-noout", "-out", modulus_file]
+    common.RunAndCheckOutput(cmd, verbose=False)
+
+    with open(modulus_file) as f:
+      modulus_string = f.read()
+    # The modulus string has the format "Modulus=$data", where $data is the
+    # concatenation of hex dump of the modulus.
+    MODULUS_PREFIX = "Modulus="
+    assert modulus_string.startswith(MODULUS_PREFIX)
+    modulus_string = modulus_string[len(MODULUS_PREFIX):]
+    key_size = len(modulus_string) / 2
+    assert key_size == 256 or key_size == 512, \
+        "Unsupported key size {}".format(key_size)
+    return key_size
 
   def Sign(self, in_file):
     """Signs the given input file. Returns the output filename."""
@@ -539,7 +569,7 @@
     metadata_sig_file = common.MakeTempFile(prefix="sig-", suffix=".bin")
     cmd = ["brillo_update_payload", "hash",
            "--unsigned_payload", self.payload_file,
-           "--signature_size", "256",
+           "--signature_size", str(payload_signer.key_size),
            "--metadata_hash_file", metadata_sig_file,
            "--payload_hash_file", payload_sig_file]
     common.RunAndCheckOutput(cmd)
@@ -554,7 +584,7 @@
     cmd = ["brillo_update_payload", "sign",
            "--unsigned_payload", self.payload_file,
            "--payload", signed_payload_file,
-           "--signature_size", "256",
+           "--signature_size", str(payload_signer.key_size),
            "--metadata_signature_file", signed_metadata_sig_file,
            "--payload_signature_file", signed_payload_sig_file]
     common.RunAndCheckOutput(cmd)
@@ -887,17 +917,14 @@
 
   script.ShowProgress(system_progress, 0)
 
-  # See the notes in WriteBlockIncrementalOTAPackage().
-  allow_shared_blocks = target_info.get('ext4_share_dup_blocks') == "true"
-
   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.GetSparseImage(partition, OPTIONS.input_tmp, input_zip,
-                                allow_shared_blocks)
-    tgt.ResetFileMap()
+    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
 
@@ -1482,8 +1509,10 @@
   device_specific = common.DeviceSpecificParams(
       source_zip=source_zip,
       source_version=source_api_version,
+      source_tmp=OPTIONS.source_tmp,
       target_zip=target_zip,
       target_version=target_api_version,
+      target_tmp=OPTIONS.target_tmp,
       output_zip=output_zip,
       script=script,
       metadata=metadata,
@@ -1499,20 +1528,20 @@
   target_recovery = common.GetBootableImage(
       "/tmp/recovery.img", "recovery.img", OPTIONS.target_tmp, "RECOVERY")
 
-  # When target uses 'BOARD_EXT4_SHARE_DUP_BLOCKS := true', images may contain
-  # shared blocks (i.e. some blocks will show up in multiple files' block
-  # list). We can only allocate such shared blocks to the first "owner", and
-  # disable imgdiff for all later occurrences.
+  # 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.GetSparseImage("system", OPTIONS.source_tmp, source_zip,
-                                     allow_shared_blocks)
+  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.GetSparseImage("system", OPTIONS.target_tmp, target_zip,
-                                     allow_shared_blocks,
-                                     hashtree_info_generator)
+  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(","))
@@ -1537,13 +1566,16 @@
   if HasVendorPartition(target_zip):
     if not HasVendorPartition(source_zip):
       raise RuntimeError("can't generate incremental that adds /vendor")
-    vendor_src = common.GetSparseImage("vendor", OPTIONS.source_tmp, source_zip,
-                                       allow_shared_blocks)
+    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.GetSparseImage(
-        "vendor", OPTIONS.target_tmp, target_zip, allow_shared_blocks,
-        hashtree_info_generator)
+    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
@@ -2087,6 +2119,8 @@
       OPTIONS.payload_signer = a
     elif o == "--payload_signer_args":
       OPTIONS.payload_signer_args = shlex.split(a)
+    elif o == "--payload_signer_key_size":
+      OPTIONS.payload_signer_key_size = a
     elif o == "--extracted_input_target_files":
       OPTIONS.extracted_input = a
     elif o == "--skip_postinstall":
@@ -2125,6 +2159,7 @@
                                  "log_diff=",
                                  "payload_signer=",
                                  "payload_signer_args=",
+                                 "payload_signer_key_size=",
                                  "extracted_input_target_files=",
                                  "skip_postinstall",
                                  "retrofit_dynamic_partitions",
@@ -2199,7 +2234,7 @@
     if OPTIONS.package_key is None:
       OPTIONS.package_key = OPTIONS.info_dict.get(
           "default_system_dev_certificate",
-          "build/target/product/security/testkey")
+          "build/make/target/product/security/testkey")
     # Get signing keys
     OPTIONS.key_passwords = common.GetKeyPasswords([OPTIONS.package_key])
 
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index c482a49..64e7ca8 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -56,7 +56,7 @@
 
       where $devkey is the directory part of the value of
       default_system_dev_certificate from the input target-files's
-      META/misc_info.txt.  (Defaulting to "build/target/product/security"
+      META/misc_info.txt.  (Defaulting to "build/make/target/product/security"
       if the value is not present in misc_info.
 
       -d and -k options are added to the set of mappings in the order
@@ -802,7 +802,7 @@
     print("for OTA package verification")
   else:
     devkey = misc_info.get("default_system_dev_certificate",
-                           "build/target/product/security/testkey")
+                           "build/make/target/product/security/testkey")
     mapped_devkey = OPTIONS.key_map.get(devkey, devkey)
     if mapped_devkey != devkey:
       misc_info["default_system_dev_certificate"] = mapped_devkey
@@ -959,7 +959,7 @@
   for s, d in key_mapping_options:
     if s is None:   # -d option
       devkey = misc_info.get("default_system_dev_certificate",
-                             "build/target/product/security/testkey")
+                             "build/make/target/product/security/testkey")
       devkeydir = os.path.dirname(devkey)
 
       OPTIONS.key_map.update({
diff --git a/tools/releasetools/sparse_img.py b/tools/releasetools/sparse_img.py
old mode 100644
new mode 100755
index 7919ba4..3367896
--- a/tools/releasetools/sparse_img.py
+++ b/tools/releasetools/sparse_img.py
@@ -1,3 +1,5 @@
+#!/usr/bin/env python
+#
 # Copyright (C) 2014 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,6 +14,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from __future__ import print_function
+
+import argparse
 import bisect
 import logging
 import os
@@ -344,3 +349,21 @@
     """Throw away the file map and treat the entire image as
     undifferentiated data."""
     self.file_map = {"__DATA": self.care_map}
+
+
+def GetImagePartitionSize(img):
+  try:
+    simg = SparseImage(img, build_map=False)
+    return simg.blocksize * simg.total_blocks
+  except ValueError:
+    return os.path.getsize(img)
+
+
+if __name__ == '__main__':
+  parser = argparse.ArgumentParser()
+  parser.add_argument('image')
+  parser.add_argument('--get_partition_size', action='store_true',
+                      help='Return partition size of the image')
+  args = parser.parse_args()
+  if args.get_partition_size:
+    print(GetImagePartitionSize(args.image))
diff --git a/tools/releasetools/test_add_img_to_target_files.py b/tools/releasetools/test_add_img_to_target_files.py
index 482f86c..013ade6 100644
--- a/tools/releasetools/test_add_img_to_target_files.py
+++ b/tools/releasetools/test_add_img_to_target_files.py
@@ -34,18 +34,6 @@
   def setUp(self):
     OPTIONS.input_tmp = common.MakeTempDir()
 
-  def _verifyCareMap(self, expected, file_name):
-    """Parses the care_map.pb; and checks the content in plain text."""
-    text_file = common.MakeTempFile(prefix="caremap-", suffix=".txt")
-
-    # Calls an external binary to convert the proto message.
-    cmd = ["care_map_generator", "--parse_proto", file_name, text_file]
-    common.RunAndCheckOutput(cmd)
-
-    with open(text_file, 'r') as verify_fp:
-      plain_text = verify_fp.read()
-    self.assertEqual('\n'.join(expected), plain_text)
-
   @staticmethod
   def _create_images(images, prefix):
     """Creates images under OPTIONS.input_tmp/prefix."""
@@ -164,6 +152,19 @@
     }
     return image_paths
 
+  def _verifyCareMap(self, expected, file_name):
+    """Parses the care_map.pb; and checks the content in plain text."""
+    text_file = common.MakeTempFile(prefix="caremap-", suffix=".txt")
+
+    # Calls an external binary to convert the proto message.
+    cmd = ["care_map_generator", "--parse_proto", file_name, text_file]
+    common.RunAndCheckOutput(cmd)
+
+    with open(text_file) as verify_fp:
+      plain_text = verify_fp.read()
+    self.assertEqual('\n'.join(expected), plain_text)
+
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_AddCareMapForAbOta(self):
     image_paths = self._test_AddCareMapForAbOta()
 
@@ -179,6 +180,7 @@
 
     self._verifyCareMap(expected, care_map_file)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_AddCareMapForAbOta_withNonCareMapPartitions(self):
     """Partitions without care_map should be ignored."""
     image_paths = self._test_AddCareMapForAbOta()
@@ -196,6 +198,7 @@
 
     self._verifyCareMap(expected, care_map_file)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_AddCareMapForAbOta_withAvb(self):
     """Tests the case for device using AVB."""
     image_paths = self._test_AddCareMapForAbOta()
@@ -223,6 +226,7 @@
 
     self._verifyCareMap(expected, care_map_file)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_AddCareMapForAbOta_noFingerprint(self):
     """Tests the case for partitions without fingerprint."""
     image_paths = self._test_AddCareMapForAbOta()
@@ -240,6 +244,7 @@
 
     self._verifyCareMap(expected, care_map_file)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_AddCareMapForAbOta_withThumbprint(self):
     """Tests the case for partitions with thumbprint."""
     image_paths = self._test_AddCareMapForAbOta()
@@ -282,6 +287,7 @@
     self.assertRaises(AssertionError, AddCareMapForAbOta, None,
                       ['system', 'vendor'], image_paths)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_AddCareMapForAbOta_zipOutput(self):
     """Tests the case with ZIP output."""
     image_paths = self._test_AddCareMapForAbOta()
@@ -304,6 +310,7 @@
                 "google/sailfish/678:user/dev-keys"]
     self._verifyCareMap(expected, os.path.join(temp_dir, care_map_name))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_AddCareMapForAbOta_zipOutput_careMapEntryExists(self):
     """Tests the case with ZIP output which already has care_map entry."""
     image_paths = self._test_AddCareMapForAbOta()
@@ -338,6 +345,7 @@
     self.assertEqual(
         ['--include_descriptors_from_image', '/path/to/system.img'], cmd)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_AppendVBMetaArgsForPartition_vendorAsChainedPartition(self):
     testdata_dir = test_utils.get_testdata_dir()
     pubkey = os.path.join(testdata_dir, 'testkey.pubkey.pem')
diff --git a/tools/releasetools/test_apex_utils.py b/tools/releasetools/test_apex_utils.py
index 2f8ee49..c7d5807 100644
--- a/tools/releasetools/test_apex_utils.py
+++ b/tools/releasetools/test_apex_utils.py
@@ -39,6 +39,7 @@
       payload_fp.write(os.urandom(8192))
     return payload_file
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_ParseApexPayloadInfo(self):
     payload_file = self._GetTestPayload()
     apex_utils.SignApexPayload(
@@ -48,16 +49,20 @@
     self.assertEqual(self.SALT, payload_info['Salt'])
     self.assertEqual('testkey', payload_info['apex.key'])
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_SignApexPayload(self):
     payload_file = self._GetTestPayload()
     apex_utils.SignApexPayload(
         payload_file, self.payload_key, 'testkey', 'SHA256_RSA2048', self.SALT)
     apex_utils.VerifyApexPayload(payload_file, self.payload_key)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_SignApexPayload_withSignerHelper(self):
     payload_file = self._GetTestPayload()
+    signing_helper = os.path.join(self.testdata_dir, 'signing_helper.sh')
+    os.chmod(signing_helper, 0o700)
     payload_signer_args = '--signing_helper_with_files {}'.format(
-        os.path.join(self.testdata_dir, 'signing_helper.sh'))
+        signing_helper)
     apex_utils.SignApexPayload(
         payload_file,
         self.payload_key,
@@ -65,6 +70,7 @@
         payload_signer_args)
     apex_utils.VerifyApexPayload(payload_file, self.payload_key)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_SignApexPayload_invalidKey(self):
     self.assertRaises(
         apex_utils.ApexSigningError,
@@ -75,6 +81,7 @@
         'SHA256_RSA2048',
         self.SALT)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_VerifyApexPayload_wrongKey(self):
     payload_file = self._GetTestPayload()
     apex_utils.SignApexPayload(
diff --git a/tools/releasetools/test_blockimgdiff.py b/tools/releasetools/test_blockimgdiff.py
index 806ff4b..b6d47d4 100644
--- a/tools/releasetools/test_blockimgdiff.py
+++ b/tools/releasetools/test_blockimgdiff.py
@@ -14,9 +14,13 @@
 # limitations under the License.
 #
 
+import os
+from hashlib import sha1
+
 import common
 from blockimgdiff import (
-    BlockImageDiff, EmptyImage, HeapItem, ImgdiffStats, Transfer)
+    BlockImageDiff, DataImage, EmptyImage, FileImage, HeapItem, ImgdiffStats,
+    Transfer)
 from rangelib import RangeSet
 from test_utils import ReleaseToolsTestCase
 
@@ -261,3 +265,45 @@
 
     self.assertRaises(AssertionError, imgdiff_stats.Log, "/system/app/app1.apk",
                       "invalid reason")
+
+
+class DataImageTest(ReleaseToolsTestCase):
+  def test_read_range_set(self):
+    data = "file" + ('\0' * 4092)
+    image = DataImage(data)
+    self.assertEqual(data, "".join(image.ReadRangeSet(image.care_map)))
+
+
+class FileImageTest(ReleaseToolsTestCase):
+  def setUp(self):
+    self.file_path = common.MakeTempFile()
+    self.data = os.urandom(4096 * 4)
+    with open(self.file_path, 'w') as f:
+      f.write(self.data)
+    self.file = FileImage(self.file_path)
+
+  def test_totalsha1(self):
+    self.assertEqual(sha1(self.data).hexdigest(), self.file.TotalSha1())
+
+  def test_ranges(self):
+    blocksize = self.file.blocksize
+    for s in range(4):
+      for e in range(s, 4):
+        expected_data = self.data[s * blocksize : e * blocksize]
+
+        rs = RangeSet([s, e])
+        data = "".join(self.file.ReadRangeSet(rs))
+        self.assertEqual(expected_data, data)
+
+        sha1sum = self.file.RangeSha1(rs)
+        self.assertEqual(sha1(expected_data).hexdigest(), sha1sum)
+
+        tmpfile = common.MakeTempFile()
+        with open(tmpfile, 'w') as f:
+          self.file.WriteRangeDataToFd(rs, f)
+        with open(tmpfile, 'r') as f:
+          self.assertEqual(expected_data, f.read())
+
+  def test_read_all(self):
+    data = "".join(self.file.ReadRangeSet(self.file.care_map))
+    self.assertEqual(self.data, data)
diff --git a/tools/releasetools/test_build_image.py b/tools/releasetools/test_build_image.py
index 1cebd0c..b24805f 100644
--- a/tools/releasetools/test_build_image.py
+++ b/tools/releasetools/test_build_image.py
@@ -18,12 +18,13 @@
 import os.path
 
 import common
+import test_utils
 from build_image import (
-    BuildImageError, CheckHeadroom, GetFilesystemCharacteristics, SetUpInDirAndFsConfig)
-from test_utils import ReleaseToolsTestCase
+    BuildImageError, CheckHeadroom, GetFilesystemCharacteristics,
+    SetUpInDirAndFsConfig)
 
 
-class BuildImageTest(ReleaseToolsTestCase):
+class BuildImageTest(test_utils.ReleaseToolsTestCase):
 
   # Available: 1000 blocks.
   EXT4FS_OUTPUT = (
@@ -48,6 +49,7 @@
     self.assertRaises(
         BuildImageError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_CheckHeadroom_WrongFsType(self):
     prop_dict = {
         'fs_type' : 'f2fs',
@@ -72,6 +74,7 @@
     self.assertRaises(
         AssertionError, CheckHeadroom, self.EXT4FS_OUTPUT, prop_dict)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_CheckHeadroom_WithMke2fsOutput(self):
     """Tests the result parsing from actual call to mke2fs."""
     input_dir = common.MakeTempDir()
@@ -177,13 +180,14 @@
     self.assertIn('fs-config-root\n', fs_config_data)
     self.assertEqual('/', prop_dict['mount_point'])
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetFilesystemCharacteristics(self):
     input_dir = common.MakeTempDir()
     output_image = common.MakeTempFile(suffix='.img')
     command = ['mkuserimg_mke2fs', input_dir, output_image, 'ext4',
                '/system', '409600', '-j', '0']
     proc = common.Run(command)
-    ext4fs_output, _ = proc.communicate()
+    proc.communicate()
     self.assertEqual(0, proc.returncode)
 
     output_file = common.MakeTempFile(suffix='.img')
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index d4fa5f3..9b76734 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -315,6 +315,7 @@
     finally:
       os.remove(zip_file_name)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_ZipDelete(self):
     zip_file = tempfile.NamedTemporaryFile(delete=False, suffix='.zip')
     output_zip = zipfile.ZipFile(zip_file.name, 'w',
@@ -376,6 +377,7 @@
     common.ZipClose(output_zip)
     return zip_file
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_UnzipTemp(self):
     zip_file = self._test_UnzipTemp_createZipFile()
     unzipped_dir = common.UnzipTemp(zip_file)
@@ -385,6 +387,7 @@
     self.assertTrue(os.path.exists(os.path.join(unzipped_dir, 'Bar4')))
     self.assertTrue(os.path.exists(os.path.join(unzipped_dir, 'Dir5/Baz5')))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_UnzipTemp_withPatterns(self):
     zip_file = self._test_UnzipTemp_createZipFile()
 
@@ -425,6 +428,7 @@
     self.assertFalse(os.path.exists(os.path.join(unzipped_dir, 'Bar4')))
     self.assertFalse(os.path.exists(os.path.join(unzipped_dir, 'Dir5/Baz5')))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_UnzipTemp_withPartiallyMatchingPatterns(self):
     zip_file = self._test_UnzipTemp_createZipFile()
     unzipped_dir = common.UnzipTemp(zip_file, ['Test*', 'Nonexistent*'])
@@ -451,14 +455,14 @@
       'name="RecoveryLocalizer.apk" certificate="certs/devkey.x509.pem"'
       ' private_key="certs/devkey.pk8"\n'
       'name="Settings.apk"'
-      ' certificate="build/target/product/security/platform.x509.pem"'
-      ' private_key="build/target/product/security/platform.pk8"\n'
+      ' certificate="build/make/target/product/security/platform.x509.pem"'
+      ' private_key="build/make/target/product/security/platform.pk8"\n'
       'name="TV.apk" certificate="PRESIGNED" private_key=""\n'
   )
 
   APKCERTS_CERTMAP1 = {
       'RecoveryLocalizer.apk' : 'certs/devkey',
-      'Settings.apk' : 'build/target/product/security/platform',
+      'Settings.apk' : 'build/make/target/product/security/platform',
       'TV.apk' : 'PRESIGNED',
   }
 
@@ -575,6 +579,7 @@
     wrong_input = os.path.join(self.testdata_dir, 'testkey.pk8')
     self.assertRaises(AssertionError, common.ExtractPublicKey, wrong_input)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_ExtractAvbPublicKey(self):
     privkey = os.path.join(self.testdata_dir, 'testkey.key')
     pubkey = os.path.join(self.testdata_dir, 'testkey.pubkey.pem')
@@ -594,18 +599,22 @@
       actual = common.ParseCertificate(cert_fp.read())
     self.assertEqual(expected, actual)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetMinSdkVersion(self):
     test_app = os.path.join(self.testdata_dir, 'TestApp.apk')
     self.assertEqual('24', common.GetMinSdkVersion(test_app))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetMinSdkVersion_invalidInput(self):
     self.assertRaises(
         common.ExternalError, common.GetMinSdkVersion, 'does-not-exist.apk')
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetMinSdkVersionInt(self):
     test_app = os.path.join(self.testdata_dir, 'TestApp.apk')
     self.assertEqual(24, common.GetMinSdkVersionInt(test_app, {}))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetMinSdkVersionInt_invalidInput(self):
     self.assertRaises(
         common.ExternalError, common.GetMinSdkVersionInt, 'does-not-exist.apk',
@@ -617,6 +626,7 @@
   def setUp(self):
     self.testdata_dir = test_utils.get_testdata_dir()
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetSparseImage_emptyBlockMapFile(self):
     target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
     with zipfile.ZipFile(target_files, 'w') as target_files_zip:
@@ -641,12 +651,15 @@
         },
         sparse_image.file_map)
 
-  def test_GetSparseImage_invalidImageName(self):
+  def test_GetSparseImage_missingImageFile(self):
     self.assertRaises(
-        AssertionError, common.GetSparseImage, 'system2', None, None, False)
+        AssertionError, common.GetSparseImage, 'system2', self.testdata_dir,
+        None, False)
     self.assertRaises(
-        AssertionError, common.GetSparseImage, 'unknown', None, None, False)
+        AssertionError, common.GetSparseImage, 'unknown', self.testdata_dir,
+        None, False)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetSparseImage_missingBlockMapFile(self):
     target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
     with zipfile.ZipFile(target_files, 'w') as target_files_zip:
@@ -665,6 +678,7 @@
           AssertionError, common.GetSparseImage, 'system', tempdir, input_zip,
           False)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetSparseImage_sharedBlocks_notAllowed(self):
     """Tests the case of having overlapping blocks but disallowed."""
     target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
@@ -687,6 +701,7 @@
           AssertionError, common.GetSparseImage, 'system', tempdir, input_zip,
           False)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetSparseImage_sharedBlocks_allowed(self):
     """Tests the case for target using BOARD_EXT4_SHARE_DUP_BLOCKS := true."""
     target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
@@ -729,6 +744,7 @@
     self.assertFalse(sparse_image.file_map['__NONZERO-0'].extra)
     self.assertFalse(sparse_image.file_map['/system/file1'].extra)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetSparseImage_incompleteRanges(self):
     """Tests the case of ext4 images with holes."""
     target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
@@ -752,6 +768,7 @@
     self.assertFalse(sparse_image.file_map['/system/file1'].extra)
     self.assertTrue(sparse_image.file_map['/system/file2'].extra['incomplete'])
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetSparseImage_systemRootImage_filenameWithExtraLeadingSlash(self):
     target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
     with zipfile.ZipFile(target_files, 'w') as target_files_zip:
@@ -779,6 +796,7 @@
     self.assertTrue(
         sparse_image.file_map['/system/app/file3'].extra['incomplete'])
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetSparseImage_systemRootImage_nonSystemFiles(self):
     target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
     with zipfile.ZipFile(target_files, 'w') as target_files_zip:
@@ -801,6 +819,7 @@
     self.assertFalse(sparse_image.file_map['//system/file1'].extra)
     self.assertTrue(sparse_image.file_map['//init.rc'].extra['incomplete'])
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetSparseImage_fileNotFound(self):
     target_files = common.MakeTempFile(prefix='target_files-', suffix='.zip')
     with zipfile.ZipFile(target_files, 'w') as target_files_zip:
@@ -820,6 +839,7 @@
           AssertionError, common.GetSparseImage, 'system', tempdir, input_zip,
           False)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetAvbChainedPartitionArg(self):
     pubkey = os.path.join(self.testdata_dir, 'testkey.pubkey.pem')
     info_dict = {
@@ -833,6 +853,7 @@
     self.assertEqual('2', args[1])
     self.assertTrue(os.path.exists(args[2]))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetAvbChainedPartitionArg_withPrivateKey(self):
     key = os.path.join(self.testdata_dir, 'testkey.key')
     info_dict = {
@@ -846,6 +867,7 @@
     self.assertEqual('2', args[1])
     self.assertTrue(os.path.exists(args[2]))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetAvbChainedPartitionArg_withSpecifiedKey(self):
     info_dict = {
         'avb_avbtool': 'avbtool',
@@ -860,6 +882,7 @@
     self.assertEqual('2', args[1])
     self.assertTrue(os.path.exists(args[2]))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetAvbChainedPartitionArg_invalidKey(self):
     pubkey = os.path.join(self.testdata_dir, 'testkey_with_passwd.x509.pem')
     info_dict = {
@@ -920,6 +943,7 @@
       self.assertIn('/', loaded_dict['fstab'])
       self.assertIn('/system', loaded_dict['fstab'])
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_LoadInfoDict_dirInput(self):
     target_files = self._test_LoadInfoDict_createTargetFiles(
         self.INFO_DICT_DEFAULT,
@@ -931,6 +955,7 @@
     self.assertIn('/', loaded_dict['fstab'])
     self.assertIn('/system', loaded_dict['fstab'])
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_LoadInfoDict_dirInput_legacyRecoveryFstabPath(self):
     target_files = self._test_LoadInfoDict_createTargetFiles(
         self.INFO_DICT_DEFAULT,
@@ -988,6 +1013,7 @@
       self.assertEqual(2, loaded_dict['fstab_version'])
       self.assertIsNone(loaded_dict['fstab'])
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_LoadInfoDict_missingMetaMiscInfoTxt(self):
     target_files = self._test_LoadInfoDict_createTargetFiles(
         self.INFO_DICT_DEFAULT,
@@ -996,6 +1022,7 @@
     with zipfile.ZipFile(target_files, 'r') as target_files_zip:
       self.assertRaises(ValueError, common.LoadInfoDict, target_files_zip)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_LoadInfoDict_repacking(self):
     target_files = self._test_LoadInfoDict_createTargetFiles(
         self.INFO_DICT_DEFAULT,
@@ -1064,6 +1091,7 @@
     validate_target_files.ValidateInstallRecoveryScript(self._tempdir,
                                                         self._info)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_recovery_from_boot(self):
     recovery_image = common.File("recovery.img", self.recovery_data)
     self._out_tmp_sink("recovery.img", recovery_image.data, "IMAGES")
diff --git a/tools/releasetools/test_merge_target_files.py b/tools/releasetools/test_merge_target_files.py
index bb9ce8e..ec452a8 100644
--- a/tools/releasetools/test_merge_target_files.py
+++ b/tools/releasetools/test_merge_target_files.py
@@ -16,7 +16,6 @@
 
 import os.path
 
-import common
 import test_utils
 from merge_target_files import (
     read_config_list, validate_config_lists, default_system_item_list,
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index c2da907..bf94cc2 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -427,6 +427,7 @@
     common.OPTIONS.search_path = test_utils.get_search_path()
     self.assertIsNotNone(common.OPTIONS.search_path)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetPackageMetadata_abOta_full(self):
     target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
     target_info_dict['ab_update'] = 'true'
@@ -445,6 +446,7 @@
         },
         metadata)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetPackageMetadata_abOta_incremental(self):
     target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
     target_info_dict['ab_update'] = 'true'
@@ -467,6 +469,7 @@
         },
         metadata)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetPackageMetadata_nonAbOta_full(self):
     target_info = BuildInfo(self.TEST_TARGET_INFO_DICT, None)
     metadata = GetPackageMetadata(target_info)
@@ -482,6 +485,7 @@
         },
         metadata)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetPackageMetadata_nonAbOta_incremental(self):
     target_info = BuildInfo(self.TEST_TARGET_INFO_DICT, None)
     source_info = BuildInfo(self.TEST_SOURCE_INFO_DICT, None)
@@ -501,6 +505,7 @@
         },
         metadata)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetPackageMetadata_wipe(self):
     target_info = BuildInfo(self.TEST_TARGET_INFO_DICT, None)
     common.OPTIONS.wipe_user_data = True
@@ -518,6 +523,7 @@
         },
         metadata)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetPackageMetadata_retrofitDynamicPartitions(self):
     target_info = BuildInfo(self.TEST_TARGET_INFO_DICT, None)
     common.OPTIONS.retrofit_dynamic_partitions = True
@@ -542,6 +548,7 @@
          source_info['build.prop']['ro.build.date.utc'],
          target_info['build.prop']['ro.build.date.utc'])
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetPackageMetadata_unintentionalDowngradeDetected(self):
     target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
     source_info_dict = copy.deepcopy(self.TEST_SOURCE_INFO_DICT)
@@ -554,6 +561,7 @@
     self.assertRaises(RuntimeError, GetPackageMetadata, target_info,
                       source_info)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetPackageMetadata_downgrade(self):
     target_info_dict = copy.deepcopy(self.TEST_TARGET_INFO_DICT)
     source_info_dict = copy.deepcopy(self.TEST_SOURCE_INFO_DICT)
@@ -582,6 +590,7 @@
         },
         metadata)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetTargetFilesZipForSecondaryImages(self):
     input_file = construct_target_files(secondary=True)
     target_file = GetTargetFilesZipForSecondaryImages(input_file)
@@ -600,6 +609,7 @@
     self.assertNotIn('IMAGES/system_other.img', namelist)
     self.assertNotIn('IMAGES/system.map', namelist)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetTargetFilesZipForSecondaryImages_skipPostinstall(self):
     input_file = construct_target_files(secondary=True)
     target_file = GetTargetFilesZipForSecondaryImages(
@@ -619,6 +629,7 @@
     self.assertNotIn('IMAGES/system.map', namelist)
     self.assertNotIn(POSTINSTALL_CONFIG, namelist)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetTargetFilesZipForSecondaryImages_withoutRadioImages(self):
     input_file = construct_target_files(secondary=True)
     common.ZipDelete(input_file, 'RADIO/bootloader.img')
@@ -639,12 +650,14 @@
     self.assertNotIn('RADIO/bootloader.img', namelist)
     self.assertNotIn('RADIO/modem.img', namelist)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetTargetFilesZipWithoutPostinstallConfig(self):
     input_file = construct_target_files()
     target_file = GetTargetFilesZipWithoutPostinstallConfig(input_file)
     with zipfile.ZipFile(target_file) as verify_zip:
       self.assertNotIn(POSTINSTALL_CONFIG, verify_zip.namelist())
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetTargetFilesZipWithoutPostinstallConfig_missingEntry(self):
     input_file = construct_target_files()
     common.ZipDelete(input_file, POSTINSTALL_CONFIG)
@@ -675,20 +688,25 @@
     FinalizeMetadata(metadata, zip_file, output_file, needed_property_files)
     self.assertIn('ota-test-property-files', metadata)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_FinalizeMetadata(self):
     self._test_FinalizeMetadata()
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_FinalizeMetadata_withNoSigning(self):
     common.OPTIONS.no_signing = True
     self._test_FinalizeMetadata()
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_FinalizeMetadata_largeEntry(self):
     self._test_FinalizeMetadata(large_entry=True)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_FinalizeMetadata_largeEntry_withNoSigning(self):
     common.OPTIONS.no_signing = True
     self._test_FinalizeMetadata(large_entry=True)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_FinalizeMetadata_insufficientSpace(self):
     entries = [
         'required-entry1',
@@ -766,6 +784,7 @@
           expected = entry.replace('.', '-').upper().encode()
         self.assertEqual(expected, input_fp.read(size))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Compute(self):
     entries = (
         'required-entry1',
@@ -805,6 +824,7 @@
     with zipfile.ZipFile(zip_file, 'r') as zip_fp:
       self.assertRaises(KeyError, property_files.Compute, zip_fp)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Finalize(self):
     entries = [
         'required-entry1',
@@ -825,6 +845,7 @@
     entries[2] = 'metadata'
     self._verify_entries(zip_file, tokens, entries)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Finalize_assertReservedLength(self):
     entries = (
         'required-entry1',
@@ -998,6 +1019,7 @@
         ),
         property_files.optional)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_GetPayloadMetadataOffsetAndSize(self):
     target_file = construct_target_files()
     payload = Payload()
@@ -1071,6 +1093,7 @@
 
     return zip_file
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Compute(self):
     zip_file = self.construct_zip_package_withValidPayload()
     property_files = AbOtaPropertyFiles()
@@ -1084,6 +1107,7 @@
     self._verify_entries(
         zip_file, tokens, ('care_map.txt', 'compatibility.zip'))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Finalize(self):
     zip_file = self.construct_zip_package_withValidPayload(with_metadata=True)
     property_files = AbOtaPropertyFiles()
@@ -1099,6 +1123,7 @@
     self._verify_entries(
         zip_file, tokens, ('care_map.txt', 'compatibility.zip'))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Verify(self):
     zip_file = self.construct_zip_package_withValidPayload(with_metadata=True)
     property_files = AbOtaPropertyFiles()
@@ -1182,6 +1207,7 @@
   def test_init(self):
     payload_signer = PayloadSigner()
     self.assertEqual('openssl', payload_signer.signer)
+    self.assertEqual(256, payload_signer.key_size)
 
   def test_init_withPassword(self):
     common.OPTIONS.package_key = os.path.join(
@@ -1195,9 +1221,17 @@
   def test_init_withExternalSigner(self):
     common.OPTIONS.payload_signer = 'abc'
     common.OPTIONS.payload_signer_args = ['arg1', 'arg2']
+    common.OPTIONS.payload_signer_key_size = '512'
     payload_signer = PayloadSigner()
     self.assertEqual('abc', payload_signer.signer)
     self.assertEqual(['arg1', 'arg2'], payload_signer.signer_args)
+    self.assertEqual(512, payload_signer.key_size)
+
+  def test_GetKeySizeInBytes_512Bytes(self):
+    signing_key = os.path.join(self.testdata_dir, 'testkey_RSA4096.key')
+    # pylint: disable=protected-access
+    key_size = PayloadSigner._GetKeySizeInBytes(signing_key)
+    self.assertEqual(512, key_size)
 
   def test_Sign(self):
     payload_signer = PayloadSigner()
@@ -1225,6 +1259,7 @@
     """Uses testdata/payload_signer.sh as the external payload signer."""
     common.OPTIONS.payload_signer = os.path.join(
         self.testdata_dir, 'payload_signer.sh')
+    os.chmod(common.OPTIONS.payload_signer, 0o700)
     common.OPTIONS.payload_signer_args = [
         os.path.join(self.testdata_dir, 'testkey.pk8')]
     payload_signer = PayloadSigner()
@@ -1264,14 +1299,17 @@
     payload.Generate(target_file, source_file)
     return payload
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Generate_full(self):
     payload = self._create_payload_full()
     self.assertTrue(os.path.exists(payload.payload_file))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Generate_incremental(self):
     payload = self._create_payload_incremental()
     self.assertTrue(os.path.exists(payload.payload_file))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Generate_additionalArgs(self):
     target_file = construct_target_files()
     source_file = construct_target_files()
@@ -1282,12 +1320,14 @@
         target_file, additional_args=["--source_image", source_file])
     self.assertTrue(os.path.exists(payload.payload_file))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Generate_invalidInput(self):
     target_file = construct_target_files()
     common.ZipDelete(target_file, 'IMAGES/vendor.img')
     payload = Payload()
     self.assertRaises(common.ExternalError, payload.Generate, target_file)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Sign_full(self):
     payload = self._create_payload_full()
     payload.Sign(PayloadSigner())
@@ -1301,6 +1341,7 @@
         os.path.join(self.testdata_dir, 'testkey.x509.pem'),
         output_file)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Sign_incremental(self):
     payload = self._create_payload_incremental()
     payload.Sign(PayloadSigner())
@@ -1314,6 +1355,7 @@
         os.path.join(self.testdata_dir, 'testkey.x509.pem'),
         output_file)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Sign_withDataWipe(self):
     common.OPTIONS.wipe_user_data = True
     payload = self._create_payload_full()
@@ -1322,6 +1364,7 @@
     with open(payload.payload_properties) as properties_fp:
       self.assertIn("POWERWASH=1", properties_fp.read())
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Sign_secondary(self):
     payload = self._create_payload_full(secondary=True)
     payload.Sign(PayloadSigner())
@@ -1329,6 +1372,7 @@
     with open(payload.payload_properties) as properties_fp:
       self.assertIn("SWITCH_SLOT_ON_REBOOT=0", properties_fp.read())
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_Sign_badSigner(self):
     """Tests that signing failure can be captured."""
     payload = self._create_payload_full()
@@ -1336,6 +1380,7 @@
     payload_signer.signer_args.append('bad-option')
     self.assertRaises(common.ExternalError, payload.Sign, payload_signer)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_WriteToZip(self):
     payload = self._create_payload_full()
     payload.Sign(PayloadSigner())
@@ -1357,6 +1402,7 @@
           continue
         self.assertEqual(zipfile.ZIP_STORED, entry_info.compress_type)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_WriteToZip_unsignedPayload(self):
     """Unsigned payloads should not be allowed to be written to zip."""
     payload = self._create_payload_full()
@@ -1372,6 +1418,7 @@
     with zipfile.ZipFile(output_file, 'w') as output_zip:
       self.assertRaises(AssertionError, payload.WriteToZip, output_zip)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_WriteToZip_secondary(self):
     payload = self._create_payload_full(secondary=True)
     payload.Sign(PayloadSigner())
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index 6a4df1a..d745200 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -34,8 +34,8 @@
 </policy>"""
 
   # pylint: disable=line-too-long
-  APEX_KEYS_TXT = """name="apex.apexd_test.apex" public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package.avbpubkey" private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem" container_certificate="build/target/product/security/testkey.x509.pem" container_private_key="build/target/product/security/testkey.pk8"
-name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem" container_certificate="build/target/product/security/testkey.x509.pem" container_private_key="build/target/product/security/testkey.pk8"
+  APEX_KEYS_TXT = """name="apex.apexd_test.apex" public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package.avbpubkey" private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem" container_certificate="build/make/target/product/security/testkey.x509.pem" container_private_key="build/make/target/product/security/testkey.pk8"
+name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem" container_certificate="build/make/target/product/security/testkey.x509.pem" container_private_key="build/make/target/product/security/testkey.pk8"
 """
 
   def setUp(self):
@@ -395,10 +395,10 @@
     self.assertEqual({
         'apex.apexd_test.apex': (
             'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
-            'build/target/product/security/testkey'),
+            'build/make/target/product/security/testkey'),
         'apex.apexd_test_different_app.apex': (
             'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
-            'build/target/product/security/testkey'),
+            'build/make/target/product/security/testkey'),
         }, keys_info)
 
   def test_ReadApexKeysInfo_mismatchingContainerKeys(self):
@@ -407,8 +407,8 @@
         'name="apex.apexd_test_different_app2.apex" '
         'public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" '
         'private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem" '
-        'container_certificate="build/target/product/security/testkey.x509.pem" '
-        'container_private_key="build/target/product/security/testkey2.pk8"')
+        'container_certificate="build/make/target/product/security/testkey.x509.pem" '
+        'container_private_key="build/make/target/product/security/testkey2.pk8"')
     target_files = common.MakeTempFile(suffix='.zip')
     with zipfile.ZipFile(target_files, 'w') as target_files_zip:
       target_files_zip.writestr('META/apexkeys.txt', apex_keys)
@@ -421,8 +421,8 @@
     apex_keys = self.APEX_KEYS_TXT + (
         'name="apex.apexd_test_different_app2.apex" '
         'public_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey" '
-        'container_certificate="build/target/product/security/testkey.x509.pem" '
-        'container_private_key="build/target/product/security/testkey.pk8"')
+        'container_certificate="build/make/target/product/security/testkey.x509.pem" '
+        'container_private_key="build/make/target/product/security/testkey.pk8"')
     target_files = common.MakeTempFile(suffix='.zip')
     with zipfile.ZipFile(target_files, 'w') as target_files_zip:
       target_files_zip.writestr('META/apexkeys.txt', apex_keys)
@@ -433,10 +433,10 @@
     self.assertEqual({
         'apex.apexd_test.apex': (
             'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
-            'build/target/product/security/testkey'),
+            'build/make/target/product/security/testkey'),
         'apex.apexd_test_different_app.apex': (
             'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
-            'build/target/product/security/testkey'),
+            'build/make/target/product/security/testkey'),
         }, keys_info)
 
   def test_ReadApexKeysInfo_missingPayloadPublicKey(self):
@@ -444,8 +444,8 @@
     apex_keys = self.APEX_KEYS_TXT + (
         'name="apex.apexd_test_different_app2.apex" '
         'private_key="system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem" '
-        'container_certificate="build/target/product/security/testkey.x509.pem" '
-        'container_private_key="build/target/product/security/testkey.pk8"')
+        'container_certificate="build/make/target/product/security/testkey.x509.pem" '
+        'container_private_key="build/make/target/product/security/testkey.pk8"')
     target_files = common.MakeTempFile(suffix='.zip')
     with zipfile.ZipFile(target_files, 'w') as target_files_zip:
       target_files_zip.writestr('META/apexkeys.txt', apex_keys)
@@ -456,8 +456,8 @@
     self.assertEqual({
         'apex.apexd_test.apex': (
             'system/apex/apexd/apexd_testdata/com.android.apex.test_package.pem',
-            'build/target/product/security/testkey'),
+            'build/make/target/product/security/testkey'),
         'apex.apexd_test_different_app.apex': (
             'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
-            'build/target/product/security/testkey'),
+            'build/make/target/product/security/testkey'),
         }, keys_info)
diff --git a/tools/releasetools/test_utils.py b/tools/releasetools/test_utils.py
old mode 100644
new mode 100755
index edb3d41..1e919f7
--- a/tools/releasetools/test_utils.py
+++ b/tools/releasetools/test_utils.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 #
 # Copyright (C) 2018 The Android Open Source Project
 #
@@ -30,6 +31,18 @@
 # Some test runner doesn't like outputs from stderr.
 logging.basicConfig(stream=sys.stdout)
 
+# Use ANDROID_BUILD_TOP as an indicator to tell if the needed tools (e.g.
+# avbtool, mke2fs) are available while running the tests. Not having the var or
+# having empty string means we can't run the tests that require external tools.
+EXTERNAL_TOOLS_UNAVAILABLE = not os.environ.get("ANDROID_BUILD_TOP")
+
+
+def SkipIfExternalToolsUnavailable():
+  """Decorator function that allows skipping tests per tools availability."""
+  if EXTERNAL_TOOLS_UNAVAILABLE:
+    return unittest.skip('External tools unavailable')
+  return lambda func: func
+
 
 def get_testdata_dir():
   """Returns the testdata dir, in relative to the script dir."""
@@ -40,6 +53,19 @@
 
 def get_search_path():
   """Returns the search path that has 'framework/signapk.jar' under."""
+
+  def signapk_exists(path):
+    signapk_path = os.path.realpath(
+        os.path.join(path, 'framework', 'signapk.jar'))
+    return os.path.exists(signapk_path)
+
+  # Try with ANDROID_BUILD_TOP first.
+  full_path = os.path.realpath(os.path.join(
+      os.environ.get('ANDROID_BUILD_TOP', ''), 'out', 'host', 'linux-x86'))
+  if signapk_exists(full_path):
+    return full_path
+
+  # Otherwise try going with relative pathes.
   current_dir = os.path.dirname(os.path.realpath(__file__))
   for path in (
       # In relative to 'build/make/tools/releasetools' in the Android source.
@@ -47,9 +73,7 @@
       # Or running the script unpacked from otatools.zip.
       ['..']):
     full_path = os.path.realpath(os.path.join(current_dir, *path))
-    signapk_path = os.path.realpath(
-        os.path.join(full_path, 'framework', 'signapk.jar'))
-    if os.path.exists(signapk_path):
+    if signapk_exists(full_path):
       return full_path
   return None
 
@@ -123,3 +147,10 @@
 
   def tearDown(self):
     common.Cleanup()
+
+
+if __name__ == '__main__':
+  testsuite = unittest.TestLoader().discover(
+      os.path.dirname(os.path.realpath(__file__)))
+  # atest needs a verbosity level of >= 2 to correctly parse the result.
+  unittest.TextTestRunner(verbosity=2).run(testsuite)
diff --git a/tools/releasetools/test_validate_target_files.py b/tools/releasetools/test_validate_target_files.py
index 5f619ec..70e3b49 100644
--- a/tools/releasetools/test_validate_target_files.py
+++ b/tools/releasetools/test_validate_target_files.py
@@ -55,6 +55,7 @@
         0, proc.returncode,
         "Failed to sign boot image with boot_signer: {}".format(stdoutdata))
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_ValidateVerifiedBootImages_bootImage(self):
     input_tmp = common.MakeTempDir()
     os.mkdir(os.path.join(input_tmp, 'IMAGES'))
@@ -69,6 +70,7 @@
     }
     ValidateVerifiedBootImages(input_tmp, info_dict, options)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_ValidateVerifiedBootImages_bootImage_wrongKey(self):
     input_tmp = common.MakeTempDir()
     os.mkdir(os.path.join(input_tmp, 'IMAGES'))
@@ -85,6 +87,7 @@
         AssertionError, ValidateVerifiedBootImages, input_tmp, info_dict,
         options)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_ValidateVerifiedBootImages_bootImage_corrupted(self):
     input_tmp = common.MakeTempDir()
     os.mkdir(os.path.join(input_tmp, 'IMAGES'))
@@ -139,6 +142,7 @@
     # Append the verity metadata.
     verity_image_builder.Build(output_file)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_ValidateVerifiedBootImages_systemImage(self):
     input_tmp = common.MakeTempDir()
     os.mkdir(os.path.join(input_tmp, 'IMAGES'))
@@ -162,6 +166,7 @@
     }
     ValidateVerifiedBootImages(input_tmp, info_dict, options)
 
+  @test_utils.SkipIfExternalToolsUnavailable()
   def test_ValidateFileConsistency_incompleteRange(self):
     input_tmp = common.MakeTempDir()
     os.mkdir(os.path.join(input_tmp, 'IMAGES'))
diff --git a/tools/releasetools/test_verity_utils.py b/tools/releasetools/test_verity_utils.py
index e0607c8..1cc539f 100644
--- a/tools/releasetools/test_verity_utils.py
+++ b/tools/releasetools/test_verity_utils.py
@@ -24,7 +24,8 @@
 import common
 import sparse_img
 from rangelib import RangeSet
-from test_utils import get_testdata_dir, ReleaseToolsTestCase
+from test_utils import (
+    get_testdata_dir, ReleaseToolsTestCase, SkipIfExternalToolsUnavailable)
 from verity_utils import (
     CreateHashtreeInfoGenerator, CreateVerityImageBuilder, HashtreeInfo,
     VerifiedBootVersion1HashtreeInfoGenerator)
@@ -89,6 +90,7 @@
 
     return output_file
 
+  @SkipIfExternalToolsUnavailable()
   def test_CreateHashtreeInfoGenerator(self):
     image_file = sparse_img.SparseImage(self._generate_image())
 
@@ -99,6 +101,7 @@
     self.assertEqual(self.partition_size, generator.partition_size)
     self.assertTrue(generator.fec_supported)
 
+  @SkipIfExternalToolsUnavailable()
   def test_DecomposeSparseImage(self):
     image_file = sparse_img.SparseImage(self._generate_image())
 
@@ -109,6 +112,7 @@
     self.assertEqual(12288, generator.hashtree_size)
     self.assertEqual(32768, generator.metadata_size)
 
+  @SkipIfExternalToolsUnavailable()
   def test_ParseHashtreeMetadata(self):
     image_file = sparse_img.SparseImage(self._generate_image())
     generator = VerifiedBootVersion1HashtreeInfoGenerator(
@@ -123,6 +127,7 @@
     self.assertEqual(self.fixed_salt, generator.hashtree_info.salt)
     self.assertEqual(self.expected_root_hash, generator.hashtree_info.root_hash)
 
+  @SkipIfExternalToolsUnavailable()
   def test_ValidateHashtree_smoke(self):
     generator = VerifiedBootVersion1HashtreeInfoGenerator(
         self.partition_size, 4096, True)
@@ -138,6 +143,7 @@
 
     self.assertTrue(generator.ValidateHashtree())
 
+  @SkipIfExternalToolsUnavailable()
   def test_ValidateHashtree_failure(self):
     generator = VerifiedBootVersion1HashtreeInfoGenerator(
         self.partition_size, 4096, True)
@@ -153,6 +159,7 @@
 
     self.assertFalse(generator.ValidateHashtree())
 
+  @SkipIfExternalToolsUnavailable()
   def test_Generate(self):
     image_file = sparse_img.SparseImage(self._generate_image())
     generator = CreateHashtreeInfoGenerator('system', 4096, self.prop_dict)
@@ -193,6 +200,7 @@
     del prop_dict['verity_block_device']
     self.assertIsNone(CreateVerityImageBuilder(prop_dict))
 
+  @SkipIfExternalToolsUnavailable()
   def test_CalculateMaxImageSize(self):
     verity_image_builder = CreateVerityImageBuilder(self.DEFAULT_PROP_DICT)
     size = verity_image_builder.CalculateMaxImageSize()
@@ -221,11 +229,13 @@
     cmd = ['verity_verifier', image, '-mincrypt', verify_key]
     common.RunAndCheckOutput(cmd)
 
+  @SkipIfExternalToolsUnavailable()
   def test_Build(self):
     self._BuildAndVerify(
         self.DEFAULT_PROP_DICT,
         os.path.join(get_testdata_dir(), 'testkey_mincrypt'))
 
+  @SkipIfExternalToolsUnavailable()
   def test_Build_SanityCheck(self):
     # A sanity check for the test itself: the image shouldn't be verifiable
     # with wrong key.
@@ -235,6 +245,7 @@
         self.DEFAULT_PROP_DICT,
         os.path.join(get_testdata_dir(), 'verity_mincrypt'))
 
+  @SkipIfExternalToolsUnavailable()
   def test_Build_FecDisabled(self):
     prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT)
     del prop_dict['verity_fec']
@@ -242,6 +253,7 @@
         prop_dict,
         os.path.join(get_testdata_dir(), 'testkey_mincrypt'))
 
+  @SkipIfExternalToolsUnavailable()
   def test_Build_SquashFs(self):
     verity_image_builder = CreateVerityImageBuilder(self.DEFAULT_PROP_DICT)
     verity_image_builder.CalculateMaxImageSize()
@@ -282,6 +294,7 @@
     verity_image_builder = CreateVerityImageBuilder(prop_dict)
     self.assertIsNone(verity_image_builder)
 
+  @SkipIfExternalToolsUnavailable()
   def test_Build(self):
     prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT)
     verity_image_builder = CreateVerityImageBuilder(prop_dict)
diff --git a/tools/releasetools/testdata/testkey_RSA4096.key b/tools/releasetools/testdata/testkey_RSA4096.key
new file mode 100644
index 0000000..07115e1
--- /dev/null
+++ b/tools/releasetools/testdata/testkey_RSA4096.key
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQC7y8EH4O8M9aA7
+UhaWLlW5ceQxZi0P7DNOgog/82SIZh1/Vv0S8KCu9LcngK60oIejPU3k9zb0Mpl2
+4OEtupbOq9SV0nyRIp33rs9EJ0zm8keZ2jEfwTubdhE4GumlwkbfYHlMPmpufqOq
+uxKfCOUZk3ZEC5RFDBqVLGrf9m22ITMQwNGj/u/mtAg2UXRGy534eU1evHOFH8tD
+IxXd378m+gRY+bPi6fOkrJgAw6N01NwwsHRxxQsVgp8m1EKpPJ+ARRtP6YYtNsNB
+KTOXqZw18OD7eG7yVONAf7oSOMNRK7qg6ZU6YN/y1k+YZF3D/1HU9THoDXIpBHoW
+R2SpEM63Ua8ilSmx9PfoaDn27VrpjIcq50HqKAXOvclxOCyVD0pRkrryPpevYCVu
+x9/InmW3K4dPiAy0KmmS4ZSLUJnr6Lnkt8C3VxXHqZ4T7MlgrjrO70YqCxeDvYE0
+KL/e/UeJ69nANybkDThhBkxkOC1vvik3VXO4ITPEKCnLHdvdj8rwkjqf3Ex5A0g8
+XaH0l6I72pqxXi8nnU9udLrUEdHUT1KHzjnZBVP6aomcDy5Gnbb6wXTBTkB7fdQB
+nGcqT0DH67PqJE/rCUguVSmX4KGyOVrr5S1GQTg1EmHbF2Kf6P0YJpcVU7PHRE8s
+BisP39wzoE5XsIpn/aKpWdpcfqxjTQIDAQABAoICAQCB/vtyLryLpgPyzFIiR5TD
+uBkUMPyEhybE9ArI6fzvhnBo05h/4d34/iFC0QsesfjygN9I3fBGfjhJWEXH19/I
+1J1l0Ly14taiu3lyXhoXzCLQV3+l0acnaEVnJwoR2jghLLEKnDIkprk42CJ9wDSG
+zdMSK0nJuiU0mfipa/ZqGvU0ZaU49qKuenUs1Jm+3/hMJfvu1ljJEEcuBD2Axv+V
+RYB47vEc5IHpvifCb6rYlviNI7iXgKS5kSAGSuySJgrrSessGCTva3chxhmWpKwj
+ksjKioWSbjyZS1FMh8p8h966wLayIJklikCy5tcZc8X7und/gL9DsXuprGX7uky8
+3ZS2cJjiVimkwoROq5VPa+0SBmNJWRBNvRfARiaKkyyidVxIsvjFNDFPQp1jYlzM
+fvGJwgnCiUQP56hvri3irriWN8Le2U8lqQQ7YaDLKcsf6iiMGwfxcK+6E4MUv797
+V5CZXSC7RrPd9wdj6UIqtgSGVUH3BV7kB+fYYfvV15kpj6IXYTxElfAZ2ak3g9sv
+JZ6moKbRN0xSufkDftMGv77cH13v97Iy3Whp8zEPMBnbsdpPp6DpIH8sl2R7O+zr
+uMty6vXw0Ux69LEpz4b4HyD7t65zTSwpou5YhfZt/yRzovawsQIRGlc4E1FJDFjf
+e9LvazMXo/us3T5LNv5pAQKCAQEA5Kq1RJgMlvKOfGaEah1xu65s3I1lGuz+9c1x
+geYFlta9H2vG1aADUtgmIBjjC+1z4KLD9jrjrwwbqKnisu7/qUOR6Qf8BHFbrMSs
+J8IMOD3Vw/UVc/8LCjoI4n1XaKYJtOyIxKJtWKAbgtvgVOAGSt47LEOOchXNnAKv
+C3Flak3ADYaUQFLoiwmp6WdSL+uiLisukKNjmYu8vxhg9255p31PB6xixd0raoF/
+oDTfgY1fG/OFXvQd+GcjrTJ2Lqk1GtZqau5MEkS5jsKKnPJ6+ozd2t+QVkMrIQER
+WeTtZ7gimJo6QF8uyyG8WqT1qxbO2zV4Nrwak6ozRFhEJdnJrQKCAQEA0j5hY6sr
+apIvEUFsK6k1rEb77+1p85eyCOSYZpHEIe0hy89MjMUFA5IKhsXnUqhkiuJURUrD
+VtccWWJt5DUgS6HzJUGjeXo07wkqVz+10l+l+RSHleNBYlbxSpZQtvkKQkISF56c
+bSjLzOGM4RE8NxBdFg6EijwlKlZ8kW1ZJaQv9fuR+QS9DFXSiYUJSDiwLF0F6ogQ
+i1h3RN3RIKYc9kizYqBKaksg8EfQEyJs2Rhl5JrPmdZvDTpSeGRqz66WbdL4gSNv
+ud64BYY+Uhec9yH2HDal1l/j1dFbh+Nzs2v4b5TYmCO/zX5GfucUrZaGHbZcovlo
+/abKhURKW/N0IQKCAQEAhz0PCAqFJ6E89AYNulS/tyhp6ecWLN6NzAI9Z34LQDKw
+l6y+ZAnG7XA43DLb1WoSZoDdNPuPPTAEC7SuBvWi7xCvcwrt2hLRDVUkHD9/yqOH
+keWZUok8lkfMiWdoEtRgWUireuA1m3zVyIcSHiCAmDbm+D7cOEz81ZAgxrvCJyTk
+uRsnAwQF1HVasFgTG5RYzsVrPM/lUCJ89ugMMUp9WLmbzAYARNWRn+QG/1FF/vEF
+lxpnfskSEJ+vUffOPbqFVeIJ/kQBaayLsgsMv9YJNbWqYJBoZRxEnbhr8qaaYgVd
+MLPGT9v7aNgC9fkp8o4CuVLeTkDh1wOKXpl1dI1h4QKCAQEAgfNExxI517lbllLV
+xXblUgLeHkKkxofw50ZEXMGkdUPZK9yJ+Eie/MH796nDfXfQDXgvllTLwJVdVHJe
+cjvUJmuHmnOj06YRqd4EacFbZRjxwa9Kzv6Un3AV3IBki3QLP0EPZcIH9gDNV2ni
+Zgr9KRvYLZXznm3mmvCyNkFcZMPDUUuZwk2HfGRfqditEBLZ8dHdokVP1JFtxwdE
+B+Yk6KWvGzrwRBsD1QDOP8V7egR2loKJ5xB/u7Fc4EVRL+U93cwVBd0dZcmf/Oop
+AxzNTIOVV4L/pi3G6ZZp+OhBz5jhCjb6Wa9fEmkGsdGrGlB7vUnGoIWAu6eobg7z
+1zn3gQKCAQBwyViGs7b5HuYQ8UNkvBK9MxUE6h/qHEshbw+QtD/wcdNNpwLTawoW
+JH3bWzD01p1DsbRx/bcV5yaiWDhuslSH2xB6+N1gx2ohg8lPmFhKQiR1OTQ3L603
+Y+3h8FNO/c3YPcNr/k4N+tVKPSJvz0NcbkNs9qGUUsiEppVtc17VFAv/yPicV/wP
+0vC4Qw4xitSlIzD1QtPl0HfhA3ZM6fBb0lYx3tpJjmkrWPVjwWhYIAVLD6j7Jark
+NtMW9wSG21atSgWX1jFOiVsu3qzDpMvLXbH2FpAO9t+9GSDcSzfUMQLymWyW1+Dl
+L0rBGoJyEopSbtycAkWEHb/YLolfaTRd
+-----END PRIVATE KEY-----