check-flagged-apis: parse flag names and values

Teach check-flagged-apis to parse the parsed_flags protobuf generated by
aconfig.

Note: `m all_aconfig_declarations` generates a protobuf file that
contains all info about all flags.

Bug: 334870672
Test: atest --host check-flagged-apis-test
Test: check-flagged-apis --api-signature out/target/product/mainline_x86/obj/ETC/frameworks-base-api-current.txt_intermediates/frameworks-base-api-current.txt --flag-values out/soong/.intermediates/all_aconfig_declarations.pb
Change-Id: I397b32ae2a373b429ef6ce22e0a06a0f15202b91
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 d7890d7..5fb67be 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
@@ -15,8 +15,11 @@
  */
 package com.android.checkflaggedapis
 
+import android.aconfig.Aconfig
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -33,6 +36,22 @@
 """
         .trim()
 
+private val PARSED_FLAGS =
+    {
+      val parsed_flag =
+          Aconfig.parsed_flag
+              .newBuilder()
+              .setPackage("android.flag")
+              .setName("foo")
+              .setState(Aconfig.flag_state.ENABLED)
+              .setPermission(Aconfig.flag_permission.READ_ONLY)
+              .build()
+      val parsed_flags = Aconfig.parsed_flags.newBuilder().addParsedFlag(parsed_flag).build()
+      val binaryProto = ByteArrayOutputStream()
+      parsed_flags.writeTo(binaryProto)
+      ByteArrayInputStream(binaryProto.toByteArray())
+    }()
+
 @RunWith(DeviceJUnit4ClassRunner::class)
 class CheckFlaggedApisTest : BaseHostJUnit4Test() {
   @Test
@@ -41,4 +60,11 @@
     val actual = parseApiSignature("in-memory", API_SIGNATURE.byteInputStream())
     assertEquals(expected, actual)
   }
+
+  @Test
+  fun testParseFlagValues() {
+    val expected: Map<Flag, Boolean> = mapOf(Flag("android.flag.foo") to true)
+    val actual = parseFlagValues(PARSED_FLAGS)
+    assertEquals(expected, actual)
+  }
 }
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 5fede7b..005f6c0 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
@@ -17,6 +17,7 @@
 
 package com.android.checkflaggedapis
 
+import android.aconfig.Aconfig
 import com.android.tools.metalava.model.BaseItemVisitor
 import com.android.tools.metalava.model.FieldItem
 import com.android.tools.metalava.model.text.ApiFile
@@ -98,6 +99,15 @@
               """)
           .path(mustExist = true, canBeDir = false, mustBeReadable = true)
           .required()
+  private val flagValuesPath by
+      option("--flag-values")
+          .help(
+              """
+            Path to aconfig parsed_flags binary proto file.
+            Tip: `m all_aconfig_declarations` will generate a file that includes all information about all flags.
+            """)
+          .path(mustExist = true, canBeDir = false, mustBeReadable = true)
+          .required()
 
   override fun run() {
     @Suppress("UNUSED_VARIABLE")
@@ -105,6 +115,8 @@
         apiSignaturePath.toFile().inputStream().use {
           parseApiSignature(apiSignaturePath.toString(), it)
         }
+    @Suppress("UNUSED_VARIABLE")
+    val flags = flagValuesPath.toFile().inputStream().use { parseFlagValues(it) }
     throw ProgramResult(0)
   }
 }
@@ -132,4 +144,11 @@
   return output
 }
 
+internal fun parseFlagValues(input: InputStream): Map<Flag, Boolean> {
+  val parsedFlags = Aconfig.parsed_flags.parseFrom(input).getParsedFlagList()
+  return parsedFlags.associateBy(
+      { Flag("${it.getPackage()}.${it.getName()}") },
+      { it.getState() == Aconfig.flag_state.ENABLED })
+}
+
 fun main(args: Array<String>) = CheckCommand().main(args)