Bug 1039493 - Break out B2G DevTools files. r=fabrice

--HG--
rename : b2g/chrome/content/devtools.js => b2g/chrome/content/devtools/hud.js
This commit is contained in:
J. Ryan Stinnett 2014-08-18 15:40:00 -04:00
parent 6788da60da
commit 3bb8e41245
7 changed files with 543 additions and 503 deletions

View File

@ -0,0 +1,251 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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";
// This file is only loaded on Gonk to manage ADB state
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(
{'debugger.remote-mode': 'disabled'});
}
},
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 = USBRemoteDebugger.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));

View File

@ -0,0 +1,275 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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";
XPCOMUtils.defineLazyGetter(this, "DebuggerServer", function() {
Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
return DebuggerServer;
});
XPCOMUtils.defineLazyGetter(this, "devtools", function() {
const { devtools } =
Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
return devtools;
});
XPCOMUtils.defineLazyGetter(this, "discovery", function() {
return devtools.require("devtools/toolkit/discovery/discovery");
});
let RemoteDebugger = {
_promptDone: false,
_promptAnswer: false,
_listening: false,
prompt: function() {
this._listen();
this._promptDone = false;
shell.sendChromeEvent({
"type": "remote-debugger-prompt"
});
while(!this._promptDone) {
Services.tm.currentThread.processNextEvent(true);
}
return this._promptAnswer;
},
_listen: function() {
if (this._listening) {
return;
}
this.handleEvent = this.handleEvent.bind(this);
let content = shell.contentBrowser.contentWindow;
content.addEventListener("mozContentEvent", this, false, true);
this._listening = true;
},
handleEvent: function(event) {
let detail = event.detail;
if (detail.type !== "remote-debugger-prompt") {
return;
}
this._promptAnswer = detail.value;
this._promptDone = true;
},
initServer: function() {
if (DebuggerServer.initialized) {
return;
}
// 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 { RootActor } = devtools.require("devtools/server/actors/root");
let root = new RootActor(connection, parameters);
root.applicationType = "operating-system";
return root;
};
#ifdef MOZ_WIDGET_GONK
DebuggerServer.on("connectionchange", function() {
AdbController.updateState();
});
#endif
}
};
let USBRemoteDebugger = {
get isDebugging() {
if (!this._listener) {
return false;
}
return DebuggerServer._connections &&
Object.keys(DebuggerServer._connections).length > 0;
},
start: function() {
if (this._listener) {
return;
}
RemoteDebugger.initServer();
let portOrPath =
Services.prefs.getCharPref("devtools.debugger.unix-domain-socket") ||
"/data/local/debugger-socket";
try {
debug("Starting USB debugger on " + portOrPath);
this._listener = DebuggerServer.openListener(portOrPath);
// 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);
} catch (e) {
debug("Unable to start USB debugger server: " + e);
}
},
stop: function() {
if (!this._listener) {
return;
}
try {
this._listener.close();
this._listener = null;
} catch (e) {
debug("Unable to stop USB debugger server: " + e);
}
}
};
let WiFiRemoteDebugger = {
start: function() {
if (this._listener) {
return;
}
RemoteDebugger.initServer();
try {
debug("Starting WiFi debugger");
this._listener = DebuggerServer.openListener(-1);
let port = this._listener.port;
debug("Started WiFi debugger on " + port);
discovery.addService("devtools", { port: port });
} catch (e) {
debug("Unable to start WiFi debugger server: " + e);
}
},
stop: function() {
if (!this._listener) {
return;
}
try {
discovery.removeService("devtools");
this._listener.close();
this._listener = null;
} catch (e) {
debug("Unable to stop WiFi debugger server: " + e);
}
}
};
(function() {
// Track these separately here so we can determine the correct value for the
// pref "devtools.debugger.remote-enabled", which is true when either mode of
// using DevTools is enabled.
let devtoolsUSB = false;
let devtoolsWiFi = false;
// 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) {
devtoolsUSB = value;
Services.prefs.setBoolPref("devtools.debugger.remote-enabled",
devtoolsUSB || devtoolsWiFi);
// This preference is consulted during startup
Services.prefs.savePrefFile(null);
try {
value ? USBRemoteDebugger.start() : USBRemoteDebugger.stop();
} catch(e) {
dump("Error while initializing USB devtools: " +
e + "\n" + e.stack + "\n");
}
});
SettingsListener.observe("debugger.remote-mode", "disabled", function(value) {
if (["disabled", "adb-only", "adb-devtools"].indexOf(value) == -1) {
dump("Illegal value for debugger.remote-mode: " + value + "\n");
return;
}
devtoolsUSB = value == "adb-devtools";
Services.prefs.setBoolPref("devtools.debugger.remote-enabled",
devtoolsUSB || devtoolsWiFi);
// This preference is consulted during startup
Services.prefs.savePrefFile(null);
try {
(value == "adb-devtools") ? USBRemoteDebugger.start()
: USBRemoteDebugger.stop();
} catch(e) {
dump("Error while initializing USB devtools: " +
e + "\n" + e.stack + "\n");
}
#ifdef MOZ_WIDGET_GONK
AdbController.setRemoteDebuggerState(value != "disabled");
#endif
});
SettingsListener.observe("devtools.remote.wifi.enabled", false,
function(value) {
devtoolsWiFi = value;
Services.prefs.setBoolPref("devtools.debugger.remote-enabled",
devtoolsUSB || devtoolsWiFi);
// Allow remote debugging on non-local interfaces when WiFi debug is enabled
// TODO: Bug 1034411: Lock down to WiFi interface, instead of all interfaces
Services.prefs.setBoolPref("devtools.debugger.force-local", !value);
// This preference is consulted during startup
Services.prefs.savePrefFile(null);
try {
value ? WiFiRemoteDebugger.start() : WiFiRemoteDebugger.stop();
} catch(e) {
dump("Error while initializing WiFi devtools: " +
e + "\n" + e.stack + "\n");
}
});
})();

