Bug 831644 - Uninstalling an app while it's currently being downloading leaves Gaia's homescreen and download progress in a corrupted, out of sync state with the webapps registry r=julienw a=jst
authorFabrice Desré <fabrice@mozilla.com>
Thu, 24 Jan 2013 21:11:23 -0800
changeset 118328 c812891df52ff5c0b740399dc140f85f238d4a88
parent 118327 58c0eb12bf23cf6fd591ef18e47317cc6a6e46d1
child 118329 96ee8f2afd10cf8d984dc9bc057ff81db6fad39d
push id355
push userfdesre@mozilla.com
push dateFri, 25 Jan 2013 05:11:32 +0000
reviewersjulienw, jst
bugs831644
milestone18.0
Bug 831644 - Uninstalling an app while it's currently being downloading leaves Gaia's homescreen and download progress in a corrupted, out of sync state with the webapps registry r=julienw a=jst
dom/apps/src/Webapps.js
dom/apps/src/Webapps.jsm
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -644,16 +644,17 @@ WebappsApplicationMgmt.prototype = {
       return;
     }
 
     cpmm.sendAsyncMessage("Webapps:ApplyDownload",
                           { manifestURL: aApp.manifestURL });
   },
 
   uninstall: function(aApp) {
+    dump("-- webapps.js uninstall " + aApp.manifestURL + "\n");
     let request = this.createRequest();
     cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: aApp.origin,
                                                  oid: this._id,
                                                  requestID: this.getRequestId(request) });
     return request;
   },
 
   getAll: function() {
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -892,19 +892,23 @@ this.DOMApplicationRegistry = {
       debug("Could not find a download for " + aManifestURL);
       return;
     }
 
     let app = this.webapps[download.appId];
 
     if (download.cacheUpdate) {
       // Cancel hosted app download.
+      app.isCanceling = true;
       try {
         download.cacheUpdate.cancel();
-      } catch (e) { debug (e); }
+      } catch (e) {
+        delete app.isCanceling;
+        debug (e);
+      }
     } else if (download.channel) {
       // Cancel packaged app download.
       app.isCanceling = true;
       try {
         download.channel.cancel(Cr.NS_BINDING_ABORTED);
       } catch(e) {
         delete app.isCanceling;
       }
@@ -2240,25 +2244,32 @@ this.DOMApplicationRegistry = {
           return;
         }
       }
       download();
     }
   },
 
   uninstall: function(aData, aMm) {
+    debug("uninstall " + aData.origin);
     for (let id in this.webapps) {
       let app = this.webapps[id];
       if (app.origin != aData.origin) {
         continue;
       }
 
+      dump("-- webapps.js uninstall " + app.manifestURL + "\n");
+
       if (!app.removable)
         return;
 
+      // Check if we are downloading something for this app, and cancel the
+      // download if needed.
+      this.cancelDownload(app.manifestURL);
+
       // Clean up the deprecated manifest cache if needed.
       if (id in this._manifestCache) {
         delete this._manifestCache[id];
       }
 
       // Clear private data first.
       this._clearPrivateData(app.localId, false);
 
@@ -2711,32 +2722,41 @@ AppcacheObserver.prototype = {
       DOMApplicationRegistry.broadcastMessage("Webapps:OfflineCache",
                                               { manifest: app.manifestURL,
                                                 installState: app.installState,
                                                 progress: app.progress });
     }
 
     let setError = function appObs_setError(aError) {
       debug("Offlinecache setError to " + aError);
-      DOMApplicationRegistry.broadcastMessage("Webapps:OfflineCache",
-                                              { manifest: app.manifestURL,
-                                                error: aError });
+      // If we are canceling the download, we already send a DOWNLOAD_CANCELED
+      // error.
+      if (!app.isCanceling) {
+        DOMApplicationRegistry.broadcastMessage("Webapps:OfflineCache",
+                                                { manifest: app.manifestURL,
+                                                  error: aError });
+      } else {
+        delete app.isCanceling;
+      }
+
       app.downloading = false;
       app.downloadAvailable = false;
       mustSave = true;
     }
 
     switch (aState) {
       case Ci.nsIOfflineCacheUpdateObserver.STATE_ERROR:
         aUpdate.removeObserver(this);
+        AppDownloadManager.remove(app.manifestURL);
         setError("APP_CACHE_DOWNLOAD_ERROR");
         break;
       case Ci.nsIOfflineCacheUpdateObserver.STATE_NOUPDATE:
       case Ci.nsIOfflineCacheUpdateObserver.STATE_FINISHED:
         aUpdate.removeObserver(this);
+        AppDownloadManager.remove(app.manifestURL);
         setStatus("installed", aUpdate.byteProgress);
         break;
       case Ci.nsIOfflineCacheUpdateObserver.STATE_DOWNLOADING:
       case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMSTARTED:
         setStatus(this.startStatus, aUpdate.byteProgress);
         break;
       case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMPROGRESS:
         let now = Date.now();