Bug 1126119 - Create SystemMessageCache and cache hasPendingMessage in content process. r=fabrice

This commit is contained in:
Kan-Ru Chen (陳侃如) 2015-02-11 11:18:32 +01:00
parent 92591b515d
commit 50b5ccd2c2
12 changed files with 167 additions and 24 deletions

View File

@ -594,6 +594,7 @@
@BINPATH@/components/SystemMessageInternal.js
@BINPATH@/components/SystemMessageManager.js
@BINPATH@/components/SystemMessageCache.js
@BINPATH@/components/SystemMessageManager.manifest
@BINPATH@/components/HCIEventTransactionSystemMessage.manifest
@BINPATH@/components/HCIEventTransactionSystemMessageConfigurator.js

View File

@ -579,6 +579,7 @@
@RESPATH@/components/TCPSocket.manifest
#ifdef MOZ_ACTIVITIES
@RESPATH@/components/SystemMessageCache.js
@RESPATH@/components/SystemMessageInternal.js
@RESPATH@/components/SystemMessageManager.js
@RESPATH@/components/SystemMessageManager.manifest

View File

@ -91,6 +91,7 @@
#include "nsAnonymousTemporaryFile.h"
#include "nsISpellChecker.h"
#include "nsClipboardProxy.h"
#include "nsISystemMessageCache.h"
#include "IHistory.h"
#include "nsNetUtil.h"
@ -530,6 +531,10 @@ InitOnContentProcessCreated()
PostForkPreload();
#endif
nsCOMPtr<nsISystemMessageCache> smc =
do_GetService("@mozilla.org/system-message-cache;1");
NS_WARN_IF(!smc);
// This will register cross-process observer.
mozilla::dom::time::InitializeDateCacheCleaner();
}

View File

@ -119,6 +119,7 @@
#include "nsISpellChecker.h"
#include "nsIStyleSheet.h"
#include "nsISupportsPrimitives.h"
#include "nsISystemMessagesInternal.h"
#include "nsITimer.h"
#include "nsIURIFixup.h"
#include "nsIWindowWatcher.h"
@ -1324,11 +1325,21 @@ ContentParent::ForwardKnownInfo()
#ifdef MOZ_WIDGET_GONK
InfallibleTArray<VolumeInfo> volumeInfo;
nsRefPtr<nsVolumeService> vs = nsVolumeService::GetSingleton();
if (vs) {
if (vs && !mIsForBrowser) {
vs->GetVolumesForIPC(&volumeInfo);
unused << SendVolumes(volumeInfo);
}
#endif /* MOZ_WIDGET_GONK */
nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
do_GetService("@mozilla.org/system-message-internal;1");
if (systemMessenger && !mIsForBrowser) {
nsCOMPtr<nsIURI> manifestURI;
nsresult rv = NS_NewURI(getter_AddRefs(manifestURI), mAppManifestURL);
if (NS_SUCCEEDED(rv)) {
systemMessenger->RefreshCache(mMessageManager, manifestURI);
}
}
}
namespace {

View File

@ -0,0 +1,84 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsISyncMessageSender");
function debug(aMsg) {
// dump("-- SystemMessageCache " + Date.now() + " : " + aMsg + "\n");
}
const kMessages = ["SystemMessageCache:RefreshCache"];
function SystemMessageCache() {
debug("init");
this._pagesCache = [];
dump("SystemMessageCache: init");
Services.obs.addObserver(this, "xpcom-shutdown", false);
kMessages.forEach(function(aMessage) {
cpmm.addMessageListener(aMessage, this);
}, this);
}
SystemMessageCache.prototype = {
observe: function(aSubject, aTopic, aData) {
switch (aTopic) {
case "xpcom-shutdown":
debug("received xpcom-shutdown");
kMessages.forEach(function(aMessage) {
cpmm.removeMessageListener(aMessage, this);
}, this);
Services.obs.removeObserver(this, "xpcom-shutdown");
cpmm = null;
break;
default:
break;
}
},
receiveMessage: function(aMessage) {
switch (aMessage.name) {
case "SystemMessageCache:RefreshCache":
this._pagesCache = aMessage.data;
debug("received RefreshCache");
break;
default:
debug("received unknown message " + aMessage.name);
break;
}
},
hasPendingMessage: function(aType, aPageURL, aManifestURL) {
let hasMessage = this._pagesCache.some(function(aPage) {
if (aPage.type === aType &&
aPage.pageURL === aPageURL &&
aPage.manifestURL === aManifestURL) {
return true;
}
return false;
}, this);
debug("hasPendingMessage " + aType + " " + aPageURL + " " +
aManifestURL + ": " + hasMessage);
return hasMessage;
},
classID: Components.ID("{5a19d86a-21e5-4ac8-9634-8c364c73f87f}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessageCache,
Ci.nsIMessageListener,
Ci.nsIObserver])
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SystemMessageCache]);

View File

