From 96a08eed5d2ff9da258cca7b298c94fe2a20a835 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 16 Jul 2014 07:19:00 +0200 Subject: [PATCH] Bug 1000428 - Part 2: Wire up WiFi enabled setting. r=past,fabrice --- b2g/chrome/content/settings.js | 95 ++++++++----- b2g/chrome/content/shell.js | 245 ++++++++++++++++++++------------- 2 files changed, 211 insertions(+), 129 deletions(-) diff --git a/b2g/chrome/content/settings.js b/b2g/chrome/content/settings.js index 3b891fe748de..203a8ee9b996 100644 --- a/b2g/chrome/content/settings.js +++ b/b2g/chrome/content/settings.js @@ -351,7 +351,7 @@ let AdbController = { // 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; + let isDebugging = USBRemoteDebugger.isDebugging; if (this.DEBUG) { this.debug("isDebugging=" + isDebugging); } @@ -432,45 +432,78 @@ 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"); - } +(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"); + } #ifdef MOZ_WIDGET_GONK - AdbController.setRemoteDebuggerState(value); + 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; - } + 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); + 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') ? RemoteDebugger.start() - : RemoteDebugger.stop(); - } catch(e) { - dump("Error while initializing devtools: " + e + "\n" + e.stack + "\n"); - } + 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'); + 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) { diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js index 65c221a50931..087e712f9934 100644 --- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -56,6 +56,16 @@ XPCOMUtils.defineLazyGetter(this, 'DebuggerServer', function() { 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); @@ -811,10 +821,11 @@ let IndexedDBPromptHelper = { } } -let RemoteDebugger = { +function RemoteDebugger() {} +RemoteDebugger.prototype = { _promptDone: false, _promptAnswer: false, - _running: false, + _listener: null, prompt: function debugger_prompt() { this._promptDone = false; @@ -835,108 +846,146 @@ let RemoteDebugger = { this._promptDone = true; }, - get isDebugging() { - if (!this._running) { + 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 = new RemoteDebugger(); + +Object.defineProperty(USBRemoteDebugger, "isDebugging", { + get: function() { + if (!this._listener) { 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 devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; - 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 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.closeAllListeners(); - } catch (e) { - dump('Unable to stop debugger server: ' + e + '\n'); - } - this._running = false; } -} +}); + +USBRemoteDebugger.start = function() { + if (this._listener) { + return; + } + + this.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); + } +}; + +USBRemoteDebugger.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 = new RemoteDebugger(); + +WiFiRemoteDebugger.start = function() { + if (this._listener) { + return; + } + + this.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); + } +}; + +WiFiRemoteDebugger.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) {