Merge "Show release-config's stderr" into main
diff --git a/core/soong_config.mk b/core/soong_config.mk
index acd213c..7300e8c 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -174,6 +174,10 @@
 $(foreach flag,$(_ALL_RELEASE_FLAGS),\
   $(call add_json_str,$(flag),$(_ALL_RELEASE_FLAGS.$(flag).VALUE)))
 $(call end_json_map)
+$(call add_json_map,  BuildFlagTypes)
+$(foreach flag,$(_ALL_RELEASE_FLAGS),\
+  $(call add_json_str,$(flag),$(_ALL_RELEASE_FLAGS.$(flag).TYPE)))
+$(call end_json_map)
 
 $(call add_json_bool, DirectedVendorSnapshot,            $(DIRECTED_VENDOR_SNAPSHOT))
 $(call add_json_map,  VendorSnapshotModules)
diff --git a/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt b/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
index 111ea91..8e285f6 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
@@ -121,6 +121,26 @@
   }
 
   @Test
+  fun testParseApiSignatureInterfacesInheritFromJavaLangObject() {
+    val apiSignature =
+        """
+          // Signature format: 2.0
+          package android {
+            @FlaggedApi("android.flag.foo") public interface Interface {
+            }
+          }
+        """
+            .trim()
+    val expected =
+        setOf(
+            Pair(
+                Symbol.createClass("android/Interface", "java/lang/Object", setOf()),
+                Flag("android.flag.foo")))
+    val actual = parseApiSignature("in-memory", apiSignature.byteInputStream())
+    assertEquals(expected, actual)
+  }
+
+  @Test
   fun testParseFlagValues() {
     val expected: Map<Flag, Boolean> =
         mapOf(Flag("android.flag.foo") to true, Flag("android.flag.bar") to true)
diff --git a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
index a277ce8..1d2440d 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
@@ -205,7 +205,11 @@
             val symbol =
                 Symbol.createClass(
                     cls.baselineElementId(),
-                    cls.superClass()?.baselineElementId(),
+                    if (cls.isInterface()) {
+                      "java/lang/Object"
+                    } else {
+                      cls.superClass()?.baselineElementId()
+                    },
                     cls.allInterfaces()
                         .map { it.baselineElementId() }
                         .filter { it != cls.baselineElementId() }
diff --git a/tools/perf/format_benchmarks b/tools/perf/format_benchmarks
index 26493b2..807e546 100755
--- a/tools/perf/format_benchmarks
+++ b/tools/perf/format_benchmarks
@@ -25,6 +25,7 @@
 import pathlib
 import statistics
 import zoneinfo
+import csv
 
 import pretty
 import utils
@@ -103,7 +104,7 @@
     def SetFixedCol(self, row_key, columns):
         self._fixed_cols[row_key] = columns
 
-    def Write(self, out):
+    def Write(self, out, fmt):
         table = []
         # Expand the column items
         for row in zip(*self._cols):
@@ -114,26 +115,33 @@
             # Update the last row of the header with title and add separator
             for i in range(len(self._titles)):
                 table[len(table)-1][i] = self._titles[i]
-            table.append(pretty.SEPARATOR)
+            if fmt == "table":
+                table.append(pretty.SEPARATOR)
         # Populate the data
         for row in self._rows:
             table.append([str(row)]
                          + self._fixed_cols[row]
                          + [str(self._data.get((col, row), "")) for col in self._cols])
-        out.write(pretty.FormatTable(table, alignments="LL"))
+        if fmt == "csv":
+            csv.writer(sys.stdout, quoting=csv.QUOTE_MINIMAL).writerows(table)
+        else:
+            out.write(pretty.FormatTable(table, alignments="LL"))
 
 
-def format_duration_sec(ns):
+def format_duration_sec(ns, fmt_sec):
     "Format a duration in ns to second precision"
     sec = round(ns / 1000000000)
-    h, sec = divmod(sec, 60*60)
-    m, sec = divmod(sec, 60)
-    result = ""
-    if h > 0:
-        result += f"{h:2d}h "
-    if h > 0 or m > 0:
-        result += f"{m:2d}m "
-    return result + f"{sec:2d}s"
+    if fmt_sec:
+        return f"{sec}"
+    else:
+        h, sec = divmod(sec, 60*60)
+        m, sec = divmod(sec, 60)
+        result = ""
+        if h > 0:
+            result += f"{h:2d}h "
+        if h > 0 or m > 0:
+            result += f"{m:2d}m "
+        return result + f"{sec:2d}s"
 
 
 def main(argv):
@@ -142,6 +150,12 @@
             allow_abbrev=False, # Don't let people write unsupportable scripts.
             description="Print analysis tables for benchmarks")
 
+    parser.add_argument("--csv", action="store_true",
+                        help="Print in CSV instead of table.")
+
+    parser.add_argument("--sec", action="store_true",
+                        help="Print in seconds instead of minutes and seconds")
+
     parser.add_argument("--tags", nargs="*",
                         help="The tags to print, in order.")
 
@@ -196,9 +210,9 @@
                                  summary["branch"],
                                  summary["tag"]]
                                 + list(key)),
-                          cell[0]["title"], format_duration_sec(duration_ns))
+                          cell[0]["title"], format_duration_sec(duration_ns, args.sec))
 
-    table.Write(sys.stdout)
+    table.Write(sys.stdout, "csv" if args.csv else "table")
 
 if __name__ == "__main__":
     main(sys.argv)