@ -40,14 +40,13 @@ try {
}
const kMessages =["SystemMessageManager:GetPendingMessages",
"SystemMessageManager:HasPendingMessages",
"SystemMessageManager:Register",
"SystemMessageManager:Unregister",
"SystemMessageManager:Message:Return:OK",
"SystemMessageManager:AskReadyToRegister",
"SystemMessageManager:HandleMessagesDone",
"SystemMessageManager:HandleMessageDone",
"child-process-shutdown"]
"child-process-shutdown"];
function debug(aMsg) {
// dump("-- SystemMessageInternal " + Date.now() + " : " + aMsg + "\n");
@ -178,6 +177,19 @@ SystemMessageInternal.prototype = {
return page;
},
_findCacheForApp: function(aManifestURL) {
let cache = [];
this._pages.forEach(function(aPage) {
if (aPage.manifestURL === aManifestURL &&
aPage.pendingMessages.length != 0) {
cache.push({ type: aPage.type,
pageURL: aPage.pageURL,
manifestURL: aPage.manifestURL });
}
});
return cache;
},
sendMessage: function(aType, aMessage, aPageURI, aManifestURI, aExtra) {
return new Promise((aResolve, aReject) => {
this.sendMessageInternal(aType, aMessage, aPageURI, aManifestURI, aExtra,
@ -349,6 +361,18 @@ SystemMessageInternal.prototype = {
pendingMessages: [] });
},
refreshCache: function(aChildMM, aManifestURI) {
if (!aManifestURI) {
throw Cr.NS_ERROR_INVALID_ARG;
}
this._refreshCacheInternal(aChildMM, aManifestURI.spec);
},
_refreshCacheInternal: function(aChildMM, aManifestURL) {
let cache = this._findCacheForApp(aManifestURL);
aChildMM.sendAsyncMessage("SystemMessageCache:RefreshCache", cache);
},
_findTargetIndex: function(aTargets, aTarget) {
if (!aTargets || !aTarget) {
return -1;
@ -417,7 +441,6 @@ SystemMessageInternal.prototype = {
// TODO: fix bug 988142 to re-enable.
// "SystemMessageManager:Unregister",
"SystemMessageManager:GetPendingMessages",
"SystemMessageManager:HasPendingMessages",
"SystemMessageManager:Message:Return:OK",
"SystemMessageManager:HandleMessagesDone",
"SystemMessageManager:HandleMessageDone"].indexOf(aMessage.name) != -1) {
@ -456,6 +479,7 @@ SystemMessageInternal.prototype = {
}
}
this._refreshCacheInternal(aMessage.target, msg.manifestURL);
debug("listeners for " + msg.manifestURL +
" innerWinID " + msg.innerWindowID);
break;
@ -514,21 +538,7 @@ SystemMessageInternal.prototype = {
manifestURL: msg.manifestURL,
pageURL: msg.pageURL,
msgQueue: pendingMessages });
break;
}
case "SystemMessageManager:HasPendingMessages":
{
debug("received SystemMessageManager:HasPendingMessages " + msg.type +
" for " + msg.pageURL + " @ " + msg.manifestURL);
// 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 = this._findPage(msg.type, msg.pageURL, msg.manifestURL);
if (!page) {
return false;
}
return page.pendingMessages.length != 0;
this._refreshCacheInternal(aMessage.target, msg.manifestURL);
break;
}
case "SystemMessageManager:Message:Return:OK":
@ -697,7 +707,7 @@ SystemMessageInternal.prototype = {
_isPageMatched: function(aPage, aType, aPageURL, aManifestURL) {
return (aPage.type === aType &&
aPage.manifestURL === aManifestURL &&
aPage.pageURL === aPageURL)
aPage.pageURL === aPageURL);
},
_createKeyForPage: function _createKeyForPage(aPage) {

View File

@ -193,10 +193,16 @@ SystemMessageManager.prototype = {
return false;
}
return cpmm.sendSyncMessage("SystemMessageManager:HasPendingMessages",
{ type: aType,
pageURL: this._pageURL,
manifestURL: this._manifestURL })[0];
/*
* NB: If the system message is fired after we received the cache
* and before we registered the pageURL we will get false
* negative however this is unlikely and will do no harm.
*/
let cache = Cc["@mozilla.org/system-message-cache;1"]
.getService(Ci.nsISystemMessageCache);
return cache.hasPendingMessage(aType, this._pageURL, this._manifestURL);
},
mozIsHandlingMessage: function() {

View File

@ -3,3 +3,6 @@ contract @mozilla.org/system-message-manager;1 {bc076ea0-609b-4d8f-83d7-5af7cbdc
component {70589ca5-91ac-4b9e-b839-d6a88167d714} SystemMessageInternal.js
contract @mozilla.org/system-message-internal;1 {70589ca5-91ac-4b9e-b839-d6a88167d714}
component {5a19d86a-21e5-4ac8-9634-8c364c73f87f} SystemMessageCache.js
contract @mozilla.org/system-message-cache;1 {5a19d86a-21e5-4ac8-9634-8c364c73f87f}

View File

@ -6,6 +6,7 @@
XPIDL_SOURCES += [
'nsIDOMNavigatorSystemMessages.idl',
'nsISystemMessageCache.idl',
'nsISystemMessageGlue.idl',
'nsISystemMessagesInternal.idl',
]

View File

@ -0,0 +1,13 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, uuid(e888447c-6d4d-4045-92bd-1a5985404375)]
interface nsISystemMessageCache : nsISupports
{
boolean hasPendingMessage(in DOMString type,
in DOMString pageURL,
in DOMString manifestURL);
};

View File

@ -6,6 +6,7 @@
interface nsIURI;
interface nsIDOMWindow;
interface nsIMessageSender;
// Implemented by the contract id @mozilla.org/system-message-internal;1
@ -45,6 +46,12 @@ interface nsISystemMessagesInternal : nsISupports
* @param manifestURI The webapp's manifest URI.
*/
void registerPage(in DOMString type, in nsIURI pageURI, in nsIURI manifestURI);
/*
* Refresh the system message cache in a content process.
* @param manifestURI The webapp's manifest URI.
*/
void refreshCache(in nsIMessageSender childMM, in nsIURI manifestURI);
};
[scriptable, uuid(002f0e82-91f0-41de-ad43-569a2b9d12df)]

View File

@ -7,6 +7,7 @@
DIRS += ['interfaces']
EXTRA_COMPONENTS += [
'SystemMessageCache.js',
'SystemMessageInternal.js',
'SystemMessageManager.js',
'SystemMessageManager.manifest',