mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-20 08:51:04 +00:00
Bug 1748550 support persisted events for captivePortal r=rpl,robwu
Differential Revision: https://phabricator.services.mozilla.com/D136299
This commit is contained in:
parent
8d79179a4c
commit
d854f45476
@ -27,83 +27,126 @@ 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");
|
||||
}
|
||||
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 = (subject, topic) => {
|
||||
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, context) {
|
||||
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, context) {
|
||||
fire = _fire;
|
||||
},
|
||||
};
|
||||
},
|
||||
"captiveURL.onChange": 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 {
|
||||
unregister: () => {
|
||||
Services.prefs.removeObserver(CAPTIVE_URL_PREF, listener);
|
||||
},
|
||||
convert(_fire, context) {
|
||||
fire = _fire;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
primeListener(extension, event, fire) {
|
||||
if (Object.hasOwn(this.PERSISTENT_EVENTS, event)) {
|
||||
return this.PERSISTENT_EVENTS[event](fire);
|
||||
}
|
||||
}
|
||||
|
||||
getAPI(context) {
|
||||
let self = this;
|
||||
return {
|
||||
captivePortal: {
|
||||
getState() {
|
||||
checkEnabled();
|
||||
return nameForCPSState(gCPS.state);
|
||||
self.checkCaptivePortalEnabled();
|
||||
return self.nameForCPSState(gCPS.state);
|
||||
},
|
||||
getLastChecked() {
|
||||
checkEnabled();
|
||||
self.checkCaptivePortalEnabled();
|
||||
return gCPS.lastChecked;
|
||||
},
|
||||
onStateChanged: new EventManager({
|
||||
context,
|
||||
name: "captivePortal.onStateChanged",
|
||||
module: "captivePortal",
|
||||
event: "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"
|
||||
);
|
||||
};
|
||||
return self.PERSISTENT_EVENTS.onStateChanged(fire).unregister;
|
||||
},
|
||||
}).api(),
|
||||
onConnectivityAvailable: new EventManager({
|
||||
context,
|
||||
name: "captivePortal.onConnectivityAvailable",
|
||||
module: "captivePortal",
|
||||
event: "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"
|
||||
);
|
||||
};
|
||||
return self.PERSISTENT_EVENTS.onConnectivityAvailable(fire)
|
||||
.unregister;
|
||||
},
|
||||
}).api(),
|
||||
canonicalURL: getSettingsAPI({
|
||||
@ -115,18 +158,11 @@ this.captivePortal = class extends ExtensionAPI {
|
||||
readOnly: true,
|
||||
onChange: new ExtensionCommon.EventManager({
|
||||
context,
|
||||
name: "captiveURL.onChange",
|
||||
module: "captivePortal",
|
||||
event: "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);
|
||||
};
|
||||
return self.PERSISTENT_EVENTS["captiveURL.onChange"](fire)
|
||||
.unregister;
|
||||
},
|
||||
}).api(),
|
||||
}),
|
||||
|
@ -1,5 +1,19 @@
|
||||
"use strict";
|
||||
|
||||
Services.prefs.setBoolPref(
|
||||
"extensions.webextensions.background-delayed-startup",
|
||||
true
|
||||
);
|
||||
|
||||
AddonTestUtils.init(this);
|
||||
AddonTestUtils.overrideCertDB();
|
||||
AddonTestUtils.createAppInfo(
|
||||
"xpcshell@tests.mozilla.org",
|
||||
"XPCShell",
|
||||
"1",
|
||||
"43"
|
||||
);
|
||||
|
||||
/**
|
||||
* This duplicates the test from netwerk/test/unit/test_captive_portal_service.js
|
||||
* however using an extension to gather the captive portal information.
|
||||
@ -30,7 +44,7 @@ registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref(PREF_DNS_NATIVE_IS_LOCALHOST);
|
||||
});
|
||||
|
||||
add_task(function setup() {
|
||||
add_task(async function setup() {
|
||||
Services.prefs.setCharPref(
|
||||
PREF_CAPTIVE_ENDPOINT,
|
||||
`http://localhost:${httpserver.identity.primaryPort}/captive.txt`
|
||||
@ -38,6 +52,9 @@ add_task(function setup() {
|
||||
Services.prefs.setBoolPref(PREF_CAPTIVE_TESTMODE, true);
|
||||
Services.prefs.setIntPref(PREF_CAPTIVE_MINTIME, 0);
|
||||
Services.prefs.setBoolPref(PREF_DNS_NATIVE_IS_LOCALHOST, true);
|
||||
|
||||
Services.prefs.setBoolPref("extensions.eventPages.enabled", true);
|
||||
await AddonTestUtils.promiseStartupManager();
|
||||
});
|
||||
|
||||
add_task(async function test_captivePortal_basic() {
|
||||
@ -46,8 +63,10 @@ add_task(async function test_captivePortal_basic() {
|
||||
);
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
useAddonManager: "permanent",
|
||||
manifest: {
|
||||
permissions: ["captivePortal"],
|
||||
background: { persistent: false },
|
||||
},
|
||||
isPrivileged: true,
|
||||
async background() {
|
||||
@ -63,6 +82,10 @@ add_task(async function test_captivePortal_basic() {
|
||||
browser.test.sendMessage("state", details);
|
||||
});
|
||||
|
||||
browser.captivePortal.canonicalURL.onChange.addListener(details => {
|
||||
browser.test.sendMessage("url", details);
|
||||
});
|
||||
|
||||
browser.test.onMessage.addListener(async msg => {
|
||||
if (msg == "getstate") {
|
||||
browser.test.sendMessage(
|
||||
@ -71,21 +94,20 @@ add_task(async function test_captivePortal_basic() {
|
||||
);
|
||||
}
|
||||
});
|
||||
browser.test.assertEq(
|
||||
"unknown",
|
||||
await browser.captivePortal.getState(),
|
||||
"initial state unknown"
|
||||
);
|
||||
},
|
||||
});
|
||||
await extension.startup();
|
||||
|
||||
extension.sendMessage("getstate");
|
||||
let details = await extension.awaitMessage("getstate");
|
||||
equal(details, "unknown", "initial state");
|
||||
|
||||
// The captive portal service is started by nsIOService when the pref becomes true, so we
|
||||
// toggle the pref. We cannot set to false before the extension loads above.
|
||||
Services.prefs.setBoolPref(PREF_CAPTIVE_ENABLED, false);
|
||||
Services.prefs.setBoolPref(PREF_CAPTIVE_ENABLED, true);
|
||||
|
||||
let details = await extension.awaitMessage("connectivity");
|
||||
details = await extension.awaitMessage("connectivity");
|
||||
equal(details.status, "clear", "initial connectivity");
|
||||
extension.sendMessage("getstate");
|
||||
details = await extension.awaitMessage("getstate");
|
||||
@ -106,5 +128,65 @@ add_task(async function test_captivePortal_basic() {
|
||||
details = await extension.awaitMessage("state");
|
||||
equal(details.state, "unlocked_portal", "state after unlocking portal");
|
||||
|
||||
assertPersistentListeners(
|
||||
extension,
|
||||
"captivePortal",
|
||||
"onConnectivityAvailable",
|
||||
{
|
||||
primed: false,
|
||||
}
|
||||
);
|
||||
|
||||
assertPersistentListeners(extension, "captivePortal", "onStateChanged", {
|
||||
primed: false,
|
||||
});
|
||||
|
||||
assertPersistentListeners(extension, "captivePortal", "captiveURL.onChange", {
|
||||
primed: false,
|
||||
});
|
||||
|
||||
info("Test event page terminate/waken");
|
||||
await extension.terminateBackground();
|
||||
|
||||
assertPersistentListeners(extension, "captivePortal", "onStateChanged", {
|
||||
primed: true,
|
||||
});
|
||||
assertPersistentListeners(
|
||||
extension,
|
||||
"captivePortal",
|
||||
"onConnectivityAvailable",
|
||||
{
|
||||
primed: true,
|
||||
}
|
||||
);
|
||||
|
||||
assertPersistentListeners(extension, "captivePortal", "captiveURL.onChange", {
|
||||
primed: true,
|
||||
});
|
||||
|
||||
info("REFRESH 2nd pass to other");
|
||||
cpResponse = "other";
|
||||
cps.recheckCaptivePortal();
|
||||
details = await extension.awaitMessage("state");
|
||||
equal(details.state, "locked_portal", "state in portal");
|
||||
|
||||
info("Test event page terminate/waken with settings");
|
||||
await extension.terminateBackground();
|
||||
|
||||
assertPersistentListeners(extension, "captivePortal", "captiveURL.onChange", {
|
||||
primed: true,
|
||||
});
|
||||
|
||||
Services.prefs.setStringPref(
|
||||
"captivedetect.canonicalURL",
|
||||
"http://example.com"
|
||||
);
|
||||
let url = await extension.awaitMessage("url");
|
||||
equal(
|
||||
url.value,
|
||||
"http://example.com",
|
||||
"The canonicalURL setting has the expected value."
|
||||
);
|
||||
|
||||
await extension.unload();
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user