Bug 597296 - Chrome registry selected locale should not changed immediatly [r=bsmedberg,glandium, a=blocking-fennec]
authorVivien Nicolas <21@vingtetun.org>
Tue, 30 Nov 2010 15:02:23 +0100
changeset 58368 a5d48a5d46cd9bc2af836eefc4cd401abbdf21b4
parent 58367 2789b87e8cba8cc181a34bbfadfd0da5ab6b37c4
child 58369 02a136225ccb56f024763c284d27a59e5f1a7dbc
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersbsmedberg, glandium, blocking-fennec
bugs597296
milestone2.0b8pre
Bug 597296 - Chrome registry selected locale should not changed immediatly [r=bsmedberg,glandium, a=blocking-fennec]
chrome/src/nsChromeRegistry.cpp
chrome/src/nsChromeRegistry.h
chrome/src/nsChromeRegistryChrome.cpp
chrome/src/nsChromeRegistryChrome.h
chrome/src/nsChromeRegistryContent.cpp
chrome/src/nsChromeRegistryContent.h
chrome/test/unit/data/test_bug519468.manifest
chrome/test/unit/test_bug519468.js
--- a/chrome/src/nsChromeRegistry.cpp
+++ b/chrome/src/nsChromeRegistry.cpp
@@ -551,16 +551,17 @@ nsChromeRegistry::FlushAllCaches()
   obsSvc->NotifyObservers((nsIChromeRegistry*) this,
                           NS_CHROME_FLUSH_TOPIC, nsnull);
 }  
 
 // xxxbsmedberg Move me to nsIWindowMediator
 NS_IMETHODIMP
 nsChromeRegistry::ReloadChrome()
 {
+  UpdateSelectedLocale();
   FlushAllCaches();
   // Do a reload of all top level windows.
   nsresult rv = NS_OK;
 
   // Get the window mediator
   nsCOMPtr<nsIWindowMediator> windowMediator
     (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
   if (windowMediator) {
--- a/chrome/src/nsChromeRegistry.h
+++ b/chrome/src/nsChromeRegistry.h
@@ -109,16 +109,20 @@ public:
   static nsChromeRegistry* gChromeRegistry;
 
   static nsresult Canonify(nsIURL* aChromeURL);
 
 protected:
   void FlushSkinCaches();
   void FlushAllCaches();
 
+  // Update the selected locale used by the chrome registry, and fire a
+  // notification about this change
+  virtual void UpdateSelectedLocale() = 0;
+
   static void LogMessage(const char* aMsg, ...);
   static void LogMessageWithContext(nsIURI* aURL, PRUint32 aLineNumber, PRUint32 flags,
                                     const char* aMsg, ...);
 
   virtual nsIURI* GetBaseURIFromPackage(const nsCString& aPackage,
                                         const nsCString& aProvider,
                                         const nsCString& aPath) = 0;
   virtual nsresult GetFlagsFromPackage(const nsCString& aPackage,
--- a/chrome/src/nsChromeRegistryChrome.cpp
+++ b/chrome/src/nsChromeRegistryChrome.cpp
@@ -345,16 +345,19 @@ nsChromeRegistryChrome::SelectLocaleFrom
   else {
     nsXPIDLCString provider;
     rv = prefs->GetCharPref(SELECTED_LOCALE_PREF, getter_Copies(provider));
     if (NS_SUCCEEDED(rv)) {
       mSelectedLocale = provider;
     }
   }
 
+  if (NS_FAILED(rv))
+    NS_ERROR("Couldn't select locale from pref!");
+
   return rv;
 }
 
 NS_IMETHODIMP
 nsChromeRegistryChrome::Observe(nsISupports *aSubject, const char *aTopic,
                                 const PRUnichar *someData)
 {
   nsresult rv = NS_OK;
@@ -362,25 +365,28 @@ nsChromeRegistryChrome::Observe(nsISuppo
   if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
     nsCOMPtr<nsIPrefBranch> prefs (do_QueryInterface(aSubject));
     NS_ASSERTION(prefs, "Bad observer call!");
 
     NS_ConvertUTF16toUTF8 pref(someData);
 
     if (pref.EqualsLiteral(MATCH_OS_LOCALE_PREF) ||
         pref.EqualsLiteral(SELECTED_LOCALE_PREF)) {
-      rv = SelectLocaleFromPref(prefs);
-      if (NS_SUCCEEDED(rv) && mProfileLoaded)
-        FlushAllCaches();
+      if (!mProfileLoaded) {
+        rv = SelectLocaleFromPref(prefs);
+        if (NS_FAILED(rv))
+          return rv;
+      }
+      FlushAllCaches();
     }
     else if (pref.EqualsLiteral(SELECTED_SKIN_PREF)) {
       nsXPIDLCString provider;
       rv = prefs->GetCharPref(pref.get(), getter_Copies(provider));
       if (NS_FAILED(rv)) {
-        NS_ERROR("Couldn't get new locale pref!");
+        NS_ERROR("Couldn't get new skin pref!");
         return rv;
       }
 
       mSelectedSkin = provider;
       RefreshSkins();
     } else {
       NS_ERROR("Unexpected pref!");
     }
@@ -456,16 +462,31 @@ EnumerateOverride(nsIURI* aURIKey,
 
 struct EnumerationArgs
 {
   InfallibleTArray<ChromePackage>& packages;
   const nsCString& selectedLocale;
   const nsCString& selectedSkin;
 };
 
+void nsChromeRegistryChrome::UpdateSelectedLocale()
+{
+  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
+  if (prefs) {
+    nsresult rv = SelectLocaleFromPref(prefs);
+    if (NS_SUCCEEDED(rv)) {
+      nsCOMPtr<nsIObserverService> obsSvc =
+        mozilla::services::GetObserverService();
+      NS_ASSERTION(obsSvc, "Couldn't get observer service.");
+      obsSvc->NotifyObservers((nsIChromeRegistry*) this,
+                              "selected-locale-has-changed", nsnull);
+    }
+  }
+}
+
 void
 nsChromeRegistryChrome::SendRegisteredChrome(
     mozilla::dom::PContentParent* aParent)
 {
   InfallibleTArray<ChromePackage> packages;
   InfallibleTArray<ResourceMapping> resources;
   InfallibleTArray<OverrideMapping> overrides;
 
--- a/chrome/src/nsChromeRegistryChrome.h
+++ b/chrome/src/nsChromeRegistryChrome.h
@@ -82,16 +82,17 @@ class nsChromeRegistryChrome : public ns
  private:
 #ifdef MOZ_IPC
   static PLDHashOperator CollectPackages(PLDHashTable *table,
                                          PLDHashEntryHdr *entry,
                                          PRUint32 number, void *arg);
 #endif
 
   nsresult SelectLocaleFromPref(nsIPrefBranch* prefs);
+  NS_OVERRIDE void UpdateSelectedLocale();
   NS_OVERRIDE nsIURI* GetBaseURIFromPackage(const nsCString& aPackage,
                                              const nsCString& aProvider,
                                              const nsCString& aPath);
   NS_OVERRIDE nsresult GetFlagsFromPackage(const nsCString& aPackage,
                                            PRUint32* aFlags);
 
   static const PLDHashTableOps kTableOps;
   static PLDHashNumber HashKey(PLDHashTable *table, const void *key);
--- a/chrome/src/nsChromeRegistryContent.cpp
+++ b/chrome/src/nsChromeRegistryContent.cpp
@@ -262,16 +262,21 @@ nsChromeRegistryContent::GetStyleOverlay
 
 NS_IMETHODIMP
 nsChromeRegistryContent::GetXULOverlays(nsIURI *aChromeURL,
                                         nsISimpleEnumerator **aResult)
 {
   CONTENT_NOT_IMPLEMENTED();
 }
 
+void nsChromeRegistryContent::UpdateSelectedLocale()
+{
+  CONTENT_NOTREACHED();
+}
+
 void
 nsChromeRegistryContent::ManifestContent(ManifestProcessingContext& cx,
                                          int lineno, char *const * argv,
                                          bool platform, bool contentaccessible)
 {
   CONTENT_NOTREACHED();
 }
 
--- a/chrome/src/nsChromeRegistryContent.h
+++ b/chrome/src/nsChromeRegistryContent.h
@@ -83,16 +83,17 @@ class nsChromeRegistryContent : public n
     nsCOMPtr<nsIURI> skinBaseURI;
     PRUint32         flags;
   };
   
   void RegisterPackage(const ChromePackage& aPackage);
   void RegisterResource(const ResourceMapping& aResource);
   void RegisterOverride(const OverrideMapping& aOverride);
 
+  NS_OVERRIDE void UpdateSelectedLocale();
   NS_OVERRIDE nsIURI* GetBaseURIFromPackage(const nsCString& aPackage,
                                  const nsCString& aProvider,
                                  const nsCString& aPath);
   NS_OVERRIDE nsresult GetFlagsFromPackage(const nsCString& aPackage, PRUint32* aFlags);
 
   nsClassHashtable<nsCStringHashKey, PackageEntry> mPackagesHash;
 
   virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
--- a/chrome/test/unit/data/test_bug519468.manifest
+++ b/chrome/test/unit/data/test_bug519468.manifest
@@ -1,2 +1,3 @@
 locale testmatchos en-US jar:en-US.jar!/locale/en-US/global/
 locale testmatchos fr-FR jar:en-US.jar!/locale/en-US/global/
+locale testmatchos de-DE jar:en-US.jar!/locale/en-US/global/
--- a/chrome/test/unit/test_bug519468.js
+++ b/chrome/test/unit/test_bug519468.js
@@ -35,47 +35,61 @@
  *
  * ***** END LICENSE BLOCK *****
  */
 
 var MANIFESTS = [
   do_get_file("data/test_bug519468.manifest")
 ];
 
+do_test_pending()
 registerManifests(MANIFESTS);
 
 var chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]
                 .getService(Ci.nsIXULChromeRegistry)
                 .QueryInterface(Ci.nsIToolkitChromeRegistry);
 chromeReg.checkForNewChrome();
 
 var localeService = Cc["@mozilla.org/intl/nslocaleservice;1"]
                     .getService(Ci.nsILocaleService);
 
 var prefService = Cc["@mozilla.org/preferences-service;1"]
                   .getService(Ci.nsIPrefService)
                   .QueryInterface(Ci.nsIPrefBranch);
+var os = Cc["@mozilla.org/observer-service;1"]
+         .getService(Ci.nsIObserverService);
+
+var systemLocale = localeService.getLocaleComponentForUserAgent();
+var count = 0;
+var testsLocale = [
+  {matchOS: false, selected: null, locale: "en-US"},
+  {matchOS: true, selected: null, locale: systemLocale},
+  {matchOS: true, selected: "fr-FR", locale: systemLocale},
+  {matchOS: false, selected: "fr-FR", locale: "fr-FR"},
+  {matchOS: false, selected: "de-DE", locale: "de-DE"},
+  {matchOS: true, selected: null, locale: systemLocale}
+];
 
 function test_locale(aTest) {
   prefService.setBoolPref("intl.locale.matchOS", aTest.matchOS);
   prefService.setCharPref("general.useragent.locale", aTest.selected || "en-US");
 
-  var selectedLocale = chromeReg.getSelectedLocale("testmatchos");
-  do_check_eq(selectedLocale, aTest.locale);
+  chromeReg.reloadChrome();
 }
 
-function run_test()
-{
-  var systemLocale = localeService.getLocaleComponentForUserAgent();
+function checkValidity() {
+  var selectedLocale = chromeReg.getSelectedLocale("testmatchos");
+  do_check_eq(selectedLocale, testsLocale[count].locale);
 
-  var tests = [
-    {matchOS: false, selected: null, locale: "en-US"},
-    {matchOS: true, selected: null, locale: systemLocale},
-    {matchOS: true, selected: "fr-FR", locale: systemLocale},
-    {matchOS: false, selected: "fr-FR", locale: "fr-FR"},
-    {matchOS: true, selected: null, locale: systemLocale}
-  ];
-
-  for (var i = 0; i < tests.length; ++ i) {
-    var test = tests[i];
-    test_locale(test);
+  count++;
+  if (count >= testsLocale.length) {
+    os.removeObserver(checkValidity, "selected-locale-has-changed");
+    do_test_finished();
+  }
+  else {
+    test_locale(testsLocale[count]);
   }
 }
+
+function run_test() {
+  os.addObserver(checkValidity, "selected-locale-has-changed", false);
+  test_locale(testsLocale[count]);
+}