Merge "Revert "Adds modern wallpaper pickers to AOSP installs"" into main
diff --git a/core/base_rules.mk b/core/base_rules.mk
index e7c28ec..b3c5b94 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -965,6 +965,9 @@
       $(my_init_rc_installed) \
       $(my_installed_test_data) \
       $(my_vintf_installed))
+
+  ALL_MODULES.$(my_register_name).INSTALLED_SYMLINKS := $(LOCAL_SOONG_INSTALL_SYMLINKS)
+
   # Store the list of colon-separated pairs of the built and installed locations
   # of files provided by this module.  Used by custom packaging rules like
   # package-modules.mk that need to copy the built files to a custom install
diff --git a/core/board_config.mk b/core/board_config.mk
index 7fd5e61..c3a6864 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -186,7 +186,6 @@
   BUILD_BROKEN_TREBLE_SYSPROP_NEVERALLOW \
   BUILD_BROKEN_USES_NETWORK \
   BUILD_BROKEN_VENDOR_PROPERTY_NAMESPACE \
-  BUILD_BROKEN_VENDOR_SEAPP_USES_COREDOMAIN \
   BUILD_BROKEN_VINTF_PRODUCT_COPY_FILES \
 
 _build_broken_var_list += \
diff --git a/core/main.mk b/core/main.mk
index 5738cdb..12b7bd0 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1720,8 +1720,10 @@
     unbundled_build_modules := $(sort $(TARGET_BUILD_APPS))
   endif
 
-  # Dist the installed files if they exist.
-  apps_only_installed_files := $(foreach m,$(unbundled_build_modules),$(ALL_MODULES.$(m).INSTALLED))
+  # Dist the installed files if they exist, except the installed symlinks. dist-for-goals emits
+  # `cp src dest` commands, which will fail to copy dangling symlinks.
+  apps_only_installed_files := $(foreach m,$(unbundled_build_modules),\
+    $(filter-out $(ALL_MODULES.$(m).INSTALLED_SYMLINKS),$(ALL_MODULES.$(m).INSTALLED)))
   $(call dist-for-goals,apps_only, $(apps_only_installed_files))
 
   # Dist the bundle files if they exist.
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 58d2c2f..26998ed 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -283,16 +283,15 @@
 
 $(call add_json_str,  ShippingApiLevel, $(PRODUCT_SHIPPING_API_LEVEL))
 
-$(call add_json_list, BuildBrokenPluginValidation,          $(BUILD_BROKEN_PLUGIN_VALIDATION))
-$(call add_json_bool, BuildBrokenClangProperty,             $(filter true,$(BUILD_BROKEN_CLANG_PROPERTY)))
-$(call add_json_bool, BuildBrokenClangAsFlags,              $(filter true,$(BUILD_BROKEN_CLANG_ASFLAGS)))
-$(call add_json_bool, BuildBrokenClangCFlags,               $(filter true,$(BUILD_BROKEN_CLANG_CFLAGS)))
-$(call add_json_bool, GenruleSandboxing,                    $(filter true,$(GENRULE_SANDBOXING)))
-$(call add_json_bool, BuildBrokenEnforceSyspropOwner,       $(filter true,$(BUILD_BROKEN_ENFORCE_SYSPROP_OWNER)))
-$(call add_json_bool, BuildBrokenTrebleSyspropNeverallow,   $(filter true,$(BUILD_BROKEN_TREBLE_SYSPROP_NEVERALLOW)))
-$(call add_json_bool, BuildBrokenUsesSoongPython2Modules,   $(filter true,$(BUILD_BROKEN_USES_SOONG_PYTHON2_MODULES)))
-$(call add_json_bool, BuildBrokenVendorPropertyNamespace,   $(filter true,$(BUILD_BROKEN_VENDOR_PROPERTY_NAMESPACE)))
-$(call add_json_bool, BuildBrokenVendorSeappUsesCoredomain, $(filter true,$(BUILD_BROKEN_VENDOR_SEAPP_USES_COREDOMAIN)))
+$(call add_json_list, BuildBrokenPluginValidation,        $(BUILD_BROKEN_PLUGIN_VALIDATION))
+$(call add_json_bool, BuildBrokenClangProperty,           $(filter true,$(BUILD_BROKEN_CLANG_PROPERTY)))
+$(call add_json_bool, BuildBrokenClangAsFlags,            $(filter true,$(BUILD_BROKEN_CLANG_ASFLAGS)))
+$(call add_json_bool, BuildBrokenClangCFlags,             $(filter true,$(BUILD_BROKEN_CLANG_CFLAGS)))
+$(call add_json_bool, GenruleSandboxing,                  $(filter true,$(GENRULE_SANDBOXING)))
+$(call add_json_bool, BuildBrokenEnforceSyspropOwner,     $(filter true,$(BUILD_BROKEN_ENFORCE_SYSPROP_OWNER)))
+$(call add_json_bool, BuildBrokenTrebleSyspropNeverallow, $(filter true,$(BUILD_BROKEN_TREBLE_SYSPROP_NEVERALLOW)))
+$(call add_json_bool, BuildBrokenUsesSoongPython2Modules, $(filter true,$(BUILD_BROKEN_USES_SOONG_PYTHON2_MODULES)))
+$(call add_json_bool, BuildBrokenVendorPropertyNamespace, $(filter true,$(BUILD_BROKEN_VENDOR_PROPERTY_NAMESPACE)))
 $(call add_json_list, BuildBrokenInputDirModules, $(BUILD_BROKEN_INPUT_DIR_MODULES))
 
 $(call add_json_list, BuildWarningBadOptionalUsesLibsAllowlist,    $(BUILD_WARNING_BAD_OPTIONAL_USES_LIBS_ALLOWLIST))
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 734d64e..001ed45 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -70,7 +70,6 @@
     com.android.scheduling \
     com.android.sdkext \
     com.android.tethering \
