Bug 1337694 - Add Language negotiation to LocaleService API draft
authorZibi Braniecki <gandalf@mozilla.com>
Sun, 19 Feb 2017 18:15:27 -0800
changeset 486831 f2189a78081ad535efb59ba387ef424fe7b94d2d
parent 486830 3dd2473efa260b2efcf89c399e40910f0c9c0260
child 546324 bb65092fec1f1c60aef1c8fdabce307b9410f588
push id46069
push userzbraniecki@mozilla.com
push dateMon, 20 Feb 2017 02:17:11 +0000
bugs1337694
milestone54.0a1
Bug 1337694 - Add Language negotiation to LocaleService API MozReview-Commit-ID: 59zOYC8Y219
intl/locale/LocaleService.cpp
intl/locale/LocaleService.h
intl/locale/mozILocaleService.idl
intl/locale/tests/gtest/TestLocaleServiceNegotiate.cpp
--- a/intl/locale/LocaleService.cpp
+++ b/intl/locale/LocaleService.cpp
@@ -5,16 +5,17 @@
 
 #include "LocaleService.h"
 
 #include "jsapi.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Services.h"
 #include "nsIObserverService.h"
 #include "nsIToolkitChromeRegistry.h"
+#include "unicode/uloc.h"
 
 using namespace mozilla::intl;
 
 NS_IMPL_ISUPPORTS(LocaleService, mozILocaleService)
 
 mozilla::StaticRefPtr<LocaleService> LocaleService::sInstance;
 
 /**
@@ -70,19 +71,41 @@ LocaleService::Refresh()
     mAppLocales = Move(newLocales);
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
       obs->NotifyObservers(nullptr, "intl:app-locales-changed", nullptr);
     }
   }
 }
 
-void LocaleService::Negotiate(nsTArray<nsCString>& requestedLocales,
-    nsTArray<nsCString>& availableLocales, nsACString& defaultLocale, nsTArray<nsCString>& aRetVal)
+void LocaleService::NegotiateLanguages(nsTArray<nsACString>& aRequested,
+    nsTArray<nsACString>& aAvailable, nsACString& aDefaultLocale, nsTArray<nsACString>& aRetVal)
 {
+
+  const char** requested = new const char *[aRequested.Length()];
+  const char** available = new const char *[aAvailable.Length()];
+  const char* defaultLocale = PromiseFlatCString(aDefaultLocale).get();
+  uint32_t requestedCount = aRequested.Length();
+  uint32_t availableCount = aAvailable.Length();
+
+  for (uint32_t i = 0; i < requestedCount; i++) {
+    requested[i] = PromiseFlatCString(aRequested[i]).get();
+  }
+  for (uint32_t i = 0; i < availableCount; i++) {
+    available[i] = PromiseFlatCString(aAvailable[i]).get();
+  }
+
+  uint32_t count;
+  char** retVal;
+
+  LocaleService::NegotiateLanguages(&*requested, &*available, &*defaultLocale, requestedCount, availableCount, &count, &retVal);
+
+  for (uint32_t i = 0; i < count; i++) {
+     aRetVal[i] = nsDependentCString(retVal[i]); 
+  } 
 }
 
 /**
  * mozILocaleService methods
  */
 NS_IMETHODIMP
 LocaleService::GetAppLocales(JSContext* aCtx, JS::MutableHandleValue aRetVal)
 {
@@ -110,8 +133,34 @@ NS_IMETHODIMP
 LocaleService::GetAppLocale(nsACString& aRetVal)
 {
   if (mAppLocales.IsEmpty()) {
     ReadAppLocales(mAppLocales);
   }
   aRetVal = mAppLocales[0];
   return NS_OK;
 }
+
+NS_IMETHODIMP
+LocaleService::NegotiateLanguages(const char** aRequested,
+                                  const char** aAvailable,
+                                  const char*  aDefaultLocale,
+                                  uint32_t aRequestedCount,
+                                  uint32_t aAvailableCount,
+                                  uint32_t* aCount, char*** aRetVal)
+{
+  const int32_t kPatternMax = 160;
+  char pattern[kPatternMax];
+  UErrorCode status = U_ZERO_ERROR;
+
+  int32_t size = uloc_addLikelySubtags(
+      aDefaultLocale, pattern, kPatternMax, &status);
+  printf("%s\n", pattern);
+
+  uint32_t count = 1;
+  char** retVal = (char**)moz_xmalloc(count * sizeof(char*));
+
+  retVal[0] = (char*)pattern;
+
+  *aCount = count;
+  *aRetVal = retVal;
+  return NS_OK;
+}
--- a/intl/locale/LocaleService.h
+++ b/intl/locale/LocaleService.h
@@ -67,18 +67,20 @@ public:
   /**
    * 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();
 
-  void Negotiate(nsTArray<nsCString>& requestedLocales,
-      nsTArray<nsCString>& availableLocales, nsACString& defaultLocale, nsTArray<nsCString>& aRetVal);
+  void NegotiateLanguages(nsTArray<nsACString>& aRequested,
+                          nsTArray<nsACString>& aAvailable,
+                          nsACString& aDefaultLocale,
+                          nsTArray<nsACString>& aRetVal);
 
 protected:
   nsTArray<nsCString> mAppLocales;
 
 private:
   virtual ~LocaleService() {};
 
   static StaticRefPtr<LocaleService> sInstance;
--- a/intl/locale/mozILocaleService.idl
+++ b/intl/locale/mozILocaleService.idl
@@ -24,16 +24,24 @@ interface mozILocaleService : nsISupport
    *
    * 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.)
    */
   [implicit_jscontext] jsval getAppLocales();
+  void negotiateLanguages(
+                          [array, size_is(aRequestedCount)] in string aRequested, 
+                          [array, size_is(aAvailableCount)] in string aAvailable, 
+                          in string aDefaultLocale,
+                          [optional] in unsigned long aRequestedCount,
+                          [optional] in unsigned long aAvailableCount,
+                          [optional] out unsigned long aCount,
+                          [retval, array, size_is(aCount)] out string aLocales);
 
   /**
    * Returns the best locale that the application should be localized to.
    *
    * The result is a valid locale ID and it should be
    * used for all APIs that do not handle language negotiation.
    *
    * Where possible, getAppLocales() should be preferred over this API and
--- a/intl/locale/tests/gtest/TestLocaleServiceNegotiate.cpp
+++ b/intl/locale/tests/gtest/TestLocaleServiceNegotiate.cpp
@@ -1,13 +1,25 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gtest/gtest.h"
-#include "LocaleService.h"
+#include "mozilla/intl/LocaleService.h"
 #include "mozilla/Services.h"
 #include "nsIToolkitChromeRegistry.h"
 
 using namespace mozilla::intl;
 
+TEST(Intl_Locale_LocaleService, Negotiate) {
+  nsTArray<nsACString> requestedLocales;
+  nsTArray<nsACString> availableLocales;
+  nsTArray<nsACString> supportedLocales;
+  nsAutoCString defaultLocale("sr");
 
+  LocaleService::GetInstance()->NegotiateLanguages(
+      requestedLocales, availableLocales, defaultLocale, supportedLocales);
+
+  ASSERT_TRUE(supportedLocales.Length() == 1);
+  ASSERT_TRUE(supportedLocales[0].Equals("sr-Cyrl-RS"));
+}
+