Merge "releasetools: common.LoadInfoDict() takes a bool parameter for repacking."
diff --git a/core/Makefile b/core/Makefile
index 73e93fc..e11dd02 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -2835,23 +2835,29 @@
 $(INSTALLED_SUPERIMAGE_TARGET) $(INSTALLED_SUPERIMAGE_EMPTY_TARGET): PRIVATE_PARTITION_SUFFIX=_a
 endif # AB_OTA_UPDATER
 
-$(INSTALLED_SUPERIMAGE_TARGET) $(INSTALLED_SUPERIMAGE_EMPTY_TARGET): $(HOST_OUT_EXECUTABLES)/lpmake
+$(INSTALLED_SUPERIMAGE_TARGET) $(INSTALLED_SUPERIMAGE_EMPTY_TARGET): $(LPMAKE)
+
+# $(1): slot A suffix (_a or empty)
+# $(2): include images or not (true or empty)
+define build-superimage-target-args
+  $(if $(2), --sparse) \
+  --metadata-size 65536 \
+  --metadata-slots $(if $(1),2,1) \
+  --device-size $(BOARD_SUPER_PARTITION_SIZE) \
+  $(foreach name,$(BOARD_SUPER_PARTITION_PARTITION_LIST), \
+    --partition $(name)$(1):$$($(UUIDGEN) $(name)$(1)):readonly:$(if $(2),$(call read-size-of-partitions,$(name)),0) \
+    $(if $(2), --image $(name)$(1)=$(call images-for-partitions,$(name))) \
+    $(if $(1), --partition $(name)_b:$$($(UUIDGEN) $(name)_b):readonly:0) \
+  )
+endef
 
 # $(1): output image path
 # $(2): slot A suffix (_a or empty)
 # $(3): include images or not (true or empty)
 define build-superimage-target
   $(HOST_OUT_EXECUTABLES)/lpmake \
-    $(if $(3), --sparse) \
-    --metadata-size 65536 \
-    --metadata-slots $(if $(2),2,1) \
-    --device-size $(BOARD_SUPER_PARTITION_SIZE) \
-    --output $(1) \
-    $(foreach name,$(BOARD_SUPER_PARTITION_PARTITION_LIST), \
-      --partition $(name)$(2):$$($(UUIDGEN) $(name)$(2)):readonly:$(if $(3),$(call read-size-of-partitions,$(name)),0) \
-      $(if $(3), --image $(name)$(2)=$(call images-for-partitions,$(name))) \
-      $(if $(2), --partition $(name)_b:$$($(UUIDGEN) $(name)_b):readonly:0) \
-    )
+    $(call build-superimage-target-args,$(2),$(3)) \
+    --output $(1)
 endef
 
 $(INSTALLED_SUPERIMAGE_TARGET):
@@ -2974,6 +2980,7 @@
   $(HOST_OUT_EXECUTABLES)/lib/shflags/shflags \
   $(HOST_OUT_EXECUTABLES)/delta_generator \
   $(HOST_OUT_EXECUTABLES)/care_map_generator \
+  $(LPMAKE) \
   $(AVBTOOL) \
   $(BLK_ALLOC_TO_BASE_FS) \
   $(BROTLI) \
@@ -3014,7 +3021,9 @@
   $(HOST_LIBRARY_PATH)/libsparse-host$(HOST_SHLIB_SUFFIX) \
   $(HOST_LIBRARY_PATH)/libbase$(HOST_SHLIB_SUFFIX) \
   $(HOST_LIBRARY_PATH)/libpcre2$(HOST_SHLIB_SUFFIX) \
-  $(HOST_LIBRARY_PATH)/libbrotli$(HOST_SHLIB_SUFFIX)
+  $(HOST_LIBRARY_PATH)/libbrotli$(HOST_SHLIB_SUFFIX) \
+  $(HOST_LIBRARY_PATH)/liblp$(HOST_SHLIB_SUFFIX) \
+  $(HOST_LIBRARY_PATH)/libext4_utils$(HOST_SHLIB_SUFFIX)
 
 
 .PHONY: otatools
@@ -3162,6 +3171,7 @@
 		$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_BASE_FS_PATH) \
 		$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PRODUCT_SERVICES_BASE_FS_PATH) \
 		$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_ODM_BASE_FS_PATH) \
+		$(LPMAKE) \
 		$(SELINUX_FC) \
 		$(APKCERTS_FILE) \
 		$(SOONG_ZIP) \
@@ -3488,6 +3498,13 @@
 ifdef BUILT_VENDOR_MATRIX
 	$(hide) cp $(BUILT_VENDOR_MATRIX) $(zip_root)/META/vendor_matrix.xml
 endif
+ifdef BOARD_SUPER_PARTITION_SIZE
+	$(hide) echo "super_size=$(BOARD_SUPER_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo "lpmake=$(notdir $(LPMAKE))" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo -n "lpmake_args=" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo $(call build-superimage-target-args,$(if $(filter true,$(AB_OTA_UPDATER)),_a,)) \
+	    >> $(zip_root)/META/misc_info.txt
+endif
 
 	$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
 	    build/make/tools/releasetools/add_img_to_target_files -a -v -p $(HOST_OUT) $(zip_root)
diff --git a/core/android_manifest.mk b/core/android_manifest.mk
index 13da10c..d1cfe15 100644
--- a/core/android_manifest.mk
+++ b/core/android_manifest.mk
@@ -58,10 +58,14 @@
 $(fixed_android_manifest): PRIVATE_EXPORTED_SDK_LIBS_FILE := $(my_exported_sdk_libs_file)
 $(fixed_android_manifest): $(my_exported_sdk_libs_file)
 
-$(fixed_android_manifest): PRIVATE_MANIFEST_FIXER_FLAGS :=
+my_manifest_fixer_flags :=
 ifneq ($(LOCAL_MODULE_CLASS),APPS)
-$(fixed_android_manifest): PRIVATE_MANIFEST_FIXER_FLAGS := --library
+    my_manifest_fixer_flags += --library
 endif
+ifeq ($(LOCAL_PRIVATE_PLATFORM_APIS),true)
+    my_manifest_fixer_flags += --uses-non-sdk-api
+endif
+$(fixed_android_manifest): PRIVATE_MANIFEST_FIXER_FLAGS := $(my_manifest_fixer_flags)
 $(fixed_android_manifest): $(MANIFEST_FIXER)
 $(fixed_android_manifest): $(main_android_manifest)
 	@echo "Fix manifest: $@"
diff --git a/core/config.mk b/core/config.mk
index f3be496..dd881db 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -691,6 +691,7 @@
 FAT16COPY := build/make/tools/fat16copy.py
 CHECK_LINK_TYPE := build/make/tools/check_link_type.py
 UUIDGEN := build/make/tools/uuidgen.py
+LPMAKE := $(HOST_OUT_EXECUTABLES)/lpmake$(HOST_EXECUTABLE_SUFFIX)
 
 PROGUARD := external/proguard/bin/proguard.sh
 JAVATAGS := build/make/tools/java-event-log-tags.py
diff --git a/core/definitions.mk b/core/definitions.mk
index 3d9c140..fa7e052 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2879,12 +2879,10 @@
 	$(CLASS2GREYLIST) --public-api-list $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) $(1) \
 	    --write-whitelist $(2) --write-greylist $(3)
 
-$(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): $(2)
+$(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): $(2) $(3)
 $(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): \
     PRIVATE_WHITELIST_INPUTS := $$(PRIVATE_WHITELIST_INPUTS) $(2)
-
-$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): $(3)
-$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): \
+$(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): \
     PRIVATE_GREYLIST_INPUTS := $$(PRIVATE_GREYLIST_INPUTS) $(3)
 endif
 endef
diff --git a/core/jetifier.mk b/core/jetifier.mk
index 33a4624..fff4230 100644
--- a/core/jetifier.mk
+++ b/core/jetifier.mk
@@ -24,7 +24,7 @@
 
 $(my_jetifier_output_path) : $(my_jetifier_input_path) $(JETIFIER)
 	rm -rf $@
-	$(JETIFIER) -outputfile $@ -i $<
+	$(JETIFIER) -l error -o $@ -i $<
 
   LOCAL_JETIFIER_OUTPUT_FILE := $(my_jetifier_output_path)
   LOCAL_INTERMEDIATE_TARGETS += $(LOCAL_JETIFIER_OUTPUT_FILE)
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index e57b198..0ba85f3 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -318,8 +318,8 @@
 
 ifndef PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION
   # Used to set minimum supported target sdk version. Apps targeting sdk
-  # version lower than the set value will fail to install and run on android
-  # device.
+  # version lower than the set value will result in a warning being shown
+  # when any activity from the app is started.
   PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 17
 endif
 .KATI_READONLY := PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 832e509..ef0d0c8 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -24,6 +24,7 @@
     android.hidl.manager-V1.0-java \
     android.hidl.memory@1.0-impl \
     android.hidl.memory@1.0-impl.vendor \
+    android.system.suspend@1.0-service \
     android.test.base \
     android.test.mock \
     android.test.runner \
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index a3dc6c3..9e8b698 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -625,6 +625,22 @@
       shutil.copy(img_radio_path, prebuilt_path)
 
 
+def AddSuperEmpty(output_zip):
+  """Create a super_empty.img and store it in output_zip."""
+
+  img = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", "super_empty.img")
+  cmd = [OPTIONS.info_dict.get('lpmake')]
+  cmd += shlex.split(OPTIONS.info_dict.get('lpmake_args').strip())
+  cmd += ['--output', img.name]
+
+  p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+  stdoutdata, _ = p.communicate()
+  assert p.returncode == 0, \
+      "lpmake tool failed:\n{}".format(stdoutdata)
+
+  img.Write()
+
+
 def ReplaceUpdatedFiles(zip_filename, files_list):
   """Updates all the ZIP entries listed in files_list.
 
@@ -793,6 +809,10 @@
     banner("vbmeta")
     AddVBMeta(output_zip, partitions)
 
+  if OPTIONS.info_dict.get("super_size"):
+    banner("super_empty")
+    AddSuperEmpty(output_zip)
+
   banner("radio")
   ab_partitions_txt = os.path.join(OPTIONS.input_tmp, "META",
                                    "ab_partitions.txt")
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index 3595a9e..7ed85fe 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -163,15 +163,32 @@
     [0,1]."""
     self.script.append("set_progress(%f);" % (frac,))
 
-  def PatchCheck(self, filename, *sha1):
-    """Check that the given file has one of the
-    given *sha1 hashes, checking the version saved in cache if the
-    file does not match."""
-    self.script.append(
-        'apply_patch_check("%s"' % (filename,) +
-        "".join([', "%s"' % (i,) for i in sha1]) +
-        ') || abort("E%d: \\"%s\\" has unexpected contents.");' % (
-            common.ErrorCode.BAD_PATCH_FILE, filename))
+  def PatchCheck(self, filename, *sha1):  # pylint: disable=unused-argument
+    """Checks that the given partition has the desired checksum.
+
+    The call to this function is being deprecated in favor of
+    PatchPartitionCheck(). It will try to parse and handle the old format,
+    unless the format is unknown.
+    """
+    tokens = filename.split(':')
+    assert len(tokens) == 6 and tokens[0] == 'EMMC', \
+        "Failed to handle unknown format. Use PatchPartitionCheck() instead."
+    source = '{}:{}:{}:{}'.format(tokens[0], tokens[1], tokens[2], tokens[3])
+    target = '{}:{}:{}:{}'.format(tokens[0], tokens[1], tokens[4], tokens[5])
+    self.PatchPartitionCheck(target, source)
+
+  def PatchPartitionCheck(self, target, source):
+    """Checks whether updater can patch the given partitions.
+
+    It checks the checksums of the given partitions. If none of them matches the
+    expected checksum, updater will additionally look for a backup on /cache.
+    """
+    self.script.append(self.WordWrap((
+        'patch_partition_check("{target}",\0"{source}") ||\n    abort('
+        '"E{code}: \\"{target}\\" or \\"{source}\\" has unexpected '
+        'contents.");').format(
+            target=target, source=source,
+            code=common.ErrorCode.BAD_PATCH_FILE)))
 
   def CacheFreeSpaceCheck(self, amount):
     """Check that there's at least 'amount' space that can be made
@@ -251,17 +268,41 @@
   def ApplyPatch(self, srcfile, tgtfile, tgtsize, tgtsha1, *patchpairs):
     """Apply binary patches (in *patchpairs) to the given srcfile to
     produce tgtfile (which may be "-" to indicate overwriting the
-    source file."""
-    if len(patchpairs) % 2 != 0 or len(patchpairs) == 0:
-      raise ValueError("bad patches given to ApplyPatch")
-    cmd = ['apply_patch("%s",\0"%s",\0%s,\0%d'
-           % (srcfile, tgtfile, tgtsha1, tgtsize)]
-    for i in range(0, len(patchpairs), 2):
-      cmd.append(',\0%s,\0package_extract_file("%s")' % patchpairs[i:i+2])
-    cmd.append(') ||\n    abort("E%d: Failed to apply patch to %s");' % (
-        common.ErrorCode.APPLY_PATCH_FAILURE, srcfile))
-    cmd_str = "".join(cmd)
-    self.script.append(self.WordWrap(cmd_str))
+    source file.
+
+    This edify function is being deprecated in favor of PatchPartition(). It
+    will try to redirect calls to PatchPartition() if possible. On unknown /
+    invalid inputs, raises an exception.
+    """
+    tokens = srcfile.split(':')
+    assert (len(tokens) == 6 and tokens[0] == 'EMMC' and tgtfile == '-' and
+            len(patchpairs) == 2), \
+        "Failed to handle unknown format. Use PatchPartition() instead."
+
+    # Also sanity check the args.
+    assert tokens[3] == patchpairs[0], \
+        "Found mismatching values for source SHA-1: {} vs {}".format(
+            tokens[3], patchpairs[0])
+    assert int(tokens[4]) == tgtsize, \
+        "Found mismatching values for target size: {} vs {}".format(
+            tokens[4], tgtsize)
+    assert tokens[5] == tgtsha1, \
+        "Found mismatching values for target SHA-1: {} vs {}".format(
+            tokens[5], tgtsha1)
+
+    source = '{}:{}:{}:{}'.format(tokens[0], tokens[1], tokens[2], tokens[3])
+    target = '{}:{}:{}:{}'.format(tokens[0], tokens[1], tokens[4], tokens[5])
+    patch = patchpairs[1]
+    self.PatchPartition(target, source, patch)
+
+  def PatchPartition(self, target, source, patch):
+    """Applies the patch to the source partition and writes it to target."""
+    self.script.append(self.WordWrap((
+        'patch_partition("{target}",\0"{source}",\0'
+        'package_extract_file("{patch}")) ||\n'
+        '    abort("E{code}: Failed to apply patch to {source}");').format(
+            target=target, source=source, patch=patch,
+            code=common.ErrorCode.APPLY_PATCH_FAILURE)))
 
   def WriteRawImage(self, mount_point, fn, mapfn=None):
     """Write the given package file into the partition for the given
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 9ad3f6b..583af2d 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -1523,18 +1523,14 @@
       print("boot      target: %d  source: %d  diff: %d" % (
           target_boot.size, source_boot.size, len(d)))
 
-      common.ZipWriteStr(output_zip, "patch/boot.img.p", d)
+      common.ZipWriteStr(output_zip, "boot.img.p", d)
 
-      # TODO(b/110106408): Remove after properly handling the SHA-1 embedded in
-      # the filename argument in updater code. Prior to that, explicitly list
-      # the SHA-1 of the source image, in case the updater tries to find a
-      # matching backup from /cache. Similarly for the call to
-      # script.ApplyPatch() below.
-      script.PatchCheck("%s:%s:%d:%s:%d:%s" %
-                        (boot_type, boot_device,
-                         source_boot.size, source_boot.sha1,
-                         target_boot.size, target_boot.sha1),
-                        source_boot.sha1)
+      script.PatchPartitionCheck(
+          "{}:{}:{}:{}".format(
+              boot_type, boot_device, target_boot.size, target_boot.sha1),
+          "{}:{}:{}:{}".format(
+              boot_type, boot_device, source_boot.size, source_boot.sha1))
+
       size.append(target_boot.size)
 
   if size:
@@ -1590,13 +1586,12 @@
         print("boot image changed; including patch.")
         script.Print("Patching boot image...")
         script.ShowProgress(0.1, 10)
-        script.ApplyPatch("%s:%s:%d:%s:%d:%s"
-                          % (boot_type, boot_device,
-                             source_boot.size, source_boot.sha1,
-                             target_boot.size, target_boot.sha1),
-                          "-",
-                          target_boot.size, target_boot.sha1,
-                          source_boot.sha1, "patch/boot.img.p")
+        script.PatchPartition(
+            '{}:{}:{}:{}'.format(
+                boot_type, boot_device, target_boot.size, target_boot.sha1),
+            '{}:{}:{}:{}'.format(
+                boot_type, boot_device, source_boot.size, source_boot.sha1),
+            'boot.img.p')
     else:
       print("boot image unchanged; skipping.")