Merge "add allow list for exported flags not used for API" into main
diff --git a/core/soong_config.mk b/core/soong_config.mk
index c3cbaf3..f5c5238 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -467,6 +467,7 @@
   $(call add_json_bool, ProductUseDynamicPartitions, $(filter true,$(PRODUCT_USE_DYNAMIC_PARTITIONS)))
   $(call add_json_bool, ProductRetrofitDynamicPartitions, $(filter true,$(PRODUCT_RETROFIT_DYNAMIC_PARTITIONS)))
   $(call add_json_bool, ProductBuildSuperPartition, $(filter true,$(PRODUCT_BUILD_SUPER_PARTITION)))
+  $(call add_json_bool, BuildingSuperEmptyImage, $(filter true,$(BUILDING_SUPER_EMPTY_IMAGE)))
   $(call add_json_str, BoardSuperPartitionSize, $(BOARD_SUPER_PARTITION_SIZE))
   $(call add_json_str, BoardSuperPartitionMetadataDevice, $(BOARD_SUPER_PARTITION_METADATA_DEVICE))
   $(call add_json_list, BoardSuperPartitionBlockDevices, $(BOARD_SUPER_PARTITION_BLOCK_DEVICES))
diff --git a/tools/aconfig/aconfig/src/codegen/java.rs b/tools/aconfig/aconfig/src/codegen/java.rs
index 61802f2..d74e87a 100644
--- a/tools/aconfig/aconfig/src/codegen/java.rs
+++ b/tools/aconfig/aconfig/src/codegen/java.rs
@@ -59,7 +59,8 @@
     let runtime_lookup_required =
         flag_elements.iter().any(|elem| elem.is_read_write) || library_exported;
     let container = (flag_elements.first().expect("zero template flags").container).to_string();
-    let is_platform_container = matches!(container.as_str(), "system" | "product" | "vendor");
+    let is_platform_container =
+        matches!(container.as_str(), "system" | "system_ext" | "product" | "vendor");
     let context = Context {
         flag_elements,
         namespace_flags,
diff --git a/tools/aconfig/fake_device_config/src/android/os/Build.java b/tools/aconfig/fake_device_config/src/android/os/Build.java
index 790ff82..8ec72fb 100644
--- a/tools/aconfig/fake_device_config/src/android/os/Build.java
+++ b/tools/aconfig/fake_device_config/src/android/os/Build.java
@@ -18,9 +18,6 @@
 
 public class Build {
     public static class VERSION {
-        public static final int SDK_INT = placeholder();
-        private static int placeholder() {
-            throw new UnsupportedOperationException("Stub!");
-        }
+        public static final int SDK_INT = 0;
     }
 }
diff --git a/tools/otatools_package/Android.bp b/tools/otatools_package/Android.bp
new file mode 100644
index 0000000..5c7bfc7
--- /dev/null
+++ b/tools/otatools_package/Android.bp
@@ -0,0 +1,65 @@
+// Copyright (C) 2025 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.
+
+package {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_genrule_host {
+    name: "otatools_package_dep_jars",
+    tools: ["soong_zip"],
+    compile_multilib: "first",
+    cmd: "mkdir -p $(genDir)/framework && " +
+        "cp $(in) $(genDir)/framework && " +
+        "$(location soong_zip) -o $(out) -C $(genDir) -D $(genDir)/framework",
+    srcs: [
+        ":apksigner",
+        ":boot_signer",
+        ":signapk",
+        ":verity_signer",
+    ],
+    out: ["otatools_package_dep_jars.zip"],
+}
+
+genrule {
+    name: "otatools_package_cert_files",
+    tools: ["soong_zip"],
+    cmd: "mkdir -p $(genDir)/tmp/ && " +
+        "echo $(in) > $(genDir)/tmp/zip_files.list && " +
+        "$(location soong_zip) -o $(out) -l $(genDir)/tmp/zip_files.list ",
+    srcs: [
+        ":soong_generated_otatools_package_filegroup",
+    ],
+    out: ["otatools_package_cert_files.zip"],
+}
+
+java_genrule_host {
+    name: "otatools_package",
+    tools: ["merge_zips"],
+    compile_multilib: "first",
+    cmd: "$(location merge_zips) $(out) $(in)",
+    srcs: [
+        ":otatools_package_cert_files",
+        ":otatools_package_dep_jars",
+        ":otatools_package_releasetools",
+    ],
+    // TODO: Rename as "otatools.zip" when the rest files are ready.
+    out: ["otatools_temp.zip"],
+    dist: {
+        targets: [
+            "otatools-package-temp",
+        ],
+    },
+}
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 3467152..2232385 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -650,3 +650,12 @@
         unit_test: true,
     },
 }
+
+genrule {
+    name: "otatools_package_releasetools",
+    tools: ["soong_zip"],
+    srcs: ["**/*"],
+    cmd: "find build/make/tools/releasetools -name '*.pyc' -prune -o \\( -type f -o -type l \\) -print | sort > $(genDir)/files.txt && " +
+        "$(location soong_zip) -o $(out) -C build/make/tools -l $(genDir)/files.txt",
+    out: ["otatools_package_releasetools.zip"],
+}
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index b6c96c4..08b4d6a 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -49,8 +49,8 @@
 # Use a fixed timestamp (01/01/2009 00:00:00 UTC) for files when packaging
 # images. (b/24377993, b/80600931)
 FIXED_FILE_TIMESTAMP = int((
-    datetime.datetime(2009, 1, 1, 0, 0, 0, 0, None) -
-    datetime.datetime.utcfromtimestamp(0)).total_seconds())
+    datetime.datetime(2009, 1, 1, 0, 0, 0, 0, datetime.UTC) -
+    datetime.datetime.fromtimestamp(0, datetime.UTC)).total_seconds())
 
 
 class BuildImageError(Exception):
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index b6cbb15..e5f5f92 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -2993,7 +2993,7 @@
     os.chmod(filename, perms)
 
     # Use a fixed timestamp so the output is repeatable.
-    # Note: Use of fromtimestamp rather than utcfromtimestamp here is
+    # Note: Use of fromtimestamp without specifying a timezone here is
     # intentional. zip stores datetimes in local time without a time zone
     # attached, so we need "epoch" but in the local time zone to get 2009/01/01
     # in the zip archive.