Bug 797803 - System Message API: System App fails to receive system messages. r=fabrice

This commit is contained in:
Gene Lian 2012-10-09 11:15:47 +08:00
parent 402b94937e
commit 8a7f74658e
2 changed files with 60 additions and 4 deletions

View File

@ -32,6 +32,7 @@ try {
const kMessages =["SystemMessageManager:GetPendingMessages",
"SystemMessageManager:Register",
"SystemMessageManager:Message:Return:OK",
"SystemMessageManager:AskReadyToRegister",
"child-process-shutdown"]
function debug(aMsg) {
@ -54,6 +55,8 @@ function SystemMessageInternal() {
kMessages.forEach(function(aMsg) {
ppmm.addMessageListener(aMsg, this);
}, this);
Services.obs.notifyObservers(this, "system-message-internal-ready", null);
}
SystemMessageInternal.prototype = {
@ -142,6 +145,9 @@ SystemMessageInternal.prototype = {
receiveMessage: function receiveMessage(aMessage) {
let msg = aMessage.json;
switch(aMessage.name) {
case "SystemMessageManager:AskReadyToRegister":
return true;
break;
case "SystemMessageManager:Register":
{
let manifest = msg.manifest;

View File

@ -13,6 +13,8 @@ Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
const kSystemMessageInternalReady = "system-message-internal-ready";
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsISyncMessageSender");
@ -39,6 +41,20 @@ function SystemMessageManager() {
// Pending messages for this page, keyed by message type.
this._pendings = {};
// Flag to specify if this process has already registered manifest.
this._registerManifestReady = false;
// Flag to determine this process is a parent or child process.
let appInfo = Cc["@mozilla.org/xre/app-info;1"];
this._isParentProcess =
!appInfo || appInfo.getService(Ci.nsIXULRuntime)
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
// An oberver to listen to whether the |SystemMessageInternal| is ready.
if (this._isParentProcess) {
Services.obs.addObserver(this, kSystemMessageInternalReady, false);
}
}
SystemMessageManager.prototype = {
@ -145,7 +161,11 @@ SystemMessageManager.prototype = {
uninit: function sysMessMgr_uninit() {
this._handlers = null;
this._pendings = null;
this._pendings = null;
if (this._isParentProcess) {
Services.obs.removeObserver(this, kSystemMessageInternalReady);
}
},
receiveMessage: function sysMessMgr_receiveMessage(aMessage) {
@ -187,15 +207,45 @@ SystemMessageManager.prototype = {
.getService(Ci.nsIAppsService);
this._manifest = appsService.getManifestURLByLocalId(principal.appId);
this._window = aWindow;
cpmm.sendAsyncMessage("SystemMessageManager:Register",
{ manifest: this._manifest });
// Two cases are valid to register the manifest for the current process:
// 1. This is asked by a child process (parent process must be ready).
// 2. Parent process has already constructed the |SystemMessageInternal|.
// Otherwise, delay to do it when the |SystemMessageInternal| is ready.
let readyToRegister = true;
if (this._isParentProcess) {
let ready = cpmm.sendSyncMessage(
"SystemMessageManager:AskReadyToRegister", null);
if (ready.length == 0 || !ready[0]) {
readyToRegister = false;
}
}
if (readyToRegister) {
this._registerManifest();
}
debug("done");
},
observe: function sysMessMgr_observe(aSubject, aTopic, aData) {
if (aTopic === kSystemMessageInternalReady) {
this._registerManifest();
}
},
_registerManifest: function sysMessMgr_registerManifest() {
if (!this._registerManifestReady) {
cpmm.sendAsyncMessage("SystemMessageManager:Register",
{ manifest: this._manifest });
this._registerManifestReady = true;
}
},
classID: Components.ID("{bc076ea0-609b-4d8f-83d7-5af7cbdc3bb2}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMNavigatorSystemMessages,
Ci.nsIDOMGlobalPropertyInitializer]),
Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsIObserver]),
classInfo: XPCOMUtils.generateCI({classID: Components.ID("{bc076ea0-609b-4d8f-83d7-5af7cbdc3bb2}"),
contractID: "@mozilla.org/system-message-manager;1",