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/. */
7 ChromeUtils.defineESModuleGetters(lazy, {
8 pprint: "chrome://remote/content/shared/Format.sys.mjs",
9 waitForObserverTopic: "chrome://remote/content/marionette/sync.sys.mjs",
13 * Quits the application with the provided flags.
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.
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.
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.
33 * @returns {Record<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.
40 export async function quit(flags = [], safeMode = false, isWindowless = false) {
41 if (flags.includes("eSilently")) {
44 `Silent restarts only allowed with "moz:windowless" capability set`
47 if (!flags.includes("eRestart")) {
48 throw new TypeError(`"silently" only works with restart flag`);
52 const quits = ["eConsiderQuit", "eAttemptQuit", "eForceQuit"];
57 for (let k of flags) {
58 if (!(k in Ci.nsIAppStartup)) {
59 throw new TypeError(lazy.pprint`Expected ${k} in ${Ci.nsIAppStartup}`);
62 if (quits.includes(k)) {
64 throw new TypeError(`${k} cannot be combined with ${quitSeen}`);
69 mode |= Ci.nsIAppStartup[k];
74 mode |= Ci.nsIAppStartup.eAttemptQuit;
77 // Notify all windows that an application quit has been requested.
78 const cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(
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;
88 // Delay response until the application is about to quit.
89 const quitApplication = lazy.waitForObserverTopic("quit-application");
92 Services.startup.restartInSafeMode(mode);
94 Services.startup.quit(mode);
98 cause: (await quitApplication).data,
99 forced: cancelQuit.data,