Bug 1867925 - Mark some storage-access-api tests as intermittent after wpt-sync....
[gecko.git] / toolkit / modules / ActorManagerParent.sys.mjs
blob3bf7299abe502f863b4f81113badbbaca7062058
1 /* vim: set ts=2 sw=2 sts=2 et tw=80: */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4  * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /**
7  * This module handles JavaScript-implemented JSWindowActors, registered through DOM IPC
8  * infrastructure, and are fission-compatible.
9  */
11 import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
12 import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
14 /**
15  * Fission-compatible JSProcess implementations.
16  * Each actor options object takes the form of a ProcessActorOptions dictionary.
17  * Detailed documentation of these options is in dom/docs/ipc/jsactors.rst,
18  * available at https://firefox-source-docs.mozilla.org/dom/ipc/jsactors.html
19  */
20 let JSPROCESSACTORS = {
21   AsyncPrefs: {
22     parent: {
23       esModuleURI: "resource://gre/modules/AsyncPrefs.sys.mjs",
24     },
25     child: {
26       esModuleURI: "resource://gre/modules/AsyncPrefs.sys.mjs",
27     },
28   },
30   ContentPrefs: {
31     parent: {
32       esModuleURI: "resource://gre/modules/ContentPrefServiceParent.sys.mjs",
33     },
34     child: {
35       esModuleURI: "resource://gre/modules/ContentPrefServiceChild.sys.mjs",
36     },
37   },
39   ExtensionContent: {
40     child: {
41       esModuleURI: "resource://gre/modules/ExtensionContent.sys.mjs",
42     },
43     includeParent: true,
44   },
46   ProcessConduits: {
47     parent: {
48       esModuleURI: "resource://gre/modules/ConduitsParent.sys.mjs",
49     },
50     child: {
51       esModuleURI: "resource://gre/modules/ConduitsChild.sys.mjs",
52     },
53   },
56 /**
57  * Fission-compatible JSWindowActor implementations.
58  * Each actor options object takes the form of a WindowActorOptions dictionary.
59  * Detailed documentation of these options is in dom/docs/ipc/jsactors.rst,
60  * available at https://firefox-source-docs.mozilla.org/dom/ipc/jsactors.html
61  */
62 let JSWINDOWACTORS = {
63   AboutCertViewer: {
64     parent: {
65       esModuleURI: "resource://gre/modules/AboutCertViewerParent.sys.mjs",
66     },
67     child: {
68       esModuleURI: "resource://gre/modules/AboutCertViewerChild.sys.mjs",
70       events: {
71         DOMDocElementInserted: { capture: true },
72       },
73     },
75     matches: ["about:certificate"],
76   },
78   AboutHttpsOnlyError: {
79     parent: {
80       esModuleURI: "resource://gre/actors/AboutHttpsOnlyErrorParent.sys.mjs",
81     },
82     child: {
83       esModuleURI: "resource://gre/actors/AboutHttpsOnlyErrorChild.sys.mjs",
84       events: {
85         DOMDocElementInserted: {},
86       },
87     },
88     matches: ["about:httpsonlyerror?*"],
89     allFrames: true,
90   },
92   AboutTranslations: {
93     parent: {
94       esModuleURI: "resource://gre/actors/AboutTranslationsParent.sys.mjs",
95     },
96     child: {
97       esModuleURI: "resource://gre/actors/AboutTranslationsChild.sys.mjs",
98       events: {
99         // Run the actor before any content of the page appears to inject functions.
100         DOMDocElementInserted: {},
101         DOMContentLoaded: {},
102         // Used to show and hide the translations button.
103         pageshow: { mozSystemGroup: true },
104         pagehide: { mozSystemGroup: true },
105       },
106     },
107     matches: ["about:translations"],
108     remoteTypes: ["privilegedabout"],
109     enablePreference: "browser.translations.enable",
110   },
112   AudioPlayback: {
113     parent: {
114       esModuleURI: "resource://gre/actors/AudioPlaybackParent.sys.mjs",
115     },
117     child: {
118       esModuleURI: "resource://gre/actors/AudioPlaybackChild.sys.mjs",
119       observers: ["audio-playback"],
120     },
122     allFrames: true,
123   },
125   AutoComplete: {
126     parent: {
127       esModuleURI: "resource://gre/actors/AutoCompleteParent.sys.mjs",
128       // These two messages are also used, but are currently synchronous calls
129       // through the per-process message manager.
130       // "FormAutoComplete:GetSelectedIndex",
131       // "FormAutoComplete:SelectBy"
132     },
134     child: {
135       esModuleURI: "resource://gre/actors/AutoCompleteChild.sys.mjs",
136     },
138     allFrames: true,
139   },
141   Autoplay: {
142     parent: {
143       esModuleURI: "resource://gre/actors/AutoplayParent.sys.mjs",
144     },
146     child: {
147       esModuleURI: "resource://gre/actors/AutoplayChild.sys.mjs",
148       events: {
149         GloballyAutoplayBlocked: {},
150       },
151     },
153     allFrames: true,
154   },
156   AutoScroll: {
157     parent: {
158       esModuleURI: "resource://gre/actors/AutoScrollParent.sys.mjs",
159     },
161     child: {
162       esModuleURI: "resource://gre/actors/AutoScrollChild.sys.mjs",
163       events: {
164         mousedown: { capture: true, mozSystemGroup: true },
165       },
166     },
168     allFrames: true,
169   },
171   BackgroundThumbnails: {
172     child: {
173       esModuleURI: "resource://gre/actors/BackgroundThumbnailsChild.sys.mjs",
174       events: {
175         DOMDocElementInserted: { capture: true },
176       },
177     },
178     messageManagerGroups: ["thumbnails"],
179   },
181   BrowserElement: {
182     parent: {
183       esModuleURI: "resource://gre/actors/BrowserElementParent.sys.mjs",
184     },
186     child: {
187       esModuleURI: "resource://gre/actors/BrowserElementChild.sys.mjs",
188       events: {
189         DOMWindowClose: {},
190       },
191     },
193     allFrames: true,
194   },
196   Conduits: {
197     parent: {
198       esModuleURI: "resource://gre/modules/ConduitsParent.sys.mjs",
199     },
201     child: {
202       esModuleURI: "resource://gre/modules/ConduitsChild.sys.mjs",
203     },
205     allFrames: true,
206   },
208   Controllers: {
209     parent: {
210       esModuleURI: "resource://gre/actors/ControllersParent.sys.mjs",
211     },
212     child: {
213       esModuleURI: "resource://gre/actors/ControllersChild.sys.mjs",
214     },
216     allFrames: true,
217   },
219   CookieBanner: {
220     parent: {
221       esModuleURI: "resource://gre/actors/CookieBannerParent.sys.mjs",
222     },
223     child: {
224       esModuleURI: "resource://gre/actors/CookieBannerChild.sys.mjs",
225       events: {
226         DOMContentLoaded: {},
227         load: { capture: true },
228       },
229     },
230     // Only need handle cookie banners for HTTP/S scheme.
231     matches: ["https://*/*", "http://*/*"],
232     // Only handle banners for browser tabs (including sub-frames).
233     messageManagerGroups: ["browsers"],
234     // Cookie banners can be shown in sub-frames so we need to include them.
235     allFrames: true,
236     // Holds lazy pref getters.
237     _prefs: {},
238     // Remember current register state to avoid duplicate calls to register /
239     // unregister.
240     _isRegistered: false,
241     onAddActor(register, unregister) {
242       // Register / unregister on pref changes.
243       let onPrefChange = () => {
244         if (
245           this._prefs["cookiebanners.bannerClicking.enabled"] &&
246           (this._prefs["cookiebanners.service.mode"] != 0 ||
247             this._prefs["cookiebanners.service.mode.privateBrowsing"] != 0)
248         ) {
249           if (!this._isRegistered) {
250             register();
251             this._isRegistered = true;
252           }
253         } else if (this._isRegistered) {
254           unregister();
255           this._isRegistered = false;
256         }
257       };
259       // Add lazy pref getters with pref observers so we can dynamically enable
260       // or disable the actor.
261       [
262         "cookiebanners.bannerClicking.enabled",
263         "cookiebanners.service.mode",
264         "cookiebanners.service.mode.privateBrowsing",
265       ].forEach(prefName => {
266         XPCOMUtils.defineLazyPreferenceGetter(
267           this._prefs,
268           prefName,
269           prefName,
270           null,
271           onPrefChange
272         );
273       });
275       // Check initial state.
276       onPrefChange();
277     },
278   },
280   ExtFind: {
281     child: {
282       esModuleURI: "resource://gre/actors/ExtFindChild.sys.mjs",
283     },
285     allFrames: true,
286   },
288   FindBar: {
289     parent: {
290       esModuleURI: "resource://gre/actors/FindBarParent.sys.mjs",
291     },
292     child: {
293       esModuleURI: "resource://gre/actors/FindBarChild.sys.mjs",
294       events: {
295         keypress: { mozSystemGroup: true },
296       },
297     },
299     allFrames: true,
300     messageManagerGroups: ["browsers", "test"],
301   },
303   // This is the actor that responds to requests from the find toolbar and
304   // searches for matches and highlights them.
305   Finder: {
306     child: {
307       esModuleURI: "resource://gre/actors/FinderChild.sys.mjs",
308     },
310     allFrames: true,
311   },
313   FormHistory: {
314     parent: {
315       esModuleURI: "resource://gre/actors/FormHistoryParent.sys.mjs",
316     },
317     child: {
318       esModuleURI: "resource://gre/actors/FormHistoryChild.sys.mjs",
319       events: {
320         DOMFormBeforeSubmit: {},
321       },
322     },
324     allFrames: true,
325   },
327   InlineSpellChecker: {
328     parent: {
329       esModuleURI: "resource://gre/actors/InlineSpellCheckerParent.sys.mjs",
330     },
332     child: {
333       esModuleURI: "resource://gre/actors/InlineSpellCheckerChild.sys.mjs",
334     },
336     allFrames: true,
337   },
339   KeyPressEventModelChecker: {
340     child: {
341       esModuleURI:
342         "resource://gre/actors/KeyPressEventModelCheckerChild.sys.mjs",
343       events: {
344         CheckKeyPressEventModel: { capture: true, mozSystemGroup: true },
345       },
346     },
348     allFrames: true,
349   },
351   LoginManager: {
352     parent: {
353       esModuleURI: "resource://gre/modules/LoginManagerParent.sys.mjs",
354     },
355     child: {
356       esModuleURI: "resource://gre/modules/LoginManagerChild.sys.mjs",
357       events: {
358         DOMFormBeforeSubmit: {},
359         DOMFormHasPassword: {},
360         DOMFormHasPossibleUsername: {},
361         DOMInputPasswordAdded: {},
362       },
363     },
365     allFrames: true,
366     messageManagerGroups: ["browsers", "webext-browsers", ""],
367   },
369   ManifestMessages: {
370     child: {
371       esModuleURI: "resource://gre/modules/ManifestMessagesChild.sys.mjs",
372     },
373   },
375   NetError: {
376     parent: {
377       esModuleURI: "resource://gre/actors/NetErrorParent.sys.mjs",
378     },
379     child: {
380       esModuleURI: "resource://gre/actors/NetErrorChild.sys.mjs",
381       events: {
382         DOMDocElementInserted: {},
383         click: {},
384       },
385     },
387     matches: ["about:certerror?*", "about:neterror?*"],
388     allFrames: true,
389   },
391   PictureInPictureLauncher: {
392     parent: {
393       esModuleURI: "resource://gre/modules/PictureInPicture.sys.mjs",
394     },
395     child: {
396       esModuleURI: "resource://gre/actors/PictureInPictureChild.sys.mjs",
397       events: {
398         MozTogglePictureInPicture: { capture: true },
399       },
400     },
402     allFrames: true,
403   },
405   PictureInPicture: {
406     parent: {
407       esModuleURI: "resource://gre/modules/PictureInPicture.sys.mjs",
408     },
409     child: {
410       esModuleURI: "resource://gre/actors/PictureInPictureChild.sys.mjs",
411     },
413     allFrames: true,
414   },
416   PictureInPictureToggle: {
417     parent: {
418       esModuleURI: "resource://gre/modules/PictureInPicture.sys.mjs",
419     },
420     child: {
421       esModuleURI: "resource://gre/actors/PictureInPictureChild.sys.mjs",
422       events: {
423         UAWidgetSetupOrChange: {},
424         contextmenu: { capture: true },
425       },
426     },
428     allFrames: true,
429   },
431   PopupBlocking: {
432     parent: {
433       esModuleURI: "resource://gre/actors/PopupBlockingParent.sys.mjs",
434     },
435     child: {
436       esModuleURI: "resource://gre/actors/PopupBlockingChild.sys.mjs",
437       events: {
438         DOMPopupBlocked: { capture: true },
439         // Only listen for the `pageshow` event after the actor has already been
440         // created for some other reason.
441         pageshow: { createActor: false },
442       },
443     },
444     allFrames: true,
445   },
447   Printing: {
448     parent: {
449       esModuleURI: "resource://gre/actors/PrintingParent.sys.mjs",
450     },
451     child: {
452       esModuleURI: "resource://gre/actors/PrintingChild.sys.mjs",
453       events: {
454         PrintingError: { capture: true },
455         printPreviewUpdate: { capture: true },
456       },
457     },
458   },
460   PrintingSelection: {
461     child: {
462       esModuleURI: "resource://gre/actors/PrintingSelectionChild.sys.mjs",
463     },
464     allFrames: true,
465   },
467   PurgeSessionHistory: {
468     child: {
469       esModuleURI: "resource://gre/actors/PurgeSessionHistoryChild.sys.mjs",
470     },
471     allFrames: true,
472   },
474   ReportBrokenSite: {
475     parent: {
476       esModuleURI: "resource://gre/actors/ReportBrokenSiteParent.sys.mjs",
477     },
478     child: {
479       esModuleURI: "resource://gre/actors/ReportBrokenSiteChild.sys.mjs",
480     },
481     matches: [
482       "http://*/*",
483       "https://*/*",
484       "about:certerror?*",
485       "about:neterror?*",
486     ],
487     messageManagerGroups: ["browsers"],
488     allFrames: true,
489   },
491   // This actor is available for all pages that one can
492   // view the source of, however it won't be created until a
493   // request to view the source is made via the message
494   // 'ViewSource:LoadSource' or 'ViewSource:LoadSourceWithSelection'.
495   ViewSource: {
496     child: {
497       esModuleURI: "resource://gre/actors/ViewSourceChild.sys.mjs",
498     },
500     allFrames: true,
501   },
503   // This actor is for the view-source page itself.
504   ViewSourcePage: {
505     parent: {
506       esModuleURI: "resource://gre/actors/ViewSourcePageParent.sys.mjs",
507     },
508     child: {
509       esModuleURI: "resource://gre/actors/ViewSourcePageChild.sys.mjs",
510       events: {
511         pageshow: { capture: true },
512         click: {},
513       },
514     },
516     matches: ["view-source:*"],
517     allFrames: true,
518   },
520   WebChannel: {
521     parent: {
522       esModuleURI: "resource://gre/actors/WebChannelParent.sys.mjs",
523     },
524     child: {
525       esModuleURI: "resource://gre/actors/WebChannelChild.sys.mjs",
526       events: {
527         WebChannelMessageToChrome: { capture: true, wantUntrusted: true },
528       },
529     },
531     allFrames: true,
532   },
534   Thumbnails: {
535     child: {
536       esModuleURI: "resource://gre/actors/ThumbnailsChild.sys.mjs",
537     },
538   },
540   // Determines if a page can be translated, and coordinates communication with the
541   // translations engine.
542   Translations: {
543     parent: {
544       esModuleURI: "resource://gre/actors/TranslationsParent.sys.mjs",
545     },
546     child: {
547       esModuleURI: "resource://gre/actors/TranslationsChild.sys.mjs",
548       events: {
549         DOMContentLoaded: {},
550       },
551     },
552     matches: [
553       "http://*/*",
554       "https://*/*",
555       "file:///*",
557       // The actor is explicitly loaded by this page,
558       // so it needs to be allowed for it.
559       "about:translations",
560     ],
561     enablePreference: "browser.translations.enable",
562   },
564   // A single process that controls all of the translations.
565   TranslationsEngine: {
566     parent: {
567       esModuleURI: "resource://gre/actors/TranslationsEngineParent.sys.mjs",
568     },
569     child: {
570       esModuleURI: "resource://gre/actors/TranslationsEngineChild.sys.mjs",
571       events: {
572         DOMContentLoaded: { createActor: true },
573       },
574     },
575     includeChrome: true,
576     matches: ["chrome://global/content/translations/translations-engine.html"],
577     enablePreference: "browser.translations.enable",
578   },
580   UAWidgets: {
581     child: {
582       esModuleURI: "resource://gre/actors/UAWidgetsChild.sys.mjs",
583       events: {
584         UAWidgetSetupOrChange: {},
585         UAWidgetTeardown: {},
586       },
587     },
589     includeChrome: true,
590     allFrames: true,
591   },
593   UnselectedTabHover: {
594     parent: {
595       esModuleURI: "resource://gre/actors/UnselectedTabHoverParent.sys.mjs",
596     },
597     child: {
598       esModuleURI: "resource://gre/actors/UnselectedTabHoverChild.sys.mjs",
599       events: {
600         "UnselectedTabHover:Enable": {},
601         "UnselectedTabHover:Disable": {},
602       },
603     },
605     allFrames: true,
606   },
610  * Note that turning on page data collection for snapshots currently disables
611  * collection of generic page info for normal history entries. See bug 1740234.
612  */
613 if (!Services.prefs.getBoolPref("browser.pagedata.enabled", false)) {
614   JSWINDOWACTORS.ContentMeta = {
615     parent: {
616       esModuleURI: "resource://gre/actors/ContentMetaParent.sys.mjs",
617     },
619     child: {
620       esModuleURI: "resource://gre/actors/ContentMetaChild.sys.mjs",
621       events: {
622         DOMContentLoaded: {},
623         DOMMetaAdded: { createActor: false },
624       },
625     },
627     messageManagerGroups: ["browsers"],
628   };
631 if (AppConstants.platform != "android") {
632   // Note that GeckoView has another implementation in mobile/android/actors.
633   JSWINDOWACTORS.Select = {
634     parent: {
635       esModuleURI: "resource://gre/actors/SelectParent.sys.mjs",
636     },
638     child: {
639       esModuleURI: "resource://gre/actors/SelectChild.sys.mjs",
640       events: {
641         mozshowdropdown: {},
642         "mozshowdropdown-sourcetouch": {},
643         mozhidedropdown: { mozSystemGroup: true },
644       },
645     },
647     includeChrome: true,
648     allFrames: true,
649   };
651   // Note that GeckoView handles MozOpenDateTimePicker in GeckoViewPrompt.
652   JSWINDOWACTORS.DateTimePicker = {
653     parent: {
654       esModuleURI: "resource://gre/actors/DateTimePickerParent.sys.mjs",
655     },
657     child: {
658       esModuleURI: "resource://gre/actors/DateTimePickerChild.sys.mjs",
659       events: {
660         MozOpenDateTimePicker: {},
661         MozUpdateDateTimePicker: {},
662         MozCloseDateTimePicker: {},
663       },
664     },
666     includeChrome: true,
667     allFrames: true,
668   };
671 export var ActorManagerParent = {
672   _addActors(actors, kind) {
673     let register, unregister;
674     switch (kind) {
675       case "JSProcessActor":
676         register = ChromeUtils.registerProcessActor;
677         unregister = ChromeUtils.unregisterProcessActor;
678         break;
679       case "JSWindowActor":
680         register = ChromeUtils.registerWindowActor;
681         unregister = ChromeUtils.unregisterWindowActor;
682         break;
683       default:
684         throw new Error("Invalid JSActor kind " + kind);
685     }
686     for (let [actorName, actor] of Object.entries(actors)) {
687       // The actor defines its own register/unregister logic.
688       if (actor.onAddActor) {
689         actor.onAddActor(
690           () => register(actorName, actor),
691           () => unregister(actorName, actor)
692         );
693         continue;
694       }
696       // If enablePreference is set, only register the actor while the
697       // preference is set to true.
698       if (actor.enablePreference) {
699         let actorNameProp = actorName + "_Preference";
700         XPCOMUtils.defineLazyPreferenceGetter(
701           this,
702           actorNameProp,
703           actor.enablePreference,
704           false,
705           (prefName, prevValue, isEnabled) => {
706             if (isEnabled) {
707               register(actorName, actor);
708             } else {
709               unregister(actorName, actor);
710             }
711             if (actor.onPreferenceChanged) {
712               actor.onPreferenceChanged(prefName, prevValue, isEnabled);
713             }
714           }
715         );
716         if (!this[actorNameProp]) {
717           continue;
718         }
719       }
721       register(actorName, actor);
722     }
723   },
725   addJSProcessActors(actors) {
726     this._addActors(actors, "JSProcessActor");
727   },
728   addJSWindowActors(actors) {
729     this._addActors(actors, "JSWindowActor");
730   },
733 ActorManagerParent.addJSProcessActors(JSPROCESSACTORS);
734 ActorManagerParent.addJSWindowActors(JSWINDOWACTORS);