Bug 1858795 - Disable the re-engagement and first encounter of a cookie banner dialogs.
parent
38cf43b8b4
commit
a5bacc4d12
@ -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
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue