Merge "Uses the KNOWN_HIDL_INTERFACES file in host_init_verifier."
diff --git a/core/Makefile b/core/Makefile
index e921dfa..838a96c 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -4536,6 +4536,19 @@
 
 endif # TARGET_BUILD_APPS
 
+
+ifeq (true,$(PRODUCT_USE_DYNAMIC_PARTITIONS))
+
+# Dump variables used by build_super_image.py (for building super.img and super_empty.img).
+# $(1): output file
+define dump-super-image-info
+  $(call dump-dynamic-partitions-info,$(1))
+  $(if $(filter true,$(AB_OTA_UPDATER)), \
+    echo "ab_update=true" >> $(1))
+endef
+
+endif # PRODUCT_USE_DYNAMIC_PARTITIONS
+
 # -----------------------------------------------------------------
 # super partition image (dist)
 
@@ -4544,13 +4557,6 @@
 # BOARD_SUPER_PARTITION_SIZE must be defined to build super image.
 ifneq ($(BOARD_SUPER_PARTITION_SIZE),)
 
-# Dump variables used by build_super_image.py.
-define dump-super-image-info
-  $(call dump-dynamic-partitions-info,$(1))
-  $(if $(filter true,$(AB_OTA_UPDATER)), \
-    echo "ab_update=true" >> $(1))
-endef
-
 ifneq (true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS))
 
 # For real devices and for dist builds, build super image from target files to an intermediate directory.
@@ -4631,7 +4637,7 @@
 # -----------------------------------------------------------------
 # super empty image
 
-ifeq (true,$(PRODUCT_BUILD_SUPER_PARTITION))
+ifeq (true,$(PRODUCT_USE_DYNAMIC_PARTITIONS))
 ifneq ($(BOARD_SUPER_PARTITION_SIZE),)
 
 INSTALLED_SUPERIMAGE_EMPTY_TARGET := $(PRODUCT_OUT)/super_empty.img
@@ -4647,7 +4653,7 @@
 $(call dist-for-goals,dist_files,$(INSTALLED_SUPERIMAGE_EMPTY_TARGET))
 
 endif # BOARD_SUPER_PARTITION_SIZE != ""
-endif # PRODUCT_BUILD_SUPER_PARTITION == "true"
+endif # PRODUCT_USE_DYNAMIC_PARTITIONS == "true"
 
 
 # -----------------------------------------------------------------
diff --git a/core/config.mk b/core/config.mk
index 4ce664a..537dc92 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -891,16 +891,12 @@
 #     - BOARD_{GROUP}_PARTITION_PARTITION_LIST: the list of partitions that belongs to this group.
 #       If empty, no partitions belong to this group, and the sum of sizes is effectively 0.
 $(foreach group,$(call to-upper,$(BOARD_SUPER_PARTITION_GROUPS)), \
-    $(eval BOARD_$(group)_PARTITION_LIST ?=) \
-    $(eval .KATI_READONLY := BOARD_$(group)_PARTITION_LIST) \
-)
-ifeq ($(PRODUCT_BUILD_SUPER_PARTITION),true)
-$(foreach group,$(call to-upper,$(BOARD_SUPER_PARTITION_GROUPS)), \
     $(eval BOARD_$(group)_SIZE := $(strip $(BOARD_$(group)_SIZE))) \
     $(if $(BOARD_$(group)_SIZE),,$(error BOARD_$(group)_SIZE must not be empty)) \
     $(eval .KATI_READONLY := BOARD_$(group)_SIZE) \
+    $(eval BOARD_$(group)_PARTITION_LIST ?=) \
+    $(eval .KATI_READONLY := BOARD_$(group)_PARTITION_LIST) \
 )
-endif # PRODUCT_BUILD_SUPER_PARTITION
 
 # BOARD_*_PARTITION_LIST: a list of the following tokens
 valid_super_partition_list := system vendor product product_services odm
diff --git a/core/main.mk b/core/main.mk
index 73aa649..7ee63c6 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -343,6 +343,15 @@
 endif
 endif
 
+## java coverage ##
+# Install additional tools on java coverage builds
+ifeq (true,$(EMMA_INSTRUMENT))
+ifneq (,$(filter debug,$(tags_to_install)))
+  tags_to_install += java_coverage
+endif
+endif
+
+
 ## sdk ##
 
 ifdef is_sdk_build
@@ -1140,6 +1149,7 @@
     $(if $(filter debug,$(tags_to_install)),$(PRODUCTS.$(_mk).PRODUCT_PACKAGES_DEBUG)) \
     $(if $(filter tests,$(tags_to_install)),$(PRODUCTS.$(_mk).PRODUCT_PACKAGES_TESTS)) \
     $(if $(filter asan,$(tags_to_install)),$(PRODUCTS.$(_mk).PRODUCT_PACKAGES_DEBUG_ASAN)) \
+    $(if $(filter java_coverage,$(tags_to_install)),$(PRODUCTS.$(_mk).PRODUCT_PACKAGES_DEBUG_JAVA_COVERAGE)) \
     $(call auto-included-modules) \
   ) \
   $(eval ### Filter out the overridden packages and executables before doing expansion) \
diff --git a/core/product.mk b/core/product.mk
index 9ec3257..77b129d 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -126,6 +126,8 @@
 _product_list_vars += PRODUCT_PACKAGES
 _product_list_vars += PRODUCT_PACKAGES_DEBUG
 _product_list_vars += PRODUCT_PACKAGES_DEBUG_ASAN
+# Packages included only for eng/userdebug builds, when building with EMMA_INSTRUMENT=true
+_product_list_vars += PRODUCT_PACKAGES_DEBUG_JAVA_COVERAGE
 _product_list_vars += PRODUCT_PACKAGES_ENG
 _product_list_vars += PRODUCT_PACKAGES_TESTS
 
diff --git a/target/board/BoardConfigMainlineCommon.mk b/target/board/BoardConfigMainlineCommon.mk
index be014bf..9bc7e0c 100644
--- a/target/board/BoardConfigMainlineCommon.mk
+++ b/target/board/BoardConfigMainlineCommon.mk
@@ -39,6 +39,9 @@
 # Enable system property split for Treble
 BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true
 
+# Include stats logging code in LMKD
+TARGET_LMKD_STATS_LOG := true
+
 # Generate an APEX image for experiment b/119800099.
 DEXPREOPT_GENERATE_APEX_IMAGE := true
 
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index f09493e..162fbed 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -187,6 +187,7 @@
     libwifi-service \
     libwilhelm \
     linker \
+    linkerconfig \
     lmkd \
     locksettings \
     logcat \
@@ -375,6 +376,9 @@
 # Packages included only for eng/userdebug builds, when building with SANITIZE_TARGET=address
 PRODUCT_PACKAGES_DEBUG_ASAN :=
 
+PRODUCT_PACKAGES_DEBUG_JAVA_COVERAGE := \
+    libdumpcoverage
+
 PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
     frameworks/base/config/preloaded-classes:system/etc/preloaded-classes)
 
diff --git a/target/product/mainline_system.mk b/target/product/mainline_system.mk
index f836bd3..8bcc212 100644
--- a/target/product/mainline_system.mk
+++ b/target/product/mainline_system.mk
@@ -97,9 +97,6 @@
 PRODUCT_HOST_PACKAGES += \
     tinyplay
 
-# Enable stats logging in LMKD
-TARGET_LMKD_STATS_LOG := true
-
 # Enable dynamic partition size
 PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
 
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 44719ed..98386a6 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -126,7 +126,7 @@
   if not image_size:
     return None
 
-  image_blocks = int(image_size) / 4096 - 1
+  image_blocks = int(image_size) // 4096 - 1
   assert image_blocks > 0, "blocks for {} must be positive".format(which)
 
   # For sparse images, we will only check the blocks that are listed in the care
@@ -154,16 +154,16 @@
     return img.name
 
   def output_sink(fn, data):
-    ofile = open(os.path.join(OPTIONS.input_tmp, "SYSTEM", fn), "w")
-    ofile.write(data)
-    ofile.close()
+    output_file = os.path.join(OPTIONS.input_tmp, "SYSTEM", fn)
+    with open(output_file, "wb") as ofile:
+      ofile.write(data)
 
     if output_zip:
       arc_name = "SYSTEM/" + fn
       if arc_name in output_zip.namelist():
         OPTIONS.replace_updated_files_list.append(arc_name)
       else:
-        common.ZipWrite(output_zip, ofile.name, arc_name)
+        common.ZipWrite(output_zip, output_file, arc_name)
 
   if (OPTIONS.rebuild_recovery and recovery_img is not None and
       boot_img is not None):
@@ -290,7 +290,7 @@
 
 
 def CreateImage(input_dir, info_dict, what, output_file, block_list=None):
-  logger.info("creating " + what + ".img...")
+  logger.info("creating %s.img...", what)
 
   image_props = build_image.ImagePropFromGlobalDict(info_dict, what)
   fstab = info_dict["fstab"]
@@ -778,7 +778,7 @@
   partitions = dict()
 
   def banner(s):
-    logger.info("\n\n++++ " + s + " ++++\n\n")
+    logger.info("\n\n++++ %s  ++++\n\n", s)
 
   boot_image = None
   if has_boot:
@@ -888,10 +888,11 @@
     banner("vbmeta")
     AddVBMeta(output_zip, partitions, "vbmeta", vbmeta_partitions)
 
-  if OPTIONS.info_dict.get("build_super_partition") == "true":
+  if OPTIONS.info_dict.get("use_dynamic_partitions") == "true":
     banner("super_empty")
     AddSuperEmpty(output_zip)
 
+  if OPTIONS.info_dict.get("build_super_partition") == "true":
     if OPTIONS.info_dict.get(
         "build_retrofit_dynamic_partitions_ota_package") == "true":
       banner("super split images")
@@ -901,7 +902,7 @@
   ab_partitions_txt = os.path.join(OPTIONS.input_tmp, "META",
                                    "ab_partitions.txt")
   if os.path.exists(ab_partitions_txt):
-    with open(ab_partitions_txt, 'r') as f:
+    with open(ab_partitions_txt) as f:
       ab_partitions = f.readlines()
 
     # For devices using A/B update, make sure we have all the needed images
@@ -916,7 +917,7 @@
   pack_radioimages_txt = os.path.join(
       OPTIONS.input_tmp, "META", "pack_radioimages.txt")
   if os.path.exists(pack_radioimages_txt):
-    with open(pack_radioimages_txt, 'r') as f:
+    with open(pack_radioimages_txt) as f:
       AddPackRadioImages(output_zip, f.readlines())
 
   if output_zip:
diff --git a/tools/releasetools/apex_utils.py b/tools/releasetools/apex_utils.py
index 0751125..6eaa12f 100644
--- a/tools/releasetools/apex_utils.py
+++ b/tools/releasetools/apex_utils.py
@@ -18,7 +18,6 @@
 import os.path
 import re
 import shlex
-import sys
 import zipfile
 
 import common
@@ -42,11 +41,11 @@
     Exception.__init__(self, message)
 
 
-def SignApexPayload(payload_file, payload_key_path, payload_key_name, algorithm,
-                    salt, signing_args=None):
+def SignApexPayload(avbtool, payload_file, payload_key_path, payload_key_name,
+                    algorithm, salt, signing_args=None):
   """Signs a given payload_file with the payload key."""
   # Add the new footer. Old footer, if any, will be replaced by avbtool.
-  cmd = ['avbtool', 'add_hashtree_footer',
+  cmd = [avbtool, 'add_hashtree_footer',
          '--do_not_generate_fec',
          '--algorithm', algorithm,
          '--key', payload_key_path,
@@ -65,12 +64,12 @@
 
   # Verify the signed payload image with specified public key.
   logger.info('Verifying %s', payload_file)
-  VerifyApexPayload(payload_file, payload_key_path)
+  VerifyApexPayload(avbtool, payload_file, payload_key_path)
 
 
-def VerifyApexPayload(payload_file, payload_key):
+def VerifyApexPayload(avbtool, payload_file, payload_key):
   """Verifies the APEX payload signature with the given key."""
-  cmd = ['avbtool', 'verify_image', '--image', payload_file,
+  cmd = [avbtool, 'verify_image', '--image', payload_file,
          '--key', payload_key]
   try:
     common.RunAndCheckOutput(cmd)
@@ -80,10 +79,11 @@
             payload_file, payload_key, e))
 
 
-def ParseApexPayloadInfo(payload_path):
+def ParseApexPayloadInfo(avbtool, payload_path):
   """Parses the APEX payload info.
 
   Args:
+    avbtool: The AVB tool to use.
     payload_path: The path to the payload image.
 
   Raises:
@@ -96,7 +96,7 @@
   if not os.path.exists(payload_path):
     raise ApexInfoError('Failed to find image: {}'.format(payload_path))
 
-  cmd = ['avbtool', 'info_image', '--image', payload_path]
+  cmd = [avbtool, 'info_image', '--image', payload_path]
   try:
     output = common.RunAndCheckOutput(cmd)
   except common.ExternalError as e:
@@ -150,7 +150,7 @@
   return payload_info
 
 
-def SignApex(apex_data, payload_key, container_key, container_pw,
+def SignApex(avbtool, apex_data, payload_key, container_key, container_pw,
              codename_to_api_level_map, signing_args=None):
   """Signs the current APEX with the given payload/container keys.
 
@@ -178,8 +178,9 @@
   with zipfile.ZipFile(apex_file) as apex_fd:
     payload_file = apex_fd.extract(APEX_PAYLOAD_IMAGE, payload_dir)
 
-  payload_info = ParseApexPayloadInfo(payload_file)
+  payload_info = ParseApexPayloadInfo(avbtool, payload_file)
   SignApexPayload(
+      avbtool,
       payload_file,
       payload_key,
       payload_info['apex.key'],
@@ -188,7 +189,7 @@
       signing_args)
 
   # 1b. Update the embedded payload public key.
-  payload_public_key = common.ExtractAvbPublicKey(payload_key)
+  payload_public_key = common.ExtractAvbPublicKey(avbtool, payload_key)
 
   common.ZipDelete(apex_file, APEX_PAYLOAD_IMAGE)
   common.ZipDelete(apex_file, APEX_PUBKEY)
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 4bebef5..edde89c 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -54,7 +54,9 @@
       base_search_path = os.path.join(base_out_path,
                                       os.path.basename(os.getcwd()))
 
+    # Python >= 3.3 returns 'linux', whereas Python 2.7 gives 'linux2'.
     platform_search_path = {
+        "linux": os.path.join(base_search_path, "host/linux-x86"),
         "linux2": os.path.join(base_search_path, "host/linux-x86"),
         "darwin": os.path.join(base_search_path, "host/darwin-x86"),
     }
@@ -576,7 +578,7 @@
   """
   if key is None:
     key = info_dict["avb_" + partition + "_key_path"]
-  pubkey_path = ExtractAvbPublicKey(key)
+  pubkey_path = ExtractAvbPublicKey(info_dict["avb_avbtool"], key)
   rollback_index_location = info_dict[
       "avb_" + partition + "_rollback_index_location"]
   return "{}:{}:{}".format(partition, rollback_index_location, pubkey_path)
@@ -2237,10 +2239,11 @@
   return pubkey
 
 
-def ExtractAvbPublicKey(key):
+def ExtractAvbPublicKey(avbtool, key):
   """Extracts the AVB public key from the given public or private key.
 
   Args:
+    avbtool: The AVB tool to use.
     key: The input key file, which should be PEM-encoded public or private key.
 
   Returns:
@@ -2248,7 +2251,7 @@
   """
   output = MakeTempFile(prefix='avb-', suffix='.avbpubkey')
   RunAndCheckOutput(
-      ['avbtool', 'extract_public_key', "--key", key, "--output", output])
+      [avbtool, 'extract_public_key', "--key", key, "--output", output])
   return output
 
 
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index e2b0e3d..a9e9151 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -526,9 +526,9 @@
         list_prefix='super_',
         list_suffix='_partition_list')
     merged_dict.update(merged_dynamic_partitions_dict)
-    # Ensure that add_img_to_target_files rebuilds super_empty.img. This flag
-    # may have been set to false in the partial builds to prevent duplicate
-    # building of super.img and super_empty.img.
+    # Ensure that add_img_to_target_files rebuilds super split images for
+    # devices that retrofit dynamic partitions. This flag may have been set to
+    # false in the partial builds to prevent duplicate building of super.img.
     merged_dict['build_super_partition'] = 'true'
 
   # Replace <image>_selinux_fc values with framework or vendor file_contexts.bin
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 3442b27..0e84327 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -1938,7 +1938,7 @@
   target_file = common.MakeTempFile(prefix="targetfiles-", suffix=".zip")
   shutil.copyfile(input_file, target_file)
 
-  with zipfile.ZipFile(input_file, 'r') as input_zip:
+  with zipfile.ZipFile(input_file) as input_zip:
     namelist = input_zip.namelist()
 
   input_tmp = common.UnzipTemp(input_file, RETROFIT_DAP_UNZIP_PATTERN)
diff --git a/tools/releasetools/sign_apex.py b/tools/releasetools/sign_apex.py
index affd6a7..2516e15 100755
--- a/tools/releasetools/sign_apex.py
+++ b/tools/releasetools/sign_apex.py
@@ -19,6 +19,9 @@
 
 Usage:  sign_apex [flags] input_apex_file output_apex_file
 
+  --avbtool <avbtool>
+      Optional flag that specifies the AVB tool to use. Defaults to `avbtool`.
+
   --container_key <key>
       Mandatory flag that specifies the container signing key.
 
@@ -40,12 +43,14 @@
 logger = logging.getLogger(__name__)
 
 
-def SignApexFile(apex_file, payload_key, container_key, signing_args=None):
+def SignApexFile(avbtool, apex_file, payload_key, container_key,
+                 signing_args=None):
   """Signs the given apex file."""
   with open(apex_file, 'rb') as input_fp:
     apex_data = input_fp.read()
 
   return apex_utils.SignApex(
+      avbtool,
       apex_data,
       payload_key=payload_key,
       container_key=container_key,
@@ -59,7 +64,9 @@
   options = {}
 
   def option_handler(o, a):
-    if o == '--container_key':
+    if o == '--avbtool':
+      options['avbtool'] = a
+    elif o == '--container_key':
       # Strip the suffix if any, as common.SignFile expects no suffix.
       DEFAULT_CONTAINER_KEY_SUFFIX = '.x509.pem'
       if a.endswith(DEFAULT_CONTAINER_KEY_SUFFIX):
@@ -77,6 +84,7 @@
       argv, __doc__,
       extra_opts='',
       extra_long_opts=[
+          'avbtool=',
           'container_key=',
           'payload_extra_args=',
           'payload_key=',
@@ -91,6 +99,7 @@
   common.InitLogging()
 
   signed_apex = SignApexFile(
+      options.get('avbtool', 'avbtool'),
       args[0],
       options['payload_key'],
       options['container_key'],
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index 668ad9b..a7e6bb0 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -154,11 +154,11 @@
 
 def GetApkCerts(certmap):
   # apply the key remapping to the contents of the file
-  for apk, cert in certmap.iteritems():
+  for apk, cert in certmap.items():
     certmap[apk] = OPTIONS.key_map.get(cert, cert)
 
   # apply all the -e options, overriding anything in the file
-  for apk, cert in OPTIONS.extra_apks.iteritems():
+  for apk, cert in OPTIONS.extra_apks.items():
     if not cert:
       cert = "PRESIGNED"
     certmap[apk] = OPTIONS.key_map.get(cert, cert)
@@ -468,6 +468,7 @@
             maxsize, name, payload_key))
 
         signed_apex = apex_utils.SignApex(
+            misc_info['avb_avbtool'],
             data,
             payload_key,
             container_key,
@@ -519,14 +520,14 @@
       if stat.S_ISLNK(info.external_attr >> 16):
         new_data = data
       else:
-        new_data = RewriteProps(data)
+        new_data = RewriteProps(data.decode())
       common.ZipWriteStr(output_tf_zip, out_info, new_data)
 
     # Replace the certs in *mac_permissions.xml (there could be multiple, such
     # as {system,vendor}/etc/selinux/{plat,nonplat}_mac_permissions.xml).
     elif filename.endswith("mac_permissions.xml"):
       print("Rewriting %s with new keys." % (filename,))
-      new_data = ReplaceCerts(data)
+      new_data = ReplaceCerts(data.decode())
       common.ZipWriteStr(output_tf_zip, out_info, new_data)
 
     # Ask add_img_to_target_files to rebuild the recovery patch if needed.
@@ -572,7 +573,8 @@
       # key is specified via --avb_system_other_key.
       signing_key = OPTIONS.avb_keys.get("system_other")
       if signing_key:
-        public_key = common.ExtractAvbPublicKey(signing_key)
+        public_key = common.ExtractAvbPublicKey(
+            misc_info['avb_avbtool'], signing_key)
         print("    Rewriting AVB public key of system_other in /product")
         common.ZipWrite(output_tf_zip, public_key, filename)
 
@@ -630,17 +632,17 @@
   Raises:
     AssertionError: On finding duplicate entries.
   """
-  for old, new in OPTIONS.key_map.iteritems():
+  for old, new in OPTIONS.key_map.items():
     if OPTIONS.verbose:
       print("    Replacing %s.x509.pem with %s.x509.pem" % (old, new))
 
     try:
       with open(old + ".x509.pem") as old_fp:
         old_cert16 = base64.b16encode(
-            common.ParseCertificate(old_fp.read())).lower()
+            common.ParseCertificate(old_fp.read())).decode().lower()
       with open(new + ".x509.pem") as new_fp:
         new_cert16 = base64.b16encode(
-            common.ParseCertificate(new_fp.read())).lower()
+            common.ParseCertificate(new_fp.read())).decode().lower()
     except IOError as e:
       if OPTIONS.verbose or e.errno != errno.ENOENT:
         print("    Error accessing %s: %s.\nSkip replacing %s.x509.pem with "
@@ -858,7 +860,7 @@
         writable.
     key_path: The path to the PEM encoded X.509 certificate.
   """
-  in_cmdline = input_zip.read("BOOT/cmdline")
+  in_cmdline = input_zip.read("BOOT/cmdline").decode()
   # Copy in_cmdline to output_zip if veritykeyid is not present.
   if "veritykeyid" not in in_cmdline:
     common.ZipWriteStr(output_zip, "BOOT/cmdline", in_cmdline)
@@ -891,7 +893,7 @@
   current in-memory dict contains additional items computed at runtime.
   """
   misc_info_old = common.LoadDictionaryFromLines(
-      input_zip.read('META/misc_info.txt').split('\n'))
+      input_zip.read('META/misc_info.txt').decode().split('\n'))
   items = []
   for key in sorted(misc_info):
     if key in misc_info_old:
