mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
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:
parent
6db9e6c28e
commit
41bd0431d4
@ -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
|
||||
|
@ -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();
|
@ -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();
|
||||
});
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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">
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -12,7 +12,6 @@ EXTRA_COMPONENTS += [
|
||||
'B2GAboutRedirector.js',
|
||||
'ContentHandler.js',
|
||||
'ContentPermissionPrompt.js',
|
||||
'DebuggerServerController.js',
|
||||
'FilePicker.js',
|
||||
'HelperAppDialog.js',
|
||||
'MailtoProtocolHandler.js',
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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]);
|
@ -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}
|
@ -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',
|
||||
]
|
@ -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();
|
||||
|
@ -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"
|
||||
];
|
2
browser/devtools/devtools-clhandler.manifest
Normal file
2
browser/devtools/devtools-clhandler.manifest
Normal 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}
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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"
|
||||
|
@ -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']
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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/*
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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]);
|
@ -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}
|
||||
|
@ -16,7 +16,6 @@ EXTRA_COMPONENTS += [
|
||||
'BrowserStartup.js',
|
||||
'ContentDispatchChooser.js',
|
||||
'ContentPermissionPrompt.js',
|
||||
'DebuggerServerController.js',
|
||||
'DirectoryProvider.js',
|
||||
'DownloadManagerUI.js',
|
||||
'HelperAppDialog.js',
|
||||
|
@ -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);
|
||||
|
@ -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]);
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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]);
|
@ -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
|
@ -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) {
|
||||
|
@ -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");
|
||||
},
|
||||
}
|
||||
];
|
||||
|
@ -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']
|
||||
|
@ -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;
|
||||
|
@ -9,7 +9,6 @@ MOCHITEST_CHROME_MANIFESTS += ['tests/mochitest/chrome.ini']
|
||||
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDebuggerServerController.idl',
|
||||
'nsIJSInspector.idl',
|
||||
]
|
||||
|
||||
|
@ -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();
|
||||
};
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
});
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user