Merge "Dist api_fingerprint file for droidcore"
diff --git a/OWNERS b/OWNERS
index 5c7f5ad..57d8994 100644
--- a/OWNERS
+++ b/OWNERS
@@ -3,6 +3,7 @@
 # Since this file affects all Android developers, lock it down. There is still
 # round the world timzeone coverage.
 per-file envsetup.sh = joeo@google.com, jingwen@google.com, lberki@google.com
+per-file shell_utils.sh = joeo@google.com, jingwen@google.com, lberki@google.com
 
 # Finalization scripts
 per-file finalize* = smoreland@google.com, alexbuy@google.com
diff --git a/core/Makefile b/core/Makefile
index 29415d4..9b3e3d9 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -509,6 +509,15 @@
 endef
 
 # $(1): kernel module directory name (top is an out of band value for no directory)
+define build-vendor-kernel-ramdisk-recovery-load
+$(if $(filter top,$(1)),\
+  $(eval _kver :=)$(eval _sep :=),\
+  $(eval _kver := $(1))$(eval _sep :=_))\
+  $(if $(BOARD_VENDOR_KERNEL_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD$(_sep)$(_kver)),\
+    $(call copy-many-files,$(call module-load-list-copy-paths,$(call intermediates-dir-for,PACKAGING,vendor_kernel_ramdisk_recovery_module_list$(_sep)$(_kver)),$(BOARD_VENDOR_KERNEL_RAMDISK_KERNEL_MODULES$(_sep)$(_kver)),$(BOARD_VENDOR_KERNEL_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD$(_sep)$(_kver)),modules.load.recovery,$(TARGET_VENDOR_KERNEL_RAMDISK_OUT))))
+endef
+
+# $(1): kernel module directory name (top is an out of band value for no directory)
 define build-vendor-charger-load
 $(if $(filter top,$(1)),\
   $(eval _kver :=)$(eval _sep :=),\
@@ -579,6 +588,7 @@
   $(eval $(result_var) += $(call build-image-kernel-modules-dir,VENDOR_RAMDISK,$(output_dir),,modules.load,$(VENDOR_RAMDISK_STRIPPED_MODULE_STAGING_DIR),$(kmd))) \
   $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,VENDOR_KERNEL_RAMDISK,$(TARGET_VENDOR_KERNEL_RAMDISK_OUT),,modules.load,$(VENDOR_KERNEL_RAMDISK_STRIPPED_MODULE_STAGING_DIR),$(kmd))) \
   $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-vendor-ramdisk-recovery-load,$(kmd))) \
+  $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-vendor-kernel-ramdisk-recovery-load,$(kmd))) \
   $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,VENDOR,$(if $(filter true,$(BOARD_USES_VENDOR_DLKMIMAGE)),$(TARGET_OUT_VENDOR_DLKM),$(TARGET_OUT_VENDOR)),vendor,modules.load,$(VENDOR_STRIPPED_MODULE_STAGING_DIR),$(kmd),$(BOARD_SYSTEM_KERNEL_MODULES),system)) \
   $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-vendor-charger-load,$(kmd))) \
   $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,ODM,$(if $(filter true,$(BOARD_USES_ODM_DLKMIMAGE)),$(TARGET_OUT_ODM_DLKM),$(TARGET_OUT_ODM)),odm,modules.load,,$(kmd))) \
@@ -587,6 +597,19 @@
     $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-recovery-as-boot-load,$(kmd))),\
     $(eval ALL_DEFAULT_INSTALLED_MODULES += $(call build-image-kernel-modules-dir,GENERIC_RAMDISK,$(TARGET_RAMDISK_OUT),,modules.load,,$(kmd)))))
 
