summaryrefslogtreecommitdiffstats
path: root/remote/shared/Browser.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'remote/shared/Browser.sys.mjs')
-rw-r--r--remote/shared/Browser.sys.mjs102
1 files changed, 102 insertions, 0 deletions
diff --git a/remote/shared/Browser.sys.mjs b/remote/shared/Browser.sys.mjs
new file mode 100644
index 0000000000..c8bff1f55a
--- /dev/null
+++ b/remote/shared/Browser.sys.mjs
@@ -0,0 +1,102 @@
+/* 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/. */
+
+const lazy = {};
+
+ChromeUtils.defineESModuleGetters(lazy, {
+ pprint: "chrome://remote/content/shared/Format.sys.mjs",
+ waitForObserverTopic: "chrome://remote/content/marionette/sync.sys.mjs",
+});
+
+/**
+ * Quits the application with the provided flags.
+ *
+ * Optional {@link nsIAppStartup} flags may be provided as
+ * an array of masks, and these will be combined by ORing
+ * them with a bitmask. The available masks are defined in
+ * https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIAppStartup.
+ *
+ * Crucially, only one of the *Quit flags can be specified. The |eRestart|
+ * flag may be bit-wise combined with one of the *Quit flags to cause
+ * the application to restart after it quits.
+ *
+ * @param {Array.<string>=} flags
+ * Constant name of masks to pass to |Services.startup.quit|.
+ * If empty or undefined, |nsIAppStartup.eAttemptQuit| is used.
+ * @param {boolean=} safeMode
+ * Optional flag to indicate that the application has to
+ * be restarted in safe mode.
+ * @param {boolean=} isWindowless
+ * Optional flag to indicate that the browser was started in windowless mode.
+ *
+ * @returns {Object<string,boolean>}
+ * Dictionary containing information that explains the shutdown reason.
+ * The value for `cause` contains the shutdown kind like "shutdown" or
+ * "restart", while `forced` will indicate if it was a normal or forced
+ * shutdown of the application. "in_app" is always set to indicate that
+ * it is a shutdown triggered from within the application.
+ */
+export async function quit(flags = [], safeMode = false, isWindowless = false) {
+ if (flags.includes("eSilently")) {
+ if (!isWindowless) {
+ throw new Error(
+ `Silent restarts only allowed with "moz:windowless" capability set`
+ );
+ }
+ if (!flags.includes("eRestart")) {
+ throw new TypeError(`"silently" only works with restart flag`);
+ }
+ }
+
+ const quits = ["eConsiderQuit", "eAttemptQuit", "eForceQuit"];
+
+ let quitSeen;
+ let mode = 0;
+ if (flags.length) {
+ for (let k of flags) {
+ if (!(k in Ci.nsIAppStartup)) {
+ throw new TypeError(lazy.pprint`Expected ${k} in ${Ci.nsIAppStartup}`);
+ }
+
+ if (quits.includes(k)) {
+ if (quitSeen) {
+ throw new TypeError(`${k} cannot be combined with ${quitSeen}`);
+ }
+ quitSeen = k;
+ }
+
+ mode |= Ci.nsIAppStartup[k];
+ }
+ }
+
+ if (!quitSeen) {
+ mode |= Ci.nsIAppStartup.eAttemptQuit;
+ }
+
+ // Notify all windows that an application quit has been requested.
+ const cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(
+ Ci.nsISupportsPRBool
+ );
+ Services.obs.notifyObservers(cancelQuit, "quit-application-requested");
+
+ // If the shutdown of the application is prevented force quit it instead.
+ if (cancelQuit.data) {
+ mode |= Ci.nsIAppStartup.eForceQuit;
+ }
+
+ // Delay response until the application is about to quit.
+ const quitApplication = lazy.waitForObserverTopic("quit-application");
+
+ if (safeMode) {
+ Services.startup.restartInSafeMode(mode);
+ } else {
+ Services.startup.quit(mode);
+ }
+
+ return {
+ cause: (await quitApplication).data,
+ forced: cancelQuit.data,
+ in_app: true,
+ };
+}