Create EXTRA_INSTALL_ZIPS variable

Make needs to know about the "extra" zip files that are extracted
to the staging directories so that it can track all the installed files
correctly.

Also add a utility tool for listing the contents of relevant zips.

Bug: 337869220
Test: m droid and checked the contents of file_list.txt when adding an android_app_set locally
Change-Id: Idc5dd785b03c05f7972c66620d4e6359892b3863
diff --git a/android/makevars.go b/android/makevars.go
index e73645f..b6bc14e 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -473,7 +473,7 @@
 
 # Values written by Soong to generate install rules that can be amended by Kati.
 
-
+EXTRA_INSTALL_ZIPS :=
 `)
 
 	preserveSymlinksFlag := "-d"
@@ -507,9 +507,12 @@
 		if extraFiles := install.extraFiles; extraFiles != nil {
 			fmt.Fprintf(buf, "\t( unzip -qDD -d '%s' '%s' 2>&1 | grep -v \"zipfile is empty\"; exit $${PIPESTATUS[0]} ) || \\\n", extraFiles.dir.String(), extraFiles.zip.String())
 			fmt.Fprintf(buf, "\t  ( code=$$?; if [ $$code -ne 0 -a $$code -ne 1 ]; then exit $$code; fi )\n")
+			fmt.Fprintf(buf, "EXTRA_INSTALL_ZIPS += %s:%s\n", extraFiles.dir.String(), extraFiles.zip.String())
 		}
+
 		fmt.Fprintln(buf)
 	}
+	fmt.Fprintf(buf, ".KATI_READONLY := EXTRA_INSTALL_ZIPS\n")
 
 	for _, symlink := range symlinks {
 		fmt.Fprintf(buf, "%s:", symlink.to.String())
diff --git a/scripts/Android.bp b/scripts/Android.bp
index 790fbe0..80cd935 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -296,3 +296,9 @@
     main: "buildinfo.py",
     srcs: ["buildinfo.py"],
 }
+
+python_binary_host {
+    name: "extra_install_zips_file_list",
+    main: "extra_install_zips_file_list.py",
+    srcs: ["extra_install_zips_file_list.py"],
+}
diff --git a/scripts/extra_install_zips_file_list.py b/scripts/extra_install_zips_file_list.py
new file mode 100755
index 0000000..8ea2a4b
--- /dev/null
+++ b/scripts/extra_install_zips_file_list.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import sys
+import zipfile
+from typing import List
+
+def list_files_in_zip(zipfile_path: str) -> List[str]:
+    with zipfile.ZipFile(zipfile_path, 'r') as zf:
+        return zf.namelist()
+
+def main():
+    parser = argparse.ArgumentParser(
+        description='Lists paths to all files inside an EXTRA_INSTALL_ZIPS zip file relative to a partition staging directory. '
+        'This script is just a helper because its difficult to implement this logic in make code.'
+    )
+    parser.add_argument('staging_dir',
+        help='Path to the partition staging directory')
+    parser.add_argument('extra_install_zips', nargs='*',
+        help='The value of EXTRA_INSTALL_ZIPS from make. It should be a list of extraction_dir:zip_file pairs.')
+    args = parser.parse_args()
+
+    staging_dir = args.staging_dir.removesuffix('/') + '/'
+
+    for zip_pair in args.extra_install_zips:
+        d, z = zip_pair.split(':')
+        d = d.removesuffix('/') + '/'
+
+        if d.startswith(staging_dir):
+            d = os.path.relpath(d, staging_dir)
+            if d == '.':
+                d = ''
+            for f in list_files_in_zip(z):
+                print(os.path.join(d, f))
+
+
+if __name__ == "__main__":
+    main()