Open Bug 2043396 Opened 4 months ago Updated 4 months ago

Address Android voice-list fingerprint surface

Categories

(Core :: Privacy: Anti-Tracking, enhancement)

enhancement

Tracking

()

People

(Reporter: tjr, Unassigned)

References

(Blocks 1 open bug)

Details

Summary

speechSynthesis.getVoices() on Android exposes the user's installed TTS-engine voice list to the web. Because Firefox-Android does not bundle its own engine — it proxies the platform's android.speech.tts.TextToSpeech service — the voice list a user emits is entirely determined by which TTS engine the device manufacturer pre-installed. This produces three dominant cohorts (canonical Google TTS, pre-Android-15 Google TTS, and a zero-voice cohort of devices without any TTS engine) plus a long tail of manufacturer-specific TTS variants that classify the user's device family and regional SKU to a non-trivial degree.

Background

Firefox/Fenix does not bundle a TTS engine on Android. SpeechSynthesis is proxied to the platform's android.speech.tts.TextToSpeech service (Bug 1184142 added the API support; Bug 1463496 enabled it; Bug 1254378 added lazy voice loading). The voice list Firefox reports is therefore whatever the device's pre-installed TTS engine exposes. Two axes drive the per-cohort variation:

  • Which TTS engine the OEM ships. Most Android devices ship Google TTS; many Samsung devices ship Samsung's Bixby Text-to-Speech instead (or alongside, with Bixby as the active engine); post-2019-GMS-ban Huawei devices ship Huawei HMS TTS; some Xiaomi devices ship a Chinese-market variant; budget OEMs sometimes ship no TTS at all to reduce factory footprint.
  • Which version of that engine. Google TTS itself updated its voice catalogue at Android 15 (the pre-Android-15 variant has it_IT at position 3 where the canonical Android-15+ version has is_IS). Bixby TTS has many distinct catalogue versions across Samsung device generations.

The result is a voices_sha1 distribution dominated by three top-level cohorts plus a long tail of vendor / generation / region variants.

Three top-level cohorts

