Use conventional args style for gen_jarjar

gen_jarjar supported multi-valued arguments via space-separated lists,
like "--apistubs foo bar". This is unusual, as "bar" would generally be
interpreted as a positional argument instead.

Change the usage to "--apistubs foo --apistubs bar", which is more
conventional. Also remove the "--jars" switch to have the jars be
positional arguments instead, and change the "--unsupportedapi"
arguments to be a column-separated list (like java classpath), instead
of space-separated. For --unsupportedapi, this allows providing a list
of files via minimal modifications in the genrule usage.

Test: m
Change-Id: Id67ad16de2ea6682fee402540f464ed3b5b0cca9
diff --git a/framework/Android.bp b/framework/Android.bp
index fcce7a5..485961c 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -228,12 +228,13 @@
     ],
     out: ["framework_connectivity_jarjar_rules.txt"],
     cmd: "$(location jarjar-rules-generator) " +
-        "--jars $(location :framework-connectivity-pre-jarjar{.jar}) " +
+        "$(location :framework-connectivity-pre-jarjar{.jar}) " +
         "$(location :framework-connectivity-t-pre-jarjar{.jar}) " +
         "--prefix android.net.connectivity " +
         "--apistubs $(location :framework-connectivity.stubs.module_lib{.jar}) " +
-        "$(location :framework-connectivity-t.stubs.module_lib{.jar}) " +
-        "--unsupportedapi $(locations :connectivity-hiddenapi-files) " +
+        "--apistubs $(location :framework-connectivity-t.stubs.module_lib{.jar}) " +
+        // Make a ":"-separated list. There will be an extra ":" but empty items are ignored.
+        "--unsupportedapi $$(printf ':%s' $(locations :connectivity-hiddenapi-files)) " +
         "--excludes $(location jarjar-excludes.txt) " +
         "--output $(out)",
     visibility: [
diff --git a/service/Android.bp b/service/Android.bp
index b68d389..743dfcf 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -307,7 +307,7 @@
     ],
     out: ["service_connectivity_jarjar_rules.txt"],
     cmd: "$(location jarjar-rules-generator) " +
-        "--jars $(location :service-connectivity-pre-jarjar{.jar}) " +
+        "$(location :service-connectivity-pre-jarjar{.jar}) " +
         "$(location :service-connectivity-tiramisu-pre-jarjar{.jar}) " +
         "--prefix android.net.connectivity " +
         "--excludes $(location jarjar-excludes.txt) " +
@@ -326,7 +326,7 @@
     ],
     out: ["service_nearby_jarjar_rules.txt"],
     cmd: "$(location jarjar-rules-generator) " +
-        "--jars $(location :service-nearby-pre-jarjar{.jar}) " +
+        "$(location :service-nearby-pre-jarjar{.jar}) " +
         "--prefix com.android.server.nearby " +
         "--excludes $(location jarjar-excludes.txt) " +
         "--output $(out)",
diff --git a/tools/Android.bp b/tools/Android.bp
index 1fa93bb..7d6b248 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -48,6 +48,7 @@
 java_library {
     name: "jarjar-rules-generator-testjavalib",
     srcs: ["testdata/java/**/*.java"],
+    libs: ["unsupportedappusage"],
     visibility: ["//visibility:private"],
 }
 
@@ -67,6 +68,17 @@
     compile_dex: false,
 }
 
+java_library {
+    name: "framework-connectivity-t.stubs.module_lib-for-test",
+    visibility: ["//visibility:private"],
+    static_libs: [
+        "framework-connectivity-t.stubs.module_lib",
+    ],
+    // Not strictly necessary but specified as this MUST not have generate
+    // a dex jar as that will break the tests.
+    compile_dex: false,
+}
+
 python_test_host {
     name: "jarjar-rules-generator-test",
     srcs: [
@@ -75,8 +87,11 @@
     ],
     data: [
         "testdata/test-jarjar-excludes.txt",
+        // two unsupportedappusage lists with different classes to test using multiple lists
         "testdata/test-unsupportedappusage.txt",
+        "testdata/test-other-unsupportedappusage.txt",
         ":framework-connectivity.stubs.module_lib-for-test",
+        ":framework-connectivity-t.stubs.module_lib-for-test",
         ":jarjar-rules-generator-testjavalib",
     ],
     main: "gen_jarjar_test.py",
diff --git a/tools/gen_jarjar.py b/tools/gen_jarjar.py
index 2ff53fa..eb686ce 100755
--- a/tools/gen_jarjar.py
+++ b/tools/gen_jarjar.py
@@ -28,8 +28,8 @@
 def parse_arguments(argv):
     parser = argparse.ArgumentParser()
     parser.add_argument(
-        '--jars', nargs='+',
-        help='Path to pre-jarjar JAR. Can be followed by multiple space-separated paths.')
+        'jars', nargs='+',
+        help='Path to pre-jarjar JAR. Multiple jars can be specified.')
     parser.add_argument(
         '--prefix', required=True,
         help='Package prefix to use for jarjared classes, '
@@ -37,18 +37,17 @@
     parser.add_argument(
         '--output', required=True, help='Path to output jarjar rules file.')
     parser.add_argument(
-        '--apistubs', nargs='*', default=[],
-        help='Path to API stubs jar. Classes that are API will not be jarjared. Can be followed by '
-             'multiple space-separated paths.')
+        '--apistubs', action='append', default=[],
+        help='Path to API stubs jar. Classes that are API will not be jarjared. Can be repeated to '
+             'specify multiple jars.')
     parser.add_argument(
-        '--unsupportedapi', nargs='*', default=[],
-        help='Path to UnsupportedAppUsage hidden API .txt lists. '
-             'Classes that have UnsupportedAppUsage API will not be jarjared. Can be followed by '
-             'multiple space-separated paths.')
+        '--unsupportedapi',
+        help='Column(:)-separated paths to UnsupportedAppUsage hidden API .txt lists. '
+             'Classes that have UnsupportedAppUsage API will not be jarjared.')
     parser.add_argument(
-        '--excludes', nargs='*', default=[],
-        help='Path to files listing classes that should not be jarjared. Can be followed by '
-             'multiple space-separated paths. '
+        '--excludes', action='append', default=[],
+        help='Path to files listing classes that should not be jarjared. Can be repeated to '
+             'specify multiple files.'
              'Each file should contain one full-match regex per line. Empty lines or lines '
              'starting with "#" are ignored.')
     return parser.parse_args(argv)
@@ -103,8 +102,10 @@
     for apistubs_file in args.apistubs:
         excluded_classes.update(_list_toplevel_jar_classes(apistubs_file))
 
-    for unsupportedapi_file in args.unsupportedapi:
-        excluded_classes.update(_list_hiddenapi_classes(unsupportedapi_file))
+    unsupportedapi_files = (args.unsupportedapi and args.unsupportedapi.split(':')) or []
+    for unsupportedapi_file in unsupportedapi_files:
+        if unsupportedapi_file:
+            excluded_classes.update(_list_hiddenapi_classes(unsupportedapi_file))
 
     exclude_regexes = []
     for exclude_file in args.excludes:
diff --git a/tools/gen_jarjar_test.py b/tools/gen_jarjar_test.py
index 8d8e82b..f5bf499 100644
--- a/tools/gen_jarjar_test.py
+++ b/tools/gen_jarjar_test.py
@@ -31,11 +31,11 @@
 class TestGenJarjar(unittest.TestCase):
     def test_gen_rules(self):
         args = gen_jarjar.parse_arguments([
-            "--jars", "jarjar-rules-generator-testjavalib.jar",
+            "jarjar-rules-generator-testjavalib.jar",
             "--prefix", "jarjar.prefix",
             "--output", "test-output-rules.txt",
             "--apistubs", "framework-connectivity.stubs.module_lib.jar",
-            "--unsupportedapi", "testdata/test-unsupportedappusage.txt",
+            "--unsupportedapi", ":testdata/test-unsupportedappusage.txt",
             "--excludes", "testdata/test-jarjar-excludes.txt",
         ])
         gen_jarjar.make_jarjar_rules(args)
@@ -43,6 +43,39 @@
         with open(args.output) as out:
             lines = out.readlines()
 
+        self.maxDiff = None
+        self.assertListEqual([
+            'rule android.net.IpSecTransform jarjar.prefix.@0\n',
+            'rule android.net.IpSecTransformTest jarjar.prefix.@0\n',
+            'rule android.net.IpSecTransformTest$* jarjar.prefix.@0\n',
+            'rule test.unsupportedappusage.OtherUnsupportedUsageClass jarjar.prefix.@0\n',
+            'rule test.unsupportedappusage.OtherUnsupportedUsageClassTest jarjar.prefix.@0\n',
+            'rule test.unsupportedappusage.OtherUnsupportedUsageClassTest$* jarjar.prefix.@0\n',
+            'rule test.utils.TestUtilClass jarjar.prefix.@0\n',
+            'rule test.utils.TestUtilClassTest jarjar.prefix.@0\n',
+            'rule test.utils.TestUtilClassTest$* jarjar.prefix.@0\n',
+            'rule test.utils.TestUtilClass$TestInnerClass jarjar.prefix.@0\n',
+            'rule test.utils.TestUtilClass$TestInnerClassTest jarjar.prefix.@0\n',
+            'rule test.utils.TestUtilClass$TestInnerClassTest$* jarjar.prefix.@0\n'
+        ], lines)
+
+    def test_gen_rules_repeated_args(self):
+        args = gen_jarjar.parse_arguments([
+            "jarjar-rules-generator-testjavalib.jar",
+            "--prefix", "jarjar.prefix",
+            "--output", "test-output-rules.txt",
+            "--apistubs", "framework-connectivity.stubs.module_lib.jar",
+            "--apistubs", "framework-connectivity-t.stubs.module_lib.jar",
+            "--unsupportedapi",
+            "testdata/test-unsupportedappusage.txt:testdata/test-other-unsupportedappusage.txt",
+            "--excludes", "testdata/test-jarjar-excludes.txt",
+        ])
+        gen_jarjar.make_jarjar_rules(args)
+
+        with open(args.output) as out:
+            lines = out.readlines()
+
+        self.maxDiff = None
         self.assertListEqual([
             'rule test.utils.TestUtilClass jarjar.prefix.@0\n',
             'rule test.utils.TestUtilClassTest jarjar.prefix.@0\n',
diff --git a/tools/testdata/java/android/net/IpSecTransform.java b/tools/testdata/java/android/net/IpSecTransform.java
new file mode 100644
index 0000000..0140bc5
--- /dev/null
+++ b/tools/testdata/java/android/net/IpSecTransform.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package android.net;
+
+/**
+ * Test class with a name matching a public API in a secondary (framework-connectivity-t) stubs jar.
+ */
+public class IpSecTransform {
+}
diff --git a/tools/testdata/java/test/unsupportedappusage/OtherUnsupportedUsageClass.java b/tools/testdata/java/test/unsupportedappusage/OtherUnsupportedUsageClass.java
new file mode 100644
index 0000000..9d3ae2e0
--- /dev/null
+++ b/tools/testdata/java/test/unsupportedappusage/OtherUnsupportedUsageClass.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package test.unsupportedappusage;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+public class OtherUnsupportedUsageClass {
+    // The annotation is just for completeness, what matters is the unsupportedappusage.txt file
+    @UnsupportedAppUsage
+    public void testSecondMethod() {}
+}
diff --git a/tools/testdata/java/test/unsupportedappusage/TestUnsupportedAppUsageClass.java b/tools/testdata/java/test/unsupportedappusage/TestUnsupportedAppUsageClass.java
index 9d32296..460c91b 100644
--- a/tools/testdata/java/test/unsupportedappusage/TestUnsupportedAppUsageClass.java
+++ b/tools/testdata/java/test/unsupportedappusage/TestUnsupportedAppUsageClass.java
@@ -16,6 +16,11 @@
 
 package test.unsupportedappusage;
 
+
+import android.compat.annotation.UnsupportedAppUsage;
+
 public class TestUnsupportedAppUsageClass {
+    // The annotation is just for completeness, what matters is the unsupportedappusage.txt file
+    @UnsupportedAppUsage
     public void testMethod() {}
 }
diff --git a/tools/testdata/test-other-unsupportedappusage.txt b/tools/testdata/test-other-unsupportedappusage.txt
new file mode 100644
index 0000000..b7d74a4
--- /dev/null
+++ b/tools/testdata/test-other-unsupportedappusage.txt
@@ -0,0 +1 @@
+Ltest/unsupportedappusage/OtherUnsupportedUsageClass;->testSecondMethod()V
\ No newline at end of file