Bug 1379420 - Introduce LocaleService::GetRegionalPrefsLocales. r?jfkthame draft
authorZibi Braniecki <zbraniecki@mozilla.com>
Sat, 08 Jul 2017 13:54:04 -0700
changeset 606453 7a827ffd240e84d9b391a48e47f26ae8894efeea
parent 606207 d6f2a893cd7a77cacbb1b139fff78d09c2f001e0
child 636766 c525fff39b294a8e87dfa9a539cff07da651dfaa
push id67700
push userbmo:gandalf@aviary.pl
push dateMon, 10 Jul 2017 23:18:11 +0000
reviewersjfkthame
bugs1379420
milestone56.0a1
Bug 1379420 - Introduce LocaleService::GetRegionalPrefsLocales. r?jfkthame In scenarios where users use OS in one locale set and the App in another, users should be able to chose which locale set to follow for regional preferences. This method should be used over getAppLocales for all cases where the locales are used to format regional preferences related items like calendars, dates, units etc. MozReview-Commit-ID: OOBYIZCKXE
intl/locale/LocaleService.cpp
intl/locale/LocaleService.h
intl/locale/mozILocaleService.idl
modules/libpref/init/all.js
--- a/intl/locale/LocaleService.cpp
+++ b/intl/locale/LocaleService.cpp
@@ -215,16 +215,28 @@ LocaleService::GetAppLocalesAsBCP47(nsTA
   for (uint32_t i = 0; i < mAppLocales.Length(); i++) {
     nsAutoCString locale(mAppLocales[i]);
     SanitizeForBCP47(locale);
     aRetVal.AppendElement(locale);
   }
 }
 
 void
+LocaleService::GetRegionalPrefsLocales(nsTArray<nsCString>& aRetVal)
+{
+  bool useOSLocales = Preferences::GetBool("intl.regional_prefs.use_os_locales", false);
+
+  if (useOSLocales && OSPreferences::GetInstance()->GetSystemLocales(aRetVal)) {
+    return;
+  }
+
+  GetAppLocalesAsBCP47(aRetVal);
+}
+
+void
 LocaleService::AssignAppLocales(const nsTArray<nsCString>& aAppLocales)
 {
   MOZ_ASSERT(!mIsServer, "This should only be called for LocaleService in client mode.");
 
   mAppLocales = aAppLocales;
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
     obs->NotifyObservers(nullptr, "intl:app-locales-changed", nullptr);
@@ -607,16 +619,33 @@ LocaleService::GetAppLocaleAsBCP47(nsACS
     NegotiateAppLocales(mAppLocales);
   }
   aRetVal = mAppLocales[0];
 
   SanitizeForBCP47(aRetVal);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+LocaleService::GetRegionalPrefsLocales(uint32_t* aCount, char*** aOutArray)
+{
+  AutoTArray<nsCString,10> rgLocales;
+
+  GetRegionalPrefsLocales(rgLocales);
+
+  *aCount = rgLocales.Length();
+  *aOutArray = static_cast<char**>(moz_xmalloc(*aCount * sizeof(char*)));
+
+  for (uint32_t i = 0; i < *aCount; i++) {
+    (*aOutArray)[i] = moz_xstrdup(rgLocales[i].get());
+  }
+
+  return NS_OK;
+}
+
 static LocaleService::LangNegStrategy
 ToLangNegStrategy(int32_t aStrategy)
 {
   switch (aStrategy) {
     case 1:
       return LocaleService::LangNegStrategy::Matching;
     case 2:
       return LocaleService::LangNegStrategy::Lookup;
--- a/intl/locale/LocaleService.h
+++ b/intl/locale/LocaleService.h
@@ -121,16 +121,36 @@ public:
    *   nsTArray<nsCString> appLocales;
    *   LocaleService::GetInstance()->GetAppLocalesAsLangTags(appLocales);
    *
    * (See mozILocaleService.idl for a JS-callable version of this.)
    */
   void GetAppLocalesAsLangTags(nsTArray<nsCString>& aRetVal);
   void GetAppLocalesAsBCP47(nsTArray<nsCString>& aRetVal);
 
+
+  /**
+   * Returns a list of locales to use for any regional specific operations
+   * like date formatting, calendars, unit formatting etc.
+   *
+   * The result is a ordered list of valid locale IDs and it should be
+   * used for all APIs that accept list of locales, like ECMA402 and L10n APIs.
+   *
+   * This API always returns at least one locale.
+   *
+   * Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"]
+   *
+   * Usage:
+   *   nsTArray<nsCString> rgLocales;
+   *   LocaleService::GetInstance()->GetRegionalPrefsLocales(rgLocales);
+   *
+   * (See mozILocaleService.idl for a JS-callable version of this.)
+   */
+  void GetRegionalPrefsLocales(nsTArray<nsCString>& aRetVal);
+
   /**
    * This method should only be called in the client mode.
    *
    * It replaces all the language negotiation and is supposed to be called
    * in order to bring the client LocaleService in sync with the server
    * LocaleService.
    *
    * Currently, it's called by the IPC code.
--- a/intl/locale/mozILocaleService.idl
+++ b/intl/locale/mozILocaleService.idl
@@ -78,16 +78,32 @@ interface mozILocaleService : nsISupport
    * (See LocaleService.h for a more C++-friendly version of this.)
    */
   void getAppLocalesAsLangTags([optional] out unsigned long aCount,
                                [retval, array, size_is(aCount)] out string aLocales);
   void getAppLocalesAsBCP47([optional] out unsigned long aCount,
                             [retval, array, size_is(aCount)] out string aLocales);
 
   /**
+   * Returns a list of locales to use for any regional specific operations
+   * like date formatting, calendars, unit formatting etc.
+   *
+   * The result is a ordered list of valid locale IDs and it should be
+   * used for all APIs that accept list of locales, like ECMA402 and L10n APIs.
+   *
+   * This API always returns at least one locale.
+   *
+   * Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"]
+   *
+   * (See LocaleService.h for a more C++-friendly version of this.)
+   */
+  void getRegionalPrefsLocales([optional] out unsigned long aCount,
+                        [retval, array, size_is(aCount)] out string aOutArray);
+
+  /**
    * Negotiates the best locales out of a ordered list of requested locales and
    * a list of available locales.
    *
    * Internally it uses the following naming scheme:
    *
    *  Requested - locales requested by the user
    *  Available - locales for which the data is available
    *  Supported - locales negotiated by the algorithm
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2181,16 +2181,20 @@ pref("converter.html2txt.always_include_
 pref("intl.accept_languages",               "chrome://global/locale/intl.properties");
 pref("intl.menuitems.alwaysappendaccesskeys","chrome://global/locale/intl.properties");
 pref("intl.menuitems.insertseparatorbeforeaccesskeys","chrome://global/locale/intl.properties");
 pref("intl.charset.detector",               "chrome://global/locale/intl.properties");
 pref("intl.charset.fallback.override",      "");
 pref("intl.charset.fallback.tld",           true);
 pref("intl.ellipsis",                       "chrome://global-platform/locale/intl.properties");
 pref("intl.locale.matchOS",                 false);
+// this pref allows user to request that all internationalization formatters
+// like date/time formatting, unit formatting, calendars etc. should use
+// OS locale set instead of the app locale set.
+pref("intl.regional_prefs.use_os_locales",  false);
 // fallback charset list for Unicode conversion (converting from Unicode)
 // currently used for mail send only to handle symbol characters (e.g Euro, trademark, smartquotes)
 // for ISO-8859-1
 pref("intl.fallbackCharsetList.ISO-8859-1", "windows-1252");
 pref("font.language.group",                 "chrome://global/locale/intl.properties");
 
 // Android-specific pref to use key-events-only mode for IME-unaware webapps.
 #ifdef MOZ_WIDGET_ANDROID