Merge "Remove BOARD_BPT* variables and the bpt parition table image" into main
diff --git a/core/Makefile b/core/Makefile
index 7d0c8f1..4d6fbe4 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1045,8 +1045,8 @@
 COMPRESSION_COMMAND := $(LZ4) -l -12 --favor-decSpeed
 RAMDISK_EXT := .lz4
 else
-COMPRESSION_COMMAND_DEPS := $(MINIGZIP)
-COMPRESSION_COMMAND := $(MINIGZIP)
+COMPRESSION_COMMAND_DEPS := $(GZIP)
+COMPRESSION_COMMAND := $(GZIP)
 RAMDISK_EXT := .gz
 endif
 
@@ -4960,7 +4960,9 @@
 endif # INSTALLED_BOOTIMAGE_TARGET
 endif # my_board_extracted_kernel
 
-ifneq ($(my_board_extracted_kernel),true)
+ifeq ($(my_board_extracted_kernel),true)
+$(call dist-for-goals, droid_targets, $(BUILT_KERNEL_VERSION_FILE))
+else
 $(warning Neither INSTALLED_KERNEL_TARGET nor INSTALLED_BOOTIMAGE_TARGET is defined when \
     PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS  is true. Information about the updated kernel \
     cannot be built into OTA update package. You can fix this by: \
@@ -5223,7 +5225,6 @@
   make_f2fs_casefold \
   merge_ota \
   merge_target_files \
-  minigzip \
   mk_combined_img \
   mkbootfs \
   mkbootimg \
diff --git a/core/app_prebuilt_internal.mk b/core/app_prebuilt_internal.mk
index 9fab44d..b141a98 100644
--- a/core/app_prebuilt_internal.mk
+++ b/core/app_prebuilt_internal.mk
@@ -227,7 +227,7 @@
 $(built_module): PRIVATE_EMBEDDED_JNI_LIBS := $(embedded_prebuilt_jni_libs)
 
 ifdef LOCAL_COMPRESSED_MODULE
-$(built_module) : $(MINIGZIP)
+$(built_module) : $(GZIP)
 endif
 
 ifeq ($(module_run_appcompat),true)
@@ -305,4 +305,4 @@
 ###########################################################
 ## SBOM generation
 ###########################################################
-include $(BUILD_SBOM_GEN)
\ No newline at end of file
+include $(BUILD_SBOM_GEN)
diff --git a/core/config.mk b/core/config.mk
index c166ef7..cbcdfbb 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -645,10 +645,11 @@
 # For non-supported hosts, do not generate breakpad symbols.
 BREAKPAD_GENERATE_SYMBOLS := false
 endif
+GZIP := prebuilts/build-tools/path/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/gzip
 PROTOC := $(HOST_OUT_EXECUTABLES)/aprotoc$(HOST_EXECUTABLE_SUFFIX)
 NANOPB_SRCS := $(HOST_OUT_EXECUTABLES)/protoc-gen-nanopb
 MKBOOTFS := $(HOST_OUT_EXECUTABLES)/mkbootfs$(HOST_EXECUTABLE_SUFFIX)
-MINIGZIP := $(HOST_OUT_EXECUTABLES)/minigzip$(HOST_EXECUTABLE_SUFFIX)
+MINIGZIP := $(GZIP)
 LZ4 := $(HOST_OUT_EXECUTABLES)/lz4$(HOST_EXECUTABLE_SUFFIX)
 GENERATE_GKI_CERTIFICATE := $(HOST_OUT_EXECUTABLES)/generate_gki_certificate$(HOST_EXECUTABLE_SUFFIX)
 ifeq (,$(strip $(BOARD_CUSTOM_MKBOOTIMG)))
diff --git a/core/definitions.mk b/core/definitions.mk
index be40584..2484f1e 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2941,7 +2941,7 @@
 define compress-package
 $(hide) \
   mv $@ $@.uncompressed; \
-  $(MINIGZIP) -9 -c $@.uncompressed > $@.compressed; \
+  $(GZIP) -9 -c $@.uncompressed > $@.compressed; \
   rm -f $@.uncompressed; \
   mv $@.compressed $@;
 endef
diff --git a/core/dupcheck.sh b/core/dupcheck.sh
new file mode 100755
index 0000000..13ab782
--- /dev/null
+++ b/core/dupcheck.sh
@@ -0,0 +1,118 @@
+#!/bin/bash
+
+# Find duplicate shared libraries by md5 checksum and possible duplicates by size.
+# Results will be available in the out directory of the build.
+# Usage:
+# ./dupcheck.sh <out_dir> <image>
+
+OUT_DIR="$1"
+IMG="$2"
+TMP_MD5="${OUT_DIR}/_dup_md5"
+TMP_SIZE="${OUT_DIR}/_dup_size"
+TMP_CHECK="${OUT_DIR}/_dup_tmp_check"
+TMP_SIZE_REAL="${OUT_DIR}/_dup_size_real"
+TMP_FILE1="${OUT_DIR}/_dup_f1"
+TMP_FILE2="${OUT_DIR}/_dup_f2"
+MD5_DUPLICATES="${OUT_DIR}/duplicate-libs-md5-${IMG}.txt"
+SIZE_DUPLICATES="${OUT_DIR}/duplicate-libs-size-${IMG}.txt"
+
+# Check arguments
+if [ "$#" -ne 2 ]; then
+	echo "Usage: ./dupcheck.sh <out_dir> <image>"
+	exit 1
+fi
+
+# Check host and toolchain version
+CHECK_HOST=$(uname)
+if [ "${CHECK_HOST}" == "Linux" ]; then
+	ARCH="linux-x86"
+else
+	ARCH="darwin-x86"
+fi
+BINUTILS_PATH="./prebuilts/clang/host/${ARCH}/llvm-binutils-stable"
+
+# Remove any old files if they exist.
+if [ -f "${MD5_DUPLICATES}" ]; then
+	rm "${MD5_DUPLICATES}"
+fi
+
+if [ -f "${SIZE_DUPLICATES}" ]; then
+	rm "${SIZE_DUPLICATES}"
+fi
+
+# Find all .so files and calculate their md5.
+find ./"${OUT_DIR}"/${IMG}/ -name "lib*.so" -type f -print0 | xargs -0 md5sum | sed -e "s# .*/# #" | sort | uniq -c | sort -g | sed "/^.*1 /d" | sed "s/^. *[0-9] //" > "${TMP_MD5}" 2>&1
+
+if [ -s "${TMP_MD5}" ]; then
+	while read -r list; do
+		checksum=$(echo "${list}" | cut -f1 -d ' ')
+		filename=$(echo "${list}" | cut -f2 -d ' ')
+		# For each md5, list the file paths that match.
+		{
+			echo "MD5: ${checksum}";											                \
+			find ./"${OUT_DIR}"/${IMG}/ -name "${filename}" -type f -print0 | xargs -0 md5sum | grep "${checksum}" | sed 's/^.* //';	\
+			echo "";													                \
+		} >> "${MD5_DUPLICATES}"
+	done <"${TMP_MD5}"
+else
+	echo "No duplicate files by md5 found." >> "${MD5_DUPLICATES}"
+fi
+
+# Cleanup
+rm "${TMP_MD5}"
+
+# Find possible duplicate .so files by size.
+find ./"${OUT_DIR}"/${IMG}/ -name "*.so" -type f -print0 | xargs -0 stat --format="%s %n" 2>/dev/null | sed -e "s# .*/# #" | sort | uniq -c | sort -g | sed "/^.*1 /d" > "${TMP_SIZE}" 2>&1
+if [ -s "${TMP_SIZE}" ]; then
+	while read -r list; do
+		size=$(echo "${list}" | cut -f2 -d ' ')
+		filename=$(echo "${list}" | cut -f3 -d ' ')
+		# Check if the files are not in the md5sum list and do nothing if that is the case.
+		find ./"${OUT_DIR}"/${IMG}/ -name "${filename}" -type f -print0 | xargs -0 stat --format="%s %n" 2>/dev/null | grep "${size}" | sed "s/^.* //" | sort > "${TMP_CHECK}" 2>&1
+		while read -r filepath; do
+			found=$(grep -F "${filepath}" "${MD5_DUPLICATES}")
+			if [ -z "${found}" ]; then
+				echo "${filepath}" >> "${TMP_SIZE_REAL}"
+			fi
+		done<"${TMP_CHECK}"
+		# For every duplication found, diff the .note and .text sections.
+		if [ -s "${TMP_SIZE_REAL}" ]; then
+			{
+				echo "File: ${filename}, Size: ${size}";	\
+				cat "${TMP_SIZE_REAL}";				\
+				echo "";					\
+			} >> "${SIZE_DUPLICATES}"
+			count=$(wc -l "${TMP_SIZE_REAL}" | cut -f1 -d ' ')
+			# Limitation: this only works for file pairs. If more than two possible duplications are found, the user need to check manually
+			# all the possible combinations using the llvm-readelf and llvm-objdump commands below.
+			if [ "${count}" = 2 ]; then
+				file1=$(head -n 1 "${TMP_SIZE_REAL}")
+				file2=$(tail -n 1 "${TMP_SIZE_REAL}")
+				# Check .note section
+				${BINUTILS_PATH}/llvm-readelf --wide --notes "${file1}" > "${TMP_FILE1}" 2>&1
+				${BINUTILS_PATH}/llvm-readelf --wide --notes "${file2}" > "${TMP_FILE2}" 2>&1
+				{
+					diff -u "${TMP_FILE1}" "${TMP_FILE2}" | sed "1d;2d;3d";	\
+					echo "";
+				} >> "${SIZE_DUPLICATES}"
+				# Check .text section
+				${BINUTILS_PATH}/llvm-objdump --line-numbers --disassemble --demangle --reloc --no-show-raw-insn --section=.text "${file1}" | sed "1d;2d"> "${TMP_FILE1}" 2>&1
+				${BINUTILS_PATH}/llvm-objdump --line-numbers --disassemble --demangle --reloc --no-show-raw-insn --section=.text "${file2}" | sed "1d;2d"> "${TMP_FILE2}" 2>&1
+				{
+					diff -u "${TMP_FILE1}" "${TMP_FILE2}" | sed "1d;2d;3d";	\
+					echo "";
+				} >> "${SIZE_DUPLICATES}"
+				# Cleanup
+				rm "${TMP_FILE1}" "${TMP_FILE2}"
+			else
+				echo "*Note: more than one duplicate. Manually verify all possible combinations." >> "${SIZE_DUPLICATES}"
+			fi
+			rm "${TMP_SIZE_REAL}"
+			echo "" >> "${SIZE_DUPLICATES}"
+		fi
+	done <"${TMP_SIZE}"
+	# Cleanup
+	rm "${TMP_SIZE}" "${TMP_CHECK}"
+else
+	echo "No duplicate files by size found." >> "${SIZE_DUPLICATES}"
+fi
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 7cfab5b..a03a62b 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -531,7 +531,7 @@
 $(LOCAL_BUILT_MODULE): PRIVATE_RES_PACKAGE := $(my_res_package)
 $(LOCAL_BUILT_MODULE) : $(my_res_package) $(AAPT2)
 ifdef LOCAL_COMPRESSED_MODULE
-$(LOCAL_BUILT_MODULE) : $(MINIGZIP)
+$(LOCAL_BUILT_MODULE) : $(GZIP)
 endif
 ifeq (true, $(LOCAL_UNCOMPRESS_DEX))
 $(LOCAL_BUILT_MODULE) : $(ZIP2ZIP)
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
old mode 100755
new mode 100644
diff --git a/target/board/generic_x86_64_arm64/BoardConfig.mk b/target/board/generic_x86_64_arm64/BoardConfig.mk
old mode 100755
new mode 100644
diff --git a/target/board/generic_x86_64_arm64/device.mk b/target/board/generic_x86_64_arm64/device.mk
old mode 100755
new mode 100644
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 7fc33b0..c0a4394 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -348,7 +348,6 @@
     incident_report \
     ld.mc \
     lpdump \
-    minigzip \
     mke2fs \
     mkfs.erofs \
     resize2fs \
diff --git a/tools/aconfig/src/codegen_cpp.rs b/tools/aconfig/src/codegen_cpp.rs
index a802725..8acac8e 100644
--- a/tools/aconfig/src/codegen_cpp.rs
+++ b/tools/aconfig/src/codegen_cpp.rs
@@ -133,8 +133,6 @@
 
 #include <string>
 #include <memory>
-#include <server_configurable_flags/get_flags.h>
-using namespace server_configurable_flags;
 
 namespace com::android::aconfig::test {
 class flag_provider_interface {
@@ -196,8 +194,6 @@
 
 #include <string>
 #include <memory>
-#include <server_configurable_flags/get_flags.h>
-using namespace server_configurable_flags;
 
 namespace com::android::aconfig::test {
 class flag_provider_interface {
@@ -258,6 +254,8 @@
 #define com_android_aconfig_test_flag_provider_HEADER_H
 
 #include "com_android_aconfig_test.h"
+#include <server_configurable_flags/get_flags.h>
+using namespace server_configurable_flags;
 
 namespace com::android::aconfig::test {
 class flag_provider : public flag_provider_interface {
@@ -294,6 +292,8 @@
 #define com_android_aconfig_test_flag_provider_HEADER_H
 
 #include "com_android_aconfig_test.h"
+#include <server_configurable_flags/get_flags.h>
+using namespace server_configurable_flags;
 
 #include <unordered_map>
 #include <unordered_set>
diff --git a/tools/aconfig/templates/cpp_exported_header.template b/tools/aconfig/templates/cpp_exported_header.template
index e244de3..ee8f0dd 100644
--- a/tools/aconfig/templates/cpp_exported_header.template
+++ b/tools/aconfig/templates/cpp_exported_header.template
@@ -3,10 +3,7 @@
 
 #include <string>
 #include <memory>
-{{ if readwrite }}
-#include <server_configurable_flags/get_flags.h>
-using namespace server_configurable_flags;
-{{ endif }}
+
 namespace {cpp_namespace} \{
 
 class flag_provider_interface \{
diff --git a/tools/aconfig/templates/cpp_prod_flag_provider.template b/tools/aconfig/templates/cpp_prod_flag_provider.template
index c966ed4..6ba9e41 100644
--- a/tools/aconfig/templates/cpp_prod_flag_provider.template
+++ b/tools/aconfig/templates/cpp_prod_flag_provider.template
@@ -1,6 +1,10 @@
 #ifndef {header}_flag_provider_HEADER_H
 #define {header}_flag_provider_HEADER_H
 #include "{header}.h"
+{{ if readwrite }}
+#include <server_configurable_flags/get_flags.h>
+using namespace server_configurable_flags;
+{{ endif }}
 
 namespace {cpp_namespace} \{
 class flag_provider : public flag_provider_interface \{
diff --git a/tools/aconfig/templates/cpp_test_flag_provider.template b/tools/aconfig/templates/cpp_test_flag_provider.template
index bd597e7..a24116b 100644
--- a/tools/aconfig/templates/cpp_test_flag_provider.template
+++ b/tools/aconfig/templates/cpp_test_flag_provider.template
@@ -2,6 +2,11 @@
 #define {header}_flag_provider_HEADER_H
 #include "{header}.h"
 
+{{ if readwrite }}
+#include <server_configurable_flags/get_flags.h>
+using namespace server_configurable_flags;
+{{ endif }}
+
 #include <unordered_map>
 #include <unordered_set>
 #include <cassert>
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 7a2dcb7..5a7cc76 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -168,7 +168,6 @@
         "brillo_update_payload",
         "checkvintf",
         "generate_gki_certificate",
-        "minigzip",
         "lz4",
         "toybox",
         "unpack_bootimg",
@@ -244,7 +243,6 @@
         "bsdiff",
         "generate_gki_certificate",
         "imgdiff",
-        "minigzip",
         "lz4",
         "mkbootfs",
         "signapk",
@@ -310,7 +308,6 @@
         "deapexer",
         "generate_gki_certificate",
         "imgdiff",
-        "minigzip",
         "lz4",
         "mkbootfs",
         "signapk",
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 091121f..1f021e0 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -985,7 +985,7 @@
         each of the variables.
     ramdisk_format: If name is "boot", the format of ramdisk inside the
         boot image. Otherwise, its value is ignored.
-        Use lz4 to decompress by default. If its value is gzip, use minigzip.
+        Use lz4 to decompress by default. If its value is gzip, use gzip.
   """
 
   def __init__(self, input_file, name, placeholder_values=None):
@@ -1638,9 +1638,9 @@
     p2 = Run(["lz4", "-l", "-12", "--favor-decSpeed"], stdin=p1.stdout,
              stdout=ramdisk_img.file.fileno())
   elif ramdisk_format == RamdiskFormat.GZ:
-    p2 = Run(["minigzip"], stdin=p1.stdout, stdout=ramdisk_img.file.fileno())
+    p2 = Run(["gzip"], stdin=p1.stdout, stdout=ramdisk_img.file.fileno())
   else:
-    raise ValueError("Only support lz4 or minigzip ramdisk format.")
+    raise ValueError("Only support lz4 or gzip ramdisk format.")
 
   p2.wait()
   p1.wait()
@@ -2120,20 +2120,33 @@
   # According to https://stackoverflow.com/questions/434641/how-do-i-set-permissions-attributes-on-a-file-in-a-zip-file-using-pythons-zip/6297838#6297838
   # higher bits of |external_attr| are unix file permission and types
   unix_filetype = info.external_attr >> 16
+  file_perm = unix_filetype & 0o777
 
   def CheckMask(a, mask):
     return (a & mask) == mask
 
   def IsSymlink(a):
     return CheckMask(a, stat.S_IFLNK)
+
+  def IsDir(a):
+    return CheckMask(a, stat.S_IFDIR)
   # python3.11 zipfile implementation doesn't handle symlink correctly
   if not IsSymlink(unix_filetype):
-    return input_zip.extract(info, dirname)
+    target = input_zip.extract(info, dirname)
+    # We want to ensure that the file is at least read/writable by owner and readable by all users
+    if IsDir(unix_filetype):
+      os.chmod(target, file_perm | 0o755)
+    else:
+      os.chmod(target, file_perm | 0o644)
+    return target
   if dirname is None:
     dirname = os.getcwd()
   target = os.path.join(dirname, info.filename)
   os.makedirs(os.path.dirname(target), exist_ok=True)
+  if os.path.exists(target):
+    os.unlink(target)
   os.symlink(input_zip.read(info).decode(), target)
+  return target
 
 
 def UnzipToDir(filename, dirname, patterns=None):
@@ -4075,7 +4088,7 @@
   Get build.prop from ramdisk within the boot image
 
   Args:
-    boot_img: the boot image file. Ramdisk must be compressed with lz4 or minigzip format.
+    boot_img: the boot image file. Ramdisk must be compressed with lz4 or gzip format.
 
   Return:
     An extracted file that stores properties in the boot image.
@@ -4094,11 +4107,11 @@
     elif ramdisk_format == RamdiskFormat.GZ:
       with open(ramdisk, 'rb') as input_stream:
         with open(uncompressed_ramdisk, 'wb') as output_stream:
-          p2 = Run(['minigzip', '-d'], stdin=input_stream.fileno(),
+          p2 = Run(['gzip', '-d'], stdin=input_stream.fileno(),
                    stdout=output_stream.fileno())
           p2.wait()
     else:
-      logger.error('Only support lz4 or minigzip ramdisk format.')
+      logger.error('Only support lz4 or gzip ramdisk format.')
       return None
 
     abs_uncompressed_ramdisk = os.path.abspath(uncompressed_ramdisk)