зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1169290 - Make Marionette component safe to load in child process. r=maja_zf
The Marionette XPCOM component is loaded once per process, but only ever initialised in the main process. A subprocess that calls nsIMarionette.running will always see it return false because loading the MarionetteComponent class resets the MarionetteComponent#server property to null, causing MarionetteComponent#running to return false. To report the correct value in child processes they need to query the main process for the running state. This patch introduces a synchronous IPC message call to the main process using the child process message manager (CPMM). Because nsIMarionette is currently never used in a subprocess it is considered acceptable to use sync IPC in this case, especially given the circumstances that Marionette instruments the browser and is not tied to any frontend Firefox UX. MozReview-Commit-ID: 93xtZN4MvWq --HG-- extra : rebase_source : bc90a1720323c5a768d2c03a05bbb8e2a2d1ea60
This commit is contained in:
Родитель
aa4f63e6a1
Коммит
6d8cae5183
|
@ -46,6 +46,9 @@ const ENV_ENABLED = "MOZ_MARIONETTE";
|
|||
// pref being set to 4444.
|
||||
const ENV_PRESERVE_PREFS = "MOZ_MARIONETTE_PREF_STATE_ACROSS_RESTARTS";
|
||||
|
||||
const isRemote = Services.appinfo.processType ==
|
||||
Services.appinfo.PROCESS_TYPE_CONTENT;
|
||||
|
||||
const LogLevel = {
|
||||
get(level) {
|
||||
let levels = new Map([
|
||||
|
@ -137,7 +140,7 @@ const prefs = {
|
|||
},
|
||||
};
|
||||
|
||||
class MarionetteComponent {
|
||||
class MarionetteMainProcess {
|
||||
constructor() {
|
||||
this.server = null;
|
||||
|
||||
|
@ -154,6 +157,7 @@ class MarionetteComponent {
|
|||
this.enabled = env.exists(ENV_ENABLED);
|
||||
|
||||
Services.prefs.addObserver(PREF_ENABLED, this);
|
||||
Services.ppmm.addMessageListener("Marionette:IsRunning", this);
|
||||
}
|
||||
|
||||
get running() {
|
||||
|
@ -168,6 +172,17 @@ class MarionetteComponent {
|
|||
return Services.prefs.getBoolPref(PREF_ENABLED);
|
||||
}
|
||||
|
||||
receiveMessage({name}) {
|
||||
switch (name) {
|
||||
case "Marionette:IsRunning":
|
||||
return this.running;
|
||||
|
||||
default:
|
||||
log.warn("Unknown IPC message to main process: " + name);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
observe(subject, topic) {
|
||||
log.debug(`Received observer notification ${topic}`);
|
||||
|
||||
|
@ -311,14 +326,38 @@ class MarionetteComponent {
|
|||
}
|
||||
}
|
||||
|
||||
class MarionetteContentProcess {
|
||||
get running() {
|
||||
let reply = Services.cpmm.sendSyncMessage("Marionette:IsRunning");
|
||||
if (reply.length == 0) {
|
||||
log.warn("No reply from main process");
|
||||
return false;
|
||||
}
|
||||
return reply[0];
|
||||
}
|
||||
|
||||
get QueryInterface() {
|
||||
return XPCOMUtils.generateQI([Ci.nsIMarionette]);
|
||||
}
|
||||
}
|
||||
|
||||
const MarionetteFactory = {
|
||||
instance_: null,
|
||||
|
||||
createInstance(outer, iid) {
|
||||
if (outer) {
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
|
||||
let marionette = new MarionetteComponent();
|
||||
return marionette.QueryInterface(iid);
|
||||
if (!this.instance_) {
|
||||
if (isRemote) {
|
||||
this.instance_ = new MarionetteContentProcess();
|
||||
} else {
|
||||
this.instance_ = new MarionetteMainProcess();
|
||||
}
|
||||
}
|
||||
|
||||
return this.instance_.QueryInterface(iid);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче