Bug 903291 - Delay processing petitions from the DOM API until the application registry is ready r=fabrice

This commit is contained in:
Antonio M. Amaya 2014-07-14 23:27:57 +02:00
Родитель 4b9dbdaec6
Коммит bd4e685d55
3 изменённых файлов: 135 добавлений и 93 удалений

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

@ -174,8 +174,8 @@ this.DOMApplicationRegistry = {
}
for (let i = 0; i < apps.length; i++) {
let domApp = apps[i].get();
if (!domApp) {
apps.splice(i);
if (!domApp || domApp._window === null) {
apps.splice(i, 1);
continue;
}
domApp._proxy = new Proxy(domApp, {
@ -233,8 +233,9 @@ this.DOMApplicationRegistry = {
// Get rid of dead weak references.
for (let i = 0; i < apps.length; i++) {
if (!apps[i].get()) {
apps.splice(i);
let app = apps[i].get();
if (!app || app._window === null) {
apps.splice(i, 1);
}
}

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

@ -748,7 +748,6 @@ WebappsApplicationMgmt.prototype = {
},
uninstall: function(aApp) {
dump("-- webapps.js uninstall " + aApp.manifestURL + "\n");
let request = this.createRequest();
cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: aApp.origin,
manifestURL: aApp.manifestURL,

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

@ -179,6 +179,7 @@ this.DOMApplicationRegistry = {
}).bind(this));
cpmm.addMessageListener("Activities:Register:OK", this);
cpmm.addMessageListener("Activities:Register:KO", this);
Services.obs.addObserver(this, "xpcom-shutdown", false);
Services.obs.addObserver(this, "memory-pressure", false);
@ -275,9 +276,15 @@ this.DOMApplicationRegistry = {
return this._registryStarted.promise;
},
// The registry will be safe to clone when this promise is resolved.
_safeToClone: Promise.defer(),
// Notify we are done with registering apps and save a copy of the registry.
_registryReady: Promise.defer(),
notifyAppsRegistryReady: function notifyAppsRegistryReady() {
// Usually this promise will be resolved earlier, but just in case,
// resolve it here also.
this._safeToClone.resolve();
this._registryReady.resolve();
Services.obs.notifyObservers(this, "webapps-registry-ready", null);
this._saveApps();
@ -287,6 +294,10 @@ this.DOMApplicationRegistry = {
return this._registryReady.promise;
},
get safeToClone() {
return this._safeToClone.promise;
},
// Ensure that the .to property in redirects is a relative URL.
sanitizeRedirects: function sanitizeRedirects(aSource) {
if (!aSource) {
@ -962,6 +973,7 @@ this.DOMApplicationRegistry = {
this._registerInterAppConnections(manifest, app);
appsToRegister.push({ manifest: manifest, app: app });
});
this._safeToClone.resolve();
this._registerActivitiesForApps(appsToRegister, aRunUpdate);
});
},
@ -1089,88 +1101,114 @@ this.DOMApplicationRegistry = {
let mm = aMessage.target;
msg.mm = mm;
let processedImmediately = true;
// There are two kind of messages: the messages that only make sense once the
// registry is ready, and those that can (or have to) be treated as soon as
// they're received.
switch (aMessage.name) {
case "Webapps:Install": {
#ifdef MOZ_WIDGET_ANDROID
Services.obs.notifyObservers(mm, "webapps-runtime-install", JSON.stringify(msg));
#else
this.doInstall(msg, mm);
#endif
case "Activities:Register:KO":
dump("Activities didn't register correctly!");
case "Activities:Register:OK":
// Activities:Register:OK is special because it's one way the registryReady
// promise can be resolved.
// XXX: What to do when the activities registration failed? At this point
// just act as if nothing happened.
this.notifyAppsRegistryReady();
break;
}
case "Webapps:GetSelf":
this.getSelf(msg, mm);
case "Webapps:GetList":
// GetList is special because it's synchronous. So far so well, it's the
// only synchronous message, if we get more at some point they should get
// this treatment also.
return this.doGetList();
case "child-process-shutdown":
this.removeMessageListener(["Webapps:Internal:AllMessages"], mm);
break;
case "Webapps:Uninstall":
#ifdef MOZ_WIDGET_ANDROID
Services.obs.notifyObservers(mm, "webapps-runtime-uninstall", JSON.stringify(msg));
#else
this.doUninstall(msg, mm);
#endif
break;
case "Webapps:Launch":
this.doLaunch(msg, mm);
break;
case "Webapps:CheckInstalled":
this.checkInstalled(msg, mm);
break;
case "Webapps:GetInstalled":
this.getInstalled(msg, mm);
break;
case "Webapps:GetNotInstalled":
this.getNotInstalled(msg, mm);
break;
case "Webapps:GetAll":
this.doGetAll(msg, mm);
break;
case "Webapps:InstallPackage": {
#ifdef MOZ_WIDGET_ANDROID
Services.obs.notifyObservers(mm, "webapps-runtime-install-package", JSON.stringify(msg));
#else
this.doInstallPackage(msg, mm);
#endif
break;
}
case "Webapps:RegisterForMessages":
this.addMessageListener(msg.messages, msg.app, mm);
break;
case "Webapps:UnregisterForMessages":
this.removeMessageListener(msg, mm);
break;
case "child-process-shutdown":
this.removeMessageListener(["Webapps:Internal:AllMessages"], mm);
break;
case "Webapps:GetList":
return this.doGetList();
break;
case "Webapps:Download":
this.startDownload(msg.manifestURL);
break;
case "Webapps:CancelDownload":
this.cancelDownload(msg.manifestURL);
break;
case "Webapps:CheckForUpdate":
this.checkForUpdate(msg, mm);
break;
case "Webapps:ApplyDownload":
this.applyDownload(msg.manifestURL);
break;
case "Activities:Register:OK":
this.notifyAppsRegistryReady();
break;
case "Webapps:Install:Return:Ack":
this.onInstallSuccessAck(msg.manifestURL);
break;
case "Webapps:AddReceipt":
this.addReceipt(msg, mm);
break;
case "Webapps:RemoveReceipt":
this.removeReceipt(msg, mm);
break;
case "Webapps:ReplaceReceipt":
this.replaceReceipt(msg, mm);
break;
default:
processedImmediately = false;
}
if (processedImmediately) {
return;
}
// For all the rest (asynchronous), we wait till the registry is ready
// before processing the message.
this.registryReady.then( () => {
switch (aMessage.name) {
case "Webapps:Install": {
#ifdef MOZ_WIDGET_ANDROID
Services.obs.notifyObservers(mm, "webapps-runtime-install", JSON.stringify(msg));
#else
this.doInstall(msg, mm);
#endif
break;
}
case "Webapps:GetSelf":
this.getSelf(msg, mm);
break;
case "Webapps:Uninstall":
#ifdef MOZ_WIDGET_ANDROID
Services.obs.notifyObservers(mm, "webapps-runtime-uninstall", JSON.stringify(msg));
#else
this.doUninstall(msg, mm);
#endif
break;
case "Webapps:Launch":
this.doLaunch(msg, mm);
break;
case "Webapps:CheckInstalled":
this.checkInstalled(msg, mm);
break;
case "Webapps:GetInstalled":
this.getInstalled(msg, mm);
break;
case "Webapps:GetNotInstalled":
this.getNotInstalled(msg, mm);
break;
case "Webapps:GetAll":
this.doGetAll(msg, mm);
break;
case "Webapps:InstallPackage": {
#ifdef MOZ_WIDGET_ANDROID
Services.obs.notifyObservers(mm, "webapps-runtime-install-package", JSON.stringify(msg));
#else
this.doInstallPackage(msg, mm);
#endif
break;
}
case "Webapps:Download":
this.startDownload(msg.manifestURL);
break;
case "Webapps:CancelDownload":
this.cancelDownload(msg.manifestURL);
break;
case "Webapps:CheckForUpdate":
this.checkForUpdate(msg, mm);
break;
case "Webapps:ApplyDownload":
this.applyDownload(msg.manifestURL);
break;
case "Webapps:Install:Return:Ack":
this.onInstallSuccessAck(msg.manifestURL);
break;
case "Webapps:AddReceipt":
this.addReceipt(msg, mm);
break;
case "Webapps:RemoveReceipt":
this.removeReceipt(msg, mm);
break;
case "Webapps:ReplaceReceipt":
this.replaceReceipt(msg, mm);
break;
}
});
},
getAppInfo: function getAppInfo(aAppId) {
@ -1251,27 +1289,27 @@ this.DOMApplicationRegistry = {
doGetList: function() {
let tmp = [];
for (let id in this.webapps) {
tmp.push({ id: id });
}
let res = {};
let done = false;
this._readManifests(tmp).then(
function(manifests) {
manifests.forEach((item) => {
res[item.id] = item.manifest;
});
done = true;
// We allow cloning the registry when the local processing has been done.
this.safeToClone.then( () => {
for (let id in this.webapps) {
tmp.push({ id: id });
}
);
this._readManifests(tmp).then(
function(manifests) {
manifests.forEach((item) => {
res[item.id] = item.manifest;
});
done = true;
}
);
});
let thread = Services.tm.currentThread;
while (!done) {
//debug("before processNextEvent");
thread.processNextEvent(/* mayWait */ true);
//after("before processNextEvent");
}
return { webapps: this.webapps, manifests: res };
},
@ -3748,9 +3786,13 @@ this.DOMApplicationRegistry = {
},
doGetAll: function(aData, aMm) {
this.getAll(function (apps) {
aData.apps = apps;
aMm.sendAsyncMessage("Webapps:GetAll:Return:OK", aData);
// We can't do this until the registry is ready.
debug("doGetAll");
this.registryReady.then(() => {
this.getAll(function (apps) {
aData.apps = apps;
aMm.sendAsyncMessage("Webapps:GetAll:Return:OK", aData);
});
});
},