Bug 675252 - Check for locale updates before updating Fennec. r=mfinkle
authorWes Johnston <wjohnston@mozilla.com>
Mon, 15 Aug 2011 10:42:52 -0700
changeset 75288 083551a45a833bb34e8d0ef68e7fcbd49dee6851
parent 75287 bc3e24e625c2975847932af2f475dbf3fe408dca
child 75289 485f0838da930c169ee790875405dfc0760b754e
push id1218
push userwjohnston@mozilla.com
push dateMon, 15 Aug 2011 17:48:38 +0000
treeherdermozilla-inbound@083551a45a83 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs675252
milestone8.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 675252 - Check for locale updates before updating Fennec. r=mfinkle
mobile/components/UpdatePrompt.js
mobile/modules/LocaleRepository.jsm
--- a/mobile/components/UpdatePrompt.js
+++ b/mobile/components/UpdatePrompt.js
@@ -53,16 +53,26 @@ XPCOMUtils.defineLazyGetter(this, "gUpda
 XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function aus_gBrandBundle() {
   return Services.strings.createBundle("chrome://branding/locale/brand.properties");
 });
 
 XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function aus_gBrowserBundle() {
   return Services.strings.createBundle("chrome://browser/locale/browser.properties");
 });
 
+XPCOMUtils.defineLazyGetter(this, "AddonManager", function() {
+  Cu.import("resource://gre/modules/AddonManager.jsm");
+  return AddonManager;
+});
+
+XPCOMUtils.defineLazyGetter(this, "LocaleRepository", function() {
+  Cu.import("resource://gre/modules/LocaleRepository.jsm");
+  return LocaleRepository;
+});
+
 function getPref(func, preference, defaultValue) {
   try {
     return Services.prefs[func](preference);
   } catch (e) {}
   return defaultValue;
 }
 
 // -----------------------------------------------------------------------
@@ -187,23 +197,55 @@ UpdatePrompt.prototype = {
     let imageUrl = "";
     this._showNotification(aUpdate, title, text, imageUrl, "available");
   },
 
   showUpdateDownloaded: function UP_showUpdateDownloaded(aUpdate, aBackground) {
     if (!this._enabled)
       return;
 
+    // uninstall all installed locales
+    AddonManager.getAddonsByTypes(["locale"], (function (aAddons) {
+      if (aAddons.length > 0) {
+        let listener = this.getAddonListener(aUpdate, this);
+        AddonManager.addAddonListener(listener);  
+        aAddons.forEach(function(aAddon) {
+          listener._uninstalling.push(aAddon.id);
+          aAddon.uninstall();
+        }, this);
+      } else {
+        this._showDownloadedNotification(aUpdate);
+      }
+    }).bind(this));
+  },
+
+  _showDownloadedNotification: function UP_showDlNotification(aUpdate) {
     let stringsPrefix = "updateDownloaded_" + aUpdate.type + ".";
     let title = gUpdateBundle.formatStringFromName(stringsPrefix + "title", [aUpdate.name], 1);
     let text = gUpdateBundle.GetStringFromName(stringsPrefix + "text");
     let imageUrl = "";
     this._showNotification(aUpdate, title, text, imageUrl, "downloaded");
   },
 
+  _uninstalling: [],
+  _installing: [],
+  _currentUpdate: null,
+
+  _reinstallLocales: function UP_reinstallLocales(aUpdate, aListener, aPending) {
+    LocaleRepository.getLocales((function(aLocales) {
+      aLocales.forEach(function(aLocale, aIndex, aArray) {
+        let index = aPending.indexOf(aLocale.addon.id);
+        if (index > -1) {
+          aListener._installing.push(aLocale.addon.id);
+          aLocale.addon.install.install();
+        }
+      }, this);
+    }).bind(this), { buildID: aUpdate.buildID });
+  },
+
   showUpdateInstalled: function UP_showUpdateInstalled() {
     if (!this._enabled || !getPref("getBoolPref", "app.update.showInstalledUI", false))
       return;
 
     let title = gBrandBundle.GetStringFromName("brandShortName");
     let text = gUpdateBundle.GetStringFromName("installSuccess");
     let imageUrl = "";
     this._showNotification(aUpdate, title, text, imageUrl, "installed");
@@ -253,13 +295,44 @@ UpdatePrompt.prototype = {
   // When new data has been downloaded
   onProgress: function(request, context, progress, maxProgress) {
     this._updateDownloadProgress(progress, maxProgress);
   },
 
   // When we have new status text
   onStatus: function(request, context, status, statusText) {
     // NOT IMPL
+  },
+
+  // -------------------------------
+  // AddonListener
+  // -------------------------------
+  getAddonListener: function(aUpdate, aUpdatePrompt) {
+    return {
+      _installing: [],
+      _uninstalling: [],
+      onInstalling: function(aAddon, aNeedsRestart) {
+        let index = this._installing.indexOf(aAddon.id);
+        if (index > -1)
+          this._installing.splice(index, 1);
+    
+        if (this._installing.length == 0) {
+          aUpdatePrompt._showDownloadedNotification(aUpdate);
+          AddonManager.removeAddonListener(this);
+        }
+      },
+    
+      onUninstalling: function(aAddon, aNeedsRestart) {
+        let pending = [];
+        let index = this._uninstalling.indexOf(aAddon.id);
+        if (index > -1) {
+          pending.push(aAddon.id);
+          this._uninstalling.splice(index, 1);
+        }
+        if (this._uninstalling.length == 0)
+          aUpdatePrompt._reinstallLocales(aUpdate, this, pending);
+      }
+    }
   }
-  
+
 };
 
 const NSGetFactory = XPCOMUtils.generateNSGetFactory([UpdatePrompt]);
--- a/mobile/modules/LocaleRepository.jsm
+++ b/mobile/modules/LocaleRepository.jsm
@@ -77,24 +77,36 @@ var LocaleRepository = {
     return (textContent.length > 0) ? textContent : null;
   },
   
   _getDescendantTextContent: function _getDescendantTextContent(aElement, aTagName) {
     let descendant = this._getUniqueDescendant(aElement, aTagName);
     return (descendant != null) ? this._getTextContent(descendant) : null;
   },
 
-  getLocales: function getLocales(aCallback) {
-    if (!gServiceURL) {
+  getLocales: function getLocales(aCallback, aFilters) {
+    let url = gServiceURL;
+
+    if (!url) {
       aCallback([]);
       return;
     }
+
+    let buildID = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).QueryInterface(Ci.nsIXULRuntime).appBuildID;
+    if (aFilters) {
+      if (aFilters.buildID)
+        buildid = aFilters.buildID;
+    }
+    buildID = buildID.substring(0,4) + "-" + buildID.substring(4).replace(/\d{2}(?=\d)/g, "$&-");
+    url = url.replace(/%BUILDID_EXPANDED%/g, buildID);
+    url = Services.urlFormatter.formatURL(url);
+
     let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
     request.mozBackgroundRequest = true;
-    request.open("GET", gServiceURL, true);
+    request.open("GET", url, true);
     request.overrideMimeType("text/xml");
   
     let self = this;
     request.onreadystatechange = function () {
       if (request.readyState == 4) {
         if (request.status == 200) {
           self.log("---- got response")
           let documentElement = request.responseXML.documentElement;