fenix-liberate.patch raw
1 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
2 index 1c7225db5d34..2b18b3eee978 100644
3 --- a/gradle/libs.versions.toml
4 +++ b/gradle/libs.versions.toml
5 @@ -51,16 +51,10 @@ work = "2.11.1"
6
7 # Google other
8 accompanist = "0.37.3"
9 -firebase-messaging = "25.0.1"
10 installreferrer = "2.2"
11 ksp = "2.3.6"
12 material = "1.13.0"
13 osslicenses-plugin = "0.10.10"
14 -play-integrity = "1.6.0"
15 -play-review = "2.0.2"
16 -play-services-ads-id = "18.3.0"
17 -play-services-base = "18.10.0"
18 -play-services-fido = "21.2.0"
19 protobuf = "4.33.2" # Keep Protobuf in sync with the version used by AppServices.
20
21 # Gradle plugins
22 @@ -120,7 +114,6 @@ kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref =
23 kotlin-serialization = { module = "org.jetbrains.kotlin.plugin.serialization:org.jetbrains.kotlin.plugin.serialization.gradle.plugin", version.ref = "kotlin" }
24 kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" }
25 kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
26 -kotlinx-coroutines-play-services = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-play-services", version.ref = "coroutines" }
27 kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }
28 kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" }
29
30 @@ -210,7 +203,6 @@ androidx-compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling
31
32 # Google other
33 accompanist-drawablepainter = { module = "com.google.accompanist:accompanist-drawablepainter", version.ref = "accompanist" }
34 -firebase-messaging = { module = "com.google.firebase:firebase-messaging", version.ref = "firebase-messaging" }
35 google-material = { module = "com.google.android.material:material", version.ref = "material" }
36 installreferrer = { module = "com.android.installreferrer:installreferrer", version.ref = "installreferrer" }
37 ksp-symbol-processing-aa = { module = "com.google.devtools.ksp:symbol-processing-aa", version.ref = "ksp" }
38 @@ -219,12 +211,6 @@ ksp-symbol-processing-api = { module = "com.google.devtools.ksp:symbol-processin
39 ksp-symbol-processing-common-deps = { module = "com.google.devtools.ksp:symbol-processing-common-deps", version.ref = "ksp" }
40 mlkit-prompt = { module = "com.google.mlkit:genai-prompt", version = "1.0.0-alpha1" }
41 osslicenses-plugin = { module = "com.google.android.gms:oss-licenses-plugin", version.ref = "osslicenses-plugin" }
42 -play-integrity = { module = "com.google.android.play:integrity", version.ref = "play-integrity" }
43 -play-review = { module = "com.google.android.play:review", version.ref = "play-review" }
44 -play-review-ktx = { module = "com.google.android.play:review-ktx", version.ref = "play-review" }
45 -play-services-ads-id = { module = "com.google.android.gms:play-services-ads-identifier", version.ref = "play-services-ads-id" }
46 -play-services-base = { module = "com.google.android.gms:play-services-base", version.ref = "play-services-base" }
47 -play-services-fido = { module = "com.google.android.gms:play-services-fido", version.ref = "play-services-fido" }
48 protobuf-compiler = { module = "com.google.protobuf:protoc", version.ref = "protobuf" }
49 protobuf-javalite = { module = "com.google.protobuf:protobuf-javalite", version.ref = "protobuf" }
50
51 diff --git a/mobile/android/android-components/.buildconfig.yml b/mobile/android/android-components/.buildconfig.yml
52 index c26c00fa5a13..ff79084820f0 100644
53 --- a/mobile/android/android-components/.buildconfig.yml
54 +++ b/mobile/android/android-components/.buildconfig.yml
55 @@ -1769,18 +1769,6 @@ projects:
56 - components:support-test
57 - components:tooling-fetch-tests
58 - components:tooling-lint
59 - components:lib-integrity-googleplay:
60 - description: A library for verifying the integrity of an installation using Google
61 - Play
62 - path: components/lib/integrity-googleplay
63 - publish: true
64 - upstream_dependencies:
65 - - components:concept-base
66 - - components:concept-fetch
67 - - components:concept-integrity
68 - - components:support-base
69 - - components:support-test
70 - - components:tooling-lint
71 components:lib-jexl:
72 description: 'Javascript Expression Language: Powerful context-based expression
73 parser and evaluator.'
74 @@ -1821,17 +1809,6 @@ projects:
75 - components:support-base
76 - components:support-test
77 - components:tooling-lint
78 - components:lib-push-firebase:
79 - description: An implementation of concept-push for the Firebase Message Service.
80 - path: components/lib/push-firebase
81 - publish: true
82 - upstream_dependencies:
83 - - components:concept-base
84 - - components:concept-fetch
85 - - components:concept-push
86 - - components:support-base
87 - - components:support-test
88 - - components:tooling-lint
89 components:lib-shake:
90 description: A library to detect shake gestures from accelerometer data
91 path: components/lib/shake
92 diff --git a/mobile/android/fenix/.buildconfig.yml b/mobile/android/fenix/.buildconfig.yml
93 index 7d6b48243700..5e94d59bfa5e 100644
94 --- a/mobile/android/fenix/.buildconfig.yml
95 +++ b/mobile/android/fenix/.buildconfig.yml
96 @@ -69,10 +69,8 @@ projects:
97 - components:lib-crash
98 - components:lib-crash-sentry
99 - components:lib-dataprotect
100 - - components:lib-integrity-googleplay
101 - components:lib-llm-mlpa
102 - components:lib-publicsuffixlist
103 - - components:lib-push-firebase
104 - components:lib-shake
105 - components:lib-state
106 - components:service-digitalassetlinks
107 diff --git a/mobile/android/fenix/app/build.gradle b/mobile/android/fenix/app/build.gradle
108 index 4930620b7123..552003446b24 100644
109 --- a/mobile/android/fenix/app/build.gradle
110 +++ b/mobile/android/fenix/app/build.gradle
111 @@ -623,16 +623,13 @@ dependencies {
112 implementation project(':components:lib-crash')
113 implementation project(':components:lib-crash-sentry')
114 implementation project(':components:lib-dataprotect')
115 - implementation project(':components:lib-push-firebase')
116 implementation project(':components:lib-state')
117 implementation project(':components:lib-accelerometer-sensormanager')
118 - implementation project(':components:lib-integrity-googleplay')
119 implementation project(':components:lib-llm-mlpa')
120 implementation project(':components:lib-shake')
121
122 implementation ComponentsDependencies.mozilla_appservices_syncmanager
123 implementation libs.accompanist.drawablepainter
124 - implementation libs.adjust
125 implementation libs.androidx.activity
126 implementation libs.androidx.activity.ktx
127 implementation libs.androidx.annotation
128 @@ -679,16 +676,14 @@ dependencies {
129 implementation libs.androidx.viewpager2
130 implementation libs.androidx.work.runtime
131 implementation libs.google.material
132 - implementation libs.installreferrer
133 implementation libs.kotlinx.coroutines
134 implementation libs.kotlinx.serialization.json
135 implementation libs.mozilla.glean
136 - implementation libs.play.review
137 - implementation libs.play.review.ktx
138 - implementation libs.play.services.ads.id
139 implementation libs.protobuf.javalite
140 implementation libs.sentry
141
142 + implementation 'org.microg.gms:play-services-ads-identifier:0.3.13.250932'
143 +
144 debugImplementation libs.androidx.compose.ui.tooling
145 debugImplementation libs.leakcanary
146
147 diff --git a/mobile/android/fenix/app/proguard-rules.pro b/mobile/android/fenix/app/proguard-rules.pro
148 index 39a6df6fb62e..86ee82a027dc 100644
149 --- a/mobile/android/fenix/app/proguard-rules.pro
150 +++ b/mobile/android/fenix/app/proguard-rules.pro
151 @@ -28,3 +28,11 @@
152
153 # Keep code generated from Glean Metrics
154 -keep class org.mozilla.fenix.GleanMetrics.** { *; }
155 +
156 +####################################################################################################
157 +# Checker Framework
158 +####################################################################################################
159 +
160 +-dontwarn org.checkerframework.checker.nullness.qual.EnsuresNonNull
161 +-dontwarn org.checkerframework.checker.nullness.qual.EnsuresNonNullIf
162 +-dontwarn org.checkerframework.checker.nullness.qual.RequiresNonNull
163 diff --git a/mobile/android/fenix/app/src/main/java/com/adjust/sdk/Adjust.java b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/Adjust.java
164 new file mode 100644
165 index 000000000000..1bafc51be64e
166 --- /dev/null
167 +++ b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/Adjust.java
168 @@ -0,0 +1,55 @@
169 +/*
170 + * Copyright (c) 2012-2017 adjust GmbH,
171 + * http://www.adjust.com
172 + *
173 + * Permission is hereby granted, free of charge, to any person obtaining
174 + * a copy of this software and associated documentation files (the
175 + * "Software"), to deal in the Software without restriction, including
176 + * without limitation the rights to use, copy, modify, merge, publish,
177 + * distribute, sublicense, and/or sell copies of the Software, and to
178 + * permit persons to whom the Software is furnished to do so, subject to
179 + * the following conditions:
180 + *
181 + * The above copyright notice and this permission notice shall be
182 + * included in all copies or substantial portions of the Software.
183 + *
184 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
185 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
186 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
187 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
188 + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
189 + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
190 + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
191 + */
192 +
193 +package com.adjust.sdk;
194 +
195 +import android.content.Context;
196 +
197 +public class Adjust {
198 + public static void initSdk(AdjustConfig adjustConfig) {
199 + }
200 +
201 + public static void trackEvent(AdjustEvent event) {
202 + }
203 +
204 + public static void onResume() {
205 + }
206 +
207 + public static void onPause() {
208 + }
209 +
210 + public static void enable() {
211 + }
212 +
213 + public static void disable() {
214 + }
215 +
216 + public static void gdprForgetMe(final Context context) {
217 + }
218 +
219 + public static void trackThirdPartySharing(
220 + final AdjustThirdPartySharing adjustThirdPartySharing)
221 + {
222 + }
223 +}
224 diff --git a/mobile/android/fenix/app/src/main/java/com/adjust/sdk/AdjustAttribution.java b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/AdjustAttribution.java
225 new file mode 100644
226 index 000000000000..ab6b3badbdb1
227 --- /dev/null
228 +++ b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/AdjustAttribution.java
229 @@ -0,0 +1,49 @@
230 +/*
231 + * Copyright (c) 2012-2017 adjust GmbH,
232 + * http://www.adjust.com
233 + *
234 + * Permission is hereby granted, free of charge, to any person obtaining
235 + * a copy of this software and associated documentation files (the
236 + * "Software"), to deal in the Software without restriction, including
237 + * without limitation the rights to use, copy, modify, merge, publish,
238 + * distribute, sublicense, and/or sell copies of the Software, and to
239 + * permit persons to whom the Software is furnished to do so, subject to
240 + * the following conditions:
241 + *
242 + * The above copyright notice and this permission notice shall be
243 + * included in all copies or substantial portions of the Software.
244 + *
245 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
246 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
247 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
248 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
249 + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
250 + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
251 + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
252 + */
253 +
254 +package com.adjust.sdk;
255 +
256 +import java.io.Serializable;
257 +
258 +public class AdjustAttribution implements Serializable {
259 + public String network;
260 + public String campaign;
261 + public String adgroup;
262 + public String creative;
263 +
264 + @Override
265 + public boolean equals(Object other) {
266 + return false;
267 + }
268 +
269 + @Override
270 + public int hashCode() {
271 + return 0;
272 + }
273 +
274 + @Override
275 + public String toString() {
276 + return "";
277 + }
278 +}
279 diff --git a/mobile/android/fenix/app/src/main/java/com/adjust/sdk/AdjustConfig.java b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/AdjustConfig.java
280 new file mode 100644
281 index 000000000000..df58236bc456
282 --- /dev/null
283 +++ b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/AdjustConfig.java
284 @@ -0,0 +1,52 @@
285 +/*
286 + * Copyright (c) 2012-2017 adjust GmbH,
287 + * http://www.adjust.com
288 + *
289 + * Permission is hereby granted, free of charge, to any person obtaining
290 + * a copy of this software and associated documentation files (the
291 + * "Software"), to deal in the Software without restriction, including
292 + * without limitation the rights to use, copy, modify, merge, publish,
293 + * distribute, sublicense, and/or sell copies of the Software, and to
294 + * permit persons to whom the Software is furnished to do so, subject to
295 + * the following conditions:
296 + *
297 + * The above copyright notice and this permission notice shall be
298 + * included in all copies or substantial portions of the Software.
299 + *
300 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
301 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
302 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
303 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
304 + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
305 + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
306 + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
307 + */
308 +
309 +package com.adjust.sdk;
310 +
311 +import android.content.Context;
312 +
313 +import java.util.List;
314 +
315 +public class AdjustConfig {
316 + public static final String ENVIRONMENT_SANDBOX = "sandbox";
317 + public static final String ENVIRONMENT_PRODUCTION = "production";
318 +
319 + public AdjustConfig(Context context, String appToken, String environment) {
320 + }
321 +
322 + public AdjustConfig(Context context, String appToken, String environment, boolean allowSuppressLogLevel) {
323 + }
324 +
325 + public void setOnAttributionChangedListener(OnAttributionChangedListener onAttributionChangedListener) {
326 + }
327 +
328 + public void enablePreinstallTracking() {
329 + }
330 +
331 + public void setLogLevel(LogLevel logLevel) {
332 + }
333 +
334 + public void enableCoppaCompliance() {
335 + }
336 +}
337 diff --git a/mobile/android/fenix/app/src/main/java/com/adjust/sdk/AdjustEvent.java b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/AdjustEvent.java
338 new file mode 100644
339 index 000000000000..0b4d80ed4b2c
340 --- /dev/null
341 +++ b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/AdjustEvent.java
342 @@ -0,0 +1,31 @@
343 +package com.adjust.sdk;
344 +
345 +/**
346 + * Created by pfms on 05/11/14.
347 + */
348 +public class AdjustEvent {
349 +
350 + public AdjustEvent(String eventToken) {
351 + }
352 +
353 + public void setRevenue(double revenue, String currency) {
354 + }
355 +
356 + public void addCallbackParameter(String key, String value) {
357 + }
358 +
359 + public void addPartnerParameter(String key, String value) {
360 + }
361 +
362 + public void setOrderId(String orderId) {
363 + }
364 +
365 + public void setCallbackId(String callbackId) {
366 + }
367 +
368 + public void setProductId(String productId) {
369 + }
370 +
371 + public void setPurchaseToken(String purchaseToken) {
372 + }
373 +}
374 diff --git a/mobile/android/fenix/app/src/main/java/com/adjust/sdk/AdjustThirdPartySharing.java b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/AdjustThirdPartySharing.java
375 new file mode 100644
376 index 000000000000..1a8314dae0a1
377 --- /dev/null
378 +++ b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/AdjustThirdPartySharing.java
379 @@ -0,0 +1,13 @@
380 +package com.adjust.sdk;
381 +
382 +public class AdjustThirdPartySharing {
383 +
384 + public AdjustThirdPartySharing(final Boolean isEnabled) {
385 + }
386 +
387 + public void addPartnerSharingSetting(final String partnerName,
388 + final String key,
389 + final boolean value)
390 + {
391 + }
392 +}
393 diff --git a/mobile/android/fenix/app/src/main/java/com/adjust/sdk/Constants.java b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/Constants.java
394 new file mode 100644
395 index 000000000000..bfaeee26e8e1
396 --- /dev/null
397 +++ b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/Constants.java
398 @@ -0,0 +1,18 @@
399 +//
400 +// Constants.java
401 +// Adjust
402 +//
403 +// Created by keyboardsurfer on 2013-11-08.
404 +// Copyright (c) 2012-2014 adjust GmbH. All rights reserved.
405 +// See the file MIT-LICENSE for copying permission.
406 +//
407 +
408 +package com.adjust.sdk;
409 +
410 +/**
411 + * @author keyboardsurfer
412 + * @since 8.11.13
413 + */
414 +public interface Constants {
415 + String ADJUST_PREINSTALL_SYSTEM_PROPERTY_PATH = "adjust.preinstall.path";
416 +}
417 diff --git a/mobile/android/fenix/app/src/main/java/com/adjust/sdk/LogLevel.java b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/LogLevel.java
418 new file mode 100644
419 index 000000000000..f4ef17f4c492
420 --- /dev/null
421 +++ b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/LogLevel.java
422 @@ -0,0 +1,43 @@
423 +/*
424 + * Copyright (c) 2012-2017 adjust GmbH,
425 + * http://www.adjust.com
426 + *
427 + * Permission is hereby granted, free of charge, to any person obtaining
428 + * a copy of this software and associated documentation files (the
429 + * "Software"), to deal in the Software without restriction, including
430 + * without limitation the rights to use, copy, modify, merge, publish,
431 + * distribute, sublicense, and/or sell copies of the Software, and to
432 + * permit persons to whom the Software is furnished to do so, subject to
433 + * the following conditions:
434 + *
435 + * The above copyright notice and this permission notice shall be
436 + * included in all copies or substantial portions of the Software.
437 + *
438 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
439 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
440 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
441 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
442 + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
443 + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
444 + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
445 + */
446 +
447 +package com.adjust.sdk;
448 +
449 +import android.util.Log;
450 +
451 +/**
452 + * Created by pfms on 11/03/15.
453 + */
454 +public enum LogLevel {
455 + VERBOSE(Log.VERBOSE), DEBUG(Log.DEBUG), INFO(Log.INFO), WARN(Log.WARN), ERROR(Log.ERROR), ASSERT(Log.ASSERT), SUPPRESS(8);
456 + final int androidLogLevel;
457 +
458 + LogLevel(final int androidLogLevel) {
459 + this.androidLogLevel = androidLogLevel;
460 + }
461 +
462 + public int getAndroidLogLevel() {
463 + return androidLogLevel;
464 + }
465 +}
466 diff --git a/mobile/android/fenix/app/src/main/java/com/adjust/sdk/OnAttributionChangedListener.java b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/OnAttributionChangedListener.java
467 new file mode 100644
468 index 000000000000..7efa1c6804c6
469 --- /dev/null
470 +++ b/mobile/android/fenix/app/src/main/java/com/adjust/sdk/OnAttributionChangedListener.java
471 @@ -0,0 +1,29 @@
472 +/*
473 + * Copyright (c) 2012-2017 adjust GmbH,
474 + * http://www.adjust.com
475 + *
476 + * Permission is hereby granted, free of charge, to any person obtaining
477 + * a copy of this software and associated documentation files (the
478 + * "Software"), to deal in the Software without restriction, including
479 + * without limitation the rights to use, copy, modify, merge, publish,
480 + * distribute, sublicense, and/or sell copies of the Software, and to
481 + * permit persons to whom the Software is furnished to do so, subject to
482 + * the following conditions:
483 + *
484 + * The above copyright notice and this permission notice shall be
485 + * included in all copies or substantial portions of the Software.
486 + *
487 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
488 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
489 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
490 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
491 + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
492 + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
493 + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
494 + */
495 +
496 +package com.adjust.sdk;
497 +
498 +public interface OnAttributionChangedListener {
499 + void onAttributionChanged(AdjustAttribution attribution);
500 +}
501 diff --git a/mobile/android/fenix/app/src/main/java/com/google/firebase/messaging/FirebaseMessagingService.java b/mobile/android/fenix/app/src/main/java/com/google/firebase/messaging/FirebaseMessagingService.java
502 new file mode 100644
503 index 000000000000..4d5fd8153d21
504 --- /dev/null
505 +++ b/mobile/android/fenix/app/src/main/java/com/google/firebase/messaging/FirebaseMessagingService.java
506 @@ -0,0 +1,42 @@
507 +// Copyright 2020 Google LLC
508 +//
509 +// Licensed under the Apache License, Version 2.0 (the "License");
510 +// you may not use this file except in compliance with the License.
511 +// You may obtain a copy of the License at
512 +//
513 +// http://www.apache.org/licenses/LICENSE-2.0
514 +//
515 +// Unless required by applicable law or agreed to in writing, software
516 +// distributed under the License is distributed on an "AS IS" BASIS,
517 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
518 +// See the License for the specific language governing permissions and
519 +// limitations under the License.
520 +package com.google.firebase.messaging;
521 +
522 +import android.app.Service;
523 +import android.content.Intent;
524 +import android.os.Binder;
525 +import android.os.IBinder;
526 +
527 +public class FirebaseMessagingService extends Service {
528 +
529 + private final IBinder mBinder = new Binder();
530 +
531 + public void onMessageReceived(RemoteMessage message) {
532 + }
533 +
534 + public void onMessageSent(String msgId) {
535 + }
536 +
537 + public void onNewToken(String token) {
538 + }
539 +
540 + public void onSendError(String msgId, Exception exception) {
541 + }
542 +
543 + @Override
544 + public IBinder onBind(Intent intent) {
545 + return mBinder;
546 + }
547 +
548 +}
549 diff --git a/mobile/android/fenix/app/src/main/java/com/google/firebase/messaging/RemoteMessage.java b/mobile/android/fenix/app/src/main/java/com/google/firebase/messaging/RemoteMessage.java
550 new file mode 100644
551 index 000000000000..9ad59a31e43c
552 --- /dev/null
553 +++ b/mobile/android/fenix/app/src/main/java/com/google/firebase/messaging/RemoteMessage.java
554 @@ -0,0 +1,33 @@
555 +// Copyright 2020 Google LLC
556 +//
557 +// Licensed under the Apache License, Version 2.0 (the "License");
558 +// you may not use this file except in compliance with the License.
559 +// You may obtain a copy of the License at
560 +//
561 +// http://www.apache.org/licenses/LICENSE-2.0
562 +//
563 +// Unless required by applicable law or agreed to in writing, software
564 +// distributed under the License is distributed on an "AS IS" BASIS,
565 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
566 +// See the License for the specific language governing permissions and
567 +// limitations under the License.
568 +package com.google.firebase.messaging;
569 +
570 +import android.os.Parcel;
571 +import android.os.Parcelable;
572 +import java.util.Map;
573 +
574 +public class RemoteMessage implements Parcelable {
575 +
576 + public int describeContents() {
577 + return 0;
578 + }
579 +
580 + public void writeToParcel(Parcel out, int flags) {
581 + }
582 +
583 + public Map<String, String> getData() {
584 + return null;
585 + }
586 +
587 +}
588 diff --git a/mobile/android/fenix/app/src/main/java/mozilla/components/lib/push/firebase/AbstractFirebasePushService.kt b/mobile/android/fenix/app/src/main/java/mozilla/components/lib/push/firebase/AbstractFirebasePushService.kt
589 new file mode 100644
590 index 000000000000..b50a6f03a218
591 --- /dev/null
592 +++ b/mobile/android/fenix/app/src/main/java/mozilla/components/lib/push/firebase/AbstractFirebasePushService.kt
593 @@ -0,0 +1,32 @@
594 +/* This Source Code Form is subject to the terms of the Mozilla Public
595 + * License, v. 2.0. If a copy of the MPL was not distributed with this
596 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
597 +
598 +package mozilla.components.lib.push.firebase
599 +
600 +import android.content.Context
601 +import com.google.firebase.messaging.FirebaseMessagingService
602 +import com.google.firebase.messaging.RemoteMessage
603 +import mozilla.components.concept.push.PushService
604 +
605 +abstract class AbstractFirebasePushService() : FirebaseMessagingService(), PushService {
606 +
607 + override fun start(context: Context) {
608 + }
609 +
610 + override fun onNewToken(newToken: String) {
611 + }
612 +
613 + override fun onMessageReceived(remoteMessage: RemoteMessage?) {
614 + }
615 +
616 + final override fun stop() {
617 + }
618 +
619 + override fun deleteToken() {
620 + }
621 +
622 + override fun isServiceAvailable(context: Context): Boolean {
623 + return false
624 + }
625 +}
626 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
627 index 8dd1374d2d94..fb6785a50a77 100644
628 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
629 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
630 @@ -412,7 +412,6 @@ open class FenixApplication : Application(), Provider, ThemeProvider {
631 queueIncrementNumberOfAppLaunches(queue)
632 queueRestoreLocale(queue)
633 queueStorageMaintenance(queue)
634 - queueIntegrityClientWarmUp(queue)
635 queueNimbusFetchInForeground(queue)
636 queueSetAutofillMetrics(queue)
637 queueDownloadWallpapers(queue)
638 @@ -533,14 +532,6 @@ open class FenixApplication : Application(), Provider, ThemeProvider {
639 components.core.autofillStorage.registerStorageMaintenanceWorker()
640 }
641
642 - @OptIn(DelicateCoroutinesApi::class) // GlobalScope usage
643 - private fun queueIntegrityClientWarmUp(queue: RunWhenReadyQueue) =
644 - runOnVisualCompleteness(queue) {
645 - GlobalScope.launch(IO) {
646 - components.integrityClient.warmUp()
647 - }
648 - }
649 -
650 @OptIn(DelicateCoroutinesApi::class) // GlobalScope usage
651 private fun queueNimbusFetchInForeground(queue: RunWhenReadyQueue) =
652 runOnVisualCompleteness(queue) {
653 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
654 index cbbdc3c76899..97fedfafc208 100644
655 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
656 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
657 @@ -1372,19 +1372,16 @@ abstract class BaseBrowserFragment :
658 view = view,
659 )
660
661 - // This component feature only works on Fenix when built on Mozilla infrastructure.
662 - if (BuildConfig.MOZILLA_OFFICIAL) {
663 - webAuthnFeature.set(
664 - feature = WebAuthnFeature(
665 - engine = requireComponents.core.engine,
666 - activity = requireActivity(),
667 - exitFullScreen = requireComponents.useCases.sessionUseCases.exitFullscreen::invoke,
668 - currentTab = { store.state.selectedTabId },
669 - ),
670 - owner = this,
671 - view = view,
672 - )
673 - }
674 + webAuthnFeature.set(
675 + feature = WebAuthnFeature(
676 + engine = requireComponents.core.engine,
677 + activity = requireActivity(),
678 + exitFullScreen = requireComponents.useCases.sessionUseCases.exitFullscreen::invoke,
679 + currentTab = { store.state.selectedTabId },
680 + ),
681 + owner = this,
682 + view = view,
683 + )
684
685 screenOrientationFeature.set(
686 feature = ScreenOrientationFeature(
687 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt
688 index 2c3b431cec24..e7550716a0fa 100644
689 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt
690 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt
691 @@ -10,7 +10,6 @@ import androidx.compose.runtime.Composable
692 import androidx.compose.runtime.ReadOnlyComposable
693 import androidx.compose.ui.platform.LocalContext
694 import androidx.core.app.NotificationManagerCompat
695 -import com.google.android.play.core.review.ReviewManagerFactory
696 import mozilla.components.feature.addons.AddonManager
697 import mozilla.components.feature.addons.amo.AMOAddonsProvider
698 import mozilla.components.feature.addons.migration.DefaultSupportedAddonsChecker
699 @@ -18,11 +17,6 @@ import mozilla.components.feature.addons.update.DefaultAddonUpdater
700 import mozilla.components.feature.autofill.AutofillConfiguration
701 import mozilla.components.lib.crash.store.CrashAction
702 import mozilla.components.lib.crash.store.CrashMiddleware
703 -import mozilla.components.lib.integrity.googleplay.GooglePlayIntegrityClient
704 -import mozilla.components.lib.integrity.googleplay.GoogleProjectNumber
705 -import mozilla.components.lib.integrity.googleplay.IntegrityManagerProvider
706 -import mozilla.components.lib.integrity.googleplay.RequestHashProvider
707 -import mozilla.components.lib.integrity.googleplay.TokenProviderFactory
708 import mozilla.components.lib.publicsuffixlist.PublicSuffixList
709 import mozilla.components.service.fxrelay.eligibility.RelayEligibilityStore
710 import mozilla.components.service.fxrelay.eligibility.middlewares.ClearLastUsedMiddleware
711 @@ -247,7 +241,6 @@ class Components(private val context: Context) {
712
713 val playStoreReviewPromptController by lazyMonitored {
714 PlayStoreReviewPromptController(
715 - manager = ReviewManagerFactory.create(context),
716 numberOfAppLaunches = { settings.numberOfAppLaunches },
717 )
718 }
719 @@ -364,16 +357,6 @@ class Components(private val context: Context) {
720 )
721 }
722
723 - val integrityClient by lazyMonitored {
724 - GooglePlayIntegrityClient(
725 - TokenProviderFactory.create(
726 - IntegrityManagerProvider.create(context),
727 - GoogleProjectNumber.create(BuildConfig.GPS_INTEGRITY_TOKEN),
728 - ),
729 - RequestHashProvider.randomHashProvider(),
730 - )
731 - }
732 -
733 val termsOfUsePromptRepository by lazyMonitored {
734 DefaultTermsOfUsePromptRepository(settings)
735 }
736 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/PlayStoreReviewPromptController.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/PlayStoreReviewPromptController.kt
737 index f08c5cecdade..7f75cc75c20c 100644
738 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/PlayStoreReviewPromptController.kt
739 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/PlayStoreReviewPromptController.kt
740 @@ -11,9 +11,6 @@ import androidx.annotation.VisibleForTesting
741 import androidx.core.net.toUri
742 import androidx.fragment.app.FragmentActivity
743 import androidx.navigation.fragment.NavHostFragment
744 -import com.google.android.play.core.review.ReviewException
745 -import com.google.android.play.core.review.ReviewInfo
746 -import com.google.android.play.core.review.ReviewManager
747 import kotlinx.coroutines.Dispatchers
748 import kotlinx.coroutines.withContext
749 import mozilla.components.support.base.log.logger.Logger
750 @@ -35,7 +32,6 @@ val logger = Logger("PlayStoreReviewPromptController")
751 * Wraps the Play Store In-App Review API.
752 */
753 class PlayStoreReviewPromptController(
754 - private val manager: ReviewManager,
755 private val numberOfAppLaunches: () -> Int,
756 ) {
757
758 @@ -47,80 +43,12 @@ class PlayStoreReviewPromptController(
759 onNotDisplayed: () -> Unit = {},
760 onError: () -> Unit = {},
761 ) {
762 - logger.info("tryPromptReview in progress...")
763 - val reviewInfoTask = withContext(Dispatchers.IO) { manager.requestReviewFlow() }
764 -
765 - reviewInfoTask.addOnCompleteListener(activity) { task ->
766 - val result = if (task.isSuccessful) {
767 - logger.info("Review flow launched.")
768 - // Launch the in-app flow.
769 - manager.launchReviewFlow(activity, task.result)
770 -
771 - ReviewPromptAttemptResult.from(task.result.toString())
772 - } else {
773 - Error
774 - }
775 -
776 - when (result) {
777 - NotDisplayed -> {
778 - logger.warn("In-app review flow reported as not displayed, even though there was no error.")
779 -
780 - onNotDisplayed()
781 - }
782 -
783 - Error -> {
784 - val reviewErrorCode =
785 - (task.exception as? ReviewException)?.errorCode ?: ERROR_CODE_UNEXPECTED
786 - logger.warn("Failed to launch in-app review flow due to: $reviewErrorCode.")
787 -
788 - onError()
789 - }
790 -
791 - Displayed, Unknown -> {}
792 - }
793 -
794 - recordReviewPromptEvent(
795 - promptAttemptResult = result,
796 - numberOfAppLaunches = numberOfAppLaunches(),
797 - now = Date(),
798 - )
799 - }
800 -
801 - logger.info("tryPromptReview completed.")
802 }
803
804 /**
805 * Try to launch the play store review flow.
806 */
807 fun tryLaunchPlayStoreReview(activity: Activity) {
808 - logger.info("tryLaunchPlayStoreReview in progress...")
809 -
810 - try {
811 - logger.info("Navigating to Play store listing.")
812 - activity.startActivity(
813 - Intent(Intent.ACTION_VIEW, SupportUtils.RATE_APP_URL.toUri()),
814 - )
815 - } catch (e: ActivityNotFoundException) {
816 - // Device without the play store installed.
817 - // Opening the play store website.
818 -
819 - activity.applicationContext.components.useCases.fenixBrowserUseCases.loadUrlOrSearch(
820 - searchTermOrURL = SupportUtils.FENIX_PLAY_STORE_URL,
821 - newTab = true,
822 - )
823 -
824 - // https://bugzilla.mozilla.org/show_bug.cgi?id=1997148
825 - (activity as? FragmentActivity)
826 - ?.supportFragmentManager
827 - ?.fragments
828 - ?.firstOrNull { it is NavHostFragment }
829 - ?.let { (it as NavHostFragment).navController }
830 - ?.openToBrowser()
831 -
832 - logger.warn("Failed to launch play store review flow due to: $e.")
833 - }
834 -
835 - logger.info("tryLaunchPlayStoreReview completed.")
836 }
837
838 companion object {
839 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/InstallReferrerWorker.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/InstallReferrerWorker.kt
840 index be9e47f9fbf2..fd16b5119e41 100644
841 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/InstallReferrerWorker.kt
842 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/InstallReferrerWorker.kt
843 @@ -9,8 +9,6 @@ import android.os.RemoteException
844 import androidx.annotation.VisibleForTesting
845 import androidx.work.CoroutineWorker
846 import androidx.work.WorkerParameters
847 -import com.android.installreferrer.api.InstallReferrerClient
848 -import com.android.installreferrer.api.InstallReferrerStateListener
849 import kotlinx.coroutines.suspendCancellableCoroutine
850 import mozilla.components.support.base.log.logger.Logger
851 import mozilla.telemetry.glean.GleanTimerId
852 @@ -43,31 +41,7 @@ class InstallReferrerWorker(
853 private val settings = context.settings()
854
855 override suspend fun doWork(): Result {
856 - val referrerClient = DefaultInstallReferrerClient(applicationContext)
857 - val (responseCode, referrerResponse) = fetchInstallReferrer(referrerClient)
858 -
859 - return when (responseCode) {
860 - InstallReferrerClient.InstallReferrerResponse.OK -> {
861 - handleSuccess(referrerResponse, responseCode, settings)
862 - Result.success()
863 - }
864 -
865 - InstallReferrerClient.InstallReferrerResponse.SERVICE_DISCONNECTED,
866 - InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE,
867 - -> {
868 - if (shouldRetry(runAttemptCount)) {
869 - Result.retry()
870 - } else {
871 - markAsComplete(responseCode)
872 - Result.failure()
873 - }
874 - }
875 -
876 - else -> {
877 - markAsComplete(responseCode)
878 - Result.failure()
879 - }
880 - }
881 + return Result.success()
882 }
883
884 @VisibleForTesting
885 @@ -76,103 +50,6 @@ class InstallReferrerWorker(
886 responseCode: Int,
887 settings: Settings,
888 ) {
889 - if (!installReferrerResponse.isNullOrBlank()) {
890 - PlayStoreAttribution.installReferrerResponse.set(installReferrerResponse)
891 -
892 - val utmParams = UTMParams.parseUTMParameters(installReferrerResponse)
893 - val metaParams = MetaParams.extractMetaAttribution(utmParams.content)
894 - if (metaParams != null) {
895 - settings.isUserMetaAttributed = true
896 - metaParams.recordMetaAttribution()
897 - } else {
898 - settings.isUserMetaAttributed = false
899 - }
900 -
901 - utmParams.recordInstallReferrer(settings)
902 - }
903 -
904 - markAsComplete(responseCode)
905 - }
906 -
907 - private fun markAsComplete(responseCode: Int) {
908 - settings.utmParamsKnown = true
909 - PlayStoreAttribution.responseCode.set(responseCode.toString())
910 - Pings.playStoreAttribution.submit()
911 - }
912 -
913 - companion object {
914 - private val logger = Logger("InstallReferrerWorker")
915 -
916 - @VisibleForTesting
917 - internal fun shouldRetry(runAttemptCount: Int): Boolean {
918 - return runAttemptCount < InstallReferrerMetricsService.MAX_RETRIES
919 - }
920 -
921 - @VisibleForTesting
922 - internal suspend fun fetchInstallReferrer(
923 - referrerClient: InstallReferrerClientWrapper,
924 - ): Pair<Int, String?> {
925 - val timerId = PlayStoreAttribution.attributionTime.start()
926 -
927 - return suspendCancellableCoroutine { continuation ->
928 - continuation.invokeOnCancellation {
929 - safelyEndConnection(referrerClient)
930 - }
931 -
932 - val listener = createReferrerStateListener(timerId, referrerClient, continuation)
933 - referrerClient.startConnection(listener)
934 - }
935 - }
936 -
937 - private fun createReferrerStateListener(
938 - timerId: GleanTimerId,
939 - referrerClient: InstallReferrerClientWrapper,
940 - continuation: kotlin.coroutines.Continuation<Pair<Int, String?>>,
941 - ) = object : InstallReferrerStateListener {
942 - override fun onInstallReferrerSetupFinished(responseCode: Int) {
943 - PlayStoreAttribution.attributionTime.stopAndAccumulate(timerId)
944 - val referrerResponse = getReferrerResponseIfOk(responseCode, referrerClient)
945 - safelyEndConnection(referrerClient)
946 - continuation.resume(Pair(responseCode, referrerResponse))
947 - }
948 -
949 - override fun onInstallReferrerServiceDisconnected() {
950 - continuation.resume(
951 - Pair(
952 - InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE,
953 - null,
954 - ),
955 - )
956 - }
957 - }
958 -
959 - private fun getReferrerResponseIfOk(
960 - responseCode: Int,
961 - referrerClient: InstallReferrerClientWrapper,
962 - ): String? {
963 - if (responseCode != InstallReferrerClient.InstallReferrerResponse.OK) {
964 - return null
965 - }
966 -
967 - return try {
968 - referrerClient.getInstallReferrer()
969 - } catch (e: RemoteException) {
970 - logger.error("Failed to retrieve install referrer", e)
971 - null
972 - } catch (e: SecurityException) {
973 - logger.error("Failed to retrieve install referrer", e)
974 - null
975 - }
976 - }
977 -
978 - @Suppress("TooGenericExceptionCaught")
979 - private fun safelyEndConnection(referrerClient: InstallReferrerClientWrapper) {
980 - try {
981 - referrerClient.endConnection()
982 - } catch (e: Exception) {
983 - logger.error("Failed to end connection", e)
984 - }
985 - }
986 }
987 }
988
989 @@ -181,30 +58,10 @@ class InstallReferrerWorker(
990 */
991 @VisibleForTesting
992 internal interface InstallReferrerClientWrapper {
993 - fun startConnection(listener: InstallReferrerStateListener)
994 fun getInstallReferrer(): String?
995 fun endConnection()
996 }
997
998 -/**
999 - * Default implementation that wraps the actual InstallReferrerClient.
1000 - */
1001 -private class DefaultInstallReferrerClient(context: Context) : InstallReferrerClientWrapper {
1002 - private val client = InstallReferrerClient.newBuilder(context).build()
1003 -
1004 - override fun startConnection(listener: InstallReferrerStateListener) {
1005 - client.startConnection(listener)
1006 - }
1007 -
1008 - override fun getInstallReferrer(): String? {
1009 - return client.installReferrer?.installReferrer
1010 - }
1011 -
1012 - override fun endConnection() {
1013 - client.endConnection()
1014 - }
1015 -}
1016 -
1017 /**
1018 * Descriptions of utm parameters comes from
1019 * https://support.google.com/analytics/answer/1033863
1020 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/MarketingAttributionService.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/MarketingAttributionService.kt
1021 index c35705351b3e..b0156324642b 100644
1022 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/MarketingAttributionService.kt
1023 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/metrics/MarketingAttributionService.kt
1024 @@ -7,8 +7,6 @@ package org.mozilla.fenix.components.metrics
1025 import android.content.Context
1026 import android.os.RemoteException
1027 import androidx.annotation.VisibleForTesting
1028 -import com.android.installreferrer.api.InstallReferrerClient
1029 -import com.android.installreferrer.api.InstallReferrerStateListener
1030 import kotlinx.coroutines.CoroutineScope
1031 import kotlinx.coroutines.Dispatchers
1032 import kotlinx.coroutines.launch
1033 @@ -28,87 +26,18 @@ const val ADJUST_REFTAG_PREFIX = "adjust_reftag="
1034 */
1035 class MarketingAttributionService(private val context: Context) {
1036 private val logger = Logger("MarketingAttributionService")
1037 - private var referrerClient: InstallReferrerClient? = null
1038
1039 /**
1040 * Starts the connection with the install referrer and handle the response.
1041 */
1042 @Suppress("CognitiveComplexMethod")
1043 fun start() {
1044 - val client = InstallReferrerClient.newBuilder(context).build()
1045 - referrerClient = client
1046 -
1047 - client.startConnection(
1048 - object : InstallReferrerStateListener {
1049 - override fun onInstallReferrerSetupFinished(responseCode: Int) {
1050 - when (responseCode) {
1051 - InstallReferrerClient.InstallReferrerResponse.OK -> {
1052 - // Connection established.
1053 - val installReferrerResponse = try {
1054 - client.installReferrer.installReferrer
1055 - } catch (e: RemoteException) {
1056 - // We can't do anything about this.
1057 - logger.error("Failed to retrieve install referrer response", e)
1058 - null
1059 - } catch (e: SecurityException) {
1060 - // https://issuetracker.google.com/issues/72926755
1061 - logger.error("Failed to retrieve install referrer response", e)
1062 - null
1063 - }
1064 -
1065 - val distributionIdManager = context.components.distributionIdManager
1066 -
1067 - if (!installReferrerResponse.isNullOrBlank()) {
1068 - response = installReferrerResponse
1069 - val utmParams =
1070 - UTMParams.parseUTMParameters(installReferrerResponse)
1071 -
1072 - context.settings().isUserMetaAttributed = isMetaAttribution(installReferrerResponse)
1073 -
1074 - distributionIdManager.updateDistributionIdFromUtmParams(utmParams)
1075 - CoroutineScope(Dispatchers.IO).launch {
1076 - distributionIdManager.startAdjustIfSkippingConsentScreen()
1077 - }
1078 - }
1079 -
1080 - CoroutineScope(Dispatchers.IO).launch {
1081 - context.settings().shouldShowMarketingOnboarding =
1082 - shouldShowMarketingOnboarding(
1083 - installReferrerResponse,
1084 - distributionIdManager,
1085 - )
1086 - }
1087 -
1088 - return
1089 - }
1090 -
1091 - InstallReferrerClient.InstallReferrerResponse.FEATURE_NOT_SUPPORTED,
1092 - InstallReferrerClient.InstallReferrerResponse.DEVELOPER_ERROR,
1093 - InstallReferrerClient.InstallReferrerResponse.PERMISSION_ERROR,
1094 - InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE,
1095 - -> {
1096 - context.settings().shouldShowMarketingOnboarding = false
1097 - return
1098 - }
1099 - }
1100 -
1101 - // End the connection, and null out the client.
1102 - stop()
1103 - }
1104 -
1105 - override fun onInstallReferrerServiceDisconnected() {
1106 - referrerClient = null
1107 - }
1108 - },
1109 - )
1110 }
1111
1112 /**
1113 * Stops the connection with the install referrer.
1114 */
1115 fun stop() {
1116 - referrerClient?.endConnection()
1117 - referrerClient = null
1118 }
1119
1120 /**
1121 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/navigation/DebugDrawerRoute.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/navigation/DebugDrawerRoute.kt
1122 index abd548208c15..959565d2241b 100644
1123 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/navigation/DebugDrawerRoute.kt
1124 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/navigation/DebugDrawerRoute.kt
1125 @@ -8,7 +8,6 @@ import androidx.annotation.StringRes
1126 import androidx.compose.runtime.Composable
1127 import mozilla.components.browser.state.state.BrowserState
1128 import mozilla.components.browser.state.store.BrowserStore
1129 -import mozilla.components.concept.integrity.IntegrityClient
1130 import mozilla.components.concept.storage.CreditCardsAddressesStorage
1131 import mozilla.components.concept.storage.LoginsStorage
1132 import org.mozilla.fenix.R
1133 @@ -23,7 +22,6 @@ import org.mozilla.fenix.debugsettings.crashtools.CrashTools
1134 import org.mozilla.fenix.debugsettings.creditcards.CreditCardsTools
1135 import org.mozilla.fenix.debugsettings.gleandebugtools.GleanDebugToolsStore
1136 import org.mozilla.fenix.debugsettings.gleandebugtools.ui.GleanDebugToolsScreen
1137 -import org.mozilla.fenix.debugsettings.integrity.IntegrityTools
1138 import org.mozilla.fenix.debugsettings.llm.LlmTools
1139 import org.mozilla.fenix.debugsettings.logins.LoginsTools
1140 import org.mozilla.fenix.debugsettings.region.RegionTools
1141 @@ -86,10 +84,6 @@ enum class DebugDrawerRoute(
1142 route = "crash_debug_tools",
1143 title = R.string.crash_debug_tools_title,
1144 ),
1145 - IntegrityTools(
1146 - route = "integrity_tools",
1147 - title = R.string.integrity_debug_tools_title,
1148 - ),
1149 LlmTools(
1150 route = "llm_tools",
1151 title = R.string.llm_debug_tools_title,
1152 @@ -107,7 +101,6 @@ enum class DebugDrawerRoute(
1153 * @param loginsStorage [LoginsStorage] used to access logins for [LoginsScreen].
1154 * @param addressesDebugRegionRepository used to control storage for [AddressesTools].
1155 * @param creditCardsAddressesStorage used to access addresses for [AddressesTools].
1156 - * @param integrityClient used to test an [IntegrityClient] in [IntegrityTools].
1157 * @param inactiveTabsEnabled Whether the inactive tabs feature is enabled.
1158 * @param llm the component group [Llm].
1159 */
1160 @@ -120,7 +113,6 @@ enum class DebugDrawerRoute(
1161 loginsStorage: LoginsStorage,
1162 addressesDebugRegionRepository: AddressesDebugRegionRepository,
1163 creditCardsAddressesStorage: CreditCardsAddressesStorage,
1164 - integrityClient: IntegrityClient,
1165 inactiveTabsEnabled: Boolean,
1166 llm: Llm,
1167 ): List<DebugDrawerDestination> =
1168 @@ -235,14 +227,6 @@ enum class DebugDrawerRoute(
1169 CrashTools()
1170 }
1171 }
1172 - IntegrityTools -> {
1173 - onClick = {
1174 - debugDrawerStore.dispatch(DebugDrawerAction.NavigateTo.IntegrityDebugTools)
1175 - }
1176 - content = {
1177 - IntegrityTools(integrityClient)
1178 - }
1179 - }
1180
1181 LlmTools -> {
1182 onClick = {
1183 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/store/DebugDrawerAction.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/store/DebugDrawerAction.kt
1184 index 4719845ff56e..234bd51c9773 100644
1185 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/store/DebugDrawerAction.kt
1186 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/store/DebugDrawerAction.kt
1187 @@ -89,11 +89,6 @@ sealed class DebugDrawerAction : Action {
1188 */
1189 object CrashDebugTools : NavigateTo()
1190
1191 - /**
1192 - * [NavigateTo] action fired when the debug drawer needs to navigate to [IntegrityTools].
1193 - */
1194 - object IntegrityDebugTools : NavigateTo()
1195 -
1196 /**
1197 * [NavigateTo] action fired when the debug drawer needs to navigate to [LlmTools].
1198 */
1199 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/store/DebugDrawerNavigationMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/store/DebugDrawerNavigationMiddleware.kt
1200 index 15917e848afa..389bc3e05848 100644
1201 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/store/DebugDrawerNavigationMiddleware.kt
1202 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/store/DebugDrawerNavigationMiddleware.kt
1203 @@ -55,8 +55,6 @@ class DebugDrawerNavigationMiddleware(
1204 navController.navigate(route = DebugDrawerRoute.AddonsDebugTools.route)
1205 is DebugDrawerAction.NavigateTo.CrashDebugTools ->
1206 navController.navigate(route = DebugDrawerRoute.CrashDebugTools.route)
1207 - is DebugDrawerAction.NavigateTo.IntegrityDebugTools ->
1208 - navController.navigate(route = DebugDrawerRoute.IntegrityTools.route)
1209 is DebugDrawerAction.NavigateTo.LlmDebugTools ->
1210 navController.navigate(route = DebugDrawerRoute.LlmTools.route)
1211 is DebugDrawerAction.OnBackPressed -> navController.popBackStack()
1212 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/ui/FenixOverlay.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/ui/FenixOverlay.kt
1213 index 4f379233e869..ff3e7e48f5d4 100644
1214 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/ui/FenixOverlay.kt
1215 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/debugsettings/ui/FenixOverlay.kt
1216 @@ -113,7 +113,6 @@ fun FenixOverlay(
1217 },
1218 creditCardsAddressesStorage = context.components.core.autofillStorage,
1219 inactiveTabsEnabled = inactiveTabsEnabled,
1220 - integrityClient = context.components.integrityClient,
1221 llm = context.components.llm,
1222 )
1223 }
1224 @@ -127,7 +126,6 @@ fun FenixOverlay(
1225 * @param loginsStorage [LoginsStorage] used to access logins for [LoginsTools].
1226 * @param addressesDebugRegionRepository used to control storage for [AddressesTools].
1227 * @param creditCardsAddressesStorage used to access addresses for [AddressesTools].
1228 - * @param integrityClient used to test an [IntegrityClient].
1229 * @param llm the component group [Llm].
1230 * @param inactiveTabsEnabled Whether the inactive tabs feature is enabled.
1231 */
1232 @@ -140,7 +138,6 @@ private fun FenixOverlay(
1233 loginsStorage: LoginsStorage,
1234 addressesDebugRegionRepository: AddressesDebugRegionRepository,
1235 creditCardsAddressesStorage: CreditCardsAddressesStorage,
1236 - integrityClient: IntegrityClient,
1237 llm: Llm,
1238 inactiveTabsEnabled: Boolean,
1239 ) {
1240 @@ -168,7 +165,6 @@ private fun FenixOverlay(
1241 loginsStorage = loginsStorage,
1242 addressesDebugRegionRepository = addressesDebugRegionRepository,
1243 creditCardsAddressesStorage = creditCardsAddressesStorage,
1244 - integrityClient = integrityClient,
1245 llm = llm,
1246 )
1247 }
1248 @@ -219,7 +215,6 @@ private fun FenixOverlayPreview() {
1249 loginsStorage = FakeLoginsStorage(),
1250 addressesDebugRegionRepository = FakeAddressesDebugRegionRepository(),
1251 creditCardsAddressesStorage = FakeCreditCardsAddressesStorage(),
1252 - integrityClient = IntegrityClient.testSuccess,
1253 llm = Llm(FakeClient()),
1254 )
1255 }
1256 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/pocket/ContentRecommendationsFeatureHelper.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/pocket/ContentRecommendationsFeatureHelper.kt
1257 index d211d3625dbf..0458e8704d5c 100644
1258 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/pocket/ContentRecommendationsFeatureHelper.kt
1259 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/pocket/ContentRecommendationsFeatureHelper.kt
1260 @@ -16,22 +16,7 @@ object ContentRecommendationsFeatureHelper {
1261 /**
1262 * List of supported content recommendations locales.
1263 */
1264 - val CONTENT_RECOMMENDATIONS_SUPPORTED_LOCALE = listOf(
1265 - "fr",
1266 - "fr-FR",
1267 - "es",
1268 - "es-ES",
1269 - "it",
1270 - "it-IT",
1271 - "en",
1272 - "en-CA",
1273 - "en-GB",
1274 - "en-US",
1275 - "de",
1276 - "de-DE",
1277 - "de-AT",
1278 - "de-CH",
1279 - )
1280 + val CONTENT_RECOMMENDATIONS_SUPPORTED_LOCALE = listOf<String>()
1281
1282 /**
1283 * Show Pocket sponsored stories in between Pocket recommended stories on home.
1284 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
1285 index d3b5cb6187ac..61f458c19fdc 100644
1286 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
1287 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/OnboardingFragment.kt
1288 @@ -474,8 +474,7 @@ class OnboardingFragment : Fragment() {
1289 }
1290
1291 if (!settings.isTelemetryEnabled) {
1292 - Pings.onboardingOptOut.setEnabled(true)
1293 - Pings.onboardingOptOut.submit()
1294 + Pings.onboardingOptOut.setEnabled(false)
1295 }
1296
1297 // The marketing telemetry may be enabled after finishing onboarding.
1298 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt
1299 index 09a40c4d935b..8a81595ebc7c 100644
1300 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt
1301 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt
1302 @@ -30,6 +30,8 @@ object SupportUtils {
1303 const val FXACCOUNT_SUMO_URL = "https://support.mozilla.org/kb/access-mozilla-services-firefox-account"
1304 const val ANDROID_SUPPORT_SUMO_URL = "mzl.la/AndroidSupport"
1305 const val RELAY_MANAGE_URL = "https://relay.firefox.com"
1306 + const val FDROID_URL = "https://f-droid.org/"
1307 + const val EFF_URL = "https://www.eff.org/"
1308
1309 // This is locale-less on purpose so that the content negotiation happens on the AMO side because the current
1310 // user language might not be supported by AMO and/or the language might not be exactly what AMO is expecting
1311 diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
1312 index 5c3035c5b371..845f2a979282 100644
1313 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
1314 +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
1315 @@ -174,8 +174,7 @@ class Settings(
1316 private val logger = Logger("Settings")
1317
1318 @VisibleForTesting
1319 - internal val isCrashReportEnabledInBuild: Boolean =
1320 - BuildConfig.CRASH_REPORTING && Config.channel.isReleased
1321 + internal val isCrashReportEnabledInBuild: Boolean = false
1322
1323 override val preferences: SharedPreferences =
1324 appContext.getSharedPreferences(FENIX_PREFERENCES, MODE_PRIVATE)
1325 @@ -199,11 +198,7 @@ class Settings(
1326 /**
1327 * Indicates if the stories homescreen section should be shown.
1328 */
1329 - var showPocketRecommendationsFeature by lazyFeatureFlagBooleanPreference(
1330 - appContext.getPreferenceKey(R.string.pref_key_pocket_homescreen_recommendations),
1331 - featureFlag = ContentRecommendationsFeatureHelper.isContentRecommendationsFeatureEnabled(appContext),
1332 - defaultValue = { homescreenSections[HomeScreenSection.POCKET] == true },
1333 - )
1334 + var showPocketRecommendationsFeature = false
1335
1336 /**
1337 * Indicates what simple toolbar shortcut key is currently selected.
1338 @@ -238,11 +233,7 @@ class Settings(
1339 /**
1340 * Indicates if the Pocket recommendations homescreen section should also show sponsored stories.
1341 */
1342 - val showPocketSponsoredStories by lazyFeatureFlagBooleanPreference(
1343 - key = appContext.getPreferenceKey(R.string.pref_key_pocket_sponsored_stories),
1344 - defaultValue = { homescreenSections[HomeScreenSection.POCKET_SPONSORED_STORIES] == true },
1345 - featureFlag = ContentRecommendationsFeatureHelper.isPocketSponsoredStoriesFeatureEnabled(appContext),
1346 - )
1347 + val showPocketSponsoredStories = false
1348
1349 /**
1350 * Indicates whether or not the "Recently Visited" section should be shown on the home screen.
1351 @@ -566,12 +557,7 @@ class Settings(
1352 default = true,
1353 )
1354
1355 - val isCrashReportingEnabled: Boolean
1356 - get() = isCrashReportEnabledInBuild &&
1357 - preferences.getBoolean(
1358 - appContext.getPreferenceKey(R.string.pref_key_crash_reporter),
1359 - true,
1360 - )
1361 + val isCrashReportingEnabled: Boolean = false
1362
1363 var crashReportChoice by stringPreference(
1364 appContext.getPreferenceKey(R.string.pref_key_crash_reporting_choice),
1365 @@ -583,20 +569,11 @@ class Settings(
1366 default = false,
1367 )
1368
1369 - var isTelemetryEnabled by booleanPreference(
1370 - appContext.getPreferenceKey(R.string.pref_key_telemetry),
1371 - default = true,
1372 - )
1373 + var isTelemetryEnabled = false
1374
1375 - var isMarketingTelemetryEnabled by booleanPreference(
1376 - appContext.getPreferenceKey(R.string.pref_key_marketing_telemetry),
1377 - default = false,
1378 - )
1379 + var isMarketingTelemetryEnabled = false
1380
1381 - var hasMadeMarketingTelemetrySelection by booleanPreference(
1382 - appContext.getPreferenceKey(R.string.pref_key_marketing_telemetry_selection_made),
1383 - default = false,
1384 - )
1385 + var hasMadeMarketingTelemetrySelection = false
1386
1387 var hasAcceptedTermsOfService by booleanPreference(
1388 appContext.getPreferenceKey(R.string.pref_key_terms_accepted),
1389 @@ -710,16 +687,9 @@ class Settings(
1390 * sure that users who upgrade and had telemetry disabled don't start sending the
1391 * daily usage ping telemetry.
1392 */
1393 - var isDailyUsagePingEnabled by booleanPreference(
1394 - appContext.getPreferenceKey(R.string.pref_key_daily_usage_ping),
1395 - default = isTelemetryEnabled,
1396 - persistDefaultIfNotExists = true,
1397 - )
1398 + var isDailyUsagePingEnabled = false
1399
1400 - var isExperimentationEnabled by booleanPreference(
1401 - appContext.getPreferenceKey(R.string.pref_key_experimentation_v2),
1402 - default = isTelemetryEnabled,
1403 - )
1404 + var isExperimentationEnabled = false
1405
1406 /**
1407 * This lets us know if the user has disabled experimentation manually so that we know
1408 @@ -2095,10 +2065,7 @@ class Settings(
1409 /**
1410 * Indicates if the Contile functionality should be visible.
1411 */
1412 - var showContileFeature by booleanPreference(
1413 - key = appContext.getPreferenceKey(R.string.pref_key_enable_contile),
1414 - default = true,
1415 - )
1416 + var showContileFeature = false
1417
1418 /**
1419 * Indicates if the Unified Search feature should be visible.
1420 diff --git a/mobile/android/fenix/app/src/main/res/xml/home_preferences.xml b/mobile/android/fenix/app/src/main/res/xml/home_preferences.xml
1421 index e1afb71a53b2..aa4c14b19436 100644
1422 --- a/mobile/android/fenix/app/src/main/res/xml/home_preferences.xml
1423 +++ b/mobile/android/fenix/app/src/main/res/xml/home_preferences.xml
1424 @@ -13,7 +13,8 @@
1425 android:dependency="@string/pref_key_show_top_sites"
1426 android:layout="@layout/checkbox_left_sub_preference"
1427 android:key="@string/pref_key_enable_contile"
1428 - android:title="@string/customize_toggle_contile" />
1429 + android:title="@string/customize_toggle_contile"
1430 + app:isPreferenceVisible="false" />
1431
1432 <androidx.preference.SwitchPreference
1433 android:key="@string/pref_key_recent_tabs"
1434 @@ -29,13 +30,15 @@
1435
1436 <androidx.preference.SwitchPreference
1437 android:key="@string/pref_key_pocket_homescreen_recommendations"
1438 - android:title="@string/customize_toggle_pocket_3" />
1439 + android:title="@string/customize_toggle_pocket_3"
1440 + app:isPreferenceVisible="false" />
1441
1442 <androidx.preference.CheckBoxPreference
1443 android:dependency="@string/pref_key_pocket_homescreen_recommendations"
1444 android:layout="@layout/checkbox_left_sub_preference"
1445 android:key="@string/pref_key_pocket_sponsored_stories"
1446 - android:title="@string/customize_toggle_pocket_sponsored" />
1447 + android:title="@string/customize_toggle_pocket_sponsored"
1448 + app:isPreferenceVisible="false" />
1449
1450 <androidx.preference.Preference
1451 android:key="@string/pref_key_wallpapers"
1452 diff --git a/mobile/android/fenix/app/src/main/res/xml/preferences.xml b/mobile/android/fenix/app/src/main/res/xml/preferences.xml
1453 index 9235796cf72f..bb261eb1738e 100644
1454 --- a/mobile/android/fenix/app/src/main/res/xml/preferences.xml
1455 +++ b/mobile/android/fenix/app/src/main/res/xml/preferences.xml
1456 @@ -147,11 +147,6 @@
1457 app:iconSpaceReserved="false"
1458 android:title="@string/preferences_notifications" />
1459
1460 - <androidx.preference.Preference
1461 - android:key="@string/pref_key_data_choices"
1462 - app:iconSpaceReserved="false"
1463 - android:title="@string/preferences_data_collection" />
1464 -
1465 </androidx.preference.PreferenceCategory>
1466
1467 <PreferenceCategory
1468 @@ -223,11 +218,6 @@
1469 android:title="@string/preferences_category_about"
1470 app:iconSpaceReserved="false"
1471 android:layout="@layout/preference_category_no_icon_style">
1472 - <androidx.preference.Preference
1473 - android:key="@string/pref_key_rate"
1474 - app:iconSpaceReserved="false"
1475 - android:title="@string/preferences_rate" />
1476 -
1477 <androidx.preference.Preference
1478 android:key="@string/pref_key_about"
1479 app:iconSpaceReserved="false"
1480 diff --git a/mobile/android/fenix/app/src/main/res/xml/site_permissions_details_exceptions_preferences.xml b/mobile/android/fenix/app/src/main/res/xml/site_permissions_details_exceptions_preferences.xml
1481 index dfe2d28572f2..54a99d9e1dc5 100644
1482 --- a/mobile/android/fenix/app/src/main/res/xml/site_permissions_details_exceptions_preferences.xml
1483 +++ b/mobile/android/fenix/app/src/main/res/xml/site_permissions_details_exceptions_preferences.xml
1484 @@ -44,7 +44,8 @@
1485 android:icon="@drawable/ic_link"
1486 android:key="@string/pref_key_browser_feature_media_key_system_access"
1487 android:title="@string/preference_phone_feature_media_key_system_access"
1488 - android:summary="@string/preference_option_phone_feature_ask_to_allow"/>
1489 + android:summary="@string/preference_option_phone_feature_ask_to_allow"
1490 + app:isPreferenceVisible="false"/>
1491
1492 <androidx.preference.Preference
1493 android:icon="@drawable/ic_autoplay"
1494 diff --git a/mobile/android/fenix/app/src/main/res/xml/site_permissions_preferences.xml b/mobile/android/fenix/app/src/main/res/xml/site_permissions_preferences.xml
1495 index d224eedd7c87..2d1fc926bb34 100644
1496 --- a/mobile/android/fenix/app/src/main/res/xml/site_permissions_preferences.xml
1497 +++ b/mobile/android/fenix/app/src/main/res/xml/site_permissions_preferences.xml
1498 @@ -73,6 +73,7 @@
1499 android:key="@string/pref_key_browser_feature_media_key_system_access"
1500 android:title="@string/preference_phone_feature_media_key_system_access"
1501 android:summary="@string/preference_option_phone_feature_ask_to_allow"
1502 + app:isPreferenceVisible="false"
1503 app:allowDividerBelow="true"/>
1504
1505 <androidx.preference.Preference
1506