Cohort sha1 voices_count Identity
Google TTS canonical 3300736ade4c… 81 Modern Google TTS catalogue; ships on Android 15+ devices
Google TTS pre-Android-15 4d97a8166c6b… 81 Old Google TTS catalogue; ships on Android 8-14 and on Huawei post-GMS-ban (Huawei's HMS TTS reuses a fork of the pre-2019 Google catalogue)
Zero-voice da39a3ee5e6b… 0 SHA1("") — device has no usable TTS engine installed

The split between canonical and pre-Android-15 is perfectly bimodal at Android API 35: 100% of API 26-34 clients emit the variant hash, 100% of API 35+ clients emit the canonical hash, with only 3 crossover users across 6.34M Android-Google-TTS clients. Conditional on os_version, this distinction contributes ~0 bits of fingerprint information — it's exactly the same as "is this Android ≥15?".

Samsung Bixby TTS family

A non-trivial slice of Android — concentrated on Samsung devices — emits voice-URI formats that are completely different from Google TTS. Where Google TTS produces URIs like #m:en_IN, #m:ar, Samsung Bixby TTS produces URIs in ISO-639-3_ISO-3166_voiceTag format like eng_USA_default, deu_DEU_f00, por_BRA_default. This identifies the engine unambiguously.

There are ~14 distinct Bixby TTS hashes in the population, each tightly mapped to a Samsung device generation × Android version × region:

sha1 voices_count Top Samsung models Top Android API Notes
17510e8e2cd5… 18 SM-G781 (S20 FE), SM-G780 (S20 FE), SM-A515 (A51), SM-G973 (S10), SM-A715 (A71) 33, 31 S10/S20-FE/A51/A71 generation
c1747ace314d… 14 SM-A226 (A22), SM-A127 (A12), SM-A325 (A32), SM-A135 (A13), SM-A505 (A50) 33, 34 Galaxy A-series mid-range int'l
765032b065a2… 28 SM-A528 (A52s), SM-A525 (A52), SM-A236 (A23) 34 only A52-cohort on Android 14
a1db027773a7… 24 SM-A137 (A13), SM-A235 (A23), SM-A136 (A13 5G), SM-A546 (A54), SM-A155 (A15) 34 only A13/A23/A15 cohort
55324669ae2b… 7 SM-A125 (A12), SM-A405 (A40), SM-A415 (A41), SM-A505 (A50), SM-G960 (S9) 31, 30, 29 Older S9/A40-era
4de379be6eff… 9 SM-A217 (A21s), SM-M315 (M31), SM-G950 (S8), SM-M515 (M51), SM-T720 (Tab S5e) 31, 30, 28 Older S8/A21s/M-series
ab565e145bd8… 6 SM-A135M (A13 LATAM), SM-A325M (A32 LATAM), SM-A225M (A22 LATAM), SM-T510 (Tab A) 34, 33 LATAM _M SKU: pt-BR + es-MX voices
6e85f49e587d… 4 SM-G781U/V/U1 (S20 FE US), SM-A326U (A32 5G US) 33, 34 US carrier SKU: en-US + es-US voices
c0d076237b44… 24 SM-T870 (Tab S7), SM-G525 (Xcover 5), SM-T970 (Tab S7+) 33, 34 Tab S7-generation tablets
be01fc542a74… 18 SM-X200 (Tab A8), SM-X205 (Tab A8 LTE) 34 only Tab A8 on Android 14
9ec57a23c05a… 4 SM-G973U (S10 US), SM-G970U (S10e US), SM-A136U (A13 5G US) 31, 33 US carrier S10-era
fbe76e1efaf9… 3 SM-T510 (Tab A 10.1), SM-A217M (A21s LATAM), SM-A125M (A12 LATAM) 31, 30 LATAM minimum Tab A / A12
33dc301ee51a… 1 SM-T500 (Tab A7), SM-A202F (A20e), SM-A115F (A11), SM-M015G (M01 Core) 31, 30 Single-voice (en-US only) on budget Samsung
f89833aca948… 7 SM-T580 (Tab A 10.1 2016), SM-T585, SM-J710 (J7) 27 only Old Bixby — Tab A 2016 / J7 on Android 8.1

The voices_count alone ({1, 3, 4, 6, 7, 9, 14, 18, 22, 24, 28}) is a partial classifier within this family — there's no overlap with Google TTS's 81-voice count or with each other, so it pins down the Samsung device generation / region without needing the full sha1.

Non-Samsung outliers

sha1 voices_count Identity
eca93555417f… 80 Google TTS India-market variant — #m:ar, #m:en_GB, #m:hu_HU, #m:mni_IN, #m:sat_IN, #m:ur_PK (Manipuri + Santali + Urdu-Pakistan, not in the standard catalogue). Top models: very recent Xiaomi 2024-2025 SKUs
b938fb814ce3… 22 Huawei HMS TTS — sample #m:ar, #m:de_IT, #m:en_MY, #m:es_ES, #m:it, #m:pl. Top models: HUAWEI JNY-LX1 (P40 Lite), ELS-NX9 (P40 Pro), AQM-LX1 (Y-series), BAH3-W59 (MediaPad). Distinct from the pre-Android-15 Google TTS fork — Huawei has multiple HMS TTS catalogue variants
b91d5a37fa68… 4 Chinese-market Xiaomi TTS — #m:en, #m:zh, #m:zh__#Hans, #m:zh__#Hant. English + Simplified/Traditional Chinese only

Distribution data

All Android

voices_sha1 (prefix) % of cohort identity
3300736ade4c 55.67% Google TTS canonical (Android 15+, 81 voices)
4d97a8166c6b 15.20% Google TTS pre-Android-15 (81 voices)
da39a3ee5e6b 12.65% voices_count=0 (no TTS engine; SHA1 of empty)
17510e8e2cd5 3.05% Samsung Bixby TTS (S10/S20-FE/A51/A71-era, 18 voices)
c1747ace314d 1.82% Samsung Bixby TTS (A12/A22/A32/A13-era, 14 voices)
765032b065a2 1.24% Samsung Bixby TTS (A52/A52s/A23, 28 voices)
(11,777 more distinct values) 10.37% each < 1% of cohort

samsung

voices_sha1 (prefix) % of cohort identity
3300736ade4c 64.77% Google TTS canonical
17510e8e2cd5 6.67% Samsung Bixby TTS (S10/S20-FE/A51/A71-era, 18 voices)
c1747ace314d 3.99% Samsung Bixby TTS (A12/A22/A32/A13-era, 14 voices)
da39a3ee5e6b 3.94% voices_count=0
765032b065a2 2.71% Samsung Bixby TTS (A52/A52s/A23, 28 voices)
a1db027773a7 1.45% Samsung Bixby TTS (A13/A23/A15, 24 voices)
55324669ae2b 1.41% Samsung Bixby TTS (S9/A40-era, 7 voices)
4de379be6eff 1.24% Samsung Bixby TTS (S8/A21s/M-series, 9 voices)
ab565e145bd8 1.20% Samsung Bixby TTS LATAM _M SKU (6 voices)
6e85f49e587d 1.07% Samsung Bixby TTS US _U/_V SKU (4 voices)
(11,051 more distinct values) 11.54% each < 1% of cohort

Samsung is the manufacturer with the most distinct hashes (11,061 in the long tail) because the Bixby TTS family fragments their users across many device generations and regional SKUs.

Xiaomi

voices_sha1 (prefix) % of cohort identity
3300736ade4c 42.77% Google TTS canonical
4d97a8166c6b 35.04% Google TTS pre-Android-15
da39a3ee5e6b 19.61% voices_count=0
b91d5a37fa68 1.06% Chinese-market Xiaomi TTS (en + zh only, 4 voices)
(339 more distinct values) 1.53% each < 1% of cohort

Xiaomi is structurally simple: it's almost entirely Google TTS (canonical + pre-Android-15) and zero-voice, with a small Chinese-market specialty.

Google (Pixel)

Pixel devices.

voices_sha1 (prefix) % of cohort identity
3300736ade4c 91.09% Google TTS canonical
da39a3ee5e6b 4.46% voices_count=0
4d97a8166c6b 4.02% Google TTS pre-Android-15
(216 more distinct values) 0.42% each < 1% of cohort

Pixels show the cleanest distribution — Google updates Android and Google TTS in lockstep on its own devices, so 91% sit on the canonical hash.

motorola

voices_sha1 (prefix) % of cohort identity
3300736ade4c 53.12% Google TTS canonical
4d97a8166c6b 24.95% Google TTS pre-Android-15
da39a3ee5e6b 20.66% voices_count=0
(158 more distinct values) 1.28% each < 1% of cohort

HUAWEI

Post-2019 GMS ban — most ship without Google services.

voices_sha1 (prefix) % of cohort identity
da39a3ee5e6b 30.52% voices_count=0
4d97a8166c6b 24.81% Google TTS pre-Android-15 (HMS TTS fork of pre-2019 Google catalogue)
b938fb814ce3 10.71% Huawei HMS TTS (P40 Lite/Pro / Y-series, 22 voices)
0567682c27a7 6.83% (uncharacterized — additional HMS TTS variant)
07b0febdd67a 5.75% (uncharacterized — additional HMS TTS variant)
894454194df4 3.47% (uncharacterized)
6b7a84e60328 2.60% (uncharacterized)
8b7693e24282 2.47% (uncharacterized)
e63085074429 2.29% (uncharacterized)
3b7352e19eb1 2.25% (uncharacterized)
38b4c78fb83f 2.02% (uncharacterized)
b91d5a37fa68 1.82% Chinese-market Xiaomi TTS (some Huaweis ship a similar EN+ZH minimum)
(97 more distinct values) 4.47% each < 1% of cohort

HUAWEI is the manufacturer with the most internal-distribution diversity at >1% per cohort — at least 8 uncharacterized HMS TTS variants each carrying 2-7% of HUAWEI clients. This wasn't surfaced by the upstream analysis (which scoped its Huawei investigation to voices_count = 81 and concluded "100% pre-Android-15-Google fork" — that conclusion holds only within the 81-voice subset).

OnePlus

voices_sha1 (prefix) % of cohort identity
3300736ade4c 56.82% Google TTS canonical
4d97a8166c6b 36.41% Google TTS pre-Android-15
da39a3ee5e6b 3.46% voices_count=0
9833362c16d8 1.75% (uncharacterized)
(142 more distinct values) 1.55% each < 1% of cohort

vivo

voices_sha1 (prefix) % of cohort identity
3300736ade4c 52.12% Google TTS canonical
4d97a8166c6b 23.76% Google TTS pre-Android-15
da39a3ee5e6b 15.00% voices_count=0
b6d49f9a3da8 4.70% (uncharacterized — possibly vivo-specific TTS variant)
06c36869a41d 1.10% (uncharacterized)
(128 more distinct values) 3.32% each < 1% of cohort

OPPO

voices_sha1 (prefix) % of cohort identity
3300736ade4c 38.40% Google TTS canonical
4d97a8166c6b 33.06% Google TTS pre-Android-15
da39a3ee5e6b 24.59% voices_count=0
9833362c16d8 1.18% (uncharacterized; shared with OnePlus — these are the same parent company)
(115 more distinct values) 2.77% each < 1% of cohort

realme

voices_sha1 (prefix) % of cohort identity
3300736ade4c 40.58% Google TTS canonical
4d97a8166c6b 34.50% Google TTS pre-Android-15
da39a3ee5e6b 21.15% voices_count=0
(107 more distinct values) 3.76% each < 1% of cohort

HONOR

voices_sha1 (prefix) % of cohort identity
3300736ade4c 62.99% Google TTS canonical
4d97a8166c6b 21.01% Google TTS pre-Android-15
da39a3ee5e6b 12.63% voices_count=0
b98ab82debcf 2.19% (uncharacterized)
(87 more distinct values) 1.17% each < 1% of cohort

LENOVO

Mostly tablets.

voices_sha1 (prefix) % of cohort identity
da39a3ee5e6b 42.99% voices_count=0 (Lenovo budget tablets often ship without Google TTS)
3300736ade4c 34.54% Google TTS canonical
4d97a8166c6b 19.80% Google TTS pre-Android-15
(55 more distinct values) 2.68% each < 1% of cohort

LENOVO has by far the highest zero-voice rate among major manufacturers (42.99%) — consistent with their dominant product mix being budget Android tablets where OEMs reduce factory footprint.

Fairphone

Often runs /e/OS or other de-Googled Android.

voices_sha1 (prefix) % of cohort identity
3300736ade4c 71.66% Google TTS canonical
da39a3ee5e6b 11.89% voices_count=0
4d97a8166c6b 6.36% Google TTS pre-Android-15
a0057230d387 4.67% (uncharacterized — Fairphone / /e/OS-specific TTS)
389280f707ad 4.13% (uncharacterized — Fairphone / /e/OS-specific TTS)
(54 more distinct values) 1.29% each < 1% of cohort

Fairphone is notable for two reasons: (1) most Fairphone users keep Google TTS (71.66% canonical), contrary to the assumption that the de-Googling community uniformly removes GMS; (2) the two Fairphone-distinctive cohorts at ~4-5% each (a0057230d387, 389280f707ad) are not seen at significant share on any other manufacturer — these are almost certainly /e/OS or CalyxOS replacement TTS engines and effectively flag the user as running de-Googled Android.

Observations from the data

  1. Three top-level hashes cover ~83.5% of Android, but the remaining ~16.5% is a structured long tail — not random noise. Most of it is Samsung Bixby TTS variants (which leak Samsung device family × Android version × regional SKU), Huawei HMS TTS variants (at least 8 distinct ones), Chinese-market Xiaomi TTS, /e/OS replacement engines on Fairphone, and miscellaneous vendor-specific TTS.

  2. The Google-TTS-canonical-vs-variant distinction is fully redundant with os_version. The split is perfectly bimodal at Android API 35 (Google updated the TTS catalogue at Android 15), with 3 crossover users across 6.34M clients. A user reporting the variant hash necessarily runs Android ≤14

  3. The voices_count alone is a partial classifier within the Bixby family. Samsung Bixby variants emit voices_count ∈ {1, 3, 4, 6, 7, 9, 14, 18, 22, 24, 28} — distinct from Google TTS's 81 and largely distinct from each other. A Samsung user reporting voices_count = 28 is almost certainly on a Galaxy A52 / A52s / A23 running Android 14; voices_count = 4 plus an en-US-only voice sample on a Samsung device pins down a US carrier SKU.

  4. Samsung SKU suffixes leak through the Bixby TTS variant. LATAM SKUs (_M suffix — A135M, A325M, A125M) emit Portuguese-Brazil + Spanish-Mexico voices in their Bixby TTS list. US carrier SKUs (_U/_V/_U1 suffix — G781U, G781V, A326U, G973U) emit English-US + Spanish-US-only Bixby TTS lists. So even without consulting the model name, the voices_sha1 partitions Samsung users by region/carrier.

  5. Manufacturer-level distribution patterns:

    • Pixels (Google): highest canonical concentration (91.09%). Pixels update Android and Google TTS in lockstep.
    • Samsung: most diverse (11,061 distinct hashes in the long tail) because of the Bixby TTS variants.
    • HUAWEI: most internal-cohort diversity at >1% per cohort — at least 8 uncharacterized HMS TTS variants. The upstream analysis's "100% pre-Android-15 Google fork on Huawei" claim was scoped to voices_count = 81 and misses these.
    • LENOVO: highest zero-voice rate (42.99%) — dominated by budget tablets without preinstalled TTS.
    • OPPO / OnePlus: share an uncharacterized hash 9833362c16d8 at low single-digit %, consistent with them being the same parent company (BBK Electronics).
    • Fairphone: two distinctive a0057230d387 and 389280f707ad hashes (~4-5% each) that don't appear at meaningful share elsewhere — almost certainly /e/OS / CalyxOS replacement TTS engines, effectively a de-Googled-Android flag.
  6. voices_default is None for 100% of Android clients. Android's TextToSpeech.getDefaultVoice() semantics don't map onto Firefox's default-detection path, so the field is uniformly empty across all Android clients regardless of which engine they have. It carries 0 bits.

  7. The zero-voice cohort is non-uniform across manufacturers. Lenovo at 43%, OPPO at 25%, motorola at 21%, realme at 21%, Xiaomi at 20% (these mostly reflect budget devices). Pixel at 4%, Samsung at 4% (flagship-heavy populations preinstall TTS). HUAWEI at 31% is mixed — partly post-GMS-ban devices with no TTS engine reachable, partly older devices.

You need to log in before you can comment on or make changes to this bug.