Bug 784378 - 'Apps API - Clear Private Data'. r=jlebar.

This commit is contained in:
Ben Turner 2012-09-26 15:03:25 -07:00
parent 828bac4ca2
commit 76576b59c1
6 changed files with 118 additions and 1 deletions

View File

@ -12,6 +12,7 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
@ -319,6 +320,14 @@ WebappsApplication.prototype = {
return request;
},
clearBrowserData: function() {
let browserChild =
BrowserElementPromptService.getBrowserElementChildForWindow(this._window);
if (browserChild) {
browserChild.messageManager.sendAsyncMessage("Webapps:ClearBrowserData");
}
},
uninit: function() {
this._onprogress = null;
cpmm.sendAsyncMessage("Webapps:UnregisterForMessages",

View File

@ -63,6 +63,8 @@ let DOMApplicationRegistry = {
"Webapps:GetList", "Webapps:RegisterForMessages",
"Webapps:UnregisterForMessages"];
this.frameMessages = ["Webapps:ClearBrowserData"];
this.messages.forEach((function(msgName) {
ppmm.addMessageListener(msgName, this);
}).bind(this));
@ -1136,6 +1138,79 @@ let DOMApplicationRegistry = {
return true;
#endif
},
_notifyCategoryAndObservers: function(subject, topic, data) {
const serviceMarker = "service,";
// First create observers from the category manager.
let cm =
Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
let enumerator = cm.enumerateCategory(topic);
let observers = [];
while (enumerator.hasMoreElements()) {
let entry =
enumerator.getNext().QueryInterface(Ci.nsISupportsCString).data;
let contractID = cm.getCategoryEntry(topic, entry);
let factoryFunction;
if (contractID.substring(0, serviceMarker.length) == serviceMarker) {
contractID = contractID.substring(serviceMarker.length);
factoryFunction = "getService";
}
else {
factoryFunction = "createInstance";
}
try {
let handler = Cc[contractID][factoryFunction]();
if (handler) {
let observer = handler.QueryInterface(Ci.nsIObserver);
observers.push(observer);
}
} catch(e) { }
}
// Next enumerate the registered observers.
enumerator = Services.obs.enumerateObservers(topic);
while (enumerator.hasMoreElements()) {
let observer = enumerator.getNext();
if (observers.indexOf(observer) == -1) {
observers.push(observer);
}
}
observers.forEach(function (observer) {
try {
observer.observe(subject, topic, data);
} catch(e) { }
});
},
registerBrowserElementParentForApp: function(bep, appId) {
let mm = bep._mm;
// Make a listener function that holds on to this appId.
let listener = this.receiveAppMessage.bind(this, appId);
this.frameMessages.forEach(function(msgName) {
mm.addMessageListener(msgName, listener);
});
},
receiveAppMessage: function(appId, message) {
switch (message.name) {
case "Webapps:ClearBrowserData":
let subject = {
appId: appId,
browserOnly: true,
QueryInterface: XPCOMUtils.generateQI([Ci.mozIApplicationClearPrivateDataParams])
};
this._notifyCategoryAndObservers(subject, "webapps-clear-data", null);
break;
}
}
};

View File

@ -675,6 +675,18 @@ BrowserElementChild.prototype = {
onProgressChange: function(webProgress, request, curSelfProgress,
maxSelfProgress, curTotalProgress, maxTotalProgress) {},
},
// Expose the message manager for WebApps and others.
_messageManagerPublic: {
sendAsyncMessage: global.sendAsyncMessage.bind(global),
sendSyncMessage: global.sendSyncMessage.bind(global),
addMessageListener: global.addMessageListener.bind(global),
removeMessageListener: global.removeMessageListener.bind(global)
},
get messageManager() {
return this._messageManagerPublic;
}
};
var api = new BrowserElementChild();

View File

@ -13,6 +13,11 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
XPCOMUtils.defineLazyGetter(this, "DOMApplicationRegistry", function () {
Cu.import("resource://gre/modules/Webapps.jsm");
return DOMApplicationRegistry;
});
const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
const BROWSER_FRAMES_ENABLED_PREF = "dom.mozBrowserFramesEnabled";
const TOUCH_EVENTS_ENABLED_PREF = "dom.w3c_touch_events.enabled";
@ -250,6 +255,18 @@ function BrowserElementParent(frameLoader, hasRemoteFrame) {
// Insert ourself into the prompt service.
BrowserElementPromptService.mapFrameToBrowserElementParent(this._frameElement, this);
// If this browser represents an app then let the Webapps module register for
// any messages that it needs.
let appManifestURL =
this._frameElement.QueryInterface(Ci.nsIMozBrowserFrame).appManifestURL;
if (appManifestURL) {
let appId =
DOMApplicationRegistry.getAppLocalIdByManifestURL(appManifestURL);
if (appId != Ci.nsIScriptSecurityManager.NO_APP_ID) {
DOMApplicationRegistry.registerBrowserElementParentForApp(this, appId);
}
}
}
BrowserElementParent.prototype = {

View File

@ -16,6 +16,7 @@ GRE_MODULE = 1
XPIDLSRCS = \
mozIApplication.idl \
mozIApplicationClearPrivateDataParams.idl \
nsIDOMApplicationRegistry.idl \
nsIDOMApplicationRegistry2.idl \
nsIAppsService.idl \

View File

@ -8,7 +8,7 @@
interface nsIDOMDOMRequest;
interface nsIArray;
[scriptable, uuid(e3649c1d-c950-495e-b0ed-6ce40be9743b)]
[scriptable, uuid(738360f5-19ad-456a-a477-cdbc250e1718)]
interface mozIDOMApplication : nsISupports
{
readonly attribute jsval manifest;
@ -41,6 +41,9 @@ interface mozIDOMApplication : nsISupports
/* startPoint will be used when several launch_path exists for an app */
nsIDOMDOMRequest launch([optional] in DOMString startPoint);
nsIDOMDOMRequest uninstall();
/* Clear data that has been collected through mozbrowser elements. */
void clearBrowserData();
};
[scriptable, uuid(4c36ca48-841e-4d5a-8c46-dda14ac633ca)]