Bug 1347002 - Add LocaleService::GetAvailableLocales. r?jfkthame draft
authorZibi Braniecki <gandalf@mozilla.com>
Mon, 13 Mar 2017 17:33:24 -0700
changeset 503019 ce49c6f915326f4a4b4ed0266f05c7f98ae36fdf
parent 503014 eed2a089da94eab4970f367cebbd5bfeffad88f6
child 550308 5be3ab44f6ade2e7b19ed4850cef183faa6fc205
push id50454
push userzbraniecki@mozilla.com
push dateWed, 22 Mar 2017 17:10:52 +0000
reviewersjfkthame
bugs1347002
milestone55.0a1
Bug 1347002 - Add LocaleService::GetAvailableLocales. r?jfkthame MozReview-Commit-ID: 99I5WgdzXlb
intl/locale/LocaleService.cpp
intl/locale/LocaleService.h
intl/locale/mozILocaleService.idl
--- a/intl/locale/LocaleService.cpp
+++ b/intl/locale/LocaleService.cpp
@@ -6,16 +6,17 @@
 #include "LocaleService.h"
 
 #include <algorithm>  // find_if()
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Services.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/intl/OSPreferences.h"
 #include "nsIObserverService.h"
+#include "nsStringEnumerator.h"
 #include "nsIToolkitChromeRegistry.h"
 
 #ifdef ENABLE_INTL_API
 #include "unicode/uloc.h"
 #endif
 
 #define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
 #define SELECTED_LOCALE_PREF "general.useragent.locale"
@@ -167,16 +168,43 @@ LocaleService::GetRequestedLocales(nsTAr
   }
 
   // At the moment we just take a single locale, but in the future
   // we'll want to allow user to specify a list of requested locales.
   aRetVal.AppendElement(locale);
   return true;
 }
 
+bool
+LocaleService::GetAvailableLocales(nsTArray<nsCString>& aRetVal)
+{
+  nsCOMPtr<nsIToolkitChromeRegistry> cr =
+    mozilla::services::GetToolkitChromeRegistryService();
+
+  nsCOMPtr<nsIUTF8StringEnumerator> localesEnum;
+
+  nsresult rv =
+    cr->GetLocalesForPackage(NS_LITERAL_CSTRING("global"), getter_AddRefs(localesEnum));
+  if (!NS_SUCCEEDED(rv)) {
+    return false;
+  }
+
+  bool more;
+  while (NS_SUCCEEDED(rv = localesEnum->HasMore(&more)) && more) {
+    nsAutoCString localeStr;
+    rv = localesEnum->GetNext(localeStr);
+    if (!NS_SUCCEEDED(rv)) {
+      return false;
+    }
+
+    aRetVal.AppendElement(localeStr);
+  }
+  return !aRetVal.IsEmpty();
+}
+
 void
 LocaleService::Refresh()
 {
   nsTArray<nsCString> newLocales;
   ReadAppLocales(newLocales);
 
   if (mAppLocales != newLocales) {
     mAppLocales = Move(newLocales);
@@ -656,8 +684,25 @@ LocaleService::SetRequestedLocales(const
     Preferences::ClearUser(SELECTED_LOCALE_PREF);
   } else {
     Preferences::SetCString(SELECTED_LOCALE_PREF, aRequested[0]);
   }
 
   Preferences::SetBool(MATCH_OS_LOCALE_PREF, aRequestedCount == 0);
   return NS_OK;
 }
+
+NS_IMETHODIMP
+LocaleService::GetAvailableLocales(uint32_t* aCount, char*** aOutArray)
+{
+  AutoTArray<nsCString, 100> availableLocales;
+  bool res = GetAvailableLocales(availableLocales);
+
+  if (!res) {
+    NS_ERROR("Couldn't retrieve available locales!");
+    return NS_ERROR_FAILURE;
+  }
+
+  *aCount = availableLocales.Length();
+  *aOutArray = CreateOutArray(availableLocales);
+
+  return NS_OK;
+}
--- a/intl/locale/LocaleService.h
+++ b/intl/locale/LocaleService.h
@@ -99,27 +99,47 @@ public:
    * localized to.
    *
    * The result is a sorted list of valid locale IDs and it should be
    * used as a requestedLocales input list for languages negotiation.
    *
    * Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"]
    *
    * Usage:
-   *   nsTArray<nsCString> appLocales;
-   *   LocaleService::GetInstance()->GetRequestedLocales(appLocales);
+   *   nsTArray<nsCString> reqLocales;
+   *   LocaleService::GetInstance()->GetRequestedLocales(reqLocales);
    *
    * Returns a boolean indicating if the attempt to retrieve prefs
    * was successful.
    *
    * (See mozILocaleService.idl for a JS-callable version of this.)
    */
   bool GetRequestedLocales(nsTArray<nsCString>& aRetVal);
 
   /**
+   * Returns a list of available locales that can be used to
+   * localize the app.
+   *
+   * The result is an unsorted list of valid locale IDs and it should be
+   * used as a availableLocales input list for languages negotiation.
+   *
+   * Example: ["de", "en-US", "pl", "sr-Cyrl", "zh-Hans-HK"]
+   *
+   * Usage:
+   *   nsTArray<nsCString> availLocales;
+   *   LocaleService::GetInstance()->GetAvailableLocales(availLocales);
+   *
+   * Returns a boolean indicating if the attempt to retrieve at least
+   * one locale was successful.
+   *
+   * (See mozILocaleService.idl for a JS-callable version of this.)
+   */
+  bool GetAvailableLocales(nsTArray<nsCString>& aRetVal);
+
+  /**
    * Triggers a refresh of the language negotiation process.
    *
    * If the result differs from the previous list, it will additionally
    * trigger a global event "intl:app-locales-changed".
    */
   void Refresh();
 
   /**
--- a/intl/locale/mozILocaleService.idl
+++ b/intl/locale/mozILocaleService.idl
@@ -156,9 +156,20 @@ interface mozILocaleService : nsISupport
    *
    * If an empty list is passed, the list of requested locales will
    * be picked from the operating system.
    *
    * Example: ["de"]
    */
   void setRequestedLocales([array, size_is(aRequestedCount)] in string aRequested,
                            [optional] in unsigned long aRequestedCount);
+
+  /**
+   * Returns a list of locales that the app can be localized to.
+   *
+   * The result is an unordered list of locale IDs which should be
+   * used as a availableLocales input list for language negotiation.
+   *
+   * Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"]
+   */
+  void getAvailableLocales([optional] out unsigned long aCount,
+                           [retval, array, size_is(aCount)] out string aLocales);
 };