Bug 1429185 - Disable all devtools entry points with devtools.policy.disabled;r=ochameau
MozReview-Commit-ID: 9ObZc8my1mE
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -430,17 +430,18 @@ nsContextMenu.prototype = {
this.onMathML && !this.isContentSelected);
var shouldShow = !(this.isContentSelected ||
this.onImage || this.onCanvas ||
this.onVideo || this.onAudio ||
this.onLink || this.onTextInput);
var showInspect = this.inTabBrowser &&
- Services.prefs.getBoolPref("devtools.inspector.enabled", true);
+ Services.prefs.getBoolPref("devtools.inspector.enabled", true) &&
+ !Services.prefs.getBoolPref("devtools.policy.disabled", false);
this.showItem("context-viewsource", shouldShow);
this.showItem("context-viewinfo", shouldShow);
// The page info is broken for WebExtension popups, as the browser is
// destroyed when the popup is closed.
this.setItemAttr("context-viewinfo", "disabled", this.webExtBrowserType === "popup");
this.showItem("inspect-separator", showInspect);
this.showItem("context-inspect", showInspect);
--- a/devtools/shim/devtools-startup-prefs.js
+++ b/devtools/shim/devtools-startup-prefs.js
@@ -30,8 +30,12 @@ pref("devtools.onboarding.experiment", "
// If devtools.onboarding.experiment is set to "on" or "force", we will flip the
// devtools.enabled preference to false once. The flag is used to make sure it is only
// flipped once.
pref("devtools.onboarding.experiment.flipped", false);
// Flag to check if we already logged the devtools onboarding related probe.
pref("devtools.onboarding.telemetry.logged", false);
+
+// Completely disable DevTools entry points, as well as all DevTools command line
+// arguments This should be merged with devtools.enabled, see Bug 1440675.
+pref("devtools.policy.disabled", false);
\ No newline at end of file
--- a/devtools/shim/devtools-startup.js
+++ b/devtools/shim/devtools-startup.js
@@ -27,16 +27,18 @@ const kDebuggerPrefs = [
];
// If devtools.toolbar.visible is set to true, the developer toolbar should appear on
// startup.
const TOOLBAR_VISIBLE_PREF = "devtools.toolbar.visible";
const DEVTOOLS_ENABLED_PREF = "devtools.enabled";
+const DEVTOOLS_POLICY_DISABLED_PREF = "devtools.policy.disabled";
+
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", {});
ChromeUtils.defineModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm");
ChromeUtils.defineModuleGetter(this, "CustomizableUI",
"resource:///modules/CustomizableUI.jsm");
ChromeUtils.defineModuleGetter(this, "CustomizableWidgets",
@@ -187,69 +189,90 @@ DevToolsStartup.prototype = {
*/
recorded: false,
/**
* Flag that indicates if the developer toggle was already added to customizableUI.
*/
developerToggleCreated: false,
+ isDisabledByPolicy: function () {
+ return Services.prefs.getBoolPref(DEVTOOLS_POLICY_DISABLED_PREF, false);
+ },
+
handle: function (cmdLine) {
- let consoleFlag = cmdLine.handleFlag("jsconsole", false);
- let debuggerFlag = cmdLine.handleFlag("jsdebugger", false);
- let devtoolsFlag = cmdLine.handleFlag("devtools", false);
+ let flags = this.readCommandLineFlags(cmdLine);
// handle() can be called after browser startup (e.g. opening links from other apps).
let isInitialLaunch = cmdLine.state == Ci.nsICommandLine.STATE_INITIAL_LAUNCH;
if (isInitialLaunch) {
// Execute only on first launch of this browser instance.
- let hasDevToolsFlag = consoleFlag || devtoolsFlag || debuggerFlag;
+ let hasDevToolsFlag = flags.console || flags.devtools || flags.debugger;
this.setupEnabledPref(hasDevToolsFlag);
// Store devtoolsFlag to check it later in onWindowReady.
- this.devtoolsFlag = devtoolsFlag;
+ this.devtoolsFlag = flags.devtools;
// Only top level Firefox Windows fire a browser-delayed-startup-finished event
Services.obs.addObserver(this.onWindowReady, "browser-delayed-startup-finished");
- if (AppConstants.MOZ_DEV_EDITION) {
+ if (AppConstants.MOZ_DEV_EDITION && !this.isDisabledByPolicy()) {
// On DevEdition, the developer toggle is displayed by default in the navbar area
// and should be created before the first paint.
this.hookDeveloperToggle();
}
// Update menu items when devtools.enabled changes.
Services.prefs.addObserver(DEVTOOLS_ENABLED_PREF, this.onEnabledPrefChanged);
}
- if (consoleFlag) {
+ if (flags.console) {
this.handleConsoleFlag(cmdLine);
}
- if (debuggerFlag) {
+ if (flags.debugger) {
this.handleDebuggerFlag(cmdLine);
}
- let debuggerServerFlag;
+ if (flags.debuggerServer) {
+ this.handleDebuggerServerFlag(cmdLine, flags.debuggerServer);
+ }
+ },
+
+ readCommandLineFlags(cmdLine) {
+ // All command line flags are disabled if DevTools are disabled by policy.
+ if (this.isDisabledByPolicy()) {
+ return { console: false, debugger: false, devtools: false, debuggerServer: false };
+ }
+
+ let console = cmdLine.handleFlag("jsconsole", false);
+ let debuggerFlag = cmdLine.handleFlag("jsdebugger", false);
+ let devtools = cmdLine.handleFlag("devtools", false);
+
+ let debuggerServer;
try {
- debuggerServerFlag =
+ debuggerServer =
cmdLine.handleFlagWithParam("start-debugger-server", false);
} catch (e) {
// We get an error if the option is given but not followed by a value.
// By catching and trying again, the value is effectively optional.
- debuggerServerFlag = cmdLine.handleFlag("start-debugger-server", false);
+ debuggerServer = cmdLine.handleFlag("start-debugger-server", false);
}
- if (debuggerServerFlag) {
- this.handleDebuggerServerFlag(cmdLine, debuggerServerFlag);
- }
+
+ return { console, debugger: debuggerFlag, devtools, debuggerServer };
},
/**
* Called when receiving the "browser-delayed-startup-finished" event for a new
* top-level window.
*/
onWindowReady(window) {
+ if (this.isDisabledByPolicy()) {
+ this.removeDevToolsMenus(window);
+ return;
+ }
+
this.hookWindow(window);
if (Services.prefs.getBoolPref(TOOLBAR_VISIBLE_PREF, false)) {
// Loading devtools-browser will open the developer toolbar by also checking this
// pref.
this.initDevTools();
}
@@ -258,16 +281,24 @@ DevToolsStartup.prototype = {
if (!this._firstWindowReadyReceived) {
this.onFirstWindowReady(window);
this._firstWindowReadyReceived = true;
}
JsonView.initialize();
},
+ removeDevToolsMenus(window) {
+ // This will hide the "Tools > Web Developer" menu.
+ window.document.getElementById("webDeveloperMenu").setAttribute("hidden", "true");
+ // This will hide the "Web Developer" item in the hamburger menu.
+ window.document.getElementById("appMenu-developer-button").setAttribute("hidden",
+ "true");
+ },
+
onFirstWindowReady(window) {
if (this.devtoolsFlag) {
this.handleDevToolsFlag(window);
}
// Wait until we get a window before sending a ping to telemetry to avoid slowing down
// the startup phase.
this.pingOnboardingTelemetry();
@@ -611,16 +642,22 @@ DevToolsStartup.prototype = {
* @param {String} reason
* One of "KeyShortcut", "SystemMenu", "HamburgerMenu", "ContextMenu",
* "CommandLine".
* @param {String} keyId
* Optional. If the onboarding flow was triggered by a keyboard shortcut, pass
* the shortcut key id (or toolId) to about:devtools.
*/
openInstallPage: function (reason, keyId) {
+ // If DevTools are completely disabled, bail out here as this might be called directly
+ // from other files.
+ if (this.isDisabledByPolicy()) {
+ return;
+ }
+
let { gBrowser } = Services.wm.getMostRecentWindow("navigator:browser");
// Focus about:devtools tab if there is already one opened in the current window.
for (let tab of gBrowser.tabs) {
let browser = tab.linkedBrowser;
// browser.documentURI might be undefined if the browser tab is still loading.
let location = browser.documentURI ? browser.documentURI.spec : "";
if (location.startsWith("about:devtools") &&