Fix --annotation-allowed-classes-file, and start using it

Also add some presubmit tests as a smoke test.

Bug: 292141694
Test: run-all-tests.sh
Test: atest --no-bazel-mode CtsUtilTestCasesRavenwood

Change-Id: I30569313b764dfa30db9c2c5627050da4a6a1d67
diff --git a/Ravenwood.bp b/Ravenwood.bp
index 3310898..2f67090 100644
--- a/Ravenwood.bp
+++ b/Ravenwood.bp
@@ -30,7 +30,7 @@
     name: "framework-minus-apex.ravenwood-base",
     tools: ["hoststubgen"],
     cmd: "$(location hoststubgen) " +
-        "@$(location :ravenwood-standard-options) " +
+        "@$(location ravenwood/ravenwood-standard-options.txt) " +
 
         "--out-stub-jar $(location ravenwood_stub.jar) " +
         "--out-impl-jar $(location ravenwood.jar) " +
@@ -39,11 +39,13 @@
         "--gen-input-dump-file $(location hoststubgen_dump.txt) " +
 
         "--in-jar $(location :framework-minus-apex-for-hoststubgen) " +
-        "--policy-override-file $(location framework-minus-apex-ravenwood-policies.txt) ",
+        "--policy-override-file $(location ravenwood/framework-minus-apex-ravenwood-policies.txt) " +
+        "--annotation-allowed-classes-file $(location ravenwood/ravenwood-annotation-allowed-classes.txt) ",
     srcs: [
         ":framework-minus-apex-for-hoststubgen",
-        "framework-minus-apex-ravenwood-policies.txt",
-        ":ravenwood-standard-options",
+        "ravenwood/framework-minus-apex-ravenwood-policies.txt",
+        "ravenwood/ravenwood-standard-options.txt",
+        "ravenwood/ravenwood-annotation-allowed-classes.txt",
     ],
     out: [
         "ravenwood.jar",
diff --git a/TEST_MAPPING b/TEST_MAPPING
index b215ee4..3409838 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -128,6 +128,17 @@
       ]
     }
   ],
+  "postsubmit-ravenwood": [
+    // TODO(ravenwood) promote it to presubmit
+    // TODO: Enable it once the infra knows how to run it.
+//    {
+//      "name": "CtsUtilTestCasesRavenwood",
+//      "file_patterns": [
+//        "*Ravenwood*",
+//        "*ravenwood*"
+//      ]
+//    }
+  ],
   "postsubmit-managedprofile-stress": [
     {
       "name": "ManagedProfileLifecycleStressTest"
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index 5c9bf18..ec12d21 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -16,15 +16,6 @@
     visibility: ["//visibility:public"],
 }
 
-// File that contains the standard command line arguments to hoststubgen.
-filegroup {
-    name: "ravenwood-standard-options",
-    srcs: [
-        "ravenwood-standard-options.txt",
-    ],
-    visibility: ["//visibility:public"],
-}
-
 java_library {
     name: "ravenwood-annotations-lib",
     srcs: [":ravenwood-annotations"],
diff --git a/ravenwood/TEST_MAPPING b/ravenwood/TEST_MAPPING
new file mode 100644
index 0000000..72eb665
--- /dev/null
+++ b/ravenwood/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+    "presubmit": [
+        // Let's only run this one as a smoke test.
+        // TODO: Enable it once the infra knows how to run it.
+        // { "name": "CtsUtilTestCasesRavenwood" }
+    ]
+}
diff --git a/framework-minus-apex-ravenwood-policies.txt b/ravenwood/framework-minus-apex-ravenwood-policies.txt
similarity index 100%
rename from framework-minus-apex-ravenwood-policies.txt
rename to ravenwood/framework-minus-apex-ravenwood-policies.txt
diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/ravenwood-annotation-allowed-classes.txt
new file mode 100644
index 0000000..0811f90
--- /dev/null
+++ b/ravenwood/ravenwood-annotation-allowed-classes.txt
@@ -0,0 +1,2 @@
+# Only classes listed here can use the Ravenwood annotations.
+
diff --git a/tools/hoststubgen/TEST_MAPPING b/tools/hoststubgen/TEST_MAPPING
index e02492d..192b6f2 100644
--- a/tools/hoststubgen/TEST_MAPPING
+++ b/tools/hoststubgen/TEST_MAPPING
@@ -1,8 +1,11 @@
 {
-    // TODO: Change to presubmit.
-    "postsubmit": [
+    "presubmit": [
         { "name": "tiny-framework-dump-test" },
         { "name": "hoststubgentest" },
         { "name": "hoststubgen-invoke-test" }
+
+        // As a smoke test.
+        // TODO: Enable it once the infra knows how to run it.
+        // { "name": "CtsUtilTestCasesRavenwood" }
     ]
 }
diff --git a/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh b/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh
index 34b2145..0068afb 100755
--- a/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh
+++ b/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh
@@ -27,8 +27,14 @@
 
 # Set up the constants and variables
 
+# Bazel sets $TEST_TMPDIR.
 export TEMP=$TEST_TMPDIR
 
+if [[ "$TEMP" == "" ]] ; then
+  TEMP=./tmp
+  mkdir -p $TEMP
+fi
+
 JAR=hoststubgen-test-tiny-framework.jar
 STUB=$TEMP/stub.jar
 IMPL=$TEMP/impl.jar
@@ -72,6 +78,26 @@
       --in-jar $JAR \
       --out-stub-jar $STUB \
       --out-impl-jar $IMPL \
+      --stub-annotation \
+          android.hosttest.annotation.HostSideTestStub \
+      --keep-annotation \
+          android.hosttest.annotation.HostSideTestKeep \
+      --stub-class-annotation \
+          android.hosttest.annotation.HostSideTestWholeClassStub \
+      --keep-class-annotation \
+          android.hosttest.annotation.HostSideTestWholeClassKeep \
+      --throw-annotation \
+          android.hosttest.annotation.HostSideTestThrow \
+      --remove-annotation \
+          android.hosttest.annotation.HostSideTestRemove \
+      --substitute-annotation \
+          android.hosttest.annotation.HostSideTestSubstitute \
+      --native-substitute-annotation \
+          android.hosttest.annotation.HostSideTestNativeSubstitutionClass \
+      --class-load-hook-annotation \
+          android.hosttest.annotation.HostSideTestClassLoadHook \
+      --stub-static-initializer-annotation \
+          android.hosttest.annotation.HostSideTestStaticInitializerStub \
       $filter_arg \
       |& tee $HOSTSTUBGEN_OUT
   HOSTSTUBGEN_RC=${PIPESTATUS[0]}
@@ -157,6 +183,12 @@
 * # All other classes allowed
 "
 
+run_hoststubgen_for_success "One specific class disallowed, but it doesn't use annotations" \
+    "
+!com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+* # All other classes allowed
+"
+
 
 
 echo "All tests passed"
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
index 9bb5381e..eda6761 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
@@ -133,6 +133,25 @@
         }
     }
 
+    fun findAnyAnnotation(
+            className: String,
+            anyAnnotations: Set<String>,
+            visibleAnnotations: List<AnnotationNode>?,
+            invisibleAnnotations: List<AnnotationNode>?,
+    ): AnnotationNode? {
+        val ret = findAnyAnnotation(anyAnnotations, visibleAnnotations, invisibleAnnotations)
+
+        if (ret != null) {
+            if (!annotationAllowedClassesFilter.matches(className)) {
+                throw InvalidAnnotationException(
+                        "Class ${className.toHumanReadableClassName()} is not allowed to have " +
+                                "Ravenwood annotations. Contact g/ravenwood for more details.")
+            }
+        }
+
+        return ret
+    }
+
     /**
      * Find a visibility annotation.
      *
@@ -149,28 +168,22 @@
     ): FilterPolicyWithReason? {
         detectInvalidAnnotations(visibles, invisibles, type, name1, name2, name3)
 
-        if (!annotationAllowedClassesFilter.matches(className)) {
-            throw InvalidAnnotationException(
-                    "Class ${className.toHumanReadableClassName()} is not allowed to have " +
-                    "Ravenwood annotations. Contact g/ravenwood for more details.")
-        }
-
-        findAnyAnnotation(stubAnnotations, visibles, invisibles)?.let {
+        findAnyAnnotation(className, stubAnnotations, visibles, invisibles)?.let {
             return FilterPolicy.Stub.withReason(reasonAnnotation)
         }
-        findAnyAnnotation(stubClassAnnotations, visibles, invisibles)?.let {
+        findAnyAnnotation(className, stubClassAnnotations, visibles, invisibles)?.let {
             return FilterPolicy.StubClass.withReason(reasonClassAnnotation)
         }
-        findAnyAnnotation(keepAnnotations, visibles, invisibles)?.let {
+        findAnyAnnotation(className, keepAnnotations, visibles, invisibles)?.let {
             return FilterPolicy.Keep.withReason(reasonAnnotation)
         }
-        findAnyAnnotation(keepClassAnnotations, visibles, invisibles)?.let {
+        findAnyAnnotation(className, keepClassAnnotations, visibles, invisibles)?.let {
             return FilterPolicy.KeepClass.withReason(reasonClassAnnotation)
         }
-        findAnyAnnotation(throwAnnotations, visibles, invisibles)?.let {
+        findAnyAnnotation(className, throwAnnotations, visibles, invisibles)?.let {
             return FilterPolicy.Throw.withReason(reasonAnnotation)
         }
-        findAnyAnnotation(removeAnnotations, visibles, invisibles)?.let {
+        findAnyAnnotation(className, removeAnnotations, visibles, invisibles)?.let {
             return FilterPolicy.Remove.withReason(reasonAnnotation)
         }
 
@@ -227,7 +240,7 @@
         val cn = classes.getClass(className)
 
         if (methodName == CLASS_INITIALIZER_NAME && descriptor == CLASS_INITIALIZER_DESC) {
-            findAnyAnnotation(stubStaticInitializerAnnotations,
+            findAnyAnnotation(cn.name, stubStaticInitializerAnnotations,
                     cn.visibleAnnotations, cn.invisibleAnnotations)?.let {
                 return FilterPolicy.Stub.withReason(reasonAnnotation)
             }