summaryrefslogtreecommitdiffstats
path: root/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java')
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java1975
1 files changed, 1975 insertions, 0 deletions
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java
new file mode 100644
index 0000000000..6135c17d95
--- /dev/null
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java
@@ -0,0 +1,1975 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * vim: ts=4 sw=4 expandtab:
+ * 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.geckoview;
+
+import android.annotation.SuppressLint;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import androidx.annotation.AnyThread;
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.mozilla.gecko.util.GeckoBundle;
+
+/** Content Blocking API to hold and control anti-tracking, cookie and Safe Browsing settings. */
+@AnyThread
+public class ContentBlocking {
+ /** {@link SafeBrowsingProvider} configuration for Google's legacy SafeBrowsing server. */
+ public static final SafeBrowsingProvider GOOGLE_LEGACY_SAFE_BROWSING_PROVIDER =
+ SafeBrowsingProvider.withName("google")
+ .version("2.2")
+ .lists(
+ "goog-badbinurl-shavar",
+ "goog-downloadwhite-digest256",
+ "goog-phish-shavar",
+ "googpub-phish-shavar",
+ "goog-malware-shavar",
+ "goog-unwanted-shavar")
+ .updateUrl(
+ "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%MAJOR_VERSION%&pver=2.2&key=%GOOGLE_SAFEBROWSING_API_KEY%")
+ .getHashUrl(
+ "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%MAJOR_VERSION%&pver=2.2")
+ .reportUrl("https://safebrowsing.google.com/safebrowsing/diagnostic?site=")
+ .reportPhishingMistakeUrl("https://%LOCALE%.phish-error.mozilla.com/?url=")
+ .reportMalwareMistakeUrl("https://%LOCALE%.malware-error.mozilla.com/?url=")
+ .advisoryUrl("https://developers.google.com/safe-browsing/v4/advisory")
+ .advisoryName("Google Safe Browsing")
+ .build();
+
+ /** {@link SafeBrowsingProvider} configuration for Google's SafeBrowsing server. */
+ public static final SafeBrowsingProvider GOOGLE_SAFE_BROWSING_PROVIDER =
+ SafeBrowsingProvider.withName("google4")
+ .version("4")
+ .lists(
+ "goog-badbinurl-proto",
+ "goog-downloadwhite-proto",
+ "goog-phish-proto",
+ "googpub-phish-proto",
+ "goog-malware-proto",
+ "goog-unwanted-proto",
+ "goog-harmful-proto")
+ .updateUrl(
+ "https://safebrowsing.googleapis.com/v4/threatListUpdates:fetch?$ct=application/x-protobuf&key=%GOOGLE_SAFEBROWSING_API_KEY%&$httpMethod=POST")
+ .getHashUrl(
+ "https://safebrowsing.googleapis.com/v4/fullHashes:find?$ct=application/x-protobuf&key=%GOOGLE_SAFEBROWSING_API_KEY%&$httpMethod=POST")
+ .reportUrl("https://safebrowsing.google.com/safebrowsing/diagnostic?site=")
+ .reportPhishingMistakeUrl("https://%LOCALE%.phish-error.mozilla.com/?url=")
+ .reportMalwareMistakeUrl("https://%LOCALE%.malware-error.mozilla.com/?url=")
+ .advisoryUrl("https://developers.google.com/safe-browsing/v4/advisory")
+ .advisoryName("Google Safe Browsing")
+ .dataSharingUrl(
+ "https://safebrowsing.googleapis.com/v4/threatHits?$ct=application/x-protobuf&key=%GOOGLE_SAFEBROWSING_API_KEY%&$httpMethod=POST")
+ .dataSharingEnabled(false)
+ .build();
+
+ // This class shouldn't be instantiated
+ protected ContentBlocking() {}
+
+ @AnyThread
+ public static class Settings extends RuntimeSettings {
+ private final Map<String, SafeBrowsingProvider> mSafeBrowsingProviders = new HashMap<>();
+
+ private static final SafeBrowsingProvider[] DEFAULT_PROVIDERS = {
+ ContentBlocking.GOOGLE_LEGACY_SAFE_BROWSING_PROVIDER,
+ ContentBlocking.GOOGLE_SAFE_BROWSING_PROVIDER
+ };
+
+ @AnyThread
+ public static class Builder extends RuntimeSettings.Builder<Settings> {
+ @Override
+ protected @NonNull Settings newSettings(final @Nullable Settings settings) {
+ return new Settings(settings);
+ }
+
+ /**
+ * Set custom safe browsing providers.
+ *
+ * @param providers one or more custom providers.
+ * @return This Builder instance.
+ * @see SafeBrowsingProvider
+ */
+ public @NonNull Builder safeBrowsingProviders(
+ final @NonNull SafeBrowsingProvider... providers) {
+ getSettings().setSafeBrowsingProviders(providers);
+ return this;
+ }
+
+ /**
+ * Set the safe browsing table for phishing threats.
+ *
+ * @param safeBrowsingPhishingTable one or more lists for safe browsing phishing.
+ * @return This Builder instance.
+ * @see SafeBrowsingProvider
+ */
+ public @NonNull Builder safeBrowsingPhishingTable(
+ final @NonNull String[] safeBrowsingPhishingTable) {
+ getSettings().setSafeBrowsingPhishingTable(safeBrowsingPhishingTable);
+ return this;
+ }
+
+ /**
+ * Set the safe browsing table for malware threats.
+ *
+ * @param safeBrowsingMalwareTable one or more lists for safe browsing malware.
+ * @return This Builder instance.
+ * @see SafeBrowsingProvider
+ */
+ public @NonNull Builder safeBrowsingMalwareTable(
+ final @NonNull String[] safeBrowsingMalwareTable) {
+ getSettings().setSafeBrowsingMalwareTable(safeBrowsingMalwareTable);
+ return this;
+ }
+
+ /**
+ * Set anti-tracking categories.
+ *
+ * @param cat The categories of resources that should be blocked. Use one or more of the
+ * {@link ContentBlocking.AntiTracking} flags.
+ * @return This Builder instance.
+ */
+ public @NonNull Builder antiTracking(final @CBAntiTracking int cat) {
+ getSettings().setAntiTracking(cat);
+ return this;
+ }
+
+ /**
+ * Set safe browsing categories.
+ *
+ * @param cat The categories of resources that should be blocked. Use one or more of the
+ * {@link ContentBlocking.SafeBrowsing} flags.
+ * @return This Builder instance.
+ */
+ public @NonNull Builder safeBrowsing(final @CBSafeBrowsing int cat) {
+ getSettings().setSafeBrowsing(cat);
+ return this;
+ }
+
+ /**
+ * Set cookie storage behavior.
+ *
+ * @param behavior The storage behavior that should be applied. Use one of the {@link
+ * CookieBehavior} flags.
+ * @return The Builder instance.
+ */
+ public @NonNull Builder cookieBehavior(final @CBCookieBehavior int behavior) {
+ getSettings().setCookieBehavior(behavior);
+ return this;
+ }
+
+ /**
+ * Set cookie storage behavior in private browsing mode.
+ *
+ * @param behavior The storage behavior that should be applied. Use one of the {@link
+ * CookieBehavior} flags.
+ * @return The Builder instance.
+ */
+ public @NonNull Builder cookieBehaviorPrivateMode(final @CBCookieBehavior int behavior) {
+ getSettings().setCookieBehaviorPrivateMode(behavior);
+ return this;
+ }
+
+ /**
+ * Set the ETP behavior level.
+ *
+ * @param level The level of ETP blocking to use. Only takes effect if cookie behavior is set
+ * to {@link ContentBlocking.CookieBehavior#ACCEPT_NON_TRACKERS} or {@link
+ * ContentBlocking.CookieBehavior#ACCEPT_FIRST_PARTY_AND_ISOLATE_OTHERS}.
+ * @return The Builder instance.
+ */
+ public @NonNull Builder enhancedTrackingProtectionLevel(final @CBEtpLevel int level) {
+ getSettings().setEnhancedTrackingProtectionLevel(level);
+ return this;
+ }
+
+ /**
+ * Set whether or not email tracker blocking is enabled in private mode.
+ *
+ * @param enabled A boolean indicating whether or not email tracker blocking should be enabled
+ * in private mode.
+ * @return The builder instance.
+ */
+ public @NonNull Builder emailTrackerBlockingPrivateMode(final boolean enabled) {
+ getSettings().setEmailTrackerBlockingPrivateBrowsing(enabled);
+ return this;
+ }
+
+ /**
+ * Set whether or not strict social tracking protection is enabled. This will block resources
+ * from loading if they are on the social tracking protection list, rather than just blocking
+ * cookies as with normal social tracking protection.
+ *
+ * @param enabled A boolean indicating whether or not strict social tracking protection should
+ * be enabled.
+ * @return The builder instance.
+ */
+ public @NonNull Builder strictSocialTrackingProtection(final boolean enabled) {
+ getSettings().setStrictSocialTrackingProtection(enabled);
+ return this;
+ }
+
+ /**
+ * Set whether or not to automatically purge tracking cookies. This will purge cookies from
+ * tracking sites that do not have recent user interaction provided that the cookie behavior
+ * is set to either {@link ContentBlocking.CookieBehavior#ACCEPT_NON_TRACKERS} or {@link
+ * ContentBlocking.CookieBehavior#ACCEPT_FIRST_PARTY_AND_ISOLATE_OTHERS}.
+ *
+ * @param enabled A boolean indicating whether or not cookie purging should be enabled.
+ * @return The builder instance.
+ */
+ public @NonNull Builder cookiePurging(final boolean enabled) {
+ getSettings().setCookiePurging(enabled);
+ return this;
+ }
+
+ /**
+ * Set the Cookie Banner Handling Mode.
+ *
+ * @param mode The mode of the Cookie Banner Handling one of the {@link CBCookieBannerMode}.
+ * @return The Builder instance.
+ */
+ public @NonNull Builder cookieBannerHandlingMode(final @CBCookieBannerMode int mode) {
+ getSettings().setCookieBannerMode(mode);
+ return this;
+ }
+
+ /**
+ * When set to true, enable the use of global CookieBannerRules.
+ *
+ * @param enabled A boolean indicating whether to enable the use of global CookieBannerRules.
+ * @return The Builder instance.
+ */
+ public @NonNull Builder cookieBannerGlobalRulesEnabled(final boolean enabled) {
+ getSettings().setCookieBannerGlobalRulesEnabled(enabled);
+ return this;
+ }
+
+ /**
+ * When set to true, enable the use of global CookieBannerRules in sub-frames.
+ *
+ * @param enabled A boolean indicating whether to enable the use of global CookieBannerRules
+ * in sub-frames.
+ * @return The Builder instance.
+ */
+ public @NonNull Builder cookieBannerGlobalRulesSubFramesEnabled(final boolean enabled) {
+ getSettings().setCookieBannerGlobalRulesSubFramesEnabled(enabled);
+ return this;
+ }
+
+ /**
+ * When set to true, query parameter stripping is enabled in normal mode.
+ *
+ * @param enabled A boolean indicating whether to query parameter stripping enabled in normal
+ * mode.
+ * @return The Builder instance.
+ */
+ public @NonNull Builder queryParameterStrippingEnabled(final boolean enabled) {
+ getSettings().setQueryParameterStrippingEnabled(enabled);
+ return this;
+ }
+
+ /**
+ * When set to true, query parameter stripping is enabled in private mode.
+ *
+ * @param enabled A boolean indicating whether to query parameter stripping enabled in private
+ * mode.
+ * @return The Builder instance.
+ */
+ public @NonNull Builder queryParameterStrippingPrivateBrowsingEnabled(final boolean enabled) {
+ getSettings().setQueryParameterStrippingPrivateBrowsingEnabled(enabled);
+ return this;
+ }
+
+ /**
+ * The allowed list for the query parameter stripping feature.
+ *
+ * @param list an array of identifiers for query parameter's stripping feature.
+ * @return The Builder instance.
+ */
+ public @NonNull Builder queryParameterStrippingAllowList(final @NonNull String... list) {
+ getSettings().setQueryParameterStrippingAllowList(list);
+ return this;
+ }
+
+ /**
+ * The strip list for the query parameter stripping feature.
+ *
+ * @param list an array of identifiers for the strip list of the query parameter's stripping
+ * feature.
+ * @return The Builder instance.
+ */
+ public @NonNull Builder queryParameterStrippingStripList(final @NonNull String... list) {
+ getSettings().setQueryParameterStrippingStripList(list);
+ return this;
+ }
+
+ /**
+ * Set the Cookie Banner Handling Mode for private browsing.
+ *
+ * @param mode The mode of the Cookie Banner Handling one of the {@link CBCookieBannerMode}.
+ * @return The Builder instance.
+ */
+ public @NonNull Builder cookieBannerHandlingModePrivateBrowsing(
+ final @CBCookieBannerMode int mode) {
+ getSettings().setCookieBannerModePrivateBrowsing(mode);
+ return this;
+ }
+
+ /**
+ * When set to true, cookie banners are detected and detection events are dispatched, but they
+ * will not be handled.
+ *
+ * @param enabled A boolean indicating whether to enable cookie banner detect only mode.
+ * @return The Builder instance.
+ */
+ public @NonNull Builder cookieBannerHandlingDetectOnlyMode(final boolean enabled) {
+ getSettings().setCookieBannerDetectOnlyMode(enabled);
+ return this;
+ }
+ }
+
+ /* package */ final Pref<String> mAt =
+ new Pref<String>(
+ "urlclassifier.trackingTable", ContentBlocking.catToAtPref(AntiTracking.DEFAULT));
+ /* package */ final Pref<Boolean> mCm =
+ new Pref<Boolean>("privacy.trackingprotection.cryptomining.enabled", false);
+ /* package */ final Pref<String> mCmList =
+ new Pref<String>(
+ "urlclassifier.features.cryptomining.blacklistTables",
+ ContentBlocking.catToCmListPref(AntiTracking.NONE));
+ /* package */ final Pref<Boolean> mFp =
+ new Pref<Boolean>("privacy.trackingprotection.fingerprinting.enabled", false);
+ /* package */ final Pref<String> mFpList =
+ new Pref<String>(
+ "urlclassifier.features.fingerprinting.blacklistTables",
+ ContentBlocking.catToFpListPref(AntiTracking.NONE));
+ /* package */ final Pref<Boolean> mSt =
+ new Pref<Boolean>("privacy.socialtracking.block_cookies.enabled", false);
+ /* package */ final Pref<Boolean> mStStrict =
+ new Pref<Boolean>("privacy.trackingprotection.socialtracking.enabled", false);
+ /* package */ final Pref<String> mStList =
+ new Pref<String>(
+ "urlclassifier.features.socialtracking.annotate.blacklistTables",
+ ContentBlocking.catToPref(AntiTracking.NONE, AntiTracking.STP, STP));
+
+ /* package */ final Pref<Boolean> mSbMalware =
+ new Pref<Boolean>("browser.safebrowsing.malware.enabled", true);
+ /* package */ final Pref<Boolean> mSbPhishing =
+ new Pref<Boolean>("browser.safebrowsing.phishing.enabled", true);
+ /* package */ final Pref<Integer> mCookieBehavior =
+ new Pref<Integer>("network.cookie.cookieBehavior", CookieBehavior.ACCEPT_NON_TRACKERS);
+ /* package */ final Pref<Integer> mCookieBehaviorPrivateMode =
+ new Pref<Integer>(
+ "network.cookie.cookieBehavior.pbmode", CookieBehavior.ACCEPT_NON_TRACKERS);
+ /* package */ final Pref<Boolean> mCookiePurging =
+ new Pref<Boolean>("privacy.purge_trackers.enabled", false);
+
+ /* package */ final Pref<Boolean> mEtpEnabled =
+ new Pref<Boolean>("privacy.trackingprotection.annotate_channels", false);
+ /* package */ final Pref<Boolean> mEtpStrict =
+ new Pref<Boolean>("privacy.annotate_channels.strict_list.enabled", false);
+
+ /* package */ final Pref<Integer> mCbhMode =
+ new Pref<Integer>(
+ "cookiebanners.service.mode", CookieBannerMode.COOKIE_BANNER_MODE_DISABLED);
+ /* package */ final Pref<Integer> mCbhModePrivateBrowsing =
+ new Pref<Integer>(
+ "cookiebanners.service.mode.privateBrowsing",
+ CookieBannerMode.COOKIE_BANNER_MODE_REJECT);
+
+ /* package */ final Pref<Boolean> mChbDetectOnlyMode =
+ new Pref<Boolean>("cookiebanners.service.detectOnly", false);
+ /* package */
+ final Pref<Boolean> mCbhGlobalRulesEnabled =
+ new Pref<Boolean>("cookiebanners.service.enableGlobalRules", false);
+
+ final Pref<Boolean> mCbhGlobalRulesSubFramesEnabled =
+ new Pref<Boolean>("cookiebanners.service.enableGlobalRules.subFrames", false);
+
+ /* package */ final Pref<Boolean> mQueryParameterStrippingEnabled =
+ new Pref<Boolean>("privacy.query_stripping.enabled", false);
+
+ /* package */ final Pref<Boolean> mQueryParameterStrippingPrivateBrowsingEnabled =
+ new Pref<Boolean>("privacy.query_stripping.enabled.pbmode", false);
+
+ /* package */ final Pref<String> mQueryParameterStrippingAllowList =
+ new Pref<>("privacy.query_stripping.allow_list", "");
+
+ /* package */ final Pref<String> mQueryParameterStrippingStripList =
+ new Pref<>("privacy.query_stripping.strip_list", "");
+
+ /* package */ final Pref<Boolean> mEtb =
+ new Pref<Boolean>("privacy.trackingprotection.emailtracking.enabled", false);
+
+ /* package */ final Pref<Boolean> mEtbPrivateBrowsing =
+ new Pref<Boolean>("privacy.trackingprotection.emailtracking.pbmode.enabled", false);
+
+ /* package */ final Pref<String> mEtbList =
+ new Pref<String>(
+ "urlclassifier.features.emailtracking.blocklistTables",
+ ContentBlocking.catToPref(AntiTracking.NONE, AntiTracking.EMAIL, EMAIL));
+
+ /* package */ final Pref<String> mSafeBrowsingMalwareTable =
+ new Pref<>(
+ "urlclassifier.malwareTable",
+ ContentBlocking.listsToPref(
+ "goog-malware-proto",
+ "goog-unwanted-proto",
+ "moztest-harmful-simple",
+ "moztest-malware-simple",
+ "moztest-unwanted-simple"));
+ /* package */ final Pref<String> mSafeBrowsingPhishingTable =
+ new Pref<>(
+ "urlclassifier.phishTable",
+ ContentBlocking.listsToPref(
+ // In official builds, we are allowed to use Google's private phishing
+ // list (see bug 1288840).
+ BuildConfig.MOZILLA_OFFICIAL ? "goog-phish-proto" : "googpub-phish-proto",
+ "moztest-phish-simple"));
+
+ /** Construct default settings. */
+ /* package */ Settings() {
+ this(null /* settings */);
+ }
+
+ /**
+ * Copy-construct settings.
+ *
+ * @param settings Copy from this settings.
+ */
+ /* package */ Settings(final @Nullable Settings settings) {
+ this(null /* parent */, settings);
+ }
+
+ /**
+ * Copy-construct nested settings.
+ *
+ * @param parent The parent settings used for nesting.
+ * @param settings Copy from this settings.
+ */
+ /* package */ Settings(
+ final @Nullable RuntimeSettings parent, final @Nullable Settings settings) {
+ super(parent);
+
+ if (settings != null) {
+ updatePrefs(settings);
+ } else {
+ // Set default browsing providers
+ setSafeBrowsingProviders(DEFAULT_PROVIDERS);
+ }
+ }
+
+ @Override
+ protected void updatePrefs(final @NonNull RuntimeSettings settings) {
+ super.updatePrefs(settings);
+
+ final ContentBlocking.Settings source = (ContentBlocking.Settings) settings;
+ for (final SafeBrowsingProvider provider : source.mSafeBrowsingProviders.values()) {
+ mSafeBrowsingProviders.put(provider.getName(), new SafeBrowsingProvider(this, provider));
+ }
+ }
+
+ /**
+ * Get the collection of {@link SafeBrowsingProvider} for this runtime.
+ *
+ * @return an unmodifiable collection of {@link SafeBrowsingProvider}
+ * @see SafeBrowsingProvider
+ */
+ public @NonNull Collection<SafeBrowsingProvider> getSafeBrowsingProviders() {
+ return Collections.unmodifiableCollection(mSafeBrowsingProviders.values());
+ }
+
+ /**
+ * Sets the collection of {@link SafeBrowsingProvider} for this runtime.
+ *
+ * <p>By default the collection is composed of {@link
+ * ContentBlocking#GOOGLE_LEGACY_SAFE_BROWSING_PROVIDER} and {@link
+ * ContentBlocking#GOOGLE_SAFE_BROWSING_PROVIDER}.
+ *
+ * @param providers {@link SafeBrowsingProvider} instances for this runtime.
+ * @return the {@link Settings} instance.
+ * @see SafeBrowsingProvider
+ */
+ public @NonNull Settings setSafeBrowsingProviders(
+ final @NonNull SafeBrowsingProvider... providers) {
+ mSafeBrowsingProviders.clear();
+
+ for (final SafeBrowsingProvider provider : providers) {
+ mSafeBrowsingProviders.put(provider.getName(), new SafeBrowsingProvider(this, provider));
+ }
+
+ return this;
+ }
+
+ /**
+ * Get the table for SafeBrowsing Phishing. The identifiers present in this table must match one
+ * of the identifiers present in {@link SafeBrowsingProvider#getLists}.
+ *
+ * @return an array of identifiers for SafeBrowsing's Phishing feature
+ * @see SafeBrowsingProvider.Builder#lists
+ */
+ public @NonNull String[] getSafeBrowsingPhishingTable() {
+ return ContentBlocking.prefToLists(mSafeBrowsingPhishingTable.get());
+ }
+
+ /**
+ * Sets the table for SafeBrowsing Phishing.
+ *
+ * @param table an array of identifiers for SafeBrowsing's Phishing feature.
+ * @return this {@link Settings} instance.
+ * @see SafeBrowsingProvider.Builder#lists
+ */
+ public @NonNull Settings setSafeBrowsingPhishingTable(final @NonNull String... table) {
+ mSafeBrowsingPhishingTable.commit(ContentBlocking.listsToPref(table));
+ return this;
+ }
+
+ /**
+ * Get the table for SafeBrowsing Malware. The identifiers present in this table must match one
+ * of the identifiers present in {@link SafeBrowsingProvider#getLists}.
+ *
+ * @return an array of identifiers for SafeBrowsing's Malware feature
+ * @see SafeBrowsingProvider.Builder#lists
+ */
+ public @NonNull String[] getSafeBrowsingMalwareTable() {
+ return ContentBlocking.prefToLists(mSafeBrowsingMalwareTable.get());
+ }
+
+ /**
+ * Sets the allowed list for the query parameter stripping feature.
+ *
+ * @param list an array of identifiers for the allowed list of the query parameter's stripping
+ * feature.
+ * @return this {@link Settings} instance.
+ */
+ public @NonNull Settings setQueryParameterStrippingAllowList(final @NonNull String... list) {
+ mQueryParameterStrippingAllowList.commit(ContentBlocking.listsToPref(list));
+ return this;
+ }
+
+ /**
+ * Get the allowed list for the query parameter stripping feature.
+ *
+ * @return an array of identifiers for the allowed list for the query parameter stripping
+ * feature.
+ */
+ public @NonNull String[] getQueryParameterStrippingAllowList() {
+ return ContentBlocking.prefToLists(mQueryParameterStrippingAllowList.get());
+ }
+
+ /**
+ * Sets the strip list for the query parameter stripping feature.
+ *
+ * @param list an array of identifiers for the strip list of the query parameter's stripping
+ * feature.
+ * @return this {@link Settings} instance.
+ */
+ public @NonNull Settings setQueryParameterStrippingStripList(final @NonNull String... list) {
+ mQueryParameterStrippingStripList.commit(ContentBlocking.listsToPref(list));
+ return this;
+ }
+
+ /**
+ * Get the strip list for the query parameter stripping feature
+ *
+ * @return an array of identifiers for the allowed list for the query parameter stripping
+ * feature.
+ */
+ public @NonNull String[] getQueryParameterStrippingStripList() {
+ return ContentBlocking.prefToLists(mQueryParameterStrippingStripList.get());
+ }
+
+ /**
+ * Sets the table for SafeBrowsing Malware.
+ *
+ * @param table an array of identifiers for SafeBrowsing's Malware feature.
+ * @return this {@link Settings} instance.
+ * @see SafeBrowsingProvider.Builder#lists
+ */
+ public @NonNull Settings setSafeBrowsingMalwareTable(final @NonNull String... table) {
+ mSafeBrowsingMalwareTable.commit(ContentBlocking.listsToPref(table));
+ return this;
+ }
+
+ /**
+ * Set anti-tracking categories.
+ *
+ * @param cat The categories of resources that should be blocked. Use one or more of the {@link
+ * ContentBlocking.AntiTracking} flags.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setAntiTracking(final @CBAntiTracking int cat) {
+ mAt.commit(ContentBlocking.catToAtPref(cat));
+
+ mCm.commit(ContentBlocking.catToCmPref(cat));
+ mCmList.commit(ContentBlocking.catToCmListPref(cat));
+
+ mFp.commit(ContentBlocking.catToFpPref(cat));
+ mFpList.commit(ContentBlocking.catToFpListPref(cat));
+
+ mSt.commit(ContentBlocking.catToStPref(cat));
+ mStList.commit(ContentBlocking.catToPref(cat, AntiTracking.STP, STP));
+
+ mEtb.commit(ContentBlocking.catToEtbPref(cat));
+ mEtbList.commit(ContentBlocking.catToPref(cat, AntiTracking.EMAIL, EMAIL));
+ return this;
+ }
+
+ /**
+ * Set the ETP behavior level.
+ *
+ * @param level The level of ETP blocking to use; must be one of {@link
+ * ContentBlocking.EtpLevel} flags. Only takes effect if the cookie behavior is {@link
+ * ContentBlocking.CookieBehavior#ACCEPT_NON_TRACKERS} or {@link
+ * ContentBlocking.CookieBehavior#ACCEPT_FIRST_PARTY_AND_ISOLATE_OTHERS}.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setEnhancedTrackingProtectionLevel(final @CBEtpLevel int level) {
+ mEtpEnabled.commit(
+ level == ContentBlocking.EtpLevel.DEFAULT || level == ContentBlocking.EtpLevel.STRICT);
+ mEtpStrict.commit(level == ContentBlocking.EtpLevel.STRICT);
+ return this;
+ }
+
+ /**
+ * Set whether or not strict social tracking protection is enabled (ie, whether to block content
+ * or just cookies). Will only block if social tracking protection lists are supplied to {@link
+ * #setAntiTracking}.
+ *
+ * @param enabled A boolean indicating whether or not to enable strict social tracking
+ * protection.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setStrictSocialTrackingProtection(final boolean enabled) {
+ mStStrict.commit(enabled);
+ return this;
+ }
+
+ /**
+ * Set safe browsing categories.
+ *
+ * @param cat The categories of resources that should be blocked. Use one or more of the {@link
+ * ContentBlocking.SafeBrowsing} flags.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setSafeBrowsing(final @CBSafeBrowsing int cat) {
+ mSbMalware.commit(ContentBlocking.catToSbMalware(cat));
+ mSbPhishing.commit(ContentBlocking.catToSbPhishing(cat));
+ return this;
+ }
+
+ /**
+ * Get the set anti-tracking categories.
+ *
+ * @return The categories of resources to be blocked.
+ */
+ public @CBAntiTracking int getAntiTrackingCategories() {
+ return ContentBlocking.atListToAtCat(mAt.get())
+ | ContentBlocking.cmListToAtCat(mCmList.get())
+ | ContentBlocking.fpListToAtCat(mFpList.get())
+ | ContentBlocking.stListToAtCat(mStList.get())
+ | ContentBlocking.etbListToAtCat(mEtbList.get());
+ }
+
+ /**
+ * Get the set ETP behavior level.
+ *
+ * @return The current ETP level; one of {@link ContentBlocking.EtpLevel}.
+ */
+ public @CBEtpLevel int getEnhancedTrackingProtectionLevel() {
+ if (mEtpStrict.get()) {
+ return ContentBlocking.EtpLevel.STRICT;
+ } else if (mEtpEnabled.get()) {
+ return ContentBlocking.EtpLevel.DEFAULT;
+ }
+ return ContentBlocking.EtpLevel.NONE;
+ }
+
+ /**
+ * Get whether or not strict social tracking protection is enabled.
+ *
+ * @return A boolean indicating whether or not strict social tracking protection is enabled.
+ */
+ public boolean getStrictSocialTrackingProtection() {
+ return mStStrict.get();
+ }
+
+ /**
+ * Get the set safe browsing categories.
+ *
+ * @return The categories of resources to be blocked.
+ */
+ public @CBSafeBrowsing int getSafeBrowsingCategories() {
+ return ContentBlocking.sbMalwareToSbCat(mSbMalware.get())
+ | ContentBlocking.sbPhishingToSbCat(mSbPhishing.get());
+ }
+
+ /**
+ * Get the assigned cookie storage behavior.
+ *
+ * @return The assigned behavior, as one of {@link CookieBehavior} flags.
+ */
+ @SuppressLint("WrongConstant")
+ public @CBCookieBehavior int getCookieBehavior() {
+ return mCookieBehavior.get();
+ }
+
+ /**
+ * Set cookie storage behavior.
+ *
+ * @param behavior The storage behavior that should be applied. Use one of the {@link
+ * CookieBehavior} flags.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setCookieBehavior(final @CBCookieBehavior int behavior) {
+ mCookieBehavior.commit(behavior);
+ return this;
+ }
+
+ /**
+ * Get the assigned private mode cookie storage behavior.
+ *
+ * @return The assigned behavior, as one of {@link CookieBehavior} flags.
+ */
+ @SuppressLint("WrongConstant")
+ public @CBCookieBehavior int getCookieBehaviorPrivateMode() {
+ return mCookieBehaviorPrivateMode.get();
+ }
+
+ /**
+ * Set cookie storage behavior for private browsing mode.
+ *
+ * @param behavior The storage behavior that should be applied. Use one of the {@link
+ * CookieBehavior} flags.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setCookieBehaviorPrivateMode(final @CBCookieBehavior int behavior) {
+ mCookieBehaviorPrivateMode.commit(behavior);
+ return this;
+ }
+
+ /**
+ * Get whether or not cookie purging is enabled.
+ *
+ * @return A boolean indicating whether or not cookie purging is enabled.
+ */
+ public boolean getCookiePurging() {
+ return mCookiePurging.get();
+ }
+
+ /**
+ * Enable or disable cookie purging. This will automatically purge cookies from tracking sites
+ * that have no recent user interaction, provided the cookie behavior is set to {@link
+ * ContentBlocking.CookieBehavior#ACCEPT_NON_TRACKERS} or {@link
+ * ContentBlocking.CookieBehavior#ACCEPT_FIRST_PARTY_AND_ISOLATE_OTHERS}.
+ *
+ * @param enabled A boolean indicating whether to enable cookie purging.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setCookiePurging(final boolean enabled) {
+ mCookiePurging.commit(enabled);
+ return this;
+ }
+
+ /**
+ * Set the Cookie Banner Handling Mode to the new provided {@link CBCookieBannerMode} value.
+ *
+ * @param mode Integer indicating the new mode.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setCookieBannerMode(final @CBCookieBannerMode int mode) {
+ mCbhMode.commit(mode);
+ return this;
+ }
+
+ /**
+ * When set to true, cookie banners are detected and detection events are dispatched, but they
+ * will not be handled. Requires the service to be enabled for the desired mode via
+ * setCookieBannerMode.
+ *
+ * @param enabled A boolean indicating whether to enable cookie banners.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setCookieBannerDetectOnlyMode(final boolean enabled) {
+ mChbDetectOnlyMode.commit(enabled);
+ return this;
+ }
+
+ /**
+ * Enables/disables the use of global CookieBannerRules, which apply to all sites. This enable
+ * handling of CMPs across sites without the use of site-specific rules.
+ *
+ * @param enabled A boolean indicating whether or not to enable.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setCookieBannerGlobalRulesEnabled(final boolean enabled) {
+ mCbhGlobalRulesEnabled.commit(enabled);
+ return this;
+ }
+
+ /**
+ * Indicates if global CookieBannerRules is enabled or not.
+ *
+ * @return Indicates if global CookieBannerRule is enabled or disabled.
+ */
+ public boolean getCookieBannerGlobalRulesEnabled() {
+ return mCbhGlobalRulesEnabled.get();
+ }
+
+ /**
+ * Whether global rules are allowed to run in sub-frames. Running query selectors in every
+ * sub-frame may negatively impact performance, but is required for some CMPs.
+ *
+ * @param enabled A boolean indicating whether or not to enable.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setCookieBannerGlobalRulesSubFramesEnabled(final boolean enabled) {
+ mCbhGlobalRulesSubFramesEnabled.commit(enabled);
+ return this;
+ }
+
+ /**
+ * Indicates if email tracker blocking is enabled in private mode.
+ *
+ * @return Indicates if email tracker blocking is enabled or disabled in private mode.
+ */
+ public @NonNull Boolean getEmailTrackerBlockingPrivateBrowsingEnabled() {
+ return mEtbPrivateBrowsing.get();
+ }
+
+ /**
+ * Sets whether email tracker blocking is enabled in private mode.
+ *
+ * @param enabled A boolean indicating whether or not to enable.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setEmailTrackerBlockingPrivateBrowsing(final boolean enabled) {
+ mEtbPrivateBrowsing.commit(enabled);
+ return this;
+ }
+
+ /**
+ * Sets whether query parameter stripping is enabled in normal mode.
+ *
+ * @param enabled A boolean indicating whether or not to enable.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setQueryParameterStrippingEnabled(final boolean enabled) {
+ mQueryParameterStrippingEnabled.commit(enabled);
+ return this;
+ }
+
+ /**
+ * Indicates if query parameter stripping is enabled in normal mode.
+ *
+ * @return Indicates if query parameter stripping is enabled or disabled in normal mode.
+ */
+ public boolean getQueryParameterStrippingEnabled() {
+ return mQueryParameterStrippingEnabled.get();
+ }
+
+ /**
+ * Sets Whether query parameter stripping is enabled in private mode.
+ *
+ * @param enabled A boolean indicating whether or not to enable in private mode.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setQueryParameterStrippingPrivateBrowsingEnabled(
+ final boolean enabled) {
+ mQueryParameterStrippingPrivateBrowsingEnabled.commit(enabled);
+ return this;
+ }
+
+ /**
+ * Indicates if query parameter stripping is enabled in private mode.
+ *
+ * @return Indicates if global CookieBannerRules is enabled or disabled in sub-frames.
+ */
+ public boolean getQueryParameterStrippingPrivateBrowsingEnabled() {
+ return mQueryParameterStrippingPrivateBrowsingEnabled.get();
+ }
+
+ /**
+ * Indicates if global CookieBannerRules is enabled or not in sub-frames.
+ *
+ * @return Indicates if global CookieBannerRules is enabled or disabled in sub-frames.
+ */
+ public boolean getCookieBannerGlobalRulesSubFramesEnabled() {
+ return mCbhGlobalRulesSubFramesEnabled.get();
+ }
+
+ /**
+ * Indicates if cookie banner handling detect only mode is enabled.
+ *
+ * @return boolean indicating if the cookie banner handling detect only mode setting is enabled.
+ */
+ public boolean getCookieBannerDetectOnlyMode() {
+ return mChbDetectOnlyMode.get();
+ }
+
+ /**
+ * Gets the current cookie banner handling mode.
+ *
+ * @return int the current cookie banner handling mode, one of the {@link CBCookieBannerMode}.
+ */
+ @SuppressLint("WrongConstant")
+ public @CBCookieBannerMode int getCookieBannerMode() {
+ return mCbhMode.get();
+ }
+
+ /**
+ * Set the Cookie Banner Handling Mode for private browsing to the new provided {@link
+ * CBCookieBannerMode} value.
+ *
+ * @param mode Integer indicating the new mode.
+ * @return This Settings instance.
+ */
+ public @NonNull Settings setCookieBannerModePrivateBrowsing(
+ final @CBCookieBannerMode int mode) {
+ mCbhModePrivateBrowsing.commit(mode);
+ return this;
+ }
+
+ /**
+ * Gets the current cookie banner handling mode for private browsing.
+ *
+ * @return int the current cookie banner handling mode, one of the {@link CBCookieBannerMode}.
+ */
+ @SuppressLint("WrongConstant")
+ public @CBCookieBannerMode int getCookieBannerModePrivateBrowsing() {
+ return mCbhModePrivateBrowsing.get();
+ }
+
+ public static final Parcelable.Creator<Settings> CREATOR =
+ new Parcelable.Creator<Settings>() {
+ @Override
+ public Settings createFromParcel(final Parcel in) {
+ final Settings settings = new Settings();
+ settings.readFromParcel(in);
+ return settings;
+ }
+
+ @Override
+ public Settings[] newArray(final int size) {
+ return new Settings[size];
+ }
+ };
+ }
+
+ /**
+ * Holds configuration for a SafeBrowsing provider. <br>
+ * <br>
+ * This class can be used to modify existing configuration for SafeBrowsing providers or to add a
+ * custom SafeBrowsing provider to the app. <br>
+ * <br>
+ * Default configuration for Google's SafeBrowsing servers can be found at {@link
+ * ContentBlocking#GOOGLE_SAFE_BROWSING_PROVIDER} and {@link
+ * ContentBlocking#GOOGLE_LEGACY_SAFE_BROWSING_PROVIDER}. <br>
+ * <br>
+ * This class is immutable, once constructed its values cannot be changed. <br>
+ * <br>
+ * You can, however, use the {@link #from} method to build upon an existing configuration. For
+ * example to override the Google's server configuration, you can do the following: <br>
+ *
+ * <pre><code>
+ * SafeBrowsingProvider override = SafeBrowsingProvider
+ * .from(ContentBlocking.GOOGLE_SAFE_BROWSING_PROVIDER)
+ * .getHashUrl("http://my-custom-server.com/...")
+ * .updateUrl("http://my-custom-server.com/...")
+ * .build();
+ *
+ * runtime.getContentBlocking().setSafeBrowsingProviders(override);
+ * </code></pre>
+ *
+ * This will override the configuration. <br>
+ * <br>
+ * You can also add a custom SafeBrowsing provider using the {@link #withName} method. For
+ * example, to add a custom provider that provides the list <code>testprovider-phish-digest256
+ * </code> do the following: <br>
+ *
+ * <pre><code>
+ * SafeBrowsingProvider custom = SafeBrowsingProvider
+ * .withName("custom-provider")
+ * .version("2.2")
+ * .lists("testprovider-phish-digest256")
+ * .updateUrl("http://my-custom-server2.com/...")
+ * .getHashUrl("http://my-custom-server2.com/...")
+ * .build();
+ * </code></pre>
+ *
+ * And then add the custom provider (adding optionally existing providers): <br>
+ *
+ * <pre><code>
+ * runtime.getContentBlocking().setSafeBrowsingProviders(
+ * custom,
+ * // Add this if you want to keep the existing configuration too.
+ * ContentBlocking.GOOGLE_SAFE_BROWSING_PROVIDER,
+ * ContentBlocking.GOOGLE_LEGACY_SAFE_BROWSING_PROVIDER);
+ * </code></pre>
+ *
+ * And set the list in the phishing configuration <br>
+ *
+ * <pre><code>
+ * runtime.getContentBlocking().setSafeBrowsingPhishingTable(
+ * "testprovider-phish-digest256",
+ * // Existing configuration
+ * "goog-phish-proto");
+ * </code></pre>
+ *
+ * Note that any list present in the phishing or malware tables need to appear in one safe
+ * browsing provider's {@link #getLists} property.
+ *
+ * <p>See also <a href="https://developers.google.com/safe-browsing/v4">safe-browsing/v4</a>.
+ */
+ @AnyThread
+ public static class SafeBrowsingProvider extends RuntimeSettings {
+ private static final String ROOT = "browser.safebrowsing.provider.";
+
+ private final String mName;
+
+ /* package */ final Pref<String> mVersion;
+ /* package */ final Pref<String> mLists;
+ /* package */ final Pref<String> mUpdateUrl;
+ /* package */ final Pref<String> mGetHashUrl;
+ /* package */ final Pref<String> mReportUrl;
+ /* package */ final Pref<String> mReportPhishingMistakeUrl;
+ /* package */ final Pref<String> mReportMalwareMistakeUrl;
+ /* package */ final Pref<String> mAdvisoryUrl;
+ /* package */ final Pref<String> mAdvisoryName;
+ /* package */ final Pref<String> mDataSharingUrl;
+ /* package */ final Pref<Boolean> mDataSharingEnabled;
+
+ /**
+ * Creates a {@link SafeBrowsingProvider.Builder} for a provider with the given name.
+ *
+ * <p>Note: the <code>mozilla</code> name is reserved for internal use, and this method will
+ * throw if you attempt to build a provider with that name.
+ *
+ * @param name The name of the provider.
+ * @return a {@link Builder} instance that can be used to build a provider.
+ * @throws IllegalArgumentException if this method is called with <code>name="mozilla"</code>
+ */
+ @NonNull
+ public static Builder withName(final @NonNull String name) {
+ if ("mozilla".equals(name)) {
+ throw new IllegalArgumentException("The 'mozilla' name is reserved for internal use.");
+ }
+ return new Builder(name);
+ }
+
+ /**
+ * Creates a {@link SafeBrowsingProvider.Builder} based on the given provider.
+ *
+ * <p>All properties not otherwise specified will be copied from the provider given in input.
+ *
+ * @param provider The source provider for this builder.
+ * @return a {@link Builder} instance that can be used to create a configuration based on the
+ * builder in input.
+ */
+ @NonNull
+ public static Builder from(final @NonNull SafeBrowsingProvider provider) {
+ return new Builder(provider);
+ }
+
+ @AnyThread
+ public static class Builder {
+ final SafeBrowsingProvider mProvider;
+
+ private Builder(final String name) {
+ mProvider = new SafeBrowsingProvider(name);
+ }
+
+ private Builder(final SafeBrowsingProvider source) {
+ mProvider = new SafeBrowsingProvider(source);
+ }
+
+ /**
+ * Sets the SafeBrowsing protocol session for this provider.
+ *
+ * @param version the version strong, e.g. "2.2" or "4".
+ * @return this {@link Builder} instance.
+ */
+ public @NonNull Builder version(final @NonNull String version) {
+ mProvider.mVersion.set(version);
+ return this;
+ }
+
+ /**
+ * Sets the lists provided by this provider.
+ *
+ * @param lists one or more lists for this provider, e.g. "goog-malware-proto",
+ * "goog-unwanted-proto"
+ * @return this {@link Builder} instance.
+ */
+ public @NonNull Builder lists(final @NonNull String... lists) {
+ mProvider.mLists.set(ContentBlocking.listsToPref(lists));
+ return this;
+ }
+
+ /**
+ * Sets the url that will be used to update the threat list for this provider.
+ *
+ * <p>See also <a
+ * href="https://developers.google.com/safe-browsing/v4/reference/rest/v4/threatListUpdates/fetch">
+ * v4/threadListUpdates/fetch </a>.
+ *
+ * @param updateUrl the update url endpoint for this provider
+ * @return this {@link Builder} instance.
+ */
+ public @NonNull Builder updateUrl(final @NonNull String updateUrl) {
+ mProvider.mUpdateUrl.set(updateUrl);
+ return this;
+ }
+
+ /**
+ * Sets the url that will be used to get the full hashes that match a partial hash.
+ *
+ * <p>See also <a
+ * href="https://developers.google.com/safe-browsing/v4/reference/rest/v4/fullHashes/find">
+ * v4/fullHashes/find </a>.
+ *
+ * @param getHashUrl the gethash url endpoint for this provider
+ * @return this {@link Builder} instance.
+ */
+ public @NonNull Builder getHashUrl(final @NonNull String getHashUrl) {
+ mProvider.mGetHashUrl.set(getHashUrl);
+ return this;
+ }
+
+ /**
+ * Set the url that will be used to report a url to the SafeBrowsing provider.
+ *
+ * @param reportUrl the url endpoint to report a url to this provider.
+ * @return this {@link Builder} instance.
+ */
+ public @NonNull Builder reportUrl(final @NonNull String reportUrl) {
+ mProvider.mReportUrl.set(reportUrl);
+ return this;
+ }
+
+ /**
+ * Set the url that will be used to report a url mistakenly reported as Phishing to the
+ * SafeBrowsing provider.
+ *
+ * @param reportPhishingMistakeUrl the url endpoint to report a url to this provider.
+ * @return this {@link Builder} instance.
+ */
+ public @NonNull Builder reportPhishingMistakeUrl(
+ final @NonNull String reportPhishingMistakeUrl) {
+ mProvider.mReportPhishingMistakeUrl.set(reportPhishingMistakeUrl);
+ return this;
+ }
+
+ /**
+ * Set the url that will be used to report a url mistakenly reported as Malware to the
+ * SafeBrowsing provider.
+ *
+ * @param reportMalwareMistakeUrl the url endpoint to report a url to this provider.
+ * @return this {@link Builder} instance.
+ */
+ public @NonNull Builder reportMalwareMistakeUrl(
+ final @NonNull String reportMalwareMistakeUrl) {
+ mProvider.mReportMalwareMistakeUrl.set(reportMalwareMistakeUrl);
+ return this;
+ }
+
+ /**
+ * Set the url that will be used to give a general advisory about this SafeBrowsing provider.
+ *
+ * @param advisoryUrl the adivisory page url for this provider.
+ * @return this {@link Builder} instance.
+ */
+ public @NonNull Builder advisoryUrl(final @NonNull String advisoryUrl) {
+ mProvider.mAdvisoryUrl.set(advisoryUrl);
+ return this;
+ }
+
+ /**
+ * Set the advisory name for this provider.
+ *
+ * @param advisoryName the adivisory name for this provider.
+ * @return this {@link Builder} instance.
+ */
+ public @NonNull Builder advisoryName(final @NonNull String advisoryName) {
+ mProvider.mAdvisoryName.set(advisoryName);
+ return this;
+ }
+
+ /**
+ * Set url to share threat data to the provider, if enabled by {@link #dataSharingEnabled}.
+ *
+ * @param dataSharingUrl the url endpoint
+ * @return this {@link Builder} instance.
+ */
+ public @NonNull Builder dataSharingUrl(final @NonNull String dataSharingUrl) {
+ mProvider.mDataSharingUrl.set(dataSharingUrl);
+ return this;
+ }
+
+ /**
+ * Set whether to share threat data with the provider, off by default.
+ *
+ * @param dataSharingEnabled <code>true</code> if the browser should share threat data with
+ * the provider.
+ * @return this {@link Builder} instance.
+ */
+ public @NonNull Builder dataSharingEnabled(final boolean dataSharingEnabled) {
+ mProvider.mDataSharingEnabled.set(dataSharingEnabled);
+ return this;
+ }
+
+ /**
+ * Build the {@link SafeBrowsingProvider} based on this {@link Builder} instance.
+ *
+ * @return thie {@link SafeBrowsingProvider} instance.
+ */
+ public @NonNull SafeBrowsingProvider build() {
+ return new SafeBrowsingProvider(mProvider);
+ }
+ }
+
+ /* package */ SafeBrowsingProvider(final SafeBrowsingProvider source) {
+ this(/* name */ null, /* parent */ null, source);
+ }
+
+ /* package */ SafeBrowsingProvider(
+ final RuntimeSettings parent, final SafeBrowsingProvider source) {
+ this(/* name */ null, parent, source);
+ }
+
+ /* package */ SafeBrowsingProvider(final String name) {
+ this(name, /* parent */ null, /* source */ null);
+ }
+
+ /* package */ SafeBrowsingProvider(
+ final String name, final RuntimeSettings parent, final SafeBrowsingProvider source) {
+ super(parent);
+
+ if (name != null) {
+ mName = name;
+ } else if (source != null) {
+ mName = source.mName;
+ } else {
+ throw new IllegalArgumentException("Either name or source must be non-null");
+ }
+
+ mVersion = new Pref<>(ROOT + mName + ".pver", null);
+ mLists = new Pref<>(ROOT + mName + ".lists", null);
+ mUpdateUrl = new Pref<>(ROOT + mName + ".updateURL", null);
+ mGetHashUrl = new Pref<>(ROOT + mName + ".gethashURL", null);
+ mReportUrl = new Pref<>(ROOT + mName + ".reportURL", null);
+ mReportPhishingMistakeUrl = new Pref<>(ROOT + mName + ".reportPhishMistakeURL", null);
+ mReportMalwareMistakeUrl = new Pref<>(ROOT + mName + ".reportMalwareMistakeURL", null);
+ mAdvisoryUrl = new Pref<>(ROOT + mName + ".advisoryURL", null);
+ mAdvisoryName = new Pref<>(ROOT + mName + ".advisoryName", null);
+ mDataSharingUrl = new Pref<>(ROOT + mName + ".dataSharingURL", null);
+ mDataSharingEnabled = new Pref<>(ROOT + mName + ".dataSharing.enabled", false);
+
+ if (source != null) {
+ updatePrefs(source);
+ }
+ }
+
+ /**
+ * Get the name of this provider.
+ *
+ * @return a string containing the name.
+ */
+ public @NonNull String getName() {
+ return mName;
+ }
+
+ /**
+ * Get the version for this provider.
+ *
+ * @return a string representing the version, e.g. "2.2" or "4".
+ */
+ public @Nullable String getVersion() {
+ return mVersion.get();
+ }
+
+ /**
+ * Get the lists provided by this provider.
+ *
+ * @return an array of string identifiers for the lists
+ */
+ public @NonNull String[] getLists() {
+ return ContentBlocking.prefToLists(mLists.get());
+ }
+
+ /**
+ * Get the url that will be used to update the threat list for this provider.
+ *
+ * <p>See also <a
+ * href="https://developers.google.com/safe-browsing/v4/reference/rest/v4/threatListUpdates/fetch">
+ * v4/threadListUpdates/fetch </a>.
+ *
+ * @return a string containing the URL.
+ */
+ public @Nullable String getUpdateUrl() {
+ return mUpdateUrl.get();
+ }
+
+ /**
+ * Get the url that will be used to get the full hashes that match a partial hash.
+ *
+ * <p>See also <a
+ * href="https://developers.google.com/safe-browsing/v4/reference/rest/v4/fullHashes/find">
+ * v4/fullHashes/find </a>.
+ *
+ * @return a string containing the URL.
+ */
+ public @Nullable String getGetHashUrl() {
+ return mGetHashUrl.get();
+ }
+
+ /**
+ * Get the url that will be used to report a url to the SafeBrowsing provider.
+ *
+ * @return a string containing the URL.
+ */
+ public @Nullable String getReportUrl() {
+ return mReportUrl.get();
+ }
+
+ /**
+ * Get the url that will be used to report a url mistakenly reported as Phishing to the
+ * SafeBrowsing provider.
+ *
+ * @return a string containing the URL.
+ */
+ public @Nullable String getReportPhishingMistakeUrl() {
+ return mReportPhishingMistakeUrl.get();
+ }
+
+ /**
+ * Get the url that will be used to report a url mistakenly reported as Malware to the
+ * SafeBrowsing provider.
+ *
+ * @return a string containing the URL.
+ */
+ public @Nullable String getReportMalwareMistakeUrl() {
+ return mReportMalwareMistakeUrl.get();
+ }
+
+ /**
+ * Get the url that will be used to give a general advisory about this SafeBrowsing provider.
+ *
+ * @return a string containing the URL.
+ */
+ public @Nullable String getAdvisoryUrl() {
+ return mAdvisoryUrl.get();
+ }
+
+ /**
+ * Get the advisory name for this provider.
+ *
+ * @return a string containing the URL.
+ */
+ public @Nullable String getAdvisoryName() {
+ return mAdvisoryName.get();
+ }
+
+ /**
+ * Get the url to share threat data to the provider, if enabled by {@link
+ * #getDataSharingEnabled}.
+ *
+ * @return this {@link Builder} instance.
+ */
+ public @Nullable String getDataSharingUrl() {
+ return mDataSharingUrl.get();
+ }
+
+ /**
+ * Get whether to share threat data with the provider.
+ *
+ * @return <code>true</code> if the browser should whare threat data with the provider, <code>
+ * false</code> otherwise.
+ */
+ public @Nullable Boolean getDataSharingEnabled() {
+ return mDataSharingEnabled.get();
+ }
+
+ @Override // Parcelable
+ @AnyThread
+ public void writeToParcel(final Parcel out, final int flags) {
+ out.writeValue(mName);
+ super.writeToParcel(out, flags);
+ }
+
+ /** Creator instance for this class. */
+ public static final Parcelable.Creator<SafeBrowsingProvider> CREATOR =
+ new Parcelable.Creator<SafeBrowsingProvider>() {
+ @Override
+ public SafeBrowsingProvider createFromParcel(final Parcel source) {
+ final String name = (String) source.readValue(getClass().getClassLoader());
+ final SafeBrowsingProvider settings = new SafeBrowsingProvider(name);
+ settings.readFromParcel(source);
+ return settings;
+ }
+
+ @Override
+ public SafeBrowsingProvider[] newArray(final int size) {
+ return new SafeBrowsingProvider[size];
+ }
+ };
+ }
+
+ private static String listsToPref(final String... lists) {
+ final StringBuilder prefBuilder = new StringBuilder();
+
+ for (final String list : lists) {
+ if (list.contains(",")) {
+ // We use ',' as the separator, so the list name cannot contain it.
+ // Should never happen.
+ throw new IllegalArgumentException("List name cannot contain ',' character.");
+ }
+
+ prefBuilder.append(list);
+ prefBuilder.append(",");
+ }
+
+ // Remove trailing ","
+ if (lists.length > 0) {
+ prefBuilder.setLength(prefBuilder.length() - 1);
+ }
+
+ return prefBuilder.toString();
+ }
+
+ private static String[] prefToLists(final String pref) {
+ return pref != null ? pref.split(",") : new String[] {};
+ }
+
+ public static class AntiTracking {
+ public static final int NONE = 0;
+
+ /** Block advertisement trackers. */
+ public static final int AD = 1 << 1;
+
+ /** Block analytics trackers. */
+ public static final int ANALYTIC = 1 << 2;
+
+ /**
+ * Block social trackers. Note: This is not the same as "Social Tracking Protection", which is
+ * controlled by {@link #STP}.
+ */
+ public static final int SOCIAL = 1 << 3;
+
+ /** Block content trackers. May cause issues with some web sites. */
+ public static final int CONTENT = 1 << 4;
+
+ /** Block Gecko test trackers (used for tests). */
+ public static final int TEST = 1 << 5;
+
+ /** Block cryptocurrency miners. */
+ public static final int CRYPTOMINING = 1 << 6;
+
+ /** Block fingerprinting trackers. */
+ public static final int FINGERPRINTING = 1 << 7;
+
+ /** Block trackers on the Social Tracking Protection list. */
+ public static final int STP = 1 << 8;
+
+ /** Block email trackers */
+ public static final int EMAIL = 1 << 9;
+
+ /** Block ad, analytic, social and test trackers. */
+ public static final int DEFAULT = AD | ANALYTIC | SOCIAL | TEST;
+
+ /** Block all known trackers. May cause issues with some web sites. */
+ public static final int STRICT = DEFAULT | CONTENT | CRYPTOMINING | FINGERPRINTING | EMAIL;
+
+ protected AntiTracking() {}
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ flag = true,
+ value = {
+ AntiTracking.AD,
+ AntiTracking.ANALYTIC,
+ AntiTracking.SOCIAL,
+ AntiTracking.CONTENT,
+ AntiTracking.TEST,
+ AntiTracking.CRYPTOMINING,
+ AntiTracking.FINGERPRINTING,
+ AntiTracking.DEFAULT,
+ AntiTracking.STRICT,
+ AntiTracking.STP,
+ AntiTracking.EMAIL,
+ AntiTracking.NONE
+ })
+ public @interface CBAntiTracking {}
+
+ public static class SafeBrowsing {
+ public static final int NONE = 0;
+
+ /** Block malware sites. */
+ public static final int MALWARE = 1 << 10;
+
+ /** Block unwanted sites. */
+ public static final int UNWANTED = 1 << 11;
+
+ /** Block harmful sites. */
+ public static final int HARMFUL = 1 << 12;
+
+ /** Block phishing sites. */
+ public static final int PHISHING = 1 << 13;
+
+ /** Block all unsafe sites. */
+ public static final int DEFAULT = MALWARE | UNWANTED | HARMFUL | PHISHING;
+
+ protected SafeBrowsing() {}
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ flag = true,
+ value = {
+ SafeBrowsing.MALWARE, SafeBrowsing.UNWANTED,
+ SafeBrowsing.HARMFUL, SafeBrowsing.PHISHING,
+ SafeBrowsing.DEFAULT, SafeBrowsing.NONE
+ })
+ public @interface CBSafeBrowsing {}
+
+ // Sync values with nsICookieService.idl.
+ public static class CookieBehavior {
+ /** Accept first-party and third-party cookies and site data. */
+ public static final int ACCEPT_ALL = 0;
+
+ /**
+ * Accept only first-party cookies and site data to block cookies which are not associated with
+ * the domain of the visited site.
+ */
+ public static final int ACCEPT_FIRST_PARTY = 1;
+
+ /** Do not store any cookies and site data. */
+ public static final int ACCEPT_NONE = 2;
+
+ /**
+ * Accept first-party and third-party cookies and site data only from sites previously visited
+ * in a first-party context.
+ */
+ public static final int ACCEPT_VISITED = 3;
+
+ /**
+ * Accept only first-party and non-tracking third-party cookies and site data to block cookies
+ * which are not associated with the domain of the visited site set by known trackers.
+ */
+ public static final int ACCEPT_NON_TRACKERS = 4;
+
+ /**
+ * Enable dynamic first party isolation (dFPI); this will block third-party tracking cookies in
+ * accordance with the ETP level and isolate non-tracking third-party cookies.
+ */
+ public static final int ACCEPT_FIRST_PARTY_AND_ISOLATE_OTHERS = 5;
+
+ protected CookieBehavior() {}
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ CookieBehavior.ACCEPT_ALL, CookieBehavior.ACCEPT_FIRST_PARTY,
+ CookieBehavior.ACCEPT_NONE, CookieBehavior.ACCEPT_VISITED,
+ CookieBehavior.ACCEPT_NON_TRACKERS
+ })
+ public @interface CBCookieBehavior {}
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({EtpLevel.NONE, EtpLevel.DEFAULT, EtpLevel.STRICT})
+ public @interface CBEtpLevel {}
+
+ /** Possible settings for ETP. */
+ public static class EtpLevel {
+ /** Do not enable ETP at all. */
+ public static final int NONE = 0;
+
+ /** Enable ETP for ads, analytic, and social tracking lists. */
+ public static final int DEFAULT = 1;
+
+ /**
+ * Enable ETP for all of the default lists as well as the content list. May break many sites!
+ */
+ public static final int STRICT = 2;
+ }
+
+ /** Holds content block event details. */
+ public static class BlockEvent {
+ /** The URI of the blocked resource. */
+ public final @NonNull String uri;
+
+ private final @CBAntiTracking int mAntiTrackingCat;
+ private final @CBSafeBrowsing int mSafeBrowsingCat;
+ private final @CBCookieBehavior int mCookieBehaviorCat;
+ private final boolean mIsBlocking;
+
+ @SuppressWarnings("checkstyle:javadocmethod")
+ public BlockEvent(
+ @NonNull final String uri,
+ final @CBAntiTracking int atCat,
+ final @CBSafeBrowsing int sbCat,
+ final @CBCookieBehavior int cbCat,
+ final boolean isBlocking) {
+ this.uri = uri;
+ this.mAntiTrackingCat = atCat;
+ this.mSafeBrowsingCat = sbCat;
+ this.mCookieBehaviorCat = cbCat;
+ this.mIsBlocking = isBlocking;
+ }
+
+ /**
+ * The anti-tracking category types of the blocked resource.
+ *
+ * @return One or more of the {@link AntiTracking} flags.
+ */
+ @UiThread
+ public @CBAntiTracking int getAntiTrackingCategory() {
+ return mAntiTrackingCat;
+ }
+
+ /**
+ * The safe browsing category types of the blocked resource.
+ *
+ * @return One or more of the {@link SafeBrowsing} flags.
+ */
+ @UiThread
+ public @CBSafeBrowsing int getSafeBrowsingCategory() {
+ return mSafeBrowsingCat;
+ }
+
+ /**
+ * The cookie types of the blocked resource.
+ *
+ * @return One or more of the {@link CookieBehavior} flags.
+ */
+ @UiThread
+ public @CBCookieBehavior int getCookieBehaviorCategory() {
+ return mCookieBehaviorCat;
+ }
+
+ /* package */ static BlockEvent fromBundle(@NonNull final GeckoBundle bundle) {
+ final String uri = bundle.getString("uri");
+ final String blockedList = bundle.getString("blockedList");
+ final String loadedList = TextUtils.join(",", bundle.getStringArray("loadedLists"));
+ final long error = bundle.getLong("error", 0L);
+ final long category = bundle.getLong("category", 0L);
+
+ final String matchedList = blockedList != null ? blockedList : loadedList;
+
+ // Note: Even if loadedList is non-empty it does not necessarily
+ // mean that the event is not a blocking event.
+ final boolean blocking =
+ (blockedList != null || error != 0L || ContentBlocking.isBlockingGeckoCbCat(category));
+
+ return new BlockEvent(
+ uri,
+ ContentBlocking.atListToAtCat(matchedList)
+ | ContentBlocking.cmListToAtCat(matchedList)
+ | ContentBlocking.fpListToAtCat(matchedList)
+ | ContentBlocking.stListToAtCat(matchedList)
+ | ContentBlocking.etbListToAtCat(matchedList),
+ ContentBlocking.errorToSbCat(error),
+ ContentBlocking.geckoCatToCbCat(category),
+ blocking);
+ }
+
+ @UiThread
+ @SuppressWarnings("checkstyle:javadocmethod")
+ public boolean isBlocking() {
+ return mIsBlocking;
+ }
+ }
+
+ /** GeckoSession applications implement this interface to handle content blocking events. */
+ public interface Delegate {
+ /**
+ * A content element has been blocked from loading. Set blocked element categories via {@link
+ * GeckoRuntimeSettings} and enable content blocking via {@link GeckoSessionSettings}.
+ *
+ * @param session The GeckoSession that initiated the callback.
+ * @param event The {@link BlockEvent} details.
+ */
+ @UiThread
+ default void onContentBlocked(
+ @NonNull final GeckoSession session, @NonNull final BlockEvent event) {}
+
+ /**
+ * A content element that could be blocked has been loaded.
+ *
+ * @param session The GeckoSession that initiated the callback.
+ * @param event The {@link BlockEvent} details.
+ */
+ @UiThread
+ default void onContentLoaded(
+ @NonNull final GeckoSession session, @NonNull final BlockEvent event) {}
+ }
+
+ private static final String TEST = "moztest-track-simple";
+ private static final String AD = "ads-track-digest256";
+ private static final String ANALYTIC = "analytics-track-digest256";
+ private static final String SOCIAL = "social-track-digest256";
+ private static final String CONTENT = "content-track-digest256";
+ private static final String CRYPTOMINING = "base-cryptomining-track-digest256";
+ private static final String FINGERPRINTING = "base-fingerprinting-track-digest256";
+ private static final String STP =
+ "social-tracking-protection-facebook-digest256,social-tracking-protection-linkedin-digest256,social-tracking-protection-twitter-digest256";
+ private static final String EMAIL = "base-email-track-digest256";
+
+ /* package */ static @CBSafeBrowsing int sbMalwareToSbCat(final boolean enabled) {
+ return enabled
+ ? (SafeBrowsing.MALWARE | SafeBrowsing.UNWANTED | SafeBrowsing.HARMFUL)
+ : SafeBrowsing.NONE;
+ }
+
+ /* package */ static @CBSafeBrowsing int sbPhishingToSbCat(final boolean enabled) {
+ return enabled ? SafeBrowsing.PHISHING : SafeBrowsing.NONE;
+ }
+
+ /* package */ static boolean catToSbMalware(@CBAntiTracking final int cat) {
+ return (cat & (SafeBrowsing.MALWARE | SafeBrowsing.UNWANTED | SafeBrowsing.HARMFUL)) != 0;
+ }
+
+ /* package */ static boolean catToSbPhishing(@CBAntiTracking final int cat) {
+ return (cat & SafeBrowsing.PHISHING) != 0;
+ }
+
+ /* package */ static String catToAtPref(@CBAntiTracking final int cat) {
+ final StringBuilder builder = new StringBuilder();
+
+ if ((cat & AntiTracking.TEST) != 0) {
+ builder.append(TEST).append(',');
+ }
+ if ((cat & AntiTracking.AD) != 0) {
+ builder.append(AD).append(',');
+ }
+ if ((cat & AntiTracking.ANALYTIC) != 0) {
+ builder.append(ANALYTIC).append(',');
+ }
+ if ((cat & AntiTracking.SOCIAL) != 0) {
+ builder.append(SOCIAL).append(',');
+ }
+ if ((cat & AntiTracking.CONTENT) != 0) {
+ builder.append(CONTENT).append(',');
+ }
+ if (builder.length() == 0) {
+ return "";
+ }
+ // Trim final ','.
+ return builder.substring(0, builder.length() - 1);
+ }
+
+ /* package */ static boolean catToCmPref(@CBAntiTracking final int cat) {
+ return (cat & AntiTracking.CRYPTOMINING) != 0;
+ }
+
+ /* package */ static String catToCmListPref(@CBAntiTracking final int cat) {
+ final StringBuilder builder = new StringBuilder();
+
+ if ((cat & AntiTracking.CRYPTOMINING) != 0) {
+ builder.append(CRYPTOMINING);
+ }
+ return builder.toString();
+ }
+
+ /* package */ static boolean catToFpPref(@CBAntiTracking final int cat) {
+ return (cat & AntiTracking.FINGERPRINTING) != 0;
+ }
+
+ /* package */ static String catToFpListPref(@CBAntiTracking final int cat) {
+ final StringBuilder builder = new StringBuilder();
+
+ if ((cat & AntiTracking.FINGERPRINTING) != 0) {
+ builder.append(FINGERPRINTING);
+ }
+ return builder.toString();
+ }
+
+ /* package */ static @CBAntiTracking int fpListToAtCat(final String list) {
+ int cat = AntiTracking.NONE;
+ if (list == null) {
+ return cat;
+ }
+ if (list.indexOf(FINGERPRINTING) != -1) {
+ cat |= AntiTracking.FINGERPRINTING;
+ }
+ return cat;
+ }
+
+ /* package */ static boolean catToStPref(@CBAntiTracking final int cat) {
+ return (cat & AntiTracking.STP) != 0;
+ }
+
+ /* package */ static boolean catToEtbPref(@CBAntiTracking final int cat) {
+ return (cat & AntiTracking.EMAIL) != 0;
+ }
+
+ /**
+ * Generic method for converting a category of anti-tracking to a Pref.
+ *
+ * @param cat Int representing the enabled anti-tracking blockers.
+ * @param tbCat Int representing the category mask to check for.
+ * @param catPrefString String to return if [cat] contains [tbCat].
+ * @return Pref string if [cat] contains [tbCat] otherwise empty string.
+ */
+ /* package */ static String catToPref(
+ @CBAntiTracking final int cat, final int tbCat, final String catPrefString) {
+ if ((cat & tbCat) != 0) {
+ return catPrefString;
+ } else {
+ return "";
+ }
+ }
+
+ /* package */ static @CBAntiTracking int atListToAtCat(final String list) {
+ int cat = AntiTracking.NONE;
+
+ if (list == null) {
+ return cat;
+ }
+ if (list.indexOf(TEST) != -1) {
+ cat |= AntiTracking.TEST;
+ }
+ if (list.indexOf(AD) != -1) {
+ cat |= AntiTracking.AD;
+ }
+ if (list.indexOf(ANALYTIC) != -1) {
+ cat |= AntiTracking.ANALYTIC;
+ }
+ if (list.indexOf(SOCIAL) != -1) {
+ cat |= AntiTracking.SOCIAL;
+ }
+ if (list.indexOf(CONTENT) != -1) {
+ cat |= AntiTracking.CONTENT;
+ }
+ return cat;
+ }
+
+ /* package */ static @CBAntiTracking int cmListToAtCat(final String list) {
+ int cat = AntiTracking.NONE;
+ if (list == null) {
+ return cat;
+ }
+ if (list.indexOf(CRYPTOMINING) != -1) {
+ cat |= AntiTracking.CRYPTOMINING;
+ }
+ return cat;
+ }
+
+ /* package */ static @CBAntiTracking int stListToAtCat(final String list) {
+ int cat = AntiTracking.NONE;
+ if (list == null) {
+ return cat;
+ }
+ if (list.indexOf(STP) != -1) {
+ cat |= AntiTracking.STP;
+ }
+ return cat;
+ }
+
+ /* package */ static @CBAntiTracking int etbListToAtCat(final String list) {
+ int cat = AntiTracking.NONE;
+ if (list == null) {
+ return cat;
+ }
+ if (list.indexOf(EMAIL) != -1) {
+ cat |= AntiTracking.EMAIL;
+ }
+ return cat;
+ }
+
+ /* package */ static @CBSafeBrowsing int errorToSbCat(final long error) {
+ // Match flags with XPCOM ErrorList.h.
+ if (error == 0x805D001FL) {
+ return SafeBrowsing.PHISHING;
+ }
+ if (error == 0x805D001EL) {
+ return SafeBrowsing.MALWARE;
+ }
+ if (error == 0x805D0023L) {
+ return SafeBrowsing.UNWANTED;
+ }
+ if (error == 0x805D0026L) {
+ return SafeBrowsing.HARMFUL;
+ }
+ return SafeBrowsing.NONE;
+ }
+
+ // Match flags with nsIWebProgressListener.idl.
+ private static final long STATE_COOKIES_LOADED = 0x8000L;
+ private static final long STATE_COOKIES_LOADED_TRACKER = 0x40000L;
+ private static final long STATE_COOKIES_LOADED_SOCIALTRACKER = 0x80000L;
+ private static final long STATE_COOKIES_BLOCKED_TRACKER = 0x20000000L;
+ private static final long STATE_COOKIES_BLOCKED_SOCIALTRACKER = 0x01000000L;
+ private static final long STATE_COOKIES_BLOCKED_ALL = 0x40000000L;
+ private static final long STATE_COOKIES_BLOCKED_FOREIGN = 0x80L;
+
+ /* package */ static boolean isBlockingGeckoCbCat(final long geckoCat) {
+ return (geckoCat
+ & (STATE_COOKIES_BLOCKED_TRACKER
+ | STATE_COOKIES_BLOCKED_SOCIALTRACKER
+ | STATE_COOKIES_BLOCKED_ALL
+ | STATE_COOKIES_BLOCKED_FOREIGN))
+ != 0;
+ }
+
+ /* package */ static @CBCookieBehavior int geckoCatToCbCat(final long geckoCat) {
+ if ((geckoCat & STATE_COOKIES_LOADED) != 0) {
+ // We don't know which setting would actually block this cookie, so
+ // we return the most strict value.
+ return CookieBehavior.ACCEPT_NONE;
+ }
+ if ((geckoCat & STATE_COOKIES_BLOCKED_FOREIGN) != 0) {
+ return CookieBehavior.ACCEPT_FIRST_PARTY;
+ }
+ // If we receive STATE_COOKIES_LOADED_{SOCIAL,}TRACKER we know that this
+ // setting would block this cookie.
+ if ((geckoCat
+ & (STATE_COOKIES_BLOCKED_TRACKER
+ | STATE_COOKIES_BLOCKED_SOCIALTRACKER
+ | STATE_COOKIES_LOADED_TRACKER
+ | STATE_COOKIES_LOADED_SOCIALTRACKER))
+ != 0) {
+ return CookieBehavior.ACCEPT_NON_TRACKERS;
+ }
+ if ((geckoCat & STATE_COOKIES_BLOCKED_ALL) != 0) {
+ return CookieBehavior.ACCEPT_NONE;
+ }
+ // TODO: There are more reasons why cookies may be blocked.
+ return CookieBehavior.ACCEPT_ALL;
+ }
+
+ // Cookie Banner Handling feature.
+
+ public static class CookieBannerMode {
+ /** Do not enable handling cookie banners. */
+ public static final int COOKIE_BANNER_MODE_DISABLED = 0;
+
+ /** Only handle banners where selecting "reject all" is possible. */
+ public static final int COOKIE_BANNER_MODE_REJECT = 1;
+
+ /** Reject cookies when possible otherwise accept the cookies. */
+ public static final int COOKIE_BANNER_MODE_REJECT_OR_ACCEPT = 2;
+
+ protected CookieBannerMode() {}
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ CookieBannerMode.COOKIE_BANNER_MODE_DISABLED,
+ CookieBannerMode.COOKIE_BANNER_MODE_REJECT,
+ CookieBannerMode.COOKIE_BANNER_MODE_REJECT_OR_ACCEPT,
+ })
+ public @interface CBCookieBannerMode {}
+}