158 lines
4 KiB
JavaScript
158 lines
4 KiB
JavaScript
/* -*- 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.importESModule(
|
|
"resource://gre/modules/ExtensionPreferencesManager.sys.mjs"
|
|
);
|
|
|
|
var { getSettingsAPI } = ExtensionPreferencesManager;
|
|
|
|
const CAPTIVE_URL_PREF = "captivedetect.canonicalURL";
|
|
|
|
var { ExtensionError } = ExtensionUtils;
|
|
|
|
this.captivePortal = class extends ExtensionAPIPersistent {
|
|
checkCaptivePortalEnabled() {
|
|
if (!gCaptivePortalEnabled) {
|
|
throw new ExtensionError("Captive Portal detection is not enabled");
|
|
}
|
|
}
|
|
|
|
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";
|
|
}
|
|
}
|
|
|
|
PERSISTENT_EVENTS = {
|
|
onStateChanged({ fire }) {
|
|
this.checkCaptivePortalEnabled();
|
|
|
|
let observer = () => {
|
|
fire.async({ state: this.nameForCPSState(gCPS.state) });
|
|
};
|
|
|
|
Services.obs.addObserver(
|
|
observer,
|
|
"ipc:network:captive-portal-set-state"
|
|
);
|
|
return {
|
|
unregister: () => {
|
|
Services.obs.removeObserver(
|
|
observer,
|
|
"ipc:network:captive-portal-set-state"
|
|
);
|
|
},
|
|
convert(_fire) {
|
|
fire = _fire;
|
|
},
|
|
};
|
|
},
|
|
onConnectivityAvailable({ fire }) {
|
|
this.checkCaptivePortalEnabled();
|
|
|
|
let observer = (subject, topic, data) => {
|
|
fire.async({ status: data });
|
|
};
|
|
|
|
Services.obs.addObserver(observer, "network:captive-portal-connectivity");
|
|
return {
|
|
unregister: () => {
|
|
Services.obs.removeObserver(
|
|
observer,
|
|
"network:captive-portal-connectivity"
|
|
);
|
|
},
|
|
convert(_fire) {
|
|
fire = _fire;
|
|
},
|
|
};
|
|
},
|
|
"captiveURL.onChange": ({ fire }) => {
|
|
let listener = () => {
|
|
fire.async({
|
|
levelOfControl: "not_controllable",
|
|
value: Services.prefs.getStringPref(CAPTIVE_URL_PREF),
|
|
});
|
|
};
|
|
Services.prefs.addObserver(CAPTIVE_URL_PREF, listener);
|
|
return {
|
|
unregister: () => {
|
|
Services.prefs.removeObserver(CAPTIVE_URL_PREF, listener);
|
|
},
|
|
convert(_fire) {
|
|
fire = _fire;
|
|
},
|
|
};
|
|
},
|
|
};
|
|
|
|
getAPI(context) {
|
|
let self = this;
|
|
return {
|
|
captivePortal: {
|
|
getState() {
|
|
self.checkCaptivePortalEnabled();
|
|
return self.nameForCPSState(gCPS.state);
|
|
},
|
|
getLastChecked() {
|
|
self.checkCaptivePortalEnabled();
|
|
return gCPS.lastChecked;
|
|
},
|
|
onStateChanged: new EventManager({
|
|
context,
|
|
module: "captivePortal",
|
|
event: "onStateChanged",
|
|
extensionApi: self,
|
|
}).api(),
|
|
onConnectivityAvailable: new EventManager({
|
|
context,
|
|
module: "captivePortal",
|
|
event: "onConnectivityAvailable",
|
|
extensionApi: self,
|
|
}).api(),
|
|
canonicalURL: getSettingsAPI({
|
|
context,
|
|
name: "captiveURL",
|
|
callback() {
|
|
return Services.prefs.getStringPref(CAPTIVE_URL_PREF);
|
|
},
|
|
readOnly: true,
|
|
onChange: new ExtensionCommon.EventManager({
|
|
context,
|
|
module: "captivePortal",
|
|
event: "captiveURL.onChange",
|
|
extensionApi: self,
|
|
}).api(),
|
|
}),
|
|
},
|
|
};
|
|
}
|
|
};
|