@@ -957,7 +959,7 @@
 
 
 def GetApiLevelAndCodename(input_tf_zip):
-  data = input_tf_zip.read("SYSTEM/build.prop")
+  data = input_tf_zip.read("SYSTEM/build.prop").decode()
   api_level = None
   codename = None
   for line in data.split("\n"):
@@ -979,7 +981,7 @@
 
 
 def GetCodenameToApiLevelMap(input_tf_zip):
-  data = input_tf_zip.read("SYSTEM/build.prop")
+  data = input_tf_zip.read("SYSTEM/build.prop").decode()
   api_level = None
   codenames = None
   for line in data.split("\n"):
@@ -997,7 +999,7 @@
   if codenames is None:
     raise ValueError("No ro.build.version.all_codenames in SYSTEM/build.prop")
 
-  result = dict()
+  result = {}
   for codename in codenames:
     codename = codename.strip()
     if codename:
@@ -1021,7 +1023,7 @@
         key.
   """
   keys = {}
-  for line in tf_zip.read("META/apexkeys.txt").split("\n"):
+  for line in tf_zip.read('META/apexkeys.txt').decode().split('\n'):
     line = line.strip()
     if not line:
       continue
diff --git a/tools/releasetools/test_apex_utils.py b/tools/releasetools/test_apex_utils.py
index c7d5807..e9c26f0 100644
--- a/tools/releasetools/test_apex_utils.py
+++ b/tools/releasetools/test_apex_utils.py
@@ -43,8 +43,9 @@
   def test_ParseApexPayloadInfo(self):
     payload_file = self._GetTestPayload()
     apex_utils.SignApexPayload(
-        payload_file, self.payload_key, 'testkey', 'SHA256_RSA2048', self.SALT)
-    payload_info = apex_utils.ParseApexPayloadInfo(payload_file)
+        'avbtool', payload_file, self.payload_key, 'testkey', 'SHA256_RSA2048',
+        self.SALT)
+    payload_info = apex_utils.ParseApexPayloadInfo('avbtool', payload_file)
     self.assertEqual('SHA256_RSA2048', payload_info['Algorithm'])
     self.assertEqual(self.SALT, payload_info['Salt'])
     self.assertEqual('testkey', payload_info['apex.key'])
@@ -53,8 +54,9 @@
   def test_SignApexPayload(self):
     payload_file = self._GetTestPayload()
     apex_utils.SignApexPayload(
-        payload_file, self.payload_key, 'testkey', 'SHA256_RSA2048', self.SALT)
-    apex_utils.VerifyApexPayload(payload_file, self.payload_key)
+        'avbtool', payload_file, self.payload_key, 'testkey', 'SHA256_RSA2048',
+        self.SALT)
+    apex_utils.VerifyApexPayload('avbtool', payload_file, self.payload_key)
 
   @test_utils.SkipIfExternalToolsUnavailable()
   def test_SignApexPayload_withSignerHelper(self):
@@ -64,17 +66,19 @@
     payload_signer_args = '--signing_helper_with_files {}'.format(
         signing_helper)
     apex_utils.SignApexPayload(
+        'avbtool',
         payload_file,
         self.payload_key,
         'testkey', 'SHA256_RSA2048', self.SALT,
         payload_signer_args)
-    apex_utils.VerifyApexPayload(payload_file, self.payload_key)
+    apex_utils.VerifyApexPayload('avbtool', payload_file, self.payload_key)
 
   @test_utils.SkipIfExternalToolsUnavailable()
   def test_SignApexPayload_invalidKey(self):
     self.assertRaises(
         apex_utils.ApexSigningError,
         apex_utils.SignApexPayload,
+        'avbtool',
         self._GetTestPayload(),
         os.path.join(self.testdata_dir, 'testkey.x509.pem'),
         'testkey',
@@ -85,10 +89,12 @@
   def test_VerifyApexPayload_wrongKey(self):
     payload_file = self._GetTestPayload()
     apex_utils.SignApexPayload(
-        payload_file, self.payload_key, 'testkey', 'SHA256_RSA2048', self.SALT)
-    apex_utils.VerifyApexPayload(payload_file, self.payload_key)
+        'avbtool', payload_file, self.payload_key, 'testkey', 'SHA256_RSA2048',
+        self.SALT)
+    apex_utils.VerifyApexPayload('avbtool', payload_file, self.payload_key)
     self.assertRaises(
         apex_utils.ApexSigningError,
         apex_utils.VerifyApexPayload,
+        'avbtool',
         payload_file,
         os.path.join(self.testdata_dir, 'testkey_with_passwd.key'))
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index 914e58e..287cf0a 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -590,8 +590,10 @@
   def test_ExtractAvbPublicKey(self):
     privkey = os.path.join(self.testdata_dir, 'testkey.key')
     pubkey = os.path.join(self.testdata_dir, 'testkey.pubkey.pem')
-    with open(common.ExtractAvbPublicKey(privkey), 'rb') as privkey_fp, \
-        open(common.ExtractAvbPublicKey(pubkey), 'rb') as pubkey_fp:
+    extracted_from_privkey = common.ExtractAvbPublicKey('avbtool', privkey)
+    extracted_from_pubkey = common.ExtractAvbPublicKey('avbtool', pubkey)
+    with open(extracted_from_privkey, 'rb') as privkey_fp, \
+        open(extracted_from_pubkey, 'rb') as pubkey_fp:
       self.assertEqual(privkey_fp.read(), pubkey_fp.read())
 
   def test_ParseCertificate(self):
diff --git a/tools/releasetools/test_merge_target_files.py b/tools/releasetools/test_merge_target_files.py
index 0a636bb..b90a2e7 100644
--- a/tools/releasetools/test_merge_target_files.py
+++ b/tools/releasetools/test_merge_target_files.py
@@ -174,6 +174,38 @@
     }
     self.assertEqual(merged_dict, expected_merged_dict)
 
+  def test_merge_dynamic_partition_info_dicts_IgnoringFrameworkGroupSize(self):
+    framework_dict = {
+        'super_partition_groups': 'group_a',
+        'dynamic_partition_list': 'system',
+        'super_group_a_list': 'system',
+        'super_group_a_size': '5000',
+    }
+    vendor_dict = {
+        'super_partition_groups': 'group_a group_b',
+        'dynamic_partition_list': 'vendor product',
+        'super_group_a_list': 'vendor',
+        'super_group_a_size': '1000',
+        'super_group_b_list': 'product',
+        'super_group_b_size': '2000',
+    }
+    merged_dict = merge_dynamic_partition_info_dicts(
+        framework_dict=framework_dict,
+        vendor_dict=vendor_dict,
+        size_prefix='super_',
+        size_suffix='_size',
+        list_prefix='super_',
+        list_suffix='_list')
+    expected_merged_dict = {
+        'super_partition_groups': 'group_a group_b',
+        'dynamic_partition_list': 'system vendor product',
+        'super_group_a_list': 'system vendor',
+        'super_group_a_size': '1000',
+        'super_group_b_list': 'product',
+        'super_group_b_size': '2000',
+    }
+    self.assertEqual(merged_dict, expected_merged_dict)
+
   def test_process_apex_keys_apk_certs_ReturnsTrueIfNoConflicts(self):
     output_dir = common.MakeTempDir()
     os.makedirs(os.path.join(output_dir, 'META'))
diff --git a/tools/releasetools/test_sign_apex.py b/tools/releasetools/test_sign_apex.py
index 4dcc214..b4ef127 100644
--- a/tools/releasetools/test_sign_apex.py
+++ b/tools/releasetools/test_sign_apex.py
@@ -35,6 +35,7 @@
     payload_key = os.path.join(self.testdata_dir, 'testkey_RSA4096.key')
     container_key = os.path.join(self.testdata_dir, 'testkey')
     signed_foo_apex = sign_apex.SignApexFile(
+        'avbtool',
         foo_apex,
         payload_key,
         container_key)
diff --git a/tools/releasetools/test_sign_target_files_apks.py b/tools/releasetools/test_sign_target_files_apks.py
index e142ebb..9a1d163 100644
--- a/tools/releasetools/test_sign_target_files_apks.py
+++ b/tools/releasetools/test_sign_target_files_apks.py
@@ -136,7 +136,7 @@
       ReplaceVerityKeyId(input_zip, output_zip, cert_file)
 
     with zipfile.ZipFile(output_file) as output_zip:
-      self.assertEqual(BOOT_CMDLINE1, output_zip.read('BOOT/cmdline'))
+      self.assertEqual(BOOT_CMDLINE1, output_zip.read('BOOT/cmdline').decode())
 
     # Test with the second certificate.
     cert_file = os.path.join(self.testdata_dir, 'testkey.x509.pem')
@@ -146,7 +146,7 @@
       ReplaceVerityKeyId(input_zip, output_zip, cert_file)
 
     with zipfile.ZipFile(output_file) as output_zip:
-      self.assertEqual(BOOT_CMDLINE2, output_zip.read('BOOT/cmdline'))
+      self.assertEqual(BOOT_CMDLINE2, output_zip.read('BOOT/cmdline').decode())
 
   def test_ReplaceVerityKeyId_no_veritykeyid(self):
     BOOT_CMDLINE = (
@@ -164,7 +164,7 @@
       ReplaceVerityKeyId(input_zip, output_zip, None)
 
     with zipfile.ZipFile(output_file) as output_zip:
-      self.assertEqual(BOOT_CMDLINE, output_zip.read('BOOT/cmdline'))
+      self.assertEqual(BOOT_CMDLINE, output_zip.read('BOOT/cmdline').decode())
 
   def test_ReplaceCerts(self):
     cert1_path = os.path.join(self.testdata_dir, 'platform.x509.pem')
diff --git a/tools/releasetools/test_validate_target_files.py b/tools/releasetools/test_validate_target_files.py
index 70e3b49..0f0d773 100644
--- a/tools/releasetools/test_validate_target_files.py
+++ b/tools/releasetools/test_validate_target_files.py
@@ -98,7 +98,7 @@
     with open(boot_image, 'r+b') as boot_fp:
       boot_fp.seek(-1, os.SEEK_END)
       last_byte = boot_fp.read(1)
-      last_byte = chr(255 - ord(last_byte))
+      last_byte = bytes([255 - ord(last_byte)])
       boot_fp.seek(-1, os.SEEK_END)
       boot_fp.write(last_byte)
 
diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py
index 5d99c99..435e7f2 100755
--- a/tools/releasetools/validate_target_files.py
+++ b/tools/releasetools/validate_target_files.py
@@ -324,7 +324,8 @@
 
     # avbtool verifies all the images that have descriptors listed in vbmeta.
     image = os.path.join(input_tmp, 'IMAGES', 'vbmeta.img')
-    cmd = ['avbtool', 'verify_image', '--image', image, '--key', key]
+    cmd = [info_dict['avb_avbtool'], 'verify_image', '--image', image,
+           '--key', key]
 
     # Append the args for chained partitions if any.
     for partition in common.AVB_PARTITIONS + common.AVB_VBMETA_PARTITIONS: