Bug 1822393 - Consume GeckoView directly in Android Components for CI builds. r=owlis...
[gecko.git] / browser / actors / PluginChild.sys.mjs
blob6eea749ef99e17f83aee979adf79b365b7dbd8c1
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
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 // Handle GMP crashes
6 export class PluginChild extends JSWindowActorChild {
7   handleEvent(event) {
8     // Ignore events for other frames.
9     let eventDoc = event.target.ownerDocument || event.target.document;
10     if (eventDoc && eventDoc != this.document) {
11       return;
12     }
14     let eventType = event.type;
15     if (eventType == "PluginCrashed") {
16       this.onPluginCrashed(event);
17     }
18   }
20   /**
21    * Determines whether or not the crashed plugin is contained within current
22    * full screen DOM element.
23    * @param fullScreenElement (DOM element)
24    *   The DOM element that is currently full screen, or null.
25    * @param domElement
26    *   The DOM element which contains the crashed plugin, or the crashed plugin
27    *   itself.
28    * @returns bool
29    *   True if the plugin is a descendant of the full screen DOM element, false otherwise.
30    **/
31   isWithinFullScreenElement(fullScreenElement, domElement) {
32     /**
33      * Traverses down iframes until it find a non-iframe full screen DOM element.
34      * @param fullScreenIframe
35      *  Target iframe to begin searching from.
36      * @returns DOM element
37      *  The full screen DOM element contained within the iframe (could be inner iframe), or the original iframe if no inner DOM element is found.
38      **/
39     let getTrueFullScreenElement = fullScreenIframe => {
40       if (
41         typeof fullScreenIframe.contentDocument !== "undefined" &&
42         fullScreenIframe.contentDocument.mozFullScreenElement
43       ) {
44         return getTrueFullScreenElement(
45           fullScreenIframe.contentDocument.mozFullScreenElement
46         );
47       }
48       return fullScreenIframe;
49     };
51     if (fullScreenElement.tagName === "IFRAME") {
52       fullScreenElement = getTrueFullScreenElement(fullScreenElement);
53     }
55     if (fullScreenElement.contains(domElement)) {
56       return true;
57     }
58     let parentIframe = domElement.ownerGlobal.frameElement;
59     if (parentIframe) {
60       return this.isWithinFullScreenElement(fullScreenElement, parentIframe);
61     }
62     return false;
63   }
65   /**
66    * The PluginCrashed event handler. The target of the event is the
67    * document that GMP is being used in.
68    */
69   async onPluginCrashed(aEvent) {
70     if (!this.contentWindow.PluginCrashedEvent.isInstance(aEvent)) {
71       return;
72     }
74     let { target, gmpPlugin, pluginID } = aEvent;
75     let fullScreenElement =
76       this.contentWindow.top.document.mozFullScreenElement;
77     if (fullScreenElement) {
78       if (this.isWithinFullScreenElement(fullScreenElement, target)) {
79         this.contentWindow.top.document.mozCancelFullScreen();
80       }
81     }
83     if (!gmpPlugin || !target.document) {
84       // TODO: Throw exception? How did we get here?
85       return;
86     }
88     this.sendAsyncMessage("PluginContent:ShowPluginCrashedNotification", {
89       pluginCrashID: { pluginID },
90     });
91   }