-    com.android.threadnetwork \
     com.android.tzdata \
     com.android.uwb \
     com.android.virt \
diff --git a/target/product/default_art_config.mk b/target/product/default_art_config.mk
index f82d177..3ca4187 100644
--- a/target/product/default_art_config.mk
+++ b/target/product/default_art_config.mk
@@ -111,7 +111,6 @@
     com.android.os.statsd:service-statsd \
     com.android.scheduling:service-scheduling \
     com.android.tethering:service-connectivity \
-    com.android.threadnetwork:service-threadnetwork \
     com.android.uwb:service-uwb \
     com.android.wifi:service-wifi \
 
diff --git a/target/product/gsi_release.mk b/target/product/gsi_release.mk
index e39af92..bd85b9f 100644
--- a/target/product/gsi_release.mk
+++ b/target/product/gsi_release.mk
@@ -28,10 +28,15 @@
 
 BUILDING_GSI := true
 
-# Exclude all files under system/product and system/system_ext
+# Exclude all files under system/product and system/system_ext,
+# and the vndk apex's compat symlinks
 PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
     system/product/% \
-    system/system_ext/%
+    system/system_ext/% \
+    system/lib/vndk-29 \
+    system/lib/vndk-sp-29 \
+    system/lib64/vndk-29 \
+    system/lib64/vndk-sp-29
 
 # GSI should always support up-to-date platform features.
 # Keep this value at the latest API level to ensure latest build system
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 5a7cc76..c785c8e 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -344,6 +344,7 @@
     },
     srcs: [
         "merge_ota.py",
+        "ota_signing_utils.py",
     ],
     libs: [
         "ota_metadata_proto",
@@ -493,6 +494,26 @@
 }
 
 python_binary_host {
+    name: "ota_from_raw_img",
+    srcs: [
+        "ota_from_raw_img.py",
+        "ota_signing_utils.py",
+    ],
+    main: "ota_from_raw_img.py",
+    defaults: [
+        "releasetools_binary_defaults",
+    ],
+    required: [
+        "delta_generator",
+    ],
+    libs: [
+        "ota_metadata_proto",
+        "releasetools_common",
+        "ota_utils_lib",
+    ],
+}
+
+python_binary_host {
     name: "ota_package_parser",
     defaults: ["releasetools_binary_defaults"],
     srcs: [
@@ -590,6 +611,7 @@
         "sign_target_files_apks.py",
         "validate_target_files.py",
         "merge_ota.py",
+        "ota_signing_utils.py",
         ":releasetools_merge_sources",
         ":releasetools_merge_tests",
 
diff --git a/tools/releasetools/merge_ota.py b/tools/releasetools/merge_ota.py
index 441312c..24d9ea9 100644
--- a/tools/releasetools/merge_ota.py
+++ b/tools/releasetools/merge_ota.py
@@ -14,7 +14,6 @@
 
 import argparse
 import logging
-import shlex
 import struct
 import sys
 import update_payload
@@ -31,6 +30,7 @@
 
 from payload_signer import PayloadSigner
 from ota_utils import PayloadGenerator, METADATA_PROTO_NAME, FinalizeMetadata
+from ota_signing_utils import AddSigningArgumentParse
 
 logger = logging.getLogger(__name__)
 
@@ -126,7 +126,7 @@
     ExtendPartitionUpdates(output_manifest.partitions, manifest.partitions)
     try:
       MergeDynamicPartitionMetadata(
-        output_manifest.dynamic_partition_metadata, manifest.dynamic_partition_metadata)
+          output_manifest.dynamic_partition_metadata, manifest.dynamic_partition_metadata)
     except DuplicatePartitionError:
       logger.error(
           "OTA %s has duplicate partition with some of the previous OTAs", payload.name)
@@ -190,6 +190,7 @@
               f"OTA {partition_to_ota[part].name} and {payload.name} have duplicating partition {part}")
         partition_to_ota[part] = payload
 
