Bug 1347002 - Add LocaleService::GetAvailableLocales. r?jfkthame
MozReview-Commit-ID: 99I5WgdzXlb
--- 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);
};