+ifeq ($(BOARD_SYSTEM_KERNEL_MODULES),)
+ifneq ($(BOARD_SYSTEM_DLKM_SRC),)
+ifneq ($(wildcard $(BOARD_SYSTEM_DLKM_SRC)/*),)
+  SYSTEM_KERNEL_MODULES := $(shell find $(BOARD_SYSTEM_DLKM_SRC) -type f)
+  SRC_SYSTEM_KERNEL_MODULES := $(SYSTEM_KERNEL_MODULES)
+  DST_SYSTEM_KERNEL_MODULES := $(patsubst $(BOARD_SYSTEM_DLKM_SRC)/%,:$(TARGET_OUT_SYSTEM_DLKM)/%,$(SRC_SYSTEM_KERNEL_MODULES))
+  SYSTEM_KERNEL_MODULE_COPY_PAIRS := $(join $(SRC_SYSTEM_KERNEL_MODULES),$(DST_SYSTEM_KERNEL_MODULES))
+  ALL_DEFAULT_INSTALLED_MODULES += $(call copy-many-files,$(SYSTEM_KERNEL_MODULE_COPY_PAIRS))
+endif
+endif
+endif
+
+
 # -----------------------------------------------------------------
 # Cert-to-package mapping.  Used by the post-build signing tools.
 # Use a macro to add newline to each echo command
@@ -741,12 +764,6 @@
 $(call dist-for-goals,droidcore-unbundled,$(WALL_WERROR))
 
 # -----------------------------------------------------------------
-# C/C++ flag information for modules
-$(call dist-for-goals,droidcore-unbundled,$(SOONG_MODULES_CFLAG_ARTIFACTS))
-
-$(foreach a,$(SOONG_MODULES_CFLAG_ARTIFACTS),$(call declare-0p-target,$(call word-colon,1,$(a))))
-
-# -----------------------------------------------------------------
 # Modules missing profile files
 PGO_PROFILE_MISSING := $(PRODUCT_OUT)/pgo_profile_file_missing.txt
 $(PGO_PROFILE_MISSING):
@@ -925,16 +942,19 @@
 RAMDISK_EXT := .gz
 endif
 
+# This file contains /dev nodes description added to the generic ramdisk
+RAMDISK_NODE_LIST := $(PRODUCT_OUT)/ramdisk_node_list
+
 # We just build this directly to the install location.
 INSTALLED_RAMDISK_TARGET := $(BUILT_RAMDISK_TARGET)
 $(INSTALLED_RAMDISK_TARGET): PRIVATE_DIRS := debug_ramdisk dev metadata mnt proc second_stage_resources sys
-$(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_RAMDISK_FILES) $(INSTALLED_FILES_FILE_RAMDISK) | $(COMPRESSION_COMMAND_DEPS)
+$(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(RAMDISK_NODE_LIST) $(INTERNAL_RAMDISK_FILES) $(INSTALLED_FILES_FILE_RAMDISK) | $(COMPRESSION_COMMAND_DEPS)
 	$(call pretty,"Target ramdisk: $@")
 	$(hide) mkdir -p $(addprefix $(TARGET_RAMDISK_OUT)/,$(PRIVATE_DIRS))
 ifeq (true,$(BOARD_USES_GENERIC_KERNEL_IMAGE))
 	$(hide) mkdir -p $(addprefix $(TARGET_RAMDISK_OUT)/first_stage_ramdisk/,$(PRIVATE_DIRS))
 endif
-	$(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_RAMDISK_OUT) | $(COMPRESSION_COMMAND) > $@
+	$(hide) $(MKBOOTFS) -n $(RAMDISK_NODE_LIST) -d $(TARGET_OUT) $(TARGET_RAMDISK_OUT) | $(COMPRESSION_COMMAND) > $@
 
 $(call declare-1p-container,$(INSTALLED_RAMDISK_TARGET),)
 $(call declare-container-license-deps,$(INSTALLED_RAMDISK_TARGET),$(INTERNAL_RAMDISK_FILE),$(PRODUCT_OUT)/:/)
@@ -1269,7 +1289,7 @@
 	$(AVBTOOL) add_hash_footer \
 	    --image $@ \
 	    $(call get-partition-size-argument,$(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE)) \
-	    --partition_name boot $(INTERNAL_AVB_INIT_BOOT_SIGNING_ARGS) \
+	    --partition_name init_boot $(INTERNAL_AVB_INIT_BOOT_SIGNING_ARGS) \
 	    $(BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS)
 
 $(call declare-1p-container,$(INSTALLED_INIT_BOOT_IMAGE_TARGET),)
@@ -3493,6 +3513,18 @@
   INTERNAL_VENDORIMAGE_FILES += $(call create-partition-compat-symlink,$(TARGET_OUT_VENDOR)/lib/modules,/vendor_dlkm/lib/modules,vendor_dlkm.img)
 endif
 
+# Install vendor/etc/linker.config.pb when PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS is set
+ifneq ($(strip $(PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS)),)
+vendor_linker_config_file := $(TARGET_OUT_VENDOR)/etc/linker.config.pb
+$(vendor_linker_config_file): private_linker_config_fragments := $(PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS)
+$(vendor_linker_config_file): $(PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS) | $(HOST_OUT_EXECUTABLES)/conv_linker_config
+	$(HOST_OUT_EXECUTABLES)/conv_linker_config proto \
+		--source $(call normalize-path-list,$(private_linker_config_fragments)) \
+		--output $@
+$(call define declare-0p-target,$(vendor_linker_config_file),)
+INTERNAL_VENDORIMAGE_FILES += $(vendor_linker_config_file)
+endif
+
 INSTALLED_FILES_FILE_VENDOR := $(PRODUCT_OUT)/installed-files-vendor.txt
 INSTALLED_FILES_JSON_VENDOR := $(INSTALLED_FILES_FILE_VENDOR:.txt=.json)
 $(INSTALLED_FILES_FILE_VENDOR): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_VENDOR)
@@ -4079,7 +4111,8 @@
 
 INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES := \
     $(BOARD_AVB_VBMETA_SYSTEM) \
-    $(BOARD_AVB_VBMETA_VENDOR)
+    $(BOARD_AVB_VBMETA_VENDOR) \
+    $(foreach partition,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS),$(BOARD_AVB_VBMETA_$(call to-upper,$(partition))))
 
 # Not allowing the same partition to appear in multiple groups.
 ifneq ($(words $(sort $(INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES))),$(words $(INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES)))
@@ -4385,6 +4418,11 @@
 $(eval $(call check-and-set-avb-args,vbmeta_vendor))
 endif
 
+ifdef BOARD_AVB_VBMETA_CUSTOM_PARTITIONS
+$(foreach partition,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS),$(eval $(call check-and-set-avb-args,vbmeta_$(partition))))
+$(foreach partition,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS),$(eval BOARD_AVB_MAKE_VBMETA_$(call to-upper,$(partition))_IMAGE_ARGS += --padding_size 4096))
+endif
+
 ifneq ($(strip $(BOARD_CUSTOMIMAGES_PARTITION_LIST)),)
 $(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
     $(eval $(call check-and-set-custom-avb-chain-args,$(partition))))
@@ -4413,6 +4451,13 @@
     --rollback_index $(BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX)
 endif
 
+ifdef BOARD_AVB_VBMETA_CUSTOM_PARTITIONS
+  $(foreach partition,$(call to-upper,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)), \
+      $(if $(BOARD_AVB_VBMETA_$(partition)_ROLLBACK_INDEX),$(eval \
+        BOARD_AVB_MAKE_VBMETA_$(partition)_IMAGE_ARGS += \
+          --rollback_index $(BOARD_AVB_VBMETA_$(partition)_ROLLBACK_INDEX))))
+endif
+
 # $(1): the directory to extract public keys to
 define extract-avb-chain-public-keys
   $(if $(BOARD_AVB_BOOT_KEY_PATH),\
@@ -4469,7 +4514,11 @@
   $(if $(BOARD_CUSTOMIMAGES_PARTITION_LIST),\
     $(hide) $(foreach partition,$(BOARD_CUSTOMIMAGES_PARTITION_LIST), \
         $(AVBTOOL) extract_public_key --key $(BOARD_AVB_$(call to-upper,$(partition))_KEY_PATH) \
-            --output $(1)/$(partition).avbpubkey;))
+            --output $(1)/$(partition).avbpubkey;)) \
+  $(if $(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS),\
+    $(hide) $(foreach partition,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS), \
+        $(AVBTOOL) extract_public_key --key $(BOARD_AVB_VBMETA_$(call to-upper,$(partition))_KEY_PATH) \
+            --output $(1)/vbmeta_$(partition).avbpubkey;))
 endef
 
 # Builds a chained VBMeta image. This VBMeta image will contain the descriptors for the partitions
@@ -4481,13 +4530,13 @@
 # $(1): VBMeta image name, such as "vbmeta_system", "vbmeta_vendor" etc.
 # $(2): Output filename.
 define build-chained-vbmeta-image
-  $(call pretty,"Target chained vbmeta image: $@")
-  $(hide) $(AVBTOOL) make_vbmeta_image \
-      $(INTERNAL_AVB_$(call to-upper,$(1))_SIGNING_ARGS) \
-      $(BOARD_AVB_MAKE_$(call to-upper,$(1))_IMAGE_ARGS) \
-      $(foreach image,$(BOARD_AVB_$(call to-upper,$(1))), \
-          --include_descriptors_from_image $(call images-for-partitions,$(image))) \
-      --output $@
+	$(call pretty,"Target chained vbmeta image: $@")
+	$(hide) $(AVBTOOL) make_vbmeta_image \
+	    $(INTERNAL_AVB_$(call to-upper,$(1))_SIGNING_ARGS) \
+	    $(BOARD_AVB_MAKE_$(call to-upper,$(1))_IMAGE_ARGS) \
+	    $(foreach image,$(BOARD_AVB_$(call to-upper,$(1))), \
+	        --include_descriptors_from_image $(call images-for-partitions,$(image))) \
+	    --output $@
 endef
 
 ifdef BUILDING_SYSTEM_IMAGE
@@ -4515,7 +4564,26 @@
 
 $(call declare-1p-container,$(INSTALLED_VBMETA_VENDORIMAGE_TARGET),)
 
-UNMOUNTED_NOTICE_VENDOR_DEPS+= $(INSTALLED_VBMETA_VENDORIMAGE_TARGET)
+UNMOUNTED_NOTICE_VENDOR_DEPS += $(INSTALLED_VBMETA_VENDORIMAGE_TARGET)
+endif
+
+ifdef BOARD_AVB_VBMETA_CUSTOM_PARTITIONS
+define declare-custom-vbmeta-target
+INSTALLED_VBMETA_$(call to-upper,$(1))IMAGE_TARGET := $(PRODUCT_OUT)/vbmeta_$(call to-lower,$(1)).img
+$$(INSTALLED_VBMETA_$(call to-upper,$(1))IMAGE_TARGET): \
+	    $(AVBTOOL) \
+	    $(call images-for-partitions,$(BOARD_AVB_VBMETA_$(call to-upper,$(1)))) \
+	    $(BOARD_AVB_VBMETA_$(call to-upper,$(1))_KEY_PATH)
+	$$(call build-chained-vbmeta-image,vbmeta_$(call to-lower,$(1)))
+
+$(call declare-1p-container,$(INSTALLED_VBMETA_$(call to-upper,$(1))IMAGE_TARGET),)
+
+UNMOUNTED_NOTICE_VENDOR_DEPS += $(INSTALLED_VBMETA_$(call to-upper,$(1))IMAGE_TARGET)
+endef
+
+$(foreach partition,\
+          $(call to-upper,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)),\
+          $(eval $(call declare-custom-vbmeta-target,$(partition))))
 endif
 
 define build-vbmetaimage-target
@@ -4535,6 +4603,7 @@
 $(INSTALLED_VBMETAIMAGE_TARGET): PRIVATE_AVB_VBMETA_SIGNING_ARGS := \
     --algorithm $(BOARD_AVB_ALGORITHM) --key $(BOARD_AVB_KEY_PATH)
 
+
 $(INSTALLED_VBMETAIMAGE_TARGET): \
 	    $(AVBTOOL) \
 	    $(INSTALLED_BOOTIMAGE_TARGET) \
@@ -4555,8 +4624,10 @@
 	    $(INSTALLED_RECOVERYIMAGE_TARGET) \
 	    $(INSTALLED_VBMETA_SYSTEMIMAGE_TARGET) \
 	    $(INSTALLED_VBMETA_VENDORIMAGE_TARGET) \
+      $(foreach partition,$(call to-upper,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)),$(INSTALLED_VBMETA_$(partition)IMAGE_TARGET)) \
 	    $(BOARD_AVB_VBMETA_SYSTEM_KEY_PATH) \
 	    $(BOARD_AVB_VBMETA_VENDOR_KEY_PATH) \
+      $(foreach partition,$(call to-upper,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)),$(BOARD_AVB_VBMETA_$(partition)_KEY_PATH)) \
 	    $(BOARD_AVB_KEY_PATH)
 	$(build-vbmetaimage-target)
 
@@ -5016,6 +5087,7 @@
   img2simg \
   img_from_target_files \
   imgdiff \
+  initrd_bootconfig \
   libconscrypt_openjdk_jni \
   lpmake \
   lpunpack \
@@ -5061,7 +5133,7 @@
 INTERNAL_OTATOOLS_MODULES += \
   apexer \
   apex_compression_tool \
-  blkid \
+  blkid_static \
   deapexer \
   debugfs_static \
   dump_apex_info \
@@ -5308,6 +5380,15 @@
 	$(hide) echo "avb_vbmeta_vendor_algorithm=$(BOARD_AVB_VBMETA_VENDOR_ALGORITHM)" >> $@
 	$(hide) echo "avb_vbmeta_vendor_rollback_index_location=$(BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION)" >> $@
 endif # BOARD_AVB_VBMETA_VENDOR_KEY_PATH
+ifneq (,$(strip $(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)))
+	$(hide) echo "avb_custom_vbmeta_images_partition_list=$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)" >> $@
+	$(hide) $(foreach partition,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS),\
+	echo "avb_vbmeta_$(partition)=$(BOARD_AVB_VBMETA_$(call to-upper,$(partition)))" >> $@ ;\
+	echo "avb_vbmeta_$(partition)_args=$(BOARD_AVB_MAKE_VBMETA_$(call to-upper,$(partition))_IMAGE_ARGS)" >> $@ ;\
+	echo "avb_vbmeta_$(partition)_key_path=$(BOARD_AVB_VBMETA_$(call to-upper,$(partition))_KEY_PATH)" >> $@ ;\
+	echo "avb_vbmeta_$(partition)_algorithm=$(BOARD_AVB_VBMETA_$(call to-upper,$(partition))_ALGORITHM)" >> $@ ;\
+	echo "avb_vbmeta_$(partition)_rollback_index_location=$(BOARD_AVB_VBMETA_$(call to-upper,$(partition))_ROLLBACK_INDEX_LOCATION)" >> $@ ;)
+endif # BOARD_AVB_VBMETA_CUSTOM_PARTITIONS
 endif # BOARD_AVB_ENABLE
 ifdef BOARD_BPT_INPUT_FILES
 	$(hide) echo "board_bpt_enable=true" >> $@
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 00f5f21..ec5a21e 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -600,7 +600,11 @@
       # Manually handle the case where the
       # output file is in the recovery or ramdisk partition.
       ifneq (,$(filter $(TARGET_RECOVERY_ROOT_OUT)/%,$(my_module_path)))
-        my_init_rc_path := $(TARGET_RECOVERY_ROOT_OUT)/system/etc
+        ifneq (,$(filter $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/%,$(my_module_path)))
+            my_init_rc_path := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/system/etc
+        else
+            my_init_rc_path := $(TARGET_RECOVERY_ROOT_OUT)/system/etc
+        endif
       else ifneq (,$(filter $(TARGET_RAMDISK_OUT)/%,$(my_module_path)))
         my_init_rc_path := $(TARGET_RAMDISK_OUT)/system/etc
       else
@@ -712,6 +716,15 @@
 ## Compatibility suite files.
 ###########################################################
 ifdef LOCAL_COMPATIBILITY_SUITE
+
+ifneq (,$(LOCAL_FULL_TEST_CONFIG))
+  test_config := $(LOCAL_FULL_TEST_CONFIG)
+else ifneq (,$(LOCAL_TEST_CONFIG))
+  test_config := $(LOCAL_PATH)/$(LOCAL_TEST_CONFIG)
+else
+  test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
+endif
+
 ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
 
 # If we are building a native test or benchmark and its stem variants are not defined,
@@ -758,13 +771,6 @@
 
 
 # Auto-generate build config.
-ifneq (,$(LOCAL_FULL_TEST_CONFIG))
-  test_config := $(LOCAL_FULL_TEST_CONFIG)
-else ifneq (,$(LOCAL_TEST_CONFIG))
-  test_config := $(LOCAL_PATH)/$(LOCAL_TEST_CONFIG)
-else
-  test_config := $(wildcard $(LOCAL_PATH)/AndroidTest.xml)
-endif
 ifeq (,$(test_config))
   ifneq (true,$(is_native))
     is_instrumentation_test := true
@@ -843,16 +849,6 @@
   endif
 endif # $(my_prefix)$(LOCAL_MODULE_CLASS)_$(LOCAL_MODULE)_compat_files
 
-# HACK: pretend a soong LOCAL_FULL_TEST_CONFIG is autogenerated by setting the flag in
-# module-info.json
-# TODO: (b/113029686) Add explicit flag from Soong to determine if a test was
-# autogenerated.
-ifneq (,$(filter $(SOONG_OUT_DIR)%,$(LOCAL_FULL_TEST_CONFIG)))
-  ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
-    ALL_MODULES.$(my_register_name).auto_test_config := true
-  endif
-endif
-
 
 ifeq ($(use_testcase_folder),true)
 ifneq ($(my_test_data_file_pairs),)
@@ -893,6 +889,17 @@
   $(eval my_compat_dist_test_data_$(suite) := ))
 
 endif  # LOCAL_UNINSTALLABLE_MODULE
+
+# HACK: pretend a soong LOCAL_FULL_TEST_CONFIG is autogenerated by setting the flag in
+# module-info.json
+# TODO: (b/113029686) Add explicit flag from Soong to determine if a test was
+# autogenerated.
+ifneq (,$(filter $(SOONG_OUT_DIR)%,$(LOCAL_FULL_TEST_CONFIG)))
+  ifeq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+    ALL_MODULES.$(my_register_name).auto_test_config := true
+  endif
+endif
+
 endif  # LOCAL_COMPATIBILITY_SUITE
 
 my_supported_variant :=
diff --git a/core/binary.mk b/core/binary.mk
index 6320726..6f1d814 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -58,6 +58,9 @@
 my_cppflags := $(LOCAL_CPPFLAGS)
 my_cflags_no_override := $(GLOBAL_CLANG_CFLAGS_NO_OVERRIDE)
 my_cppflags_no_override := $(GLOBAL_CLANG_CPPFLAGS_NO_OVERRIDE)
+ifeq ($(my_32_64_bit_suffix), 64)
+  my_cflags_no_override += $(GLOBAL_CLANG_CFLAGS_64_NO_OVERRIDE)
+endif
 ifdef is_third_party
     my_cflags_no_override += $(GLOBAL_CLANG_EXTERNAL_CFLAGS_NO_OVERRIDE)
     my_cppflags_no_override += $(GLOBAL_CLANG_EXTERNAL_CFLAGS_NO_OVERRIDE)
diff --git a/core/clang/config.mk b/core/clang/config.mk
index 28a75ec..d03c541 100644
--- a/core/clang/config.mk
+++ b/core/clang/config.mk
@@ -2,7 +2,7 @@
 
 LLVM_READOBJ := $(LLVM_PREBUILTS_BASE)/$(BUILD_OS)-x86/$(LLVM_PREBUILTS_VERSION)/bin/llvm-readobj
 
-LLVM_RTLIB_PATH := $(LLVM_PREBUILTS_BASE)/linux-x86/$(LLVM_PREBUILTS_VERSION)/lib64/clang/$(LLVM_RELEASE_VERSION)/lib/linux/
+LLVM_RTLIB_PATH := $(LLVM_PREBUILTS_BASE)/linux-x86/$(LLVM_PREBUILTS_VERSION)/lib/clang/$(LLVM_RELEASE_VERSION)/lib/linux/
 
 define convert-to-clang-flags
 $(strip $(filter-out $(CLANG_CONFIG_UNKNOWN_CFLAGS),$(1)))
diff --git a/core/config.mk b/core/config.mk
index f5bb7ef..025a3a1 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -431,6 +431,9 @@
 $(hide) $(HOST_NM) -gP $(1) | cut -f1-2 -d" " | (grep -v U$$ >> $(2) || true)
 endef
 
+# Pick a Java compiler.
+include $(BUILD_SYSTEM)/combo/javac.mk
+
 ifeq ($(CALLED_FROM_SETUP),true)
 include $(BUILD_SYSTEM)/ccache.mk
 include $(BUILD_SYSTEM)/goma.mk
@@ -453,9 +456,6 @@
   WITH_TIDY_ONLY :=
 endif
 
-# Pick a Java compiler.
-include $(BUILD_SYSTEM)/combo/javac.mk
-
 # ---------------------------------------------------------------
 # Check that the configuration is current.  We check that
 # BUILD_ENV_SEQUENCE_NUMBER is current against this value.
diff --git a/core/main.mk b/core/main.mk
index 0453cda..3866037 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -92,6 +92,9 @@
 -include test/catbox/tools/build/config.mk
 # CTS-Root-specific config.
 -include test/cts-root/tools/build/config.mk
+# WVTS-specific config.
+-include test/wvts/tools/build/config.mk
+
 
 # Clean rules
 .PHONY: clean-dex-files
@@ -1602,6 +1605,9 @@
 .PHONY: vbmetavendorimage
 vbmetavendorimage: $(INSTALLED_VBMETA_VENDORIMAGE_TARGET)
 
+.PHONY: vbmetacustomimages
+vbmetacustomimages: $(foreach partition,$(call to-upper,$(BOARD_AVB_VBMETA_CUSTOM_PARTITIONS)),$(INSTALLED_VBMETA_$(partition)IMAGE_TARGET))
+
 # The droidcore-unbundled target depends on the subset of targets necessary to
 # perform a full system build (either unbundled or not).
 .PHONY: droidcore-unbundled
diff --git a/core/product.mk b/core/product.mk
index 7621c71..f4d5a4f 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -24,6 +24,8 @@
 
 _product_single_value_vars += PRODUCT_NAME
 _product_single_value_vars += PRODUCT_MODEL
+_product_single_value_vars += PRODUCT_NAME_FOR_ATTESTATION
+_product_single_value_vars += PRODUCT_MODEL_FOR_ATTESTATION
 
 # The resoure configuration options to use for this product.
 _product_list_vars += PRODUCT_LOCALES
@@ -43,6 +45,7 @@
 _product_single_value_vars += PRODUCT_DEVICE
 _product_single_value_vars += PRODUCT_MANUFACTURER
 _product_single_value_vars += PRODUCT_BRAND
+_product_single_value_vars += PRODUCT_BRAND_FOR_ATTESTATION
 
 # These PRODUCT_SYSTEM_* flags, if defined, are used in place of the
 # corresponding PRODUCT_* flags for the sysprops on /system.
@@ -373,6 +376,9 @@
 # If true, installs a full version of com.android.virt APEX.
 _product_single_value_vars += PRODUCT_AVF_ENABLED
 
+# List of .json files to be merged/compiled into vendor/etc/linker.config.pb
+_product_list_vars += PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS
+
 # Whether to use userfaultfd GC.
 # Possible values are:
 # - "default" or empty: both the build system and the runtime determine whether to use userfaultfd
diff --git a/core/product_config.rbc b/core/product_config.rbc
index b0d6977..97c1d00 100644
--- a/core/product_config.rbc
+++ b/core/product_config.rbc
@@ -59,6 +59,12 @@
         if _options.format == "pretty":
             print(attr, "=", repr(value))
         elif _options.format == "make":
+            value = list(value)
+            for i, x in enumerate(value):
+                if type(x) == "tuple" and len(x) == 1:
+                    value[i] = "@inherit:" + x[0] + ".mk"
+                elif type(x) != "string":
+                    fail("Wasn't a list of strings:", attr, " value:", value)
             print(attr, ":=", " ".join(value))
     elif _options.format == "pretty":
         print(attr, "=", repr(value))
@@ -456,6 +462,9 @@
 
 def __words(string_or_list):
     if type(string_or_list) == "list":
+        for x in string_or_list:
+            if type(x) != "string":
+                return string_or_list
         string_or_list = " ".join(string_or_list)
     return _mkstrip(string_or_list).split()
 
diff --git a/core/proguard.flags b/core/proguard.flags
index 53f63d8..d790061 100644
--- a/core/proguard.flags
+++ b/core/proguard.flags
@@ -9,14 +9,19 @@
 # Add this flag in your package's own configuration if it's needed.
 #-flattenpackagehierarchy
 
-# Keep classes and methods that have @VisibleForTesting annotations, except in
-# intermediate libraries that export those annotations (e.g., androidx, guava).
-# This avoids keeping library-specific test code that isn't actually needed
-# for platform testing.
+# Keep classes and members with the platform-defined @VisibleForTesting annotation.
+-keep @com.android.internal.annotations.VisibleForTesting class *
+-keepclassmembers class * {
+    @com.android.internal.annotations.VisibleForTesting *;
+}
+
+# Keep classes and members with non-platform @VisibleForTesting annotations, but
+# only within platform-defined packages. This avoids keeping external, library-specific
+# test code that isn't actually needed for platform testing.
 # TODO(b/239961360): Migrate away from androidx.annotation.VisibleForTesting
 # and com.google.common.annotations.VisibleForTesting use in platform code.
--keep @**.VisibleForTesting class !androidx.**,!com.google.common.**,*
--keepclassmembers class !androidx.**,!com.google.common.**,* {
+-keep @**.VisibleForTesting class android.**,com.android.**,com.google.android.**
+-keepclassmembers class android.**,com.android.**,com.google.android.** {
     @**.VisibleForTesting *;
 }
 
diff --git a/core/rbe.mk b/core/rbe.mk
index 65abde5..6754b0a 100644
--- a/core/rbe.mk
+++ b/core/rbe.mk
@@ -81,11 +81,11 @@
   endif
 
   ifdef RBE_R8
-    R8_WRAPPER := $(strip $(RBE_WRAPPER) --labels=type=compile,compiler=r8 --exec_strategy=$(r8_exec_strategy) --platform=$(java_r8_d8_platform) --inputs=$(OUT_DIR)/soong/host/linux-x86/framework/r8-compat-proguard.jar,build/make/core/proguard_basic_keeps.flags --toolchain_inputs=$(JAVA))
+    R8_WRAPPER := $(strip $(RBE_WRAPPER) --labels=type=compile,compiler=r8 --exec_strategy=$(r8_exec_strategy) --platform=$(java_r8_d8_platform) --inputs=$(OUT_DIR)/host/linux-x86/framework/r8.jar,build/make/core/proguard_basic_keeps.flags --toolchain_inputs=$(firstword $(JAVA)))
   endif
 
   ifdef RBE_D8
-    D8_WRAPPER := $(strip $(RBE_WRAPPER) --labels=type=compile,compiler=d8 --exec_strategy=$(d8_exec_strategy) --platform=$(java_r8_d8_platform) --inputs=$(OUT_DIR)/soong/host/linux-x86/framework/d8.jar --toolchain_inputs=$(JAVA))
+    D8_WRAPPER := $(strip $(RBE_WRAPPER) --labels=type=compile,compiler=d8 --exec_strategy=$(d8_exec_strategy) --platform=$(java_r8_d8_platform) --inputs=$(OUT_DIR)/host/linux-x86/framework/d8.jar --toolchain_inputs=$(firstword $(JAVA)))
   endif
 
   rbe_dir :=
diff --git a/core/soong_config.mk b/core/soong_config.mk
index a89db4f..091fa34 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -249,9 +249,9 @@
 $(call add_json_list, MissingUsesLibraries,              $(INTERNAL_PLATFORM_MISSING_USES_LIBRARIES))
 
 $(call add_json_map, VendorVars)
-$(foreach namespace,$(SOONG_CONFIG_NAMESPACES),\
+$(foreach namespace,$(sort $(SOONG_CONFIG_NAMESPACES)),\
   $(call add_json_map, $(namespace))\
-  $(foreach key,$(SOONG_CONFIG_$(namespace)),\
+  $(foreach key,$(sort $(SOONG_CONFIG_$(namespace))),\
     $(call add_json_str,$(key),$(subst ",\",$(SOONG_CONFIG_$(namespace)_$(key)))))\
   $(call end_json_map))
 $(call end_json_map)
@@ -266,6 +266,10 @@
 
 $(call add_json_bool, CompressedApex, $(filter true,$(PRODUCT_COMPRESSED_APEX)))
 
+ifndef APEX_BUILD_FOR_PRE_S_DEVICES
+$(call add_json_bool, TrimmedApex, $(filter true,$(PRODUCT_TRIMMED_APEX)))
+endif
+
 $(call add_json_bool, BoardUsesRecoveryAsBoot, $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)))
 
 $(call add_json_list, BoardKernelBinaries, $(BOARD_KERNEL_BINARIES))
diff --git a/core/sysprop.mk b/core/sysprop.mk
index b51818a..b7f0651 100644
--- a/core/sysprop.mk
+++ b/core/sysprop.mk
@@ -46,6 +46,10 @@
         echo "ro.product.$(1).manufacturer=$(PRODUCT_MANUFACTURER)" >> $(2);\
         echo "ro.product.$(1).model=$(PRODUCT_MODEL)" >> $(2);\
         echo "ro.product.$(1).name=$(TARGET_PRODUCT)" >> $(2);\
+        # Attestation specific properties for AOSP/GSI build running on device.
+        echo "ro.product.model_for_attestation=$(PRODUCT_MODEL_FOR_ATTESTATION)" >> $(2);\
+        echo "ro.product.brand_for_attestation=$(PRODUCT_BRAND_FOR_ATTESTATION)" >> $(2);\
+        echo "ro.product.name_for_attestation=$(PRODUCT_NAME_FOR_ATTESTATION)" >> $(2);\
     )\
     $(if $(filter true,$(ZYGOTE_FORCE_64)),\
         $(if $(filter vendor,$(1)),\
diff --git a/core/tasks/wvts.mk b/core/tasks/wvts.mk
new file mode 100644
index 0000000..a79f613
--- /dev/null
+++ b/core/tasks/wvts.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2022 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.
+
+# Widevine test suite for non-GMS partners: go/android-wvts
+ifneq ($(wildcard test/wvts/tools/wvts-tradefed/README),)
+test_suite_name := wvts
+test_suite_tradefed := wvts-tradefed
+test_suite_dynamic_config := test/wvts/tools/wvts-tradefed/DynamicConfig.xml
+test_suite_readme := test/wvts/tools/wvts-tradefed/README
+
+$(call declare-1p-target,$(test_suite_dynamic_config),wvts)
+$(call declare-1p-target,$(test_suite_readme),wvts)
+
+include $(BUILD_SYSTEM)/tasks/tools/compatibility.mk
+
+.PHONY: wvts
+wvts: $(compatibility_zip) $(compatibility_tests_list_zip)
+$(call dist-for-goals, wvts, $(compatibility_zip) $(compatibility_tests_list_zip))
+endif
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 734e32b..a664b9d 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -103,7 +103,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 := 2022-12-05
+    PLATFORM_SECURITY_PATCH := 2023-02-05
 endif
 
 include $(BUILD_SYSTEM)/version_util.mk
diff --git a/envsetup.sh b/envsetup.sh
index 4990800..0272624 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -1,3 +1,55 @@
+# Copyright (C) 2022 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.
+
+# gettop is duplicated here and in shell_utils.mk, because it's difficult
+# to find shell_utils.make without it for all the novel ways this file can be
+# sourced.  Other common functions should only be in one place or the other.
+function _gettop_once
+{
+    local TOPFILE=build/make/core/envsetup.mk
+    if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
+        # The following circumlocution ensures we remove symlinks from TOP.
+        (cd "$TOP"; PWD= /bin/pwd)
+    else
+        if [ -f $TOPFILE ] ; then
+            # The following circumlocution (repeated below as well) ensures
+            # that we record the true directory name and not one that is
+            # faked up with symlink names.
+            PWD= /bin/pwd
+        else
+            local HERE=$PWD
+            local T=
+            while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do
+                \cd ..
+                T=`PWD= /bin/pwd -P`
+            done
+            \cd "$HERE"
+            if [ -f "$T/$TOPFILE" ]; then
+                echo "$T"
+            fi
+        fi
+    fi
+}
+T=$(_gettop_once)
+if [ ! "$T" ]; then
+    echo "Couldn't locate the top of the tree. Always source build/envsetup.sh from the root of the tree." >&2
+    return 1
+fi
+IMPORTING_ENVSETUP=true source $T/build/make/shell_utils.sh
+
+
+# Help
 function hmm() {
 cat <<EOF
 
@@ -27,6 +79,7 @@
 - ggrep:      Greps on all local Gradle files.
 - gogrep:     Greps on all local Go files.
 - jgrep:      Greps on all local Java files.
+- jsongrep:   Greps on all local Json files.
 - ktgrep:     Greps on all local Kotlin files.
 - resgrep:    Greps on all local res/*.xml files.
 - mangrep:    Greps on all local AndroidManifest.xml files.
@@ -35,6 +88,7 @@
 - rsgrep:     Greps on all local Rust files.
 - sepgrep:    Greps on all local sepolicy files.
 - sgrep:      Greps on all local source files.
+- tomlgrep:   Greps on all local Toml files.
 - pygrep:     Greps on all local Python files.
 - godir:      Go to the directory containing a file.
 - allmod:     List all modules.
@@ -243,7 +297,22 @@
     if [ -n $ANDROID_PYTHONPATH ]; then
         export PYTHONPATH=${PYTHONPATH//$ANDROID_PYTHONPATH/}
     fi
-    export ANDROID_PYTHONPATH=$T/development/python-packages:
+    # //development/python-packages contains both a pseudo-PYTHONPATH which
+    # mimics an already assembled venv, but also contains real Python packages
+    # that are not in that layout until they are installed. We can fake it for
+    # the latter type by adding the package source directories to the PYTHONPATH
+    # directly. For the former group, we only need to add the python-packages
+    # directory itself.
+    #
+    # This could be cleaned up by converting the remaining packages that are in
+    # the first category into a typical python source layout (that is, another
+    # layer of directory nesting) and automatically adding all subdirectories of
+    # python-packages to the PYTHONPATH instead of manually curating this. We
+    # can't convert the packages like adb to the other style because doing so
+    # would prevent exporting type info from those packages.
+    #
+    # http://b/266688086
+    export ANDROID_PYTHONPATH=$T/development/python-packages/adb:$T/development/python-packages:
     if [ -n $VENDOR_PYTHONPATH ]; then
         ANDROID_PYTHONPATH=$ANDROID_PYTHONPATH$VENDOR_PYTHONPATH
     fi
@@ -928,33 +997,6 @@
     destroy_build_var_cache
 }
 
-function gettop
-{
-    local TOPFILE=build/make/core/envsetup.mk
-    if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then
-        # The following circumlocution ensures we remove symlinks from TOP.
-        (cd "$TOP"; PWD= /bin/pwd)
-    else
-        if [ -f $TOPFILE ] ; then
-            # The following circumlocution (repeated below as well) ensures
-            # that we record the true directory name and not one that is
-            # faked up with symlink names.
-            PWD= /bin/pwd
-        else
-            local HERE=$PWD
-            local T=
-            while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do
-                \cd ..
-                T=`PWD= /bin/pwd -P`
-            done
-            \cd "$HERE"
-            if [ -f "$T/$TOPFILE" ]; then
-                echo "$T"
-            fi
-        fi
-    fi
-}
-
 # TODO: Merge into gettop as part of launching multitree
 function multitree_gettop
 {
@@ -1211,6 +1253,18 @@
         -exec grep --color -n "$@" {} +
 }
 
+function jsongrep()
+{
+    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.json" \
+        -exec grep --color -n "$@" {} +
+}
+
+function tomlgrep()
+{
+    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.toml" \
+        -exec grep --color -n "$@" {} +
+}
+
 function ktgrep()
 {
     find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.kt" \
@@ -1827,11 +1881,6 @@
         color_reset=""
     fi
 
-    if [[ "x${USE_RBE}" == "x" && $mins -gt 15 && "${ANDROID_BUILD_ENVIRONMENT_CONFIG}" == "googler" ]]; then
-        echo
-        echo "${color_warning}Start using RBE (http://go/build-fast) to get faster builds!${color_reset}"
-    fi
-
     echo
     if [ $ret -eq 0 ] ; then
         echo -n "${color_success}#### build completed successfully "
diff --git a/finalize-locally-mainline-sdk.sh b/finalize-locally-mainline-sdk.sh
new file mode 100755
index 0000000..c72ef8c
--- /dev/null
+++ b/finalize-locally-mainline-sdk.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -ex
+
+function finalize_locally_mainline_sdk() {
+    local MAINLINE_EXTENSION='6'
+
+    local top="$(dirname "$0")"/../..
+
+    # Bump SDK extension version.
+    "$top/packages/modules/SdkExtensions/gen_sdk/bump_sdk.sh" ${MAINLINE_EXTENSION}
+
+    local version_defaults="$top/build/make/core/version_defaults.mk"
+    sed -i -e "s/PLATFORM_SDK_EXTENSION_VERSION := .*/PLATFORM_SDK_EXTENSION_VERSION := ${MAINLINE_EXTENSION}/g" $version_defaults
+
+    # Build modules SDKs.
+    TARGET_BUILD_VARIANT=userdebug UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true "$top/vendor/google/build/mainline_modules_sdks.sh"
+
+    # Update prebuilts.
+    "$top/prebuilts/build-tools/path/linux-x86/python3" "$top/packages/modules/common/tools/finalize_sdk.py" -l -b 0 -f ${MAINLINE_EXTENSION} -r '' 0
+}
+
+finalize_locally_mainline_sdk
+
diff --git a/finalize-sdk-rel.sh b/finalize-sdk-rel.sh
index 35899f7..b19e56a 100755
--- a/finalize-sdk-rel.sh
+++ b/finalize-sdk-rel.sh
@@ -14,7 +14,7 @@
 
     # adb keys
     $m adb
-    LOGNAME=android-eng HOSTNAME=google.com adb keygen "$DEV_SRC_DIR/vendor/google/security/adb/${PLATFORM_VERSION}.adb_key"
+    LOGNAME=android-eng HOSTNAME=google.com "$DEV_SRC_DIR/out/host/linux-x86/bin/adb" keygen "$DEV_SRC_DIR/vendor/google/security/adb/${PLATFORM_VERSION}.adb_key"
 
     # build/make/core/version_defaults.mk
     sed -i -e "s/PLATFORM_VERSION_CODENAME.${BUILD_PREFIX} := .*/PLATFORM_VERSION_CODENAME.${BUILD_PREFIX} := REL/g" "$DEV_SRC_DIR/build/make/core/version_defaults.mk"
@@ -29,13 +29,13 @@
     cp -r "$DEV_SRC_DIR/system/sepolicy/private/" "$DEV_SRC_DIR/system/sepolicy/prebuilts/api/${PLATFORM_SDK_VERSION}.0/"
 
     # prebuilts/abi-dumps/ndk
-    git -C "$DEV_SRC_DIR/prebuilts/abi-dumps/ndk" mv current ${PLATFORM_SDK_VERSION}
+    mv "$DEV_SRC_DIR/prebuilts/abi-dumps/ndk/current" "$DEV_SRC_DIR/prebuilts/abi-dumps/ndk/$PLATFORM_SDK_VERSION"
 
     # prebuilts/abi-dumps/vndk
-    git -C "$DEV_SRC_DIR/prebuilts/abi-dumps/vndk" mv ${PLATFORM_CODENAME} ${PLATFORM_SDK_VERSION}
+    mv "$DEV_SRC_DIR/prebuilts/abi-dumps/vndk/$PLATFORM_CODENAME" "$DEV_SRC_DIR/prebuilts/abi-dumps/vndk/$PLATFORM_SDK_VERSION"
 
     # prebuilts/abi-dumps/platform
-    git -C "$DEV_SRC_DIR/prebuilts/abi-dumps/platform" mv current ${PLATFORM_SDK_VERSION}
+    mv "$DEV_SRC_DIR/prebuilts/abi-dumps/platform/current" "$DEV_SRC_DIR/prebuilts/abi-dumps/platform/$PLATFORM_SDK_VERSION"
 }
 
 finalize_sdk_rel
