Merge "Don't set the build id if we need to append the digest"
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index c9fcf47..74558f5 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -27,6 +27,7 @@
 # Add variables to the namespace below:
 
 $(call add_soong_config_var,ANDROID,TARGET_ENABLE_MEDIADRM_64)
+$(call add_soong_config_var,ANDROID,BOARD_USES_ODMIMAGE)
 
 # TODO(b/172480615): Remove when platform uses ART Module prebuilts by default.
 ifeq (,$(filter art_module,$(SOONG_CONFIG_NAMESPACES)))
diff --git a/core/dex_preopt.mk b/core/dex_preopt.mk
index dd31999..593ad66 100644
--- a/core/dex_preopt.mk
+++ b/core/dex_preopt.mk
@@ -62,7 +62,9 @@
 
 boot_zip := $(PRODUCT_OUT)/boot.zip
 bootclasspath_jars := $(DEXPREOPT_BOOTCLASSPATH_DEX_FILES)
-system_server_jars := $(foreach m,$(PRODUCT_SYSTEM_SERVER_JARS),$(PRODUCT_OUT)/system/framework/$(m).jar)
+system_server_jars := \
+  $(foreach m,$(PRODUCT_SYSTEM_SERVER_JARS),\
+    $(PRODUCT_OUT)/system/framework/$(call word-colon,2,$(m)).jar)
 
 $(boot_zip): PRIVATE_BOOTCLASSPATH_JARS := $(bootclasspath_jars)
 $(boot_zip): PRIVATE_SYSTEM_SERVER_JARS := $(system_server_jars)
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index a23bae2..d925899 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -70,9 +70,10 @@
 # /data. If we don't do this they will need to be extracted which is not favorable for RAM usage
 # or performance. If my_preopt_for_extracted_apk is true, we ignore the only preopt boot image
 # options.
+system_server_jars := $(foreach m,$(PRODUCT_SYSTEM_SERVER_JARS),$(call word-colon,2,$(m)))
 ifneq (true,$(my_preopt_for_extracted_apk))
   ifeq (true,$(WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY))
-    ifeq ($(filter $(PRODUCT_SYSTEM_SERVER_JARS) $(DEXPREOPT_BOOT_JARS_MODULES),$(LOCAL_MODULE)),)
+    ifeq ($(filter $(system_server_jars) $(DEXPREOPT_BOOT_JARS_MODULES),$(LOCAL_MODULE)),)
       LOCAL_DEX_PREOPT :=
     endif
   endif
@@ -266,7 +267,7 @@
 	  $(PRIVATE_DEXPREOPT_CONFIGS) \
 	  $(PRIVATE_RELAX_CHECK) \
 	  $<
-  $(built_module) : $(my_enforced_uses_libraries)
+  $(LOCAL_BUILT_MODULE) : $(my_enforced_uses_libraries)
 endif
 
 ################################################################################
@@ -388,7 +389,7 @@
   $(call end_json_map)
   $(call add_json_list, Archs,                          $(my_dexpreopt_archs))
   $(call add_json_list, DexPreoptImages,                $(my_dexpreopt_images))
-  $(call add_json_list, DexPreoptImageLocations,        $(my_dexpreopt_image_locations))
+  $(call add_json_list, DexPreoptImageLocationsOnHost,  $(my_dexpreopt_image_locations))
   $(call add_json_list, PreoptBootClassPathDexFiles,    $(DEXPREOPT_BOOTCLASSPATH_DEX_FILES))
   $(call add_json_list, PreoptBootClassPathDexLocations,$(DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS))
   $(call add_json_bool, PreoptExtractedApk,             $(my_preopt_for_extracted_apk))
diff --git a/core/product_config.mk b/core/product_config.mk
index eb6f69f..5c85fb8 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -231,12 +231,23 @@
 PRODUCT_AAPT_CONFIG_SP := $(PRODUCT_AAPT_CONFIG)
 PRODUCT_AAPT_CONFIG := $(subst $(space),$(comma),$(PRODUCT_AAPT_CONFIG))
 
+###########################################################
+## Add 'platform:' prefix to jars not in <apex>:<module> format.
+##
+## This makes sure that a jar corresponds to ConfigureJarList format of <apex> and <module> pairs
+## where needed.
+##
+## $(1): a list of jars either in <module> or <apex>:<module> format
+###########################################################
+
+define qualify-platform-jars
+  $(foreach jar,$(1),$(if $(findstring :,$(jar)),,platform:)$(jar))
+endef
+
 # Extra boot jars must be appended at the end after common boot jars.
 PRODUCT_BOOT_JARS += $(PRODUCT_BOOT_JARS_EXTRA)
 
-# Add 'platform:' prefix to unqualified boot jars
-PRODUCT_BOOT_JARS := $(foreach pair,$(PRODUCT_BOOT_JARS), \
-  $(if $(findstring :,$(pair)),,platform:)$(pair))
+PRODUCT_BOOT_JARS := $(call qualify-platform-jars,$(PRODUCT_BOOT_JARS))
 
 # Replaces references to overridden boot jar modules in a boot jars variable.
 # $(1): Name of a boot jars variable with <apex>:<jar> pairs.
@@ -254,6 +265,8 @@
 # The extra system server jars must be appended at the end after common system server jars.
 PRODUCT_SYSTEM_SERVER_JARS += $(PRODUCT_SYSTEM_SERVER_JARS_EXTRA)
 
+PRODUCT_SYSTEM_SERVER_JARS := $(call qualify-platform-jars,$(PRODUCT_SYSTEM_SERVER_JARS))
+
 ifndef PRODUCT_SYSTEM_NAME
   PRODUCT_SYSTEM_NAME := $(PRODUCT_NAME)
 endif
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index 4138277..181ea62 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -240,7 +240,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 := 2021-04-05
+      PLATFORM_SECURITY_PATCH := 2021-05-05
 endif
 .KATI_READONLY := PLATFORM_SECURITY_PATCH
 
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index 15c311c..1229327 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -98,9 +98,9 @@
 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 \
-    5.10-android12-0 \
 
 # Copy boot image in $OUT to target files. This is defined for targets where
 # the installed GKI APEXes are built from source.
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index feb2eb7..0e652c1 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -48,17 +48,17 @@
 PRODUCT_BOOT_JARS += \
     com.android.i18n:core-icu4j
 
-# Updatable APEX jars. Keep the list sorted.
+# Updatable APEX jars. Keep the list sorted by module names and then library names.
 PRODUCT_UPDATABLE_BOOT_JARS := \
     com.android.conscrypt:conscrypt \
+    com.android.ipsec:android.net.ipsec.ike \
     com.android.media:updatable-media \
     com.android.mediaprovider:framework-mediaprovider \
     com.android.os.statsd:framework-statsd \
     com.android.permission:framework-permission \
     com.android.sdkext:framework-sdkextensions \
-    com.android.wifi:framework-wifi \
     com.android.tethering:framework-tethering \
-    com.android.ipsec:android.net.ipsec.ike
+    com.android.wifi:framework-wifi
 
 # Minimal configuration for running dex2oat (default argument values).
 # PRODUCT_USES_DEFAULT_ART_CONFIG must be true to enable boot image compilation.
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 65c035e..687070d 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -114,6 +114,25 @@
     },
 }
 
+java_library_static {
+    name: "ota_metadata_proto_java",
+    host_supported: true,
+    proto: {
+        type: "nano",
+    },
+    srcs: ["ota_metadata.proto"],
+    sdk_version: "9",
+    target: {
+        android: {
+            jarjar_rules: "jarjar-rules.txt",
+        },
+        host: {
+            static_libs: ["libprotobuf-java-nano"],
+        },
+    },
+    visibility: ["//frameworks/base:__subpackages__"]
+}
+
 python_defaults {
     name: "releasetools_ota_from_target_files_defaults",
     srcs: [
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 00bbb21..2aceb78 100644
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -259,6 +259,7 @@
       block_list=block_list)
   return img.name
 
+
 def AddOdmDlkm(output_zip):
   """Turn the contents of OdmDlkm into an odm_dlkm image and store it in output_zip."""
 
@@ -310,6 +311,7 @@
   img.Write()
   return img.name
 
+
 def AddPvmfw(output_zip):
   """Adds the pvmfw image.
 
@@ -345,6 +347,7 @@
   img.Write()
   return img.name
 
+
 def AddCustomImages(output_zip, partition_name):
   """Adds and signs custom images in IMAGES/.
 
@@ -359,8 +362,6 @@
     AssertionError: If image can't be found.
   """
 
-  partition_size = OPTIONS.info_dict.get(
-      "avb_{}_partition_size".format(partition_name))
   key_path = OPTIONS.info_dict.get("avb_{}_key_path".format(partition_name))
   algorithm = OPTIONS.info_dict.get("avb_{}_algorithm".format(partition_name))
   extra_args = OPTIONS.info_dict.get(
@@ -955,6 +956,20 @@
     with open(pack_radioimages_txt) as f:
       AddPackRadioImages(output_zip, f.readlines())
 
+  # Calculate the vbmeta digest and put the result in to META/
+  boot_images = OPTIONS.info_dict.get("boot_images")
+  # Disable the digest calculation if the target_file is used as a container
+  # for boot images.
+  boot_container = boot_images and len(boot_images.split()) >= 2
+  if (OPTIONS.info_dict.get("avb_enable") == "true" and not boot_container and
+      OPTIONS.info_dict.get("avb_building_vbmeta_image") == "true"):
+    avbtool = OPTIONS.info_dict["avb_avbtool"]
+    digest = verity_utils.CalculateVbmetaDigest(OPTIONS.input_tmp, avbtool)
+    vbmeta_digest_txt = os.path.join(OPTIONS.input_tmp, "META",
+                                     "vbmeta_digest.txt")
+    with open(vbmeta_digest_txt, 'w') as f:
+      f.write(digest)
+
   if output_zip:
     common.ZipClose(output_zip)
     if OPTIONS.replace_updated_files_list:
diff --git a/tools/releasetools/jarjar-rules.txt b/tools/releasetools/jarjar-rules.txt
new file mode 100644
index 0000000..40043a8
--- /dev/null
+++ b/tools/releasetools/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.google.protobuf.nano.** com.android.framework.protobuf.nano.@1
diff --git a/tools/releasetools/ota_metadata.proto b/tools/releasetools/ota_metadata.proto
index 7aaca6f..ed9d0c3 100644
--- a/tools/releasetools/ota_metadata.proto
+++ b/tools/releasetools/ota_metadata.proto
@@ -23,6 +23,8 @@
 
 package build.tools.releasetools;
 option optimize_for = LITE_RUNTIME;
+option java_package = "android.ota";
+option java_outer_classname = "OtaPackageMetadata";
 
 // The build information of a particular partition on the device.
 message PartitionState {
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 313d1e6..f0110ea 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -629,6 +629,10 @@
     elif OPTIONS.replace_verity_keyid and filename == "BOOT/cmdline":
       pass
 
+    # Skip the vbmeta digest as we will recalculate it.
+    elif filename == "META/vbmeta_digest.txt":
+      pass
+
     # Skip the care_map as we will regenerate the system/vendor images.
     elif filename in ["META/care_map.pb", "META/care_map.txt"]:
       pass
diff --git a/tools/releasetools/test_verity_utils.py b/tools/releasetools/test_verity_utils.py
index a850390..e2a022a 100644
--- a/tools/releasetools/test_verity_utils.py
+++ b/tools/releasetools/test_verity_utils.py
@@ -27,7 +27,8 @@
 from test_utils import (
     get_testdata_dir, ReleaseToolsTestCase, SkipIfExternalToolsUnavailable)
 from verity_utils import (
-    CreateHashtreeInfoGenerator, CreateVerityImageBuilder, HashtreeInfo,
+    CalculateVbmetaDigest, CreateHashtreeInfoGenerator,
+    CreateVerityImageBuilder, HashtreeInfo,
     VerifiedBootVersion1HashtreeInfoGenerator)
 
 BLOCK_SIZE = common.BLOCK_SIZE
@@ -388,3 +389,31 @@
       self.assertLess(
           _SizeCalculator(min_partition_size - BLOCK_SIZE),
           image_size)
+
+  @SkipIfExternalToolsUnavailable()
+  def test_CalculateVbmetaDigest(self):
+    prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT)
+    verity_image_builder = CreateVerityImageBuilder(prop_dict)
+    self.assertEqual(2, verity_image_builder.version)
+
+    input_dir = common.MakeTempDir()
+    image_dir = common.MakeTempDir()
+    os.mkdir(os.path.join(image_dir, 'IMAGES'))
+    system_image = os.path.join(image_dir, 'IMAGES', 'system.img')
+    system_image_size = verity_image_builder.CalculateMaxImageSize()
+    cmd = ['mkuserimg_mke2fs', input_dir, system_image, 'ext4', '/system',
+           str(system_image_size), '-j', '0', '-s']
+    common.RunAndCheckOutput(cmd)
+    verity_image_builder.Build(system_image)
+
+    # Additionally make vbmeta image
+    vbmeta_image = os.path.join(image_dir, 'IMAGES', 'vbmeta.img')
+    cmd = ['avbtool', 'make_vbmeta_image', '--include_descriptors_from_image',
+           system_image, '--output', vbmeta_image]
+    common.RunAndCheckOutput(cmd)
+
+    # Verify the verity metadata.
+    cmd = ['avbtool', 'verify_image', '--image', vbmeta_image]
+    common.RunAndCheckOutput(cmd)
+    digest = CalculateVbmetaDigest(image_dir, 'avbtool')
+    self.assertIsNotNone(digest)
diff --git a/tools/releasetools/verity_utils.py b/tools/releasetools/verity_utils.py
index 8faa2d1..a08ddbe 100644
--- a/tools/releasetools/verity_utils.py
+++ b/tools/releasetools/verity_utils.py
@@ -26,6 +26,7 @@
 import os.path
 import shlex
 import struct
+import sys
 
 import common
 import sparse_img
@@ -739,6 +740,30 @@
   return int(output.split()[0]) * 1024
 
 
+def CalculateVbmetaDigest(extracted_dir, avbtool):
+  """Calculates the vbmeta digest of the images in the extracted target_file"""
+
+  images_dir = common.MakeTempDir()
+  for name in ("PREBUILT_IMAGES", "RADIO", "IMAGES"):
+    path = os.path.join(extracted_dir, name)
+    if not os.path.exists(path):
+      continue
+
+    # Create symlink for image files under PREBUILT_IMAGES, RADIO and IMAGES,
+    # and put them into one directory.
+    for filename in os.listdir(path):
+      if not filename.endswith(".img"):
+        continue
+      symlink_path = os.path.join(images_dir, filename)
+      # The files in latter directory overwrite the existing links
+      common.RunAndCheckOutput(
+        ['ln', '-sf', os.path.join(path, filename), symlink_path])
+
+  cmd = [avbtool, "calculate_vbmeta_digest", "--image",
+         os.path.join(images_dir, 'vbmeta.img')]
+  return common.RunAndCheckOutput(cmd)
+
+
 def main(argv):
   if len(argv) != 2:
     print(__doc__)