mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-11 10:08:41 +00:00
Bug 782766 - [WebActivities] support blobs - Part 1: System Messages changes [r=gene]
--HG-- extra : rebase_source : bff9c5c4745493b652a6218a60d5840e09f7235e
This commit is contained in:
parent
7ec18def70
commit
0e5313830a
@ -54,7 +54,10 @@ ActivityProxy.prototype = {
|
||||
? DOMApplicationRegistry.getManifestURLByLocalId(appId)
|
||||
: null;
|
||||
cpmm.sendAsyncMessage("Activity:Start", { id: this.id,
|
||||
options: aOptions,
|
||||
options: {
|
||||
name: aOptions.name,
|
||||
data: aOptions.data
|
||||
},
|
||||
manifestURL: manifestURL,
|
||||
pageURL: aWindow.document.location.href });
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
"use strict"
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
@ -13,25 +13,59 @@ const EXPORTED_SYMBOLS = ["ObjectWrapper"];
|
||||
// Makes sure that we expose correctly chrome JS objects to content.
|
||||
|
||||
let ObjectWrapper = {
|
||||
getObjectKind: function objWrapper_getobjectkind(aObject) {
|
||||
if (!aObject) {
|
||||
return "null";
|
||||
}
|
||||
|
||||
if (Array.isArray(aObject)) {
|
||||
return "array";
|
||||
} else if (aObject.mozSlice && (typeof aObject.mozSlice == "function")) {
|
||||
return "blob";
|
||||
} else if (typeof aObject == "object") {
|
||||
return "object";
|
||||
} else {
|
||||
return "primitive";
|
||||
}
|
||||
},
|
||||
|
||||
wrap: function objWrapper_wrap(aObject, aCtxt) {
|
||||
if (!aObject) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// First check wich kind of object we have.
|
||||
let kind = this.getObjectKind(aObject);
|
||||
if (kind == "array") {
|
||||
let res = Cu.createArrayIn(aCtxt);
|
||||
aObject.forEach(function(aObj) {
|
||||
res.push(this.wrap(aObj, aCtxt));
|
||||
}, this);
|
||||
return res;
|
||||
} else if (kind == "blob") {
|
||||
return new aCtxt.Blob([aObject]);
|
||||
} else if (kind == "primitive") {
|
||||
return aObject;
|
||||
}
|
||||
|
||||
// Fall-through, we now have a dictionnary object.
|
||||
let res = Cu.createObjectIn(aCtxt);
|
||||
let propList = { };
|
||||
for (let prop in aObject) {
|
||||
let value;
|
||||
if (Array.isArray(aObject[prop])) {
|
||||
let objProp = aObject[prop];
|
||||
let propKind = this.getObjectKind(objProp);
|
||||
if (propKind == "array") {
|
||||
value = Cu.createArrayIn(aCtxt);
|
||||
aObject[prop].forEach(function(aObj) {
|
||||
// Only wrap objects.
|
||||
if (typeof aObj == "object") {
|
||||
value.push(objWrapper_wrap(aObj, aCtxt));
|
||||
} else {
|
||||
value.push(aObj);
|
||||
}
|
||||
});
|
||||
} else if (typeof(aObject[prop]) == "object") {
|
||||
value = objWrapper_wrap(aObject[prop], aCtxt);
|
||||
objProp.forEach(function(aObj) {
|
||||
value.push(this.wrap(aObj, aCtxt));
|
||||
}, this);
|
||||
} else if (propKind == "blob") {
|
||||
value = new aCtxt.Blob([objProp]);
|
||||
} else if (propKind == "object") {
|
||||
value = this.wrap(objProp, aCtxt);
|
||||
} else {
|
||||
value = aObject[prop];
|
||||
value = objProp;
|
||||
}
|
||||
propList[prop] = {
|
||||
enumerable: true,
|
||||
|
@ -1228,7 +1228,9 @@ ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
|
||||
static_cast<PBlobParent*>(remoteBlob->GetPBlob()));
|
||||
NS_ASSERTION(actor, "Null actor?!");
|
||||
|
||||
return actor;
|
||||
if (actor->Manager() == this) {
|
||||
return actor;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX This is only safe so long as all blob implementations in our tree
|
||||
|
@ -30,6 +30,7 @@ try {
|
||||
}
|
||||
|
||||
const kMessages =["SystemMessageManager:GetPendingMessages",
|
||||
"SystemMessageManager:HasPendingMessages",
|
||||
"SystemMessageManager:Register",
|
||||
"SystemMessageManager:Message:Return:OK",
|
||||
"SystemMessageManager:AskReadyToRegister",
|
||||
@ -209,7 +210,7 @@ SystemMessageInternal.prototype = {
|
||||
return page !== null;
|
||||
}, this);
|
||||
if (!page) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Return the |msg| of each pending message (drop the |msgID|).
|
||||
@ -222,7 +223,33 @@ SystemMessageInternal.prototype = {
|
||||
// pending messages in the content process (|SystemMessageManager|).
|
||||
page.pendingMessages.length = 0;
|
||||
|
||||
return pendingMessages;
|
||||
// Send the array of pending messages.
|
||||
aMessage.target.sendAsyncMessage("SystemMessageManager:GetPendingMessages:Return",
|
||||
{ type: msg.type,
|
||||
manifest: msg.manifest,
|
||||
uri: msg.uri,
|
||||
msgQueue: pendingMessages });
|
||||
break;
|
||||
}
|
||||
case "SystemMessageManager:HasPendingMessages":
|
||||
{
|
||||
debug("received SystemMessageManager:HasPendingMessages " + msg.type +
|
||||
" for " + msg.uri + " @ " + msg.manifest);
|
||||
|
||||
// This is a sync call used to return if a page has pending messages.
|
||||
// Find the right page to get its corresponding pending messages.
|
||||
let page = null;
|
||||
this._pages.some(function(aPage) {
|
||||
if (this._isPageMatched(aPage, msg.type, msg.uri, msg.manifest)) {
|
||||
page = aPage;
|
||||
}
|
||||
return page !== null;
|
||||
}, this);
|
||||
if (!page) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return page.pendingMessages.length != 0;
|
||||
break;
|
||||
}
|
||||
case "SystemMessageManager:Message:Return:OK":
|
||||
|
@ -19,15 +19,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsISyncMessageSender");
|
||||
|
||||
// Limit the number of pending messages for a given type.
|
||||
let kMaxPendingMessages;
|
||||
try {
|
||||
kMaxPendingMessages = Services.prefs.getIntPref("dom.messages.maxPendingMessages");
|
||||
} catch(e) {
|
||||
// getIntPref throws when the pref is not set.
|
||||
kMaxPendingMessages = 5;
|
||||
}
|
||||
|
||||
function debug(aMsg) {
|
||||
//dump("-- SystemMessageManager " + Date.now() + " : " + aMsg + "\n");
|
||||
}
|
||||
@ -102,61 +93,23 @@ SystemMessageManager.prototype = {
|
||||
// Last registered handler wins.
|
||||
handlers[aType] = aHandler;
|
||||
|
||||
// If we have pending messages, send them asynchronously.
|
||||
if (this._getPendingMessages(aType, true)) {
|
||||
let thread = Services.tm.mainThread;
|
||||
let pending = this._pendings[aType];
|
||||
this._pendings[aType] = [];
|
||||
let self = this;
|
||||
pending.forEach(function dispatch_pending(aPending) {
|
||||
thread.dispatch({
|
||||
run: function run() {
|
||||
self._dispatchMessage(aType, aHandler, aPending);
|
||||
}
|
||||
}, Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_getPendingMessages: function sysMessMgr_getPendingMessages(aType, aForceUpdate) {
|
||||
debug("hasPendingMessage " + aType);
|
||||
let pendings = this._pendings;
|
||||
|
||||
// If we have a handler for this type, we can't have any pending message.
|
||||
// If called from setMessageHandler, we still want to update the pending
|
||||
// queue to deliver existing messages.
|
||||
if (aType in this._handlers && !aForceUpdate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send a sync message to the parent to check if we have a pending message
|
||||
// for this type.
|
||||
let messages = cpmm.sendSyncMessage("SystemMessageManager:GetPendingMessages",
|
||||
{ type: aType,
|
||||
uri: this._uri,
|
||||
manifest: this._manifest })[0];
|
||||
if (!messages) {
|
||||
// No new pending messages, but the queue may not be empty yet.
|
||||
return pendings[aType] && pendings[aType].length != 0;
|
||||
}
|
||||
|
||||
if (!pendings[aType]) {
|
||||
pendings[aType] = [];
|
||||
}
|
||||
|
||||
// Doing that instead of pending.concat() to avoid array copy.
|
||||
messages.forEach(function hpm_addPendings(aMessage) {
|
||||
pendings[aType].push(aMessage);
|
||||
if (pendings[aType].length > kMaxPendingMessages) {
|
||||
pendings[aType].splice(0, 1);
|
||||
}
|
||||
});
|
||||
|
||||
return pendings[aType].length != 0;
|
||||
// Ask for the list of currently pending messages.
|
||||
cpmm.sendAsyncMessage("SystemMessageManager:GetPendingMessages",
|
||||
{ type: aType,
|
||||
uri: this._uri,
|
||||
manifest: this._manifest });
|
||||
},
|
||||
|
||||
mozHasPendingMessage: function sysMessMgr_hasPendingMessage(aType) {
|
||||
return this._getPendingMessages(aType, false);
|
||||
// If we have a handler for this type, we can't have any pending message.
|
||||
if (aType in this._handlers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return cpmm.sendSyncMessage("SystemMessageManager:HasPendingMessages",
|
||||
{ type: aType,
|
||||
uri: this._uri,
|
||||
manifest: this._manifest })[0];
|
||||
},
|
||||
|
||||
uninit: function sysMessMgr_uninit() {
|
||||
@ -170,22 +123,24 @@ SystemMessageManager.prototype = {
|
||||
|
||||
receiveMessage: function sysMessMgr_receiveMessage(aMessage) {
|
||||
debug("receiveMessage " + aMessage.name + " - " +
|
||||
aMessage.json.type + " for " + aMessage.json.manifest +
|
||||
aMessage.data.type + " for " + aMessage.data.manifest +
|
||||
" (" + this._manifest + ")");
|
||||
|
||||
let msg = aMessage.json;
|
||||
let msg = aMessage.data;
|
||||
if (msg.manifest != this._manifest || msg.uri != this._uri) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Send an acknowledgement to parent to clean up the pending message,
|
||||
// so a re-launched app won't handle it again, which is redundant.
|
||||
cpmm.sendAsyncMessage(
|
||||
"SystemMessageManager:Message:Return:OK",
|
||||
{ type: msg.type,
|
||||
manifest: msg.manifest,
|
||||
uri: msg.uri,
|
||||
msgID: msg.msgID });
|
||||
if (aMessage.name == "SystemMessageManager:Message") {
|
||||
// Send an acknowledgement to parent to clean up the pending message,
|
||||
// so a re-launched app won't handle it again, which is redundant.
|
||||
cpmm.sendAsyncMessage(
|
||||
"SystemMessageManager:Message:Return:OK",
|
||||
{ type: msg.type,
|
||||
manifest: msg.manifest,
|
||||
uri: msg.uri,
|
||||
msgID: msg.msgID });
|
||||
}
|
||||
|
||||
// Bail out if we have no handlers registered for this type.
|
||||
if (!(msg.type in this._handlers)) {
|
||||
@ -193,13 +148,20 @@ SystemMessageManager.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
this._dispatchMessage(msg.type, this._handlers[msg.type], msg.msg);
|
||||
let messages = (aMessage.name == "SystemMessageManager:Message")
|
||||
? [msg.msg]
|
||||
: msg.msgQueue;
|
||||
|
||||
messages.forEach(function(aMsg) {
|
||||
this._dispatchMessage(msg.type, this._handlers[msg.type], aMsg);
|
||||
}, this);
|
||||
},
|
||||
|
||||
// nsIDOMGlobalPropertyInitializer implementation.
|
||||
init: function sysMessMgr_init(aWindow) {
|
||||
debug("init");
|
||||
this.initHelper(aWindow, ["SystemMessageManager:Message"]);
|
||||
this.initHelper(aWindow, ["SystemMessageManager:Message",
|
||||
"SystemMessageManager:GetPendingMessages:Return"]);
|
||||
|
||||
let principal = aWindow.document.nodePrincipal;
|
||||
this._uri = principal.URI.spec;
|
||||
|
Loading…
x
Reference in New Issue
Block a user