Skip to content

Commit 169d5a2

Browse files
Bug 1981147 - Updating when the terms of use bottom sheet trigger behavior r=android-reviewers,gmalekpour
Differential Revision: https://phabricator.services.mozilla.com/D260377
1 parent 4326d7c commit 169d5a2

File tree

16 files changed

+286
-107
lines changed

16 files changed

+286
-107
lines changed

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
709709
// DO NOT MOVE ANYTHING ABOVE THIS getProfilerTime CALL.
710710
val startProfilerTime = components.core.engine.profiler?.getProfilerTime()
711711

712+
components.termsOfUseManager.onStart()
713+
712714
super.onStart()
713715

714716
// Diagnostic breadcrumb for "Display already aquired" crash:

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ import org.mozilla.fenix.home.HomeFragment
5959
import org.mozilla.fenix.nimbus.FxNimbus
6060
import org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.getCookieBannerUIMode
6161
import org.mozilla.fenix.shortcut.PwaOnboardingObserver
62-
import org.mozilla.fenix.termsofuse.shouldShowTermsOfUsePrompt
6362
import org.mozilla.fenix.theme.ThemeManager
6463

6564
/**
@@ -158,12 +157,6 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
158157
view = view,
159158
)
160159
}
161-
162-
if (requireContext().settings().shouldShowTermsOfUsePrompt()) {
163-
findNavController().navigate(
164-
BrowserFragmentDirections.actionGlobalTermsOfUseDialog(),
165-
)
166-
}
167160
}
168161

169162
private fun initBrowserToolbarViewActions(rootView: View) {
@@ -554,6 +547,12 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
554547

555548
subscribeToTabCollections()
556549
updateLastBrowseActivity()
550+
551+
if (requireComponents.termsOfUseManager.shouldShowTermsOfUsePromptOnBrowserFragment()) {
552+
findNavController().navigate(
553+
BrowserFragmentDirections.actionGlobalTermsOfUseDialog(),
554+
)
555+
}
557556
}
558557

559558
override fun onStop() {

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import org.mozilla.fenix.perf.StartupStateProvider
7070
import org.mozilla.fenix.perf.StrictModeManager
7171
import org.mozilla.fenix.perf.lazyMonitored
7272
import org.mozilla.fenix.reviewprompt.ReviewPromptMiddleware
73+
import org.mozilla.fenix.termsofuse.TermsOfUseManager
7374
import org.mozilla.fenix.utils.Settings
7475
import org.mozilla.fenix.utils.isLargeScreenSize
7576
import org.mozilla.fenix.wifi.WifiConnectionMonitor
@@ -332,6 +333,10 @@ class Components(private val context: Context) {
332333
distributionSettings = DefaultDistributionSettings(settings),
333334
)
334335
}
336+
337+
val termsOfUseManager by lazyMonitored {
338+
TermsOfUseManager(settings)
339+
}
335340
}
336341

337342
/**

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ import org.mozilla.fenix.snackbar.FenixSnackbarDelegate
160160
import org.mozilla.fenix.snackbar.SnackbarBinding
161161
import org.mozilla.fenix.tabstray.Page
162162
import org.mozilla.fenix.tabstray.TabsTrayAccessPoint
163-
import org.mozilla.fenix.termsofuse.shouldShowTermsOfUsePrompt
164163
import org.mozilla.fenix.theme.FirefoxTheme
165164
import org.mozilla.fenix.utils.allowUndo
166165
import org.mozilla.fenix.utils.showAddSearchWidgetPromptIfSupported
@@ -570,12 +569,6 @@ class HomeFragment : Fragment() {
570569

571570
FxNimbus.features.homescreen.recordExposure()
572571

573-
if (requireContext().settings().shouldShowTermsOfUsePrompt()) {
574-
findNavController().navigate(
575-
BrowserFragmentDirections.actionGlobalTermsOfUseDialog(),
576-
)
577-
}
578-
579572
// DO NOT MOVE ANYTHING BELOW THIS addMarker CALL!
580573
requireComponents.core.engine.profiler?.addMarker(
581574
MarkersFragmentLifecycleCallbacks.MARKER_NAME,
@@ -1155,6 +1148,12 @@ class HomeFragment : Fragment() {
11551148

11561149
// Trigger review prompt logic and show the appropriate prompt variation if applicable
11571150
requireComponents.appStore.dispatch(CheckIfEligibleForReviewPrompt)
1151+
1152+
if (requireComponents.termsOfUseManager.shouldShowTermsOfUsePromptOnHomepage()) {
1153+
findNavController().navigate(
1154+
BrowserFragmentDirections.actionGlobalTermsOfUseDialog(),
1155+
)
1156+
}
11581157
}
11591158

11601159
@VisibleForTesting
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
package org.mozilla.fenix.termsofuse
6+
7+
import org.mozilla.fenix.Config
8+
import org.mozilla.fenix.utils.Settings
9+
import org.mozilla.fenix.utils.Settings.Companion.FIVE_DAYS_MS
10+
11+
/**
12+
* Helps determine when the terms of use prompt should show.
13+
*
14+
* @param settings app settings
15+
*/
16+
class TermsOfUseManager(private val settings: Settings) {
17+
18+
private var isFirstCheckSinceStartingApp: Boolean = false
19+
20+
/**
21+
* Determines whether the Terms of Use bottom sheet should be shown on the homepage.
22+
*/
23+
fun shouldShowTermsOfUsePromptOnHomepage() =
24+
shouldShowTermsOfUsePrompt(ignoreFirstCheckSinceStartingApp = true)
25+
26+
/**
27+
* Determines whether the Terms of Use bottom sheet should be shown in the browser fragment.
28+
*/
29+
fun shouldShowTermsOfUsePromptOnBrowserFragment() = shouldShowTermsOfUsePrompt()
30+
31+
/**
32+
* Determines whether the Terms of Use bottom sheet should be shown.
33+
*
34+
* This function returns `true` if:
35+
* - The user has not accepted the Terms of Use.
36+
* - The user has not postponed accepting the Terms of Use or it's been at least 5 days since they did.
37+
* - This is the first time checking to see if we should show the prompt since starting the app
38+
* OR the [ignoreFirstCheckSinceStartingApp] flag is true (we should ignore this when checking from homepage).
39+
* - The current build channel is a debug build.
40+
*
41+
* @param ignoreFirstCheckSinceStartingApp if we should ignore the [isFirstCheckSinceStartingApp] value.
42+
* It should be ignored when checking from homepage.
43+
* @param currentTimeInMillis the current time in milliseconds
44+
* @return `true` if the Terms of Use bottom sheet should be shown; otherwise, `false`.
45+
*/
46+
@Suppress("ReturnCount")
47+
private fun shouldShowTermsOfUsePrompt(
48+
ignoreFirstCheckSinceStartingApp: Boolean = false,
49+
currentTimeInMillis: Long = System.currentTimeMillis(),
50+
): Boolean {
51+
if (settings.hasAcceptedTermsOfService) return false
52+
53+
val isFirstCheck = isFirstCheckSinceStartingApp
54+
isFirstCheckSinceStartingApp = false
55+
56+
val durationSinceLastPrompt = currentTimeInMillis - settings.lastTermsOfUsePromptTimeInMillis
57+
58+
if (settings.hasPostponedAcceptingTermsOfUse && durationSinceLastPrompt < FIVE_DAYS_MS) return false
59+
if (!ignoreFirstCheckSinceStartingApp && !isFirstCheck) return false
60+
if (!Config.channel.isDebug) return false
61+
62+
return true
63+
}
64+
65+
/**
66+
* Called from the [org.mozilla.fenix.HomeActivity]'s onStart. Used to track the first check
67+
* since starting the app.
68+
*/
69+
fun onStart() {
70+
isFirstCheckSinceStartingApp = true
71+
}
72+
}

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/termsofuse/TermsOfUseUtils.kt

Lines changed: 0 additions & 24 deletions
This file was deleted.

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/termsofuse/store/TermsOfUsePromptPreferencesMiddleware.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ class TermsOfUsePromptPreferencesMiddleware(
3232
is TermsOfUsePromptAction.OnPromptManuallyDismissed -> {
3333
repository.updateHasPostponedAcceptingTermsOfUsePreference()
3434
}
35+
36+
is TermsOfUsePromptAction.OnPromptDismissed -> {
37+
repository.updateLastTermsOfUsePromptTimeInMillis()
38+
}
3539
}
3640

3741
next(action)

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/termsofuse/store/TermsOfUsePromptRepository.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ interface TermsOfUsePromptRepository {
1919
* Updates the hasPostponedAcceptingTermsOfService preference to true
2020
*/
2121
fun updateHasPostponedAcceptingTermsOfUsePreference()
22+
23+
/**
24+
* Updates the lastTermsOfUsePromptTimeInMillis preference to the current time
25+
*
26+
* @param time the current time in milliseconds
27+
*/
28+
fun updateLastTermsOfUsePromptTimeInMillis(time: Long = System.currentTimeMillis())
2229
}
2330

2431
/**
@@ -34,6 +41,10 @@ class DefaultTermsOfUsePromptRepository(
3441
}
3542

3643
override fun updateHasPostponedAcceptingTermsOfUsePreference() {
37-
settings.hasPostponedAcceptingTermsOfService = true
44+
settings.hasPostponedAcceptingTermsOfUse = true
45+
}
46+
47+
override fun updateLastTermsOfUsePromptTimeInMillis(time: Long) {
48+
settings.lastTermsOfUsePromptTimeInMillis = time
3849
}
3950
}

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/termsofuse/store/TermsOfUsePromptStore.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ sealed interface TermsOfUsePromptAction : Action {
3333
* background scrim
3434
*/
3535
data object OnPromptManuallyDismissed : TermsOfUsePromptAction
36+
37+
/**
38+
* Triggered when the prompt is dismissed for any reason.
39+
*/
40+
data object OnPromptDismissed : TermsOfUsePromptAction
3641
}
3742

