Address Android voice-list fingerprint surface
Categories
(Core :: Privacy: Anti-Tracking, 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_ITat position 3 where the canonical Android-15+ version hasis_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
-
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.
-
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 -
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 reportingvoices_count = 28is almost certainly on a Galaxy A52 / A52s / A23 running Android 14;voices_count = 4plus an en-US-only voice sample on a Samsung device pins down a US carrier SKU. -
Samsung SKU suffixes leak through the Bixby TTS variant. LATAM SKUs (
_Msuffix — A135M, A325M, A125M) emit Portuguese-Brazil + Spanish-Mexico voices in their Bixby TTS list. US carrier SKUs (_U/_V/_U1suffix — 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. -
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 = 81and misses these. - LENOVO: highest zero-voice rate (42.99%) — dominated by budget tablets without preinstalled TTS.
- OPPO / OnePlus: share an uncharacterized hash
9833362c16d8at low single-digit %, consistent with them being the same parent company (BBK Electronics). - Fairphone: two distinctive
a0057230d387and389280f707adhashes (~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.
-
voices_defaultisNonefor 100% of Android clients. Android'sTextToSpeech.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. -
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.
Description
•