Merge "Update mts task to make mts-${MODULE} test suites"
diff --git a/core/Makefile b/core/Makefile
index add62b4..d85bd76 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -711,10 +711,6 @@
   BUILT_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
 endif
 
-# kernel cmdline for GKI
-GENERIC_KERNEL_CMDLINE := rw
-.KATI_READONLY := GENERIC_KERNEL_CMDLINE
-
 INTERNAL_PREBUILT_BOOTIMAGE :=
 
 my_installed_prebuilt_gki_apex := $(strip $(foreach package,$(PRODUCT_PACKAGES),$(if $(ALL_MODULES.$(package).EXTRACTED_BOOT_IMAGE),$(package))))
@@ -938,6 +934,17 @@
 $(INTERNAL_VENDOR_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_VENDOR_RAMDISK_FILES) | $(COMPRESSION_COMMAND_DEPS)
 	$(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_VENDOR_RAMDISK_OUT) $(PRIVATE_ADDITIONAL_DIR) | $(COMPRESSION_COMMAND) > $@
 
+INSTALLED_FILES_FILE_VENDOR_RAMDISK := $(PRODUCT_OUT)/installed-files-vendor-ramdisk.txt
+INSTALLED_FILES_JSON_VENDOR_RAMDISK := $(INSTALLED_FILES_FILE_VENDOR_RAMDISK:.txt=.json)
+$(INSTALLED_FILES_FILE_VENDOR_RAMDISK): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_VENDOR_RAMDISK)
+$(INSTALLED_FILES_FILE_VENDOR_RAMDISK): $(INTERNAL_VENDOR_RAMDISK_TARGET)
+$(INSTALLED_FILES_FILE_VENDOR_RAMDISK): $(INTERNAL_VENDOR_RAMDISK_FILES) $(FILESLIST) $(FILESLIST_UTIL)
+	echo Installed file list: $@
+	mkdir -p $(dir $@)
+	rm -f $@
+	$(hide) $(FILESLIST) $(TARGET_VENDOR_RAMDISK_OUT) > $(@:.txt=.json)
+	$(hide) $(FILESLIST_UTIL) -c $(@:.txt=.json) > $@
+
 ifdef BOARD_INCLUDE_DTB_IN_BOOTIMG
   INTERNAL_VENDOR_BOOTIMAGE_ARGS += --dtb $(INSTALLED_DTBIMAGE_TARGET)
 endif
@@ -3750,7 +3757,7 @@
 $(BUILT_KERNEL_CONFIGS_FILE): $(EXTRACT_KERNEL) $(firstword $(INSTALLED_KERNEL_TARGET))
 	$< --tools $(PRIVATE_DECOMPRESS_TOOLS) --input $(firstword $(INSTALLED_KERNEL_TARGET)) \
 	  --output-configs $@ \
-	  --output-version $(BUILT_KERNEL_VERSION_FILE)
+	  --output-release $(BUILT_KERNEL_VERSION_FILE)
 
 my_decompress_tools :=
 
@@ -3759,7 +3766,7 @@
 
 endif # INSTALLED_KERNEL_TARGET
 
-check_vintf_compatible_args += --kernel $$(cat $(BUILT_KERNEL_VERSION_FILE)):$(BUILT_KERNEL_CONFIGS_FILE)
+check_vintf_compatible_args += --kernel $(BUILT_KERNEL_VERSION_FILE):$(BUILT_KERNEL_CONFIGS_FILE)
 check_vintf_compatible_deps += $(BUILT_KERNEL_CONFIGS_FILE) $(BUILT_KERNEL_VERSION_FILE)
 
 endif # PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS
@@ -4144,6 +4151,9 @@
 	$(hide) echo "board_uses_vendorimage=true" >> $@
 endif
 ifeq ($(BOARD_AVB_ENABLE),true)
+ifeq ($(BUILDING_VBMETA_IMAGE),true)
+	$(hide) echo "avb_building_vbmeta_image=true" >> $@
+endif # BUILDING_VBMETA_IMAGE
 	$(hide) echo "avb_enable=true" >> $@
 	$(hide) echo "avb_vbmeta_key_path=$(BOARD_AVB_KEY_PATH)" >> $@
 	$(hide) echo "avb_vbmeta_algorithm=$(BOARD_AVB_ALGORITHM)" >> $@
@@ -4243,6 +4253,9 @@
 ifeq ($(BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE),true)
 	$(hide) echo "exclude_kernel_from_recovery_image=true" >> $@
 endif
+ifneq ($(BOARD_PARTIAL_OTA_UPDATE_PARTITIONS_LIST),)
+	$(hide) echo "partial_ota_update_partitions_list=$(BOARD_PARTIAL_OTA_UPDATE_PARTITIONS_LIST)" >> $@
+endif
 
 .PHONY: misc_info
 misc_info: $(INSTALLED_MISC_INFO_TARGET)
@@ -4446,7 +4459,8 @@
 
 ifdef BUILDING_BOOT_IMAGE
   $(BUILT_TARGET_FILES_PACKAGE): $(INTERNAL_RAMDISK_FILES)
-else ifdef INTERNAL_PREBUILT_BOOTIMAGE
+endif
+ifneq (,$(INTERNAL_PREBUILT_BOOTIMAGE) $(filter true,$(BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES)))
   $(BUILT_TARGET_FILES_PACKAGE): $(INSTALLED_BOOTIMAGE_TARGET)
 endif
 
@@ -4745,10 +4759,12 @@
 	$(hide) mkdir -p $(zip_root)/IMAGES
 	$(hide) cp $(INSTALLED_SYSTEM_EXTIMAGE_TARGET) $(zip_root)/IMAGES/
 endif
-ifdef INTERNAL_PREBUILT_BOOTIMAGE
+ifneq (,$(INTERNAL_PREBUILT_BOOTIMAGE) $(filter true,$(BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES)))
+ifdef INSTALLED_BOOTIMAGE_TARGET
 	$(hide) mkdir -p $(zip_root)/IMAGES
 	$(hide) cp $(INSTALLED_BOOTIMAGE_TARGET) $(zip_root)/IMAGES/
-endif
+endif # INSTALLED_BOOTIMAGE_TARGET
+endif # INTERNAL_PREBUILT_BOOTIMAGE != "" || BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES == true
 ifdef BOARD_PREBUILT_ODMIMAGE
 	$(hide) mkdir -p $(zip_root)/IMAGES
 	$(hide) cp $(INSTALLED_ODMIMAGE_TARGET) $(zip_root)/IMAGES/
diff --git a/core/base_rules.mk b/core/base_rules.mk
index adf61f1..dbd8930 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -274,6 +274,12 @@
   endif
 endif
 
+ifeq ($(LOCAL_IS_UNIT_TEST),true)
+  ifeq ($(LOCAL_IS_HOST_MODULE),true)
+    LOCAL_COMPATIBILITY_SUITE += host-unit-tests
+  endif
+endif
+
 ifeq ($(my_module_path),)
   install_path_var := $(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT$(partition_tag)_$(LOCAL_MODULE_CLASS)
   ifeq (true,$(LOCAL_PRIVILEGED_MODULE))
diff --git a/core/board_config.mk b/core/board_config.mk
index 457b3bf..d674d1a 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -107,11 +107,14 @@
 #   recovery resources are built to vendor_boot.
 # - BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT controls whether GSI AVB keys are
 #   built to vendor_boot.
+# - BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES controls whether boot images in $OUT are added
+#   to target files package directly.
 _board_strip_readonly_list += \
   BOARD_USES_GENERIC_KERNEL_IMAGE \
   BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE \
   BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT \
   BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT \
+  BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES \
 
 _build_broken_var_list := \
   BUILD_BROKEN_DUP_RULES \
@@ -787,3 +790,10 @@
       Use BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT instead)
   endif
 endif
+
+ifeq (true,$(BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT))
+  ifeq (true,$(BOARD_USES_RECOVERY_AS_BOOT))
+    $(error BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT and BOARD_USES_RECOVERY_AS_BOOT cannot be \
+      both true. Recovery resources should be installed to either boot or vendor_boot, but not both)
+  endif
+endif
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 6e1cb68..6909275 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -130,6 +130,7 @@
 LOCAL_IS_FUZZ_TARGET:=
 LOCAL_IS_HOST_MODULE:=
 LOCAL_IS_RUNTIME_RESOURCE_OVERLAY:=
+LOCAL_IS_UNIT_TEST:=
 LOCAL_JACK_CLASSPATH:=
 LOCAL_JACK_COVERAGE_EXCLUDE_FILTER:=
 LOCAL_JACK_COVERAGE_INCLUDE_FILTER:=
diff --git a/core/definitions.mk b/core/definitions.mk
index daac652..8219f82 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -107,7 +107,7 @@
 # All tests that should be skipped in presubmit check.
 ALL_DISABLED_PRESUBMIT_TESTS :=
 
-# All compatibility suites mentioned in LOCAL_COMPATIBILITY_SUITES
+# All compatibility suites mentioned in LOCAL_COMPATIBILITY_SUITE
 ALL_COMPATIBILITY_SUITES :=
 
 # All compatibility suite files to dist.
@@ -2404,6 +2404,7 @@
 	$(1) \
 	$(HOST_INIT_VERIFIER) \
 	$(call intermediates-dir-for,ETC,passwd_system)/passwd_system \
+	$(call intermediates-dir-for,ETC,passwd_system_ext)/passwd_system_ext \
 	$(call intermediates-dir-for,ETC,passwd_vendor)/passwd_vendor \
 	$(call intermediates-dir-for,ETC,passwd_odm)/passwd_odm \
 	$(call intermediates-dir-for,ETC,passwd_product)/passwd_product \
@@ -2414,6 +2415,7 @@
 	$(call intermediates-dir-for,ETC,odm_property_contexts)/odm_property_contexts
 	$(hide) $(HOST_INIT_VERIFIER) \
 	  -p $(call intermediates-dir-for,ETC,passwd_system)/passwd_system \
