Record fact-sheet permissions and use the Google services label.

This commit is contained in:
franzap
2026-09-28 18:06:48 -03:00
parent 64224659d0
commit 324a854188
5 changed files with 18 additions and 15 deletions
@@ -108,7 +108,7 @@ class AppRecord(
/**
* [facts] in file order, one row per key.
* The file is a CSV with columns fact, value, and reason.
* The file is a quoted CSV with columns fact, value, reason, and permissions.
* The sheet repeats a key once per library. A yes wins over a no.
*/
val factRows: List<AppFact>
@@ -129,6 +129,7 @@ internal fun parseFactRows(facts: String): List<AppFact> {
val factIdx = header.indexOf("fact")
val valueIdx = header.indexOf("value")
val reasonIdx = header.indexOf("reason")
val permissionsIdx = header.indexOf("permissions")
if (factIdx < 0 || valueIdx < 0) return emptyList()
val rows = LinkedHashMap<String, AppFact>()
for (record in table.drop(1)) {
@@ -140,11 +141,13 @@ internal fun parseFactRows(facts: String): List<AppFact> {
else -> continue
}
val reason = if (reasonIdx < 0) "" else record.getOrNull(reasonIdx)?.trim().orEmpty()
val permissions = if (permissionsIdx < 0) "" else record.getOrNull(permissionsIdx)?.trim().orEmpty()
val previous = rows[key]
rows[key] = AppFact(
key = key,
yes = previous?.yes == true || yes,
reason = reason.ifBlank { previous?.reason.orEmpty() },
permissions = permissions.ifBlank { previous?.permissions.orEmpty() },
)
}
return rows.values.toList()
@@ -201,6 +204,7 @@ data class AppFact(
val key: String,
val yes: Boolean,
val reason: String = "",
val permissions: String = "",
)
/** Kind 0 projection. `name`/`displayName` are already trimmed to non-blank. */
@@ -11,17 +11,18 @@ class CatalogArtifactsTest {
@Test
fun parsesFactCsvAndKeepsReason() {
val rows = parseFactRows(
"fact,value,reason\n" +
"gms,no,\"no play services, com.google\"\n" +
"gms,yes,\n" +
"fcm,yes,\"uses, cloud\"\n",
"\"fact\",\"value\",\"reason\",\"permissions\"\n" +
"\"google_services\",\"no\",\"Play services\",\"\"\n" +
"\"google_services\",\"yes\",\"Firebase Cloud Messaging\",\"\"\n" +
"\"location\",\"yes\",\"the map screen\",\"ACCESS_BACKGROUND_LOCATION,ACCESS_FINE_LOCATION\"\n",
)
assertEquals(2, rows.size)
assertEquals("gms", rows[0].key)
assertEquals("google_services", rows[0].key)
assertTrue(rows[0].yes)
assertEquals("no play services, com.google", rows[0].reason)
assertEquals("fcm", rows[1].key)
assertEquals("uses, cloud", rows[1].reason)
assertEquals("Firebase Cloud Messaging", rows[0].reason)
assertEquals("location", rows[1].key)
assertEquals("the map screen", rows[1].reason)
assertEquals("ACCESS_BACKGROUND_LOCATION,ACCESS_FINE_LOCATION", rows[1].permissions)
}
@Test
@@ -373,8 +373,7 @@ private fun FactPill(key: String, yes: Boolean) {
@Composable
private fun factLabel(key: String): String = when (key) {
"gms" -> stringResource(R.string.fact_gms)
"fcm" -> stringResource(R.string.fact_fcm)
"google_services" -> stringResource(R.string.fact_google_services)
"open_source" -> stringResource(R.string.fact_open_source)
"e2ee" -> "E2EE"
else -> key.replace('_', ' ').replaceFirstChar { it.titlecase() }
+1 -2
View File
@@ -71,9 +71,8 @@
<string name="copy">Copy</string>
<string name="privacy_and_security">Privacy and security</string>
<string name="fact_no">No %1$s</string>
<string name="fact_gms">Google Play services</string>
<string name="fact_google_services">Google services</string>
<string name="fact_open_source">Verified open source</string>
<string name="fact_fcm">Firebase Cloud Messaging</string>
<string name="app_icon_description">%1$s icon</string>
<string name="screenshot_description">%1$s screenshot</string>
<string name="profile_avatar_description">%1$s avatar</string>
@@ -8,8 +8,8 @@ import org.junit.Test
class FactPillTest {
@Test
fun antifeatureAbsenceIsPositiveAndPresenceIsNot() {
assertTrue(factIsPositive("gms", yes = false))
assertFalse(factIsPositive("gms", yes = true))
assertTrue(factIsPositive("google_services", yes = false))
assertFalse(factIsPositive("google_services", yes = true))
assertFalse(factIsPositive("account_required", yes = true))
assertTrue(factIsPositive("tracking", yes = false))
}