diff --git a/finalize-step-1-for-build-target.sh b/finalize-step-1-for-build-target.sh
index 52cf0a7..8b35a1d 100755
--- a/finalize-step-1-for-build-target.sh
+++ b/finalize-step-1-for-build-target.sh
@@ -4,49 +4,10 @@
 
 set -ex
 
-function revert_to_unfinalized_state() {
-    declare -a projects=(
-        "build/make/"
-        "build/soong/"
-        "cts/"
-        "frameworks/base/"
-        "frameworks/hardware/interfaces/"
-        "frameworks/libs/modules-utils/"
-        "frameworks/libs/net/"
-        "hardware/interfaces/"
-        "libcore/"
-        "packages/services/Car/"
-        "platform_testing/"
-        "prebuilts/abi-dumps/ndk/"
-        "prebuilts/abi-dumps/platform/"
-        "prebuilts/abi-dumps/vndk/"
-        "system/hardware/interfaces/"
-        "system/tools/aidl/"
-        "tools/platform-compat"
-        "device/generic/car"
-        "development"
-    )
-
-    for project in "${projects[@]}"
-    do
-        local git_path="$top/$project"
-        echo "Reverting: $git_path"
-        baselineHash="$(git -C $git_path log --format=%H --no-merges --max-count=1 --grep ^FINALIZATION_STEP_1_BASELINE_COMMIT)" ;
-        if [[ $baselineHash ]]; then
-          previousHash="$(git -C $git_path log --format=%H --no-merges --max-count=100 --grep ^FINALIZATION_STEP_1_SCRIPT_COMMIT $baselineHash..HEAD | tr \n \040)" ;
-        else
-          previousHash="$(git -C $git_path log --format=%H --no-merges --max-count=100 --grep ^FINALIZATION_STEP_1_SCRIPT_COMMIT | tr \n \040)" ;
-        fi ;
-        if [[ $previousHash ]]; then git -C $git_path revert --no-commit --strategy=ort --strategy-option=ours $previousHash ; fi ;
-    done
-}
-
 function finalize_step_1_main() {
     local top="$(dirname "$0")"/../..
     local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
 
-    revert_to_unfinalized_state
-
     # vndk etc finalization
     source $top/build/make/finalize-aidl-vndk-sdk-resources.sh
 
diff --git a/finalize-step-1.sh b/finalize-step-1.sh
index 20bc2bf..8871862 100755
--- a/finalize-step-1.sh
+++ b/finalize-step-1.sh
@@ -32,6 +32,9 @@
 }
 
 function finalize_step_1_main() {
+    # deprecated, do not use
+    exit 1
+
     local top="$(dirname "$0")"/../..
 
     repo selfupdate
diff --git a/finalize-step-2-for-build-target.sh b/finalize-step-2-for-build-target.sh
index caf415f..b74fd03 100755
--- a/finalize-step-2-for-build-target.sh
+++ b/finalize-step-2-for-build-target.sh
@@ -4,55 +4,19 @@
 
 set -ex
 
-function revert_to_unfinalized_state() {
-    declare -a projects=(
-        "build/make/"
-        "build/soong/"
-        "cts/"
-        "frameworks/base/"
-        "frameworks/hardware/interfaces/"
-        "frameworks/libs/modules-utils/"
-        "frameworks/libs/net/"
-        "hardware/interfaces/"
-        "libcore/"
-        "packages/services/Car/"
-        "platform_testing/"
-        "prebuilts/abi-dumps/ndk/"
-        "prebuilts/abi-dumps/platform/"
-        "prebuilts/abi-dumps/vndk/"
-        "system/hardware/interfaces/"
-        "system/tools/aidl/"
-        "tools/platform-compat"
-        "device/generic/car"
-        "development"
-    )
-
-    for project in "${projects[@]}"
-    do
-        local git_path="$top/$project"
-        echo "Reverting: $git_path"
-        baselineHash="$(git -C $git_path log --format=%H --no-merges --max-count=1 --grep ^FINALIZATION_STEP_1_BASELINE_COMMIT)" ;
-        if [[ $baselineHash ]]; then
-          previousHash="$(git -C $git_path log --format=%H --no-merges --max-count=100 --grep ^FINALIZATION_STEP_1_SCRIPT_COMMIT $baselineHash..HEAD | tr \n \040)" ;
-        else
-          previousHash="$(git -C $git_path log --format=%H --no-merges --max-count=100 --grep ^FINALIZATION_STEP_1_SCRIPT_COMMIT | tr \n \040)" ;
-        fi ;
-        if [[ $previousHash ]]; then git -C $git_path revert --no-commit --strategy=ort --strategy-option=ours $previousHash ; fi ;
-    done
-}
-
 function finalize_step_2_main() {
     local top="$(dirname "$0")"/../..
     local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
 
-    revert_to_unfinalized_state
-
     # vndk etc finalization
     source $top/build/make/finalize-aidl-vndk-sdk-resources.sh
 
     # prebuilts etc
     source $top/build/make/finalize-sdk-rel.sh
 
+    # mainline sdk prebuilts
+    source $top/build/make/finalize-locally-mainline-sdk.sh
+
     # build to confirm everything is OK
     AIDL_FROZEN_REL=true $m
 }
diff --git a/finalize-step-2.sh b/finalize-step-2.sh
index 627153b..ef80b2b 100755
--- a/finalize-step-2.sh
+++ b/finalize-step-2.sh
@@ -32,6 +32,9 @@
 }
 
 function finalize_step_2_main() {
+    # deprecated, do not use
+    exit 1
+
     local top="$(dirname "$0")"/../..
 
     repo selfupdate
diff --git a/shell_utils.sh b/shell_utils.sh
new file mode 100644
index 0000000..9de5a50
--- /dev/null
+++ b/shell_utils.sh
@@ -0,0 +1,74 @@
+# Copyright (C) 2022 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.
+
+function gettop
+{
+    local TOPFILE=build/make/core/envsetup.mk
+    # The ${TOP-} expansion allows this to work even with set -u
+    if [ -n "${TOP:-}" -a -f "${TOP:-}/$TOPFILE" ] ; then
+        # The following circumlocution ensures we remove symlinks from TOP.
+        (cd "$TOP"; PWD= /bin/pwd)
+    else
+        if [ -f $TOPFILE ] ; then
+            # The following circumlocution (repeated below as well) ensures
+            # that we record the true directory name and not one that is
+            # faked up with symlink names.
+            PWD= /bin/pwd
+        else
+            local HERE=$PWD
+            local T=
+            while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do
+                \cd ..
+                T=`PWD= /bin/pwd -P`
+            done
+            \cd "$HERE"
+            if [ -f "$T/$TOPFILE" ]; then
+                echo "$T"
+            fi
+        fi
+    fi
+}
+
+# Sets TOP, or if the root of the tree can't be found, prints a message and
+# exits.  Since this function exits, it should not be called from functions
+# defined in envsetup.sh.
+if [ -z "${IMPORTING_ENVSETUP:-}" ] ; then
+function require_top
+{
+    TOP=$(gettop)
+    if [[ ! $TOP ]] ; then
+        echo "Can not locate root of source tree. $(basename $0) must be run from within the Android source tree." >&2
+        exit 1
+    fi
+}
+fi
+
+function getoutdir
+{
+    local top=$(gettop)
+    local out_dir="${OUT_DIR:-}"
+    if [[ -z "${out_dir}" ]]; then
+        if [[ -n "${OUT_DIR_COMMON_BASE:-}" && -n "${top}" ]]; then
+            out_dir="${OUT_DIR_COMMON_BASE}/$(basename ${top})"
+        else
+            out_dir="out"
+        fi
+    fi
+    if [[ "${out_dir}" != /* ]]; then
+        out_dir="${top}/${out_dir}"
+    fi
+    echo "${out_dir}"
+}
+
+
diff --git a/target/board/BoardConfigEmuCommon.mk b/target/board/BoardConfigEmuCommon.mk
index 5acbe7f..7a07d70 100644
--- a/target/board/BoardConfigEmuCommon.mk
+++ b/target/board/BoardConfigEmuCommon.mk
@@ -34,7 +34,7 @@
   BOARD_BUILD_SUPER_IMAGE_BY_DEFAULT := true
 
   # 8G + 8M
-  BOARD_SUPER_PARTITION_SIZE := 8598323200
+  BOARD_SUPER_PARTITION_SIZE ?= 8598323200
   BOARD_SUPER_PARTITION_GROUPS := emulator_dynamic_partitions
 
   ifeq ($(QEMU_USE_SYSTEM_EXT_PARTITIONS),true)
@@ -57,7 +57,7 @@
   endif
 
   # 8G
-  BOARD_EMULATOR_DYNAMIC_PARTITIONS_SIZE := 8589934592
+  BOARD_EMULATOR_DYNAMIC_PARTITIONS_SIZE ?= 8589934592
 
   # in build environment to speed up make -j
   ifeq ($(QEMU_DISABLE_AVB),true)
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index 585630b..1e0ce19 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -36,6 +36,7 @@
 PRODUCT_MAKEFILES := \
     $(LOCAL_DIR)/aosp_arm64.mk \
     $(LOCAL_DIR)/aosp_arm.mk \
+    $(LOCAL_DIR)/aosp_riscv64.mk \
     $(LOCAL_DIR)/aosp_x86_64.mk \
     $(LOCAL_DIR)/aosp_x86.mk \
     $(LOCAL_DIR)/full.mk \
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index cabb172..b66d2c7 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -54,7 +54,6 @@
     com.android.appsearch \
     com.android.btservices \
     com.android.conscrypt \
-    com.android.cronet \
     com.android.extservices \
     com.android.i18n \
     com.android.ipsec \
@@ -389,6 +388,7 @@
     procrank \
     profcollectd \
     profcollectctl \
+    record_binder \
     servicedispatcher \
     showmap \
     sqlite3 \
diff --git a/target/product/base_vendor.mk b/target/product/base_vendor.mk
index 7fb785c..3c4d62e 100644
--- a/target/product/base_vendor.mk
+++ b/target/product/base_vendor.mk
@@ -46,7 +46,7 @@
 
 # Base modules and settings for the vendor partition.
 PRODUCT_PACKAGES += \
-    android.hardware.cas@1.2-service \
+    android.hardware.cas-service.example \
     boringssl_self_test_vendor \
     dumpsys_vendor \
     fs_config_files_nonsystem \
@@ -81,7 +81,11 @@
 
 endif
 
-# Base module when shipping api level is less than or equal to 29
+# Base modules when shipping api level is less than or equal to 33
+PRODUCT_PACKAGES_SHIPPING_API_LEVEL_33 += \
+    android.hardware.cas@1.2-service \
+
+# Base modules when shipping api level is less than or equal to 29
 PRODUCT_PACKAGES_SHIPPING_API_LEVEL_29 += \
     android.hardware.configstore@1.1-service \
     vndservice \
diff --git a/target/product/generic_ramdisk.mk b/target/product/generic_ramdisk.mk
index c7dcd60..ebac62f 100644
--- a/target/product/generic_ramdisk.mk
+++ b/target/product/generic_ramdisk.mk
@@ -29,11 +29,16 @@
     adb_debug.prop \
     userdebug_plat_sepolicy.cil \
 
+
+# For targets using dedicated recovery partition, generic ramdisk
+# might be relocated to recovery partition
 _my_paths := \
     $(TARGET_COPY_OUT_RAMDISK)/ \
     $(TARGET_COPY_OUT_DEBUG_RAMDISK)/ \
     system/usr/share/zoneinfo/tz_version \
     system/usr/share/zoneinfo/tzdata \
+    $(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/system \
+
 
 # We use the "relaxed" version here because tzdata / tz_version is only produced
 # by this makefile on a subset of devices.
diff --git a/target/product/gsi/33.txt b/target/product/gsi/33.txt
index 03a143d..db05f93 100644
--- a/target/product/gsi/33.txt
+++ b/target/product/gsi/33.txt
@@ -79,7 +79,6 @@
 VNDK-core: android.hardware.graphics.allocator@4.0.so
 VNDK-core: android.hardware.graphics.bufferqueue@1.0.so
 VNDK-core: android.hardware.graphics.bufferqueue@2.0.so
-VNDK-core: android.hardware.health-V1-ndk.so
 VNDK-core: android.hardware.health.storage-V1-ndk.so
 VNDK-core: android.hardware.identity-V4-ndk.so
 VNDK-core: android.hardware.ir-V1-ndk.so
diff --git a/target/product/gsi/Android.mk b/target/product/gsi/Android.mk
index d02dc7a..107c94f 100644
--- a/target/product/gsi/Android.mk
+++ b/target/product/gsi/Android.mk
@@ -126,8 +126,13 @@
 endef
 
 VNDK_ABI_DUMP_DIR := prebuilts/abi-dumps/vndk/$(PLATFORM_VNDK_VERSION)
-NDK_ABI_DUMP_DIR := prebuilts/abi-dumps/ndk/$(PLATFORM_VNDK_VERSION)
-PLATFORM_ABI_DUMP_DIR := prebuilts/abi-dumps/platform/$(PLATFORM_VNDK_VERSION)
+ifeq (REL,$(PLATFORM_VERSION_CODENAME))
+    NDK_ABI_DUMP_DIR := prebuilts/abi-dumps/ndk/$(PLATFORM_SDK_VERSION)
+    PLATFORM_ABI_DUMP_DIR := prebuilts/abi-dumps/platform/$(PLATFORM_SDK_VERSION)
+else
+    NDK_ABI_DUMP_DIR := prebuilts/abi-dumps/ndk/current
+    PLATFORM_ABI_DUMP_DIR := prebuilts/abi-dumps/platform/current
+endif
 VNDK_ABI_DUMPS := $(call find-abi-dump-paths,$(VNDK_ABI_DUMP_DIR))
 NDK_ABI_DUMPS := $(call find-abi-dump-paths,$(NDK_ABI_DUMP_DIR))
 PLATFORM_ABI_DUMPS := $(call find-abi-dump-paths,$(PLATFORM_ABI_DUMP_DIR))
@@ -141,7 +146,7 @@
 $(check-vndk-abi-dump-list-timestamp): PRIVATE_STUB_LIBRARIES := $(STUB_LIBRARIES)
 $(check-vndk-abi-dump-list-timestamp):
 	$(eval added_vndk_abi_dumps := $(strip $(sort $(filter-out \
-	  $(call filter-abi-dump-paths,LLNDK VNDK-SP VNDK-core,$(PRIVATE_LSDUMP_PATHS)), \
+	  $(call filter-abi-dump-paths,VNDK-SP VNDK-core,$(PRIVATE_LSDUMP_PATHS)), \
 	  $(notdir $(VNDK_ABI_DUMPS))))))
 	$(if $(added_vndk_abi_dumps), \
 	  echo -e "Found unexpected ABI reference dump files under $(VNDK_ABI_DUMP_DIR). It is caused by mismatch between Android.bp and the dump files. Run \`find \$${ANDROID_BUILD_TOP}/$(VNDK_ABI_DUMP_DIR) '(' -name $(subst $(space), -or -name ,$(added_vndk_abi_dumps)) ')' -delete\` to delete the dump files.")
@@ -154,7 +159,7 @@
 	  echo -e "Found unexpected ABI reference dump files under $(NDK_ABI_DUMP_DIR). It is caused by mismatch between Android.bp and the dump files. Run \`find \$${ANDROID_BUILD_TOP}/$(NDK_ABI_DUMP_DIR) '(' -name $(subst $(space), -or -name ,$(added_ndk_abi_dumps)) ')' -delete\` to delete the dump files.")
 
 	$(eval added_platform_abi_dumps := $(strip $(sort $(filter-out \
-	  $(call filter-abi-dump-paths,PLATFORM,$(PRIVATE_LSDUMP_PATHS)) \
+	  $(call filter-abi-dump-paths,LLNDK PLATFORM,$(PRIVATE_LSDUMP_PATHS)) \
 	  $(addsuffix .lsdump,$(PRIVATE_STUB_LIBRARIES)), \
 	  $(notdir $(PLATFORM_ABI_DUMPS))))))
 	$(if $(added_platform_abi_dumps), \
diff --git a/target/product/module_common.mk b/target/product/module_common.mk
index 54f3949..ec670ee 100644
--- a/target/product/module_common.mk
+++ b/target/product/module_common.mk
@@ -25,3 +25,8 @@
 # Builds using a module product should build modules from source, even if
 # BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE says otherwise.
 PRODUCT_MODULE_BUILD_FROM_SOURCE := true
+
+# Build sdk from source if the branch is not using slim manifests.
+ifneq (,$(strip $(wildcard frameworks/base/Android.bp)))
+  UNBUNDLED_BUILD_SDKS_FROM_SOURCE := true
+endif
diff --git a/target/product/virtual_ab_ota/android_t_baseline.mk b/target/product/virtual_ab_ota/android_t_baseline.mk
index 716c8e0..418aaa4 100644
--- a/target/product/virtual_ab_ota/android_t_baseline.mk
+++ b/target/product/virtual_ab_ota/android_t_baseline.mk
@@ -12,29 +12,11 @@
 # 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 file enables baseline features, such as io_uring,
-# userspace merge, etc. But sets compression method to none.
-# This .mk file also removes snapuserd from vendor ramdisk,
-# as T launching devices will have init_boot which has snapuserd
-# in generic ramdisk.
-# T launching devices should include this .mk file, and configure
-# compression algorithm by setting
-# PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD to gz or brotli. Complete
-# set of supported algorithms can be found in
-# system/core/fs_mgr/libsnapshot/cow_writer.cpp
-
-PRODUCT_VIRTUAL_AB_OTA := true
-
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.enabled=true
-
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.enabled=true
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.io_uring.enabled=true
-PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
-
-PRODUCT_VIRTUAL_AB_COMPRESSION := true
-PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD ?= none
-PRODUCT_PACKAGES += \
-    snapuserd \
-
+# This file should be used only for T launching devices. We maintain
+# this file just for backward compatibility for T launch devices
+# so that build doesn't break.
+#
+# All U+ launching devices should instead use vabc_features.mk.
+$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota/vabc_features.mk)
diff --git a/target/product/virtual_ab_ota/compression.mk b/target/product/virtual_ab_ota/compression.mk
index d5bd2a5..dc1ee3e 100644
--- a/target/product/virtual_ab_ota/compression.mk
+++ b/target/product/virtual_ab_ota/compression.mk
@@ -19,6 +19,12 @@
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.enabled=true
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
 PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.io_uring.enabled=true
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.batch_writes=true
+
+# Enabling this property, will improve OTA install time
+# but will use an additional CPU core
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.threads=true
+
 PRODUCT_VIRTUAL_AB_COMPRESSION := true
 PRODUCT_PACKAGES += \
     snapuserd.vendor_ramdisk \
diff --git a/target/product/virtual_ab_ota/vabc_features.mk b/target/product/virtual_ab_ota/vabc_features.mk
new file mode 100644
index 0000000..874eb9c
--- /dev/null
+++ b/target/product/virtual_ab_ota/vabc_features.mk
@@ -0,0 +1,46 @@
+#
+# Copyright (C) 2022 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 file enables baseline features, such as io_uring,
+# userspace merge, etc. But sets compression method to none.
+# This .mk file also removes snapuserd from vendor ramdisk,
+# as T launching devices will have init_boot which has snapuserd
+# in generic ramdisk.
+#
+# T and U launching devices should include this .mk file, and configure
+# compression algorithm by setting
+# PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD to lz4, gz or brotli. Complete
+# set of supported algorithms can be found in
+# system/core/fs_mgr/libsnapshot/cow_writer.cpp
+
+PRODUCT_VIRTUAL_AB_OTA := true
+
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.enabled=true
+
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.enabled=true
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.io_uring.enabled=true
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.batch_writes=true
+
+# Enabling this property, will improve OTA install time
+# but will use an additional CPU core
+# PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.threads=true
+
+PRODUCT_VIRTUAL_AB_COMPRESSION := true
+PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD ?= none
+PRODUCT_PACKAGES += \
+    snapuserd \
+
diff --git a/tests/b_tests.sh b/tests/b_tests.sh
index 45cb4f7..13f156d 100755
--- a/tests/b_tests.sh
+++ b/tests/b_tests.sh
@@ -27,6 +27,10 @@
 b build "$test_target" --run-soong-tests
 b build --run-soong-tests "$test_target"
 b --run-soong-tests build "$test_target"
+# Test that the bazel server can be restarted once shut down. If run in a
+# docker container, you need to run the docker container with --init or
+# have some other process as PID 1 that can reap zombies.
+b shutdown
 b cquery 'kind(test, //build/bazel/examples/android_app/...)' --config=android
 b run $test_target -- --help >/dev/null
 
diff --git a/tests/inherits_in_regular_variables/inherit1.rbc b/tests/inherits_in_regular_variables/inherit1.rbc
new file mode 100644
index 0000000..4ce8825
--- /dev/null
+++ b/tests/inherits_in_regular_variables/inherit1.rbc
@@ -0,0 +1,21 @@
+# Copyright 2023 Google LLC
+#
+# 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
+#
+#      https://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.
+
+load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+  cfg = rblf.cfg(handle)
+
+  cfg.setdefault("PRODUCT_PACKAGES", [])
+  cfg["PRODUCT_PACKAGES"] += ["bar"]
diff --git a/tests/inherits_in_regular_variables/product.rbc b/tests/inherits_in_regular_variables/product.rbc
new file mode 100644
index 0000000..c193c65
--- /dev/null
+++ b/tests/inherits_in_regular_variables/product.rbc
@@ -0,0 +1,27 @@
+# Copyright 2023 Google LLC
+#
+# 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
+#
+#      https://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.
+
+load("//build/make/core:product_config.rbc", "rblf")
+load(":inherit1.rbc", _inherit1_init = "init")
+
+def init(g, handle):
+  cfg = rblf.cfg(handle)
+
+  cfg.setdefault("PRODUCT_PACKAGES", [])
+  cfg["PRODUCT_PACKAGES"] += ["foo"]
+
+  g["PRODUCT_PACKAGES_COPY"] = cfg["PRODUCT_PACKAGES"]
+
+  rblf.inherit(handle, "test/inherit1", _inherit1_init)
+
diff --git a/tests/inherits_in_regular_variables/test.rbc b/tests/inherits_in_regular_variables/test.rbc
new file mode 100644
index 0000000..3a76d8a
--- /dev/null
+++ b/tests/inherits_in_regular_variables/test.rbc
@@ -0,0 +1,30 @@
+# Copyright 2023 Google LLC
+#
+# 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
+#
+#      https://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.
+
+load("//build/make/core:product_config.rbc", "rblf")
+load("//build/make/tests/input_variables.rbc", input_variables_init = "init")
+load(":product.rbc", "init")
+
+
+def assert_eq(expected, actual):
+    if expected != actual:
+        fail("Expected '%s', got '%s'" % (expected, actual))
+
+def test():
+    (globals, globals_base) = rblf.product_configuration("test/device", init, input_variables_init)
+    assert_eq(["foo", "bar"], globals["PRODUCTS.test/device.mk.PRODUCT_PACKAGES"])
+    assert_eq(["foo", ("test/inherit1",)], globals["PRODUCT_PACKAGES_COPY"])
+
+    # Ideally we would check that rblf.printvars returns the correct result, but we don't have
+    # a good way to intercept its output or mock rblf_cli
diff --git a/tests/run.rbc b/tests/run.rbc
index e8c4caa..33583eb 100644
--- a/tests/run.rbc
+++ b/tests/run.rbc
@@ -28,6 +28,7 @@
 load("//build/make/tests/single_value_inheritance:test.rbc", test_single_value_inheritance = "test")
 load("//build/make/tests/artifact_path_requirements:test.rbc", test_artifact_path_requirements = "test")
 load("//build/make/tests/prefixed_sort_order:test.rbc", test_prefixed_sort_order = "test")
+load("//build/make/tests/inherits_in_regular_variables:test.rbc", test_inherits_in_regular_variables = "test")
 
 def assert_eq(expected, actual):
     if expected != actual:
@@ -45,6 +46,11 @@
 assert_eq("a b c", rblf.mkstrip("  a b   \n  c \t"))
 assert_eq("1", rblf.mkstrip("1 "))
 
+assert_eq(["a", "b"], rblf.words("a b"))
+assert_eq(["a", "b", "c"], rblf.words(["a b", "c"]))
+# 1-tuple like we use in product variables
+assert_eq(["a b", ("c",)], rblf.words(["a b", ("c",)]))
+
 assert_eq("b1 b2", rblf.mksubst("a", "b", "a1 a2"))
 assert_eq(["b1", "x2"], rblf.mksubst("a", "b", ["a1", "x2"]))
 
@@ -176,3 +182,4 @@
 test_single_value_inheritance()
 test_artifact_path_requirements()
 test_prefixed_sort_order()
+test_inherits_in_regular_variables()
diff --git a/tools/auto_gen_test_config.py b/tools/auto_gen_test_config.py
index 943f238..ce64160 100755
--- a/tools/auto_gen_test_config.py
+++ b/tools/auto_gen_test_config.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright (C) 2017 The Android Open Source Project
 #
@@ -69,7 +69,7 @@
   module = os.path.splitext(os.path.basename(target_config))[0]
   instrumentation = instrumentation_elements[0]
   manifest = manifest_elements[0]
-  if instrumentation.attributes.has_key(ATTRIBUTE_LABEL):
+  if ATTRIBUTE_LABEL in instrumentation.attributes:
     label = instrumentation.attributes[ATTRIBUTE_LABEL].value
   else:
     label = module
diff --git a/tools/compliance/cmd/sbom/sbom.go b/tools/compliance/cmd/sbom/sbom.go
index 493d331..0f8a876 100644
--- a/tools/compliance/cmd/sbom/sbom.go
+++ b/tools/compliance/cmd/sbom/sbom.go
@@ -271,6 +271,17 @@
 	return pms[index], nil
 }
 
+// inputFiles returns the complete list of files read
+func inputFiles(lg *compliance.LicenseGraph, pmix *projectmetadata.Index, licenseTexts []string) []string {
+	projectMeta := pmix.AllMetadataFiles()
+	targets :=  lg.TargetNames()
+	files := make([]string, 0, len(licenseTexts)+len(targets)+len(projectMeta))
+	files = append(files, licenseTexts...)
+	files = append(files, targets...)
+	files = append(files, projectMeta...)
+	return files
+}
+
 // sbomGenerator implements the spdx bom utility
 
 // SBOM is part of the new government regulation issued to improve national cyber security
@@ -332,9 +343,9 @@
 			if isMainPackage {
 				mainPackage = getDocumentName(ctx, tn, pm)
 				fmt.Fprintf(ctx.stdout, "SPDXVersion: SPDX-2.2\n")
-				fmt.Fprintf(ctx.stdout, "DataLicense: CC-1.0\n")
+				fmt.Fprintf(ctx.stdout, "DataLicense: CC0-1.0\n")
 				fmt.Fprintf(ctx.stdout, "DocumentName: %s\n", mainPackage)
-				fmt.Fprintf(ctx.stdout, "SPDXID: SPDXRef-DOCUMENT-%s\n", mainPackage)
+				fmt.Fprintf(ctx.stdout, "SPDXID: SPDXRef-DOCUMENT\n")
 				fmt.Fprintf(ctx.stdout, "DocumentNamespace: Android\n")
 				fmt.Fprintf(ctx.stdout, "Creator: Organization: Google LLC\n")
 				fmt.Fprintf(ctx.stdout, "Created: %s\n", ctx.creationTime().Format("2006-01-02T15:04:05Z"))
@@ -352,8 +363,8 @@
 			}()
 			if len(path) == 0 {
 				relationships = append(relationships,
-					fmt.Sprintf("Relationship: SPDXRef-DOCUMENT-%s DESCRIBES SPDXRef-Package-%s",
-						mainPackage, getPackageName(ctx, tn)))
+					fmt.Sprintf("Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-%s",
+						getPackageName(ctx, tn)))
 			} else {
 				// Check parent and identify annotation
 				parent := path[len(path)-1]
@@ -417,6 +428,7 @@
 		fmt.Fprintf(ctx.stdout, "ExtractedText: <text>%v</text>\n", string(text))
 	}
 
-	deps := licenseTexts
+	deps := inputFiles(lg, pmix, licenseTexts)
+	sort.Strings(deps)
 	return deps, nil
 }
diff --git a/tools/compliance/cmd/sbom/sbom_test.go b/tools/compliance/cmd/sbom/sbom_test.go
index 6b40a27..6df74e2 100644
--- a/tools/compliance/cmd/sbom/sbom_test.go
+++ b/tools/compliance/cmd/sbom/sbom_test.go
@@ -30,9 +30,9 @@
 
 var (
 	spdxVersionTag              = regexp.MustCompile(`^\s*SPDXVersion: SPDX-2.2\s*$`)
-	spdxDataLicenseTag          = regexp.MustCompile(`^\s*DataLicense: CC-1.0\s*$`)
+	spdxDataLicenseTag          = regexp.MustCompile(`^\s*DataLicense: CC0-1.0\s*$`)
 	spdxDocumentNameTag         = regexp.MustCompile(`^\s*DocumentName:\s*Android*\s*$`)
-	spdxIDTag                   = regexp.MustCompile(`^\s*SPDXID:\s*SPDXRef-DOCUMENT-(.*)\s*$`)
+	spdxIDTag                   = regexp.MustCompile(`^\s*SPDXID:\s*SPDXRef-DOCUMENT\s*$`)
 	spdxDocumentNameSpaceTag    = regexp.MustCompile(`^\s*DocumentNamespace:\s*Android\s*$`)
 	spdxCreatorOrganizationTag  = regexp.MustCompile(`^\s*Creator:\s*Organization:\s*Google LLC\s*$`)
 	spdxCreatedTimeTag          = regexp.MustCompile(`^\s*Created: 1970-01-01T00:00:00Z\s*$`)
@@ -76,7 +76,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -85,7 +85,7 @@
 				spdxPkgID{"testdata/firstparty/highest.apex.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata-firstparty-highest.apex.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata-firstparty-highest.apex.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/firstparty/bin/bin1.meta_lic"},
 				packageName{"testdata/firstparty/bin/bin1.meta_lic"},
 				spdxPkgID{"testdata/firstparty/bin/bin1.meta_lic"},
@@ -129,7 +129,16 @@
 				spdxExtractedText{"&&&First Party License&&&"},
 				spdxExtractedClosingText{},
 			},
-			expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+			expectedDeps: []string{
+				"testdata/firstparty/FIRST_PARTY_LICENSE",
+				"testdata/firstparty/bin/bin1.meta_lic",
+				"testdata/firstparty/bin/bin2.meta_lic",
+				"testdata/firstparty/highest.apex.meta_lic",
+				"testdata/firstparty/lib/liba.so.meta_lic",
+				"testdata/firstparty/lib/libb.so.meta_lic",
+				"testdata/firstparty/lib/libc.a.meta_lic",
+				"testdata/firstparty/lib/libd.so.meta_lic",
+			},
 		},
 		{
 			condition: "firstparty",
@@ -139,7 +148,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -148,7 +157,7 @@
 				spdxPkgID{"testdata/firstparty/application.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/firstparty/application.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/firstparty/application.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/firstparty/bin/bin3.meta_lic"},
 				packageName{"testdata/firstparty/bin/bin3.meta_lic"},
 				spdxPkgID{"testdata/firstparty/bin/bin3.meta_lic"},
@@ -172,7 +181,13 @@
 				spdxExtractedText{"&&&First Party License&&&"},
 				spdxExtractedClosingText{},
 			},
-			expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+			expectedDeps: []string{
+				"testdata/firstparty/FIRST_PARTY_LICENSE",
+				"testdata/firstparty/application.meta_lic",
+				"testdata/firstparty/bin/bin3.meta_lic",
+				"testdata/firstparty/lib/liba.so.meta_lic",
+				"testdata/firstparty/lib/libb.so.meta_lic",
+			},
 		},
 		{
 			condition: "firstparty",
@@ -182,7 +197,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -191,7 +206,7 @@
 				spdxPkgID{"testdata/firstparty/container.zip.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/firstparty/container.zip.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/firstparty/container.zip.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/firstparty/bin/bin1.meta_lic"},
 				packageName{"testdata/firstparty/bin/bin1.meta_lic"},
 				spdxPkgID{"testdata/firstparty/bin/bin1.meta_lic"},
@@ -235,7 +250,16 @@
 				spdxExtractedText{"&&&First Party License&&&"},
 				spdxExtractedClosingText{},
 			},
-			expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+			expectedDeps: []string{
+				"testdata/firstparty/FIRST_PARTY_LICENSE",
+				"testdata/firstparty/bin/bin1.meta_lic",
+				"testdata/firstparty/bin/bin2.meta_lic",
+				"testdata/firstparty/container.zip.meta_lic",
+				"testdata/firstparty/lib/liba.so.meta_lic",
+				"testdata/firstparty/lib/libb.so.meta_lic",
+				"testdata/firstparty/lib/libc.a.meta_lic",
+				"testdata/firstparty/lib/libd.so.meta_lic",
+			},
 		},
 		{
 			condition: "firstparty",
@@ -245,7 +269,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -254,7 +278,7 @@
 				spdxPkgID{"testdata/firstparty/bin/bin1.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/firstparty/bin/bin1.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/firstparty/bin/bin1.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/firstparty/lib/liba.so.meta_lic"},
 				packageName{"testdata/firstparty/lib/liba.so.meta_lic"},
 				spdxPkgID{"testdata/firstparty/lib/liba.so.meta_lic"},
@@ -272,7 +296,12 @@
 				spdxExtractedText{"&&&First Party License&&&"},
 				spdxExtractedClosingText{},
 			},
-			expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+			expectedDeps: []string{
+				"testdata/firstparty/FIRST_PARTY_LICENSE",
+				"testdata/firstparty/bin/bin1.meta_lic",
+				"testdata/firstparty/lib/liba.so.meta_lic",
+				"testdata/firstparty/lib/libc.a.meta_lic",
+			},
 		},
 		{
 			condition: "firstparty",
@@ -282,7 +311,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -291,13 +320,16 @@
 				spdxPkgID{"testdata/firstparty/lib/libd.so.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/firstparty/lib/libd.so.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/firstparty/lib/libd.so.meta_lic", "DESCRIBES"},
 				spdxLicense{},
 				spdxLicenseID{"testdata-firstparty-FIRST_PARTY_LICENSE"},
 				spdxExtractedText{"&&&First Party License&&&"},
 				spdxExtractedClosingText{},
 			},
-			expectedDeps: []string{"testdata/firstparty/FIRST_PARTY_LICENSE"},
+			expectedDeps: []string{
+				"testdata/firstparty/FIRST_PARTY_LICENSE",
+				"testdata/firstparty/lib/libd.so.meta_lic",
+			},
 		},
 		{
 			condition: "notice",
@@ -307,7 +339,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -316,7 +348,7 @@
 				spdxPkgID{"testdata/notice/highest.apex.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/notice/highest.apex.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/notice/highest.apex.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/notice/bin/bin1.meta_lic"},
 				packageName{"testdata/notice/bin/bin1.meta_lic"},
 				spdxPkgID{"testdata/notice/bin/bin1.meta_lic"},
@@ -366,6 +398,13 @@
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/notice/NOTICE_LICENSE",
+				"testdata/notice/bin/bin1.meta_lic",
+				"testdata/notice/bin/bin2.meta_lic",
+				"testdata/notice/highest.apex.meta_lic",
+				"testdata/notice/lib/liba.so.meta_lic",
+				"testdata/notice/lib/libb.so.meta_lic",
+				"testdata/notice/lib/libc.a.meta_lic",
+				"testdata/notice/lib/libd.so.meta_lic",
 			},
 		},
 		{
@@ -376,7 +415,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -385,7 +424,7 @@
 				spdxPkgID{"testdata/notice/container.zip.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/notice/container.zip.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/notice/container.zip.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/notice/bin/bin1.meta_lic"},
 				packageName{"testdata/notice/bin/bin1.meta_lic"},
 				spdxPkgID{"testdata/notice/bin/bin1.meta_lic"},
@@ -435,6 +474,13 @@
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/notice/NOTICE_LICENSE",
+				"testdata/notice/bin/bin1.meta_lic",
+				"testdata/notice/bin/bin2.meta_lic",
+				"testdata/notice/container.zip.meta_lic",
+				"testdata/notice/lib/liba.so.meta_lic",
+				"testdata/notice/lib/libb.so.meta_lic",
+				"testdata/notice/lib/libc.a.meta_lic",
+				"testdata/notice/lib/libd.so.meta_lic",
 			},
 		},
 		{
@@ -445,7 +491,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -454,7 +500,7 @@
 				spdxPkgID{"testdata/notice/application.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata-notice-application.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata-notice-application.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/notice/bin/bin3.meta_lic"},
 				packageName{"testdata/notice/bin/bin3.meta_lic"},
 				spdxPkgID{"testdata/notice/bin/bin3.meta_lic"},
@@ -484,6 +530,10 @@
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/notice/NOTICE_LICENSE",
+				"testdata/notice/application.meta_lic",
+				"testdata/notice/bin/bin3.meta_lic",
+				"testdata/notice/lib/liba.so.meta_lic",
+				"testdata/notice/lib/libb.so.meta_lic",
 			},
 		},
 		{
@@ -494,7 +544,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -503,7 +553,7 @@
 				spdxPkgID{"testdata/notice/bin/bin1.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/notice/bin/bin1.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/notice/bin/bin1.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/notice/lib/liba.so.meta_lic"},
 				packageName{"testdata/notice/lib/liba.so.meta_lic"},
 				spdxPkgID{"testdata/notice/lib/liba.so.meta_lic"},
@@ -527,6 +577,9 @@
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/notice/NOTICE_LICENSE",
+				"testdata/notice/bin/bin1.meta_lic",
+				"testdata/notice/lib/liba.so.meta_lic",
+				"testdata/notice/lib/libc.a.meta_lic",
 			},
 		},
 		{
@@ -537,7 +590,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -546,13 +599,16 @@
 				spdxPkgID{"testdata/notice/lib/libd.so.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/notice/lib/libd.so.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/notice/lib/libd.so.meta_lic", "DESCRIBES"},
 				spdxLicense{},
 				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
 				spdxExtractedText{"%%%Notice License%%%"},
 				spdxExtractedClosingText{},
 			},
-			expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+			expectedDeps: []string{
+				"testdata/notice/NOTICE_LICENSE",
+				"testdata/notice/lib/libd.so.meta_lic",
+			},
 		},
 		{
 			condition: "reciprocal",
@@ -562,7 +618,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -571,7 +627,7 @@
 				spdxPkgID{"testdata/reciprocal/highest.apex.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/reciprocal/highest.apex.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/reciprocal/highest.apex.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/reciprocal/bin/bin1.meta_lic"},
 				packageName{"testdata/reciprocal/bin/bin1.meta_lic"},
 				spdxPkgID{"testdata/reciprocal/bin/bin1.meta_lic"},
@@ -625,6 +681,13 @@
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/notice/NOTICE_LICENSE",
 				"testdata/reciprocal/RECIPROCAL_LICENSE",
+				"testdata/reciprocal/bin/bin1.meta_lic",
+				"testdata/reciprocal/bin/bin2.meta_lic",
+				"testdata/reciprocal/highest.apex.meta_lic",
+				"testdata/reciprocal/lib/liba.so.meta_lic",
+				"testdata/reciprocal/lib/libb.so.meta_lic",
+				"testdata/reciprocal/lib/libc.a.meta_lic",
+				"testdata/reciprocal/lib/libd.so.meta_lic",
 			},
 		},
 		{
@@ -635,7 +698,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -644,7 +707,7 @@
 				spdxPkgID{"testdata/reciprocal/container.zip.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/reciprocal/container.zip.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/reciprocal/container.zip.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/reciprocal/bin/bin1.meta_lic"},
 				packageName{"testdata/reciprocal/bin/bin1.meta_lic"},
 				spdxPkgID{"testdata/reciprocal/bin/bin1.meta_lic"},
@@ -698,6 +761,13 @@
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/notice/NOTICE_LICENSE",
 				"testdata/reciprocal/RECIPROCAL_LICENSE",
+				"testdata/reciprocal/bin/bin1.meta_lic",
+				"testdata/reciprocal/bin/bin2.meta_lic",
+				"testdata/reciprocal/container.zip.meta_lic",
+				"testdata/reciprocal/lib/liba.so.meta_lic",
+				"testdata/reciprocal/lib/libb.so.meta_lic",
+				"testdata/reciprocal/lib/libc.a.meta_lic",
+				"testdata/reciprocal/lib/libd.so.meta_lic",
 			},
 		},
 		{
@@ -708,7 +778,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -717,7 +787,7 @@
 				spdxPkgID{"testdata/reciprocal/application.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/reciprocal/application.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/reciprocal/application.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/reciprocal/bin/bin3.meta_lic"},
 				packageName{"testdata/reciprocal/bin/bin3.meta_lic"},
 				spdxPkgID{"testdata/reciprocal/bin/bin3.meta_lic"},
@@ -751,6 +821,10 @@
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/notice/NOTICE_LICENSE",
 				"testdata/reciprocal/RECIPROCAL_LICENSE",
+				"testdata/reciprocal/application.meta_lic",
+				"testdata/reciprocal/bin/bin3.meta_lic",
+				"testdata/reciprocal/lib/liba.so.meta_lic",
+				"testdata/reciprocal/lib/libb.so.meta_lic",
 			},
 		},
 		{
@@ -761,7 +835,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -770,7 +844,7 @@
 				spdxPkgID{"testdata/reciprocal/bin/bin1.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/reciprocal/bin/bin1.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/reciprocal/bin/bin1.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/reciprocal/lib/liba.so.meta_lic"},
 				packageName{"testdata/reciprocal/lib/liba.so.meta_lic"},
 				spdxPkgID{"testdata/reciprocal/lib/liba.so.meta_lic"},
@@ -794,6 +868,9 @@
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/reciprocal/RECIPROCAL_LICENSE",
+				"testdata/reciprocal/bin/bin1.meta_lic",
+				"testdata/reciprocal/lib/liba.so.meta_lic",
+				"testdata/reciprocal/lib/libc.a.meta_lic",
 			},
 		},
 		{
@@ -804,7 +881,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -813,7 +890,7 @@
 				spdxPkgID{"testdata/reciprocal/lib/libd.so.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/reciprocal/lib/libd.so.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/reciprocal/lib/libd.so.meta_lic", "DESCRIBES"},
 				spdxLicense{},
 				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
 				spdxExtractedText{"%%%Notice License%%%"},
@@ -821,6 +898,7 @@
 			},
 			expectedDeps: []string{
 				"testdata/notice/NOTICE_LICENSE",
+				"testdata/reciprocal/lib/libd.so.meta_lic",
 			},
 		},
 		{
@@ -832,7 +910,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -841,7 +919,7 @@
 				spdxPkgID{"testdata/restricted/highest.apex.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/restricted/highest.apex.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/restricted/highest.apex.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/restricted/bin/bin1.meta_lic"},
 				packageName{"testdata/restricted/bin/bin1.meta_lic"},
 				spdxPkgID{"testdata/restricted/bin/bin1.meta_lic"},
@@ -899,6 +977,13 @@
 				"testdata/notice/NOTICE_LICENSE",
 				"testdata/reciprocal/RECIPROCAL_LICENSE",
 				"testdata/restricted/RESTRICTED_LICENSE",
+				"testdata/restricted/bin/bin1.meta_lic",
+				"testdata/restricted/bin/bin2.meta_lic",
+				"testdata/restricted/highest.apex.meta_lic",
+				"testdata/restricted/lib/liba.so.meta_lic",
+				"testdata/restricted/lib/libb.so.meta_lic",
+				"testdata/restricted/lib/libc.a.meta_lic",
+				"testdata/restricted/lib/libd.so.meta_lic",
 			},
 		},
 		{
@@ -910,7 +995,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -919,7 +1004,7 @@
 				spdxPkgID{"testdata/restricted/container.zip.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/restricted/container.zip.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/restricted/container.zip.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/restricted/bin/bin1.meta_lic"},
 				packageName{"testdata/restricted/bin/bin1.meta_lic"},
 				spdxPkgID{"testdata/restricted/bin/bin1.meta_lic"},
@@ -977,6 +1062,13 @@
 				"testdata/notice/NOTICE_LICENSE",
 				"testdata/reciprocal/RECIPROCAL_LICENSE",
 				"testdata/restricted/RESTRICTED_LICENSE",
+				"testdata/restricted/bin/bin1.meta_lic",
+				"testdata/restricted/bin/bin2.meta_lic",
+				"testdata/restricted/container.zip.meta_lic",
+				"testdata/restricted/lib/liba.so.meta_lic",
+				"testdata/restricted/lib/libb.so.meta_lic",
+				"testdata/restricted/lib/libc.a.meta_lic",
+				"testdata/restricted/lib/libd.so.meta_lic",
 			},
 		},
 		{
@@ -987,7 +1079,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -996,7 +1088,7 @@
 				spdxPkgID{"testdata/restricted/bin/bin1.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/restricted/bin/bin1.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/restricted/bin/bin1.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/restricted/lib/liba.so.meta_lic"},
 				packageName{"testdata/restricted/lib/liba.so.meta_lic"},
 				spdxPkgID{"testdata/restricted/lib/liba.so.meta_lic"},
@@ -1024,6 +1116,9 @@
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/reciprocal/RECIPROCAL_LICENSE",
 				"testdata/restricted/RESTRICTED_LICENSE",
+				"testdata/restricted/bin/bin1.meta_lic",
+				"testdata/restricted/lib/liba.so.meta_lic",
+				"testdata/restricted/lib/libc.a.meta_lic",
 			},
 		},
 		{
@@ -1034,7 +1129,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -1043,13 +1138,16 @@
 				spdxPkgID{"testdata/restricted/lib/libd.so.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/restricted/lib/libd.so.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/restricted/lib/libd.so.meta_lic", "DESCRIBES"},
 				spdxLicense{},
 				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
 				spdxExtractedText{"%%%Notice License%%%"},
 				spdxExtractedClosingText{},
 			},
-			expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+			expectedDeps: []string{
+				"testdata/notice/NOTICE_LICENSE",
+				"testdata/restricted/lib/libd.so.meta_lic",
+			},
 		},
 		{
 			condition: "proprietary",
@@ -1059,7 +1157,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -1068,7 +1166,7 @@
 				spdxPkgID{"testdata/proprietary/highest.apex.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/proprietary/highest.apex.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/proprietary/highest.apex.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/proprietary/bin/bin1.meta_lic"},
 				packageName{"testdata/proprietary/bin/bin1.meta_lic"},
 				spdxPkgID{"testdata/proprietary/bin/bin1.meta_lic"},
@@ -1125,6 +1223,13 @@
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/notice/NOTICE_LICENSE",
 				"testdata/proprietary/PROPRIETARY_LICENSE",
+				"testdata/proprietary/bin/bin1.meta_lic",
+				"testdata/proprietary/bin/bin2.meta_lic",
+				"testdata/proprietary/highest.apex.meta_lic",
+				"testdata/proprietary/lib/liba.so.meta_lic",
+				"testdata/proprietary/lib/libb.so.meta_lic",
+				"testdata/proprietary/lib/libc.a.meta_lic",
+				"testdata/proprietary/lib/libd.so.meta_lic",
 				"testdata/restricted/RESTRICTED_LICENSE",
 			},
 		},
@@ -1136,7 +1241,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -1145,7 +1250,7 @@
 				spdxPkgID{"testdata/proprietary/container.zip.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/proprietary/container.zip.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/proprietary/container.zip.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/proprietary/bin/bin1.meta_lic"},
 				packageName{"testdata/proprietary/bin/bin1.meta_lic"},
 				spdxPkgID{"testdata/proprietary/bin/bin1.meta_lic"},
@@ -1202,6 +1307,13 @@
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/notice/NOTICE_LICENSE",
 				"testdata/proprietary/PROPRIETARY_LICENSE",
+				"testdata/proprietary/bin/bin1.meta_lic",
+				"testdata/proprietary/bin/bin2.meta_lic",
+				"testdata/proprietary/container.zip.meta_lic",
+				"testdata/proprietary/lib/liba.so.meta_lic",
+				"testdata/proprietary/lib/libb.so.meta_lic",
+				"testdata/proprietary/lib/libc.a.meta_lic",
+				"testdata/proprietary/lib/libd.so.meta_lic",
 				"testdata/restricted/RESTRICTED_LICENSE",
 			},
 		},
@@ -1213,7 +1325,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -1222,7 +1334,7 @@
 				spdxPkgID{"testdata/proprietary/application.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/proprietary/application.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/proprietary/application.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/proprietary/bin/bin3.meta_lic"},
 				packageName{"testdata/proprietary/bin/bin3.meta_lic"},
 				spdxPkgID{"testdata/proprietary/bin/bin3.meta_lic"},
@@ -1255,6 +1367,10 @@
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/proprietary/PROPRIETARY_LICENSE",
+				"testdata/proprietary/application.meta_lic",
+				"testdata/proprietary/bin/bin3.meta_lic",
+				"testdata/proprietary/lib/liba.so.meta_lic",
+				"testdata/proprietary/lib/libb.so.meta_lic",
 				"testdata/restricted/RESTRICTED_LICENSE",
 			},
 		},
@@ -1266,7 +1382,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -1275,7 +1391,7 @@
 				spdxPkgID{"testdata/proprietary/bin/bin1.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-firstparty-FIRST_PARTY_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/proprietary/bin/bin1.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/proprietary/bin/bin1.meta_lic", "DESCRIBES"},
 				packageTag{"testdata/proprietary/lib/liba.so.meta_lic"},
 				packageName{"testdata/proprietary/lib/liba.so.meta_lic"},
 				spdxPkgID{"testdata/proprietary/lib/liba.so.meta_lic"},
@@ -1299,6 +1415,9 @@
 			expectedDeps: []string{
 				"testdata/firstparty/FIRST_PARTY_LICENSE",
 				"testdata/proprietary/PROPRIETARY_LICENSE",
+				"testdata/proprietary/bin/bin1.meta_lic",
+				"testdata/proprietary/lib/liba.so.meta_lic",
+				"testdata/proprietary/lib/libc.a.meta_lic",
 			},
 		},
 		{
@@ -1309,7 +1428,7 @@
 				spdxVersion{},
 				spdxDataLicense{},
 				spdxDocumentName{"Android"},
-				spdxID{"Android"},
+				spdxID{},
 				spdxDocumentNameSpace{},
 				spdxCreatorOrganization{},
 				spdxCreatedTime{},
@@ -1318,13 +1437,16 @@
 				spdxPkgID{"testdata/proprietary/lib/libd.so.meta_lic"},
 				spdxPkgDownloadLocation{"NOASSERTION"},
 				spdxPkgLicenseDeclared{"testdata-notice-NOTICE_LICENSE"},
-				spdxRelationship{"DOCUMENT-Android ", "testdata/proprietary/lib/libd.so.meta_lic", "DESCRIBES"},
+				spdxRelationship{"DOCUMENT ", "testdata/proprietary/lib/libd.so.meta_lic", "DESCRIBES"},
 				spdxLicense{},
 				spdxLicenseID{"testdata-notice-NOTICE_LICENSE"},
 				spdxExtractedText{"%%%Notice License%%%"},
 				spdxExtractedClosingText{},
 			},
-			expectedDeps: []string{"testdata/notice/NOTICE_LICENSE"},
+			expectedDeps: []string{
+				"testdata/notice/NOTICE_LICENSE",
+				"testdata/proprietary/lib/libd.so.meta_lic",
+			},
 		},
 	}
 	for _, tt := range tests {
@@ -1419,20 +1541,14 @@
 	return "PackageName: " + replaceSlashes(m.name)
 }
 
-type spdxID struct {
-	name string
-}
+type spdxID struct {}
 
 func (m spdxID) isMatch(line string) bool {
-	groups := spdxIDTag.FindStringSubmatch(line)
-	if len(groups) != 2 {
-		return false
-	}
-	return groups[1] == replaceSlashes(m.name)
+	return spdxIDTag.MatchString(line)
 }
 
 func (m spdxID) String() string {
-	return "SPDXID: SPDXRef-DOCUMENT-" + replaceSlashes(m.name)
+	return "SPDXID: SPDXRef-DOCUMENT"
 }
 
 type spdxPkgID struct {
@@ -1468,7 +1584,7 @@
 }
 
 func (m spdxDataLicense) String() string {
-	return "DataLicense: CC-1.0"
+	return "DataLicense: CC0-1.0"
 }
 
 type spdxDocumentName struct {
diff --git a/tools/compliance/graph.go b/tools/compliance/graph.go
index fac1d05..9ad319b 100644
--- a/tools/compliance/graph.go
+++ b/tools/compliance/graph.go
@@ -88,6 +88,15 @@
 	return targets
 }
 
+// TargetNames returns the list of target node names in the graph. (unordered)
+func (lg *LicenseGraph) TargetNames() []string {
+	targets := make([]string, 0, len(lg.targets))
+	for target := range lg.targets {
+		targets = append(targets, target)
+	}
+	return targets
+}
+
 // compliance-only LicenseGraph methods
 
 // newLicenseGraph constructs a new, empty instance of LicenseGraph.
diff --git a/tools/finalization/OWNERS b/tools/finalization/OWNERS
new file mode 100644
index 0000000..518b60d
--- /dev/null
+++ b/tools/finalization/OWNERS
@@ -0,0 +1,5 @@
+include platform/build/soong:/OWNERS
+smoreland@google.com
+alexbuy@google.com
+patb@google.com
+zyy@google.com
diff --git a/tools/finalization/cleanup.sh b/tools/finalization/cleanup.sh
new file mode 100755
index 0000000..cd87b1d
--- /dev/null
+++ b/tools/finalization/cleanup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Brings local repository to a remote head state.
+
+# set -ex
+
+function finalize_revert_local_changes_main() {
+    local top="$(dirname "$0")"/../../../..
+    local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+    # remove the out folder
+    $m clobber
+
+    repo selfupdate
+
+    repo forall -c '\
+        git checkout . ; git revert --abort ; git clean -fdx ;\
+        git checkout @ ; git branch fina-step1 -D ; git reset --hard; \
+        repo start fina-step1 ; git checkout @ ; git b fina-step1 -D ;'
+}
+
+finalize_revert_local_changes_main
diff --git a/tools/finalization/environment.sh b/tools/finalization/environment.sh
new file mode 100755
index 0000000..125c704
--- /dev/null
+++ b/tools/finalization/environment.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+set -ex
+
+export FINAL_BUG_ID='0'
+
+export FINAL_PLATFORM_CODENAME='UpsideDownCake'
+export FINAL_PLATFORM_CODENAME_JAVA='UPSIDE_DOWN_CAKE'
+export FINAL_PLATFORM_SDK_VERSION='34'
+export FINAL_PLATFORM_VERSION='14'
+
+export FINAL_BUILD_PREFIX='UP1A'
+
+export FINAL_MAINLINE_EXTENSION='6'
+export FINAL_MAINLINE_SDK_COMMIT_MESSAGE=''
+export FINAL_MAINLINE_SDK_BUILD_ID=0
diff --git a/tools/finalization/finalize-aidl-vndk-sdk-resources.sh b/tools/finalization/finalize-aidl-vndk-sdk-resources.sh
new file mode 100755
index 0000000..0426fdd
--- /dev/null
+++ b/tools/finalization/finalize-aidl-vndk-sdk-resources.sh
@@ -0,0 +1,96 @@
+#!/bin/bash
+
+set -ex
+
+function finalize_aidl_vndk_sdk_resources() {
+    local top="$(dirname "$0")"/../../../..
+    source $top/build/make/tools/finalization/environment.sh
+
+    local SDK_CODENAME="public static final int $FINAL_PLATFORM_CODENAME_JAVA = CUR_DEVELOPMENT;"
+    local SDK_VERSION="public static final int $FINAL_PLATFORM_CODENAME_JAVA = $FINAL_PLATFORM_SDK_VERSION;"
+
+    # default target to modify tree and build SDK
+    local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+    # This script is WIP and only finalizes part of the Android branch for release.
+    # The full process can be found at (INTERNAL) go/android-sdk-finalization.
+
+    # Update references in the codebase to new API version (TODO)
+
+    # bionic/NDK
+    # Adding __ANDROID_API_<>__.
+    # If this hasn't done then it's not used and not really needed. Still, let's check and add this.
+    if ! grep -q "\__.*$((${FINAL_PLATFORM_SDK_VERSION}))" api-level.h ; then
+        local tmpfile=$(mktemp /tmp/finalization.XXXXXX)
+        echo "
+/** Names the \"${FINAL_PLATFORM_CODENAME:0:1}\" API level ($FINAL_PLATFORM_SDK_VERSION), for comparison against \`__ANDROID_API__\`. */
+#define __ANDROID_API_${FINAL_PLATFORM_CODENAME:0:1}__ $FINAL_PLATFORM_SDK_VERSION" > "$tmpfile"
+
+        local api_level="$top/bionic/libc/include/android/api-level.h"
+        sed -i -e "/__.*$((${FINAL_PLATFORM_SDK_VERSION}-1))/r""$tmpfile" $api_level
+
+        rm "$tmpfile"
+    fi
+
+    # VNDK definitions for new SDK version
+    cp "$top/development/vndk/tools/definition-tool/datasets/vndk-lib-extra-list-current.txt" \
+       "$top/development/vndk/tools/definition-tool/datasets/vndk-lib-extra-list-$FINAL_PLATFORM_SDK_VERSION.txt"
+
+    AIDL_TRANSITIVE_FREEZE=true $m aidl-freeze-api create_reference_dumps
+
+    # Generate ABI dumps
+    ANDROID_BUILD_TOP="$top" \
+        out/host/linux-x86/bin/create_reference_dumps \
+        -p aosp_arm64 --build-variant user
+
+    echo "NOTE: THIS INTENTIONALLY MAY FAIL AND REPAIR ITSELF (until 'DONE')"
+    # Update new versions of files. See update-vndk-list.sh (which requires envsetup.sh)
+    $m check-vndk-list || \
+        { cp $top/out/soong/vndk/vndk.libraries.txt $top/build/make/target/product/gsi/current.txt; }
+    echo "DONE: THIS INTENTIONALLY MAY FAIL AND REPAIR ITSELF"
+
+    # Finalize SDK
+
+    # build/make
+    local version_defaults="$top/build/make/core/version_defaults.mk"
+    sed -i -e "s/PLATFORM_SDK_VERSION := .*/PLATFORM_SDK_VERSION := ${FINAL_PLATFORM_SDK_VERSION}/g" $version_defaults
+    sed -i -e "s/PLATFORM_VERSION_LAST_STABLE := .*/PLATFORM_VERSION_LAST_STABLE := ${FINAL_PLATFORM_VERSION}/g" $version_defaults
+    sed -i -e "s/sepolicy_major_vers := .*/sepolicy_major_vers := ${FINAL_PLATFORM_SDK_VERSION}/g" "$top/build/make/core/config.mk"
+    cp "$top/build/make/target/product/gsi/current.txt" "$top/build/make/target/product/gsi/$FINAL_PLATFORM_SDK_VERSION.txt"
+
+    # build/soong
+    sed -i -e "/:.*$((${FINAL_PLATFORM_SDK_VERSION}-1)),/a \\\t\t\t\"${FINAL_PLATFORM_CODENAME}\":     ${FINAL_PLATFORM_SDK_VERSION}," "$top/build/soong/android/api_levels.go"
+
+    # cts
+    echo ${FINAL_PLATFORM_VERSION} > "$top/cts/tests/tests/os/assets/platform_releases.txt"
+    sed -i -e "s/EXPECTED_SDK = $((${FINAL_PLATFORM_SDK_VERSION}-1))/EXPECTED_SDK = ${FINAL_PLATFORM_SDK_VERSION}/g" "$top/cts/tests/tests/os/src/android/os/cts/BuildVersionTest.java"
+
+    # libcore
+    sed -i "s%$SDK_CODENAME%$SDK_VERSION%g" "$top/libcore/dalvik/src/main/java/dalvik/annotation/compat/VersionCodes.java"
+
+    # platform_testing
+    local version_codes="$top/platform_testing/libraries/compatibility-common-util/src/com/android/compatibility/common/util/VersionCodes.java"
+    sed -i -e "/=.*$((${FINAL_PLATFORM_SDK_VERSION}-1));/a \\    ${SDK_VERSION}" $version_codes
+
+    # Finalize resources
+    "$top/frameworks/base/tools/aapt2/tools/finalize_res.py" \
+           "$top/frameworks/base/core/res/res/values/public-staging.xml" \
+           "$top/frameworks/base/core/res/res/values/public-final.xml"
+
+    # frameworks/base
+    sed -i "s%$SDK_CODENAME%$SDK_VERSION%g" "$top/frameworks/base/core/java/android/os/Build.java"
+    sed -i -e "/=.*$((${FINAL_PLATFORM_SDK_VERSION}-1)),/a \\    SDK_${FINAL_PLATFORM_CODENAME_JAVA} = ${FINAL_PLATFORM_SDK_VERSION}," "$top/frameworks/base/tools/aapt/SdkConstants.h"
+    sed -i -e "/=.*$((${FINAL_PLATFORM_SDK_VERSION}-1)),/a \\  SDK_${FINAL_PLATFORM_CODENAME_JAVA} = ${FINAL_PLATFORM_SDK_VERSION}," "$top/frameworks/base/tools/aapt2/SdkConstants.h"
+
+    # Bump Mainline SDK extension version.
+    "$top/packages/modules/SdkExtensions/gen_sdk/bump_sdk.sh" ${FINAL_MAINLINE_EXTENSION}
+    local version_defaults="$top/build/make/core/version_defaults.mk"
+    sed -i -e "s/PLATFORM_SDK_EXTENSION_VERSION := .*/PLATFORM_SDK_EXTENSION_VERSION := ${FINAL_MAINLINE_EXTENSION}/g" $version_defaults
+
+    # Force update current.txt
+    $m clobber
+    $m update-api
+}
+
+finalize_aidl_vndk_sdk_resources
+
diff --git a/tools/finalization/finalize-sdk-rel.sh b/tools/finalization/finalize-sdk-rel.sh
new file mode 100755
index 0000000..6e62a0e
--- /dev/null
+++ b/tools/finalization/finalize-sdk-rel.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+set -ex
+
+function finalize_sdk_rel() {
+    local top="$(dirname "$0")"/../../../..
+    source $top/build/make/tools/finalization/environment.sh
+
+    # default target to modify tree and build SDK
+    local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+    # adb keys
+    $m adb
+    LOGNAME=android-eng HOSTNAME=google.com "$top/out/host/linux-x86/bin/adb" keygen "$top/vendor/google/security/adb/${FINAL_PLATFORM_VERSION}.adb_key"
+
+    # build/make/core/version_defaults.mk
+    sed -i -e "s/PLATFORM_VERSION_CODENAME.${FINAL_BUILD_PREFIX} := .*/PLATFORM_VERSION_CODENAME.${FINAL_BUILD_PREFIX} := REL/g" "$top/build/make/core/version_defaults.mk"
+
+    # cts
+    echo "$FINAL_PLATFORM_VERSION" > "$top/cts/tests/tests/os/assets/platform_versions.txt"
+    git -C "$top/cts" mv hostsidetests/theme/assets/${FINAL_PLATFORM_CODENAME} hostsidetests/theme/assets/${FINAL_PLATFORM_SDK_VERSION}
+
+    # system/sepolicy
+    mkdir -p "$top/system/sepolicy/prebuilts/api/${FINAL_PLATFORM_SDK_VERSION}.0/"
+    cp -r "$top/system/sepolicy/public/" "$top/system/sepolicy/prebuilts/api/${FINAL_PLATFORM_SDK_VERSION}.0/"
+    cp -r "$top/system/sepolicy/private/" "$top/system/sepolicy/prebuilts/api/${FINAL_PLATFORM_SDK_VERSION}.0/"
+
+    # prebuilts/abi-dumps/ndk
+    mv "$top/prebuilts/abi-dumps/ndk/current" "$top/prebuilts/abi-dumps/ndk/$FINAL_PLATFORM_SDK_VERSION"
+
+    # prebuilts/abi-dumps/vndk
+    mv "$top/prebuilts/abi-dumps/vndk/$FINAL_PLATFORM_CODENAME" "$top/prebuilts/abi-dumps/vndk/$FINAL_PLATFORM_SDK_VERSION"
+
+    # prebuilts/abi-dumps/platform
+    mv "$top/prebuilts/abi-dumps/platform/current" "$top/prebuilts/abi-dumps/platform/$FINAL_PLATFORM_SDK_VERSION"
+}
+
+finalize_sdk_rel
+
diff --git a/tools/finalization/localonly-finalize-mainline-sdk.sh b/tools/finalization/localonly-finalize-mainline-sdk.sh
new file mode 100755
index 0000000..fc887c3
--- /dev/null
+++ b/tools/finalization/localonly-finalize-mainline-sdk.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -ex
+
+function finalize_locally_mainline_sdk() {
+    local top="$(dirname "$0")"/../../../..
+    source $top/build/make/tools/finalization/environment.sh
+
+    # Build modules SDKs.
+    TARGET_BUILD_VARIANT=userdebug UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true "$top/vendor/google/build/mainline_modules_sdks.sh"
+
+    # Update prebuilts.
+    "$top/prebuilts/build-tools/path/linux-x86/python3" "$top/packages/modules/common/tools/finalize_sdk.py" -l -b 0 -f ${FINAL_MAINLINE_EXTENSION} -r '' 0
+}
+
+finalize_locally_mainline_sdk
+
diff --git a/tools/finalization/step-1.sh b/tools/finalization/step-1.sh
new file mode 100755
index 0000000..db7f1cc
--- /dev/null
+++ b/tools/finalization/step-1.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# Script to perform a 1st step of Android Finalization: API/SDK finalization, create CLs and upload to Gerrit.
+
+set -ex
+
+function commit_step_1_changes() {
+    set +e
+    repo forall -c '\
+        if [[ $(git status --short) ]]; then
+            repo start "$FINAL_PLATFORM_CODENAME-SDK-Finalization" ;
+            git add -A . ;
+            git commit -m "$FINAL_PLATFORM_CODENAME is now $FINAL_PLATFORM_SDK_VERSION" \
+                       -m "Ignore-AOSP-First: $FINAL_PLATFORM_CODENAME Finalization
+Bug: $FINAL_BUG_ID
+Test: build";
+            repo upload --cbr --no-verify -o nokeycheck -t -y . ;
+            git clean -fdx ; git reset --hard ;
+        fi'
+}
+
+function finalize_step_1_main() {
+    local top="$(dirname "$0")"/../../../..
+    source $top/build/make/tools/finalization/environment.sh
+
+    local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+    # vndk etc finalization
+    source $top/build/make/tools/finalization/finalize-aidl-vndk-sdk-resources.sh
+
+    # build to confirm everything is OK
+    AIDL_FROZEN_REL=true $m
+
+    # move all changes to finalization branch/topic and upload to gerrit
+    commit_step_1_changes
+}
+
+finalize_step_1_main
diff --git a/tools/finalization/step-2.sh b/tools/finalization/step-2.sh
new file mode 100755
index 0000000..926b850
--- /dev/null
+++ b/tools/finalization/step-2.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# Script to perform a 2nd step of Android Finalization: REL finalization, create CLs and upload to Gerrit.
+
+function commit_step_2_changes() {
+    repo forall -c '\
+        if [[ $(git status --short) ]]; then
+            repo start "$FINAL_PLATFORM_CODENAME-SDK-Finalization-Rel" ;
+            git add -A . ;
+            git commit -m "$FINAL_PLATFORM_CODENAME/$FINAL_PLATFORM_SDK_VERSION is now REL" \
+                       -m "Ignore-AOSP-First: $FINAL_PLATFORM_CODENAME Finalization
+Bug: $FINAL_BUG_ID
+Test: build";
+
+            repo upload --cbr --no-verify -o nokeycheck -t -y . ;
+            git clean -fdx ; git reset --hard ;
+        fi'
+}
+
+function finalize_step_2_main() {
+    local top="$(dirname "$0")"/../../../..
+    source $top/build/make/tools/finalization/environment.sh
+
+    local m="$top/build/soong/soong_ui.bash --make-mode TARGET_PRODUCT=aosp_arm64 TARGET_BUILD_VARIANT=userdebug"
+
+    # prebuilts etc
+    source $top/build/make/tools/finalization/finalize-sdk-rel.sh
+
+    # Update prebuilts.
+    "$top/prebuilts/build-tools/path/linux-x86/python3" "$top/packages/modules/common/tools/finalize_sdk.py" -b ${FINAL_BUG_ID} -f ${FINAL_MAINLINE_EXTENSION} -r "${FINAL_MAINLINE_SDK_COMMIT_MESSAGE}" ${FINAL_MAINLINE_SDK_BUILD_ID}
+
+    # build to confirm everything is OK
+    AIDL_FROZEN_REL=true $m
+
+    # move all changes to finalization branch/topic and upload to gerrit
+    commit_step_2_changes
+}
+
+finalize_step_2_main
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index d308a55..b45b0a3 100644
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -1132,6 +1132,21 @@
           item for item in vbmeta_partitions
           if item not in vbmeta_vendor.split()]
       vbmeta_partitions.append("vbmeta_vendor")
+    custom_avb_partitions = OPTIONS.info_dict.get("avb_custom_vbmeta_images_partition_list", "").strip().split()
+    if custom_avb_partitions:
+      for avb_part in custom_avb_partitions:
+        partition_name = "vbmeta_" + avb_part
+        included_partitions = OPTIONS.info_dict.get("avb_vbmeta_{}".format(avb_part), "").strip().split()
+        assert included_partitions, "Custom vbmeta partition {0} missing avb_vbmeta_{0} prop".format(avb_part)
+        banner(partition_name)
+        logger.info("VBMeta partition {} needs {}".format(partition_name, included_partitions))
+        partitions[partition_name] = AddVBMeta(
+            output_zip, partitions, partition_name, included_partitions)
+        vbmeta_partitions = [
+            item for item in vbmeta_partitions
+            if item not in included_partitions]
+        vbmeta_partitions.append(partition_name)
+
 
     if OPTIONS.info_dict.get("avb_building_vbmeta_image") == "true":
       banner("vbmeta")
diff --git a/tools/releasetools/apex_utils.py b/tools/releasetools/apex_utils.py
index 194ff58..40f7c92 100644
--- a/tools/releasetools/apex_utils.py
+++ b/tools/releasetools/apex_utils.py
@@ -66,7 +66,7 @@
     self.fsckerofs_path = os.path.join(
         OPTIONS.search_path, "bin", "fsck.erofs")
     self.blkid_path = os.path.join(
-        OPTIONS.search_path, "bin", "blkid")
+        OPTIONS.search_path, "bin", "blkid_static")
     self.avbtool = avbtool if avbtool else "avbtool"
     self.sign_tool = sign_tool
 
diff --git a/tools/releasetools/check_target_files_vintf.py b/tools/releasetools/check_target_files_vintf.py
index a254cab..5b71c72 100755
--- a/tools/releasetools/check_target_files_vintf.py
+++ b/tools/releasetools/check_target_files_vintf.py
@@ -237,7 +237,7 @@
   if OPTIONS.search_path:
     debugfs_path = os.path.join(OPTIONS.search_path, 'bin', 'debugfs_static')
     deapexer_path = os.path.join(OPTIONS.search_path, 'bin', 'deapexer')
-    blkid_path = os.path.join(OPTIONS.search_path, 'bin', 'blkid')
+    blkid_path = os.path.join(OPTIONS.search_path, 'bin', 'blkid_static')
     fsckerofs_path = os.path.join(OPTIONS.search_path, 'bin', 'fsck.erofs')
     if os.path.isfile(deapexer_path):
       deapexer = deapexer_path
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 2f05d44..9919029 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1503,12 +1503,14 @@
 
   custom_partitions = OPTIONS.info_dict.get(
       "avb_custom_images_partition_list", "").strip().split()
+  custom_avb_partitions = ["vbmeta_" + part for part in OPTIONS.info_dict.get("avb_custom_vbmeta_images_partition_list", "").strip().split()]
 
   for partition, path in partitions.items():
     if partition not in needed_partitions:
       continue
     assert (partition in AVB_PARTITIONS or
             partition in AVB_VBMETA_PARTITIONS or
+            partition in custom_avb_partitions or
             partition in custom_partitions), \
         'Unknown partition: {}'.format(partition)
     assert os.path.exists(path), \
diff --git a/tools/releasetools/non_ab_ota.py b/tools/releasetools/non_ab_ota.py
index ac85aa4..7078d67 100644
--- a/tools/releasetools/non_ab_ota.py
+++ b/tools/releasetools/non_ab_ota.py
@@ -48,17 +48,12 @@
     # if the filesystem is ext4.
     partition_source_info = source_info["fstab"]["/" + name]
     check_first_block = partition_source_info.fs_type == "ext4"
-    # Disable using imgdiff for squashfs. 'imgdiff -z' expects input files to be
-    # in zip formats. However with squashfs, a) all files are compressed in LZ4;
-    # b) the blocks listed in block map may not contain all the bytes for a
-    # given file (because they're rounded to be 4K-aligned).
-    partition_target_info = target_info["fstab"]["/" + name]
-    disable_imgdiff = (partition_source_info.fs_type == "squashfs" or
-                       partition_target_info.fs_type == "squashfs")
+    # Disable imgdiff because it relies on zlib to produce stable output
+    # across different versions, which is often not the case.
     return common.BlockDifference(name, partition_tgt, partition_src,
                                   check_first_block,
                                   version=blockimgdiff_version,
-                                  disable_imgdiff=disable_imgdiff)
+                                  disable_imgdiff=True)
 
   if source_zip:
     # See notes in common.GetUserImage()
@@ -282,7 +277,7 @@
   needed_property_files = (
       NonAbOtaPropertyFiles(),
   )
-  FinalizeMetadata(metadata, staging_file, output_file, needed_property_files)
+  FinalizeMetadata(metadata, staging_file, output_file, needed_property_files, package_key=OPTIONS.package_key)
 
 
 def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_file):
@@ -409,7 +404,7 @@
   if updating_boot:
     boot_type, boot_device_expr = common.GetTypeAndDeviceExpr("/boot",
                                                               source_info)
-    d = common.Difference(target_boot, source_boot)
+    d = common.Difference(target_boot, source_boot, "bsdiff")
     _, _, d = d.ComputePatch()
     if d is None:
       include_full_boot = True
@@ -537,7 +532,7 @@
   needed_property_files = (
       NonAbOtaPropertyFiles(),
   )
-  FinalizeMetadata(metadata, staging_file, output_file, needed_property_files)
+  FinalizeMetadata(metadata, staging_file, output_file, needed_property_files, package_key=OPTIONS.package_key)
 
 
 def GenerateNonAbOtaPackage(target_file, output_file, source_file=None):
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 60e95ad..d6c39c6 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -205,7 +205,8 @@
 
   --partial "<PARTITION> [<PARTITION>[...]]"
       Generate partial updates, overriding ab_partitions list with the given
-      list.
+      list. Specify --partial= without partition list to let tooling auto detect
+      partial partition list.
 
   --custom_image <custom_partition=custom_image>
       Use the specified custom_image to update custom_partition when generating
@@ -856,6 +857,31 @@
     target_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
     source_info = None
 
+  if OPTIONS.partial == []:
+    logger.info(
+        "Automatically detecting partial partition list from input target files.")
+    OPTIONS.partial = target_info.get(
+        "partial_ota_update_partitions_list").split()
+    assert OPTIONS.partial, "Input target_file does not have"
+    " partial_ota_update_partitions_list defined, failed to auto detect partial"
+    " partition list. Please specify list of partitions to update manually via"
+    " --partial=a,b,c , or generate a complete OTA by removing the --partial"
+    " option"
+    OPTIONS.partial.sort()
+    if source_info:
+      source_partial_list = source_info.get(
+          "partial_ota_update_partitions_list").split()
+      if source_partial_list:
+        source_partial_list.sort()
+        if source_partial_list != OPTIONS.partial:
+          logger.warning("Source build and target build have different partial partition lists. Source: %s, target: %s, taking the intersection.",
+                         source_partial_list, OPTIONS.partial)
+          OPTIONS.partial = list(
+              set(OPTIONS.partial) and set(source_partial_list))
+          OPTIONS.partial.sort()
+    logger.info("Automatically deduced partial partition list: %s",
+                OPTIONS.partial)
+
   if target_info.vendor_suppressed_vabc:
     logger.info("Vendor suppressed VABC. Disabling")
     OPTIONS.disable_vabc = True
@@ -1107,9 +1133,12 @@
     elif o == "--boot_variable_file":
       OPTIONS.boot_variable_file = a
     elif o == "--partial":
-      partitions = a.split()
-      if not partitions:
-        raise ValueError("Cannot parse partitions in {}".format(a))
+      if a:
+        partitions = a.split()
+        if not partitions:
+          raise ValueError("Cannot parse partitions in {}".format(a))
+      else:
+        partitions = []
       OPTIONS.partial = partitions
     elif o == "--custom_image":
       custom_partition, custom_image = a.split("=")
@@ -1190,13 +1219,12 @@
                                  "vabc_compression_param=",
                                  "security_patch_level=",
                              ], extra_option_handler=option_handler)
+  common.InitLogging()
 
   if len(args) != 2:
     common.Usage(__doc__)
     sys.exit(1)
 
-  common.InitLogging()
-
   # Load the build info dicts from the zip directly or the extracted input
   # directory. We don't need to unzip the entire target-files zips, because they
   # won't be needed for A/B OTAs (brillo_update_payload does that on its own).
diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py
index e36a2be..e2ce31d 100644
--- a/tools/releasetools/ota_utils.py
+++ b/tools/releasetools/ota_utils.py
@@ -132,8 +132,10 @@
 
   # Re-sign the package after updating the metadata entry.
   if no_signing:
+    logger.info(f"Signing disabled for output file {output_file}")
     shutil.copy(prelim_signing, output_file)
   else:
+    logger.info(f"Signing the output file {output_file} with key {package_key}")
     SignOutput(prelim_signing, output_file, package_key, pw)
 
   # Reopen the final signed zip to double check the streaming metadata.
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 5f48dd0..4a12e74 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -531,7 +531,14 @@
       # RECOVERY/RAMDISK/default.prop is a legacy path, but will always exist
       # as a symlink in the current code. So it's a no-op here. Keeping the
       # path here for clarity.
-      "RECOVERY/RAMDISK/default.prop") or filename.endswith("build.prop")
+      # Some build props might be stored under path
+      # VENDOR_BOOT/RAMDISK_FRAGMENTS/recovery/RAMDISK/default.prop, and
+      # default.prop can be a symbolic link to prop.default, so overwrite all
+      # files that ends with build.prop, default.prop or prop.default
+      "RECOVERY/RAMDISK/default.prop") or \
+        filename.endswith("build.prop") or \
+        filename.endswith("/default.prop") or \
+        filename.endswith("/prop.default")
 
 
 def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
diff --git a/tools/signapk/Android.bp b/tools/signapk/Android.bp
index bee6a6f..c4f25f8 100644
--- a/tools/signapk/Android.bp
+++ b/tools/signapk/Android.bp
@@ -31,6 +31,10 @@
         "conscrypt-unbundled",
     ],
 
+    // b/267608166: Prevent target Java 17 so the host-side tool can run in an
+    // environment where JDK 11 is available.
+    java_version: "11",
+
     jni_libs: ["libconscrypt_openjdk_jni"],
 
     // The post-build signing tools need signapk.jar (and its shared libraries,
diff --git a/tools/warn/tidy_warn_patterns.py b/tools/warn/tidy_warn_patterns.py
index c138f1c..5ee66c0 100644
--- a/tools/warn/tidy_warn_patterns.py
+++ b/tools/warn/tidy_warn_patterns.py
@@ -224,6 +224,7 @@
     analyzer_warn_check('clang-analyzer-valist.Unterminated'),
     analyzer_group_check('clang-analyzer-core.uninitialized'),
     analyzer_group_check('clang-analyzer-deadcode'),
+    analyzer_warn_check('clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling'),
     analyzer_warn_check('clang-analyzer-security.insecureAPI.bcmp'),
     analyzer_warn_check('clang-analyzer-security.insecureAPI.bcopy'),
     analyzer_warn_check('clang-analyzer-security.insecureAPI.bzero'),
diff --git a/tools/zipalign/ZipEntry.cpp b/tools/zipalign/ZipEntry.cpp
index fcad96c..689999e 100644
--- a/tools/zipalign/ZipEntry.cpp
+++ b/tools/zipalign/ZipEntry.cpp
@@ -40,14 +40,10 @@
  */
 status_t ZipEntry::initFromCDE(FILE* fp)
 {
-    status_t result;
-    long posn; // NOLINT(google-runtime-int), for ftell/fseek
-    bool hasDD;
-
     //ALOGV("initFromCDE ---\n");
 
     /* read the CDE */
-    result = mCDE.read(fp);
+    status_t result = mCDE.read(fp);
     if (result != OK) {
         ALOGD("mCDE.read failed\n");
         return result;
@@ -56,8 +52,8 @@
     //mCDE.dump();
 
     /* using the info in the CDE, go load up the LFH */
-    posn = ftell(fp);
-    if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
+    off_t posn = ftello(fp);
+    if (fseeko(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
         ALOGD("local header seek failed (%" PRIu32 ")\n",
             mCDE.mLocalHeaderRelOffset);
         return UNKNOWN_ERROR;
@@ -69,7 +65,7 @@
         return result;
     }
 
-    if (fseek(fp, posn, SEEK_SET) != 0)
+    if (fseeko(fp, posn, SEEK_SET) != 0)
         return UNKNOWN_ERROR;
 
     //mLFH.dump();
@@ -80,7 +76,7 @@
      * compressed size, and uncompressed size will be zero.  In practice
      * these seem to be rare.
      */
-    hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;
+    bool hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;
     if (hasDD) {
         // do something clever
         //ALOGD("+++ has data descriptor\n");
diff --git a/tools/zipalign/ZipFile.cpp b/tools/zipalign/ZipFile.cpp
index f2f65a6..42cc349 100644
--- a/tools/zipalign/ZipFile.cpp
+++ b/tools/zipalign/ZipFile.cpp
@@ -35,6 +35,8 @@
 #include <assert.h>
 #include <inttypes.h>
 
+_Static_assert(sizeof(off_t) == 8, "off_t too small");
+
 namespace android {
 
 /*
@@ -205,56 +207,43 @@
  */
 status_t ZipFile::readCentralDir(void)
 {
-    status_t result = OK;
-    uint8_t* buf = NULL;
-    off_t fileLength, seekStart;
-    long readAmount;
-    int i;
-
-    fseek(mZipFp, 0, SEEK_END);
-    fileLength = ftell(mZipFp);
+    fseeko(mZipFp, 0, SEEK_END);
+    off_t fileLength = ftello(mZipFp);
     rewind(mZipFp);
 
     /* too small to be a ZIP archive? */
     if (fileLength < EndOfCentralDir::kEOCDLen) {
-        ALOGD("Length is %ld -- too small\n", (long)fileLength);
-        result = INVALID_OPERATION;
-        goto bail;
+        ALOGD("Length is %lld -- too small\n", (long long) fileLength);
+        return INVALID_OPERATION;
     }
 
-    buf = new uint8_t[EndOfCentralDir::kMaxEOCDSearch];
-    if (buf == NULL) {
-        ALOGD("Failure allocating %d bytes for EOCD search",
-             EndOfCentralDir::kMaxEOCDSearch);
-        result = NO_MEMORY;
-        goto bail;
-    }
-
+    off_t seekStart;
+    size_t readAmount;
     if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {
         seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;
         readAmount = EndOfCentralDir::kMaxEOCDSearch;
     } else {
         seekStart = 0;
-        readAmount = (long) fileLength;
+        readAmount = fileLength;
     }
-    if (fseek(mZipFp, seekStart, SEEK_SET) != 0) {
-        ALOGD("Failure seeking to end of zip at %ld", (long) seekStart);
-        result = UNKNOWN_ERROR;
-        goto bail;
+    if (fseeko(mZipFp, seekStart, SEEK_SET) != 0) {
+        ALOGD("Failure seeking to end of zip at %lld", (long long) seekStart);
+        return UNKNOWN_ERROR;
     }
 
     /* read the last part of the file into the buffer */
-    if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) {
+    uint8_t buf[EndOfCentralDir::kMaxEOCDSearch];
+    if (fread(buf, 1, readAmount, mZipFp) != readAmount) {
         if (feof(mZipFp)) {
-            ALOGW("fread %ld bytes failed, unexpected EOF", readAmount);
+            ALOGW("fread %zu bytes failed, unexpected EOF", readAmount);
         } else {
-            ALOGW("fread %ld bytes failed, %s", readAmount, strerror(errno));
+            ALOGW("fread %zu bytes failed, %s", readAmount, strerror(errno));
         }
-        result = UNKNOWN_ERROR;
-        goto bail;
+        return UNKNOWN_ERROR;
     }
 
     /* find the end-of-central-dir magic */
+    int i;
     for (i = readAmount - 4; i >= 0; i--) {
         if (buf[i] == 0x50 &&
             ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)
@@ -265,15 +254,14 @@
     }
     if (i < 0) {
         ALOGD("EOCD not found, not Zip\n");
-        result = INVALID_OPERATION;
-        goto bail;
+        return INVALID_OPERATION;
     }
 
     /* extract eocd values */
-    result = mEOCD.readBuf(buf + i, readAmount - i);
+    status_t result = mEOCD.readBuf(buf + i, readAmount - i);
     if (result != OK) {
-        ALOGD("Failure reading %ld bytes of EOCD values", readAmount - i);
-        goto bail;
+        ALOGD("Failure reading %zu bytes of EOCD values", readAmount - i);
+        return result;
     }
     //mEOCD.dump();
 
@@ -281,8 +269,7 @@
         mEOCD.mNumEntries != mEOCD.mTotalNumEntries)
     {
         ALOGD("Archive spanning not supported\n");
-        result = INVALID_OPERATION;
-        goto bail;
+        return INVALID_OPERATION;
     }
 
     /*
@@ -299,11 +286,10 @@
      * The only thing we really need right now is the file comment, which
      * we're hoping to preserve.
      */
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+    if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
         ALOGD("Failure seeking to central dir offset %" PRIu32 "\n",
              mEOCD.mCentralDirOffset);
-        result = UNKNOWN_ERROR;
-        goto bail;
+        return UNKNOWN_ERROR;
     }
 
     /*
@@ -318,7 +304,7 @@
         if (result != OK) {
             ALOGD("initFromCDE failed\n");
             delete pEntry;
-            goto bail;
+            return result;
         }
 
         mEntries.add(pEntry);
@@ -336,20 +322,16 @@
             } else {
                 ALOGW("fread EOCD failed, %s", strerror(errno));
             }
-            result = INVALID_OPERATION;
-            goto bail;
+            return INVALID_OPERATION;
         }
         if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {
             ALOGD("EOCD read check failed\n");
-            result = UNKNOWN_ERROR;
-            goto bail;
+            return UNKNOWN_ERROR;
         }
         ALOGV("+++ EOCD read check passed\n");
     }
 
-bail:
-    delete[] buf;
-    return result;
+    return OK;
 }
 
 
@@ -370,9 +352,8 @@
 {
     ZipEntry* pEntry = NULL;
     status_t result = OK;
-    long lfhPosn, startPosn, endPosn, uncompressedLen;
-    FILE* inputFp = NULL;
-    uint32_t crc;
+    off_t lfhPosn, startPosn, endPosn, uncompressedLen;
+    uint32_t crc = 0;
     time_t modWhen;
 
     if (mReadOnly)
@@ -389,13 +370,14 @@
     if (getEntryByName(storageName) != NULL)
         return ALREADY_EXISTS;
 
+    FILE* inputFp = NULL;
     if (!data) {
         inputFp = fopen(fileName, FILE_OPEN_RO);
         if (inputFp == NULL)
             return errnoToStatus(errno);
     }
 
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+    if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
         result = UNKNOWN_ERROR;
         goto bail;
     }
@@ -413,9 +395,9 @@
      * as a place-holder.  In theory the LFH isn't necessary, but in
      * practice some utilities demand it.
      */
-    lfhPosn = ftell(mZipFp);
+    lfhPosn = ftello(mZipFp);
     pEntry->mLFH.write(mZipFp);
-    startPosn = ftell(mZipFp);
+    startPosn = ftello(mZipFp);
 
     /*
      * Copy the data in, possibly compressing it as we go.
@@ -432,11 +414,11 @@
              * to be set through an API call, but I don't expect our
              * criteria to change over time.
              */
-            long src = inputFp ? ftell(inputFp) : size;
-            long dst = ftell(mZipFp) - startPosn;
+            off_t src = inputFp ? ftello(inputFp) : size;
+            off_t dst = ftello(mZipFp) - startPosn;
             if (dst + (dst / 10) > src) {
-                ALOGD("insufficient compression (src=%ld dst=%ld), storing\n",
-                    src, dst);
+                ALOGD("insufficient compression (src=%lld dst=%lld), storing\n",
+                    (long long) src, (long long) dst);
                 failed = true;
             }
         }
@@ -444,7 +426,7 @@
         if (failed) {
             compressionMethod = ZipEntry::kCompressStored;
             if (inputFp) rewind(inputFp);
-            fseek(mZipFp, startPosn, SEEK_SET);
+            fseeko(mZipFp, startPosn, SEEK_SET);
             /* fall through to kCompressStored case */
         }
     }
@@ -463,7 +445,7 @@
     }
 
     // currently seeked to end of file
-    uncompressedLen = inputFp ? ftell(inputFp) : size;
+    uncompressedLen = inputFp ? ftello(inputFp) : size;
 
     /*
      * We could write the "Data Descriptor", but there doesn't seem to
@@ -471,7 +453,7 @@
      *
      * Update file offsets.
      */
-    endPosn = ftell(mZipFp);            // seeked to end of compressed data
+    endPosn = ftello(mZipFp);            // seeked to end of compressed data
 
     /*
      * Success!  Fill out new values.
@@ -489,7 +471,7 @@
     /*
      * Go back and write the LFH.
      */
-    if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {
+    if (fseeko(mZipFp, lfhPosn, SEEK_SET) != 0) {
         result = UNKNOWN_ERROR;
         goto bail;
     }
@@ -522,7 +504,7 @@
 
     // Calculate where the entry payload offset will end up if we were to write
     // it as-is.
-    uint64_t expectedPayloadOffset = ftell(mZipFp) +
+    uint64_t expectedPayloadOffset = ftello(mZipFp) +
         android::ZipEntry::LocalFileHeader::kLFHLen +
         pEntry->mLFH.mFileNameLength +
         pEntry->mLFH.mExtraFieldLength;
@@ -548,7 +530,7 @@
 {
     ZipEntry* pEntry = NULL;
     status_t result;
-    long lfhPosn, endPosn;
+    off_t lfhPosn, endPosn;
 
     if (mReadOnly)
         return INVALID_OPERATION;
@@ -557,7 +539,7 @@
     assert(mZipFp != NULL);
     assert(mEntries.size() == mEOCD.mTotalNumEntries);
 
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+    if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
         result = UNKNOWN_ERROR;
         goto bail;
     }
@@ -585,7 +567,7 @@
      * Write the LFH.  Since we're not recompressing the data, we already
      * have all of the fields filled out.
      */
-    lfhPosn = ftell(mZipFp);
+    lfhPosn = ftello(mZipFp);
     pEntry->mLFH.write(mZipFp);
 
     /*
@@ -595,8 +577,7 @@
      * fields as well.  This is a fixed-size area immediately following
      * the data.
      */
-    if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)
-    {
+    if (fseeko(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0) {
         result = UNKNOWN_ERROR;
         goto bail;
     }
@@ -617,7 +598,7 @@
     /*
      * Update file offsets.
      */
-    endPosn = ftell(mZipFp);
+    endPosn = ftello(mZipFp);
 
     /*
      * Success!  Fill out new values.
@@ -654,7 +635,7 @@
 {
     ZipEntry* pEntry = NULL;
     status_t result;
-    long lfhPosn, uncompressedLen;
+    off_t lfhPosn, uncompressedLen;
 
     if (mReadOnly)
         return INVALID_OPERATION;
@@ -663,7 +644,7 @@
     assert(mZipFp != NULL);
     assert(mEntries.size() == mEOCD.mTotalNumEntries);
 
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+    if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
         result = UNKNOWN_ERROR;
         goto bail;
     }
@@ -688,7 +669,7 @@
      * as a place-holder.  In theory the LFH isn't necessary, but in
      * practice some utilities demand it.
      */
-    lfhPosn = ftell(mZipFp);
+    lfhPosn = ftello(mZipFp);
     pEntry->mLFH.write(mZipFp);
 
     /*
@@ -698,8 +679,7 @@
      * fields as well.  This is a fixed-size area immediately following
      * the data.
      */
-    if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)
-    {
+    if (fseeko(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0) {
         result = UNKNOWN_ERROR;
         goto bail;
     }
@@ -712,7 +692,7 @@
             result = NO_MEMORY;
             goto bail;
         }
-        long startPosn = ftell(mZipFp);
+        off_t startPosn = ftello(mZipFp);
         uint32_t crc;
         if (compressFpToFp(mZipFp, NULL, buf, uncompressedLen, &crc) != OK) {
             ALOGW("recompress of '%s' failed\n", pEntry->mCDE.mFileName);
@@ -720,13 +700,12 @@
             free(buf);
             goto bail;
         }
-        long endPosn = ftell(mZipFp);
+        off_t endPosn = ftello(mZipFp);
         pEntry->setDataInfo(uncompressedLen, endPosn - startPosn,
             pSourceEntry->getCRC32(), ZipEntry::kCompressDeflated);
         free(buf);
     } else {
-        off_t copyLen;
-        copyLen = pSourceEntry->getCompressedLen();
+        off_t copyLen = pSourceEntry->getCompressedLen();
         if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)
             copyLen += ZipEntry::kDataDescriptorLen;
 
@@ -746,12 +725,12 @@
     mEOCD.mNumEntries++;
     mEOCD.mTotalNumEntries++;
     mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
-    mEOCD.mCentralDirOffset = ftell(mZipFp);
+    mEOCD.mCentralDirOffset = ftello(mZipFp);
 
     /*
      * Go back and write the LFH.
      */
-    if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {
+    if (fseeko(mZipFp, lfhPosn, SEEK_SET) != 0) {
         result = UNKNOWN_ERROR;
         goto bail;
     }
@@ -978,7 +957,7 @@
 status_t ZipFile::flush(void)
 {
     status_t result = OK;
-    long eocdPosn;
+    off_t eocdPosn;
     int i, count;
 
     if (mReadOnly)
@@ -992,8 +971,7 @@
     if (result != OK)
         return result;
 
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0)
-        return UNKNOWN_ERROR;
+    if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) return UNKNOWN_ERROR;
 
     count = mEntries.size();
     for (i = 0; i < count; i++) {
@@ -1001,7 +979,7 @@
         pEntry->mCDE.write(mZipFp);
     }
 
-    eocdPosn = ftell(mZipFp);
+    eocdPosn = ftello(mZipFp);
     mEOCD.mCentralDirSize = eocdPosn - mEOCD.mCentralDirOffset;
 
     mEOCD.write(mZipFp);
@@ -1011,8 +989,8 @@
      * with plain files, or if we deleted some entries, there's a lot
      * of wasted space at the end of the file.  Remove it now.
      */
-    if (ftruncate(fileno(mZipFp), ftell(mZipFp)) != 0) {
-        ALOGW("ftruncate failed %ld: %s\n", ftell(mZipFp), strerror(errno));
+    if (ftruncate(fileno(mZipFp), ftello(mZipFp)) != 0) {
+        ALOGW("ftruncate failed %lld: %s\n", (long long) ftello(mZipFp), strerror(errno));
         // not fatal
     }
 
@@ -1141,32 +1119,32 @@
             if (getSize > n)
                 getSize = n;
 
-            if (fseek(fp, (long) src, SEEK_SET) != 0) {
-                ALOGW("filemove src seek %ld failed, %s",
-                    (long) src, strerror(errno));
+            if (fseeko(fp, src, SEEK_SET) != 0) {
+                ALOGW("filemove src seek %lld failed, %s",
+                    (long long) src, strerror(errno));
                 return UNKNOWN_ERROR;
             }
 
             if (fread(readBuf, 1, getSize, fp) != getSize) {
                 if (feof(fp)) {
-                    ALOGW("fread %zu bytes off=%ld failed, unexpected EOF",
-                        getSize, (long) src);
+                    ALOGW("fread %zu bytes off=%lld failed, unexpected EOF",
+                        getSize, (long long) src);
                 } else {
-                    ALOGW("fread %zu bytes off=%ld failed, %s",
-                        getSize, (long) src, strerror(errno));
+                    ALOGW("fread %zu bytes off=%lld failed, %s",
+                        getSize, (long long) src, strerror(errno));
                 }
                 return UNKNOWN_ERROR;
             }
 
-            if (fseek(fp, (long) dst, SEEK_SET) != 0) {
-                ALOGW("filemove dst seek %ld failed, %s",
-                    (long) dst, strerror(errno));
+            if (fseeko(fp, dst, SEEK_SET) != 0) {
+                ALOGW("filemove dst seek %lld failed, %s",
+                    (long long) dst, strerror(errno));
                 return UNKNOWN_ERROR;
             }
 
             if (fwrite(readBuf, 1, getSize, fp) != getSize) {
-                ALOGW("filemove write %zu off=%ld failed, %s",
-                    getSize, (long) dst, strerror(errno));
+                ALOGW("filemove write %zu off=%lld failed, %s",
+                    getSize, (long long) dst, strerror(errno));
                 return UNKNOWN_ERROR;
             }
 
@@ -1263,10 +1241,10 @@
 
     bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const {
         // Data is usually requested sequentially, so this helps avoid pointless
-        // fseeks every time we perform a read. There's an impedence mismatch
+        // seeks every time we perform a read. There's an impedence mismatch
         // here because the original API was designed around pread and pwrite.
         if (offset != current_offset_) {
-            if (fseek(fp_, offset, SEEK_SET) != 0) {
+            if (fseeko(fp_, offset, SEEK_SET) != 0) {
                 return false;
             }
 
@@ -1298,10 +1276,10 @@
         return NULL;
     }
 
-    fseek(mZipFp, 0, SEEK_SET);
+    fseeko(mZipFp, 0, SEEK_SET);
 
     off_t offset = entry->getFileOffset();
-    if (fseek(mZipFp, offset, SEEK_SET) != 0) {
+    if (fseeko(mZipFp, offset, SEEK_SET) != 0) {
         goto bail;
     }
 
diff --git a/tools/ziptime/ZipEntry.cpp b/tools/ziptime/ZipEntry.cpp
index e7b52ed..c8eb377 100644
--- a/tools/ziptime/ZipEntry.cpp
+++ b/tools/ziptime/ZipEntry.cpp
@@ -43,19 +43,16 @@
  */
 status_t ZipEntry::initAndRewriteFromCDE(FILE* fp)
 {
-    status_t result;
-    long posn;
-
     /* read the CDE */
-    result = mCDE.rewrite(fp);
+    status_t result = mCDE.rewrite(fp);
     if (result != 0) {
         LOG("mCDE.rewrite failed\n");
         return result;
     }
 
     /* using the info in the CDE, go load up the LFH */
-    posn = ftell(fp);
-    if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
+    off_t posn = ftello(fp);
+    if (fseeko(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
         LOG("local header seek failed (%" PRIu32 ")\n",
             mCDE.mLocalHeaderRelOffset);
         return -1;
@@ -67,7 +64,7 @@
         return result;
     }
 
-    if (fseek(fp, posn, SEEK_SET) != 0)
+    if (fseeko(fp, posn, SEEK_SET) != 0)
         return -1;
 
     return 0;
diff --git a/tools/ziptime/ZipFile.cpp b/tools/ziptime/ZipFile.cpp
index 1d111af..3002a65 100644
--- a/tools/ziptime/ZipFile.cpp
+++ b/tools/ziptime/ZipFile.cpp
@@ -40,8 +40,7 @@
     /* open the file */
     mZipFp = fopen(zipFileName, "r+b");
     if (mZipFp == NULL) {
-        int err = errno;
-        LOG("fopen failed: %d\n", err);
+        LOG("fopen \"%s\" failed: %s\n", zipFileName, strerror(errno));
         return -1;
     }
 
@@ -72,52 +71,39 @@
  */
 status_t ZipFile::rewriteCentralDir(void)
 {
-    status_t result = 0;
-    uint8_t* buf = NULL;
-    off_t fileLength, seekStart;
-    long readAmount;
-    int i;
-
-    fseek(mZipFp, 0, SEEK_END);
-    fileLength = ftell(mZipFp);
+    fseeko(mZipFp, 0, SEEK_END);
+    off_t fileLength = ftello(mZipFp);
     rewind(mZipFp);
 
     /* too small to be a ZIP archive? */
     if (fileLength < EndOfCentralDir::kEOCDLen) {
-        LOG("Length is %ld -- too small\n", (long)fileLength);
-        result = -1;
-        goto bail;
+        LOG("Length is %lld -- too small\n", (long long) fileLength);
+        return -1;
     }
 
-    buf = new uint8_t[EndOfCentralDir::kMaxEOCDSearch];
-    if (buf == NULL) {
-        LOG("Failure allocating %d bytes for EOCD search",
-             EndOfCentralDir::kMaxEOCDSearch);
-        result = -1;
-        goto bail;
-    }
-
+    off_t seekStart;
+    size_t readAmount;
     if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {
         seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;
         readAmount = EndOfCentralDir::kMaxEOCDSearch;
     } else {
         seekStart = 0;
-        readAmount = (long) fileLength;
+        readAmount = fileLength;
     }
-    if (fseek(mZipFp, seekStart, SEEK_SET) != 0) {
-        LOG("Failure seeking to end of zip at %ld", (long) seekStart);
-        result = -1;
-        goto bail;
+    if (fseeko(mZipFp, seekStart, SEEK_SET) != 0) {
+        LOG("Failure seeking to end of zip at %lld", (long long) seekStart);
+        return -1;
     }
 
     /* read the last part of the file into the buffer */
-    if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) {
-        LOG("short file? wanted %ld\n", readAmount);
-        result = -1;
-        goto bail;
+    uint8_t buf[EndOfCentralDir::kMaxEOCDSearch];
+    if (fread(buf, 1, readAmount, mZipFp) != readAmount) {
+        LOG("short file? wanted %zu\n", readAmount);
+        return -1;
     }
 
     /* find the end-of-central-dir magic */
+    int i;
     for (i = readAmount - 4; i >= 0; i--) {
         if (buf[i] == 0x50 &&
             ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)
@@ -127,15 +113,14 @@
     }
     if (i < 0) {
         LOG("EOCD not found, not Zip\n");
-        result = -1;
-        goto bail;
+        return -1;
     }
 
     /* extract eocd values */
-    result = mEOCD.readBuf(buf + i, readAmount - i);
+    status_t result = mEOCD.readBuf(buf + i, readAmount - i);
     if (result != 0) {
-        LOG("Failure reading %ld bytes of EOCD values", readAmount - i);
-        goto bail;
+        LOG("Failure reading %zu bytes of EOCD values", readAmount - i);
+        return result;
     }
 
     /*
@@ -152,49 +137,39 @@
      * The only thing we really need right now is the file comment, which
      * we're hoping to preserve.
      */
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
+    if (fseeko(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
         LOG("Failure seeking to central dir offset %" PRIu32 "\n",
              mEOCD.mCentralDirOffset);
-        result = -1;
-        goto bail;
+        return -1;
     }
 
     /*
      * Loop through and read the central dir entries.
      */
-    int entry;
-    for (entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {
+    for (int entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {
         ZipEntry* pEntry = new ZipEntry;
-
         result = pEntry->initAndRewriteFromCDE(mZipFp);
+        delete pEntry;
         if (result != 0) {
             LOG("initFromCDE failed\n");
-            delete pEntry;
-            goto bail;
+            return -1;
         }
-
-        delete pEntry;
     }
 
-
     /*
      * If all went well, we should now be back at the EOCD.
      */
     uint8_t checkBuf[4];
     if (fread(checkBuf, 1, 4, mZipFp) != 4) {
         LOG("EOCD check read failed\n");
-        result = -1;
-        goto bail;
+        return -1;
     }
     if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {
         LOG("EOCD read check failed\n");
-        result = -1;
-        goto bail;
+        return -1;
     }
 
-bail:
-    delete[] buf;
-    return result;
+    return 0;
 }
 
 /*