Bug 1375809 - use events to communicate between XPIProvider.jsm and ToolboxProcess.jsm;r=aswan,jryans

As DevTools are moving to be an addon and out of mozilla-central, we should remove the
coupling between the mozilla-central code and the DevTools code.

Instead of directly loading and calling the ToolboxProcess, XPIProvider.jsm now uses
events to interact with BrowserToolboxProcess.

MozReview-Commit-ID: HpnMLCILkea

--HG--
extra : rebase_source : 7b090d996fdf25ac364c05e075983454979bdeb5
This commit is contained in:
Julian Descottes 2017-06-23 17:44:05 +02:00
Родитель 99144fb346
Коммит 7003e438d1
2 изменённых файлов: 37 добавлений и 43 удалений

Просмотреть файл

@ -71,6 +71,8 @@ this.BrowserToolboxProcess = function BrowserToolboxProcess(onClose, onRun, opti
this._telemetry = new Telemetry();
this._onConnectionChange = this._onConnectionChange.bind(this);
this.close = this.close.bind(this);
Services.obs.addObserver(this.close, "quit-application");
this._initServer();
@ -133,7 +135,7 @@ BrowserToolboxProcess.prototype = {
dumpn("Created a separate loader instance for the DebuggerServer.");
// Forward interesting events.
this.debuggerServer.on("connectionchange", this.emit);
this.debuggerServer.on("connectionchange", this._onConnectionChange);
this.debuggerServer.init();
// We mainly need a root actor and tab actors for opening a toolbox, even
@ -283,6 +285,19 @@ BrowserToolboxProcess.prototype = {
});
},
/**
* Called upon receiving the connectionchange event from a debuggerServer.
*
* @param {String} what
* Type of connection change (can be either 'opened' or 'closed').
* @param {DebuggerServerConnection} connection
* The connection that was opened or closed.
*/
_onConnectionChange: function (evt, what, connection) {
let wrappedJSObject = { what, connection };
Services.obs.notifyObservers({ wrappedJSObject }, "toolbox-connection-change");
},
/**
* Closes the remote debugging server and kills the toolbox process.
*/
@ -299,7 +314,7 @@ BrowserToolboxProcess.prototype = {
this._telemetry.toolClosed("jsbrowserdebugger");
if (this.debuggerServer) {
this.debuggerServer.off("connectionchange", this.emit);
this.debuggerServer.off("connectionchange", this._onConnectionChange);
this.debuggerServer.destroy();
this.debuggerServer = null;
}
@ -337,4 +352,9 @@ Services.prefs.addObserver("devtools.debugger.log", {
}
});
Services.obs.notifyObservers(null, "ToolboxProcessLoaded");
Services.prefs.addObserver("toolbox-update-addon-options", {
observe: (subject) => {
let {id, options} = subject.wrappedJSObject;
BrowserToolboxProcess.setAddonOptions(id, options);
}
});

Просмотреть файл

@ -42,8 +42,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/Promise.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "BrowserToolboxProcess",
"resource://devtools/client/framework/ToolboxProcess.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ConsoleAPI",
"resource://gre/modules/Console.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ProductAddonChecker",
@ -197,7 +195,7 @@ XPCOMUtils.defineConstant(this, "DB_SCHEMA", 21);
XPCOMUtils.defineLazyPreferenceGetter(this, "ALLOW_NON_MPC", PREF_ALLOW_NON_MPC);
const NOTIFICATION_TOOLBOXPROCESS_LOADED = "ToolboxProcessLoaded";
const NOTIFICATION_TOOLBOX_CONNECTION_CHANGE = "toolbox-connection-change";
// Properties that exist in the install manifest
const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"];
@ -1880,8 +1878,6 @@ this.XPIProvider = {
_telemetryDetails: {},
// A Map from an add-on install to its ID
_addonFileMap: new Map(),
// Flag to know if ToolboxProcess.jsm has already been loaded by someone or not
_toolboxProcessLoaded: false,
// Have we started shutting down bootstrap add-ons?
_closing: false,
@ -2223,21 +2219,7 @@ this.XPIProvider = {
Services.prefs.addObserver(PREF_ALLOW_LEGACY, this);
Services.prefs.addObserver(PREF_ALLOW_NON_MPC, this);
Services.obs.addObserver(this, NOTIFICATION_FLUSH_PERMISSIONS);
// Cu.isModuleLoaded can fail here for external XUL apps where there is
// no chrome.manifest that defines resource://devtools.
if (ResProtocolHandler.hasSubstitution("devtools")) {
if (Cu.isModuleLoaded("resource://devtools/client/framework/ToolboxProcess.jsm")) {
// If BrowserToolboxProcess is already loaded, set the boolean to true
// and do whatever is needed
this._toolboxProcessLoaded = true;
BrowserToolboxProcess.on("connectionchange",
this.onDebugConnectionChange.bind(this));
} else {
// Else, wait for it to load
Services.obs.addObserver(this, NOTIFICATION_TOOLBOXPROCESS_LOADED);
}
}
Services.obs.addObserver(this, NOTIFICATION_TOOLBOX_CONNECTION_CHANGE);
let flushCaches = this.checkForChanges(aAppChanged, aOldAppVersion,
@ -3918,12 +3900,12 @@ this.XPIProvider = {
}
},
onDebugConnectionChange(aEvent, aWhat, aConnection) {
if (aWhat != "opened")
onDebugConnectionChange({what, connection}) {
if (what != "opened")
return;
for (let [id, val] of this.activeAddons) {
aConnection.setAddonOptions(
connection.setAddonOptions(
id, { global: val.bootstrapScope });
}
},
@ -3939,11 +3921,9 @@ this.XPIProvider = {
this.importPermissions();
}
return;
} else if (aTopic == NOTIFICATION_TOOLBOXPROCESS_LOADED) {
Services.obs.removeObserver(this, NOTIFICATION_TOOLBOXPROCESS_LOADED);
this._toolboxProcessLoaded = true;
BrowserToolboxProcess.on("connectionchange",
this.onDebugConnectionChange.bind(this));
} else if (aTopic == NOTIFICATION_TOOLBOX_CONNECTION_CHANGE) {
this.onDebugConnectionChange(aSubject.wrappedJSObject);
return;
}
if (aTopic == "nsPref:changed") {
@ -4310,13 +4290,9 @@ this.XPIProvider = {
logger.warn("Error loading bootstrap.js for " + aId, e);
}
// Only access BrowserToolboxProcess if ToolboxProcess.jsm has been
// initialized as otherwise, when it will be initialized, all addons'
// globals will be added anyways
if (this._toolboxProcessLoaded) {
BrowserToolboxProcess.setAddonOptions(aId,
{ global: activeAddon.bootstrapScope });
}
// Notify the BrowserToolboxProcess that a new addon has been loaded.
let wrappedJSObject = { id: aId, options: { global: activeAddon.bootstrapScope }};
Services.obs.notifyObservers({ wrappedJSObject }, "toolbox-update-addon-options");
},
/**
@ -4335,11 +4311,9 @@ this.XPIProvider = {
this.activeAddons.delete(aId);
this.addAddonsToCrashReporter();
// Only access BrowserToolboxProcess if ToolboxProcess.jsm has been
// initialized as otherwise, there won't be any addon globals added to it
if (this._toolboxProcessLoaded) {
BrowserToolboxProcess.setAddonOptions(aId, { global: null });
}
// Notify the BrowserToolboxProcess that an addon has been unloaded.
let wrappedJSObject = { id: aId, options: { global: null }};
Services.obs.notifyObservers({ wrappedJSObject }, "toolbox-update-addon-options");
},
/**