1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
9 ChromeUtils.defineESModuleGetters(lazy, {
10 ClientID: "resource://gre/modules/ClientID.sys.mjs",
11 ContextualIdentityService:
12 "resource://gre/modules/ContextualIdentityService.sys.mjs",
15 const RECOMMENDATION_ENABLED = "browser.discovery.enabled";
16 const TELEMETRY_ENABLED = "datareporting.healthreport.uploadEnabled";
17 const TAAR_COOKIE_NAME = "taarId";
19 export const Discovery = {
22 if (val && !lazy.gTelemetryEnabled) {
23 throw Error("unable to turn on recommendations");
25 Services.prefs.setBoolPref(RECOMMENDATION_ENABLED, val);
29 return lazy.gTelemetryEnabled && lazy.gRecommendationEnabled;
33 return DiscoveryInternal.update(true);
37 return DiscoveryInternal.update();
41 XPCOMUtils.defineLazyPreferenceGetter(
43 "gRecommendationEnabled",
44 RECOMMENDATION_ENABLED,
48 XPCOMUtils.defineLazyPreferenceGetter(
55 XPCOMUtils.defineLazyPreferenceGetter(
58 "toolkit.telemetry.cachedClientID",
62 XPCOMUtils.defineLazyPreferenceGetter(
65 "browser.discovery.containers.enabled",
70 Services.obs.addObserver(Discovery.update, "contextual-identity-created");
72 const DiscoveryInternal = {
75 this.sites = Services.prefs
76 .getCharPref("browser.discovery.sites", "")
82 // There is never a zero id, this is just for use in update.
84 if (lazy.gContainersEnabled) {
85 lazy.ContextualIdentityService.getPublicIdentities().forEach(identity => {
86 IDs.push(identity.userContextId);
92 async update(reset = false) {
93 if (reset || !Discovery.enabled) {
94 for (let site of this.sites) {
95 Services.cookies.remove(site, TAAR_COOKIE_NAME, "/", {});
96 lazy.ContextualIdentityService.getPublicIdentities().forEach(
98 let { userContextId } = identity;
99 Services.cookies.remove(site, TAAR_COOKIE_NAME, "/", {
107 if (Discovery.enabled) {
108 // If the client id is not cached, wait for the notification that it is
109 // cached. This will happen shortly after startup in TelemetryController.sys.mjs.
110 // When that happens, we'll get a pref notification for the cached id,
111 // which will call update again.
112 if (!lazy.gCachedClientID) {
115 let id = await lazy.ClientID.getClientIdHash();
116 for (let site of this.sites) {
117 // This cookie gets tied down as much as possible. Specifically,
118 // SameSite, Secure, HttpOnly and non-PrivateBrowsing.
119 for (let userContextId of this.getContextualIDs()) {
120 let originAttributes = { privateBrowsingId: 0 };
121 if (userContextId > 0) {
122 originAttributes.userContextId = userContextId;
125 Services.cookies.cookieExists(
134 Services.cookies.add(
144 Ci.nsICookie.SAMESITE_LAX,
145 Ci.nsICookie.SCHEME_HTTPS