View File

@ -4,6 +4,8 @@
'use strict';
// settings.js loads this file when the HUD setting is enabled.
const DEVELOPER_HUD_LOG_PREFIX = 'DeveloperHUD';
XPCOMUtils.defineLazyGetter(this, 'devtools', function() {

View File

@ -4,7 +4,7 @@
* 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;"
"use strict";
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -176,14 +176,14 @@ Components.utils.import('resource://gre/modules/ctypes.jsm');
}
})();
// =================== DevTools ====================
// =================== DevTools HUD ====================
let developerHUD;
SettingsListener.observe('devtools.overlay', false, (value) => {
if (value) {
if (!developerHUD) {
let scope = {};
Services.scriptloader.loadSubScript('chrome://b2g/content/devtools.js', scope);
Services.scriptloader.loadSubScript('chrome://b2g/content/devtools/hud.js', scope);
developerHUD = scope.developerHUD;
}
developerHUD.init();
@ -194,321 +194,6 @@ 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(
{'debugger.remote-mode': 'disabled'});
}
},
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 = USBRemoteDebugger.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
(function() {
// Track these separately here so we can determine the correct value for the
// pref "devtools.debugger.remote-enabled", which is true when either mode of
// using DevTools is enabled.
let devtoolsUSB = false;
let devtoolsWiFi = false;
// 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) {
devtoolsUSB = value;
Services.prefs.setBoolPref('devtools.debugger.remote-enabled',
devtoolsUSB || devtoolsWiFi);
// This preference is consulted during startup
Services.prefs.savePrefFile(null);
try {
value ? USBRemoteDebugger.start() : USBRemoteDebugger.stop();
} catch(e) {
dump("Error while initializing USB devtools: "
+ e + "\n" + e.stack + "\n");
}
});
SettingsListener.observe('debugger.remote-mode', 'disabled', function(value) {
if (['disabled', 'adb-only', 'adb-devtools'].indexOf(value) == -1) {
dump('Illegal value for debugger.remote-mode: ' + value + '\n');
return;
}
devtoolsUSB = value == 'adb-devtools';
Services.prefs.setBoolPref('devtools.debugger.remote-enabled',
devtoolsUSB || devtoolsWiFi);
// This preference is consulted during startup
Services.prefs.savePrefFile(null);
try {
(value == 'adb-devtools') ? USBRemoteDebugger.start()
: USBRemoteDebugger.stop();
} catch(e) {
dump("Error while initializing USB devtools: "
+ e + "\n" + e.stack + "\n");
}
#ifdef MOZ_WIDGET_GONK
AdbController.setRemoteDebuggerState(value != 'disabled');
#endif
});
SettingsListener.observe('devtools.remote.wifi.enabled', false,
function(value) {
devtoolsWiFi = value;
Services.prefs.setBoolPref('devtools.debugger.remote-enabled',
devtoolsUSB || devtoolsWiFi);
// Allow remote debugging on non-local interfaces when WiFi debug is enabled
// TODO: Bug 1034411: Lock down to WiFi interface, instead of all interfaces
Services.prefs.setBoolPref('devtools.debugger.force-local', !value);
// This preference is consulted during startup
Services.prefs.savePrefFile(null);
try {
value ? WiFiRemoteDebugger.start() : WiFiRemoteDebugger.stop();
} catch(e) {
dump("Error while initializing WiFi devtools: "
+ e + "\n" + e.stack + "\n");
}
});
})();
// =================== Device Storage ====================
SettingsListener.observe('device.storage.writable.name', 'sdcard', function(value) {
if (Services.prefs.getPrefType('device.storage.writable.name') != Ci.nsIPrefBranch.PREF_STRING) {

View File

@ -32,7 +32,14 @@
<!-- this script handles the "runapp" argument for desktop builds -->
<script type="application/javascript;version=1.8"
src="chrome://b2g/content/runapp.js"> </script>
#else
<!-- this file is only loaded on Gonk to manage ADB state -->
<script type="application/javascript;version=1.8"
src="chrome://b2g/content/devtools/adb.js"> </script>
#endif
<!-- manages DevTools server state -->
<script type="application/javascript;version=1.8"
src="chrome://b2g/content/devtools/debugger.js"> </script>
</head>
<body id="container">
#ifdef FXOS_SIMULATOR

View File

@ -51,21 +51,6 @@ 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, 'devtools', function() {
const { devtools } =
Cu.import('resource://gre/modules/devtools/Loader.jsm', {});
return devtools;
});
XPCOMUtils.defineLazyGetter(this, 'discovery', function() {
return devtools.require('devtools/toolkit/discovery/discovery');
});
XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
return Cc["@mozilla.org/parentprocessmessagemanager;1"]
.getService(Ci.nsIMessageListenerManager);
@ -730,9 +715,6 @@ 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;
@ -860,172 +842,6 @@ let IndexedDBPromptHelper = {
}
}
let RemoteDebugger = {
_promptDone: false,
_promptAnswer: 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;
},
initServer: function() {
if (DebuggerServer.initialized) {
return;
}
// 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 { RootActor } = devtools.require("devtools/server/actors/root");
let root = new RootActor(connection, parameters);
root.applicationType = "operating-system";
return root;
};
#ifdef MOZ_WIDGET_GONK
DebuggerServer.on("connectionchange", function() {
AdbController.updateState();
});
#endif
}
};
let USBRemoteDebugger = {
get isDebugging() {
if (!this._listener) {
return false;
}
return DebuggerServer._connections &&
Object.keys(DebuggerServer._connections).length > 0;
},
start: function() {
if (this._listener) {
return;
}
RemoteDebugger.initServer();
let portOrPath =
Services.prefs.getCharPref("devtools.debugger.unix-domain-socket") ||
"/data/local/debugger-socket";
try {
debug("Starting USB debugger on " + portOrPath);
this._listener = DebuggerServer.openListener(portOrPath);
// 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);
} catch (e) {
debug('Unable to start USB debugger server: ' + e);
}
},
stop: function() {
if (!this._listener) {
return;
}
try {
this._listener.close();
this._listener = null;
} catch (e) {
debug('Unable to stop USB debugger server: ' + e);
}
}
};
let WiFiRemoteDebugger = {
start: function() {
if (this._listener) {
return;
}
RemoteDebugger.initServer();
try {
debug("Starting WiFi debugger");
this._listener = DebuggerServer.openListener(-1);
let port = this._listener.port;
debug("Started WiFi debugger on " + port);
discovery.addService("devtools", { port: port });
} catch (e) {
debug('Unable to start WiFi debugger server: ' + e);
}
},
stop: function() {
if (!this._listener) {
return;
}
try {
discovery.removeService("devtools");
this._listener.close();
this._listener = null;
} catch (e) {
debug('Unable to stop WiFi debugger server: ' + e);
}
}
};
let KeyboardHelper = {
handleEvent: function keyboard_handleEvent(detail) {
Keyboard.setLayouts(detail.layouts);

View File

@ -13,7 +13,11 @@ chrome.jar:
* content/shell.html (content/shell.html)
* content/shell.js (content/shell.js)
content/shell.css (content/shell.css)
content/devtools.js (content/devtools.js)
#ifdef MOZ_WIDGET_GONK
content/devtools/adb.js (content/devtools/adb.js)
#endif
* content/devtools/debugger.js (content/devtools/debugger.js)
content/devtools/hud.js (content/devtools/hud.js)
#ifdef FXOS_SIMULATOR
content/desktop.css (content/desktop.css)
content/images/desktop/home-black.png (content/images/desktop/home-black.png)