Merge changes from topic "split_ramdisk"

* changes:
  Exclude board cmdline/dtb/pagesize/base in generic boot image
  Add BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT.
  Add BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE.
  Add GKI global variable.
diff --git a/core/Makefile b/core/Makefile
index b307ce5..46920b3 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1363,6 +1363,7 @@
     $(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(1))
     $(if $(PRODUCT_FS_CASEFOLD),$(hide) echo "needs_casefold=$(PRODUCT_FS_CASEFOLD)" >> $(1))
     $(if $(PRODUCT_QUOTA_PROJID),$(hide) echo "needs_projid=$(PRODUCT_QUOTA_PROJID)" >> $(1))
+    $(if $(PRODUCT_FS_COMPRESSION),$(hide) echo "needs_compress=$(PRODUCT_FS_COMPRESSION)" >> $(1))
     $(hide) echo "userdata_selinux_fc=$(SELINUX_FC)" >> $(1)
     $(hide) echo "building_userdata_image=$(BUILDING_USERDATA_IMAGE)" >> $(1)
 )
@@ -2143,7 +2144,7 @@
 #
 # Note: it's intentional to skip signing for boot-debug.img, because it
 # can only be used if the device is unlocked with verification error.
-ifdef BUILDING_BOOT_IMAGE
+ifneq ($(INSTALLED_BOOTIMAGE_TARGET),)
 ifneq ($(strip $(TARGET_NO_KERNEL)),true)
 ifneq ($(strip $(BOARD_KERNEL_BINARIES)),)
   INSTALLED_DEBUG_BOOTIMAGE_TARGET := $(foreach k,$(subst kernel,boot-debug,$(BOARD_KERNEL_BINARIES)), \
@@ -2198,7 +2199,7 @@
 	$(foreach b,$(INSTALLED_DEBUG_BOOTIMAGE_TARGET),$(call build-debug-bootimage-target,$b))
 
 endif # TARGET_NO_KERNEL
-endif # BUILDING_BOOT_IMAGE
+endif # INSTALLED_BOOTIMAGE_TARGET
 
 ifeq ($(BUILDING_VENDOR_BOOT_IMAGE),true)
 ifeq ($(BUILDING_RAMDISK_IMAGE),true)
@@ -3926,6 +3927,7 @@
   signapk \
   simg2img \
   sload_f2fs \
+  toybox \
   tune2fs \
   unpack_bootimg \
   update_host_simulator \
@@ -4438,6 +4440,7 @@
 	    $(INSTALLED_CUSTOMIMAGES_TARGET) \
 	    $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
 	    $(INSTALLED_KERNEL_TARGET) \
+	    $(INSTALLED_RAMDISK_TARGET) \
 	    $(INSTALLED_DTBIMAGE_TARGET) \
 	    $(INSTALLED_2NDBOOTLOADER_TARGET) \
 	    $(BOARD_PREBUILT_DTBOIMAGE) \
@@ -4611,6 +4614,13 @@
 	@# Extra contents of the OTA package
 	$(hide) mkdir -p $(zip_root)/OTA
 	$(hide) cp $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(zip_root)/OTA/
+ifdef BUILDING_RAMDISK_IMAGE
+ifeq (true,$(BOARD_IMG_USE_RAMDISK))
+	@# Contents of the ramdisk image
+	$(hide) mkdir -p $(zip_root)/IMAGES
+	$(hide) cp $(INSTALLED_RAMDISK_TARGET) $(zip_root)/IMAGES/
+endif
+endif
 ifeq ($(TARGET_OTA_ALLOW_NON_AB),true)
 ifneq ($(built_ota_tools),)
 	$(hide) mkdir -p $(zip_root)/OTA/bin
@@ -4989,7 +4999,7 @@
 JACOCO_REPORT_CLASSES_ALL := $(PRODUCT_OUT)/jacoco-report-classes-all.jar
 $(JACOCO_REPORT_CLASSES_ALL) :
 	@echo "Collecting uninstrumented classes"
-	find $(TARGET_COMMON_OUT_ROOT) $(HOST_COMMON_OUT_ROOT) -name "jacoco-report-classes.jar" 2>/dev/null | sort > $@.list
+	find $(TARGET_COMMON_OUT_ROOT) $(HOST_COMMON_OUT_ROOT) -name "jacoco-report-classes.jar" -o -name "proguard_usage.zip" 2>/dev/null | sort > $@.list
 	$(SOONG_ZIP) -o $@ -L 0 -C $(OUT_DIR) -P out -l $@.list
 
 endif # EMMA_INSTRUMENT=true
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 7d79baf..6e1cb68 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -74,7 +74,6 @@
 LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=
 LOCAL_DROIDDOC_DOC_ZIP :=
-LOCAL_DROIDDOC_JDIFF_DOC_ZIP :=
 LOCAL_DROIDDOC_HTML_DIR:=
 LOCAL_DROIDDOC_METADATA_ZIP:=
 LOCAL_DROIDDOC_OPTIONS:=
diff --git a/core/config.mk b/core/config.mk
index 16fa988..e197276 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -996,16 +996,6 @@
 # Set up final options.
 # ###############################################################
 
-# We run gcc/clang with PWD=/proc/self/cwd to remove the $TOP
-# from the debug output. That way two builds in two different
-# directories will create the same output.
-# /proc doesn't exist on Darwin.
-ifeq ($(HOST_OS),linux)
-RELATIVE_PWD := PWD=/proc/self/cwd
-else
-RELATIVE_PWD :=
-endif
-
 # Flags for DEX2OAT
 first_non_empty_of_three = $(if $(1),$(1),$(if $(2),$(2),$(3)))
 DEX2OAT_TARGET_ARCH := $(TARGET_ARCH)
diff --git a/core/definitions.mk b/core/definitions.mk
index bfbeee3..0a65a15 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -1179,7 +1179,7 @@
 @echo "$($(PRIVATE_PREFIX)DISPLAY) $(PRIVATE_ARM_MODE) C++: $(PRIVATE_MODULE) <= $<"
 @mkdir -p $(dir $@)
 $(if $(PRIVATE_TIDY_CHECKS),$(clang-tidy-cpp))
-$(hide) $(RELATIVE_PWD) $(PRIVATE_CXX) \
+$(hide) $(PRIVATE_CXX) \
   $(transform-cpp-to-o-compiler-args) \
   -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
 endef
@@ -1225,7 +1225,7 @@
 @echo "$($(PRIVATE_PREFIX)DISPLAY) $(PRIVATE_ARM_MODE) C: $(PRIVATE_MODULE) <= $<"
 @mkdir -p $(dir $@)
 $(if $(PRIVATE_TIDY_CHECKS),$(clang-tidy-c))
-$(hide) $(RELATIVE_PWD) $(PRIVATE_CC) \
+$(hide) $(PRIVATE_CC) \
   $(transform-c-to-o-compiler-args) \
   -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
 endef
@@ -1234,7 +1234,7 @@
 define transform-s-to-o
 @echo "$($(PRIVATE_PREFIX)DISPLAY) asm: $(PRIVATE_MODULE) <= $<"
 @mkdir -p $(dir $@)
-$(RELATIVE_PWD) $(PRIVATE_CC) \
+$(PRIVATE_CC) \
   $(call transform-c-or-s-to-o-compiler-args, $(PRIVATE_ASFLAGS)) \
   -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
 endef
@@ -1293,7 +1293,7 @@
 @echo "$($(PRIVATE_PREFIX)DISPLAY) C++: $(PRIVATE_MODULE) <= $<"
 @mkdir -p $(dir $@)
 $(if $(PRIVATE_TIDY_CHECKS),$(clang-tidy-host-cpp))
-$(hide) $(RELATIVE_PWD) $(PRIVATE_CXX) \
+$(hide) $(PRIVATE_CXX) \
   $(transform-host-cpp-to-o-compiler-args) \
   -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
 endef
@@ -1316,7 +1316,7 @@
 # $(1): extra flags
 define transform-host-c-or-s-to-o
 @mkdir -p $(dir $@)
-$(hide) $(RELATIVE_PWD) $(PRIVATE_CC) \
+$(hide) $(PRIVATE_CC) \
   $(transform-host-c-or-s-to-o-common-args) \
   $(1) \
   -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
@@ -1343,7 +1343,7 @@
 @echo "$($(PRIVATE_PREFIX)DISPLAY) C: $(PRIVATE_MODULE) <= $<"
 @mkdir -p $(dir $@)
 $(if $(PRIVATE_TIDY_CHECKS), $(clang-tidy-host-c))
-$(hide) $(RELATIVE_PWD) $(PRIVATE_CC) \
+$(hide) $(PRIVATE_CC) \
   $(transform-host-c-to-o-compiler-args) \
   -MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
 endef
diff --git a/core/rbe.mk b/core/rbe.mk
index 91606d4..90375c7 100644
--- a/core/rbe.mk
+++ b/core/rbe.mk
@@ -57,7 +57,7 @@
   java_r8_d8_platform := $(platform),Pool=java16
 
   RBE_WRAPPER := $(rbe_dir)/rewrapper
-  RBE_CXX := --labels=type=compile,lang=cpp,compiler=clang --env_var_allowlist=PWD --exec_strategy=$(cxx_rbe_exec_strategy) --platform=$(cxx_platform) --compare=$(cxx_compare)
+  RBE_CXX := --labels=type=compile,lang=cpp,compiler=clang --exec_strategy=$(cxx_rbe_exec_strategy) --platform=$(cxx_platform) --compare=$(cxx_compare)
 
   # Append rewrapper to existing *_WRAPPER variables so it's possible to
   # use both ccache and rewrapper.
diff --git a/core/soong_config.mk b/core/soong_config.mk
index d5e16f7..de60b5b 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -131,7 +131,7 @@
 $(call add_json_list, DeviceSystemSdkVersions,           $(BOARD_SYSTEMSDK_VERSIONS))
 $(call add_json_list, Platform_systemsdk_versions,       $(PLATFORM_SYSTEMSDK_VERSIONS))
 $(call add_json_bool, Malloc_not_svelte,                 $(call invert_bool,$(filter true,$(MALLOC_SVELTE))))
-$(call add_json_bool, Malloc_zero_contents,              $(MALLOC_ZERO_CONTENTS))
+$(call add_json_bool, Malloc_zero_contents,              $(call invert_bool,$(filter false,$(MALLOC_ZERO_CONTENTS))))
 $(call add_json_bool, Malloc_pattern_fill_contents,      $(MALLOC_PATTERN_FILL_CONTENTS))
 $(call add_json_str,  Override_rs_driver,                $(OVERRIDE_RS_DRIVER))
 
diff --git a/core/soong_droiddoc_prebuilt.mk b/core/soong_droiddoc_prebuilt.mk
index c0467df..4dc5d08 100644
--- a/core/soong_droiddoc_prebuilt.mk
+++ b/core/soong_droiddoc_prebuilt.mk
@@ -29,16 +29,6 @@
 $(eval $(call copy-one-file,$(LOCAL_DROIDDOC_API_VERSIONS_XML),$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(LOCAL_MODULE)_generated-api-versions.xml))
 endif
 
-ifdef LOCAL_DROIDDOC_JDIFF_DOC_ZIP
-$(eval $(call copy-one-file,$(LOCAL_DROIDDOC_JDIFF_DOC_ZIP),$(OUT_DOCS)/$(LOCAL_MODULE)-jdiff-docs.zip))
-$(call dist-for-goals,docs,$(OUT_DOCS)/$(LOCAL_MODULE)-jdiff-docs.zip)
-
-ALL_DOCS += $(OUT_DOCS)/$(LOCAL_MODULE)-jdiff-docs.zip
-
-.PHONY: $(LOCAL_MODULE) $(LOCAL_MODULE)-jdiff
-$(LOCAL_MODULE) $(LOCAL_MODULE)-jdiff : $(OUT_DOCS)/$(LOCAL_MODULE)-jdiff-docs.zip
-endif
-
 ifdef LOCAL_DROIDDOC_METADATA_ZIP
 $(eval $(call copy-one-file,$(LOCAL_DROIDDOC_METADATA_ZIP),$(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(LOCAL_MODULE)-metadata.zip))
 endif
diff --git a/core/sysprop.mk b/core/sysprop.mk
index a74ff9f..fdefced 100644
--- a/core/sysprop.mk
+++ b/core/sysprop.mk
@@ -54,7 +54,8 @@
     echo "ro.$(1).build.tags=$(BUILD_VERSION_TAGS)" >> $(2);\
     echo "ro.$(1).build.type=$(TARGET_BUILD_VARIANT)" >> $(2);\
     echo "ro.$(1).build.version.incremental=$(BUILD_NUMBER_FROM_FILE)" >> $(2);\
-    echo "ro.$(1).build.version.release=$(PLATFORM_VERSION)" >> $(2);\
+    echo "ro.$(1).build.version.release=$(PLATFORM_VERSION_LAST_STABLE)" >> $(2);\
+    echo "ro.$(1).build.version.release_or_codename=$(PLATFORM_VERSION)" >> $(2);\
     echo "ro.$(1).build.version.sdk=$(PLATFORM_SDK_VERSION)" >> $(2);\
 
 endef
diff --git a/core/tasks/apidiff.mk b/core/tasks/apidiff.mk
deleted file mode 100644
index 76e4749..0000000
--- a/core/tasks/apidiff.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2017 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.
-
-#
-# Rules for building API diffs.
-#
-
-.PHONY: api-diff
-
-api-diff: api-stubs-docs-jdiff
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index cd5fa8e..c09daeb 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -14,8 +14,8 @@
 
 test_suite_name := cts
 test_suite_tradefed := cts-tradefed
-test_suite_dynamic_config := test/suite_harness/tools/cts-tradefed/DynamicConfig.xml
-test_suite_readme := test/suite_harness/tools/cts-tradefed/README
+test_suite_dynamic_config := cts/tools/cts-tradefed/DynamicConfig.xml
+test_suite_readme := cts/tools/cts-tradefed/README
 include_test_suite_notice := true
 
 include $(BUILD_SYSTEM)/tasks/tools/compatibility.mk
diff --git a/envsetup.sh b/envsetup.sh
index a3b07a7..82c4565 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -318,6 +318,59 @@
     #export HOST_EXTRACFLAGS="-I "$T/system/kernel_headers/host_include
 }
 
+function abazel()
+{
+    local T="$(gettop)"
+    if [ ! "$T" ]; then
+        echo "Couldn't locate the top of the tree.  Try setting TOP."
+        return
+    fi
+
+    case $(uname -s) in
+        Darwin)
+            ANDROID_BAZEL_PATH="${T}/prebuilts/bazel/darwin-x86_64/bazel"
+            ANDROID_BAZELRC_PATH="${T}/build/bazel/darwin.bazelrc"
+            ANDROID_BAZEL_JDK_PATH="${T}/prebuilts/jdk/jdk11/darwin-x86"
+            ;;
+        Linux)
+            ANDROID_BAZEL_PATH="${T}/prebuilts/bazel/linux-x86_64/bazel"
+            ANDROID_BAZELRC_PATH="${T}/build/bazel/linux.bazelrc"
+            ANDROID_BAZEL_JDK_PATH="${T}/prebuilts/jdk/jdk11/linux-x86"
+            ;;
+        *)
+            ANDROID_BAZEL_PATH=
+            ANDROID_BAZELRC_PATH=
+            ANDROID_BAZEL_JDK_PATH=
+            ;;
+    esac
+
+    if [ -n "$ANDROID_BAZEL_PATH" -a -f "$ANDROID_BAZEL_PATH" ]; then
+        export ANDROID_BAZEL_PATH
+    else
+        echo "Couldn't locate Bazel binary"
+        return
+    fi
+
+    if [ -n "$ANDROID_BAZELRC_PATH" -a -f "$ANDROID_BAZELRC_PATH" ]; then
+        export ANDROID_BAZELRC_PATH
+    else
+        echo "Couldn't locate bazelrc file for Bazel"
+        return
+    fi
+
+    if [ -n "$ANDROID_BAZEL_JDK_PATH" -a -d "$ANDROID_BAZEL_JDK_PATH" ]; then
+        export ANDROID_BAZEL_JDK_PATH
+    else
+        echo "Couldn't locate JDK to use for Bazel"
+        return
+    fi
+
+    echo "WARNING: Bazel support for the Android Platform is experimental and is undergoing development."
+    echo "WARNING: Currently, build stability is not guaranteed. Thank you."
+    echo
+    "${ANDROID_BAZEL_PATH}" --server_javabase="${ANDROID_BAZEL_JDK_PATH}" --bazelrc="${ANDROID_BAZELRC_PATH}" "$@"
+}
+
 function printconfig()
 {
     local T=$(gettop)
@@ -769,7 +822,7 @@
     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)