3843
/**

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/termsofuse/ui/TermsOfUseBottomSheetFragment.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package org.mozilla.fenix.termsofuse.ui
66

77
import android.app.Dialog
8+
import android.content.DialogInterface
89
import android.os.Bundle
910
import android.view.LayoutInflater
1011
import android.view.View
@@ -16,6 +17,7 @@ import org.mozilla.fenix.components.lazyStore
1617
import org.mozilla.fenix.ext.settings
1718
import org.mozilla.fenix.settings.SupportUtils
1819
import org.mozilla.fenix.termsofuse.store.DefaultTermsOfUsePromptRepository
20+
import org.mozilla.fenix.termsofuse.store.TermsOfUsePromptAction
1921
import org.mozilla.fenix.termsofuse.store.TermsOfUsePromptPreferencesMiddleware
2022
import org.mozilla.fenix.termsofuse.store.TermsOfUsePromptStore
2123
import org.mozilla.fenix.theme.FirefoxTheme
@@ -55,7 +57,9 @@ class TermsOfUseBottomSheetFragment : BottomSheetDialogFragment() {
5557
FirefoxTheme {
5658
TermsOfUseBottomSheet(
5759
store = termsOfUsePromptStore,
58-
onDismiss = { dismiss() },
60+
onDismiss = {
61+
dismiss()
62+
},
5963
onTermsOfUseClicked = {
6064
SupportUtils.launchSandboxCustomTab(
6165
context,
@@ -82,4 +86,9 @@ class TermsOfUseBottomSheetFragment : BottomSheetDialogFragment() {
8286
}
8387
}
8488
}
89+
90+
override fun onDismiss(dialog: DialogInterface) {
91+
super.onDismiss(dialog)
92+
termsOfUsePromptStore.dispatch(TermsOfUsePromptAction.OnPromptDismissed)
93+
}
8594
}

0 commit comments

Comments
 (0)