зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1031609 - Observer service shims (r=mconley)
This commit is contained in:
Родитель
26513758b2
Коммит
a0b866406e
|
@ -150,6 +150,34 @@ let ContentPolicyChild = {
|
||||||
};
|
};
|
||||||
ContentPolicyChild.init();
|
ContentPolicyChild.init();
|
||||||
|
|
||||||
|
// This code registers observers in the child whenever an add-on in
|
||||||
|
// the parent asks for notifications on the given topic.
|
||||||
|
let ObserverChild = {
|
||||||
|
init: function() {
|
||||||
|
NotificationTracker.watch("observer", (path, count) => this.track(path, count));
|
||||||
|
},
|
||||||
|
|
||||||
|
track: function(path, count) {
|
||||||
|
let topic = path[1];
|
||||||
|
if (count) {
|
||||||
|
Services.obs.addObserver(this, topic, false);
|
||||||
|
} else {
|
||||||
|
Services.obs.removeObserver(this, topic);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
observe: function(subject, topic, data) {
|
||||||
|
let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||||
|
.getService(Ci.nsISyncMessageSender);
|
||||||
|
cpmm.sendRpcMessage("Addons:Observer:Run", {}, {
|
||||||
|
topic: topic,
|
||||||
|
subject: subject,
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ObserverChild.init();
|
||||||
|
|
||||||
let RemoteAddonsChild = {
|
let RemoteAddonsChild = {
|
||||||
init: function(global) {
|
init: function(global) {
|
||||||
},
|
},
|
||||||
|
|
|
@ -172,6 +172,80 @@ CategoryManagerInterposition.methods.deleteCategoryEntry =
|
||||||
target.deleteCategoryEntry(category, entry, persist);
|
target.deleteCategoryEntry(category, entry, persist);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This object manages add-on observers that might fire in the child
|
||||||
|
// process. Rather than managing the observers itself, it uses the
|
||||||
|
// parent's observer service. When an add-on listens on topic T,
|
||||||
|
// ObserverParent asks the child process to listen on T. It also adds
|
||||||
|
// an observer in the parent for the topic e10s-T. When the T observer
|
||||||
|
// fires in the child, the parent fires all the e10s-T observers,
|
||||||
|
// passing them CPOWs for the subject and data. We don't want to use T
|
||||||
|
// in the parent because there might be non-add-on T observers that
|
||||||
|
// won't expect to get notified in this case.
|
||||||
|
let ObserverParent = {
|
||||||
|
init: function() {
|
||||||
|
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||||
|
.getService(Ci.nsIMessageBroadcaster);
|
||||||
|
ppmm.addMessageListener("Addons:Observer:Run", this);
|
||||||
|
},
|
||||||
|
|
||||||
|
addObserver: function(observer, topic, ownsWeak) {
|
||||||
|
Services.obs.addObserver(observer, "e10s-" + topic, ownsWeak);
|
||||||
|
NotificationTracker.add(["observer", topic]);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeObserver: function(observer, topic) {
|
||||||
|
Services.obs.removeObserver(observer, "e10s-" + topic);
|
||||||
|
NotificationTracker.remove(["observer", topic]);
|
||||||
|
},
|
||||||
|
|
||||||
|
receiveMessage: function(msg) {
|
||||||
|
switch (msg.name) {
|
||||||
|
case "Addons:Observer:Run":
|
||||||
|
this.notify(msg.objects.subject, msg.objects.topic, msg.objects.data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
notify: function(subject, topic, data) {
|
||||||
|
let e = Services.obs.enumerateObservers("e10s-" + topic);
|
||||||
|
while (e.hasMoreElements()) {
|
||||||
|
let obs = e.getNext().QueryInterface(Ci.nsIObserver);
|
||||||
|
try {
|
||||||
|
obs.observe(subject, topic, data);
|
||||||
|
} catch (e) {
|
||||||
|
Cu.reportError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ObserverParent.init();
|
||||||
|
|
||||||
|
// We only forward observers for these topics.
|
||||||
|
let TOPIC_WHITELIST = ["content-document-global-created",
|
||||||
|
"document-element-inserted",];
|
||||||
|
|
||||||
|
// This interposition listens for
|
||||||
|
// nsIObserverService.{add,remove}Observer.
|
||||||
|
let ObserverInterposition = new Interposition();
|
||||||
|
|
||||||
|
ObserverInterposition.methods.addObserver =
|
||||||
|
function(addon, target, observer, topic, ownsWeak) {
|
||||||
|
if (TOPIC_WHITELIST.indexOf(topic) >= 0) {
|
||||||
|
ObserverParent.addObserver(observer, topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
target.addObserver(observer, topic, ownsWeak);
|
||||||
|
};
|
||||||
|
|
||||||
|
ObserverInterposition.methods.removeObserver =
|
||||||
|
function(addon, target, observer, topic) {
|
||||||
|
if (TOPIC_WHITELIST.indexOf(topic) >= 0) {
|
||||||
|
ObserverParent.removeObserver(observer, topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
target.removeObserver(observer, topic);
|
||||||
|
};
|
||||||
|
|
||||||
let RemoteAddonsParent = {
|
let RemoteAddonsParent = {
|
||||||
init: function() {
|
init: function() {
|
||||||
},
|
},
|
||||||
|
@ -184,6 +258,7 @@ let RemoteAddonsParent = {
|
||||||
}
|
}
|
||||||
|
|
||||||
register(Ci.nsICategoryManager, CategoryManagerInterposition);
|
register(Ci.nsICategoryManager, CategoryManagerInterposition);
|
||||||
|
register(Ci.nsIObserverService, ObserverInterposition);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
Загрузка…
Ссылка в новой задаче