+        (cd "$TOP"; PWD= /bin/pwd)
     else
         if [ -f $TOPFILE ] ; then
             # The following circumlocution (repeated below as well) ensures
@@ -779,13 +832,13 @@
         else
             local HERE=$PWD
             local T=
-            while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
+            while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do
                 \cd ..
                 T=`PWD= /bin/pwd -P`
             done
-            \cd $HERE
+            \cd "$HERE"
             if [ -f "$T/$TOPFILE" ]; then
-                echo $T
+                echo "$T"
             fi
         fi
     fi
@@ -1600,25 +1653,26 @@
 # This allows loading only approved vendorsetup.sh files
 function source_vendorsetup() {
     unset VENDOR_PYTHONPATH
+    local T="$(gettop)"
     allowed=
-    for f in $(find -L device vendor product -maxdepth 4 -name 'allowed-vendorsetup_sh-files' 2>/dev/null | sort); do
+    for f in $(cd "$T" && find -L device vendor product -maxdepth 4 -name 'allowed-vendorsetup_sh-files' 2>/dev/null | sort); do
         if [ -n "$allowed" ]; then
             echo "More than one 'allowed_vendorsetup_sh-files' file found, not including any vendorsetup.sh files:"
             echo "  $allowed"
             echo "  $f"
             return
         fi
-        allowed="$f"
+        allowed="$T/$f"
     done
 
     allowed_files=
     [ -n "$allowed" ] && allowed_files=$(cat "$allowed")
     for dir in device vendor product; do
-        for f in $(test -d $dir && \
+        for f in $(cd "$T" && test -d $dir && \
             find -L $dir -maxdepth 4 -name 'vendorsetup.sh' 2>/dev/null | sort); do
 
             if [[ -z "$allowed" || "$allowed_files" =~ $f ]]; then
-                echo "including $f"; . "$f"
+                echo "including $f"; . "$T/$f"
             else
                 echo "ignoring $f, not in $allowed"
             fi
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 586c058..1a28cf0 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -38,7 +38,6 @@
     bcc \
     blank_screen \
     blkid \
-    service-blobstore \
     bmgr \
     bootanimation \
     bootstat \
@@ -117,7 +116,6 @@
     iptables \
     ip-up-vpn \
     javax.obex \
-    service-jobscheduler \
     keystore \
     credstore \
     ld.mc \
diff --git a/target/product/gsi/current.txt b/target/product/gsi/current.txt
index de6644c..f2ef002 100644
--- a/target/product/gsi/current.txt
+++ b/target/product/gsi/current.txt
@@ -19,6 +19,7 @@
 LLNDK: libvndksupport.so
 LLNDK: libvulkan.so
 VNDK-SP: android.hardware.common-V1-ndk_platform.so
+VNDK-SP: android.hardware.common.fmq-V1-ndk_platform.so
 VNDK-SP: android.hardware.graphics.common-V1-ndk_platform.so
 VNDK-SP: android.hardware.graphics.common@1.0.so
 VNDK-SP: android.hardware.graphics.common@1.1.so
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index 7633abe..ec30527 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -30,8 +30,8 @@
 # ART APEX module.
 # Note that this package includes the minimal boot classpath JARs (listed in
 # ART_APEX_JARS), which should no longer be added directly to PRODUCT_PACKAGES.
-PRODUCT_PACKAGES += com.android.art
-PRODUCT_HOST_PACKAGES += com.android.art
+PRODUCT_PACKAGES += com.android.art-autoselect
+PRODUCT_HOST_PACKAGES += com.android.art-autoselect
 
 # Certificates.
 PRODUCT_PACKAGES += \
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 45e0514..e1543e7 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -125,6 +125,9 @@
     required: [
         "brillo_update_payload",
         "checkvintf",
+        "lz4",
+        "toybox",
+        "unpack_bootimg"
     ],
     target: {
         darwin: {
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 9cc072f..169a112 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -250,6 +250,7 @@
   run_e2fsck = False
   needs_projid = prop_dict.get("needs_projid", 0)
   needs_casefold = prop_dict.get("needs_casefold", 0)
+  needs_compress = prop_dict.get("needs_compress", 0)
 
   if fs_type.startswith("ext"):
     build_command = [prop_dict["ext_mkuserimg"]]
@@ -337,6 +338,8 @@
       build_command.append("--prjquota")
     if (needs_casefold):
       build_command.append("--casefold")
+    if (needs_compress):
+      build_command.append("--compression")
   else:
     raise BuildImageError(
         "Error: unknown filesystem type: {}".format(fs_type))
@@ -610,6 +613,7 @@
     copy_prop("userdata_selinux_fc", "selinux_fc")
     copy_prop("needs_casefold", "needs_casefold")
     copy_prop("needs_projid", "needs_projid")
+    copy_prop("needs_compress", "needs_compress")
   elif mount_point == "cache":
     copy_prop("cache_fs_type", "fs_type")
     copy_prop("cache_size", "partition_size")
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index f8fc141..acf9811 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -527,6 +527,27 @@
         return BuildInfo._RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER_LEGACY
     return BuildInfo._RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER_CURRENT
 
+  def _GetPlatformVersion(self):
+    version_sdk = self.GetBuildProp("ro.build.version.sdk")
+    # init code switches to version_release_or_codename (see b/158483506). After
+    # API finalization, release_or_codename will be the same as release. This
+    # is the best effort to support pre-S dev stage builds.
+    if int(version_sdk) >= 30:
+      try:
+        return self.GetBuildProp("ro.build.version.release_or_codename")
+      except ExternalError:
+        logger.warning('Failed to find ro.build.version.release_or_codename')
+
+    return self.GetBuildProp("ro.build.version.release")
+
+  def _GetPartitionPlatformVersion(self, partition):
+    try:
+      return self.GetPartitionBuildProp("ro.build.version.release_or_codename",
+                                        partition)
+    except ExternalError:
+      return self.GetPartitionBuildProp("ro.build.version.release",
+                                        partition)
+
   def GetOemProperty(self, key):
     if self.oem_props is not None and key in self.oem_props:
       return self.oem_dicts[0][key]
@@ -543,7 +564,7 @@
           self.GetPartitionBuildProp("ro.product.brand", partition),
           self.GetPartitionBuildProp("ro.product.name", partition),
           self.GetPartitionBuildProp("ro.product.device", partition),
-          self.GetPartitionBuildProp("ro.build.version.release", partition),
+          self._GetPartitionPlatformVersion(partition),
           self.GetPartitionBuildProp("ro.build.id", partition),
           self.GetPartitionBuildProp(
               "ro.build.version.incremental", partition),
@@ -559,7 +580,7 @@
             self.GetBuildProp("ro.product.brand"),
             self.GetBuildProp("ro.product.name"),
             self.GetBuildProp("ro.product.device"),
-            self.GetBuildProp("ro.build.version.release"),
+            self._GetPlatformVersion(),
             self.GetBuildProp("ro.build.id"),
             self.GetBuildProp("ro.build.version.incremental"),
             self.GetBuildProp("ro.build.type"),
@@ -814,6 +835,15 @@
     props._LoadBuildProp(data)
     return props
 
+  @staticmethod
+  def FromBuildPropFile(name, build_prop_file):
+    """Constructs an instance from a build prop file."""
+
+    props = PartitionBuildProps("unknown", name)
+    with open(build_prop_file) as f:
+      props._LoadBuildProp(f.read())
+    return props
+
   def _LoadBuildProp(self, data):
     for line in data.split('\n'):
       line = line.strip()
diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py
index f0e4fcf..cb0f6e6 100644
--- a/tools/releasetools/ota_utils.py
+++ b/tools/releasetools/ota_utils.py
@@ -14,14 +14,17 @@
 
 import copy
 import itertools
+import logging
 import os
 import zipfile
 
 import ota_metadata_pb2
 from common import (ZipDelete, ZipClose, OPTIONS, MakeTempFile,
                     ZipWriteStr, BuildInfo, LoadDictionaryFromFile,
-                    SignFile, PARTITIONS_WITH_CARE_MAP, PartitionBuildProps)
+                    SignFile, PARTITIONS_WITH_CARE_MAP, PartitionBuildProps,
+                    MakeTempDir, RunAndCheckOutput, ExternalError)
 
+logger = logging.getLogger(__name__)
 
 OPTIONS.no_signing = False
 OPTIONS.force_non_ab = False
@@ -38,6 +41,9 @@
 METADATA_PROTO_NAME = 'META-INF/com/android/metadata.pb'
 UNZIP_PATTERN = ['IMAGES/*', 'META/*', 'OTA/*', 'RADIO/*']
 
+# See sysprop.mk. If file is moved, add new search paths here; don't remove
+# existing search paths.
+RAMDISK_BUILD_PROP_REL_PATHS = ['system/etc/ramdisk/build.prop']
 
 def FinalizeMetadata(metadata, input_file, output_file, needed_property_files):
   """Finalizes the metadata and signs an A/B OTA package.
@@ -561,3 +567,55 @@
 
   SignFile(temp_zip_name, output_zip_name, OPTIONS.package_key, pw,
            whole_file=True)
+
+
+def GetBootImageTimestamp(boot_img):
+  """
+  Get timestamp from ramdisk within the boot image
+
+  Args:
+    boot_img: the boot image file. Ramdisk must be compressed with lz4 format.
+
+  Return:
+    An integer that corresponds to the timestamp of the boot image, or None
+    if file has unknown format. Raise exception if an unexpected error has
+    occurred.
+  """
+
+  tmp_dir = MakeTempDir('boot_', suffix='.img')
+  try:
+    RunAndCheckOutput(['unpack_bootimg', '--boot_img', boot_img, '--out', tmp_dir])
+    ramdisk = os.path.join(tmp_dir, 'ramdisk')
+    if not os.path.isfile(ramdisk):
+      logger.warning('Unable to get boot image timestamp: no ramdisk in boot')
+      return None
+    uncompressed_ramdisk = os.path.join(tmp_dir, 'uncompressed_ramdisk')
+    RunAndCheckOutput(['lz4', '-d', ramdisk, uncompressed_ramdisk])
+
+    abs_uncompressed_ramdisk = os.path.abspath(uncompressed_ramdisk)
+    extracted_ramdisk = MakeTempDir('extracted_ramdisk')
+    # Use "toybox cpio" instead of "cpio" because the latter invokes cpio from
+    # the host environment.
+    RunAndCheckOutput(['toybox', 'cpio', '-F', abs_uncompressed_ramdisk, '-i'],
+               cwd=extracted_ramdisk)
+
+    prop_file = None
+    for search_path in RAMDISK_BUILD_PROP_REL_PATHS:
+      prop_file = os.path.join(extracted_ramdisk, search_path)
+      if os.path.isfile(prop_file):
+        break
+      logger.warning('Unable to get boot image timestamp: no %s in ramdisk', search_path)
+
+    if not prop_file:
+      return None
+
+    props = PartitionBuildProps.FromBuildPropFile('boot', prop_file)
+    timestamp = props.GetProp('ro.bootimage.build.date.utc')
+    if timestamp:
+      return int(timestamp)
+    logger.warning('Unable to get boot image timestamp: ro.bootimage.build.date.utc is undefined')
+    return None
+
+  except ExternalError as e:
+    logger.warning('Unable to get boot image timestamp: %s', e)
+    return None
diff --git a/tools/releasetools/test_ota_from_target_files.py b/tools/releasetools/test_ota_from_target_files.py
index f96bc7b..9c27f7e 100644
--- a/tools/releasetools/test_ota_from_target_files.py
+++ b/tools/releasetools/test_ota_from_target_files.py
@@ -1205,11 +1205,12 @@
   ]
 
   BUILD_PROP = [
-      'ro.build.version.release=version-release',
       'ro.build.id=build-id',
       'ro.build.version.incremental=version-incremental',
       'ro.build.type=build-type',
       'ro.build.tags=build-tags',
+      'ro.build.version.release=version-release',
+      'ro.build.version.release_or_codename=version-release',
       'ro.build.version.sdk=30',
       'ro.build.version.security_patch=2020',
       'ro.build.date.utc=12345678',