+	  -p $(call intermediates-dir-for,ETC,passwd_system_ext)/passwd_system_ext \
 	  -p $(call intermediates-dir-for,ETC,passwd_vendor)/passwd_vendor \
 	  -p $(call intermediates-dir-for,ETC,passwd_odm)/passwd_odm \
 	  -p $(call intermediates-dir-for,ETC,passwd_product)/passwd_product \
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index 799b623..c31d4e8 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -189,20 +189,42 @@
   my_filtered_optional_uses_libraries := $(filter-out $(INTERNAL_PLATFORM_MISSING_USES_LIBRARIES), \
     $(LOCAL_OPTIONAL_USES_LIBRARIES))
 
-  # dexpreopt needs the paths to the dex jars of these libraries in order to
-  # construct class loader context for dex2oat.
-  my_extra_dexpreopt_libs := \
-    org.apache.http.legacy \
+  # compatibility libraries are added to class loader context of an app only if
+  # targetSdkVersion in the app's manifest is lower than the given SDK version
+
+  my_dexpreopt_libs_compat_28 := \
+    org.apache.http.legacy
+
+  my_dexpreopt_libs_compat_29 := \
     android.hidl.base-V1.0-java \
-    android.hidl.manager-V1.0-java \
+    android.hidl.manager-V1.0-java
+
+  my_dexpreopt_libs_compat_30 := \
     android.test.base \
+    android.test.mock
+
+  my_dexpreopt_libs_compat := \
+    $(my_dexpreopt_libs_compat_28) \
+    $(my_dexpreopt_libs_compat_29) \
+    $(my_dexpreopt_libs_compat_30)
 
   my_dexpreopt_libs := $(sort \
     $(LOCAL_USES_LIBRARIES) \
     $(my_filtered_optional_uses_libraries) \
-    $(my_extra_dexpreopt_libs) \
   )
 
+  # 1: SDK version
+  # 2: list of libraries
+  add_json_class_loader_context = \
+    $(call add_json_map, $(1)) \
+    $(foreach lib, $(2),\
+      $(call add_json_map, $(lib)) \
+      $(eval file := $(filter %/$(lib).jar, $(call module-installed-files,$(lib)))) \
+      $(call add_json_str, Host,       $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar) \
+      $(call add_json_str, Device,     $(call install-path-to-on-device-path,$(file))) \
+      $(call end_json_map)) \
+    $(call end_json_map)
+
   # Record dex-preopt config.
   DEXPREOPT.$(LOCAL_MODULE).DEX_PREOPT := $(LOCAL_DEX_PREOPT)
   DEXPREOPT.$(LOCAL_MODULE).MULTILIB := $(LOCAL_MULTILIB)
@@ -230,15 +252,11 @@
   $(call add_json_str,  ProfileClassListing,            $(if $(my_process_profile),$(LOCAL_DEX_PREOPT_PROFILE)))
   $(call add_json_bool, ProfileIsTextListing,           $(my_profile_is_text_listing))
   $(call add_json_bool, EnforceUsesLibraries,           $(LOCAL_ENFORCE_USES_LIBRARIES))
-  $(call add_json_list, OptionalUsesLibraries,          $(my_filtered_optional_uses_libraries))
-  $(call add_json_list, UsesLibraries,                  $(LOCAL_USES_LIBRARIES))
-  $(call add_json_map,  LibraryPaths)
-  $(foreach lib,$(my_dexpreopt_libs),\
-    $(call add_json_map, $(lib)) \
-    $(eval file := $(filter %/$(lib).jar, $(call module-installed-files,$(lib)))) \
-    $(call add_json_str, Host,   $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar) \
-    $(call add_json_str, Device, $(call install-path-to-on-device-path,$(file))) \
-    $(call end_json_map))
+  $(call add_json_map,  ClassLoaderContexts)
+  $(call add_json_class_loader_context, any, $(my_dexpreopt_libs))
+  $(call add_json_class_loader_context,  28, $(my_dexpreopt_libs_compat_28))
+  $(call add_json_class_loader_context,  29, $(my_dexpreopt_libs_compat_29))
+  $(call add_json_class_loader_context,  30, $(my_dexpreopt_libs_compat_30))
   $(call end_json_map)
   $(call add_json_list, Archs,                          $(my_dexpreopt_archs))
   $(call add_json_list, DexPreoptImages,                $(my_dexpreopt_images))
@@ -280,7 +298,7 @@
   my_dexpreopt_deps := $(my_dex_jar)
   my_dexpreopt_deps += $(if $(my_process_profile),$(LOCAL_DEX_PREOPT_PROFILE))
   my_dexpreopt_deps += \
-    $(foreach lib, $(my_dexpreopt_libs), \
+    $(foreach lib, $(my_dexpreopt_libs) $(my_dexpreopt_libs_compat), \
       $(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar)
   my_dexpreopt_deps += $(my_dexpreopt_images_deps)
   my_dexpreopt_deps += $(DEXPREOPT_BOOTCLASSPATH_DEX_FILES)
diff --git a/core/java_host_unit_test_config_template.xml b/core/java_host_unit_test_config_template.xml
new file mode 100644
index 0000000..ff300da
--- /dev/null
+++ b/core/java_host_unit_test_config_template.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<!-- This test config file is auto-generated. -->
+<configuration description="Runs {MODULE}">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-unit-tests" />
+
+    {EXTRA_CONFIGS}
+
+    <test class="com.android.tradefed.testtype.IsolatedHostTest" >
+        <option name="jar" value="{MODULE}.jar" />
+    </test>
+</configuration>
diff --git a/core/main.mk b/core/main.mk
index 9b19761..d8a0443 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1625,6 +1625,8 @@
     $(INSTALLED_FILES_JSON_RAMDISK) \
     $(INSTALLED_FILES_FILE_DEBUG_RAMDISK) \
     $(INSTALLED_FILES_JSON_DEBUG_RAMDISK) \
+    $(INSTALLED_FILES_FILE_VENDOR_RAMDISK) \
+    $(INSTALLED_FILES_JSON_VENDOR_RAMDISK) \
     $(INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK) \
     $(INSTALLED_FILES_JSON_VENDOR_DEBUG_RAMDISK) \
     $(INSTALLED_FILES_FILE_ROOT) \
@@ -1639,6 +1641,7 @@
 
 ifeq ($(SOONG_COLLECT_JAVA_DEPS), true)
   $(call dist-for-goals, dist_files, $(SOONG_OUT_DIR)/module_bp_java_deps.json)
+  $(call dist-for-goals, dist_files, $(PRODUCT_OUT)/module-info.json)
 endif
 
 .PHONY: apps_only
@@ -1773,6 +1776,8 @@
       $(INSTALLED_FILES_JSON_RAMDISK) \
       $(INSTALLED_FILES_FILE_DEBUG_RAMDISK) \
       $(INSTALLED_FILES_JSON_DEBUG_RAMDISK) \
+      $(INSTALLED_FILES_FILE_VENDOR_RAMDISK) \
+      $(INSTALLED_FILES_JSON_VENDOR_RAMDISK) \
       $(INSTALLED_FILES_FILE_VENDOR_DEBUG_RAMDISK) \
       $(INSTALLED_FILES_JSON_VENDOR_DEBUG_RAMDISK) \
       $(INSTALLED_DEBUG_RAMDISK_TARGET) \
diff --git a/core/product.mk b/core/product.mk
index 666e390..5f06141 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -120,7 +120,7 @@
 # The resoure configuration options to use for this product.
 _product_list_vars += PRODUCT_LOCALES
 _product_list_vars += PRODUCT_AAPT_CONFIG
-_product_list_vars += PRODUCT_AAPT_PREF_CONFIG
+_product_single_value_vars += PRODUCT_AAPT_PREF_CONFIG
 _product_list_vars += PRODUCT_AAPT_PREBUILT_DPI
 _product_list_vars += PRODUCT_HOST_PACKAGES
 _product_list_vars += PRODUCT_PACKAGES
@@ -209,7 +209,7 @@
 _product_list_vars += PRODUCT_SOONG_NAMESPACES
 
 _product_list_vars += PRODUCT_DEFAULT_WIFI_CHANNELS
-_product_list_vars += PRODUCT_DEFAULT_DEV_CERTIFICATE
+_product_single_value_vars += PRODUCT_DEFAULT_DEV_CERTIFICATE
 _product_list_vars += PRODUCT_MAINLINE_SEPOLICY_DEV_CERTIFICATES
 _product_list_vars += PRODUCT_RESTRICT_VENDOR_FILES
 
@@ -233,7 +233,7 @@
 # List of system_server jars delivered via apex. Format = <apex name>:<jar name>.
 _product_list_vars += PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS
 # If true, then suboptimal order of system server jars does not cause an error.
-_product_list_vars += PRODUCT_BROKEN_SUBOPTIMAL_ORDER_OF_SYSTEM_SERVER_JARS
+_product_single_value_vars += PRODUCT_BROKEN_SUBOPTIMAL_ORDER_OF_SYSTEM_SERVER_JARS
 
 # Additional system server jars to be appended at the end of the common list.
 # This is necessary to avoid jars reordering due to makefile inheritance order.
@@ -258,13 +258,13 @@
 
 # Per-module dex-preopt configs.
 _product_list_vars += PRODUCT_DEX_PREOPT_MODULE_CONFIGS
-_product_list_vars += PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER
+_product_single_value_vars += PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER
 _product_list_vars += PRODUCT_DEX_PREOPT_DEFAULT_FLAGS
-_product_list_vars += PRODUCT_DEX_PREOPT_BOOT_FLAGS
-_product_list_vars += PRODUCT_DEX_PREOPT_PROFILE_DIR
-_product_list_vars += PRODUCT_DEX_PREOPT_GENERATE_DM_FILES
-_product_list_vars += PRODUCT_DEX_PREOPT_NEVER_ALLOW_STRIPPING
-_product_list_vars += PRODUCT_DEX_PREOPT_RESOLVE_STARTUP_STRINGS
+_product_single_value_vars += PRODUCT_DEX_PREOPT_BOOT_FLAGS
+_product_single_value_vars += PRODUCT_DEX_PREOPT_PROFILE_DIR
+_product_single_value_vars += PRODUCT_DEX_PREOPT_GENERATE_DM_FILES
+_product_single_value_vars += PRODUCT_DEX_PREOPT_NEVER_ALLOW_STRIPPING
+_product_single_value_vars += PRODUCT_DEX_PREOPT_RESOLVE_STARTUP_STRINGS
 
 # Boot image options.
 _product_single_value_vars += \
@@ -272,7 +272,7 @@
     PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION \
     PRODUCT_USES_DEFAULT_ART_CONFIG \
 
-_product_list_vars += PRODUCT_SYSTEM_SERVER_COMPILER_FILTER
+_product_single_value_vars += PRODUCT_SYSTEM_SERVER_COMPILER_FILTER
 # Per-module sanitizer configs
 _product_list_vars += PRODUCT_SANITIZER_MODULE_CONFIGS
 _product_single_value_vars += PRODUCT_SYSTEM_BASE_FS_PATH
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 809a4d6..06b5555 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -1,7 +1,3 @@
-SOONG := $(SOONG_OUT_DIR)/soong
-SOONG_BOOTSTRAP := $(SOONG_OUT_DIR)/.soong.bootstrap
-SOONG_BUILD_NINJA := $(SOONG_OUT_DIR)/build.ninja
-SOONG_IN_MAKE := $(SOONG_OUT_DIR)/.soong.in_make
 SOONG_MAKEVARS_MK := $(SOONG_OUT_DIR)/make_vars-$(TARGET_PRODUCT).mk
 SOONG_VARIABLES := $(SOONG_OUT_DIR)/soong.variables
 SOONG_ANDROID_MK := $(SOONG_OUT_DIR)/Android-$(TARGET_PRODUCT).mk
diff --git a/core/soong_rust_prebuilt.mk b/core/soong_rust_prebuilt.mk
index dea7340..4cfb01f 100644
--- a/core/soong_rust_prebuilt.mk
+++ b/core/soong_rust_prebuilt.mk
@@ -82,8 +82,19 @@
   endif
 endif
 
+create_coverage_zip :=
 
 ifeq ($(NATIVE_COVERAGE),true)
+   create_coverage_zip := true
+endif
+
+# Until Rust supports LLVM coverage, Soong assumes GCOV coverage in both cases.
+# Therefore we should create the coverage zip with the gcno files in this case as well.
+ifeq ($(CLANG_COVERAGE),true)
+   create_coverage_zip := true
+endif
+
+ifdef create_coverage_zip
   ifneq (,$(strip $(LOCAL_PREBUILT_COVERAGE_ARCHIVE)))
     $(eval $(call copy-one-file,$(LOCAL_PREBUILT_COVERAGE_ARCHIVE),$(intermediates)/$(LOCAL_MODULE).zip))
     ifneq ($(LOCAL_UNINSTALLABLE_MODULE),true)
diff --git a/core/sysprop.mk b/core/sysprop.mk
index fdefced..1c66281 100644
--- a/core/sysprop.mk
+++ b/core/sysprop.mk
@@ -68,7 +68,9 @@
 #       emitted to the output
 # $(4): list of variable names each of which contains name=value pairs
 # $(5): optional list of prop names to force remove from the output. Properties from both
-#       $(3) and (4) are affected.
+#       $(3) and (4) are affected
+# $(6): optional list of files to append at the end. The content of each file is emitted
+#       to the output
 define build-properties
 ALL_DEFAULT_INSTALLED_MODULES += $(2)
 
@@ -90,7 +92,7 @@
     $(eval _option := --allow-dup)\
 )
 
-$(2): $(POST_PROCESS_PROPS) $(INTERNAL_BUILD_ID_MAKEFILE) $(API_FINGERPRINT) $(3)
+$(2): $(POST_PROCESS_PROPS) $(INTERNAL_BUILD_ID_MAKEFILE) $(API_FINGERPRINT) $(3) $(6)
 	$(hide) echo Building $$@
 	$(hide) mkdir -p $$(dir $$@)
 	$(hide) rm -f $$@ && touch $$@
@@ -113,6 +115,10 @@
 	    )\
 	)
 	$(hide) $(POST_PROCESS_PROPS) $$(_option) $$@ $(5)
+	$(hide) $(foreach file,$(strip $(6)),\
+	    if [ -f "$(file)" ]; then\
+	        cat $(file) >> $$@;\
+	    fi;)
 	$(hide) echo "# end of file" >> $$@
 endef
 
@@ -265,19 +271,6 @@
 	        TARGET_CPU_ABI2="$(TARGET_CPU_ABI2)" \
 	        bash $(BUILDINFO_SH) > $@
 
-ifneq ($(PRODUCT_OEM_PROPERTIES),)
-import_oem_prop := $(call intermediates-dir-for,ETC,system_build_prop)/oem.prop
-
-$(import_oem_prop):
-	$(hide) echo "#" >> $@; \
-	        echo "# PRODUCT_OEM_PROPERTIES" >> $@; \
-	        echo "#" >> $@;
-	$(hide) $(foreach prop,$(PRODUCT_OEM_PROPERTIES), \
-	    echo "import /oem/oem.prop $(prop)" >> $@;)
-else
-import_oem_prop :=
-endif
-
 ifdef TARGET_SYSTEM_PROP
 system_prop_file := $(TARGET_SYSTEM_PROP)
 else
@@ -285,7 +278,6 @@
 endif
 
 _prop_files_ := \
-  $(import_oem_prop) \
   $(gen_from_buildinfo_sh) \
   $(system_prop_file)
 
@@ -311,9 +303,13 @@
 
 INSTALLED_BUILD_PROP_TARGET := $(TARGET_OUT)/build.prop
 
-$(eval $(call build-properties,system,$(INSTALLED_BUILD_PROP_TARGET),\
-$(_prop_files_),$(_prop_vars_),\
-$(_blacklist_names_)))
+$(eval $(call build-properties,\
+    system,\
+    $(INSTALLED_BUILD_PROP_TARGET),\
+    $(_prop_files_),\
+    $(_prop_vars_),\
+    $(_blacklist_names_),\
+    $(empty)))
 
 # -----------------------------------------------------------------
 # vendor/build.prop
@@ -349,7 +345,8 @@
     $(INSTALLED_VENDOR_BUILD_PROP_TARGET),\
     $(_prop_files_),\
     $(_prop_vars_),\
-    $(PRODUCT_VENDOR_PROPERTY_BLACKLIST)))
+    $(PRODUCT_VENDOR_PROPERTY_BLACKLIST),\
+    $(empty)))
 
 # -----------------------------------------------------------------
 # product/etc/build.prop
@@ -366,12 +363,29 @@
     PRODUCT_PRODUCT_PROPERTIES
 
 INSTALLED_PRODUCT_BUILD_PROP_TARGET := $(TARGET_OUT_PRODUCT)/etc/build.prop
+
+ifdef PRODUCT_OEM_PROPERTIES
+import_oem_prop := $(call intermediates-dir-for,ETC,import_oem_prop)/oem.prop
+
+$(import_oem_prop):
+	$(hide) echo "####################################" >> $@; \
+	        echo "# PRODUCT_OEM_PROPERTIES" >> $@; \
+	        echo "####################################" >> $@;
+	$(hide) $(foreach prop,$(PRODUCT_OEM_PROPERTIES), \
+	    echo "import /oem/oem.prop $(prop)" >> $@;)
+
+_footers_ := $(import_oem_prop)
+else
+_footers_ :=
+endif
+
 $(eval $(call build-properties,\
     product,\
     $(INSTALLED_PRODUCT_BUILD_PROP_TARGET),\
     $(_prop_files_),\
     $(_prop_vars_),\
-    $(empty)))
+    $(empty),\
+    $(_footers_)))
 
 # ----------------------------------------------------------------
 # odm/etc/build.prop
@@ -392,6 +406,7 @@
     $(INSTALLED_ODM_BUILD_PROP_TARGET),\
     $(_prop_files),\
     $(_prop_vars_),\
+    $(empty),\
     $(empty)))
 
 # ----------------------------------------------------------------
@@ -401,7 +416,11 @@
 INSTALLED_VENDOR_DLKM_BUILD_PROP_TARGET := $(TARGET_OUT_VENDOR_DLKM)/etc/build.prop
 $(eval $(call build-properties,\
     vendor_dlkm,\
-    $(INSTALLED_VENDOR_DLKM_BUILD_PROP_TARGET)))
+    $(INSTALLED_VENDOR_DLKM_BUILD_PROP_TARGET),\
+    $(empty),\
+    $(empty),\
+    $(empty),\
+    $(empty)))
 
 # ----------------------------------------------------------------
 # odm_dlkm/etc/build.prop
@@ -410,7 +429,11 @@
 INSTALLED_ODM_DLKM_BUILD_PROP_TARGET := $(TARGET_OUT_ODM_DLKM)/etc/build.prop
 $(eval $(call build-properties,\
     odm_dlkm,\
-    $(INSTALLED_ODM_DLKM_BUILD_PROP_TARGET)))
+    $(INSTALLED_ODM_DLKM_BUILD_PROP_TARGET),\
+    $(empty),\
+    $(empty),\
+    $(empty),\
+    $(empty)))
 
 # -----------------------------------------------------------------
 # system_ext/etc/build.prop
@@ -429,6 +452,7 @@
     $(INSTALLED_SYSTEM_EXT_BUILD_PROP_TARGET),\
     $(_prop_files_),\
     $(_prop_vars_),\
+    $(empty),\
     $(empty)))
 
 # ----------------------------------------------------------------
@@ -439,4 +463,8 @@
 INSTALLED_RAMDISK_BUILD_PROP_TARGET := $(TARGET_RAMDISK_OUT)/$(RAMDISK_BUILD_PROP_REL_PATH)
 $(eval $(call build-properties,\
     bootimage,\
-    $(INSTALLED_RAMDISK_BUILD_PROP_TARGET)))
+    $(INSTALLED_RAMDISK_BUILD_PROP_TARGET),\
+    $(empty),\
+    $(empty),\
+    $(empty),\
+    $(empty)))
diff --git a/core/tasks/host_init_verifier.mk b/core/tasks/host_init_verifier.mk
new file mode 100644
index 0000000..bdf996c
--- /dev/null
+++ b/core/tasks/host_init_verifier.mk
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2020 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.
+#
+
+host_init_verifier_output := $(PRODUCT_OUT)/host_init_verifier_output.txt
+
+$(host_init_verifier_output): \
+    $(INSTALLED_SYSTEMIMAGE_TARGET) \
+    $(INSTALLED_SYSTEM_EXTIMAGE_TARGET) \
+    $(INSTALLED_VENDORIMAGE_TARGET) \
+    $(INSTALLED_ODMIMAGE_TARGET) \
+    $(INSTALLED_PRODUCTIMAGE_TARGET) \
+    $(call intermediates-dir-for,ETC,passwd_system)/passwd_system \
+    $(call intermediates-dir-for,ETC,passwd_system_ext)/passwd_system_ext \
+    $(call intermediates-dir-for,ETC,passwd_vendor)/passwd_vendor \
+    $(call intermediates-dir-for,ETC,passwd_odm)/passwd_odm \
+    $(call intermediates-dir-for,ETC,passwd_product)/passwd_product \
+    $(call intermediates-dir-for,ETC,plat_property_contexts)/plat_property_contexts \
+    $(call intermediates-dir-for,ETC,system_ext_property_contexts)/system_ext_property_contexts \
+    $(call intermediates-dir-for,ETC,product_property_contexts)/product_property_contexts \
+    $(call intermediates-dir-for,ETC,vendor_property_contexts)/vendor_property_contexts \
+    $(call intermediates-dir-for,ETC,odm_property_contexts)/odm_property_contexts
+
+# Run host_init_verifier on the partition staging directories.
+$(host_init_verifier_output): $(HOST_INIT_VERIFIER)
+	$(HOST_INIT_VERIFIER) \
+		-p $(call intermediates-dir-for,ETC,passwd_system)/passwd_system \
+		-p $(call intermediates-dir-for,ETC,passwd_system_ext)/passwd_system_ext \
+		-p $(call intermediates-dir-for,ETC,passwd_vendor)/passwd_vendor \
+		-p $(call intermediates-dir-for,ETC,passwd_odm)/passwd_odm \
+		-p $(call intermediates-dir-for,ETC,passwd_product)/passwd_product \
+		--property-contexts=$(call intermediates-dir-for,ETC,plat_property_contexts)/plat_property_contexts \
+		--property-contexts=$(call intermediates-dir-for,ETC,system_ext_property_contexts)/system_ext_property_contexts \
+		--property-contexts=$(call intermediates-dir-for,ETC,product_property_contexts)/product_property_contexts \
+		--property-contexts=$(call intermediates-dir-for,ETC,vendor_property_contexts)/vendor_property_contexts \
+		--property-contexts=$(call intermediates-dir-for,ETC,odm_property_contexts)/odm_property_contexts \
+		--out_system $(PRODUCT_OUT)/$(TARGET_COPY_OUT_SYSTEM) \
+		--out_system_ext $(PRODUCT_OUT)/$(TARGET_COPY_OUT_SYSTEM_EXT) \
+		--out_vendor $(PRODUCT_OUT)/$(TARGET_COPY_OUT_VENDOR) \
+		--out_odm $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ODM) \
+		--out_product $(PRODUCT_OUT)/$(TARGET_COPY_OUT_PRODUCT) \
+		> $@
+
+$(call dist-for-goals,droidcore,$(host_init_verifier_output))
diff --git a/core/tasks/platform_availability_check.mk b/core/tasks/platform_availability_check.mk
index 7ce6b40..1524758 100644
--- a/core/tasks/platform_availability_check.mk
+++ b/core/tasks/platform_availability_check.mk
@@ -17,6 +17,9 @@
 # Check whether there is any module that isn't available for platform
 # is installed to the platform.
 
+# Skip for unbundled builds that don't produce a platform image.
+ifeq (,$(TARGET_BUILD_UNBUNDLED))
+
 # Filter FAKE and NON_INSTALLABLE modules out and then collect those are not
 # available for platform
 _modules_not_available_for_platform := \
@@ -41,7 +44,7 @@
 # Don't error out immediately when ALLOW_MISSING_DEPENDENCIES is set.
 # Instead, add a dependency on a rule that prints the error message.
   define not_available_for_platform_rule
-    not_installable_file := $(patsubst $(OUT_DIR)/%,$(OUT_DIR)/NOT_AVAILABLE_FOR_PLATFORM/%,$(1)))
+    not_installable_file := $(patsubst $(OUT_DIR)/%,$(OUT_DIR)/NOT_AVAILABLE_FOR_PLATFORM/%,$(1))
     $(1): $$(not_installable_file)
     $$(not_installable_file):
 	$(call echo-error,$(2),Module is requested to be installed but is not \
@@ -54,3 +57,5 @@
     $(foreach i,$(filter-out $(HOST_OUT)/%,$(ALL_MODULES.$(m).INSTALLED)),\
       $(eval $(call not_available_for_platform_rule,$(i),$(m)))))
 endif
+
+endif
diff --git a/core/tasks/recovery_snapshot.mk b/core/tasks/recovery_snapshot.mk
new file mode 100644
index 0000000..fea0bb9
--- /dev/null
+++ b/core/tasks/recovery_snapshot.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2020 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.
+
+current_makefile := $(lastword $(MAKEFILE_LIST))
+
+# BOARD_VNDK_VERSION must be set to 'current' in order to generate a recovery snapshot.
+ifeq ($(BOARD_VNDK_VERSION),current)
+
+.PHONY: recovery-snapshot
+recovery-snapshot: $(SOONG_RECOVERY_SNAPSHOT_ZIP)
+
+$(call dist-for-goals, recovery-snapshot, $(SOONG_RECOVERY_SNAPSHOT_ZIP))
+
+else # BOARD_VNDK_VERSION is NOT set to 'current'
+
+.PHONY: recovery-snapshot
+recovery-snapshot: PRIVATE_MAKEFILE := $(current_makefile)
+recovery-snapshot:
+	$(call echo-error,$(PRIVATE_MAKEFILE),\
+		"CANNOT generate Recovery snapshot. BOARD_VNDK_VERSION must be set to 'current'.")
+	exit 1
+
+endif # BOARD_VNDK_VERSION
diff --git a/rbesetup.sh b/rbesetup.sh
index 0182bfd..410ed86 100644
--- a/rbesetup.sh
+++ b/rbesetup.sh
@@ -66,6 +66,7 @@
   unset USE_GOMA
   export USE_RBE="true"
   export RBE_CXX_EXEC_STRATEGY="remote_local_fallback"
+  export RBE_use_unified_cas_ops="true"
   export RBE_JAVAC=1
   export RBE_R8=1
   export RBE_D8=1
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 3d3eb2e..414e032 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -82,6 +82,9 @@
 TARGET_NO_KERNEL := false
 BOARD_USES_GENERIC_KERNEL_IMAGE := true
 BOARD_KERNEL_MODULE_INTERFACE_VERSIONS := 5.4-android12-0
+# Copy boot image in $OUT to target files. This is defined for targets where
+# the installed GKI APEXes are built from source.
+BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES := true
 
 # No vendor_boot
 BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT :=
diff --git a/target/board/generic_arm64/README.txt b/target/board/generic_arm64/README.txt
index 21c71d7..8711a14 100644
--- a/target/board/generic_arm64/README.txt
+++ b/target/board/generic_arm64/README.txt
@@ -1,5 +1,7 @@
 The "generic_arm64" product defines a non-hardware-specific arm64 target
-without a kernel or bootloader.
+without a bootloader.
+
+It is also the target to build the generic kernel image (GKI).
 
 It is not a product "base class"; no other products inherit
 from it or use it in any way.
diff --git a/target/board/generic_arm64/sepolicy/OWNERS b/target/board/generic_arm64/sepolicy/OWNERS
index ff29677..6dc2b86 100644
--- a/target/board/generic_arm64/sepolicy/OWNERS
+++ b/target/board/generic_arm64/sepolicy/OWNERS
@@ -1,8 +1 @@
-alanstokes@google.com
-bowgotsai@google.com
-jbires@google.com
-jeffv@google.com
-jgalenson@google.com
-sspatil@google.com
-tomcherry@google.com
-trong@google.com
+include platform/system/sepolicy:/OWNERS
diff --git a/target/board/mainline_arm64/sepolicy/OWNERS b/target/board/mainline_arm64/sepolicy/OWNERS
index ff29677..6dc2b86 100644
--- a/target/board/mainline_arm64/sepolicy/OWNERS
+++ b/target/board/mainline_arm64/sepolicy/OWNERS
@@ -1,8 +1 @@
-alanstokes@google.com
-bowgotsai@google.com
-jbires@google.com
-jeffv@google.com
-jgalenson@google.com
-sspatil@google.com
-tomcherry@google.com
-trong@google.com
+include platform/system/sepolicy:/OWNERS
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 4607edb..1b4c8d9 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -323,45 +323,12 @@
     tz_version_host \
     tz_version_host_tzdata_apex \
 
-ifeq ($(ART_APEX_JARS),)
-$(error ART_APEX_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
-endif
-
-# The order matters for runtime class lookup performance.
-PRODUCT_BOOT_JARS := \
-    $(ART_APEX_JARS) \
-    framework-minus-apex \
-    ext \
-    com.android.i18n:core-icu4j \
-    telephony-common \
-    voip-common \
-    ims-common
-
-PRODUCT_UPDATABLE_BOOT_JARS := \
-    com.android.conscrypt:conscrypt \
-    com.android.media:updatable-media \
-    com.android.mediaprovider:framework-mediaprovider \
-    com.android.os.statsd:framework-statsd \
-    com.android.permission:framework-permission \
-    com.android.sdkext:framework-sdkextensions \
-    com.android.wifi:framework-wifi \
-    com.android.tethering:framework-tethering
 
 PRODUCT_COPY_FILES += \
     system/core/rootdir/init.usb.rc:system/etc/init/hw/init.usb.rc \
     system/core/rootdir/init.usb.configfs.rc:system/etc/init/hw/init.usb.configfs.rc \
     system/core/rootdir/etc/hosts:system/etc/hosts
 
-# Add the compatibility library that is needed when android.test.base
-# is removed from the bootclasspath.
-# 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
-PRODUCT_BOOT_JARS += android.test.base
-endif
-
 PRODUCT_COPY_FILES += system/core/rootdir/init.zygote32.rc:system/etc/init/hw/init.zygote32.rc
 PRODUCT_SYSTEM_PROPERTIES += ro.zygote?=zygote32
 
@@ -374,6 +341,7 @@
 PRODUCT_PACKAGES_DEBUG := \
     adb_keys \
     arping \
+    dmuserd \
     gdbserver \
     idlcli \
     init-debug.rc \
@@ -421,4 +389,5 @@
 PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
     frameworks/base/config/dirty-image-objects:system/etc/dirty-image-objects)
 
+$(call inherit-product, $(SRC_TARGET_DIR)/product/bootclasspath.mk)
 $(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
diff --git a/target/product/bootclasspath.mk b/target/product/bootclasspath.mk
new file mode 100644
index 0000000..60dd071
--- /dev/null
+++ b/target/product/bootclasspath.mk
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2020 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.
+#
+
+ifeq ($(ART_APEX_JARS),)
+  $(error ART_APEX_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
+endif
+
+# The order matters for runtime class lookup performance.
+PRODUCT_BOOT_JARS := \
+    $(ART_APEX_JARS) \
+    framework-minus-apex \
+    ext \
+    com.android.i18n:core-icu4j \
+    telephony-common \
+    voip-common \
+    ims-common
+
+PRODUCT_UPDATABLE_BOOT_JARS := \
+    com.android.conscrypt:conscrypt \
+    com.android.media:updatable-media \
+    com.android.mediaprovider:framework-mediaprovider \
+    com.android.os.statsd:framework-statsd \
+    com.android.permission:framework-permission \
+    com.android.sdkext:framework-sdkextensions \
+    com.android.wifi:framework-wifi \
+    com.android.tethering:framework-tethering
+
+# Add the compatibility library that is needed when android.test.base
+# is removed from the bootclasspath.
+# 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
+  PRODUCT_BOOT_JARS += android.test.base
+endif
diff --git a/target/product/cfi-common.mk b/target/product/cfi-common.mk
index 42edd92..623a9a8 100644
--- a/target/product/cfi-common.mk
+++ b/target/product/cfi-common.mk
@@ -17,6 +17,7 @@
 # This is a set of common components to enable CFI for (across
 # compatible product configs)
 PRODUCT_CFI_INCLUDE_PATHS :=  \
+    device/generic/goldfish/wifi/wpa_supplicant_8_lib \
     device/google/cuttlefish/guest/libs/wpa_supplicant_8_lib \
     device/google/wahoo/wifi_offload \
     external/tinyxml2 \
@@ -28,7 +29,8 @@
     hardware/broadcom/wlan/bcmdhd/wpa_supplicant_8_lib \
     hardware/interfaces/nfc \
     hardware/qcom/wlan/qcwcn/wpa_supplicant_8_lib \
-    harware/interfaces/keymaster \
+    hardware/interfaces/keymaster \
+    hardware/interfaces/keymint \
     system/bt \
     system/chre \
     system/core/libnetutils \
diff --git a/target/product/generic_x86.mk b/target/product/generic_x86.mk
index 0274b5b..eeb8216 100644
--- a/target/product/generic_x86.mk
+++ b/target/product/generic_x86.mk
@@ -17,7 +17,7 @@
 # This is a generic phone product that isn't specialized for a specific device.
 # It includes the base Android platform.
 
-include $(SRC_TARGET_DIR)/product/generic.mk
+$(call inherit-product, $(SRC_TARGET_DIR)/product/generic.mk)
 
 # Overrides
 PRODUCT_BRAND := generic_x86
diff --git a/target/product/gsi/current.txt b/target/product/gsi/current.txt
index f057958..9c08e5e 100644
--- a/target/product/gsi/current.txt
+++ b/target/product/gsi/current.txt
@@ -43,6 +43,7 @@
 VNDK-SP: libc++.so
 VNDK-SP: libcompiler_rt.so
 VNDK-SP: libcutils.so
+VNDK-SP: libdmabufheap.so
 VNDK-SP: libgralloctypes.so
 VNDK-SP: libhardware.so
 VNDK-SP: libhidlbase.so
@@ -68,6 +69,7 @@
 VNDK-core: android.hardware.graphics.bufferqueue@2.0.so
 VNDK-core: android.hardware.identity-V2-ndk_platform.so
 VNDK-core: android.hardware.keymaster-V2-ndk_platform.so
+VNDK-core: android.hardware.keymint-V1-ndk_platform.so
 VNDK-core: android.hardware.light-V1-ndk_platform.so
 VNDK-core: android.hardware.media.bufferpool@2.0.so
 VNDK-core: android.hardware.media.omx@1.0.so
diff --git a/target/product/sdk_phone_x86.mk b/target/product/sdk_phone_x86.mk
index 63671dc..9096ff3 100644
--- a/target/product/sdk_phone_x86.mk
+++ b/target/product/sdk_phone_x86.mk
@@ -50,8 +50,8 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/board/emulator_x86/device.mk)
 
 # Define the host tools and libs that are parts of the SDK.
--include sdk/build/product_sdk.mk
--include development/build/product_sdk.mk
+$(call inherit-product-if-exists, sdk/build/product_sdk.mk)
+$(call inherit-product-if-exists, development/build/product_sdk.mk)
 
 # Overrides
 PRODUCT_BRAND := Android
diff --git a/target/product/sdk_phone_x86_64.mk b/target/product/sdk_phone_x86_64.mk
index c5a6245..161043b 100644
--- a/target/product/sdk_phone_x86_64.mk
+++ b/target/product/sdk_phone_x86_64.mk
@@ -51,8 +51,8 @@
 $(call inherit-product, $(SRC_TARGET_DIR)/board/emulator_x86_64/device.mk)
 
 # Define the host tools and libs that are parts of the SDK.
--include sdk/build/product_sdk.mk
--include development/build/product_sdk.mk
+$(call inherit-product-if-exists, sdk/build/product_sdk.mk)
+$(call inherit-product-if-exists, development/build/product_sdk.mk)
 
 # Overrides
 PRODUCT_BRAND := Android
diff --git a/target/product/virtual_ab_ota.mk b/target/product/virtual_ab_ota.mk
new file mode 120000
index 0000000..16f7329
--- /dev/null
+++ b/target/product/virtual_ab_ota.mk
@@ -0,0 +1 @@
+virtual_ab_ota/launch.mk
\ No newline at end of file
diff --git a/target/product/virtual_ab_ota/README.md b/target/product/virtual_ab_ota/README.md
new file mode 100644
index 0000000..c1d0d7d
--- /dev/null
+++ b/target/product/virtual_ab_ota/README.md
@@ -0,0 +1,14 @@
+# Virtual A/B makefiles
+
+Devices that uses Virtual A/B must inherit from one of the makefiles in this directory.
+
+## Structure
+
+```
+launch.mk
+  |- retrofit.mk
+  |- plus_non_ab.mk
+  |- compression.mk
+
+compression_retrofit.mk
+```
diff --git a/target/product/virtual_ab_ota_retrofit_compression.mk b/target/product/virtual_ab_ota/compression.mk
similarity index 91%
rename from target/product/virtual_ab_ota_retrofit_compression.mk
rename to target/product/virtual_ab_ota/compression.mk
index 8059f75..2251187 100644
--- a/target/product/virtual_ab_ota_retrofit_compression.mk
+++ b/target/product/virtual_ab_ota/compression.mk
@@ -14,9 +14,8 @@
 # limitations under the License.
 #
 
-$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota/launch.mk)
 
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.enabled=true
 
-PRODUCT_PACKAGES += snapuserd_ramdisk
-
+PRODUCT_PACKAGES += snapuserd.vendor_ramdisk snapuserd
diff --git a/target/product/virtual_ab_ota_retrofit_compression.mk b/target/product/virtual_ab_ota/compression_retrofit.mk
similarity index 66%
copy from target/product/virtual_ab_ota_retrofit_compression.mk
copy to target/product/virtual_ab_ota/compression_retrofit.mk
index 8059f75..b34e3f1 100644
--- a/target/product/virtual_ab_ota_retrofit_compression.mk
+++ b/target/product/virtual_ab_ota/compression_retrofit.mk
@@ -14,9 +14,11 @@
 # limitations under the License.
 #
 
-$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
-
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.enabled=true
 
-PRODUCT_PACKAGES += snapuserd_ramdisk
-
+# For devices that are not GKI-capable (eg do not have vendor_boot),
+# snapuserd.ramdisk is included rather than snapuserd.vendor_ramdisk.
+# When using virtual_ab_ota_compression_retrofit.mk, either
+# virtual_ab_ota.mk or virtual_ab_ota_retrofit.mk must be inherited
+# as well.
+PRODUCT_PACKAGES += snapuserd.ramdisk snapuserd
diff --git a/target/product/virtual_ab_ota.mk b/target/product/virtual_ab_ota/launch.mk
similarity index 100%
rename from target/product/virtual_ab_ota.mk
rename to target/product/virtual_ab_ota/launch.mk
diff --git a/target/product/virtual_ab_ota_plus_non_ab.mk b/target/product/virtual_ab_ota/plus_non_ab.mk
similarity index 97%
rename from target/product/virtual_ab_ota_plus_non_ab.mk
rename to target/product/virtual_ab_ota/plus_non_ab.mk
index 99a10ed..820fa1e 100644
--- a/target/product/virtual_ab_ota_plus_non_ab.mk
+++ b/target/product/virtual_ab_ota/plus_non_ab.mk
@@ -14,7 +14,7 @@
 # limitations under the License.
 #
 
-$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota/launch.mk)
 
 PRODUCT_OTA_FORCE_NON_AB_PACKAGE := true
 
diff --git a/target/product/virtual_ab_ota_retrofit.mk b/target/product/virtual_ab_ota/retrofit.mk
similarity index 97%
rename from target/product/virtual_ab_ota_retrofit.mk
rename to target/product/virtual_ab_ota/retrofit.mk
index 3416a4f..93b42b7 100644
--- a/target/product/virtual_ab_ota_retrofit.mk
+++ b/target/product/virtual_ab_ota/retrofit.mk
@@ -14,7 +14,7 @@
 # limitations under the License.
 #
 
-$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota/launch.mk)
 
 PRODUCT_VIRTUAL_AB_OTA_RETROFIT := true
 
diff --git a/target/product/virtual_ab_ota_compression.mk b/target/product/virtual_ab_ota_compression.mk
deleted file mode 100644
index eef3c33..0000000
--- a/target/product/virtual_ab_ota_compression.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Copyright (C) 2020 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.
-#
-
-$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
-
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.enabled=true
-
-PRODUCT_PACKAGES += snapuserd_ramdisk snapuserd
diff --git a/target/product/virtual_ab_ota_plus_non_ab.mk b/target/product/virtual_ab_ota_plus_non_ab.mk
new file mode 120000
index 0000000..4979957
--- /dev/null
+++ b/target/product/virtual_ab_ota_plus_non_ab.mk
@@ -0,0 +1 @@
+virtual_ab_ota/plus_non_ab.mk
\ No newline at end of file
diff --git a/target/product/virtual_ab_ota_retrofit.mk b/target/product/virtual_ab_ota_retrofit.mk
new file mode 120000
index 0000000..1e16ca8
--- /dev/null
+++ b/target/product/virtual_ab_ota_retrofit.mk
@@ -0,0 +1 @@
+virtual_ab_ota/retrofit.mk
\ No newline at end of file
diff --git a/tools/fs_config/fs_config_generator.py b/tools/fs_config/fs_config_generator.py
index 940a398..098fde6 100755
--- a/tools/fs_config/fs_config_generator.py
+++ b/tools/fs_config/fs_config_generator.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
 """Generates config files for Android file system properties.
 
 This script is used for generating configuration files for configuring
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 11fb584..cafc2bb 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -435,6 +435,7 @@
     ],
     required: [
         "checkvintf",
+        "host_init_verifier",
     ],
     target: {
         darwin: {
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index eb041ec..d836d65 100644
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -959,8 +959,9 @@
           if item not in vbmeta_vendor.split()]
       vbmeta_partitions.append("vbmeta_vendor")
 
-    banner("vbmeta")
-    AddVBMeta(output_zip, partitions, "vbmeta", vbmeta_partitions)
+    if OPTIONS.info_dict.get("avb_building_vbmeta_image") == "true":
+      banner("vbmeta")
+      AddVBMeta(output_zip, partitions, "vbmeta", vbmeta_partitions)
 
   if OPTIONS.info_dict.get("use_dynamic_partitions") == "true":
     banner("super_empty")
diff --git a/tools/releasetools/check_target_files_vintf.py b/tools/releasetools/check_target_files_vintf.py
index 3c2406c..a2ddfe7 100755
--- a/tools/releasetools/check_target_files_vintf.py
+++ b/tools/releasetools/check_target_files_vintf.py
@@ -100,10 +100,7 @@
                 'PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS is not set')
     return []
 
-  with open(version_path) as f:
-    version = f.read().strip()
-
-  return ['--kernel', '{}:{}'.format(version, config_path)]
+  return ['--kernel', '{}:{}'.format(version_path, config_path)]
 
 
 def CheckVintfFromExtractedTargetFiles(input_tmp, info_dict=None):
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 0683678..bae0b20 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -217,6 +217,25 @@
 def SetHostToolLocation(tool_name, location):
   OPTIONS.host_tools[tool_name] = location
 
+def FindHostToolPath(tool_name):
+  """Finds the path to the host tool.
+
+  Args:
+    tool_name: name of the tool to find
+  Returns:
+    path to the tool if found under either one of the host_tools map or under
+    the same directory as this binary is located at. If not found, tool_name
+    is returned.
+  """
+  if tool_name in OPTIONS.host_tools:
+    return OPTIONS.host_tools[tool_name]
+
+  my_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
+  tool_path = os.path.join(my_dir, tool_name)
+  if os.path.exists(tool_path):
+    return tool_path
+
+  return tool_name
 
 def Run(args, verbose=None, **kwargs):
   """Creates and returns a subprocess.Popen object.
@@ -240,12 +259,10 @@
   if 'universal_newlines' not in kwargs:
     kwargs['universal_newlines'] = True
 
-  # If explicitly set host tool location before, use that location to avoid
-  # PATH violation. Make a copy of args in case client relies on the content
-  # of args later.
-  if args and args[0] in OPTIONS.host_tools:
+  if args:
+    # Make a copy of args in case client relies on the content of args later.
     args = args[:]
-    args[0] = OPTIONS.host_tools[args[0]]
+    args[0] = FindHostToolPath(args[0])
 
   # Don't log any if caller explicitly says so.
   if verbose:
@@ -1085,6 +1102,29 @@
   return merged_dict
 
 
+def PartitionMapFromTargetFiles(target_files_dir):
+  """Builds a map from partition -> path within an extracted target files directory."""
+  # Keep possible_subdirs in sync with build/make/core/board_config.mk.
+  possible_subdirs = {
+      "system": ["SYSTEM"],
+      "vendor": ["VENDOR", "SYSTEM/vendor"],
+      "product": ["PRODUCT", "SYSTEM/product"],
+      "system_ext": ["SYSTEM_EXT", "SYSTEM/system_ext"],
+      "odm": ["ODM", "VENDOR/odm", "SYSTEM/vendor/odm"],
+      "vendor_dlkm": [
+          "VENDOR_DLKM", "VENDOR/vendor_dlkm", "SYSTEM/vendor/vendor_dlkm"
+      ],
+      "odm_dlkm": ["ODM_DLKM", "VENDOR/odm_dlkm", "SYSTEM/vendor/odm_dlkm"],
+  }
+  partition_map = {}
+  for partition, subdirs in possible_subdirs.items():
+    for subdir in subdirs:
+      if os.path.exists(os.path.join(target_files_dir, subdir)):
+        partition_map[partition] = subdir
+        break
+  return partition_map
+
+
 def SharedUidPartitionViolations(uid_dict, partition_groups):
   """Checks for APK sharedUserIds that cross partition group boundaries.
 
@@ -1117,6 +1157,36 @@
   return errors
 
 
+def RunHostInitVerifier(product_out, partition_map):
+  """Runs host_init_verifier on the init rc files within partitions.
+
+  host_init_verifier searches the etc/init path within each partition.
+
+  Args:
+    product_out: PRODUCT_OUT directory, containing partition directories.
+    partition_map: A map of partition name -> relative path within product_out.
+  """
+  allowed_partitions = ("system", "system_ext", "product", "vendor", "odm")
+  cmd = ["host_init_verifier"]
+  for partition, path in partition_map.items():
+    if partition not in allowed_partitions:
+      raise ExternalError("Unable to call host_init_verifier for partition %s" %
+                          partition)
+    cmd.extend(["--out_%s" % partition, os.path.join(product_out, path)])
+    # Add --property-contexts if the file exists on the partition.
+    property_contexts = "%s_property_contexts" % (
+        "plat" if partition == "system" else partition)
+    property_contexts_path = os.path.join(product_out, path, "etc", "selinux",
+                                          property_contexts)
+    if os.path.exists(property_contexts_path):
+      cmd.append("--property-contexts=%s" % property_contexts_path)
+    # Add the passwd file if the file exists on the partition.
+    passwd_path = os.path.join(product_out, path, "etc", "passwd")
+    if os.path.exists(passwd_path):
+      cmd.extend(["-p", passwd_path])
+  return RunAndCheckOutput(cmd)
+
+
 def AppendAVBSigningArgs(cmd, partition):
   """Append signing arguments for avbtool."""
   # e.g., "--key path/to/signing_key --algorithm SHA256_RSA4096"
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index ba9e740..9360d7b 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -456,6 +456,12 @@
     # false in the partial builds to prevent duplicate building of super.img.
     merged_dict['build_super_partition'] = 'true'
 
+  # If AVB is enabled then ensure that we build vbmeta.img.
+  # Partial builds with AVB enabled may set PRODUCT_BUILD_VBMETA_IMAGE=false to
+  # skip building an incomplete vbmeta.img.
+  if merged_dict.get('avb_enable') == 'true':
+    merged_dict['avb_building_vbmeta_image'] = 'true'
+
   # Replace <image>_selinux_fc values with framework or vendor file_contexts.bin
   # depending on which dictionary the key came from.
   # Only the file basename is required because all selinux_fc properties are
@@ -945,18 +951,15 @@
   if not check_target_files_vintf.CheckVintf(output_target_files_temp_dir):
     raise RuntimeError('Incompatible VINTF metadata')
 
+  partition_map = common.PartitionMapFromTargetFiles(
+      output_target_files_temp_dir)
+
   # Generate and check for cross-partition violations of sharedUserId
   # values in APKs. This requires the input target-files packages to contain
   # *.apk files.
   shareduid_violation_modules = os.path.join(
       output_target_files_temp_dir, 'META', 'shareduid_violation_modules.json')
   with open(shareduid_violation_modules, 'w') as f:
-    framework_partitions = item_list_to_partition_set(framework_item_list)
-    vendor_partitions = item_list_to_partition_set(vendor_item_list)
-
-    partition_map = {}
-    for partition in (framework_partitions.union(vendor_partitions)):
-      partition_map[partition.lower()] = partition.upper()
     violation = find_shareduid_violation.FindShareduidViolation(
         output_target_files_temp_dir, partition_map)
 
@@ -964,6 +967,8 @@
     f.write(violation)
 
     # Check for violations across the input builds' partition groups.
+    framework_partitions = item_list_to_partition_set(framework_item_list)
+    vendor_partitions = item_list_to_partition_set(vendor_item_list)
     shareduid_errors = common.SharedUidPartitionViolations(
         json.loads(violation), [framework_partitions, vendor_partitions])
     if shareduid_errors:
@@ -972,6 +977,17 @@
       raise ValueError('sharedUserId APK error. See %s' %
                        shareduid_violation_modules)
 
+  # Run host_init_verifier on the combined init rc files.
+  filtered_partitions = {
+      partition: path
+      for partition, path in partition_map.items()
+      # host_init_verifier checks only the following partitions:
+      if partition in ['system', 'system_ext', 'product', 'vendor', 'odm']
+  }
+  common.RunHostInitVerifier(
+      product_out=output_target_files_temp_dir,
+      partition_map=filtered_partitions)
+
   generate_images(output_target_files_temp_dir, rebuild_recovery)
 
   generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 869b713..6b82d32 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -217,10 +217,13 @@
 
 import logging
 import multiprocessing
+import os
 import os.path
+import re
 import shlex
 import shutil
 import struct
+import subprocess
 import sys
 import zipfile
 
@@ -266,6 +269,7 @@
 OPTIONS.skip_postinstall = False
 OPTIONS.skip_compatibility_check = False
 OPTIONS.disable_fec_computation = False
+OPTIONS.disable_verity_computation = False
 OPTIONS.partial = None
 OPTIONS.custom_images = {}
 
@@ -399,6 +403,8 @@
       cmd.extend(["--source_image", source_file])
       if OPTIONS.disable_fec_computation:
         cmd.extend(["--disable_fec_computation", "true"])
+      if OPTIONS.disable_verity_computation:
+        cmd.extend(["--disable_verity_computation", "true"])
     cmd.extend(additional_args)
     self._Run(cmd)
 
@@ -968,6 +974,50 @@
     ",".join([key + ":" + val for (key, val) in partition_timestamps.items()])
     ]
 
+def IsSparseImage(filepath):
+  with open(filepath, 'rb') as fp:
+    # Magic for android sparse image format
+    # https://source.android.com/devices/bootloader/images
+    return fp.read(4) == b'\x3A\xFF\x26\xED'
+
+def SupportsMainlineGkiUpdates(target_file):
+  """Return True if the build supports MainlineGKIUpdates.
+
+  This function scans the product.img file in IMAGES/ directory for
+  pattern |*/apex/com.android.gki.*.apex|. If there are files
+  matching this pattern, conclude that build supports mainline
+  GKI and return True
+
+  Args:
+    target_file: Path to a target_file.zip, or an extracted directory
+  Return:
+    True if thisb uild supports Mainline GKI Updates.
+  """
+  if target_file is None:
+    return False
+  if os.path.isfile(target_file):
+    target_file = common.UnzipTemp(target_file, ["IMAGES/product.img"])
+  if not os.path.isdir(target_file):
+    assert os.path.isdir(target_file), \
+        "{} must be a path to zip archive or dir containing extracted"\
+        " target_files".format(target_file)
+  image_file = os.path.join(target_file, "IMAGES", "product.img")
+
+  if not os.path.isfile(image_file):
+    return False
+
+  if IsSparseImage(image_file):
+    # Unsparse the image
+    tmp_img = common.MakeTempFile(suffix=".img")
+    subprocess.check_output(["simg2img", image_file, tmp_img])
+    image_file = tmp_img
+
+  cmd = ["debugfs_static", "-R", "ls -p /apex", image_file]
+  output = subprocess.check_output(cmd).decode()
+
+  pattern = re.compile(r"com\.android\.gki\..*\.apex")
+  return pattern.search(output) is not None
+
 def GenerateAbOtaPackage(target_file, output_file, source_file=None):
   """Generates an Android OTA package that has A/B update payload."""
   # Stage the output zip package for package signing.
@@ -991,6 +1041,7 @@
       # TODO(zhangkelvin) Remove this once FEC on VABC is supported
       logger.info("Virtual AB Compression enabled, disabling FEC")
       OPTIONS.disable_fec_computation = True
+      OPTIONS.disable_verity_computation = True
   else:
     assert "ab_partitions" in OPTIONS.info_dict, \
         "META/ab_partitions.txt is required for ab_update."
@@ -1039,6 +1090,10 @@
 
   additional_args += ["--max_timestamp", max_timestamp]
 
+  if SupportsMainlineGkiUpdates(source_file):
+    logger.warn("Detected build with mainline GKI, include full boot image.")
+    additional_args.extend(["--full_boot", "true"])
+
   payload.Generate(
       target_file,
       source_file,
@@ -1060,15 +1115,9 @@
     secondary_target_file = GetTargetFilesZipForSecondaryImages(
         target_file, OPTIONS.skip_postinstall)
     secondary_payload = Payload(secondary=True)
-    assert not OPTIONS.downgrade
-    partition_timestamps_flags = GeneratePartitionTimestampFlags(
-      [part
-       for part in metadata.postcondition.partition_state
-       if part.partition_name not in SECONDARY_PAYLOAD_SKIPPED_IMAGES]
-    )
     secondary_payload.Generate(secondary_target_file,
                                additional_args=["--max_timestamp",
-                               max_timestamp]+partition_timestamps_flags)
+                               max_timestamp])
     secondary_payload.Sign(payload_signer)
     secondary_payload.WriteToZip(output_zip)
 
@@ -1183,6 +1232,8 @@
       OPTIONS.output_metadata_path = a
     elif o == "--disable_fec_computation":
       OPTIONS.disable_fec_computation = True
+    elif o == "--disable_verity_computation":
+      OPTIONS.disable_verity_computation = True
     elif o == "--force_non_ab":
       OPTIONS.force_non_ab = True
     elif o == "--boot_variable_file":
@@ -1231,6 +1282,7 @@
                                  "skip_compatibility_check",
                                  "output_metadata_path=",
                                  "disable_fec_computation",
+                                 "disable_verity_computation",
                                  "force_non_ab",
                                  "boot_variable_file=",
                                  "partial=",
@@ -1254,11 +1306,6 @@
     OPTIONS.info_dict = common.LoadInfoDict(OPTIONS.extracted_input)
   else:
     OPTIONS.info_dict = ParseInfoDict(args[0])
-  if OPTIONS.partial:
-    OPTIONS.info_dict['ab_partitions'] = \
-      list(
-        set(OPTIONS.info_dict['ab_partitions']) & set(OPTIONS.partial)
-        )
 
   if OPTIONS.downgrade:
     # We should only allow downgrading incrementals (as opposed to full).
@@ -1284,6 +1331,17 @@
     logger.info("--- source info ---")
     common.DumpInfoDict(OPTIONS.source_info_dict)
 
+  if OPTIONS.partial:
+    OPTIONS.info_dict['ab_partitions'] = \
+      list(
+        set(OPTIONS.info_dict['ab_partitions']) & set(OPTIONS.partial)
+        )
+    if OPTIONS.source_info_dict:
+      OPTIONS.source_info_dict['ab_partitions'] = \
+        list(
+          set(OPTIONS.source_info_dict['ab_partitions']) & set(OPTIONS.partial)
+          )
+
   # Load OEM dicts if provided.
   OPTIONS.oem_dicts = _LoadOemDicts(OPTIONS.oem_source)
 
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index 0b368f9..ecd759c 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -996,6 +996,27 @@
         },
         sparse_image.file_map)
 
+  def test_PartitionMapFromTargetFiles(self):
+    target_files_dir = common.MakeTempDir()
+    os.makedirs(os.path.join(target_files_dir, 'SYSTEM'))
+    os.makedirs(os.path.join(target_files_dir, 'SYSTEM', 'vendor'))
+    os.makedirs(os.path.join(target_files_dir, 'PRODUCT'))
+    os.makedirs(os.path.join(target_files_dir, 'SYSTEM', 'product'))
+    os.makedirs(os.path.join(target_files_dir, 'SYSTEM', 'vendor', 'odm'))
+    os.makedirs(os.path.join(target_files_dir, 'VENDOR_DLKM'))
+    partition_map = common.PartitionMapFromTargetFiles(target_files_dir)
+    self.assertDictEqual(
+        partition_map,
+        {
+            'system': 'SYSTEM',
+            'vendor': 'SYSTEM/vendor',
+            # Prefer PRODUCT over SYSTEM/product
+            'product': 'PRODUCT',
+            'odm': 'SYSTEM/vendor/odm',
+            'vendor_dlkm': 'VENDOR_DLKM',
+            # No system_ext or odm_dlkm
+        })
+
   def test_SharedUidPartitionViolations(self):
     uid_dict = {
         'android.uid.phone': {
diff --git a/tools/warn/html_writer.py b/tools/warn/html_writer.py
index b8d3fe6..026a6d0 100644
--- a/tools/warn/html_writer.py
+++ b/tools/warn/html_writer.py
@@ -359,6 +359,25 @@
   csvwriter.writerow([total, '', 'All warnings'])
 
 
+def dump_csv_with_description(csvwriter, warning_records, warning_messages,
+                              warn_patterns, project_names):
+  """Outputs all the warning messages by project."""
+  csv_output = []
+  for record in warning_records:
+    project_name = project_names[record[1]]
+    pattern = warn_patterns[record[0]]
+    severity = pattern['severity'].header
+    category = pattern['category']
+    description = pattern['description']
+    warning = warning_messages[record[2]]
+    csv_output.append([project_name, severity,
+                       category, description,
+                       warning])
+  csv_output = sorted(csv_output)
+  for output in csv_output:
+    csvwriter.writerow(output)
+
+
 # Return s with escaped backslash and quotation characters.
 def escape_string(s):
   return s.replace('\\', '\\\\').replace('"', '\\"')
@@ -666,6 +685,12 @@
     with open(flags.csvpath, 'w') as f:
       dump_csv(csv.writer(f, lineterminator='\n'), warn_patterns)
 
+  if flags.csvwithdescription:
+    with open(flags.csvwithdescription, 'w') as f:
+      dump_csv_with_description(csv.writer(f, lineterminator='\n'),
+                                warning_records, warning_messages,
+                                warn_patterns, project_names)
+
   if flags.gencsv:
     dump_csv(csv.writer(sys.stdout, lineterminator='\n'), warn_patterns)
   else:
diff --git a/tools/warn/warn_common.py b/tools/warn/warn_common.py
index 68ed995..b2dd8ab 100755
--- a/tools/warn/warn_common.py
+++ b/tools/warn/warn_common.py
@@ -77,6 +77,9 @@
                       help='Save CSV warning file to the passed path')
   parser.add_argument('--gencsv', action='store_true',
                       help='Generate CSV file with number of various warnings')
+  parser.add_argument('--csvwithdescription', default='',
+                      help="""Save CSV warning file to the passed path this csv
+                            will contain all the warning descriptions""")
   parser.add_argument('--byproject', action='store_true',
                       help='Separate warnings in HTML output by project names')
   parser.add_argument('--url', default='',
diff --git a/tools/zipalign/Android.bp b/tools/zipalign/Android.bp
index d88ee74..135cd76 100644
--- a/tools/zipalign/Android.bp
+++ b/tools/zipalign/Android.bp
@@ -63,6 +63,8 @@
         "libgmock",
     ],
     data: [
+         "tests/data/diffOrders.zip",
+         "tests/data/holes.zip",
          "tests/data/unaligned.zip",
     ],
     defaults: ["zipalign_defaults"],
diff --git a/tools/zipalign/ZipAlign.cpp b/tools/zipalign/ZipAlign.cpp
index 1851ac5..08f67ff 100644
--- a/tools/zipalign/ZipAlign.cpp
+++ b/tools/zipalign/ZipAlign.cpp
@@ -47,7 +47,6 @@
 {
     int numEntries = pZin->getNumEntries();
     ZipEntry* pEntry;
-    int bias = 0;
     status_t status;
 
     for (int i = 0; i < numEntries; i++) {
@@ -68,30 +67,20 @@
 
             if (zopfli) {
                 status = pZout->addRecompress(pZin, pEntry, &pNewEntry);
-                bias += pNewEntry->getCompressedLen() - pEntry->getCompressedLen();
             } else {
                 status = pZout->add(pZin, pEntry, padding, &pNewEntry);
             }
         } else {
             const int alignTo = getAlignment(pageAlignSharedLibs, alignment, pEntry);
 
-            /*
-             * Copy the entry, adjusting as required.  We assume that the
-             * file position in the new file will be equal to the file
-             * position in the original.
-             */
-            off_t newOffset = pEntry->getFileOffset() + bias;
-            padding = (alignTo - (newOffset % alignTo)) % alignTo;
-
             //printf("--- %s: orig at %ld(+%d) len=%ld, adding pad=%d\n",
             //    pEntry->getFileName(), (long) pEntry->getFileOffset(),
             //    bias, (long) pEntry->getUncompressedLen(), padding);
-            status = pZout->add(pZin, pEntry, padding, &pNewEntry);
+            status = pZout->add(pZin, pEntry, alignTo, &pNewEntry);
         }
 
         if (status != OK)
             return 1;
-        bias += padding;
         //printf(" added '%s' at %ld (pad=%d)\n",
         //    pNewEntry->getFileName(), (long) pNewEntry->getFileOffset(),
         //    padding);
diff --git a/tools/zipalign/ZipFile.cpp b/tools/zipalign/ZipFile.cpp
index 29d1bc6..9938a06 100644
--- a/tools/zipalign/ZipFile.cpp
+++ b/tools/zipalign/ZipFile.cpp
@@ -503,6 +503,32 @@
 }
 
 /*
+ * Based on the current position in the output zip, assess where the entry
+ * payload will end up if written as-is. If alignment is not satisfactory,
+ * add some padding in the extra field.
+ *
+ */
+status_t ZipFile::alignEntry(android::ZipEntry* pEntry, uint32_t alignTo){
+    if (alignTo == 0 || alignTo == 1)
+        return OK;
+
+    // Calculate where the entry payload offset will end up if we were to write
+    // it as-is.
+    uint64_t expectedPayloadOffset = ftell(mZipFp) +
+        android::ZipEntry::LocalFileHeader::kLFHLen +
+        pEntry->mLFH.mFileNameLength +
+        pEntry->mLFH.mExtraFieldLength;
+
+    // If the alignment is not what was requested, add some padding in the extra
+    // so the payload ends up where is requested.
+    uint64_t alignDiff = alignTo - (expectedPayloadOffset % alignTo);
+    if (alignDiff == 0)
+        return OK;
+
+    return pEntry->addPadding(alignDiff);
+}
+
+/*
  * Add an entry by copying it from another zip file.  If "padding" is
  * nonzero, the specified number of bytes will be added to the "extra"
  * field in the header.
@@ -510,7 +536,7 @@
  * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
  */
 status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
-    int padding, ZipEntry** ppEntry)
+    int alignTo, ZipEntry** ppEntry)
 {
     ZipEntry* pEntry = NULL;
     status_t result;
@@ -537,11 +563,10 @@
     result = pEntry->initFromExternal(pSourceEntry);
     if (result != OK)
         goto bail;
-    if (padding != 0) {
-        result = pEntry->addPadding(padding);
-        if (result != OK)
-            goto bail;
-    }
+
+    result = alignEntry(pEntry, alignTo);
+    if (result != OK)
+      goto bail;
 
     /*
      * From here on out, failures are more interesting.
diff --git a/tools/zipalign/ZipFile.h b/tools/zipalign/ZipFile.h
index 11d20c5..854f981 100644
--- a/tools/zipalign/ZipFile.h
+++ b/tools/zipalign/ZipFile.h
@@ -102,14 +102,14 @@
     }
 
     /*
-     * Add an entry by copying it from another zip file.  If "padding" is
-     * nonzero, the specified number of bytes will be added to the "extra"
-     * field in the header.
+     * Add an entry by copying it from another zip file.  If "alignment" is
+     * nonzero, an appropriate number of bytes will be added to the "extra"
+     * field in the header so the entry payload is aligned.
      *
      * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
      */
     status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
-        int padding, ZipEntry** ppEntry);
+        int alignment, ZipEntry** ppEntry);
 
     /*
      * Add an entry by copying it from another zip file, recompressing with
@@ -163,6 +163,8 @@
     ZipFile(const ZipFile& src);
     ZipFile& operator=(const ZipFile& src);
 
+    status_t alignEntry(android::ZipEntry* pEntry, uint32_t alignTo);
+
     class EndOfCentralDir {
     public:
         EndOfCentralDir(void) :
diff --git a/tools/zipalign/tests/data/diffOrders.zip b/tools/zipalign/tests/data/diffOrders.zip
new file mode 100644
index 0000000..8f512ed
--- /dev/null
+++ b/tools/zipalign/tests/data/diffOrders.zip
Binary files differ
diff --git a/tools/zipalign/tests/data/holes.zip b/tools/zipalign/tests/data/holes.zip
new file mode 100644
index 0000000..c88f891
--- /dev/null
+++ b/tools/zipalign/tests/data/holes.zip
Binary files differ
diff --git a/tools/zipalign/tests/src/align_test.cpp b/tools/zipalign/tests/src/align_test.cpp
index 073a156..c79e791 100644
--- a/tools/zipalign/tests/src/align_test.cpp
+++ b/tools/zipalign/tests/src/align_test.cpp
@@ -19,6 +19,35 @@
   const std::string src = GetTestPath("unaligned.zip");
   const std::string dst = GetTestPath("unaligned_out.zip");
 
-  int result = process(src.c_str(), dst.c_str(), 4, true, false, 4096);
-  ASSERT_EQ(0, result);
+  int processed = process(src.c_str(), dst.c_str(), 4, true, false, 4096);
+  ASSERT_EQ(0, processed);
+
+  int verified = verify(dst.c_str(), 4, true, false);
+  ASSERT_EQ(0, verified);
+}
+
+// Align a zip featuring a hole at the beginning. The
+// hole in the archive is a delete entry in the Central
+// Directory.
+TEST(Align, Holes) {
+  const std::string src = GetTestPath("holes.zip");
+  const std::string dst = GetTestPath("holes_out.zip");
+
+  int processed = process(src.c_str(), dst.c_str(), 4, true, false, 4096);
+  ASSERT_EQ(0, processed);
+
+  int verified = verify(dst.c_str(), 4, false, true);
+  ASSERT_EQ(0, verified);
+}
+
+// Align a zip where LFH order and CD entries differ.
+TEST(Align, DifferenteOrders) {
+  const std::string src = GetTestPath("diffOrders.zip");
+  const std::string dst = GetTestPath("diffOrders_out.zip");
+
+  int processed = process(src.c_str(), dst.c_str(), 4, true, false, 4096);
+  ASSERT_EQ(0, processed);
+
+  int verified = verify(dst.c_str(), 4, false, true);
+  ASSERT_EQ(0, verified);
 }