diff --git a/.experimenter.yaml b/.experimenter.yaml index 0873bd28a..2859851e9 100644 --- a/.experimenter.yaml +++ b/.experimenter.yaml @@ -7,6 +7,17 @@ default-browser-message: message-location: type: string description: Where is the message to be put. +engine-settings: + description: Contains a set of settings for controlling the web engine configurations. + hasExposure: true + exposureDescription: "" + variables: + tabs-prioritization-enabled: + type: boolean + description: "If true, enables tabs prioritization feature." + total-cookie-protection-enabled: + type: boolean + description: "If true, enables the total cookie protection in all browsing modes." homescreen: description: The homescreen that the user goes to when they press home or new tab. hasExposure: true diff --git a/app/src/main/java/org/mozilla/fenix/components/TrackingProtectionPolicyFactory.kt b/app/src/main/java/org/mozilla/fenix/components/TrackingProtectionPolicyFactory.kt index c4993e363..29b6134fa 100644 --- a/app/src/main/java/org/mozilla/fenix/components/TrackingProtectionPolicyFactory.kt +++ b/app/src/main/java/org/mozilla/fenix/components/TrackingProtectionPolicyFactory.kt @@ -42,16 +42,22 @@ class TrackingProtectionPolicyFactory( } return when { - normalMode && privateMode -> trackingProtectionPolicy.adaptPolicyToChannel() - normalMode && !privateMode -> trackingProtectionPolicy.adaptPolicyToChannel().forRegularSessionsOnly() - !normalMode && privateMode -> trackingProtectionPolicy.adaptPolicyToChannel().forPrivateSessionsOnly() + normalMode && privateMode -> trackingProtectionPolicy.applyTCPIfNeeded(settings) + normalMode && !privateMode -> trackingProtectionPolicy.applyTCPIfNeeded(settings).forRegularSessionsOnly() + !normalMode && privateMode -> trackingProtectionPolicy.applyTCPIfNeeded(settings).forPrivateSessionsOnly() else -> TrackingProtectionPolicy.none() } } private fun createCustomTrackingProtectionPolicy(): TrackingProtectionPolicy { + val cookiePolicy = if (settings.enabledTotalCookieProtection) { + CookiePolicy.ACCEPT_FIRST_PARTY_AND_ISOLATE_OTHERS + } else { + getCustomCookiePolicy() + } + return TrackingProtectionPolicy.select( - cookiePolicy = getCustomCookiePolicy(), + cookiePolicy = cookiePolicy, trackingCategories = getCustomTrackingCategories(), cookiePurging = getCustomCookiePurgingPolicy() ).let { @@ -106,10 +112,17 @@ class TrackingProtectionPolicyFactory( } @VisibleForTesting -internal fun TrackingProtectionPolicyForSessionTypes.adaptPolicyToChannel(): TrackingProtectionPolicyForSessionTypes { +internal fun TrackingProtectionPolicyForSessionTypes.applyTCPIfNeeded(settings: Settings): + TrackingProtectionPolicyForSessionTypes { + val updatedCookiePolicy = if (settings.enabledTotalCookieProtection) { + CookiePolicy.ACCEPT_FIRST_PARTY_AND_ISOLATE_OTHERS + } else { + cookiePolicy + } + return TrackingProtectionPolicy.select( trackingCategories = trackingCategories, - cookiePolicy = cookiePolicy, + cookiePolicy = updatedCookiePolicy, strictSocialTrackingProtection = strictSocialTrackingProtection, cookiePurging = cookiePurging ) diff --git a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt index 6db31473c..493e1828b 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -604,6 +604,10 @@ class Settings(private val appContext: Context) : PreferencesHolder { true ) + val enabledTotalCookieProtection: Boolean by lazy { + FxNimbus.features.engineSettings.value().totalCookieProtectionEnabled + } + val blockCookiesSelectionInCustomTrackingProtection by stringPreference( appContext.getPreferenceKey(R.string.pref_key_tracking_protection_custom_cookies_select), appContext.getString(R.string.social) diff --git a/app/src/test/java/org/mozilla/fenix/components/TrackingProtectionPolicyFactoryTest.kt b/app/src/test/java/org/mozilla/fenix/components/TrackingProtectionPolicyFactoryTest.kt index 423bb7237..0329a69a8 100644 --- a/app/src/test/java/org/mozilla/fenix/components/TrackingProtectionPolicyFactoryTest.kt +++ b/app/src/test/java/org/mozilla/fenix/components/TrackingProtectionPolicyFactoryTest.kt @@ -8,6 +8,7 @@ import io.mockk.every import io.mockk.mockk import io.mockk.mockkObject import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy +import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy.CookiePolicy import mozilla.components.support.test.robolectric.testContext import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertEquals @@ -137,21 +138,40 @@ class TrackingProtectionPolicyFactoryTest { } @Test - fun `adaptPolicyToChannel MUST only update properties that have changed per given channel`() { - mockkObject(Config) + fun `GIVEN TCP is enabled by nimbus WHEN applyTCPIfNeeded THEN cookie policy should be TCP`() { + val settings: Settings = mockk(relaxed = true) + every { settings.enabledTotalCookieProtection } returns true val policies = arrayOf( TrackingProtectionPolicy.strict(), TrackingProtectionPolicy.recommended(), TrackingProtectionPolicy.select() ) - for (channel in ReleaseChannel.values()) { - every { Config.channel } returns channel + for (policy in policies) { + val adaptedPolicy = policy.applyTCPIfNeeded(settings) + assertEquals( + CookiePolicy.ACCEPT_FIRST_PARTY_AND_ISOLATE_OTHERS, + adaptedPolicy.cookiePolicy + ) + } + } - for (policy in policies) { - val adaptedPolicy = policy.adaptPolicyToChannel() - policy.assertPolicyEquals(adaptedPolicy, checkPrivacy = false) - } + fun `GIVEN TCP is NOT enabled by nimbus WHEN applyTCPIfNeeded THEN reuse cookie policy`() { + val settings: Settings = mockk(relaxed = true) + + every { settings.enabledTotalCookieProtection } returns false + + val policies = arrayOf( + TrackingProtectionPolicy.strict(), TrackingProtectionPolicy.recommended(), + TrackingProtectionPolicy.select() + ) + + for (policy in policies) { + val adaptedPolicy = policy.applyTCPIfNeeded(settings) + assertEquals( + policy.cookiePolicy, + adaptedPolicy.cookiePolicy + ) } } @@ -578,6 +598,7 @@ class TrackingProtectionPolicyFactoryTest { useCustom: Boolean = false, useTrackingProtection: Boolean = false ): Settings = mockk { + every { enabledTotalCookieProtection } returns false every { useStrictTrackingProtection } returns useStrict every { useCustomTrackingProtection } returns useCustom every { shouldUseTrackingProtection } returns useTrackingProtection diff --git a/nimbus.fml.yaml b/nimbus.fml.yaml index 6f6e48399..d24e768d9 100644 --- a/nimbus.fml.yaml +++ b/nimbus.fml.yaml @@ -202,6 +202,17 @@ features: value: enabled: true + engine-settings: + description: Contains a set of settings for controlling the web engine configurations. + variables: + tabs-prioritization-enabled: + description: If true, enables tabs prioritization feature. + type: Boolean + default: true + total-cookie-protection-enabled: + description: If true, enables the total cookie protection in all browsing modes. + type: Boolean + default: false types: objects: MessageData: