Bug 1886451: Add missing ifdef Nightly guards. r=dminor
[gecko.git] / remote / shared / Browser.sys.mjs
blobc8bff1f55a27421a8fccc098c5b38bfd5d7e4558
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 const lazy = {};
7 ChromeUtils.defineESModuleGetters(lazy, {
8   pprint: "chrome://remote/content/shared/Format.sys.mjs",
9   waitForObserverTopic: "chrome://remote/content/marionette/sync.sys.mjs",
10 });
12 /**
13  * Quits the application with the provided flags.
14  *
15  * Optional {@link nsIAppStartup} flags may be provided as
16  * an array of masks, and these will be combined by ORing
17  * them with a bitmask. The available masks are defined in
18  * https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIAppStartup.
19  *
20  * Crucially, only one of the *Quit flags can be specified. The |eRestart|
21  * flag may be bit-wise combined with one of the *Quit flags to cause
22  * the application to restart after it quits.
23  *
24  * @param {Array.<string>=} flags
25  *     Constant name of masks to pass to |Services.startup.quit|.
26  *     If empty or undefined, |nsIAppStartup.eAttemptQuit| is used.
27  * @param {boolean=} safeMode
28  *     Optional flag to indicate that the application has to
29  *     be restarted in safe mode.
30  * @param {boolean=} isWindowless
31  *     Optional flag to indicate that the browser was started in windowless mode.
32  *
33  * @returns {Object<string,boolean>}
34  *     Dictionary containing information that explains the shutdown reason.
35  *     The value for `cause` contains the shutdown kind like "shutdown" or
36  *     "restart", while `forced` will indicate if it was a normal or forced
37  *     shutdown of the application. "in_app" is always set to indicate that
38  *     it is a shutdown triggered from within the application.
39  */
40 export async function quit(flags = [], safeMode = false, isWindowless = false) {
41   if (flags.includes("eSilently")) {
42     if (!isWindowless) {
43       throw new Error(
44         `Silent restarts only allowed with "moz:windowless" capability set`
45       );
46     }
47     if (!flags.includes("eRestart")) {
48       throw new TypeError(`"silently" only works with restart flag`);
49     }
50   }
52   const quits = ["eConsiderQuit", "eAttemptQuit", "eForceQuit"];
54   let quitSeen;
55   let mode = 0;
56   if (flags.length) {
57     for (let k of flags) {
58       if (!(k in Ci.nsIAppStartup)) {
59         throw new TypeError(lazy.pprint`Expected ${k} in ${Ci.nsIAppStartup}`);
60       }
62       if (quits.includes(k)) {
63         if (quitSeen) {
64           throw new TypeError(`${k} cannot be combined with ${quitSeen}`);
65         }
66         quitSeen = k;
67       }
69       mode |= Ci.nsIAppStartup[k];
70     }
71   }
73   if (!quitSeen) {
74     mode |= Ci.nsIAppStartup.eAttemptQuit;
75   }
77   // Notify all windows that an application quit has been requested.
78   const cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(
79     Ci.nsISupportsPRBool
80   );
81   Services.obs.notifyObservers(cancelQuit, "quit-application-requested");
83   // If the shutdown of the application is prevented force quit it instead.
84   if (cancelQuit.data) {
85     mode |= Ci.nsIAppStartup.eForceQuit;
86   }
88   // Delay response until the application is about to quit.
89   const quitApplication = lazy.waitForObserverTopic("quit-application");
91   if (safeMode) {
92     Services.startup.restartInSafeMode(mode);
93   } else {
94     Services.startup.quit(mode);
95   }
97   return {
98     cause: (await quitApplication).data,
99     forced: cancelQuit.data,
100     in_app: true,
101   };