diff options
Diffstat (limited to 'toolkit/components/extensions/parent/ext-captivePortal.js')
-rw-r--r-- | toolkit/components/extensions/parent/ext-captivePortal.js | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/toolkit/components/extensions/parent/ext-captivePortal.js b/toolkit/components/extensions/parent/ext-captivePortal.js new file mode 100644 index 0000000000..baf0e04e39 --- /dev/null +++ b/toolkit/components/extensions/parent/ext-captivePortal.js @@ -0,0 +1,136 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +/* 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/. */ +"use strict"; + +XPCOMUtils.defineLazyServiceGetter( + this, + "gCPS", + "@mozilla.org/network/captive-portal-service;1", + "nsICaptivePortalService" +); + +XPCOMUtils.defineLazyPreferenceGetter( + this, + "gCaptivePortalEnabled", + "network.captive-portal-service.enabled", + false +); + +var { ExtensionPreferencesManager } = ChromeUtils.import( + "resource://gre/modules/ExtensionPreferencesManager.jsm" +); + +var { getSettingsAPI } = ExtensionPreferencesManager; + +const CAPTIVE_URL_PREF = "captivedetect.canonicalURL"; + +function nameForCPSState(state) { + switch (state) { + case gCPS.UNKNOWN: + return "unknown"; + case gCPS.NOT_CAPTIVE: + return "not_captive"; + case gCPS.UNLOCKED_PORTAL: + return "unlocked_portal"; + case gCPS.LOCKED_PORTAL: + return "locked_portal"; + default: + return "unknown"; + } +} + +var { ExtensionError } = ExtensionUtils; + +this.captivePortal = class extends ExtensionAPI { + getAPI(context) { + function checkEnabled() { + if (!gCaptivePortalEnabled) { + throw new ExtensionError("Captive Portal detection is not enabled"); + } + } + + return { + captivePortal: { + getState() { + checkEnabled(); + return nameForCPSState(gCPS.state); + }, + getLastChecked() { + checkEnabled(); + return gCPS.lastChecked; + }, + onStateChanged: new EventManager({ + context, + name: "captivePortal.onStateChanged", + register: fire => { + checkEnabled(); + + let observer = (subject, topic) => { + fire.async({ state: nameForCPSState(gCPS.state) }); + }; + + Services.obs.addObserver( + observer, + "ipc:network:captive-portal-set-state" + ); + return () => { + Services.obs.removeObserver( + observer, + "ipc:network:captive-portal-set-state" + ); + }; + }, + }).api(), + onConnectivityAvailable: new EventManager({ + context, + name: "captivePortal.onConnectivityAvailable", + register: fire => { + checkEnabled(); + + let observer = (subject, topic, data) => { + fire.async({ status: data }); + }; + + Services.obs.addObserver( + observer, + "network:captive-portal-connectivity" + ); + return () => { + Services.obs.removeObserver( + observer, + "network:captive-portal-connectivity" + ); + }; + }, + }).api(), + canonicalURL: getSettingsAPI({ + context, + name: "captiveURL", + callback() { + return Services.prefs.getStringPref(CAPTIVE_URL_PREF); + }, + readOnly: true, + onChange: new ExtensionCommon.EventManager({ + context, + name: "captiveURL.onChange", + register: fire => { + let listener = (text, id) => { + fire.async({ + levelOfControl: "not_controllable", + value: Services.prefs.getStringPref(CAPTIVE_URL_PREF), + }); + }; + Services.prefs.addObserver(CAPTIVE_URL_PREF, listener); + return () => { + Services.prefs.removeObserver(CAPTIVE_URL_PREF, listener); + }; + }, + }).api(), + }), + }, + }; + } +}; |