summaryrefslogtreecommitdiffstats
path: root/toolkit/components/normandy/content/ShieldFrameChild.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/normandy/content/ShieldFrameChild.sys.mjs')
-rw-r--r--toolkit/components/normandy/content/ShieldFrameChild.sys.mjs172
1 files changed, 172 insertions, 0 deletions
diff --git a/toolkit/components/normandy/content/ShieldFrameChild.sys.mjs b/toolkit/components/normandy/content/ShieldFrameChild.sys.mjs
new file mode 100644
index 0000000000..8ca4110f6d
--- /dev/null
+++ b/toolkit/components/normandy/content/ShieldFrameChild.sys.mjs
@@ -0,0 +1,172 @@
+/* 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/. */
+
+/**
+ * Listen for DOM events bubbling up from the about:studies page, and perform
+ * privileged actions in response to them. If we need to do anything that the
+ * content process can't handle (such as reading IndexedDB), we send a message
+ * to the parent process and handle it there.
+ */
+
+import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
+
+const lazy = {};
+
+ChromeUtils.defineESModuleGetters(lazy, {
+ AboutPages: "resource://normandy-content/AboutPages.sys.mjs",
+});
+
+XPCOMUtils.defineLazyGetter(lazy, "gBrandBundle", function () {
+ return Services.strings.createBundle(
+ "chrome://branding/locale/brand.properties"
+ );
+});
+
+XPCOMUtils.defineLazyGetter(lazy, "gStringBundle", function () {
+ return Services.strings.createBundle(
+ "chrome://global/locale/aboutStudies.properties"
+ );
+});
+
+const NIMBUS_DEBUG_PREF = "nimbus.debug";
+
+/**
+ * Listen for DOM events bubbling up from the about:studies page, and perform
+ * privileged actions in response to them. If we need to do anything that the
+ * content process can't handle (such as reading IndexedDB), we send a message
+ * to the parent process and handle it there.
+ */
+export class ShieldFrameChild extends JSWindowActorChild {
+ async handleEvent(event) {
+ // On page show or page hide,
+ // add this child to the WeakSet in AboutStudies.
+ switch (event.type) {
+ case "pageshow":
+ this.sendAsyncMessage("Shield:AddToWeakSet");
+ return;
+
+ case "pagehide":
+ this.sendAsyncMessage("Shield:RemoveFromWeakSet");
+ return;
+ }
+ switch (event.detail.action) {
+ // Actions that require the parent process
+ case "GetRemoteValue:AddonStudyList":
+ let addonStudies = await this.sendQuery("Shield:GetAddonStudyList");
+ this.triggerPageCallback(
+ "ReceiveRemoteValue:AddonStudyList",
+ addonStudies
+ );
+ break;
+ case "GetRemoteValue:PreferenceStudyList":
+ let prefStudies = await this.sendQuery("Shield:GetPreferenceStudyList");
+ this.triggerPageCallback(
+ "ReceiveRemoteValue:PreferenceStudyList",
+ prefStudies
+ );
+ break;
+ case "GetRemoteValue:MessagingSystemList":
+ let experiments = await this.sendQuery("Shield:GetMessagingSystemList");
+ this.triggerPageCallback(
+ "ReceiveRemoteValue:MessagingSystemList",
+ experiments
+ );
+ break;
+ case "RemoveAddonStudy":
+ this.sendAsyncMessage("Shield:RemoveAddonStudy", event.detail.data);
+ break;
+ case "RemovePreferenceStudy":
+ this.sendAsyncMessage(
+ "Shield:RemovePreferenceStudy",
+ event.detail.data
+ );
+ break;
+ case "RemoveMessagingSystemExperiment":
+ this.sendAsyncMessage(
+ "Shield:RemoveMessagingSystemExperiment",
+ event.detail.data
+ );
+ break;
+ case "GetRemoteValue:StudiesEnabled":
+ let studiesEnabled = await this.sendQuery("Shield:GetStudiesEnabled");
+ this.triggerPageCallback(
+ "ReceiveRemoteValue:StudiesEnabled",
+ studiesEnabled
+ );
+ break;
+ case "GetRemoteValue:DebugModeOn":
+ this.triggerPageCallback(
+ "ReceiveRemoteValue:DebugModeOn",
+ Services.prefs.getBoolPref(NIMBUS_DEBUG_PREF)
+ );
+ break;
+ case "NavigateToDataPreferences":
+ this.sendAsyncMessage("Shield:OpenDataPreferences");
+ break;
+ // Actions that can be performed in the content process
+ case "GetRemoteValue:ShieldLearnMoreHref":
+ this.triggerPageCallback(
+ "ReceiveRemoteValue:ShieldLearnMoreHref",
+ lazy.AboutPages.aboutStudies.getShieldLearnMoreHref()
+ );
+ break;
+ case "GetRemoteValue:ShieldTranslations":
+ const strings = {};
+ for (let str of lazy.gStringBundle.getSimpleEnumeration()) {
+ strings[str.key] = str.value;
+ }
+ const brandName = lazy.gBrandBundle.GetStringFromName("brandShortName");
+ strings.enabledList = lazy.gStringBundle.formatStringFromName(
+ "enabledList",
+ [brandName]
+ );
+
+ this.triggerPageCallback(
+ "ReceiveRemoteValue:ShieldTranslations",
+ strings
+ );
+ break;
+ case "ExperimentOptIn":
+ const message = await this.sendQuery(
+ "Shield:ExperimentOptIn",
+ event.detail.data
+ );
+ this.triggerPageCallback("ReceiveRemoteValue:OptInMessage", message);
+ break;
+ }
+ }
+
+ receiveMessage(msg) {
+ switch (msg.name) {
+ case "Shield:UpdateAddonStudyList":
+ this.triggerPageCallback("ReceiveRemoteValue:AddonStudyList", msg.data);
+ break;
+ case "Shield:UpdatePreferenceStudyList":
+ this.triggerPageCallback(
+ "ReceiveRemoteValue:PreferenceStudyList",
+ msg.data
+ );
+ break;
+ case "Shield:UpdateMessagingSystemExperimentList":
+ this.triggerPageCallback(
+ "ReceiveRemoteValue:MessagingSystemList",
+ msg.data
+ );
+ break;
+ }
+ }
+ /**
+ * Trigger an event to communicate with the unprivileged about:studies page.
+ * @param {String} type The type of event to trigger.
+ * @param {Object} detail The data to pass along to the event.
+ */
+ triggerPageCallback(type, detail) {
+ // Clone details and use the event class from the unprivileged context.
+ const event = new this.document.defaultView.CustomEvent(type, {
+ bubbles: true,
+ detail: Cu.cloneInto(detail, this.document.defaultView),
+ });
+ this.document.dispatchEvent(event);
+ }
+}