Bug 782766 - [WebActivities] support blobs - Part 1: System Messages changes [r=gene]

--HG--
extra : rebase_source : bff9c5c4745493b652a6218a60d5840e09f7235e
This commit is contained in:
Fabrice Desré 2012-10-25 11:45:14 -07:00
Родитель 7ec18def70
Коммит 0e5313830a
5 изменённых файлов: 118 добавлений и 90 удалений

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

@ -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;