Merge "Add pm.dexopt.cmdline mapping in product config"
diff --git a/core/Makefile b/core/Makefile
index b70948b..fbce430 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1034,10 +1034,6 @@
 
 else # TARGET_NO_KERNEL == "true"
 ifdef BOARD_PREBUILT_BOOTIMAGE
-ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
-# Remove when b/63676296 is resolved.
-$(error Prebuilt bootimage is only supported for AB targets)
-endif
 INTERNAL_PREBUILT_BOOTIMAGE := $(BOARD_PREBUILT_BOOTIMAGE)
 INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
 $(eval $(call copy-one-file,$(INTERNAL_PREBUILT_BOOTIMAGE),$(INSTALLED_BOOTIMAGE_TARGET)))
@@ -5319,6 +5315,19 @@
 	$(hide) find $(PRODUCT_OUT)/appcompat | sort >$(PRIVATE_LIST_FILE)
 	$(hide) $(SOONG_ZIP) -d -o $@ -C $(PRODUCT_OUT)/appcompat -l $(PRIVATE_LIST_FILE)
 
+# The mac build doesn't build dex2oat, so create the zip file only if the build OS is linux.
+ifeq ($(BUILD_OS),linux)
+ifneq ($(DEX2OAT),)
+dexpreopt_tools_deps := $(DEXPREOPT_GEN_DEPS) $(DEXPREOPT_GEN) $(AAPT2)
+DEXPREOPT_TOOLS_ZIP := $(PRODUCT_OUT)/dexpreopt_tools.zip
+$(DEXPREOPT_TOOLS_ZIP): $(dexpreopt_tools_deps)
+$(DEXPREOPT_TOOLS_ZIP): PRIVATE_DEXPREOPT_TOOLS_DEPS := $(dexpreopt_tools_deps)
+$(DEXPREOPT_TOOLS_ZIP): $(SOONG_ZIP)
+	$(hide) mkdir -p $(dir $@)
+	$(hide) $(SOONG_ZIP) -d -o $@ -j $(addprefix -f ,$(PRIVATE_DEXPREOPT_TOOLS_DEPS)) -f $$(realpath $(DEX2OAT))
+endif # DEX2OAT is set
+endif # BUILD_OS == linux
+
 DEXPREOPT_CONFIG_ZIP := $(PRODUCT_OUT)/dexpreopt_config.zip
 $(DEXPREOPT_CONFIG_ZIP): $(FULL_SYSTEMIMAGE_DEPS) \
 	    $(INTERNAL_RAMDISK_FILES) \
diff --git a/core/app_prebuilt_internal.mk b/core/app_prebuilt_internal.mk
index 86a4adf..79639a8 100644
--- a/core/app_prebuilt_internal.mk
+++ b/core/app_prebuilt_internal.mk
@@ -183,6 +183,30 @@
 	$(transform-prebuilt-to-target)
 
 else  # ! LOCAL_REPLACE_PREBUILT_APK_INSTALLED
+
+# If the SDK version is 30 or higher, the apk is signed with a v2+ scheme.
+# Altering it will invalidate the signature. Just do error checks instead.
+do_not_alter_apk :=
+ifeq (PRESIGNED,$(LOCAL_CERTIFICATE))
+  ifneq (,$(LOCAL_SDK_VERSION))
+    ifeq ($(call math_is_number,$(LOCAL_SDK_VERSION)),true)
+      ifeq ($(call math_gt,$(LOCAL_SDK_VERSION),29),true)
+        do_not_alter_apk := true
+      endif
+    endif
+    # TODO: Add system_current after fixing the existing modules.
+    ifneq ($(filter current test_current core_current,$(LOCAL_SDK_VERSION)),)
+        do_not_alter_apk := true
+    endif
+  endif
+endif
+
+ifeq ($(do_not_alter_apk),true)
+$(built_module) : $(my_prebuilt_src_file) | $(ZIPALIGN)
+	$(transform-prebuilt-to-target)
+	$(check-jni-dex-compression)
+	$(check-package-alignment)
+else
 # Sign and align non-presigned .apks.
 # The embedded prebuilt jni to uncompress.
 ifeq ($(LOCAL_CERTIFICATE),PRESIGNED)
@@ -229,6 +253,7 @@
 ifdef LOCAL_COMPRESSED_MODULE
 	$(compress-package)
 endif  # LOCAL_COMPRESSED_MODULE
+endif  # ! do_not_alter_apk
 endif  # ! LOCAL_REPLACE_PREBUILT_APK_INSTALLED
 
 
diff --git a/core/definitions.mk b/core/definitions.mk
index 7f2cc42..c5fe76b 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2380,6 +2380,15 @@
   fi
 endef
 
+# Verifies ZIP alignment of a package.
+#
+define check-package-alignment
+$(hide) if ! $(ZIPALIGN) -c -p 4 $@ >/dev/null ; then \
+    $(call echo-error,$@,Improper package alignment); \
+    exit 1; \
+  fi
+endef
+
 # Compress a package using the standard gzip algorithm.
 define compress-package
 $(hide) \
@@ -2448,6 +2457,15 @@
   fi
 endef
 
+# Verifies shared JNI libraries and dex files in an apk are uncompressed.
+#
+define check-jni-dex-compression
+  if (zipinfo $@ 'lib/*.so' '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then \
+    $(call echo-error,$@,Contains compressed JNI libraries and/or dex files); \
+    exit 1; \
+  fi
+endef
+
 # Remove unwanted shared JNI libraries embedded in an apk.
 #
 define remove-unwanted-prebuilt-embedded-jni-libs
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index d925899..f365347 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -210,6 +210,9 @@
 ifneq (,$(filter $(LOCAL_MODULE_TAGS),tests))
   LOCAL_ENFORCE_USES_LIBRARIES := false
 endif
+ifneq (,$(LOCAL_COMPATIBILITY_SUITE))
+  LOCAL_ENFORCE_USES_LIBRARIES := false
+endif
 
 # Disable the check if the app contains no java code.
 ifeq (,$(strip $(built_dex)$(my_prebuilt_src_file)$(LOCAL_SOONG_DEX_JAR)))
@@ -227,14 +230,9 @@
   LOCAL_ENFORCE_USES_LIBRARIES := false
 endif
 
-# Verify LOCAL_USES_LIBRARIES/LOCAL_OPTIONAL_USES_LIBRARIES
-# If LOCAL_ENFORCE_USES_LIBRARIES is not set, default to true if either of LOCAL_USES_LIBRARIES or
-# LOCAL_OPTIONAL_USES_LIBRARIES are specified.
-# Will change the default to true unconditionally in the future.
+# Verify LOCAL_USES_LIBRARIES/LOCAL_OPTIONAL_USES_LIBRARIES against the manifest.
 ifndef LOCAL_ENFORCE_USES_LIBRARIES
-  ifneq (,$(strip $(LOCAL_USES_LIBRARIES)$(LOCAL_OPTIONAL_USES_LIBRARIES)))
-    LOCAL_ENFORCE_USES_LIBRARIES := true
-  endif
+  LOCAL_ENFORCE_USES_LIBRARIES := true
 endif
 
 my_enforced_uses_libraries :=
diff --git a/core/main.mk b/core/main.mk
index c9fa148..c45c1f2 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1709,6 +1709,7 @@
     $(COVERAGE_ZIP) \
     $(APPCOMPAT_ZIP) \
     $(DEXPREOPT_CONFIG_ZIP) \
+    $(DEXPREOPT_TOOLS_ZIP) \
     $(INSTALLED_FILES_FILE) \
     $(INSTALLED_FILES_JSON) \
     $(INSTALLED_FILES_FILE_VENDOR) \
diff --git a/envsetup.sh b/envsetup.sh
index 8a995c7..6cb2cc4 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -1687,10 +1687,19 @@
     if T="$(gettop)"; then
       _wrap_build "$T/build/soong/soong_ui.bash" --build-mode --${bc} --dir="$(pwd)" "$@"
     else
-      echo "Couldn't locate the top of the tree. Try setting TOP."
+      >&2 echo "Couldn't locate the top of the tree. Try setting TOP."
+      return 1
     fi
 )
 
+function b()
+(
+    # Generate BUILD, bzl files into the synthetic Bazel workspace (out/soong/workspace).
+    m nothing GENERATE_BAZEL_FILES=true || return 1
+    # Then, run Bazel using the synthetic workspace as the --package_path.
+    "$(gettop)/tools/bazel" "$@" --config=bp2build
+)
+
 function m()
 (
     _trigger_build "all-modules" "$@"
diff --git a/target/board/BoardConfigGkiCommon.mk b/target/board/BoardConfigGkiCommon.mk
new file mode 100644
index 0000000..1a8c6b1
--- /dev/null
+++ b/target/board/BoardConfigGkiCommon.mk
@@ -0,0 +1,44 @@
+# Copyright (C) 2021 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.
+#
+
+# Enable GKI 2.0 signing.
+BOARD_GKI_SIGNING_KEY_PATH := build/make/target/product/gsi/testkey_rsa2048.pem
+BOARD_GKI_SIGNING_ALGORITHM := SHA256_RSA2048
+
+# The following is needed to allow release signing process appends more extra
+# args, e.g., passing --signing_helper_with_files from mkbootimg to avbtool.
+# See b/178559811 for more details.
+BOARD_GKI_SIGNING_SIGNATURE_ARGS := --prop foo:bar
+
+# Boot image with ramdisk and kernel
+BOARD_RAMDISK_USE_LZ4 := true
+BOARD_BOOT_HEADER_VERSION := 4
+BOARD_MKBOOTIMG_ARGS += --header_version $(BOARD_BOOT_HEADER_VERSION)
+BOARD_USES_RECOVERY_AS_BOOT :=
+TARGET_NO_KERNEL := false
+BOARD_USES_GENERIC_KERNEL_IMAGE := true
+BOARD_KERNEL_MODULE_INTERFACE_VERSIONS := \
+    5.4-android12-unstable \
+    5.10-android12-unstable \
+
+# Copy boot image in $OUT to target files. This is defined for targets where
+# the installed GKI APEXes are built from source.
+BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES := true
+
+# No vendor_boot
+BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT :=
+
+# No recovery
+BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE :=
diff --git a/target/board/BoardConfigGsiCommon.mk b/target/board/BoardConfigGsiCommon.mk
index 95ba1d0..c577870 100644
--- a/target/board/BoardConfigGsiCommon.mk
+++ b/target/board/BoardConfigGsiCommon.mk
@@ -30,14 +30,6 @@
 # the devices with metadata parition
 BOARD_USES_METADATA_PARTITION := true
 
-# Enable GKI 2.0 signing.
-BOARD_GKI_SIGNING_KEY_PATH := build/make/target/product/gsi/testkey_rsa2048.pem
-BOARD_GKI_SIGNING_ALGORITHM := SHA256_RSA2048
-# The following is needed to allow release signing process appends more extra
-# args, e.g., passing --signing_helper_with_files from mkbootimg to avbtool.
-# See b/178559811 for more details.
-BOARD_GKI_SIGNING_SIGNATURE_ARGS := --prop foo:bar
-
 # Android Verified Boot (AVB):
 #   Set the rollback index to zero, to prevent the device bootloader from
 #   updating the last seen rollback index in the tamper-evident storage.
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 423faf9..21b4065 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -53,6 +53,7 @@
 endif
 
 include build/make/target/board/BoardConfigGsiCommon.mk
+include build/make/target/board/BoardConfigGkiCommon.mk
 
 BOARD_KERNEL-4.19-GZ_BOOTIMAGE_PARTITION_SIZE := 47185920
 BOARD_KERNEL-5.4_BOOTIMAGE_PARTITION_SIZE := 67108864
@@ -73,10 +74,6 @@
 
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
 
-BOARD_RAMDISK_USE_LZ4 := true
-BOARD_BOOT_HEADER_VERSION := 4
-BOARD_MKBOOTIMG_ARGS += --header_version $(BOARD_BOOT_HEADER_VERSION)
-
 BOARD_KERNEL_BINARIES := \
     kernel-4.19-gz \
     kernel-5.4 kernel-5.4-gz kernel-5.4-lz4 \
@@ -90,24 +87,6 @@
 
 endif
 
-# Boot image
-BOARD_USES_RECOVERY_AS_BOOT :=
-TARGET_NO_KERNEL := false
-BOARD_USES_GENERIC_KERNEL_IMAGE := true
-# TODO(b/187432172): Add 5.10-android12-unstable
-BOARD_KERNEL_MODULE_INTERFACE_VERSIONS := \
-    5.4-android12-0 \
-
-# Copy boot image in $OUT to target files. This is defined for targets where
-# the installed GKI APEXes are built from source.
-BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES := true
-
-# No vendor_boot
-BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT :=
-
-# No recovery
-BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE :=
-
 # Some vendors still haven't cleaned up all device specific directories under
 # root!
 
diff --git a/target/board/generic_x86/BoardConfig.mk b/target/board/generic_x86/BoardConfig.mk
index c40c15b..47fd384 100644
--- a/target/board/generic_x86/BoardConfig.mk
+++ b/target/board/generic_x86/BoardConfig.mk
@@ -18,9 +18,8 @@
 TARGET_ARCH := x86
 TARGET_ARCH_VARIANT := x86
 
-TARGET_PRELINK_MODULE := false
-
 include build/make/target/board/BoardConfigGsiCommon.mk
+
 ifndef BUILDING_GSI
 include build/make/target/board/BoardConfigEmuCommon.mk
 
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
index 660ec6e..bdc862e 100755
--- a/target/board/generic_x86_64/BoardConfig.mk
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -22,9 +22,30 @@
 TARGET_2ND_ARCH := x86
 TARGET_2ND_ARCH_VARIANT := x86_64
 
-TARGET_PRELINK_MODULE := false
 include build/make/target/board/BoardConfigGsiCommon.mk
-ifndef BUILDING_GSI
+
+ifdef BUILDING_GSI
+include build/make/target/board/BoardConfigGkiCommon.mk
+
+BOARD_KERNEL-5.4_BOOTIMAGE_PARTITION_SIZE := 67108864
+BOARD_KERNEL-5.4-ALLSYMS_BOOTIMAGE_PARTITION_SIZE := 67108864
+BOARD_KERNEL-5.10_BOOTIMAGE_PARTITION_SIZE := 67108864
+BOARD_KERNEL-5.10-ALLSYMS_BOOTIMAGE_PARTITION_SIZE := 67108864
+
+BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
+
+BOARD_KERNEL_BINARIES := \
+    kernel-5.4 \
+    kernel-5.10 \
+
+ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
+BOARD_KERNEL_BINARIES += \
+    kernel-5.4-allsyms \
+    kernel-5.10-allsyms \
+
+endif
+
+else # BUILDING_GSI
 include build/make/target/board/BoardConfigEmuCommon.mk
 
 BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
@@ -41,4 +62,5 @@
 WIFI_DRIVER_FW_PATH_PARAM   := "/dev/null"
 WIFI_DRIVER_FW_PATH_STA     := "/dev/null"
 WIFI_DRIVER_FW_PATH_AP      := "/dev/null"
-endif
+
+endif # BUILDING_GSI
diff --git a/target/board/generic_x86_64/README.txt b/target/board/generic_x86_64/README.txt
index 46b015b..8e515c4 100644
--- a/target/board/generic_x86_64/README.txt
+++ b/target/board/generic_x86_64/README.txt
@@ -1,8 +1,7 @@
-The "generic_x86_64" product defines a non-hardware-specific IA target
-without a kernel or bootloader.
+The "generic_x86_64" product defines a non-hardware-specific x86_64 target
+without a bootloader.
 
-It can be used to build the entire user-level system, and
-will work with the IA version of the emulator,
+It is also the target to build the generic kernel image (GKI).
 
 It is not a product "base class"; no other products inherit
 from it or use it in any way.
diff --git a/target/board/generic_x86_64/device.mk b/target/board/generic_x86_64/device.mk
index 5ad008f..e195bd3 100755
--- a/target/board/generic_x86_64/device.mk
+++ b/target/board/generic_x86_64/device.mk
@@ -14,14 +14,21 @@
 # limitations under the License.
 #
 
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish # for libwifi-hal-emu
-PRODUCT_SOONG_NAMESPACES += device/generic/goldfish-opengl # for goldfish deps.
+PRODUCT_COPY_FILES += \
+    kernel/prebuilts/5.4/x86_64/kernel-5.4:kernel-5.4 \
+    kernel/prebuilts/5.10/x86_64/kernel-5.10:kernel-5.10 \
 
-ifdef NET_ETH0_STARTONBOOT
-  PRODUCT_VENDOR_PROPERTIES += net.eth0.startonboot=1
+$(call dist-for-goals, dist_files, kernel/prebuilts/5.4/x86_64/prebuilt-info.txt:kernel/5.4/prebuilt-info.txt)
+$(call dist-for-goals, dist_files, kernel/prebuilts/5.10/x86_64/prebuilt-info.txt:kernel/5.10/prebuilt-info.txt)
+
+ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
+PRODUCT_COPY_FILES += \
+    kernel/prebuilts/5.4/x86_64/kernel-5.4:kernel-5.4-allsyms \
+    kernel/prebuilts/5.10/x86_64/kernel-5.10:kernel-5.10-allsyms \
+
 endif
 
-# Ensure we package the BIOS files too.
-PRODUCT_HOST_PACKAGES += \
-	bios.bin \
-	vgabios-cirrus.bin \
+PRODUCT_BUILD_VENDOR_BOOT_IMAGE := false
+PRODUCT_BUILD_RECOVERY_IMAGE := false
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 21beda9..7e4c5ef 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -27,7 +27,6 @@
     android.test.base \
     android.test.mock \
     android.test.runner \
-    ANGLE \
     apexd \
     appops \
     app_process \
@@ -352,8 +351,6 @@
 PRODUCT_SYSTEM_PROPERTIES += debug.atrace.tags.enableflags=0
 PRODUCT_SYSTEM_PROPERTIES += persist.traced.enable=1
 
-PRODUCT_PROPERTY_OVERRIDES += ro.gfx.angle.supported=true
-
 # Packages included only for eng or userdebug builds, previously debug tagged
 PRODUCT_PACKAGES_DEBUG := \
     adb_keys \
diff --git a/target/product/gsi_release.mk b/target/product/gsi_release.mk
index 82af45f..25fa68b 100644
--- a/target/product/gsi_release.mk
+++ b/target/product/gsi_release.mk
@@ -42,9 +42,6 @@
 # Enable dynamic partition size
 PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
 
-# Enable various debugfs restrictions
-PRODUCT_SET_DEBUGFS_RESTRICTIONS := true
-
 # GSI targets should install "unflattened" APEXes in /system
 TARGET_FLATTEN_APEX := false
 
diff --git a/target/product/runtime_libart.mk b/target/product/runtime_libart.mk
index d65f180..b511aa6 100644
--- a/target/product/runtime_libart.mk
+++ b/target/product/runtime_libart.mk
@@ -75,10 +75,21 @@
 PRODUCT_PACKAGES += \
     hiddenapi-package-whitelist.xml \
 
+# The dalvik.vm.dexopt.thermal-cutoff property must contain one of the values
+# listed here:
+#
+# https://source.android.com/devices/architecture/hidl/thermal-mitigation#thermal-api
+#
+# If the thermal status of the device reaches or exceeds the value set here
+# background dexopt will be terminated and rescheduled using an exponential
+# backoff polcy.
+#
+# The thermal cutoff value is currently set to THERMAL_STATUS_MODERATE.
 PRODUCT_SYSTEM_PROPERTIES += \
     dalvik.vm.usejit=true \
     dalvik.vm.usejitprofiles=true \
     dalvik.vm.dexopt.secondary=true \
+    dalvik.vm.dexopt.thermal-cutoff=2 \
     dalvik.vm.appimageformat=lz4
 
 PRODUCT_SYSTEM_PROPERTIES += \
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 687070d..32a5dcb 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -114,6 +114,20 @@
     },
 }
 
+cc_library_static {
+    name: "ota_metadata_proto_cc",
+    srcs: [
+       "ota_metadata.proto",
+    ],
+    host_supported: true,
+    recovery_available: true,
+    proto: {
+        canonical_path_from_root: false,
+        type: "lite",
+        export_proto_headers: true,
+    },
+}
+
 java_library_static {
     name: "ota_metadata_proto_java",
     host_supported: true,
@@ -384,7 +398,7 @@
         "releasetools_common",
     ],
     required: [
-        "aapt",
+        "aapt2",
     ],
 }
 
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 2aceb78..c583d01 100644
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -420,8 +420,9 @@
     image_props["block_list"] = block_list.name
 
   # Use repeatable ext4 FS UUID and hash_seed UUID (based on partition name and
-  # build fingerprint).
-  build_info = common.BuildInfo(info_dict)
+  # build fingerprint). Also use the legacy build id, because the vbmeta digest
+  # isn't available at this point.
+  build_info = common.BuildInfo(info_dict, use_legacy_id=True)
   uuid_seed = what + "-" + build_info.GetPartitionFingerprint(what)
   image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed))
   hash_seed = "hash_seed-" + uuid_seed
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 2492da9..13c5363 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -283,7 +283,7 @@
     if "flash_logical_block_size" in prop_dict:
       build_command.extend(["-o", prop_dict["flash_logical_block_size"]])
     # Specify UUID and hash_seed if using mke2fs.
-    if prop_dict["ext_mkuserimg"] == "mkuserimg_mke2fs":
+    if os.path.basename(prop_dict["ext_mkuserimg"]) == "mkuserimg_mke2fs":
       if "uuid" in prop_dict:
         build_command.extend(["-U", prop_dict["uuid"]])
       if "hash_seed" in prop_dict:
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index b397fd0..5e2a50d 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -372,7 +372,10 @@
       "product", "product_services", "odm", "vendor", "system"]
   _RO_PRODUCT_PROPS_DEFAULT_SOURCE_ORDER_LEGACY = []
 
-  def __init__(self, info_dict, oem_dicts=None):
+  # The length of vbmeta digest to append to the fingerprint
+  _VBMETA_DIGEST_SIZE_USED = 8
+
+  def __init__(self, info_dict, oem_dicts=None, use_legacy_id=False):
     """Initializes a BuildInfo instance with the given dicts.
 
     Note that it only wraps up the given dicts, without making copies.
@@ -383,6 +386,9 @@
           that it always uses the first dict to calculate the fingerprint or the
           device name. The rest would be used for asserting OEM properties only
           (e.g. one package can be installed on one of these devices).
+      use_legacy_id: Use the legacy build id to construct the fingerprint. This
+          is used when we need a BuildInfo class, while the vbmeta digest is
+          unavailable.
 
     Raises:
       ValueError: On invalid inputs.
@@ -391,6 +397,7 @@
     self.oem_dicts = oem_dicts
 
     self._is_ab = info_dict.get("ab_update") == "true"
+    self.use_legacy_id = use_legacy_id
 
     # Skip _oem_props if oem_dicts is None to use BuildInfo in
     # sign_target_files_apks
@@ -491,6 +498,9 @@
     if prop in BuildInfo._RO_PRODUCT_RESOLVE_PROPS:
       return self._ResolveRoProductBuildProp(prop)
 
+    if prop == "ro.build.id":
+      return self._GetBuildId()
+
     prop_val = self._GetRawBuildProp(prop, None)
     if prop_val is not None:
       return prop_val
@@ -557,6 +567,34 @@
 
     return self.GetBuildProp("ro.build.version.release")
 
+  def _GetBuildId(self):
+    build_id = self._GetRawBuildProp("ro.build.id", None)
+    if build_id:
+      return build_id
+
+    legacy_build_id = self.GetBuildProp("ro.build.legacy.id")
+    if not legacy_build_id:
+      raise ExternalError("Couldn't find build id in property file")
+
+    if self.use_legacy_id:
+      return legacy_build_id
+
+    # Append the top 8 chars of vbmeta digest to the existing build id. The
+    # logic needs to match the one in init, so that OTA can deliver correctly.
+    avb_enable = self.info_dict.get("avb_enable") == "true"
+    if not avb_enable:
+      raise ExternalError("AVB isn't enabled when using legacy build id")
+
+    vbmeta_digest = self.info_dict.get("vbmeta_digest")
+    if not vbmeta_digest:
+      raise ExternalError("Vbmeta digest isn't provided when using legacy build"
+                          " id")
+    if len(vbmeta_digest) < self._VBMETA_DIGEST_SIZE_USED:
+      raise ExternalError("Invalid vbmeta digest " + vbmeta_digest)
+
+    digest_prefix = vbmeta_digest[:self._VBMETA_DIGEST_SIZE_USED]
+    return legacy_build_id + '.' + digest_prefix
+
   def _GetPartitionPlatformVersion(self, partition):
     try:
       return self.GetPartitionBuildProp("ro.build.version.release_or_codename",
@@ -790,12 +828,19 @@
   # Set up the salt (based on fingerprint) that will be used when adding AVB
   # hash / hashtree footers.
   if d.get("avb_enable") == "true":
-    build_info = BuildInfo(d)
+    build_info = BuildInfo(d, use_legacy_id=True)
     for partition in PARTITIONS_WITH_BUILD_PROP:
       fingerprint = build_info.GetPartitionFingerprint(partition)
       if fingerprint:
         d["avb_{}_salt".format(partition)] = sha256(
             fingerprint.encode()).hexdigest()
+
+    # Set the vbmeta digest if exists
+    try:
+      d["vbmeta_digest"] = read_helper("META/vbmeta_digest.txt").rstrip()
+    except KeyError:
+      pass
+
   try:
     d["ab_partitions"] = read_helper("META/ab_partitions.txt").split("\n")
   except KeyError:
@@ -1339,7 +1384,7 @@
 
   vbmeta_image = MakeTempFile()
   os.rename(output_image, vbmeta_image)
-  build_info = BuildInfo(OPTIONS.info_dict)
+  build_info = BuildInfo(OPTIONS.info_dict, use_legacy_id=True)
   version_incremental = build_info.GetBuildProp("ro.build.version.incremental")
   aftltool = OPTIONS.aftl_tool_path
   server_argument_list = [OPTIONS.aftl_server, OPTIONS.aftl_key_path]
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 61c8212..229f7e9 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -1064,11 +1064,6 @@
     # build doesn't supports it.
     if not source_info.is_vabc or not target_info.is_vabc:
       OPTIONS.disable_vabc = True
-    if not OPTIONS.disable_vabc:
-      # TODO(zhangkelvin) Remove this once FEC on VABC is supported
-      logger.info("Virtual AB Compression enabled, disabling FEC")
-      OPTIONS.disable_fec_computation = True
-      OPTIONS.disable_verity_computation = True
 
   else:
     assert "ab_partitions" in OPTIONS.info_dict, \
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index a516366..1a00549 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -48,6 +48,22 @@
 
 class BuildInfoTest(test_utils.ReleaseToolsTestCase):
 
+  TEST_INFO_FINGERPRINT_DICT = {
+      'build.prop': common.PartitionBuildProps.FromDictionary(
+          'system', {
+              'ro.product.brand': 'product-brand',
+              'ro.product.name': 'product-name',
+              'ro.product.device': 'product-device',
+              '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.sdk': 30,
+          }
+      ),
+  }
+
   TEST_INFO_DICT = {
       'build.prop': common.PartitionBuildProps.FromDictionary(
           'system', {
@@ -202,6 +218,33 @@
         'ro.build.fingerprint'] = 'bad\x80fingerprint'
     self.assertRaises(ValueError, common.BuildInfo, info_dict, None)
 
+  def test_init_goodFingerprint(self):
+    info_dict = copy.deepcopy(self.TEST_INFO_FINGERPRINT_DICT)
+    build_info = common.BuildInfo(info_dict)
+    self.assertEqual(
+      'product-brand/product-name/product-device:version-release/build-id/'
+      'version-incremental:build-type/build-tags', build_info.fingerprint)
+
+    build_props = info_dict['build.prop'].build_props
+    del build_props['ro.build.id']
+    build_props['ro.build.legacy.id'] = 'legacy-build-id'
+    build_info = common.BuildInfo(info_dict, use_legacy_id=True)
+    self.assertEqual(
+      'product-brand/product-name/product-device:version-release/'
+      'legacy-build-id/version-incremental:build-type/build-tags',
+      build_info.fingerprint)
+
+    self.assertRaises(common.ExternalError, common.BuildInfo, info_dict, None,
+                      False)
+
+    info_dict['avb_enable'] = 'true'
+    info_dict['vbmeta_digest'] = 'abcde12345'
+    build_info = common.BuildInfo(info_dict, use_legacy_id=False)
+    self.assertEqual(
+      'product-brand/product-name/product-device:version-release/'
+      'legacy-build-id.abcde123/version-incremental:build-type/build-tags',
+      build_info.fingerprint)
+
   def test___getitem__(self):
     target_info = common.BuildInfo(self.TEST_INFO_DICT, None)
     self.assertEqual('value1', target_info['property1'])