+
 def ApexInfo(file_paths):
   if len(file_paths) > 1:
     logger.info("More than one target file specified, will ignore "
@@ -201,33 +202,19 @@
       return apex_info_bytes
   return None
 
-def ParseSignerArgs(args):
-  if args is None:
-    return None
-  return shlex.split(args)
 
 def main(argv):
   parser = argparse.ArgumentParser(description='Merge multiple partial OTAs')
   parser.add_argument('packages', type=str, nargs='+',
                       help='Paths to OTA packages to merge')
-  parser.add_argument('--package_key', type=str,
-                      help='Paths to private key for signing payload')
-  parser.add_argument('--search_path', type=str,
-                      help='Search path for framework/signapk.jar')
-  parser.add_argument('--payload_signer', type=str,
-                      help='Path to custom payload signer')
-  parser.add_argument('--payload_signer_args', type=ParseSignerArgs,
-                      help='Arguments for payload signer if necessary')
-  parser.add_argument('--payload_signer_maximum_signature_size', type=str,
-                      help='Maximum signature size (in bytes) that would be '
-                      'generated by the given payload signer')
   parser.add_argument('--output', type=str,
                       help='Paths to output merged ota', required=True)
   parser.add_argument('--metadata_ota', type=str,
                       help='Output zip will use build metadata from this OTA package, if unspecified, use the last OTA package in merge list')
-  parser.add_argument('--private_key_suffix', type=str,
-                      help='Suffix to be appended to package_key path', default=".pk8")
-  parser.add_argument('-v', action="store_true", help="Enable verbose logging", dest="verbose")
+  parser.add_argument('-v', action="store_true",
+                      help="Enable verbose logging", dest="verbose")
+  AddSigningArgumentParse(parser)
+
   parser.epilog = ('This tool can also be used to resign a regular OTA. For a single regular OTA, '
                    'apex_info.pb will be written to output. When merging multiple OTAs, '
                    'apex_info.pb will not be written.')
@@ -301,8 +288,6 @@
   return 0
 
 
-
-
 if __name__ == '__main__':
   logging.basicConfig()
   sys.exit(main(sys.argv))
diff --git a/tools/releasetools/ota_from_raw_img.py b/tools/releasetools/ota_from_raw_img.py
new file mode 100644
index 0000000..ac4f9fb
--- /dev/null
+++ b/tools/releasetools/ota_from_raw_img.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2008 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.
+
+"""
+Given a series of .img files, produces an OTA package that installs thoese images
+"""
+
+import sys
+import os
+import argparse
+import subprocess
+import tempfile
+import logging
+import zipfile
+
+import common
+from payload_signer import PayloadSigner
+from ota_utils import PayloadGenerator
+from ota_signing_utils import AddSigningArgumentParse
+
+
+logger = logging.getLogger(__name__)
+
+
+def ResolveBinaryPath(filename, search_path):
+  if not search_path:
+    return filename
+  if not os.path.exists(search_path):
+    return filename
+  path = os.path.join(search_path, "bin", filename)
+  if os.path.exists(path):
+    return path
+  path = os.path.join(search_path, filename)
+  if os.path.exists(path):
+    return path
+  return path
+
+
+def main(argv):
+  parser = argparse.ArgumentParser(
+      prog=argv[0], description="Given a series of .img files, produces a full OTA package that installs thoese images")
+  parser.add_argument("images", nargs="+", type=str,
+                      help="List of images to generate OTA")
+  parser.add_argument("--partition_names", nargs='+', type=str,
+                      help="Partition names to install the images, default to basename of the image(no file name extension)")
+  parser.add_argument('--output', type=str,
+                      help='Paths to output merged ota', required=True)
+  parser.add_argument("-v", action="store_true",
+                      help="Enable verbose logging", dest="verbose")
+  AddSigningArgumentParse(parser)
+
+  args = parser.parse_args(argv[1:])
+  if args.verbose:
+    logger.setLevel(logging.INFO)
+  logger.info(args)
+  if not args.partition_names:
+    args.partition_names = [os.path.os.path.splitext(os.path.basename(path))[
+        0] for path in args.images]
+  with tempfile.NamedTemporaryFile() as unsigned_payload:
+    cmd = [ResolveBinaryPath("delta_generator", args.search_path)]
+    cmd.append("--partition_names=" + ",".join(args.partition_names))
+    cmd.append("--new_partitions=" + ",".join(args.images))
+    cmd.append("--out_file=" + unsigned_payload.name)
+    logger.info("Running %s", cmd)
+
+    subprocess.run(cmd)
+    generator = PayloadGenerator()
+    generator.payload_file = unsigned_payload.name
+    logger.info("Payload size: %d", os.path.getsize(generator.payload_file))
+
+    # Get signing keys
+    key_passwords = common.GetKeyPasswords([args.package_key])
+
+    if args.package_key:
+      logger.info("Signing payload...")
+      # TODO: remove OPTIONS when no longer used as fallback in payload_signer
+      common.OPTIONS.payload_signer_args = None
+      common.OPTIONS.payload_signer_maximum_signature_size = None
+      signer = PayloadSigner(args.package_key, args.private_key_suffix,
+                             key_passwords[args.package_key],
+                             payload_signer=args.payload_signer,
+                             payload_signer_args=args.payload_signer_args,
+                             payload_signer_maximum_signature_size=args.payload_signer_maximum_signature_size)
+      generator.payload_file = unsigned_payload.name
+      generator.Sign(signer)
+
+    logger.info("Payload size: %d", os.path.getsize(generator.payload_file))
+
+    logger.info("Writing to %s", args.output)
+    with zipfile.ZipFile(args.output, "w") as zfp:
+      generator.WriteToZip(zfp)
+
+
+if __name__ == "__main__":
+  logging.basicConfig()
+  main(sys.argv)
diff --git a/tools/releasetools/ota_signing_utils.py b/tools/releasetools/ota_signing_utils.py
new file mode 100644
index 0000000..60c8c94
--- /dev/null
+++ b/tools/releasetools/ota_signing_utils.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 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.
+
+import argparse
+import shlex
+
+
+def ParseSignerArgs(args):
+  if args is None:
+    return None
+  return shlex.split(args)
+
+
+def AddSigningArgumentParse(parser: argparse.ArgumentParser):
+  parser.add_argument('--package_key', type=str,
+                      help='Paths to private key for signing payload')
+  parser.add_argument('--search_path', '--path', type=str,
+                      help='Search path for framework/signapk.jar')
+  parser.add_argument('--payload_signer', type=str,
+                      help='Path to custom payload signer')
+  parser.add_argument('--payload_signer_args', type=ParseSignerArgs,
+                      help='Arguments for payload signer if necessary')
+  parser.add_argument('--payload_signer_maximum_signature_size', type=str,
+                      help='Maximum signature size (in bytes) that would be '
+                      'generated by the given payload signer')
+  parser.add_argument('--private_key_suffix', type=str,
+                      help='Suffix to be appended to package_key path', default=".pk8")
diff --git a/tools/releasetools/ota_utils.py b/tools/releasetools/ota_utils.py
index f288a9c..8993da9 100644
--- a/tools/releasetools/ota_utils.py
+++ b/tools/releasetools/ota_utils.py
@@ -934,9 +934,9 @@
     # 4. Dump the signed payload properties.
     properties_file = common.MakeTempFile(prefix="payload-properties-",
                                           suffix=".txt")
-    cmd = ["brillo_update_payload", "properties",
-           "--payload", self.payload_file,
-           "--properties_file", properties_file]
+    cmd = ["delta_generator",
+           "--in_file=" + self.payload_file,
+           "--properties_file=" + properties_file]
     self._Run(cmd)
 
     if self.secondary: