Backed out 7 changesets (bug 942756) for Gi bustage

Backed out changeset 87b1be303630 (bug 942756)
Backed out changeset eb385c85d88b (bug 942756)
Backed out changeset d234447173a8 (bug 942756)
Backed out changeset f7b85c252914 (bug 942756)
Backed out changeset 4e540736b330 (bug 942756)
Backed out changeset 824aec2863f5 (bug 942756)
Backed out changeset 43feed75916e (bug 942756)
This commit is contained in:
Wes Kocher 2014-04-24 14:30:44 -07:00
parent ed053a0c6b
commit 2e003f97d2
55 changed files with 739 additions and 1129 deletions

View File

@ -847,13 +847,9 @@ pref("b2g.adb.timeout-hours", 12);
// InputMethod so we can do soft keyboards
pref("dom.mozInputMethod.enabled", true);
#ifdef MOZ_WIDGET_GONK
// Absolute path to the devtool unix domain socket file used
// to communicate with a usb cable via adb forward
pref("devtools.debugger.unix-domain-socket", "/data/local/debugger-socket");
#else
pref("devtools.debugger.remote-port", 6000);
#endif
// enable Skia/GL (OpenGL-accelerated 2D drawing) for large enough 2d canvases,
// falling back to Skia/software for smaller canvases

View File

@ -1,267 +0,0 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* 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;"
Components.utils.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this,
"DebuggerServer",
"resource://gre/modules/devtools/dbg-server.jsm");
let adbController = {
DEBUG: false,
locked: undefined,
remoteDebuggerEnabled: undefined,
lockEnabled: undefined,
disableAdbTimer: null,
disableAdbTimeoutHours: 12,
umsActive: false,
init: function() {
this.updateState = this.updateState.bind(this);
Services.obs.addObserver(this.updateState,
"debugger-connection-changed",
false);
SettingsListener.observe('lockscreen.locked', undefined,
v => this.setLockscreenState(v));
SettingsListener.observe('lockscreen.enabled', undefined,
v => this.setLockscreenEnabled(v));
SettingsListener.observe('debugger.remote-mode', 'disabled',
v => {
this.setRemoteDebuggerState(v != 'disabled');
});
},
debug: function(str) {
dump("AdbController: " + str + "\n");
},
setLockscreenEnabled: function(value) {
this.lockEnabled = value;
if (this.DEBUG) {
this.debug("setLockscreenEnabled = " + this.lockEnabled);
}
this.updateState();
},
setLockscreenState: function(value) {
this.locked = value;
if (this.DEBUG) {
this.debug("setLockscreenState = " + this.locked);
}
this.updateState();
},
setRemoteDebuggerState: function(value) {
this.remoteDebuggerEnabled = value;
if (this.DEBUG) {
this.debug("setRemoteDebuggerState = " + this.remoteDebuggerEnabled);
}
this.updateState();
},
startDisableAdbTimer: function() {
if (this.disableAdbTimer) {
this.disableAdbTimer.cancel();
} else {
this.disableAdbTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
try {
this.disableAdbTimeoutHours =
Services.prefs.getIntPref("b2g.adb.timeout-hours");
} catch (e) {
// This happens if the pref doesn't exist, in which case
// disableAdbTimeoutHours will still be set to the default.
}
}
if (this.disableAdbTimeoutHours <= 0) {
if (this.DEBUG) {
this.debug("Timer to disable ADB not started due to zero timeout");
}
return;
}
if (this.DEBUG) {
this.debug("Starting timer to disable ADB in " +
this.disableAdbTimeoutHours + " hours");
}
let timeoutMilliseconds = this.disableAdbTimeoutHours * 60 * 60 * 1000;
this.disableAdbTimer.initWithCallback(this, timeoutMilliseconds,
Ci.nsITimer.TYPE_ONE_SHOT);
},
stopDisableAdbTimer: function() {
if (this.DEBUG) {
this.debug("Stopping timer to disable ADB");
}
if (this.disableAdbTimer) {
this.disableAdbTimer.cancel();
this.disableAdbTimer = null;
}
},
notify: function(aTimer) {
if (aTimer == this.disableAdbTimer) {
this.disableAdbTimer = null;
// The following dump will be the last thing that shows up in logcat,
// and will at least give the user a clue about why logcat was
// disconnected, if the user happens to be using logcat.
dump("AdbController: ADB timer expired - disabling ADB\n");
navigator.mozSettings.createLock().set(
{'devtools.debugger.remote-enabled': false});
}
},
updateState: function() {
this.umsActive = false;
this.storages = navigator.getDeviceStorages('sdcard');
this.updateStorageState(0);
},
updateStorageState: function(storageIndex) {
if (storageIndex >= this.storages.length) {
// We've iterated through all of the storage objects, now we can
// really do updateStateInternal.
this.updateStateInternal();
return;
}
let storage = this.storages[storageIndex];
if (this.DEBUG) {
this.debug("Checking availability of storage: '" +
storage.storageName);
}
let req = storage.available();
req.onsuccess = function(e) {
if (this.DEBUG) {
this.debug("Storage: '" + storage.storageName + "' is '" +
e.target.result);
}
if (e.target.result == 'shared') {
// We've found a storage area that's being shared with the PC.
// We can stop looking now.
this.umsActive = true;
this.updateStateInternal();
return;
}
this.updateStorageState(storageIndex + 1);
}.bind(this);
req.onerror = function(e) {
dump("AdbController: error querying storage availability for '" +
this.storages[storageIndex].storageName + "' (ignoring)\n");
this.updateStorageState(storageIndex + 1);
}.bind(this);
},
updateStateInternal: function() {
if (this.DEBUG) {
this.debug("updateStateInternal: called");
}
if (this.remoteDebuggerEnabled === undefined ||
this.lockEnabled === undefined ||
this.locked === undefined) {
// Part of initializing the settings database will cause the observers
// to trigger. We want to wait until both have been initialized before
// we start changing ther adb state. Without this then we can wind up
// toggling adb off and back on again (or on and back off again).
//
// For completeness, one scenario which toggles adb is using the unagi.
// The unagi has adb enabled by default (prior to b2g starting). If you
// have the phone lock disabled and remote debugging enabled, then we'll
// receive an unlock event and an rde event. However at the time we
// receive the unlock event we haven't yet received the rde event, so
// we turn adb off momentarily, which disconnects a logcat that might
// be running. Changing the defaults (in AdbController) just moves the
// problem to a different phone, which has adb disabled by default and
// we wind up turning on adb for a short period when we shouldn't.
//
// By waiting until both values are properly initialized, we avoid
// turning adb on or off accidentally.
if (this.DEBUG) {
this.debug("updateState: Waiting for all vars to be initialized");
}
return;
}
// Check if we have a remote debugging session going on. If so, we won't
// disable adb even if the screen is locked.
let isDebugging = DebuggerServer.isSocketConnected();
if (this.DEBUG) {
this.debug("isDebugging=" + isDebugging);
}
// If USB Mass Storage, USB tethering, or a debug session is active,
// then we don't want to disable adb in an automatic fashion (i.e.
// when the screen locks or due to timeout).
let sysUsbConfig = libcutils.property_get("sys.usb.config");
let rndisActive = (sysUsbConfig.split(",").indexOf("rndis") >= 0);
let usbFuncActive = rndisActive || this.umsActive || isDebugging;
let enableAdb = this.remoteDebuggerEnabled &&
(!(this.lockEnabled && this.locked) || usbFuncActive);
let useDisableAdbTimer = true;
try {
if (Services.prefs.getBoolPref("marionette.defaultPrefs.enabled")) {
// Marionette is enabled. Marionette requires that adb be on (and also
// requires that remote debugging be off). The fact that marionette
// is enabled also implies that we're doing a non-production build, so
// we want adb enabled all of the time.
enableAdb = true;
useDisableAdbTimer = false;
}
} catch (e) {
// This means that the pref doesn't exist. Which is fine. We just leave
// enableAdb alone.
}
if (this.DEBUG) {
this.debug("updateState: enableAdb = " + enableAdb +
" remoteDebuggerEnabled = " + this.remoteDebuggerEnabled +
" lockEnabled = " + this.lockEnabled +
" locked = " + this.locked +
" usbFuncActive = " + usbFuncActive);
}
// Configure adb.
let currentConfig = libcutils.property_get("persist.sys.usb.config");
let configFuncs = currentConfig.split(",");
let adbIndex = configFuncs.indexOf("adb");
if (enableAdb) {
// Add adb to the list of functions, if not already present
if (adbIndex < 0) {
configFuncs.push("adb");
}
} else {
// Remove adb from the list of functions, if present
if (adbIndex >= 0) {
configFuncs.splice(adbIndex, 1);
}
}
let newConfig = configFuncs.join(",");
if (newConfig != currentConfig) {
if (this.DEBUG) {
this.debug("updateState: currentConfig = " + currentConfig);
this.debug("updateState: newConfig = " + newConfig);
}
try {
libcutils.property_set("persist.sys.usb.config", newConfig);
} catch(e) {
dump("Error configuring adb: " + e);
}
}
if (useDisableAdbTimer) {
if (enableAdb && !usbFuncActive) {
this.startDisableAdbTimer();
} else {
this.stopDisableAdbTimer();
}
}
}
};
adbController.init();

View File

@ -46,7 +46,34 @@ function setupButtons() {
});
}
function checkDebuggerPort() {
// XXX: To be removed once bug 942756 lands.
// We are hacking 'unix-domain-socket' pref by setting a tcp port (number).
// DebuggerServer.openListener detects that it isn't a file path (string),
// and starts listening on the tcp port given here as command line argument.
if (!window.arguments) {
return;
}
// Get the command line arguments that were passed to the b2g client
let args = window.arguments[0].QueryInterface(Ci.nsICommandLine);
let dbgport;
try {
dbgport = args.handleFlagWithParam('start-debugger-server', false);
} catch(e) {}
if (dbgport) {
dump('Opening debugger server on ' + dbgport + '\n');
Services.prefs.setCharPref('devtools.debugger.unix-domain-socket', dbgport);
navigator.mozSettings.createLock().set(
{'debugger.remote-mode': 'adb-devtools'});
}
}
window.addEventListener('ContentStart', function() {
enableTouch();
setupButtons();
checkDebuggerPort();
});

View File

@ -15,10 +15,6 @@ XPCOMUtils.defineLazyGetter(this, 'DebuggerClient', function() {
return Cu.import('resource://gre/modules/devtools/dbg-client.jsm', {}).DebuggerClient;
});
XPCOMUtils.defineLazyGetter(this, 'DebuggerServer', function() {
return Cu.import('resource://gre/modules/devtools/dbg-server.jsm', {}).DebuggerServer;
});
XPCOMUtils.defineLazyGetter(this, 'WebConsoleUtils', function() {
return devtools.require('devtools/toolkit/webconsole/utils').Utils;
});
@ -62,7 +58,7 @@ let developerHUD = {
return;
if (!DebuggerServer.initialized) {
DebuggerServer.controller.start(null);
RemoteDebugger.start();
}
// We instantiate a local debugger connection so that watchers can use our

View File

@ -188,6 +188,292 @@ SettingsListener.observe('devtools.overlay', false, (value) => {
}
});
// =================== Debugger / ADB ====================
#ifdef MOZ_WIDGET_GONK
let AdbController = {
DEBUG: false,
locked: undefined,
remoteDebuggerEnabled: undefined,
lockEnabled: undefined,
disableAdbTimer: null,
disableAdbTimeoutHours: 12,
umsActive: false,
debug: function(str) {
dump("AdbController: " + str + "\n");
},
setLockscreenEnabled: function(value) {
this.lockEnabled = value;
if (this.DEBUG) {
this.debug("setLockscreenEnabled = " + this.lockEnabled);
}
this.updateState();
},
setLockscreenState: function(value) {
this.locked = value;
if (this.DEBUG) {
this.debug("setLockscreenState = " + this.locked);
}
this.updateState();
},
setRemoteDebuggerState: function(value) {
this.remoteDebuggerEnabled = value;
if (this.DEBUG) {
this.debug("setRemoteDebuggerState = " + this.remoteDebuggerEnabled);
}
this.updateState();
},
startDisableAdbTimer: function() {
if (this.disableAdbTimer) {
this.disableAdbTimer.cancel();
} else {
this.disableAdbTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
try {
this.disableAdbTimeoutHours =
Services.prefs.getIntPref("b2g.adb.timeout-hours");
} catch (e) {
// This happens if the pref doesn't exist, in which case
// disableAdbTimeoutHours will still be set to the default.
}
}
if (this.disableAdbTimeoutHours <= 0) {
if (this.DEBUG) {
this.debug("Timer to disable ADB not started due to zero timeout");
}
return;
}
if (this.DEBUG) {
this.debug("Starting timer to disable ADB in " +
this.disableAdbTimeoutHours + " hours");
}
let timeoutMilliseconds = this.disableAdbTimeoutHours * 60 * 60 * 1000;
this.disableAdbTimer.initWithCallback(this, timeoutMilliseconds,
Ci.nsITimer.TYPE_ONE_SHOT);
},
stopDisableAdbTimer: function() {
if (this.DEBUG) {
this.debug("Stopping timer to disable ADB");
}
if (this.disableAdbTimer) {
this.disableAdbTimer.cancel();
this.disableAdbTimer = null;
}
},
notify: function(aTimer) {
if (aTimer == this.disableAdbTimer) {
this.disableAdbTimer = null;
// The following dump will be the last thing that shows up in logcat,
// and will at least give the user a clue about why logcat was
// disconnected, if the user happens to be using logcat.
dump("AdbController: ADB timer expired - disabling ADB\n");
navigator.mozSettings.createLock().set(
{'devtools.debugger.remote-enabled': false});
}
},
updateState: function() {
this.umsActive = false;
this.storages = navigator.getDeviceStorages('sdcard');
this.updateStorageState(0);
},
updateStorageState: function(storageIndex) {
if (storageIndex >= this.storages.length) {
// We've iterated through all of the storage objects, now we can
// really do updateStateInternal.
this.updateStateInternal();
return;
}
let storage = this.storages[storageIndex];
if (this.DEBUG) {
this.debug("Checking availability of storage: '" +
storage.storageName);
}
let req = storage.available();
req.onsuccess = function(e) {
if (this.DEBUG) {
this.debug("Storage: '" + storage.storageName + "' is '" +
e.target.result);
}
if (e.target.result == 'shared') {
// We've found a storage area that's being shared with the PC.
// We can stop looking now.
this.umsActive = true;
this.updateStateInternal();
return;
}
this.updateStorageState(storageIndex + 1);
}.bind(this);
req.onerror = function(e) {
dump("AdbController: error querying storage availability for '" +
this.storages[storageIndex].storageName + "' (ignoring)\n");
this.updateStorageState(storageIndex + 1);
}.bind(this);
},
updateStateInternal: function() {
if (this.DEBUG) {
this.debug("updateStateInternal: called");
}
if (this.remoteDebuggerEnabled === undefined ||
this.lockEnabled === undefined ||
this.locked === undefined) {
// Part of initializing the settings database will cause the observers
// to trigger. We want to wait until both have been initialized before
// we start changing ther adb state. Without this then we can wind up
// toggling adb off and back on again (or on and back off again).
//
// For completeness, one scenario which toggles adb is using the unagi.
// The unagi has adb enabled by default (prior to b2g starting). If you
// have the phone lock disabled and remote debugging enabled, then we'll
// receive an unlock event and an rde event. However at the time we
// receive the unlock event we haven't yet received the rde event, so
// we turn adb off momentarily, which disconnects a logcat that might
// be running. Changing the defaults (in AdbController) just moves the
// problem to a different phone, which has adb disabled by default and
// we wind up turning on adb for a short period when we shouldn't.
//
// By waiting until both values are properly initialized, we avoid
// turning adb on or off accidentally.
if (this.DEBUG) {
this.debug("updateState: Waiting for all vars to be initialized");
}
return;
}
// Check if we have a remote debugging session going on. If so, we won't
// disable adb even if the screen is locked.
let isDebugging = RemoteDebugger.isDebugging;
if (this.DEBUG) {
this.debug("isDebugging=" + isDebugging);
}
// If USB Mass Storage, USB tethering, or a debug session is active,
// then we don't want to disable adb in an automatic fashion (i.e.
// when the screen locks or due to timeout).
let sysUsbConfig = libcutils.property_get("sys.usb.config");
let rndisActive = (sysUsbConfig.split(",").indexOf("rndis") >= 0);
let usbFuncActive = rndisActive || this.umsActive || isDebugging;
let enableAdb = this.remoteDebuggerEnabled &&
(!(this.lockEnabled && this.locked) || usbFuncActive);
let useDisableAdbTimer = true;
try {
if (Services.prefs.getBoolPref("marionette.defaultPrefs.enabled")) {
// Marionette is enabled. Marionette requires that adb be on (and also
// requires that remote debugging be off). The fact that marionette
// is enabled also implies that we're doing a non-production build, so
// we want adb enabled all of the time.
enableAdb = true;
useDisableAdbTimer = false;
}
} catch (e) {
// This means that the pref doesn't exist. Which is fine. We just leave
// enableAdb alone.
}
if (this.DEBUG) {
this.debug("updateState: enableAdb = " + enableAdb +
" remoteDebuggerEnabled = " + this.remoteDebuggerEnabled +
" lockEnabled = " + this.lockEnabled +
" locked = " + this.locked +
" usbFuncActive = " + usbFuncActive);
}
// Configure adb.
let currentConfig = libcutils.property_get("persist.sys.usb.config");
let configFuncs = currentConfig.split(",");
let adbIndex = configFuncs.indexOf("adb");
if (enableAdb) {
// Add adb to the list of functions, if not already present
if (adbIndex < 0) {
configFuncs.push("adb");
}
} else {
// Remove adb from the list of functions, if present
if (adbIndex >= 0) {
configFuncs.splice(adbIndex, 1);
}
}
let newConfig = configFuncs.join(",");
if (newConfig != currentConfig) {
if (this.DEBUG) {
this.debug("updateState: currentConfig = " + currentConfig);
this.debug("updateState: newConfig = " + newConfig);
}
try {
libcutils.property_set("persist.sys.usb.config", newConfig);
} catch(e) {
dump("Error configuring adb: " + e);
}
}
if (useDisableAdbTimer) {
if (enableAdb && !usbFuncActive) {
this.startDisableAdbTimer();
} else {
this.stopDisableAdbTimer();
}
}
}
};
SettingsListener.observe("lockscreen.locked", false,
AdbController.setLockscreenState.bind(AdbController));
SettingsListener.observe("lockscreen.enabled", false,
AdbController.setLockscreenEnabled.bind(AdbController));
#endif
// Keep the old setting to not break people that won't have updated
// gaia and gecko.
SettingsListener.observe('devtools.debugger.remote-enabled', false, function(value) {
Services.prefs.setBoolPref('devtools.debugger.remote-enabled', value);
// This preference is consulted during startup
Services.prefs.savePrefFile(null);
try {
value ? RemoteDebugger.start() : RemoteDebugger.stop();
} catch(e) {
dump("Error while initializing devtools: " + e + "\n" + e.stack + "\n");
}
#ifdef MOZ_WIDGET_GONK
AdbController.setRemoteDebuggerState(value);
#endif
});
SettingsListener.observe('debugger.remote-mode', false, function(value) {
if (['disabled', 'adb-only', 'adb-devtools'].indexOf(value) == -1) {
dump('Illegal value for debugger.remote-mode: ' + value + '\n');
return;
}
Services.prefs.setBoolPref('devtools.debugger.remote-enabled',
value == 'adb-devtools');
// This preference is consulted during startup
Services.prefs.savePrefFile(null);
try {
(value == 'adb-devtools') ? RemoteDebugger.start()
: RemoteDebugger.stop();
} catch(e) {
dump("Error while initializing devtools: " + e + "\n" + e.stack + "\n");
}
#ifdef MOZ_WIDGET_GONK
AdbController.setRemoteDebuggerState(value != 'disabled');
#endif
});
// =================== Device Storage ====================
SettingsListener.observe('device.storage.writable.name', 'sdcard', function(value) {
if (Services.prefs.getPrefType('device.storage.writable.name') != Ci.nsIPrefBranch.PREF_STRING) {

View File

@ -32,9 +32,6 @@
<!-- this script handles the "runapp" argument for desktop builds -->
<script type="application/javascript;version=1.8"
src="chrome://b2g/content/runapp.js"> </script>
#else
<script type="application/javascript;version=1.8"
src="chrome://b2g/content/adbController.js"> </script>
#endif
</head>
<body id="container">

View File

@ -52,6 +52,11 @@ XPCOMUtils.defineLazyServiceGetter(Services, 'fm',
'@mozilla.org/focus-manager;1',
'nsIFocusManager');
XPCOMUtils.defineLazyGetter(this, 'DebuggerServer', function() {
Cu.import('resource://gre/modules/devtools/dbg-server.jsm');
return DebuggerServer;
});
XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
return Cc["@mozilla.org/parentprocessmessagemanager;1"]
.getService(Ci.nsIMessageListenerManager);
@ -762,6 +767,9 @@ var CustomEventManager = {
case 'system-message-listener-ready':
Services.obs.notifyObservers(null, 'system-message-listener-ready', null);
break;
case 'remote-debugger-prompt':
RemoteDebugger.handleEvent(detail);
break;
case 'captive-portal-login-cancel':
CaptivePortalLoginHelper.handleEvent(detail);
break;
@ -1069,6 +1077,131 @@ let IndexedDBPromptHelper = {
}
}
let RemoteDebugger = {
_promptDone: false,
_promptAnswer: false,
_running: false,
prompt: function debugger_prompt() {
this._promptDone = false;
shell.sendChromeEvent({
"type": "remote-debugger-prompt"
});
while(!this._promptDone) {
Services.tm.currentThread.processNextEvent(true);
}
return this._promptAnswer;
},
handleEvent: function debugger_handleEvent(detail) {
this._promptAnswer = detail.value;
this._promptDone = true;
},
get isDebugging() {
if (!this._running) {
return false;
}
return DebuggerServer._connections &&
Object.keys(DebuggerServer._connections).length > 0;
},
// Start the debugger server.
start: function debugger_start() {
if (this._running) {
return;
}
if (!DebuggerServer.initialized) {
// Ask for remote connections.
DebuggerServer.init(this.prompt.bind(this));
// /!\ Be careful when adding a new actor, especially global actors.
// Any new global actor will be exposed and returned by the root actor.
// Add Firefox-specific actors, but prevent tab actors to be loaded in
// the parent process, unless we enable certified apps debugging.
let restrictPrivileges = Services.prefs.getBoolPref("devtools.debugger.forbid-certified-apps");
DebuggerServer.addBrowserActors("navigator:browser", restrictPrivileges);
/**
* Construct a root actor appropriate for use in a server running in B2G.
* The returned root actor respects the factories registered with
* DebuggerServer.addGlobalActor only if certified apps debugging is on,
* otherwise we used an explicit limited list of global actors
*
* * @param connection DebuggerServerConnection
* The conection to the client.
*/
DebuggerServer.createRootActor = function createRootActor(connection)
{
let { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
let parameters = {
// We do not expose browser tab actors yet,
// but we still have to define tabList.getList(),
// otherwise, client won't be able to fetch global actors
// from listTabs request!
tabList: {
getList: function() {
return promise.resolve([]);
}
},
// Use an explicit global actor list to prevent exposing
// unexpected actors
globalActorFactories: restrictPrivileges ? {
webappsActor: DebuggerServer.globalActorFactories.webappsActor,
deviceActor: DebuggerServer.globalActorFactories.deviceActor,
} : DebuggerServer.globalActorFactories
};
let root = new DebuggerServer.RootActor(connection, parameters);
root.applicationType = "operating-system";
return root;
};
#ifdef MOZ_WIDGET_GONK
DebuggerServer.on("connectionchange", function() {
AdbController.updateState();
});
#endif
}
let path = Services.prefs.getCharPref("devtools.debugger.unix-domain-socket") ||
"/data/local/debugger-socket";
try {
DebuggerServer.openListener(path);
// Temporary event, until bug 942756 lands and offers a way to know
// when the server is up and running.
Services.obs.notifyObservers(null, 'debugger-server-started', null);
this._running = true;
} catch (e) {
dump('Unable to start debugger server: ' + e + '\n');
}
},
stop: function debugger_stop() {
if (!this._running) {
return;
}
if (!DebuggerServer.initialized) {
// Can this really happen if we are running?
this._running = false;
return;
}
try {
DebuggerServer.closeListener();
} catch (e) {
dump('Unable to stop debugger server: ' + e + '\n');
}
this._running = false;
}
}
let KeyboardHelper = {
handleEvent: function keyboard_handleEvent(detail) {
Keyboard.setLayouts(detail.layouts);

View File

@ -25,9 +25,6 @@ chrome.jar:
content/screen.js (content/screen.js)
content/runapp.js (content/runapp.js)
#endif
#ifdef MOZ_WIDGET_GONK
content/adbController.js (content/adbController.js)
#endif
* content/content.css (content/content.css)
content/touchcontrols.css (content/touchcontrols.css)

View File

@ -87,7 +87,3 @@ component {c83c02c0-5d43-4e3e-987f-9173b313e880} SimulatorScreen.js
contract @mozilla.org/simulator-screen;1 {c83c02c0-5d43-4e3e-987f-9173b313e880}
category profile-after-change SimulatorScreen @mozilla.org/simulator-screen;1
#endif
# DebuggerServerController.js
component {9390f6ac-7914-46c6-b9d0-ccc7db550d8c} DebuggerServerController.js
contract @mozilla.org/devtools/DebuggerServerController;1 {9390f6ac-7914-46c6-b9d0-ccc7db550d8c}

View File

@ -1,195 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this,
"Settings",
"@mozilla.org/settingsService;1", "nsISettingsService");
XPCOMUtils.defineLazyModuleGetter(this,
"SystemAppProxy",
"resource://gre/modules/SystemAppProxy.jsm");
function DebuggerServerController() {
}
DebuggerServerController.prototype = {
classID: Components.ID("{9390f6ac-7914-46c6-b9d0-ccc7db550d8c}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDebuggerServerController, Ci.nsIObserver]),
init: function init(debuggerServer) {
this.debugger = debuggerServer;
Services.obs.addObserver(this, "mozsettings-changed", false);
Services.obs.addObserver(this, "debugger-server-started", false);
Services.obs.addObserver(this, "debugger-server-stopped", false);
Services.obs.addObserver(this, "xpcom-shutdown", false);
},
uninit: function uninit() {
this.debugger = null;
Services.obs.removeObserver(this, "mozsettings-changed");
Services.obs.removeObserver(this, "debugger-server-started");
Services.obs.removeObserver(this, "debugger-server-stopped");
Services.obs.removeObserver(this, "xpcom-shutdown");
},
// nsIObserver
observe: function observe(subject, topic, data) {
switch (topic) {
case "xpcom-shutdown":
this.uninit();
break;
case "debugger-server-started":
this._onDebuggerStarted(data);
break;
case "debugger-server-stopped":
this._onDebuggerStopped();
break;
case "mozsettings-changed":
let {key, value} = JSON.parse(data);
switch(key) {
case "debugger.remote-mode":
if (["disabled", "adb-only", "adb-devtools"].indexOf(value) == -1) {
dump("Illegal value for debugger.remote-mode: " + value + "\n");
return;
}
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", value == "adb-devtools");
Services.prefs.savePrefFile(null);
if (value != "adb-devtools") {
// The *pref* "devtools.debugger.remote-enabled" has been set to false (setBoolPref)
// above. In theory, it's supposed to automatically stop the debugger, but maybe the
// debugger has been started from the command line, so the value was already false,
// so the observer is not called because the value didn't change. We need to stop
// the debugger manually:
this.stop();
}
}
}
},
// nsIDebuggerController
start: function(portOrPath) {
if (!this.debugger.initialized) {
// Ask for remote connections.
this.debugger.init(Prompt.prompt.bind(Prompt));
// /!\ Be careful when adding a new actor, especially global actors.
// Any new global actor will be exposed and returned by the root actor.
// Add Firefox-specific actors, but prevent tab actors to be loaded in
// the parent process, unless we enable certified apps debugging.
let restrictPrivileges = Services.prefs.getBoolPref("devtools.debugger.forbid-certified-apps");
this.debugger.addBrowserActors("navigator:browser", restrictPrivileges);
/**
* Construct a root actor appropriate for use in a server running in B2G.
* The returned root actor respects the factories registered with
* DebuggerServer.addGlobalActor only if certified apps debugging is on,
* otherwise we used an explicit limited list of global actors
*
* * @param connection DebuggerServerConnection
* The conection to the client.
*/
let debuggerServer = this.debugger;
debuggerServer.createRootActor = function createRootActor(connection)
{
let { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
let parameters = {
// We do not expose browser tab actors yet,
// but we still have to define tabList.getList(),
// otherwise, client won't be able to fetch global actors
// from listTabs request!
tabList: {
getList: function() {
return promise.resolve([]);
}
},
// Use an explicit global actor list to prevent exposing
// unexpected actors
globalActorFactories: restrictPrivileges ? {
webappsActor: debuggerServer.globalActorFactories.webappsActor,
deviceActor: debuggerServer.globalActorFactories.deviceActor,
} : debuggerServer.globalActorFactories
};
let root = new debuggerServer.RootActor(connection, parameters);
root.applicationType = "operating-system";
return root;
};
}
if (portOrPath) {
try {
this.debugger.openListener(portOrPath);
} catch (e) {
dump("Unable to start debugger server (" + portOrPath + "): " + e + "\n");
}
}
},
stop: function() {
this.debugger.destroy();
},
_onDebuggerStarted: function(portOrPath) {
dump("Devtools debugger server started: " + portOrPath + "\n");
Settings.createLock().set("debugger.remote-mode", "adb-devtools", null);
},
_onDebuggerStopped: function() {
dump("Devtools debugger server stopped\n");
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DebuggerServerController]);
// =================== Prompt ====================
let Prompt = {
_promptDone: false,
_promptAnswer: false,
_listenerAttached: false,
prompt: function () {
if (!this._listenerAttached) {
SystemAppProxy.addEventListener("mozContentEvent", this, false, true);
this._listenerAttached = true;
}
this._promptDone = false;
SystemAppProxy._sendCustomEvent("mozChromeEvent", {
"type": "remote-debugger-prompt"
});
while(!this._promptDone) {
Services.tm.currentThread.processNextEvent(true);
}
return this._promptAnswer;
},
// Content events listener
handleEvent: function (event) {
if (event.detail.type == "remote-debugger-prompt") {
this._promptAnswer = event.detail.value;
this._promptDone = true;
}
}
}

View File

@ -12,7 +12,6 @@ EXTRA_COMPONENTS += [
'B2GAboutRedirector.js',
'ContentHandler.js',
'ContentPermissionPrompt.js',
'DebuggerServerController.js',
'FilePicker.js',
'HelperAppDialog.js',
'MailtoProtocolHandler.js',

View File

@ -434,11 +434,6 @@
@BINPATH@/components/nsBlocklistService.js
#endif
; DevTools
@BINPATH@/components/DevToolsComponents.manifest
@BINPATH@/components/DevToolsAppStartup.js
@BINPATH@/components/DebuggerServerController.js
#ifdef MOZ_UPDATER
@BINPATH@/components/nsUpdateService.manifest
@BINPATH@/components/nsUpdateService.js

View File

@ -1266,7 +1266,6 @@ pref("devtools.debugger.chrome-debugging-host", "localhost");
pref("devtools.debugger.chrome-debugging-port", 6080);
pref("devtools.debugger.remote-host", "localhost");
pref("devtools.debugger.remote-timeout", 20000);
pref("devtools.debugger.remote-enabled-pref-migrated", false);
pref("devtools.debugger.pause-on-exceptions", false);
pref("devtools.debugger.ignore-caught-exceptions", true);
pref("devtools.debugger.source-maps-enabled", true);

View File

@ -105,7 +105,7 @@
<command id="Tools:Eyedropper" oncommand="openEyedropper();"/>
<command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
<command id="Tools:ErrorConsole" oncommand="toJavaScriptConsole()" disabled="true" hidden="true"/>
<command id="Tools:DevToolsConnect" oncommand="gDevToolsBrowser.openConnectScreen(gBrowser)"/>
<command id="Tools:DevToolsConnect" oncommand="gDevToolsBrowser.openConnectScreen(gBrowser)" disabled="true" hidden="true"/>
<command id="Tools:Sanitize"
oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
<command id="Tools:PrivateBrowsing"

View File

@ -1,123 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
const { interfaces: Ci, utils: Cu, results: Cr } = Components;
const gPrefRemoteEnabled = "devtools.debugger.remote-enabled";
const gPrefMigrated = "devtools.debugger.remote-enabled-pref-migrated";
const gPrefShowNotifications = "devtools.debugger.show-server-notifications";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this,
"Alerts",
"@mozilla.org/alerts-service;1", "nsIAlertsService");
XPCOMUtils.defineLazyGetter(this,
"l10n",
() => Services.strings.createBundle("chrome://global/locale/devtools/debugger.properties"));
function DebuggerServerController() {
}
DebuggerServerController.prototype = {
classID: Components.ID("{f6e8e269-ae4a-4c4a-bf80-fb4164fb072d}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDebuggerServerController, Ci.nsIObserver]),
init: function(debuggerServer) {
this.debugger = debuggerServer;
// The remote-enabled pref used to mean that Firefox was allowed
// to connect to a debugger server. In other products (b2g, thunderbird,
// fennec, metro and webrt) this pref had a different meaning: it runs a
// debugger server. We want Firefox Desktop to follow the same rule.
//
// We don't want to surprise users with this new behavior. So we reset
// the remote-enabled pref once.
if (!Services.prefs.getBoolPref(gPrefMigrated)) {
Services.prefs.clearUserPref(gPrefRemoteEnabled);
Services.prefs.setBoolPref(gPrefMigrated, true);
}
Services.obs.addObserver(this, "debugger-server-started", false);
Services.obs.addObserver(this, "debugger-server-stopped", false);
Services.obs.addObserver(this, "xpcom-shutdown", false);
},
uninit: function() {
this.debugger = null;
Services.obs.removeObserver(this, "debugger-server-started");
Services.obs.removeObserver(this, "debugger-server-stopped");
Services.obs.removeObserver(this, "xpcom-shutdown");
},
start: function(pathOrPort) {
if (!this.debugger.initialized) {
this.debugger.init();
this.debugger.addBrowserActors();
}
if (!pathOrPort) {
// If the "devtools.debugger.unix-domain-socket" pref is set, we use a unix socket.
// If not, we use a regular TCP socket.
try {
pathOrPort = Services.prefs.getCharPref("devtools.debugger.unix-domain-socket");
} catch (e) {
pathOrPort = Services.prefs.getIntPref("devtools.debugger.remote-port");
}
}
this._showNotifications = Services.prefs.getBoolPref(gPrefShowNotifications);
try {
this.debugger.openListener(pathOrPort);
} catch (e if e.result != Cr.NS_ERROR_NOT_AVAILABLE) {
dump("Unable to start debugger server (" + pathOrPort + "): " + e + "\n");
}
},
stop: function() {
this.debugger.closeListener(true);
},
// nsIObserver
observe: function (subject, topic, data) {
if (topic == "xpcom-shutdown")
this.uninit();
if (topic == "debugger-server-started")
this._onDebuggerStarted(data);
if (topic == "debugger-server-stopped")
this._onDebuggerStopped();
},
_onDebuggerStarted: function(portOrPath) {
if (!this._showNotifications)
return;
let title = l10n.GetStringFromName("debuggerStartedAlert.title");
let port = Number(portOrPath);
let detail;
if (port) {
detail = l10n.formatStringFromName("debuggerStartedAlert.detailPort", [portOrPath], 1);
} else {
detail = l10n.formatStringFromName("debuggerStartedAlert.detailPath", [portOrPath], 1);
}
Alerts.showAlertNotification(null, title, detail, false, "", function(){});
},
_onDebuggerStopped: function() {
if (!this._showNotifications)
return;
let title = l10n.GetStringFromName("debuggerStopped.title");
Alerts.showAlertNotification(null, title, null, false, "", function(){});
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DebuggerServerController]);

View File

@ -1,7 +0,0 @@
# CommandLineHandler.js
component {9e9a9283-0ce9-4e4a-8f1c-ba129a032c32} CommandLineHandler.js
contract @mozilla.org/toolkit/console-clh;1 {9e9a9283-0ce9-4e4a-8f1c-ba129a032c32}
# DebuggerServerController.js
component {f6e8e269-ae4a-4c4a-bf80-fb4164fb072d} DebuggerServerController.js
contract @mozilla.org/devtools/DebuggerServerController;1 {f6e8e269-ae4a-4c4a-bf80-fb4164fb072d}

View File

@ -1,11 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXTRA_COMPONENTS += [
'CommandLineHandler.js',
'DebuggerServerController.js',
'DevToolsComponents.manifest',
]

View File

@ -12,9 +12,6 @@ let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
let gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
Services.prefs.setBoolPref("devtools.debugger.log", false);
// Disable notifications (to avoid "unknown window" errors)
Services.prefs.setBoolPref("devtools.debugger.show-server-notifications", false);
let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
let { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
@ -42,7 +39,6 @@ waitForExplicitFinish();
registerCleanupFunction(function() {
info("finish() was called, cleaning up...");
Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging);
Services.prefs.clearUserPref("devtools.debugger.show-server-notifications");
// Properly shut down the server to avoid memory leaks.
DebuggerServer.destroy();

View File

@ -4,6 +4,7 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const kDebuggerPrefs = [
"devtools.debugger.remote-enabled",
"devtools.debugger.chrome-enabled",
"devtools.chrome.enabled"
];

View File

@ -0,0 +1,2 @@
component {9e9a9283-0ce9-4e4a-8f1c-ba129a032c32} devtools-clhandler.js
contract @mozilla.org/toolkit/console-clh;1 {9e9a9283-0ce9-4e4a-8f1c-ba129a032c32}

View File

@ -127,7 +127,13 @@ BrowserToolboxProcess.prototype = {
this.debuggerServer.on("connectionchange", this.emit.bind(this));
}
this.debuggerServer.controller.start(Prefs.chromeDebuggingPort);
if (!this.debuggerServer.initialized) {
this.debuggerServer.init();
this.debuggerServer.addBrowserActors();
dumpn("initialized and added the browser actors for the DebuggerServer.");
}
this.debuggerServer.openListener(Prefs.chromeDebuggingPort);
dumpn("Finished initializing the chrome toolbox server.");
dumpn("Started listening on port: " + Prefs.chromeDebuggingPort);

View File

@ -439,13 +439,18 @@ let gDevToolsBrowser = {
toggleCmd("Tools:DevAppMgr", appMgrEnabled);
// Enable Browser Toolbox?
let chromeEnabled = Services.prefs.getBoolPref("devtools.chrome.enabled") &&
let chromeEnabled = Services.prefs.getBoolPref("devtools.chrome.enabled");
let devtoolsRemoteEnabled = Services.prefs.getBoolPref("devtools.debugger.remote-enabled");
let remoteEnabled = chromeEnabled && devtoolsRemoteEnabled &&
Services.prefs.getBoolPref("devtools.debugger.chrome-enabled");
toggleCmd("Tools:BrowserToolbox", chromeEnabled);
toggleCmd("Tools:BrowserToolbox", remoteEnabled);
// Enable Error Console?
let consoleEnabled = Services.prefs.getBoolPref("devtools.errorconsole.enabled");
toggleCmd("Tools:ErrorConsole", consoleEnabled);
// Enable DevTools connection screen, if the preference allows this.
toggleCmd("Tools:DevToolsConnect", devtoolsRemoteEnabled);
},
observe: function(subject, topic, prefName) {

View File

@ -6,9 +6,9 @@
let gItemsToTest = {
"menu_devToolbar": "devtools.toolbar.enabled",
"menu_devAppMgr": "devtools.appmanager.enabled",
"menu_browserToolbox": ["devtools.chrome.enabled", "devtools.debugger.chrome-enabled"],
"menu_browserToolbox": ["devtools.chrome.enabled", "devtools.debugger.remote-enabled", "devtools.debugger.chrome-enabled"],
"javascriptConsole": "devtools.errorconsole.enabled",
"menu_devtools_connect": [],
"menu_devtools_connect": "devtools.debugger.remote-enabled",
};
function expectedAttributeValueFromPrefs(prefs) {

View File

@ -13,10 +13,6 @@ let promise = tempScope.Promise;
let {devtools} = Components.utils.import("resource://gre/modules/devtools/Loader.jsm", {});
let TargetFactory = devtools.TargetFactory;
let {Services} = Components.utils.import("resource://gre/modules/Services.jsm", {});
// Disable notifications (to avoid "unknown window" errors)
Services.prefs.setBoolPref("devtools.debugger.show-server-notifications", false);
gDevTools.testing = true;
SimpleTest.registerCleanupFunction(() => {
gDevTools.testing = false;
@ -58,7 +54,6 @@ registerCleanupFunction(function tearDown() {
while (gBrowser.tabs.length > 1) {
gBrowser.removeCurrentTab();
}
Services.prefs.clearUserPref("devtools.debugger.show-server-notifications");
});
function synthesizeKeyFromKeyTag(aKeyId, document) {

View File

@ -97,7 +97,7 @@
</hbox>
<hbox class="hidden-labels-box">
<checkbox label="&options.enableRemote.label3;"
tooltiptext="&options.enableRemote.tooltip2;"
tooltiptext="&options.enableRemote.tooltip;"
data-pref="devtools.debugger.remote-enabled"/>
</hbox>
<label class="options-citation-label"

View File

@ -8,7 +8,6 @@ DIRS += [
'app-manager',
'canvasdebugger',
'commandline',
'components',
'debugger',
'eyedropper',
'fontinspector',
@ -30,4 +29,9 @@ DIRS += [
'webconsole',
]
EXTRA_COMPONENTS += [
'devtools-clhandler.js',
'devtools-clhandler.manifest',
]
JAR_MANIFESTS += ['jar.mn']

View File

@ -17,6 +17,7 @@ let ProfilerController = temp.ProfilerController;
function test() {
waitForExplicitFinish();
Services.prefs.setBoolPref(REMOTE_ENABLED, true);
loadTab(URL, function onTabLoad(tab, browser) {
DebuggerServer.init(function () true);

View File

@ -4,8 +4,8 @@
let temp = {};
const PROFILER_ENABLED = "devtools.profiler.enabled";
const REMOTE_ENABLED = "devtools.debugger.remote-enabled";
const SHOW_PLATFORM_DATA = "devtools.profiler.ui.show-platform-data";
const SHOW_NOTIFICATIONS = "devtools.debugger.show-server-notifications";
const PROFILE_IDLE = 0;
const PROFILE_RUNNING = 1;
const PROFILE_COMPLETED = 2;
@ -31,8 +31,8 @@ SimpleTest.registerCleanupFunction(() => {
registerCleanupFunction(function () {
helpers = null;
Services.prefs.clearUserPref(PROFILER_ENABLED);
Services.prefs.clearUserPref(REMOTE_ENABLED);
Services.prefs.clearUserPref(SHOW_PLATFORM_DATA);
Services.prefs.clearUserPref(SHOW_NOTIFICATIONS);
DebuggerServer.destroy();
// These tests use a lot of memory due to GL contexts, so force a GC to help

View File

@ -366,6 +366,8 @@
@BINPATH@/browser/components/DownloadsStartup.js
@BINPATH@/browser/components/DownloadsUI.js
@BINPATH@/browser/components/BrowserPlaces.manifest
@BINPATH@/browser/components/devtools-clhandler.manifest
@BINPATH@/browser/components/devtools-clhandler.js
@BINPATH@/browser/components/Experiments.manifest
@BINPATH@/browser/components/ExperimentsService.js
@BINPATH@/components/Downloads.manifest
@ -573,20 +575,11 @@
@BINPATH@/components/MozKeyboard.js
@BINPATH@/components/InputMethod.manifest
#ifdef MOZ_DEBUG
@BINPATH@/components/TestInterfaceJS.js
@BINPATH@/components/TestInterfaceJS.manifest
#endif
; DevTools browser
@BINPATH@/browser/components/DevToolsComponents.manifest
@BINPATH@/browser/components/DebuggerServerController.js
@BINPATH@/browser/components/CommandLineHandler.js
; DevTools toolkit
@BINPATH@/components/DevToolsComponents.manifest
@BINPATH@/components/DevToolsAppStartup.js
; Modules
@BINPATH@/browser/modules/*
@BINPATH@/modules/*

View File

@ -1351,14 +1351,18 @@ listenManual2=%1$S can allow remote debugging over a TCP/IP connection. For secu
# function of 'port' parameter to the 'listen' command.
listenPortDesc=The TCP port to listen on
# LOCALIZATION NOTE (listenFailed) Text of a failure message during the
# LOCALIZATION NOTE (listenDisabledOutput) Text of a message output during the
# execution of the 'listen' command.
listenFailed=Listen failed.
listenDisabledOutput=Listen is disabled by the devtools.debugger.remote-enabled preference
# LOCALIZATION NOTE (listenInitOutput) Text of a message output during the
# execution of the 'listen' command. %1$S is a port number
listenInitOutput=Listening on port %1$S
# LOCALIZATION NOTE (listenNoInitOutput) Text of a message output during the
# execution of the 'listen' command.
listenNoInitOutput=DebuggerServer not initialized
# LOCALIZATION NOTE (mediaDesc, mediaEmulateDesc, mediaEmulateManual,
# mediaEmulateType, mediaResetDesc, mediaResetManual) These strings describe
# the 'media' commands and all available parameters.

View File

@ -67,7 +67,7 @@
- checkbox that toggles remote debugging, i.e. devtools.debugger.remote-enabled
- boolean preference in about:config, in the options panel. -->
<!ENTITY options.enableRemote.label3 "Enable remote debugging">
<!ENTITY options.enableRemote.tooltip2 "Turning this option on will start a debugger server and allow other instances of Firefox to debug this instance">
<!ENTITY options.enableRemote.tooltip "Turning this option on will allow the developer tools to debug remote Firefox instance like Firefox OS">
<!-- LOCALIZATION NOTE (options.disableJavaScript.label,
- options.disableJavaScript.tooltip): This is the options panel label and

View File

@ -11,6 +11,10 @@ Cu.import("resource://gre/modules/WindowsPrefSync.jsm");
* Constants
*/
// Devtools Messages
const debugServerStateChanged = "devtools.debugger.remote-enabled";
const debugServerPortChanged = "devtools.debugger.remote-port";
// delay when showing the tab bar briefly after a new foreground tab opens
const kForegroundTabAnimationDelay = 1000;
// delay when showing the tab bar after opening a new background tab opens
@ -77,6 +81,12 @@ var BrowserUI = {
ready: false, // used for tests to determine when delayed initialization is done
init: function() {
// start the debugger now so we can use it on the startup code as well
if (Services.prefs.getBoolPref(debugServerStateChanged)) {
this.runDebugServer();
}
Services.prefs.addObserver(debugServerStateChanged, this, false);
Services.prefs.addObserver(debugServerPortChanged, this, false);
Services.prefs.addObserver("app.crashreporter.autosubmit", this, false);
Services.prefs.addObserver("metro.private_browsing.enabled", this, false);
this.updatePrivateBrowsingUI();
@ -196,6 +206,8 @@ var BrowserUI = {
messageManager.removeMessageListener("Browser:MozApplicationManifest", OfflineApps);
Services.prefs.removeObserver(debugServerStateChanged, this);
Services.prefs.removeObserver(debugServerPortChanged, this);
Services.prefs.removeObserver("app.crashreporter.autosubmit", this);
Services.prefs.removeObserver("metro.private_browsing.enabled", this);
@ -209,6 +221,37 @@ var BrowserUI = {
if (WindowsPrefSync) {
WindowsPrefSync.uninit();
}
this.stopDebugServer();
},
/************************************
* Devtools Debugger
*/
runDebugServer: function runDebugServer(aPort) {
let port = aPort || Services.prefs.getIntPref(debugServerPortChanged);
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
DebuggerServer.addActors('chrome://browser/content/dbg-metro-actors.js');
}
DebuggerServer.openListener(port);
},
stopDebugServer: function stopDebugServer() {
if (DebuggerServer.initialized) {
DebuggerServer.destroy();
}
},
// If the server is not on, port changes have nothing to effect. The new value
// will be picked up if the server is started.
// To be consistent with desktop fx, if the port is changed while the server
// is running, restart server.
changeDebugPort:function changeDebugPort(aPort) {
if (DebuggerServer.initialized) {
this.stopDebugServer();
this.runDebugServer(aPort);
}
},
/*********************************
@ -584,6 +627,16 @@ var BrowserUI = {
case "browser.cache.disk_cache_ssl":
this._sslDiskCacheEnabled = Services.prefs.getBoolPref(aData);
break;
case debugServerStateChanged:
if (Services.prefs.getBoolPref(aData)) {
this.runDebugServer();
} else {
this.stopDebugServer();
}
break;
case debugServerPortChanged:
this.changeDebugPort(Services.prefs.getIntPref(aData));
break;
case "app.crashreporter.autosubmit":
#ifdef MOZ_CRASHREPORTER
CrashReporter.submitReports = Services.prefs.getBoolPref(aData);

View File

@ -1,99 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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";
const { interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this,
"Alerts",
"@mozilla.org/alerts-service;1", "nsIAlertsService");
XPCOMUtils.defineLazyGetter(this,
"l10n",
() => Services.strings.createBundle("chrome://global/locale/devtools/debugger.properties"));
function DebuggerServerController() {
}
DebuggerServerController.prototype = {
classID: Components.ID("{0849238d-6fb7-4bc4-87b7-4019bb53e01b}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDebuggerServerController, Ci.nsIObserver]),
init: function(debuggerServer) {
this.debugger = debuggerServer;
Services.obs.addObserver(this, "debugger-server-started", false);
Services.obs.addObserver(this, "debugger-server-stopped", false);
Services.obs.addObserver(this, "xpcom-shutdown", false);
},
uninit: function() {
this.debugger = null;
Services.obs.removeObserver(this, "debugger-server-started");
Services.obs.removeObserver(this, "debugger-server-stopped");
Services.obs.removeObserver(this, "xpcom-shutdown");
},
start: function(pathOrPort) {
if (!this.debugger.initialized) {
this.debugger.init();
this.debugger.addBrowserActors();
this.debugger.addActors("chrome://browser/content/dbg-metro-actors.js");
}
if (!pathOrPort) {
// If the "devtools.debugger.unix-domain-socket" pref is set, we use a unix socket.
// If not, we use a regular TCP socket.
try {
pathOrPort = Services.prefs.getCharPref("devtools.debugger.unix-domain-socket");
} catch (e) {
pathOrPort = Services.prefs.getIntPref("devtools.debugger.remote-port");
}
}
try {
this.debugger.openListener(pathOrPort);
} catch (e if e.result != Cr.NS_ERROR_NOT_AVAILABLE) {
dump("Unable to start debugger server (" + pathOrPort + "): " + e + "\n");
}
},
stop: function() {
this.debugger.closeListener(true);
},
// nsIObserver
observe: function (subject, topic, data) {
if (topic == "xpcom-shutdown")
this.uninit();
if (topic == "debugger-server-started")
this._onDebuggerStarted(data);
if (topic == "debugger-server-stopped")
this._onDebuggerStopped();
},
_onDebuggerStarted: function(portOrPath) {
let title = l10n.GetStringFromName("debuggerStartedAlert.title");
let port = Number(portOrPath);
let detail;
if (port) {
detail = l10n.formatStringFromName("debuggerStartedAlert.detailPort", [portOrPath], 1);
} else {
detail = l10n.formatStringFromName("debuggerStartedAlert.detailPath", [portOrPath], 1);
}
Alerts.showAlertNotification(null, title, detail, false, "", function(){});
},
_onDebuggerStopped: function() {
let title = l10n.GetStringFromName("debuggerStopped.title");
Alerts.showAlertNotification(null, title, null, false, "", function(){});
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DebuggerServerController]);

View File

@ -81,6 +81,3 @@ contract @mozilla.org/safebrowsing/application;1 {aadaed90-6c03-42d0-924a-fc6119
category app-startup SafeBrowsing service,@mozilla.org/safebrowsing/application;1
#endif
# DebuggerServerController.js
component {0849238d-6fb7-4bc4-87b7-4019bb53e01b} DebuggerServerController.js
contract @mozilla.org/devtools/DebuggerServerController;1 {0849238d-6fb7-4bc4-87b7-4019bb53e01b}

View File

@ -16,7 +16,6 @@ EXTRA_COMPONENTS += [
'BrowserStartup.js',
'ContentDispatchChooser.js',
'ContentPermissionPrompt.js',
'DebuggerServerController.js',
'DirectoryProvider.js',
'DownloadManagerUI.js',
'HelperAppDialog.js',

View File

@ -31,6 +31,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
XPCOMUtils.defineLazyModuleGetter(this, "sendMessageToJava",
"resource://gre/modules/Messaging.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "DebuggerServer",
"resource://gre/modules/devtools/dbg-server.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UserAgentOverrides",
"resource://gre/modules/UserAgentOverrides.jsm");
@ -372,6 +375,7 @@ var BrowserApp = {
#else
WebappsUI.init();
#endif
RemoteDebugger.init();
Reader.init();
UserAgentOverrides.init();
DesktopUserAgent.init();
@ -750,6 +754,7 @@ var BrowserApp = {
#ifndef MOZ_ANDROID_SYNTHAPKS
WebappsUI.uninit();
#endif
RemoteDebugger.uninit();
Reader.uninit();
UserAgentOverrides.uninit();
DesktopUserAgent.uninit();
@ -7316,6 +7321,117 @@ var WebappsUI = {
}
#endif
var RemoteDebugger = {
init: function rd_init() {
Services.prefs.addObserver("devtools.debugger.", this, false);
if (this._isEnabled())
this._start();
},
observe: function rd_observe(aSubject, aTopic, aData) {
if (aTopic != "nsPref:changed")
return;
switch (aData) {
case "devtools.debugger.remote-enabled":
if (this._isEnabled())
this._start();
else
this._stop();
break;
case "devtools.debugger.remote-port":
if (this._isEnabled())
this._restart();
break;
}
},
uninit: function rd_uninit() {
Services.prefs.removeObserver("devtools.debugger.", this);
this._stop();
},
_getPort: function _rd_getPort() {
return Services.prefs.getIntPref("devtools.debugger.remote-port");
},
_isEnabled: function rd_isEnabled() {
return Services.prefs.getBoolPref("devtools.debugger.remote-enabled");
},
/**
* Prompt the user to accept or decline the incoming connection.
* This is passed to DebuggerService.init as a callback.
*
* @return true if the connection should be permitted, false otherwise
*/
_showConnectionPrompt: function rd_showConnectionPrompt() {
let title = Strings.browser.GetStringFromName("remoteIncomingPromptTitle");
let msg = Strings.browser.GetStringFromName("remoteIncomingPromptMessage");
let disable = Strings.browser.GetStringFromName("remoteIncomingPromptDisable");
let cancel = Strings.browser.GetStringFromName("remoteIncomingPromptCancel");
let agree = Strings.browser.GetStringFromName("remoteIncomingPromptAccept");
// Make prompt. Note: button order is in reverse.
let prompt = new Prompt({
window: null,
hint: "remotedebug",
title: title,
message: msg,
buttons: [ agree, cancel, disable ],
priority: 1
});
// The debugger server expects a synchronous response, so spin on result since Prompt is async.
let result = null;
prompt.show(function(data) {
result = data.button;
});
// Spin this thread while we wait for a result.
let thread = Services.tm.currentThread;
while (result == null)
thread.processNextEvent(true);
if (result === 0)
return true;
if (result === 2) {
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", false);
this._stop();
}
return false;
},
_restart: function rd_restart() {
this._stop();
this._start();
},
_start: function rd_start() {
try {
if (!DebuggerServer.initialized) {
DebuggerServer.init(this._showConnectionPrompt.bind(this));
DebuggerServer.addBrowserActors();
DebuggerServer.addActors("chrome://browser/content/dbg-browser-actors.js");
}
let port = this._getPort();
DebuggerServer.openListener(port);
dump("Remote debugger listening on port " + port);
} catch(e) {
dump("Remote debugger didn't start: " + e);
}
},
_stop: function rd_start() {
DebuggerServer.closeListener();
dump("Remote debugger stopped");
}
};
var Telemetry = {
addData: function addData(aHistogramId, aValue) {
let histogram = Services.telemetry.getHistogramById(aHistogramId);

View File

@ -1,145 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
const { interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this,
"Alerts",
"@mozilla.org/alerts-service;1", "nsIAlertsService");
XPCOMUtils.defineLazyModuleGetter(this,
"Prompt",
"resource://gre/modules/Prompt.jsm");
let Strings = {};
XPCOMUtils.defineLazyGetter(Strings, "debugger",
() => Services.strings.createBundle("chrome://global/locale/devtools/debugger.properties"));
XPCOMUtils.defineLazyGetter(Strings, "browser",
() => Services.strings.createBundle("chrome://browser/locale/browser.properties"));
function DebuggerServerController() {
}
DebuggerServerController.prototype = {
classID: Components.ID("{f6e8e269-ae4a-4c4a-bf80-fb4164fb072c}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDebuggerServerController, Ci.nsIObserver]),
init: function(debuggerServer) {
this.debugger = debuggerServer;
Services.obs.addObserver(this, "debugger-server-started", false);
Services.obs.addObserver(this, "debugger-server-stopped", false);
Services.obs.addObserver(this, "xpcom-shutdown", false);
},
uninit: function() {
this.debugger = null;
Services.obs.removeObserver(this, "debugger-server-started");
Services.obs.removeObserver(this, "debugger-server-stopped");
Services.obs.removeObserver(this, "xpcom-shutdown");
},
start: function(pathOrPort) {
if (!this.debugger.initialized) {
this.debugger.init(this.prompt.bind(this));
this.debugger.addBrowserActors();
this.debugger.addActors("chrome://browser/content/dbg-browser-actors.js");
}
if (!pathOrPort) {
// If the "devtools.debugger.unix-domain-socket" pref is set, we use a unix socket.
// If not, we use a regular TCP socket.
try {
pathOrPort = Services.prefs.getCharPref("devtools.debugger.unix-domain-socket");
} catch (e) {
pathOrPort = Services.prefs.getIntPref("devtools.debugger.remote-port");
}
}
try {
this.debugger.openListener(pathOrPort);
} catch (e) {
dump("Unable to start debugger server (" + pathOrPort + "): " + e + "\n");
}
},
stop: function() {
this.debugger.destroy();
},
prompt: function() {
let title = Strings.browser.GetStringFromName("remoteIncomingPromptTitle");
let msg = Strings.browser.GetStringFromName("remoteIncomingPromptMessage");
let disable = Strings.browser.GetStringFromName("remoteIncomingPromptDisable");
let cancel = Strings.browser.GetStringFromName("remoteIncomingPromptCancel");
let agree = Strings.browser.GetStringFromName("remoteIncomingPromptAccept");
// Make prompt. Note: button order is in reverse.
let prompt = new Prompt({
window: null,
hint: "remotedebug",
title: title,
message: msg,
buttons: [ agree, cancel, disable ],
priority: 1
});
// The debugger server expects a synchronous response, so spin on result since Prompt is async.
let result = null;
prompt.show(function(data) {
result = data.button;
});
// Spin this thread while we wait for a result.
let thread = Services.tm.currentThread;
while (result == null)
thread.processNextEvent(true);
if (result === 0)
return true;
if (result === 2) {
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", false);
this.debugger.destroy();
}
return false;
},
// nsIObserver
observe: function (subject, topic, data) {
if (topic == "xpcom-shutdown")
this.uninit();
if (topic == "debugger-server-started")
this._onDebuggerStarted(data);
if (topic == "debugger-server-stopped")
this._onDebuggerStopped();
},
_onDebuggerStarted: function(portOrPath) {
if (!Services.prefs.getBoolPref("devtools.debugger.show-server-notifications"))
return;
let title = l10n.GetStringFromName("debuggerStartedAlert.title");
let port = Number(portOrPath);
let detail;
if (port) {
detail = l10n.formatStringFromName("debuggerStartedAlert.detailPort", [portOrPath], 1);
} else {
detail = l10n.formatStringFromName("debuggerStartedAlert.detailPath", [portOrPath], 1);
}
Alerts.showAlertNotification(null, title, detail, false, "", function(){});
},
_onDebuggerStopped: function() {
if (!Services.prefs.getBoolPref("devtools.debugger.show-server-notifications"))
return;
let title = l10n.GetStringFromName("debuggerStopped.title");
Alerts.showAlertNotification(null, title, null, false, "", function(){});
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DebuggerServerController]);

View File

@ -120,7 +120,3 @@ category update-timer WebappsUpdateTimer @mozilla.org/webapps-update-timer;1,get
# ColorPicker.js
component {430b987f-bb9f-46a3-99a5-241749220b29} ColorPicker.js
contract @mozilla.org/colorpicker;1 {430b987f-bb9f-46a3-99a5-241749220b29}
# DebuggerServerController.js
component {f6e8e269-ae4a-4c4a-bf80-fb4164fb072c} DebuggerServerController.js
contract @mozilla.org/devtools/DebuggerServerController;1 {f6e8e269-ae4a-4c4a-bf80-fb4164fb072c}

View File

@ -420,11 +420,6 @@
@BINPATH@/components/captivedetect.js
#endif
; DevTools
@BINPATH@/components/DevToolsComponents.manifest
@BINPATH@/components/DevToolsAppStartup.js
@BINPATH@/components/DebuggerServerController.js
#ifdef MOZ_WEBSPEECH
@BINPATH@/components/dom_webspeechsynth.xpt
#endif

View File

@ -567,10 +567,7 @@ pref("devtools.chrome.enabled", false);
// Disable remote debugging protocol logging
pref("devtools.debugger.log", false);
// Show notifications when server starts/stops
pref("devtools.debugger.show-server-notifications", true);
// Run a server debugger. Changing this pref dynamically will
// stop / start the server debugger.
// Disable remote debugging connections
pref("devtools.debugger.remote-enabled", false);
pref("devtools.debugger.remote-port", 6000);
// Force debugger server binding on the loopback interface

View File

@ -515,6 +515,7 @@ class MochitestOptions(optparse.OptionParser):
if options.jsdebugger:
options.extraPrefs += [
"devtools.debugger.remote-enabled=true",
"devtools.debugger.chrome-enabled=true",
"devtools.chrome.enabled=true",
"devtools.debugger.prompt-connection=false"

View File

@ -1,133 +0,0 @@
/* 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/. */
/**
* This component handles the -start-debugger-server command line
* option. It also starts and stops the debugger server when the
* devtools.debugger.remote-enable pref changes.
*/
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const REMOTE_ENABLED_PREF = "devtools.debugger.remote-enabled";
const UNIX_SOCKET_PREF = "devtools.debugger.unix-domain-socket";
const REMOTE_PORT_PREF = "devtools.debugger.remote-port";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this,
"DebuggerServer",
"resource://gre/modules/devtools/dbg-server.jsm");
function DevToolsAppStartup() {
}
DevToolsAppStartup.prototype = {
classID: Components.ID("{9ba9bbe7-5866-46f1-bea6-3299066b7933}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler, Ci.nsIObserver]),
get dbgPortOrPath() {
if (!this._dbgPortOrPath) {
// set default dbgPortOrPath value from preferences:
try {
this._dbgPortOrPath = Services.prefs.getCharPref(UNIX_SOCKET_PREF);
} catch(e) {
try {
this._dbgPortOrPath = Services.prefs.getIntPref(REMOTE_PORT_PREF);
} catch(e) {}
}
}
return this._dbgPortOrPath;
},
set dbgPortOrPath(value) {
this._dbgPortOrPath = value;
},
// nsICommandLineHandler
get helpInfo() {
let str = "";
// Starting the debugger is handled on the app side (not in /toolkit/).
// If the app didn't expose a debugger controller component, we don't
// support the -start-debugger-server option.
if (DebuggerServer.controller) {
str += " -start-debugger-server [<port or unix domain socket path>]";
if (this.dbgPortOrPath) {
str += " (default: " + this.dbgPortOrPath + ")";
}
str += "\n";
}
return str;
},
handle: function(cmdLine) {
if (!DebuggerServer.controller) {
// This app doesn't expose a debugger controller.
// We can't handle the -start-debugger-server option
// or the remote-enable pref.
return;
}
let startDebuggerServerBecauseCmdLine = false;
try {
// Returns null if the argument was not specified. Throws
// NS_ERROR_INVALID_ARG if there is no parameter specified (because
// it was the last argument or the next argument starts with '-').
// However, someone could still explicitly pass an empty argument.
let param = cmdLine.handleFlagWithParam("start-debugger-server", false);
if (param) {
startDebuggerServerBecauseCmdLine = true;
this.dbgPortOrPath = param;
}
} catch(e) {
startDebuggerServerBecauseCmdLine = true;
}
// App has started and we handled the command line options (if any).
// Time to start the debugger if needed and observe the remote-enable
// pref.
if (startDebuggerServerBecauseCmdLine ||
Services.prefs.getBoolPref(REMOTE_ENABLED_PREF)) {
if (this.dbgPortOrPath) {
DebuggerServer.controller.start(this.dbgPortOrPath);
} else {
dump("Can't start debugger: no port or path specified\n");
}
}
Services.prefs.addObserver(REMOTE_ENABLED_PREF, this, false);
Services.prefs.addObserver(UNIX_SOCKET_PREF, this, false);
Services.prefs.addObserver(REMOTE_PORT_PREF, this, false);
},
// nsIObserver
observe: function (subject, topic, data) {
if (topic == "nsPref:changed") {
switch (data) {
case REMOTE_ENABLED_PREF:
if (Services.prefs.getBoolPref(data)) {
DebuggerServer.controller.start(this.dbgPortOrPath);
} else {
DebuggerServer.controller.stop();
}
break;
case UNIX_SOCKET_PREF:
case REMOTE_PORT_PREF:
// reset dbgPortOrPath value
this.dbgPortOrPath = null;
break;
}
}
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DevToolsAppStartup]);

View File

@ -1,3 +0,0 @@
component {9ba9bbe7-5866-46f1-bea6-3299066b7933} DevToolsAppStartup.js
contract @mozilla.org/toolkit/devtools-app-startup;1 {9ba9bbe7-5866-46f1-bea6-3299066b7933}
category command-line-handler DevToolsAppStartup @mozilla.org/toolkit/devtools-app-startup;1

View File

@ -14,16 +14,31 @@ const { Services } = Cu.import("resource://gre/modules/Services.jsm");
let gClient, gActor;
function connect(onDone) {
Services.prefs.setBoolPref("devtools.debugger.prompt-connection", false);
let observer = {
observe: function (subject, topic, data) {
Services.obs.removeObserver(observer, "debugger-server-started");
let transport = debuggerSocketConnect("127.0.0.1", 6000);
startClient(transport, onDone);
}
};
Services.obs.addObserver(observer, "debugger-server-started", false);
DebuggerServer.controller.start(6000);
if (Services.appinfo.name == "B2G") {
// On b2g, we try to exercice the code that launches the production debugger server
let settingsService = Cc["@mozilla.org/settingsService;1"].getService(Ci.nsISettingsService);
settingsService.createLock().set("devtools.debugger.remote-enabled", true, null);
// We can't use `set` callback as it is fired before shell.js code listening for this setting
// is actually called. Same thing applies to mozsettings-changed obs notification.
// So listen to a custom event until bug 942756 lands
let observer = {
observe: function (subject, topic, data) {
Services.obs.removeObserver(observer, "debugger-server-started");
let transport = debuggerSocketConnect("127.0.0.1", 6000);
startClient(transport, onDone);
}
};
Services.obs.addObserver(observer, "debugger-server-started", false);
} else {
// Initialize a loopback remote protocol connection
DebuggerServer.init(function () { return true; });
// We need to register browser actors to have `listTabs` working
// and also have a root actor
DebuggerServer.addBrowserActors();
let transport = DebuggerServer.connectPipe();
startClient(transport, onDone);
}
}
function startClient(transport, onDone) {

View File

@ -30,13 +30,20 @@ exports.items = [
}
],
exec: function(args, context) {
DebuggerServer.controller.start(args.port);
if (!DebuggerServer._listener) {
return gcli.lookup("listenFailed");
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
}
var reply = DebuggerServer.openListener(args.port);
if (!reply) {
throw new Error(gcli.lookup("listenDisabledOutput"));
}
return gcli.lookupFormat("listenInitOutput", [ '' + args.port ]);
if (DebuggerServer.initialized) {
return gcli.lookupFormat("listenInitOutput", [ "" + args.port ]);
}
return gcli.lookup("listenNoInitOutput");
},
}
];

View File

@ -16,10 +16,5 @@ PARALLEL_DIRS += [
'pretty-fast'
]
EXTRA_COMPONENTS += [
'DevToolsAppStartup.js',
'DevToolsComponents.manifest'
]
MOCHITEST_CHROME_MANIFESTS += ['tests/mochitest/chrome.ini']
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']

View File

@ -152,7 +152,6 @@ var DebuggerServer = {
_listener: null,
_initialized: false,
_transportInitialized: false,
_controller: null,
xpcInspector: null,
// Number of currently open TCP connections.
_socketConnections: 0,
@ -165,17 +164,6 @@ var DebuggerServer = {
LONG_STRING_INITIAL_LENGTH: 1000,
LONG_STRING_READ_LENGTH: 65 * 1024,
get controller() {
if (!this._controller) {
let cid = "@mozilla.org/devtools/DebuggerServerController;1";
if (cid in Cc) {
this._controller = Cc[cid].createInstance(Ci.nsIDebuggerServerController);
this._controller.init(this);
}
}
return this._controller;
},
/**
* A handler function that prompts the user to accept or decline the incoming
* connection.
@ -261,13 +249,6 @@ var DebuggerServer = {
get initialized() this._initialized,
/**
* Returns true if at least one connection is active.
*/
isSocketConnected: function DS_isSocketConnected() {
return this._connections && Object.keys(this._connections).length > 0;
},
/**
* Performs cleanup tasks before shutting down the debugger server. Such tasks
* include clearing any actor constructors added at runtime. This method
@ -447,6 +428,9 @@ var DebuggerServer = {
* Otherwise, the path to the unix socket domain file to listen on.
*/
openListener: function DS_openListener(aPortOrPath) {
if (!Services.prefs.getBoolPref("devtools.debugger.remote-enabled")) {
return false;
}
this._checkInit();
// Return early if the server is already listening.
@ -480,7 +464,6 @@ var DebuggerServer = {
}
this._socketConnections++;
Services.obs.notifyObservers(null, "debugger-server-started", aPortOrPath);
return true;
},
@ -502,7 +485,6 @@ var DebuggerServer = {
this._listener.close();
this._listener = null;
this._socketConnections = 0;
Services.obs.notifyObservers(null, "debugger-server-stopped", null);
}
return true;

View File

@ -9,7 +9,6 @@ MOCHITEST_CHROME_MANIFESTS += ['tests/mochitest/chrome.ini']
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
XPIDL_SOURCES += [
'nsIDebuggerServerController.idl',
'nsIJSInspector.idl',
]

View File

@ -1,13 +0,0 @@
/* 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/. */
#include "nsISupports.idl"
[scriptable, uuid(8ac35a92-0741-4ec8-9444-774b9ba19a63)]
interface nsIDebuggerServerController: nsISupports
{
void init(in jsval debugger);
void start(in string portOrPath);
void stop();
};

View File

@ -16,6 +16,8 @@ const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
// Always log packets when running tests. runxpcshelltests.py will throw
// the output away anyway, unless you give it the --verbose flag.
Services.prefs.setBoolPref("devtools.debugger.log", true);
// Enable remote debugging for the relevant tests.
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
function tryImport(url) {
try {

View File

@ -22,14 +22,3 @@ remoteIncomingPromptMessage=An incoming request to permit remote debugging conne
# third button in the incoming connection dialog that lets the user disable the
# remote debugger server.
remoteIncomingPromptDisable=Disable
# LOCALIZATION NOTE (debuggerStarted.*): The message is displayed in a system
# notification box when the debugger is started. %S is the port or path the
# server is listening to.
debuggerStartedAlert.title=Debugger Server now running
debuggerStartedAlert.detailPort=Listening on port %S
debuggerStartedAlert.detailPath=Listening on %S
# LOCALIZATION NOTE (debuggerStopped.title): The message is displayed in a system
# notification box when the debugger is stopped.
debuggerStopped.title=Debugger Server stopped

View File

@ -34,6 +34,7 @@ const PREF_GETADDONS_CACHE_ID_ENABLED = "extensions.%ID%.getAddons.cache.enabled
const PREF_UI_TYPE_HIDDEN = "extensions.ui.%TYPE%.hidden";
const PREF_UI_LASTCATEGORY = "extensions.ui.lastCategory";
const PREF_ADDON_DEBUGGING_ENABLED = "devtools.chrome.enabled";
const PREF_REMOTE_DEBUGGING_ENABLED = "devtools.debugger.remote-enabled";
const LOADING_MSG_DELAY = 100;
@ -153,6 +154,7 @@ function initialize(event) {
gViewController.loadInitialView(view);
Services.prefs.addObserver(PREF_ADDON_DEBUGGING_ENABLED, debuggingPrefChanged, false);
Services.prefs.addObserver(PREF_REMOTE_DEBUGGING_ENABLED, debuggingPrefChanged, false);
}
function notifyInitialized() {
@ -174,6 +176,7 @@ function shutdown() {
gViewController.shutdown();
Services.obs.removeObserver(sendEMPong, "EM-ping");
Services.prefs.removeObserver(PREF_ADDON_DEBUGGING_ENABLED, debuggingPrefChanged);
Services.prefs.removeObserver(PREF_REMOTE_DEBUGGING_ENABLED, debuggingPrefChanged);
}
function sendEMPong(aSubject, aTopic, aData) {
@ -1011,7 +1014,9 @@ var gViewController = {
isEnabled: function cmd_debugItem_isEnabled(aAddon) {
let debuggerEnabled = Services.prefs.
getBoolPref(PREF_ADDON_DEBUGGING_ENABLED);
return aAddon && aAddon.isDebuggable && debuggerEnabled;
let remoteEnabled = Services.prefs.
getBoolPref(PREF_REMOTE_DEBUGGING_ENABLED);
return aAddon && aAddon.isDebuggable && debuggerEnabled && remoteEnabled;
}
},

View File

@ -1358,7 +1358,8 @@
this._showStatus(showProgress ? "progress" : "none");
let debuggable = this.mAddon.isDebuggable &&
Services.prefs.getBoolPref('devtools.chrome.enabled');
Services.prefs.getBoolPref('devtools.chrome.enabled') &&
Services.prefs.getBoolPref('devtools.debugger.remote-enabled');
this._debugBtn.disabled = this._debugBtn.hidden = !debuggable

View File

@ -13,9 +13,8 @@ const getDebugButton = node =>
node.ownerDocument.getAnonymousElementByAttribute(node, "anonid", "debug-btn");
const addonDebuggingEnabled = bool =>
Services.prefs.setBoolPref("devtools.chrome.enabled", !!bool);
Services.prefs.setBoolPref("devtools.debugger.show-server-notifications", false);
const remoteDebuggingEnabled = bool =>
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", !!bool);
function test() {
requestLongerTimeout(2);
@ -38,6 +37,7 @@ function test() {
Task.spawn(function* () {
addonDebuggingEnabled(false);
remoteDebuggingEnabled(false);
yield testDOM((nondebug, debuggable) => {
is(nondebug.disabled, true,
@ -51,6 +51,35 @@ function test() {
});
addonDebuggingEnabled(true);
remoteDebuggingEnabled(false);
yield testDOM((nondebug, debuggable) => {
is(nondebug.disabled, true,
"addon:enabled::remote:disabled button is disabled for legacy addons");
is(nondebug.disabled, true,
"addon:enabled::remote:disabled button is hidden for legacy addons");
is(debuggable.disabled, true,
"addon:enabled::remote:disabled button is disabled for debuggable addons");
is(debuggable.disabled, true,
"addon:enabled::remote:disabled button is hidden for debuggable addons");
});
addonDebuggingEnabled(false);
remoteDebuggingEnabled(true);
yield testDOM((nondebug, debuggable) => {
is(nondebug.disabled, true,
"addon:disabled::remote:enabled button is disabled for legacy addons");
is(nondebug.disabled, true,
"addon:disabled::remote:enabled button is hidden for legacy addons");
is(debuggable.disabled, true,
"addon:disabled::remote:enabled button is disabled for debuggable addons");
is(debuggable.disabled, true,
"addon:disabled::remote:enabled button is hidden for debuggable addons");
});
addonDebuggingEnabled(true);
remoteDebuggingEnabled(true);
yield testDOM((nondebug, debuggable) => {
is(nondebug.disabled, true,
@ -63,7 +92,6 @@ function test() {
"addon:enabled::remote:enabled button is visible for debuggable addons");
});
Services.prefs.clearUserPref("devtools.debugger.show-server-notifications");
finish();
});

View File

@ -76,6 +76,7 @@ pref("dom.always_allow_move_resize_window", true);
pref("plugin.allowed_types", "application/x-shockwave-flash,application/futuresplash");
pref("devtools.debugger.remote-enabled", true);
pref("devtools.debugger.force-local", true);
// The default for this pref reflects whether the build is capable of IPC.