зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1606862 support devtools as an optional extension permission r=rpl
Differential Revision: https://phabricator.services.mozilla.com/D71829
This commit is contained in:
Родитель
a184202d1f
Коммит
327dcc3d53
|
@ -54,7 +54,7 @@
|
|||
"url": "chrome://browser/content/parent/ext-devtools.js",
|
||||
"schema": "chrome://browser/content/schemas/devtools.json",
|
||||
"scopes": ["devtools_parent"],
|
||||
"events": ["uninstall"],
|
||||
"events": ["uninstall", "startup"],
|
||||
"manifest": ["devtools_page"],
|
||||
"paths": [
|
||||
["devtools"]
|
||||
|
|
|
@ -29,9 +29,7 @@ function getDevToolsPrefBranchName(extensionId) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieve the devtools target for the devtools extension proxy context
|
||||
* (lazily cloned from the target of the toolbox associated to the context
|
||||
* the first time that it is accessed).
|
||||
* Retrieve the tabId for the given devtools toolbox.
|
||||
*
|
||||
* @param {Toolbox} toolbox
|
||||
* A devtools toolbox instance.
|
||||
|
@ -257,6 +255,7 @@ class DevToolsPageDefinition {
|
|||
if (this.devtoolsPageForToolbox.size === 0) {
|
||||
DevToolsShim.off("theme-changed", this.onThemeChanged);
|
||||
}
|
||||
this.extension.emit("devtools-page-shutdown", toolbox);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,11 +310,29 @@ this.devtools = class extends ExtensionAPI {
|
|||
constructor(extension) {
|
||||
super(extension);
|
||||
|
||||
this._initialized = false;
|
||||
|
||||
// DevToolsPageDefinition instance (created in onManifestEntry).
|
||||
this.pageDefinition = null;
|
||||
|
||||
this.onToolboxCreated = this.onToolboxCreated.bind(this);
|
||||
this.onToolboxDestroy = this.onToolboxDestroy.bind(this);
|
||||
|
||||
/* eslint-disable mozilla/balanced-listeners */
|
||||
extension.on("add-permissions", (ignoreEvent, permissions) => {
|
||||
if (permissions.permissions.includes("devtools")) {
|
||||
this._initialize();
|
||||
}
|
||||
});
|
||||
extension.on("remove-permissions", (ignoreEvent, permissions) => {
|
||||
Services.prefs.setBoolPref(
|
||||
`${getDevToolsPrefBranchName(extension.id)}.enabled`,
|
||||
false
|
||||
);
|
||||
if (permissions.permissions.includes("devtools")) {
|
||||
this._uninitialize();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static onUninstall(extensionId) {
|
||||
|
@ -327,9 +344,13 @@ this.devtools = class extends ExtensionAPI {
|
|||
prefBranch.deleteBranch("");
|
||||
}
|
||||
|
||||
onManifestEntry(entryName) {
|
||||
_initialize() {
|
||||
const { extension } = this;
|
||||
|
||||
if (!extension.hasPermission("devtools") || this._initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.initDevToolsPref();
|
||||
|
||||
// Create the devtools_page definition.
|
||||
|
@ -346,9 +367,17 @@ this.devtools = class extends ExtensionAPI {
|
|||
|
||||
DevToolsShim.on("toolbox-created", this.onToolboxCreated);
|
||||
DevToolsShim.on("toolbox-destroy", this.onToolboxDestroy);
|
||||
this._initialized = true;
|
||||
}
|
||||
|
||||
onShutdown() {
|
||||
_uninitialize() {
|
||||
// devtoolsPrefBranch is set in onManifestEntry, and nullified
|
||||
// later in onShutdown. If it isn't set, then onManifestEntry
|
||||
// did not initialize devtools for the extension.
|
||||
if (!this._initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
DevToolsShim.off("toolbox-created", this.onToolboxCreated);
|
||||
DevToolsShim.off("toolbox-destroy", this.onToolboxDestroy);
|
||||
|
||||
|
@ -362,6 +391,15 @@ this.devtools = class extends ExtensionAPI {
|
|||
}
|
||||
|
||||
this.uninitDevToolsPref();
|
||||
this._initialized = false;
|
||||
}
|
||||
|
||||
onStartup() {
|
||||
this._initialize();
|
||||
}
|
||||
|
||||
onShutdown() {
|
||||
this._uninitialize();
|
||||
}
|
||||
|
||||
getAPI(context) {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"$extend": "Permission",
|
||||
"$extend": "OptionalPermission",
|
||||
"choices": [{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
|
|
@ -119,6 +119,7 @@ support-files = !/browser/components/places/tests/browser/head.js
|
|||
[browser_ext_devtools_inspectedWindow_targetSwitch.js]
|
||||
[browser_ext_devtools_network.js]
|
||||
skip-if = fission || os == 'linux' || (os == 'mac' && debug) || (debug && os == 'win' && bits == 64) # Bug1570478
|
||||
[browser_ext_devtools_optional.js]
|
||||
[browser_ext_devtools_page.js]
|
||||
[browser_ext_devtools_page_incognito.js]
|
||||
[browser_ext_devtools_panel.js]
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
loadTestSubscript("head_devtools.js");
|
||||
|
||||
/**
|
||||
* This test file ensures that:
|
||||
*
|
||||
* - the devtools_page property creates a new WebExtensions context
|
||||
* - the devtools_page can exchange messages with the background page
|
||||
*/
|
||||
add_task(async function test_devtools_page_runtime_api_messaging() {
|
||||
Services.prefs.setBoolPref(
|
||||
"extensions.webextOptionalPermissionPrompts",
|
||||
false
|
||||
);
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("extensions.webextOptionalPermissionPrompts");
|
||||
});
|
||||
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
"http://mochi.test:8888/"
|
||||
);
|
||||
|
||||
function background() {
|
||||
let perm = { permissions: ["devtools"], origins: [] };
|
||||
browser.test.onMessage.addListener(async (msg, sender) => {
|
||||
if (msg === "request") {
|
||||
let granted = await new Promise(resolve => {
|
||||
browser.test.withHandlingUserInput(() => {
|
||||
resolve(browser.permissions.request(perm));
|
||||
});
|
||||
});
|
||||
browser.test.assertTrue(granted, "permission request succeeded");
|
||||
browser.test.sendMessage("done");
|
||||
} else if (msg === "revoke") {
|
||||
browser.permissions.remove(perm);
|
||||
browser.test.sendMessage("done");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function devtools_page() {
|
||||
browser.test.sendMessage("devtools_page_loaded");
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
background,
|
||||
manifest: {
|
||||
optional_permissions: ["devtools"],
|
||||
devtools_page: "devtools_page.html",
|
||||
},
|
||||
files: {
|
||||
"devtools_page.html": `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<script src="devtools_page.js"></script>
|
||||
</body>
|
||||
</html>`,
|
||||
"devtools_page.js": devtools_page,
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
function checkEnabled(expect = false) {
|
||||
Assert.equal(
|
||||
expect,
|
||||
Services.prefs.getBoolPref(
|
||||
`devtools.webextensions.${extension.id}.enabled`,
|
||||
false
|
||||
),
|
||||
"devtools enabled pref is correct"
|
||||
);
|
||||
}
|
||||
|
||||
checkEnabled(false);
|
||||
|
||||
// Open the devtools first, then request permission
|
||||
info("Open the developer toolbox");
|
||||
await openToolboxForTab(tab);
|
||||
assertDevToolsExtensionEnabled(extension.uuid, false);
|
||||
|
||||
extension.sendMessage("request");
|
||||
await extension.awaitMessage("done");
|
||||
checkEnabled(true);
|
||||
|
||||
info("Wait the devtools page load");
|
||||
await extension.awaitMessage("devtools_page_loaded");
|
||||
assertDevToolsExtensionEnabled(extension.uuid, true);
|
||||
|
||||
let policy = WebExtensionPolicy.getByID(extension.id);
|
||||
let closed = new Promise(resolve => {
|
||||
// eslint-disable-next-line mozilla/balanced-listeners
|
||||
policy.extension.on("devtools-page-shutdown", resolve);
|
||||
});
|
||||
|
||||
extension.sendMessage("revoke");
|
||||
await extension.awaitMessage("done");
|
||||
|
||||
await closed;
|
||||
checkEnabled(false);
|
||||
assertDevToolsExtensionEnabled(extension.uuid, false);
|
||||
|
||||
await extension.unload();
|
||||
|
||||
await closeToolboxForTab(tab);
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
|
@ -3,7 +3,7 @@
|
|||
"use strict";
|
||||
|
||||
/* exported openToolboxForTab, closeToolboxForTab, getToolboxTargetForTab,
|
||||
registerBlankToolboxPanel, TOOLBOX_BLANK_PANEL_ID */
|
||||
registerBlankToolboxPanel, TOOLBOX_BLANK_PANEL_ID, assertDevToolsExtensionEnabled */
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
|
@ -19,6 +19,12 @@ XPCOMUtils.defineLazyGetter(this, "TargetFactory", () => {
|
|||
return TargetFactory;
|
||||
});
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"DevToolsShim",
|
||||
"chrome://devtools-startup/content/DevToolsShim.jsm"
|
||||
);
|
||||
|
||||
const TOOLBOX_BLANK_PANEL_ID = "testBlankPanel";
|
||||
|
||||
// Register a blank custom tool so that we don't need to wait the webconsole
|
||||
|
@ -86,3 +92,13 @@ async function closeToolboxForTab(tab) {
|
|||
})}`
|
||||
);
|
||||
}
|
||||
|
||||
function assertDevToolsExtensionEnabled(uuid, enabled) {
|
||||
for (let toolbox of DevToolsShim.getToolboxes()) {
|
||||
is(
|
||||
enabled,
|
||||
!!toolbox.isWebExtensionEnabled(uuid),
|
||||
`extension is ${enabled ? "enabled" : "disabled"} on toolbox`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -635,7 +635,10 @@ class ExtensionData {
|
|||
this.manifest.permissions
|
||||
);
|
||||
|
||||
if (this.manifest.devtools_page) {
|
||||
if (
|
||||
this.manifest.devtools_page &&
|
||||
!this.manifest.optional_permissions.includes("devtools")
|
||||
) {
|
||||
permissions.add("devtools");
|
||||
}
|
||||
|
||||
|
@ -2435,6 +2438,18 @@ class Extension extends ExtensionData {
|
|||
}
|
||||
}
|
||||
|
||||
// Ensure devtools permission is set
|
||||
if (
|
||||
this.manifest.devtools_page &&
|
||||
!this.manifest.optional_permissions.includes("devtools")
|
||||
) {
|
||||
ExtensionPermissions.add(this.id, {
|
||||
permissions: ["devtools"],
|
||||
origins: [],
|
||||
});
|
||||
this.permissions.add("devtools");
|
||||
}
|
||||
|
||||
GlobalManager.init(this);
|
||||
|
||||
this.initSharedData();
|
||||
|
|
|
@ -50,6 +50,7 @@ add_task(async function setup() {
|
|||
"activeTab",
|
||||
"clipboardRead",
|
||||
"clipboardWrite",
|
||||
"devtools",
|
||||
"downloads.open",
|
||||
"geolocation",
|
||||
"management",
|
||||
|
|
Загрузка…
Ссылка в новой задаче