Bug 1858795 - Disable the re-engagement and first encounter of a cookie banner dialogs.

fenix/121.0
Arturo Mejia 8 months ago committed by mergify[bot]
parent 38cf43b8b4
commit a5bacc4d12

@ -243,7 +243,6 @@ features:
{
"feature-ui": 0,
"feature-setting-value": 0,
"dialog-re-engage-time": 4,
"feature-setting-value-pbm": 0
}
defaults:
@ -252,7 +251,6 @@ features:
"sections-enabled": {
"feature-ui": 1,
"feature-setting-value": 0,
"dialog-re-engage-time": 4,
"feature-setting-value-pbm": 0
}
}
@ -261,7 +259,6 @@ features:
"sections-enabled": {
"feature-ui": 1,
"feature-setting-value": 0,
"dialog-re-engage-time": 4,
"feature-setting-value-pbm": 0
}
}
@ -459,10 +456,6 @@ types:
feature-setting-value:
description: An integer either 0 or 1 indicating if cookie banner setting should be enabled or disabled,
0 for setting the value to disabled, 1 for enabling the setting with the value reject_all.
dialog-re-engage-time:
description: An integer indicating the number of hours that needs to happen before
the re-engagement dialog shows again since the last seen, for example if set to 4
that means if the users has seen the dialog, it will see it 4 hours later.
feature-setting-value-pbm:
description: An integer either 0 or 1 indicating if cookie banner setting should be enabled or disabled,
0 for setting the value to disabled, 1 for enabling the setting with the value reject_all.

@ -67,11 +67,6 @@ interface FeatureSettingsHelper {
*/
var etpPolicy: ETPPolicy
/**
* Enable or disable cookie banner reduction dialog.
*/
var isCookieBannerReductionDialogEnabled: Boolean
/**
* Enable or disable open in app banner.
*/

@ -33,7 +33,6 @@ class FeatureSettingsHelperDelegate() : FeatureSettingsHelper {
isTCPCFREnabled = settings.shouldShowTotalCookieProtectionCFR,
isWallpaperOnboardingEnabled = settings.showWallpaperOnboarding,
isDeleteSitePermissionsEnabled = settings.deleteSitePermissions,
isCookieBannerReductionDialogEnabled = !settings.userOptOutOfReEngageCookieBannerDialog,
isOpenInAppBannerEnabled = settings.shouldShowOpenInAppBanner,
etpPolicy = getETPPolicy(settings),
tabsTrayRewriteEnabled = settings.enableTabsTrayToCompose,
@ -63,7 +62,6 @@ class FeatureSettingsHelperDelegate() : FeatureSettingsHelper {
override var isRecentlyVisitedFeatureEnabled: Boolean by updatedFeatureFlags::isRecentlyVisitedFeatureEnabled
override var isPWAsPromptEnabled: Boolean by updatedFeatureFlags::isPWAsPromptEnabled
override var isTCPCFREnabled: Boolean by updatedFeatureFlags::isTCPCFREnabled
override var isCookieBannerReductionDialogEnabled: Boolean by updatedFeatureFlags::isCookieBannerReductionDialogEnabled
override var isOpenInAppBannerEnabled: Boolean by updatedFeatureFlags::isOpenInAppBannerEnabled
override var etpPolicy: ETPPolicy by updatedFeatureFlags::etpPolicy
override var tabsTrayRewriteEnabled: Boolean by updatedFeatureFlags::tabsTrayRewriteEnabled
@ -90,7 +88,6 @@ class FeatureSettingsHelperDelegate() : FeatureSettingsHelper {
settings.shouldShowTotalCookieProtectionCFR = featureFlags.isTCPCFREnabled
settings.showWallpaperOnboarding = featureFlags.isWallpaperOnboardingEnabled
settings.deleteSitePermissions = featureFlags.isDeleteSitePermissionsEnabled
settings.userOptOutOfReEngageCookieBannerDialog = !featureFlags.isCookieBannerReductionDialogEnabled
settings.shouldShowOpenInAppBanner = featureFlags.isOpenInAppBannerEnabled
settings.enableTabsTrayToCompose = featureFlags.tabsTrayRewriteEnabled
settings.enableComposeTopSites = featureFlags.composeTopSitesEnabled
@ -109,7 +106,6 @@ private data class FeatureFlags(
var isTCPCFREnabled: Boolean,
var isWallpaperOnboardingEnabled: Boolean,
var isDeleteSitePermissionsEnabled: Boolean,
var isCookieBannerReductionDialogEnabled: Boolean,
var isOpenInAppBannerEnabled: Boolean,
var etpPolicy: ETPPolicy,
var tabsTrayRewriteEnabled: Boolean,

@ -52,7 +52,6 @@ class HomeActivityTestRule(
isTCPCFREnabled: Boolean = settings.shouldShowTotalCookieProtectionCFR,
isWallpaperOnboardingEnabled: Boolean = settings.showWallpaperOnboarding,
isDeleteSitePermissionsEnabled: Boolean = settings.deleteSitePermissions,
isCookieBannerReductionDialogEnabled: Boolean = !settings.userOptOutOfReEngageCookieBannerDialog,
isOpenInAppBannerEnabled: Boolean = settings.shouldShowOpenInAppBanner,
etpPolicy: ETPPolicy = getETPPolicy(settings),
tabsTrayRewriteEnabled: Boolean = false,
@ -67,7 +66,6 @@ class HomeActivityTestRule(
this.isTCPCFREnabled = isTCPCFREnabled
this.isWallpaperOnboardingEnabled = isWallpaperOnboardingEnabled
this.isDeleteSitePermissionsEnabled = isDeleteSitePermissionsEnabled
this.isCookieBannerReductionDialogEnabled = isCookieBannerReductionDialogEnabled
this.isOpenInAppBannerEnabled = isOpenInAppBannerEnabled
this.etpPolicy = etpPolicy
this.tabsTrayRewriteEnabled = tabsTrayRewriteEnabled
@ -126,7 +124,6 @@ class HomeActivityTestRule(
isPWAsPromptEnabled = false,
isTCPCFREnabled = false,
isWallpaperOnboardingEnabled = false,
isCookieBannerReductionDialogEnabled = false,
isOpenInAppBannerEnabled = false,
composeTopSitesEnabled = composeTopSitesEnabled,
)
@ -164,7 +161,6 @@ class HomeActivityIntentTestRule internal constructor(
isTCPCFREnabled: Boolean = settings.shouldShowTotalCookieProtectionCFR,
isWallpaperOnboardingEnabled: Boolean = settings.showWallpaperOnboarding,
isDeleteSitePermissionsEnabled: Boolean = settings.deleteSitePermissions,
isCookieBannerReductionDialogEnabled: Boolean = !settings.userOptOutOfReEngageCookieBannerDialog,
isOpenInAppBannerEnabled: Boolean = settings.shouldShowOpenInAppBanner,
etpPolicy: ETPPolicy = getETPPolicy(settings),
tabsTrayRewriteEnabled: Boolean = false,
@ -179,7 +175,6 @@ class HomeActivityIntentTestRule internal constructor(
this.isTCPCFREnabled = isTCPCFREnabled
this.isWallpaperOnboardingEnabled = isWallpaperOnboardingEnabled
this.isDeleteSitePermissionsEnabled = isDeleteSitePermissionsEnabled
this.isCookieBannerReductionDialogEnabled = isCookieBannerReductionDialogEnabled
this.isOpenInAppBannerEnabled = isOpenInAppBannerEnabled
this.etpPolicy = etpPolicy
this.tabsTrayRewriteEnabled = tabsTrayRewriteEnabled
@ -244,7 +239,6 @@ class HomeActivityIntentTestRule internal constructor(
isTCPCFREnabled = settings.shouldShowTotalCookieProtectionCFR
isWallpaperOnboardingEnabled = settings.showWallpaperOnboarding
isDeleteSitePermissionsEnabled = settings.deleteSitePermissions
isCookieBannerReductionDialogEnabled = !settings.userOptOutOfReEngageCookieBannerDialog
isOpenInAppBannerEnabled = settings.shouldShowOpenInAppBanner
etpPolicy = getETPPolicy(settings)
}
@ -275,7 +269,6 @@ class HomeActivityIntentTestRule internal constructor(
isPWAsPromptEnabled = false,
isTCPCFREnabled = false,
isWallpaperOnboardingEnabled = false,
isCookieBannerReductionDialogEnabled = false,
isOpenInAppBannerEnabled = false,
composeTopSitesEnabled = composeTopSitesEnabled,
)

@ -61,7 +61,6 @@ class ComposeSearchTest {
isRecentTabsFeatureEnabled = false,
isTCPCFREnabled = false,
isWallpaperOnboardingEnabled = false,
isCookieBannerReductionDialogEnabled = false,
tabsTrayRewriteEnabled = true,
),
) { it.activity }

@ -77,7 +77,6 @@ class SearchTest {
isRecentTabsFeatureEnabled = false,
isTCPCFREnabled = false,
isWallpaperOnboardingEnabled = false,
isCookieBannerReductionDialogEnabled = false,
tabsTrayRewriteEnabled = false,
),
) { it.activity }

@ -10,6 +10,7 @@ import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.components.toolbar.CFR_MINIMUM_NUMBER_OPENED_TABS
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule
@ -28,12 +29,12 @@ class TotalCookieProtectionTest {
val composeTestRule = AndroidComposeTestRule(
HomeActivityTestRule(
isTCPCFREnabled = true,
isCookieBannerReductionDialogEnabled = false,
),
) { it.activity }
@Before
fun setUp() {
CFR_MINIMUM_NUMBER_OPENED_TABS = 0
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()
start()
@ -43,6 +44,7 @@ class TotalCookieProtectionTest {
@After
fun tearDown() {
mockWebServer.shutdown()
CFR_MINIMUM_NUMBER_OPENED_TABS = 5
}
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2260552

@ -147,7 +147,6 @@ import org.mozilla.fenix.settings.TrackingProtectionFragmentDirections
import org.mozilla.fenix.settings.about.AboutFragmentDirections
import org.mozilla.fenix.settings.logins.fragment.LoginDetailFragmentDirections
import org.mozilla.fenix.settings.logins.fragment.SavedLoginsAuthFragmentDirections
import org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.dialog.CookieBannerReEngagementDialogUtils
import org.mozilla.fenix.settings.search.SaveSearchEngineFragmentDirections
import org.mozilla.fenix.settings.search.SearchEngineFragmentDirections
import org.mozilla.fenix.settings.studies.StudiesFragmentDirections
@ -531,10 +530,6 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
// and the user changes the system language
// More details here: https://github.com/mozilla-mobile/fenix/pull/27793#discussion_r1029892536
components.core.store.dispatch(SearchAction.RefreshSearchEnginesAction)
CookieBannerReEngagementDialogUtils.tryToEnableDetectOnlyModeIfNeeded(
components.settings,
components.core.engine.settings,
)
}
override fun onStart() {

@ -16,14 +16,11 @@ import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab
import mozilla.components.browser.state.selector.findTab
import mozilla.components.browser.state.state.SessionState
import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.browser.thumbnails.BrowserThumbnails
import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.concept.engine.permission.SitePermissions
@ -32,11 +29,9 @@ import mozilla.components.feature.contextmenu.ContextMenuCandidate
import mozilla.components.feature.readerview.ReaderViewFeature
import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.tabs.WindowFeature
import mozilla.components.lib.state.ext.consumeFlow
import mozilla.components.service.glean.private.NoExtras
import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
import org.mozilla.fenix.GleanMetrics.ReaderMode
import org.mozilla.fenix.GleanMetrics.Shopping
import org.mozilla.fenix.HomeActivity
@ -52,7 +47,6 @@ import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.runIfFragmentIsAttached
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.nimbus.FxNimbus
import org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.dialog.CookieBannerReEngagementDialogUtils
import org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.getCookieBannerUIMode
import org.mozilla.fenix.shopping.DefaultShoppingExperienceFeature
import org.mozilla.fenix.shopping.ReviewQualityCheckFeature
@ -209,10 +203,6 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
)
}
if (!context.settings().shouldUseCookieBanner && !context.settings().userOptOutOfReEngageCookieBannerDialog) {
observeCookieBannerHandlingState(context.components.core.store)
}
standardSnackbarErrorBinding.set(
feature = StandardSnackbarErrorBinding(
requireActivity(),
@ -613,22 +603,4 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
internal fun updateLastBrowseActivity() {
requireContext().settings().lastBrowseActivity = System.currentTimeMillis()
}
private fun observeCookieBannerHandlingState(store: BrowserStore) {
consumeFlow(store) { flow ->
flow.mapNotNull { state ->
state.findCustomTabOrSelectedTab(customTabSessionId)
}.ifAnyChanged { tab ->
arrayOf(
tab.cookieBanner,
)
}.collect {
CookieBannerReEngagementDialogUtils.tryToShowReEngagementDialog(
settings = requireContext().settings(),
status = it.cookieBanner,
navController = findNavController(),
)
}
}
}
}

@ -144,8 +144,6 @@ class Core(
httpsOnlyMode = context.settings().getHttpsOnlyMode(),
cookieBannerHandlingModePrivateBrowsing = context.settings().getCookieBannerHandlingPrivateMode(),
cookieBannerHandlingMode = context.settings().getCookieBannerHandling(),
cookieBannerHandlingDetectOnlyMode = context.settings()
.shouldShowCookieBannerReEngagementDialog(),
)
GeckoEngine(

@ -56,7 +56,9 @@ private const val CFR_TO_ANCHOR_VERTICAL_PADDING = -6
/**
* The minimum number of opened tabs to show the Total Cookie Protection CFR.
*/
private const val CFR_MINIMUM_NUMBER_OPENED_TABS = 5
internal var CFR_MINIMUM_NUMBER_OPENED_TABS = 5
@VisibleForTesting
internal set
/**
* Delegate for handling all the business logic for showing CFRs in the toolbar.
@ -183,8 +185,7 @@ class BrowserToolbarCFRPresenter(
}
settings.shouldShowTotalCookieProtectionCFR && (
!settings.shouldShowCookieBannerReEngagementDialog() ||
settings.openTabsCount >= CFR_MINIMUM_NUMBER_OPENED_TABS
settings.openTabsCount >= CFR_MINIMUM_NUMBER_OPENED_TABS
) -> ToolbarCFR.TCP
shoppingExperienceFeature.isEnabled &&

@ -52,8 +52,6 @@ class CookieBannersFragment : PreferenceFragmentCompat() {
val mode = requireContext().settings().getCookieBannerHandling()
getEngineSettings().cookieBannerHandlingModePrivateBrowsing = mode
getEngineSettings().cookieBannerHandlingMode = mode
getEngineSettings().cookieBannerHandlingDetectOnlyMode =
requireContext().settings().shouldShowCookieBannerReEngagementDialog()
CookieBanners.settingChanged.record(CookieBanners.SettingChangedExtra(metricTag))
requireContext().components.useCases.sessionUseCases.reload()
return super.onPreferenceChange(preference, newValue)

@ -1,112 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.DialogFragment
import mozilla.components.concept.engine.EngineSession.CookieBannerHandlingMode.DISABLED
import mozilla.components.concept.engine.EngineSession.CookieBannerHandlingMode.REJECT_ALL
import mozilla.components.concept.engine.Settings
import mozilla.telemetry.glean.private.NoExtras
import org.mozilla.fenix.GleanMetrics.CookieBanners
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getRootView
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.theme.FirefoxTheme
/**
* Displays a cookie banner dialog fragment that contains the dialog compose and his logic.
*/
class CookieBannerReEngagementDialog : DialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View = ComposeView(requireContext()).apply {
CookieBanners.visitedReEngagementDialog.record(NoExtras())
setContent {
FirefoxTheme {
val title =
context.getString(
R.string.reduce_cookie_banner_dialog_title,
context.getString(R.string.app_name),
)
val message =
context.getString(
R.string.reduce_cookie_banner_dialog_body,
context.getString(R.string.app_name),
)
val allowButtonText =
context.getString(
R.string.reduce_cookie_banner_dialog_change_setting_button,
)
CookieBannerReEngagementDialogCompose(
dialogTitle = title,
dialogText = message,
allowButtonText = allowButtonText,
declineButtonText = getString(R.string.reduce_cookie_banner_dialog_not_now_button),
onAllowButtonClicked = {
CookieBanners.allowReEngagementDialog.record(NoExtras())
requireContext().settings().shouldUseCookieBanner = true
getEngineSettings().cookieBannerHandlingModePrivateBrowsing = REJECT_ALL
getEngineSettings().cookieBannerHandlingMode = REJECT_ALL
getEngineSettings().cookieBannerHandlingDetectOnlyMode = false
reload()
requireContext().getRootView()?.let {
FenixSnackbar.make(
view = it,
duration = LENGTH_SNACKBAR_DURATION,
isDisplayedWithBrowserToolbar = true,
)
.setText(getString(R.string.reduce_cookie_banner_dialog_snackbar_text))
.show()
}
dismiss()
},
onNotNowButtonClicked = {
disabledCookieBannerHandlingDetectOnlyMode()
CookieBanners.notNowReEngagementDialog.record(NoExtras())
dismiss()
},
onCloseButtonClicked = {
disabledCookieBannerHandlingDetectOnlyMode()
requireContext().settings().userOptOutOfReEngageCookieBannerDialog = true
CookieBanners.optOutReEngagementDialog.record(NoExtras())
dismiss()
},
)
}
}
}
private fun disabledCookieBannerHandlingDetectOnlyMode() {
getEngineSettings().cookieBannerHandlingDetectOnlyMode = false
getEngineSettings().cookieBannerHandlingModePrivateBrowsing = DISABLED
getEngineSettings().cookieBannerHandlingMode = DISABLED
}
private fun getEngineSettings(): Settings {
return requireContext().components.core.engine.settings
}
private fun reload() {
return requireContext().components.useCases.sessionUseCases.reload()
}
companion object {
private const val LENGTH_SNACKBAR_DURATION = 4000 // 4 seconds in ms
}
}

@ -1,136 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.dialog
import android.content.res.Configuration.UI_MODE_NIGHT_NO
import android.content.res.Configuration.UI_MODE_NIGHT_YES
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.button.TextButton
import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.theme.defaultTypography
@Composable
@Preview(uiMode = UI_MODE_NIGHT_YES)
@Preview(uiMode = UI_MODE_NIGHT_NO)
private fun CookieBannerReEngagementDialogComposePreview() {
FirefoxTheme {
CookieBannerReEngagementDialogCompose(
dialogTitle = "Allow Firefox to reject cookie banners?",
dialogText =
"Automatically reject cookie requests, when possible. Otherwise, " +
"accept all cookies to dismiss cookie banners.",
onAllowButtonClicked = {},
onNotNowButtonClicked = {},
onCloseButtonClicked = {},
allowButtonText = "Dismiss banners",
declineButtonText = "NOT NOW",
)
}
}
/**
* Displays the cookie banner reducer dialog
*/
@Suppress("LongParameterList", "LongMethod")
@Composable
fun CookieBannerReEngagementDialogCompose(
dialogTitle: String,
dialogText: String,
allowButtonText: String,
declineButtonText: String,
onCloseButtonClicked: () -> Unit,
onAllowButtonClicked: () -> Unit,
onNotNowButtonClicked: () -> Unit,
) {
Dialog(
properties = DialogProperties(dismissOnBackPress = false, dismissOnClickOutside = false),
onDismissRequest = onNotNowButtonClicked,
) {
Surface(
color = Color.Transparent,
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.clip(RoundedCornerShape(8.dp))
.background(color = FirefoxTheme.colors.layer1),
) {
Column {
IconButton(
modifier = Modifier
.align(Alignment.End)
.size(48.dp),
onClick = onCloseButtonClicked,
) {
Icon(
painter = painterResource(R.drawable.mozac_ic_cross_24),
contentDescription = stringResource(R.string.content_description_close_button),
tint = FirefoxTheme.colors.iconPrimary,
)
}
Text(
modifier = Modifier.padding(
start = 24.dp,
end = 24.dp,
bottom = 8.dp,
),
color = FirefoxTheme.colors.textPrimary,
text = dialogTitle,
style = defaultTypography.headline7,
)
Text(
modifier = Modifier.padding(horizontal = 24.dp),
color = FirefoxTheme.colors.textPrimary,
fontSize = 16.sp,
text = dialogText,
style = defaultTypography.body1,
)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(end = 24.dp, bottom = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(
space = 8.dp,
alignment = Alignment.End,
),
) {
TextButton(
text = declineButtonText,
onClick = onNotNowButtonClicked,
)
TextButton(
text = allowButtonText,
onClick = onAllowButtonClicked,
)
}
}
}
}
}

@ -1,55 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.dialog
import androidx.navigation.NavController
import mozilla.components.concept.engine.EngineSession.CookieBannerHandlingMode.REJECT_ALL
import mozilla.components.concept.engine.EngineSession.CookieBannerHandlingStatus
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.BrowserFragmentDirections
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.utils.Settings
import mozilla.components.concept.engine.Settings as EngineSettings
/**
* An utility object for interacting with the re-engagement cookie banner dialog.
*/
object CookieBannerReEngagementDialogUtils {
/**
* Tries to show the re-engagement cookie banner dialog, when the right conditions are met, o
* otherwise the dialog won't show.
*/
fun tryToShowReEngagementDialog(
settings: Settings,
status: CookieBannerHandlingStatus,
navController: NavController,
) {
if (status == CookieBannerHandlingStatus.DETECTED &&
settings.shouldShowCookieBannerReEngagementDialog()
) {
settings.cookieBannerReEngagementDialogShowsCount.increment()
settings.lastInteractionWithReEngageCookieBannerDialogInMs = System.currentTimeMillis()
settings.cookieBannerDetectedPreviously = true
val directions =
BrowserFragmentDirections.actionBrowserFragmentToCookieBannerDialogFragment()
navController.nav(R.id.browserFragment, directions)
}
}
/**
* Tries to enable the detect only mode after the time limit for the cookie banner has been
* expired.
*/
fun tryToEnableDetectOnlyModeIfNeeded(
settings: Settings,
engineSettings: EngineSettings,
) {
if (settings.shouldShowCookieBannerReEngagementDialog()) {
engineSettings.cookieBannerHandlingDetectOnlyMode = true
engineSettings.cookieBannerHandlingModePrivateBrowsing = REJECT_ALL
engineSettings.cookieBannerHandlingMode = REJECT_ALL
}
}
}

@ -622,50 +622,9 @@ class Settings(private val appContext: Context) : PreferencesHolder {
default = { cookieBannersSection[CookieBannersSection.FEATURE_SETTING_VALUE_PBM] == 1 },
)
var userOptOutOfReEngageCookieBannerDialog by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_cookie_banner_re_engage_dialog_dismissed),
default = false,
)
var lastInteractionWithReEngageCookieBannerDialogInMs by longPreference(
appContext.getPreferenceKey(
R.string.pref_key_cookie_banner_re_engage_dialog_last_interaction_in_ms,
),
default = 0L,
)
var cookieBannerDetectedPreviously by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_cookie_banner_first_banner_detected),
default = false,
)
val shouldShowCookieBannerUI: Boolean
get() = cookieBannersSection[CookieBannersSection.FEATURE_UI] == 1
/**
* Indicates after how many hours a cookie banner dialog should be shown again
*/
@VisibleForTesting
internal val timerForCookieBannerDialog: Long
get() = 60 * 60 * 1000L *
(cookieBannersSection[CookieBannersSection.DIALOG_RE_ENGAGE_TIME] ?: 4)
/**
* Indicates if we should should show the cookie banner dialog that invites the user to turn-on
* the setting.
*/
fun shouldShowCookieBannerReEngagementDialog(): Boolean {
val shouldShowDialog =
shouldShowCookieBannerUI && cookieBannerReEngagementDialogShowsCount.underMaxCount() &&
!userOptOutOfReEngageCookieBannerDialog && !shouldUseCookieBanner
return if (shouldShowDialog) {
!cookieBannerDetectedPreviously ||
timeNowInMillis() - lastInteractionWithReEngageCookieBannerDialogInMs >= timerForCookieBannerDialog
} else {
false
}
}
/**
* Declared as a function for performance purposes. This could be declared as a variable using
* booleanPreference like other members of this class. However, doing so will make it so it will
@ -1768,9 +1727,7 @@ class Settings(private val appContext: Context) : PreferencesHolder {
fun getCookieBannerHandling(): CookieBannerHandlingMode {
return when (shouldUseCookieBanner) {
true -> CookieBannerHandlingMode.REJECT_ALL
false -> if (shouldShowCookieBannerReEngagementDialog()) {
CookieBannerHandlingMode.REJECT_ALL
} else {
false -> {
CookieBannerHandlingMode.DISABLED
}
}
@ -1788,14 +1745,6 @@ class Settings(private val appContext: Context) : PreferencesHolder {
}
}
/**
* Times that the cookie banner re-engagement dialog has been shown.
*/
val cookieBannerReEngagementDialogShowsCount = counterPreference(
appContext.getPreferenceKey(R.string.pref_key_cookie_banner_re_engagement_dialog_shows_counter),
maxCount = 2,
)
var setAsDefaultGrowthSent by booleanPreference(
key = appContext.getPreferenceKey(R.string.pref_key_growth_set_as_default),
default = false,

@ -299,9 +299,6 @@
<action
android:id="@+id/action_browserFragment_to_quickSettingsSheetDialogFragment"
app:destination="@id/quickSettingsSheetDialogFragment" />
<action
android:id="@+id/action_browserFragment_to_cookieBannerDialogFragment"
app:destination="@id/cookieBannerDialogFragment" />
<action
android:id="@+id/action_browserFragment_to_reviewQualityCheckDialogFragment"
app:destination="@id/reviewQualityCheckFragment" />
@ -970,9 +967,6 @@
android:name="cookieBannerUIMode"
app:argType="org.mozilla.fenix.trackingprotection.CookieBannerUIMode" />
</dialog>
<dialog
android:id="@+id/cookieBannerDialogFragment"
android:name="org.mozilla.fenix.settings.quicksettings.protections.cookiebanners.dialog.CookieBannerReEngagementDialog" />
<fragment
android:id="@+id/accountProblemFragment"
android:name="org.mozilla.fenix.settings.account.AccountProblemFragment">

@ -162,11 +162,7 @@
<!-- Cookie Banner Reduction Settings-->
<string name="pref_key_cookie_banner_settings" translatable="false">pref_key_cookie_banner_settings</string>
<string name="pref_key_cookie_banner_re_engage_dialog_last_interaction_in_ms" translatable="false">pref_key_cookie_banner_re_engage_dialog_last_interaction_with_dialog_in_ms</string>
<string name="pref_key_cookie_banner_re_engage_dialog_dismissed" translatable="false">pref_key_cookie_banner_re_engage_dialog_dismissed</string>
<string name="pref_key_cookie_banner_first_banner_detected" translatable="false">pref_key_cookie_banner_first_banner_detected</string>
<string name="pref_key_cookie_banner_v1" translatable="false">pref_key_cookie_banner_v1</string>
<string name="pref_key_cookie_banner_re_engagement_dialog_shows_counter" translatable="false">pref_key_cookie_banner_re_engagement_dialog_shows_counter</string>
<string name="pref_key_cookie_banner_private_mode" translatable="false">pref_key_cookie_banner_private_mode</string>
<!-- Tracking Protection Settings -->

@ -475,15 +475,15 @@
<!-- Long text for a detail explanation indicating what will happen if cookie banner handling is on for a site, this is shown as part of the cookie banner panel in the toolbar. The first parameter is the application name -->
<string name="reduce_cookie_banner_details_panel_description_on_for_site_2">%1$s tries to automatically reject all cookie requests on supported sites.</string>
<!-- Title text for the cookie banner re-engagement dialog. The first parameter is the application name. -->
<string name="reduce_cookie_banner_dialog_title">Allow %1$s to reject cookie banners?</string>
<string name="reduce_cookie_banner_dialog_title" moz:RemovedIn="120" tools:ignore="UnusedResources">Allow %1$s to reject cookie banners?</string>
<!-- Body text for the cookie banner re-engagement dialog use. The first parameter is the application name. -->
<string name="reduce_cookie_banner_dialog_body">%1$s can automatically reject many cookie banner requests.</string>
<string name="reduce_cookie_banner_dialog_body" moz:RemovedIn="120" tools:ignore="UnusedResources">%1$s can automatically reject many cookie banner requests.</string>
<!-- Remind me later text button for the onboarding dialog -->
<string name="reduce_cookie_banner_dialog_not_now_button">Not Now</string>
<string name="reduce_cookie_banner_dialog_not_now_button" moz:RemovedIn="120" tools:ignore="UnusedResources">Not Now</string>
<!-- Snack text for the cookie banner dialog, after user hit the dismiss banner button -->
<string name="reduce_cookie_banner_dialog_snackbar_text">Youll see fewer cookie requests</string>
<string name="reduce_cookie_banner_dialog_snackbar_text" moz:RemovedIn="120" tools:ignore="UnusedResources">Youll see fewer cookie requests</string>
<!-- Change setting text button, for the cookie banner re-engagement dialog -->
<string name="reduce_cookie_banner_dialog_change_setting_button">Allow</string>
<string name="reduce_cookie_banner_dialog_change_setting_button" moz:RemovedIn="120" tools:ignore="UnusedResources">Allow</string>
<!-- Description of the preference to enable "HTTPS-Only" mode. -->
<string name="preferences_https_only_summary">Automatically attempts to connect to sites using HTTPS encryption protocol for increased security.</string>

@ -168,7 +168,6 @@ class BrowserToolbarCFRPresenterTest {
val presenter = createPresenter(
settings = mockk {
every { shouldShowTotalCookieProtectionCFR } returns false
every { shouldShowCookieBannerReEngagementDialog() } returns false
every { shouldShowReviewQualityCheckCFR } returns false
every { shouldShowEraseActionCFR } returns false
},
@ -429,7 +428,7 @@ class BrowserToolbarCFRPresenterTest {
browserStore: BrowserStore = mockk(),
settings: Settings = mockk {
every { shouldShowTotalCookieProtectionCFR } returns true
every { shouldShowCookieBannerReEngagementDialog() } returns false
every { openTabsCount } returns 5
every { shouldShowReviewQualityCheckCFR } returns false
every { shouldShowEraseActionCFR } returns false
},
@ -456,8 +455,8 @@ class BrowserToolbarCFRPresenterTest {
browserStore: BrowserStore = mockk(),
settings: Settings = mockk(relaxed = true) {
every { shouldShowTotalCookieProtectionCFR } returns true
every { shouldShowCookieBannerReEngagementDialog() } returns false
every { shouldShowEraseActionCFR } returns true
every { openTabsCount } returns 5
every { shouldShowReviewQualityCheckCFR } returns true
},
toolbar: BrowserToolbar = mockk {

Loading…
Cancel
Save