Bug 1449821 - 4. Use one child message listener per EventDispatcher; r?esawin
Instead of registering a new message listener for every event, register
a single listener for each EventDispatcher to improve performance.
MozReview-Commit-ID: Lg7eR29uESo
--- a/mobile/android/modules/geckoview/Messaging.jsm
+++ b/mobile/android/modules/geckoview/Messaging.jsm
@@ -13,16 +13,23 @@ XPCOMUtils.defineLazyServiceGetter(this,
"nsIUUIDGenerator");
const IS_PARENT_PROCESS = (Services.appinfo.processType ==
Services.appinfo.PROCESS_TYPE_DEFAULT);
function DispatcherDelegate(aDispatcher, aMessageManager) {
this._dispatcher = aDispatcher;
this._messageManager = aMessageManager;
+
+ if (!aDispatcher) {
+ // Child process.
+ this._replies = new Map();
+ (aMessageManager || Services.cpmm).addMessageListener(
+ "GeckoView:MessagingReply", this);
+ }
}
DispatcherDelegate.prototype = {
/**
* Register a listener to be notified of event(s).
*
* @param aListener Target listener implementing nsIAndroidEventListener.
* @param aEvents String or array of strings of events to listen to.
@@ -66,32 +73,22 @@ DispatcherDelegate.prototype = {
let mm = this._messageManager || Services.cpmm;
let forwardData = {
global: !this._messageManager,
event: aEvent,
data: aData,
};
if (aCallback) {
- forwardData.uuid = UUIDGen.generateUUID().toString();
- mm.addMessageListener("GeckoView:MessagingReply", function listener(msg) {
- if (msg.data.uuid !== forwardData.uuid) {
- return;
- }
- if (msg.data.type === "success") {
- aCallback.onSuccess(msg.data.response);
- } else if (msg.data.type === "error") {
- aCallback.onError(msg.data.response);
- } else if (msg.data.type === "finalize") {
- aFinalizer && aFinalizer.onFinalize();
- mm.removeMessageListener(msg.name, listener);
- } else {
- throw new Error("invalid reply type");
- }
+ const uuid = UUIDGen.generateUUID().toString();
+ this._replies.set(uuid, {
+ callback: aCallback,
+ finalizer: aFinalizer,
});
+ forwardData.uuid = uuid;
}
mm.sendAsyncMessage("GeckoView:Messaging", forwardData);
},
/**
* Sends a request to Java.
*
@@ -116,16 +113,39 @@ DispatcherDelegate.prototype = {
aMsg.type = undefined;
this.dispatch(type, aMsg, {
onSuccess: resolve,
onError: reject,
});
});
},
+
+ receiveMessage: function(aMsg) {
+ const {uuid, type} = aMsg.data;
+ const reply = this._replies.get(uuid);
+ if (!reply) {
+ return;
+ }
+
+ if (type === "success") {
+ reply.callback.onSuccess(aMsg.data.response);
+ } else if (type === "error") {
+ reply.callback.onError(aMsg.data.response);
+ } else if (type === "finalize") {
+ if (typeof reply.finalizer === "function") {
+ reply.finalizer();
+ } else if (reply.finalizer) {
+ reply.finalizer.onFinalize();
+ }
+ this._replies.delete(uuid);
+ } else {
+ throw new Error("invalid reply type");
+ }
+ },
};
var EventDispatcher = {
instance: new DispatcherDelegate(IS_PARENT_PROCESS ? Services.androidBridge : undefined),
/**
* Return an EventDispatcher instance for a chrome DOM window. In a content
* process, return a proxy through the message manager that automatically