extract_utils: Add functions to extract vendor blobs from vendor.img

Change-Id: I6f37adc955856fa78e719eb30249800abe80020c
diff --git a/extract_utils.sh b/extract_utils.sh
index fb39fa9..00a998a 100644
--- a/extract_utils.sh
+++ b/extract_utils.sh
@@ -211,6 +211,25 @@
 }
 
 #
+# suffix_match_file:
+#
+# $1: the suffix to match on
+# $2: the file to match the suffix for
+#
+# Internal function which returns true if a filename contains the
+# specified suffix.
+#
+function suffix_match_file() {
+    local SUFFIX="$1"
+    local FILE="$2"
+    if [[ "$FILE" = *"$SUFFIX" ]]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+#
 # truncate_file
 #
 # $1: the filename to truncate
@@ -1268,3 +1287,94 @@
         chmod 644 "$OUTPUT_DIR/$FILE"
     done
 }
+
+function extract_img_data() {
+    local image_file="$1"
+    local out_dir="$2"
+    local logFile="$TMPDIR/debugfs.log"
+
+    if [ ! -d "$out_dir" ]; then
+        mkdir -p "$out_dir"
+    fi
+
+    if [[ "$HOST_OS" == "Darwin" ]]; then
+        debugfs -R "rdump / \"$out_dir\"" "$image_file" &> "$logFile" || {
+            echo "[-] Failed to extract data from '$image_file'"
+            abort 1
+        }
+    else
+        debugfs -R 'ls -p' "$image_file" 2>/dev/null | cut -d '/' -f6 | while read -r entry
+        do
+            debugfs -R "rdump \"$entry\" \"$out_dir\"" "$image_file" >> "$logFile" 2>&1 || {
+                echo "[-] Failed to extract data from '$image_file'"
+                abort 1
+            }
+        done
+    fi
+
+    local symlink_err="rdump: Attempt to read block from filesystem resulted in short read while reading symlink"
+    if grep -Fq "$symlink_err" "$logFile"; then
+        echo "[-] Symlinks have not been properly processed from $image_file"
+        echo "[!] If you don't have a compatible debugfs version, modify 'execute-all.sh' to disable 'USE_DEBUGFS' flag"
+        abort 1
+    fi
+}
+
+declare -ra VENDOR_SKIP_FILES=(
+  "bin/toybox_vendor"
+  "bin/toolbox"
+  "bin/grep"
+  "build.prop"
+  "compatibility_matrix.xml"
+  "default.prop"
+  "etc/NOTICE.xml.gz"
+  "etc/vintf/compatibility_matrix.xml"
+  "etc/vintf/manifest.xml"
+  "etc/wifi/wpa_supplicant.conf"
+  "manifest.xml"
+  "overlay/DisplayCutoutEmulationCorner/DisplayCutoutEmulationCornerOverlay.apk"
+  "overlay/DisplayCutoutEmulationDouble/DisplayCutoutEmulationDoubleOverlay.apk"
+  "overlay/DisplayCutoutEmulationTall/DisplayCutoutEmulationTallOverlay.apk"
+  "overlay/DisplayCutoutNoCutout/NoCutoutOverlay.apk"
+  "overlay/framework-res__auto_generated_rro.apk"
+  "overlay/SysuiDarkTheme/SysuiDarkThemeOverlay.apk"
+)
+
+function array_contains() {
+    local element
+    for element in "${@:2}"; do [[ "$element" == "$1" ]] && return 0; done
+    return 1
+}
+
+function generate_prop_list_from_image() {
+    local image_file="$1"
+    local image_dir="$TMPDIR/image-temp"
+    local output_list="$2"
+    local output_list_tmp="$TMPDIR/_proprietary-blobs.txt"
+    local -n skipped_vendor_files="$3"
+
+    extract_img_data "$image_file" "$image_dir"
+
+    find "$image_dir" -not -type d | sed "s#^$image_dir/##" | while read -r FILE
+    do
+        # Skip VENDOR_SKIP_FILES since it will be re-generated at build time
+        if array_contains "$FILE" "${VENDOR_SKIP_FILES[@]}"; then
+            continue
+        fi
+        # Skip device defined skipped files since they will be re-generated at build time
+        if array_contains "$FILE" "${skipped_vendor_files[@]}"; then
+            continue
+        fi
+        if suffix_match_file ".apk" "$FILE" ; then
+            echo "-vendor/$FILE" >> "$output_list_tmp"
+        else
+            echo "vendor/$FILE" >> "$output_list_tmp"
+        fi
+    done
+
+    # Sort merged file with all lists
+    sort -u "$output_list_tmp" > "$output_list"
+
+    # Clean-up
+    rm -f "$output_list_tmp"
+}