Initial commit of "HostStubGen" (Ravenwood)

See tools/hoststubgen/README.md for the directory structure...

This CL contains:
- The HostGenTool.

- Libraries to build / run host side tets. (helper-*/ directories)

- Currently we expose ArrayMap and Log to the host side, but we also need to
expose a lot more classes that the tests usee.

- Some sample tests. (test-framework/ and test-tiny-framework/)

Sample tests contain very small tests for ArrayMap and Log.

- This version doen't loa JNI code yet. It still uses the Java substitution
for Log's native methods.

This is because `libandroid_runtime` seems to have a lot of obscure dependencies,
and using `libandroid_runtime` could cause obscure build errors when someone
make chages to any of direct/indirect dependencies.

- Current version doesn't use any Java annotations to control what are exposed
on the host side. Instead, we use `framework-policy-override.txt`, which is
easier to change. (because changing the file wouln't require rebuilding
framework-minus-apex.jar.)

- Currently we expose ArrayMap and Log to the host side, but we also need to
expose a lot more classes that the tests usee. See the `framework-policy-override.txt`
file.

Test: ./scripts/run-all-tests.sh
Bug: 292141694
Change-Id: If149e26aa919d17a0b82dacc78f31bd79fbb110b
diff --git a/tools/hoststubgen/scripts/dump-jar b/tools/hoststubgen/scripts/dump-jar
new file mode 100755
index 0000000..93729fb
--- /dev/null
+++ b/tools/hoststubgen/scripts/dump-jar
@@ -0,0 +1,163 @@
+#!/bin/bash
+# Copyright (C) 2023 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.
+
+set -e
+
+
+help() {
+    cat <<'EOF'
+
+  dump-jar: Dump java classes in jar files
+
+    Usage:
+      dump-jar [-v] CLASS-FILE [...]
+
+        Dump a *.class file
+
+      dump-jar [-v] [-s] [-o OUTPUT-FILENAME] JAR-FILE[: filename regex] [...]
+
+        Dump a jar file.
+
+        If a filename contains a ':', then the following part
+        will be used to filter files in the jar file.
+
+        For example, "file.jar:/MyClass$" will only dump "MyClass" in file.jar.
+
+    Options:
+      -v: Enable verbose output.
+
+      -s: Simple output mode, used to check HostStubGen output jars.
+
+      -o: Write the output to a specified file.
+EOF
+}
+
+# Parse the options.
+
+verbose=0
+simple=0
+output=""
+while getopts "hvso:" opt; do
+case "$opt" in
+    h)
+        help
+        exit 0
+        ;;
+    v)
+        verbose=1
+        ;;
+    s)
+        simple=1
+        ;;
+    o)
+        output="$OPTARG"
+        ;;
+    '?')
+        help
+        exit 1
+        ;;
+esac
+done
+shift $(($OPTIND - 1))
+
+JAVAP_OPTS="${JAVAP_OPTS:--v -p -s -sysinfo -constants}"
+
+if (( $simple )) ; then
+  JAVAP_OPTS="-p -c -v"
+fi
+
+
+# Normalize a java class name.
+# Convert '.' to '/'
+# Remove the *.class suffix.
+normalize() {
+  local name="$1"
+  name="${name%.class}" # Remove the .class suffix.
+  echo "$name" | tr '.' '/'
+}
+
+# Convert the output for `-s` as needed.
+filter_output() {
+  if (( $simple )) ; then
+    # For "simple output" mode,
+    # - Normalize the constant numbers (replace with "#x")
+    # - Remove the constant pool
+    # - Remove the line number table
+    # - Some other transient lines
+    #
+    # `/PATTERN-1/,/PATTERN-1/{//!d}` is a trick to delete lines between two patterns, without
+    # the start and the end lines.
+    sed -e 's/#[0-9][0-9]*/#x/g' \
+        -e '/^Constant pool:/,/^[^ ]/{//!d}' \
+        -e '/^ *line *[0-9][0-9]*: *[0-9][0-9]*$/d' \
+        -e '/SHA-256 checksum/d' \
+        -e '/Last modified/d' \
+        -e '/^Classfile jar/d'
+  else
+    cat # Print as-is.
+  fi
+}
+
+# Write to the output file (specified with -o) as needed.
+write_to_out() {
+  if [[ -n "$output" ]] ; then
+    cat >"$output"
+    echo "Wrote output to $output" 1>&2
+  else
+    cat # print to stdout
+  fi
+}
+
+for file in "${@}"; do
+
+    # *.class?
+    if echo "$file" | grep -qE '\.class$' ; then
+        echo "# Class: $file" 1>&2
+        javap $dump_code_opt $JAVAP_OPTS $file
+
+    # *.jar?
+    elif echo "$file" | grep -qE '\.jar(:.*)?$' ; then
+        # Take the regex. Remove everything up to : in $file
+        regex=""
+        if [[ "$file" =~ : ]] ; then
+            regex="$(normalize "${file##*:}")"
+        fi
+
+        # Remove everything after ':', inclusively, in $file.
+        file="${file%:*}"
+
+        # Print the filename and the regex.
+        if ! (( $simple )) ; then
+          echo -n "# Jar: $file"
+          if [[ "$regex" != "" ]] ;then
+              echo -n "  (regex: $regex)"
+          fi
+          echo
+        fi
+
+        jar tf "$file" | grep '\.class$' | sort | while read -r class ; do
+            if normalize "$class" | grep -q -- "$regex" ; then
+                echo "## Class: $class"
+                javap $dump_code_opt $JAVAP_OPTS -cp $file ${class%.class}
+            else
+                (( $verbose )) && echo "## Skipping class: $class"
+            fi
+        done
+
+    else
+        echo "Unknown file type: $file" 1>&2
+        exit 1
+    fi
+done | filter_output | write_to_out