Commits:
-
d4d29dca
by Beatriz Rizental at 2026-07-28T15:50:37+02:00
BB 45085: [android] Confine GooglePlayIntegrityClient to Components.kt
Uplifting: https://phabricator.services.mozilla.com/D313912
-
584d0657
by Beatriz Rizental at 2026-07-28T15:50:37+02:00
fixup! [android] Disable features and functionality
Bug 45085: Disable GooglePlayIntegrity
-
51b77601
by Beatriz Rizental at 2026-07-28T15:50:37+02:00
fixup! [android] Disable features and functionality
Bug 45134: Return deterministic NIL value for ClientUUID
6 changed files:
Changes:
mobile/android/fenix/app/build.gradle
| ... |
... |
@@ -564,7 +564,6 @@ dependencies { |
|
564
|
564
|
implementation project(':components:lib-push-firebase')
|
|
565
|
565
|
implementation project(':components:lib-state')
|
|
566
|
566
|
implementation project(':components:lib-accelerometer-sensormanager')
|
|
567
|
|
- implementation project(':components:lib-integrity-googleplay')
|
|
568
|
567
|
implementation project(':components:lib-llm-mlpa')
|
|
569
|
568
|
implementation project(':components:lib-shake')
|
|
570
|
569
|
implementation project(':components:lib-ai-controls')
|
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
| ... |
... |
@@ -592,7 +592,7 @@ open class FenixApplication : Application(), Provider, ThemeProvider { |
|
592
|
592
|
}
|
|
593
|
593
|
runOnVisualCompleteness(queue) {
|
|
594
|
594
|
GlobalScope.launch(IO) {
|
|
595
|
|
- components.integrityClient.warmUp()
|
|
|
595
|
+ components.warmUpIntegrityClient()
|
|
596
|
596
|
}
|
|
597
|
597
|
}
|
|
598
|
598
|
}
|
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/ClientUUID.kt
| ... |
... |
@@ -6,8 +6,6 @@ package org.mozilla.fenix.components |
|
6
|
6
|
|
|
7
|
7
|
import android.content.Context
|
|
8
|
8
|
import android.content.SharedPreferences
|
|
9
|
|
-import androidx.core.content.edit
|
|
10
|
|
-import mozilla.components.lib.integrity.googleplay.RequestHashProvider
|
|
11
|
9
|
import mozilla.components.lib.llm.mlpa.UserIdProvider
|
|
12
|
10
|
import mozilla.components.lib.llm.mlpa.service.UserId
|
|
13
|
11
|
import mozilla.components.support.ktx.kotlin.toHexString
|
| ... |
... |
@@ -39,9 +37,15 @@ fun interface Hasher { |
|
39
|
37
|
|
|
40
|
38
|
/**
|
|
41
|
39
|
* Generates and persists a stable per-install UUID, used to identify this client
|
|
42
|
|
- * consistently across [UserIdProvider] and [RequestHashProvider] consumers.
|
|
|
40
|
+ * consistently across [UserIdProvider] consumers and other callers that need a
|
|
|
41
|
+ * stable per-request hash derived from that UUID.
|
|
43
|
42
|
*/
|
|
44
|
|
-interface ClientUUID : UserIdProvider, RequestHashProvider {
|
|
|
43
|
+interface ClientUUID : UserIdProvider {
|
|
|
44
|
+ /**
|
|
|
45
|
+ * Generates a hash derived from the client's stable UUID.
|
|
|
46
|
+ */
|
|
|
47
|
+ fun generateHash(): String
|
|
|
48
|
+
|
|
45
|
49
|
companion object {
|
|
46
|
50
|
/**
|
|
47
|
51
|
* Convenience initializer that creates a [SharedPreferences] to be used by [ClientUUID].
|
| ... |
... |
@@ -62,12 +66,9 @@ internal class PrefsBackedClientUUID( |
|
62
|
66
|
private val generateUUID: () -> String = { UUID.randomUUID().toString() },
|
|
63
|
67
|
private val hasher: Hasher = Hasher.sha256,
|
|
64
|
68
|
) : ClientUUID {
|
|
|
69
|
+ // tor-browser#45134: never expose a unique, trackable per-install identifier.
|
|
65
|
70
|
private val uuid: String by lazy {
|
|
66
|
|
- getPrefs().let { prefs ->
|
|
67
|
|
- prefs.getString(KEY, null) ?: generateUUID().also {
|
|
68
|
|
- prefs.edit { putString(KEY, it) }
|
|
69
|
|
- }
|
|
70
|
|
- }
|
|
|
71
|
+ NIL_UUID
|
|
71
|
72
|
}
|
|
72
|
73
|
|
|
73
|
74
|
override fun getUserId() = UserId(uuid)
|
| ... |
... |
@@ -76,5 +77,6 @@ internal class PrefsBackedClientUUID( |
|
76
|
77
|
|
|
77
|
78
|
companion object {
|
|
78
|
79
|
private const val KEY = "uuid"
|
|
|
80
|
+ private const val NIL_UUID = "00000000-0000-0000-0000-000000000000"
|
|
79
|
81
|
}
|
|
80
|
82
|
} |
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt
| ... |
... |
@@ -19,6 +19,7 @@ import kotlinx.coroutines.MainScope |
|
19
|
19
|
import kotlinx.coroutines.SupervisorJob
|
|
20
|
20
|
import mozilla.components.concept.ai.controls.AIFeatureBlock
|
|
21
|
21
|
import mozilla.components.concept.ai.controls.AIFeatureRegistry
|
|
|
22
|
+import mozilla.components.concept.integrity.IntegrityClient
|
|
22
|
23
|
import mozilla.components.feature.addons.AddonManager
|
|
23
|
24
|
import mozilla.components.feature.addons.amo.AMOAddonsProvider
|
|
24
|
25
|
import mozilla.components.feature.addons.migration.DefaultSupportedAddonsChecker
|
| ... |
... |
@@ -31,7 +32,6 @@ import mozilla.components.lib.ai.controls.dataStore |
|
31
|
32
|
import mozilla.components.lib.ai.controls.default
|
|
32
|
33
|
import mozilla.components.lib.crash.store.CrashAction
|
|
33
|
34
|
import mozilla.components.lib.crash.store.CrashMiddleware
|
|
34
|
|
-import mozilla.components.lib.integrity.googleplay.GooglePlayIntegrityClient
|
|
35
|
35
|
import mozilla.components.lib.llm.mlpa.MlpaTokenStorage
|
|
36
|
36
|
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
|
|
37
|
37
|
import mozilla.components.service.fxrelay.eligibility.RelayEligibilityStore
|
| ... |
... |
@@ -437,14 +437,18 @@ class Components(private val context: Context) { |
|
437
|
437
|
)
|
|
438
|
438
|
}
|
|
439
|
439
|
|
|
440
|
|
- val integrityClient by lazyMonitored {
|
|
441
|
|
- GooglePlayIntegrityClient.create(
|
|
442
|
|
- context = context,
|
|
443
|
|
- projectNumberToken = BuildConfig.GPS_INTEGRITY_TOKEN,
|
|
444
|
|
- requestHashProvider = clientUUID,
|
|
445
|
|
- )
|
|
|
440
|
+ // tor-browser#45085: Disable Google Play Integrity
|
|
|
441
|
+ val integrityClient: IntegrityClient by lazyMonitored {
|
|
|
442
|
+ IntegrityClient { Result.failure(IllegalStateException("Google Play Integrity is disabled")) }
|
|
446
|
443
|
}
|
|
447
|
444
|
|
|
|
445
|
+ /**
|
|
|
446
|
+ * Eagerly initializes the underlying Play Integrity token provider. This is exposed
|
|
|
447
|
+ * separately from [integrityClient] because warm-up is specific to the Google
|
|
|
448
|
+ * Play-backed implementation and isn't part of the [IntegrityClient] concept.
|
|
|
449
|
+ */
|
|
|
450
|
+ suspend fun warmUpIntegrityClient(): Boolean = false // tor-browser#45085: no-op
|
|
|
451
|
+
|
|
448
|
452
|
val termsOfUsePromptRepository by lazyMonitored {
|
|
449
|
453
|
DefaultTermsOfUsePromptRepository(settings)
|
|
450
|
454
|
}
|
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/llm/Llm.kt
| ... |
... |
@@ -5,8 +5,7 @@ |
|
5
|
5
|
package org.mozilla.fenix.components.llm
|
|
6
|
6
|
|
|
7
|
7
|
import mozilla.components.concept.fetch.Client
|
|
8
|
|
-import mozilla.components.lib.integrity.googleplay.GooglePlayIntegrityClient
|
|
9
|
|
-import mozilla.components.lib.integrity.googleplay.IntegrityConsumer
|
|
|
8
|
+import mozilla.components.concept.integrity.IntegrityClient
|
|
10
|
9
|
import mozilla.components.lib.llm.mlpa.MlpaLlmProvider
|
|
11
|
10
|
import mozilla.components.lib.llm.mlpa.MlpaTokenProvider
|
|
12
|
11
|
import mozilla.components.lib.llm.mlpa.MlpaTokenStorage
|
| ... |
... |
@@ -25,7 +24,7 @@ class Llm( |
|
25
|
24
|
private val client: Client,
|
|
26
|
25
|
private val storage: MlpaTokenStorage,
|
|
27
|
26
|
private val fxaTokenProvider: FxaAccessTokenProvider,
|
|
28
|
|
- private val integrityClient: GooglePlayIntegrityClient,
|
|
|
27
|
+ private val integrityClient: IntegrityClient,
|
|
29
|
28
|
private val userIdProvider: UserIdProvider,
|
|
30
|
29
|
) {
|
|
31
|
30
|
|
| ... |
... |
@@ -36,7 +35,7 @@ class Llm( |
|
36
|
35
|
MlpaTokenProvider.choose(
|
|
37
|
36
|
MlpaTokenProvider.fxaTokenProvider(fxaTokenProvider),
|
|
38
|
37
|
MlpaTokenProvider.mlpaIntegrityHandshake(
|
|
39
|
|
- integrityClient = integrityClient.forConsumer(IntegrityConsumer.Summarize),
|
|
|
38
|
+ integrityClient = integrityClient,
|
|
40
|
39
|
authenticationService = fenixMlpaService,
|
|
41
|
40
|
userIdProvider = userIdProvider,
|
|
42
|
41
|
storage = storage,
|
mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/ClientUUIDTest.kt
| ... |
... |
@@ -7,9 +7,25 @@ package org.mozilla.fenix.components |
|
7
|
7
|
import mozilla.components.lib.llm.mlpa.service.UserId
|
|
8
|
8
|
import mozilla.components.support.test.fakes.android.FakeSharedPreferences
|
|
9
|
9
|
import org.junit.Assert.assertEquals
|
|
|
10
|
+import org.junit.Ignore
|
|
10
|
11
|
import org.junit.Test
|
|
11
|
12
|
|
|
12
|
13
|
class ClientUUIDTest {
|
|
|
14
|
+ @Test
|
|
|
15
|
+ fun `that the client uuid is always the nil uuid, regardless of generateUUID`() {
|
|
|
16
|
+ val prefs = FakeSharedPreferences()
|
|
|
17
|
+ val nilUuid = UserId("00000000-0000-0000-0000-000000000000")
|
|
|
18
|
+
|
|
|
19
|
+ val first = PrefsBackedClientUUID({ prefs }, generateUUID = { "my-generated-uuid" })
|
|
|
20
|
+ assertEquals(nilUuid, first.getUserId())
|
|
|
21
|
+ // idempotency check
|
|
|
22
|
+ assertEquals(nilUuid, first.getUserId())
|
|
|
23
|
+
|
|
|
24
|
+ val second = PrefsBackedClientUUID({ prefs }, generateUUID = { "another-generated-uuid" })
|
|
|
25
|
+ assertEquals(nilUuid, second.getUserId())
|
|
|
26
|
+ }
|
|
|
27
|
+
|
|
|
28
|
+ @Ignore("tor-browser#45134: PrefsBackedClientUUID always returns the nil uuid, see the test above")
|
|
13
|
29
|
@Test
|
|
14
|
30
|
fun `that a client uuid will only be generated the first time`() {
|
|
15
|
31
|
val prefs = FakeSharedPreferences()
|
| ... |
... |
@@ -25,6 +41,7 @@ class ClientUUIDTest { |
|
25
|
41
|
assertEquals(UserId("my-generated-uuid"), second.getUserId())
|
|
26
|
42
|
}
|
|
27
|
43
|
|
|
|
44
|
+ @Ignore("tor-browser#45134: PrefsBackedClientUUID always returns the nil uuid, so the hash is no longer derived from generateUUID's output")
|
|
28
|
45
|
@Test
|
|
29
|
46
|
fun `that generateHash uses the provided hasher`() {
|
|
30
|
47
|
val prefs = FakeSharedPreferences()
|
|