Bug 1352343 - Bind LocaleService to react to OSPreferences `intl:system-locales-changed`. r?jfkthame draft
authorZibi Braniecki <zbraniecki@mozilla.com>
Thu, 05 Oct 2017 18:43:38 +0200
changeset 678624 30df702016a6266e23cceb14c843feb6c8ccc1ce
parent 677214 77a4c52e9987d2359969d7c478183b438b464744
child 678625 870688e801beb0b6181a37cd86da61bd48650df4
push id83984
push userbmo:gandalf@aviary.pl
push dateWed, 11 Oct 2017 17:32:13 +0000
reviewersjfkthame
bugs1352343
milestone58.0a1
Bug 1352343 - Bind LocaleService to react to OSPreferences `intl:system-locales-changed`. r?jfkthame MozReview-Commit-ID: Hnhun0bAVSr
intl/locale/LocaleService.cpp
--- a/intl/locale/LocaleService.cpp
+++ b/intl/locale/LocaleService.cpp
@@ -14,16 +14,18 @@
 #include "nsIObserverService.h"
 #include "nsIToolkitChromeRegistry.h"
 #include "nsStringEnumerator.h"
 #include "nsXULAppAPI.h"
 #include "nsZipArchive.h"
 
 #include "unicode/uloc.h"
 
+#define INTL_SYSTEM_LOCALES_CHANGED "intl:system-locales-changed"
+
 #define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
 #define SELECTED_LOCALE_PREF "general.useragent.locale"
 
 //XXX: This pref is used only by Android and we use it to emulate
 //     retrieving OS locale until we get proper hook into JNI in bug 1337078.
 #define ANDROID_OS_LOCALE_PREF "intl.locale.os"
 
 static const char* kObservedPrefs[] = {
@@ -170,26 +172,36 @@ LocaleService::GetInstance()
   if (!sInstance) {
     sInstance = new LocaleService(XRE_IsParentProcess());
 
     if (sInstance->IsServer()) {
       // We're going to observe for requested languages changes which come
       // from prefs.
       DebugOnly<nsresult> rv = Preferences::AddWeakObservers(sInstance, kObservedPrefs);
       MOZ_ASSERT(NS_SUCCEEDED(rv), "Adding observers failed.");
+
+      nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+      if (obs) {
+        obs->AddObserver(sInstance, INTL_SYSTEM_LOCALES_CHANGED, true);
+      }
     }
-    ClearOnShutdown(&sInstance);
+    ClearOnShutdown(&sInstance, ShutdownPhase::Shutdown);
   }
   return sInstance;
 }
 
 LocaleService::~LocaleService()
 {
   if (mIsServer) {
     Preferences::RemoveObservers(this, kObservedPrefs);
+
+    nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+    if (obs) {
+      obs->RemoveObserver(this, INTL_SYSTEM_LOCALES_CHANGED);
+    }
   }
 }
 
 void
 LocaleService::GetAppLocalesAsLangTags(nsTArray<nsCString>& aRetVal)
 {
   if (mAppLocales.IsEmpty()) {
     NegotiateAppLocales(mAppLocales);
@@ -265,44 +277,44 @@ LocaleService::GetAvailableLocales(nsTAr
   }
 
   aRetVal = mAvailableLocales;
   return true;
 }
 
 
 void
-LocaleService::OnAvailableLocalesChanged()
+LocaleService::AvailableLocalesChanged()
 {
   MOZ_ASSERT(mIsServer, "This should only be called in the server mode.");
   mAvailableLocales.Clear();
   // In the future we may want to trigger here intl:available-locales-changed
-  OnLocalesChanged();
+  LocalesChanged();
 }
 
 void
-LocaleService::OnRequestedLocalesChanged()
+LocaleService::RequestedLocalesChanged()
 {
   MOZ_ASSERT(mIsServer, "This should only be called in the server mode.");
 
   nsTArray<nsCString> newLocales;
   ReadRequestedLocales(newLocales);
 
   if (mRequestedLocales != newLocales) {
     mRequestedLocales = Move(newLocales);
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
       obs->NotifyObservers(nullptr, "intl:requested-locales-changed", nullptr);
     }
-    OnLocalesChanged();
+    LocalesChanged();
   }
 }
 
 void
-LocaleService::OnLocalesChanged()
+LocaleService::LocalesChanged()
 {
   MOZ_ASSERT(mIsServer, "This should only be called in the server mode.");
 
   // if mAppLocales has not been initialized yet, just return
   if (mAppLocales.IsEmpty()) {
     return;
   }
 
@@ -514,29 +526,34 @@ LocaleService::IsAppLocaleRTL()
 }
 
 NS_IMETHODIMP
 LocaleService::Observe(nsISupports *aSubject, const char *aTopic,
                       const char16_t *aData)
 {
   MOZ_ASSERT(mIsServer, "This should only be called in the server mode.");
 
-  NS_ConvertUTF16toUTF8 pref(aData);
+  if (!strcmp(aTopic, INTL_SYSTEM_LOCALES_CHANGED)) {
+    RequestedLocalesChanged();
+  } else {
+    NS_ConvertUTF16toUTF8 pref(aData);
 
-  // This is a temporary solution until we get bug 1337078 landed.
-  if (pref.EqualsLiteral(ANDROID_OS_LOCALE_PREF)) {
-    OSPreferences::GetInstance()->Refresh();
+    // This is a temporary solution until we get bug 1337078 landed.
+    if (pref.EqualsLiteral(ANDROID_OS_LOCALE_PREF)) {
+      OSPreferences::GetInstance()->Refresh();
+    }
+    // At the moment the only thing we're observing are settings indicating
+    // user requested locales.
+    if (pref.EqualsLiteral(MATCH_OS_LOCALE_PREF) ||
+        pref.EqualsLiteral(SELECTED_LOCALE_PREF) ||
+        pref.EqualsLiteral(ANDROID_OS_LOCALE_PREF)) {
+      RequestedLocalesChanged();
+    }
   }
-  // At the moment the only thing we're observing are settings indicating
-  // user requested locales.
-  if (pref.EqualsLiteral(MATCH_OS_LOCALE_PREF) ||
-      pref.EqualsLiteral(SELECTED_LOCALE_PREF) ||
-      pref.EqualsLiteral(ANDROID_OS_LOCALE_PREF)) {
-    OnRequestedLocalesChanged();
-  }
+
   return NS_OK;
 }
 
 bool
 LocaleService::LanguagesMatch(const nsCString& aRequested,
                               const nsCString& aAvailable)
 {
   return Locale(aRequested, true).LanguageMatches(Locale(aAvailable, true));