Bug 1337078 - Improve the use of Android API in OSPreferences; r?jchen
MozReview-Commit-ID: GWSjP5bUquE
--- a/intl/locale/android/OSPreferences_android.cpp
+++ b/intl/locale/android/OSPreferences_android.cpp
@@ -1,36 +1,42 @@
/* -*- 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 "OSPreferences.h"
#include "mozilla/Preferences.h"
+#include "GeneratedJNIWrappers.h"
+#include "Locale.h"
using namespace mozilla::intl;
-bool
-OSPreferences::ReadSystemLocales(nsTArray<nsCString>& aLocaleList)
+if (!jni::IsAvailable()) {
+ return false;
+}
+
+bool OSPreferences::ReadSystemLocales(nsTArray<nsCString>& aLocaleList)
{
- //XXX: This is a quite sizable hack to work around the fact that we cannot
- // retrieve OS locale in C++ without reaching out to JNI.
- // Once we fix this (bug 1337078), this hack should not be necessary.
- //
- //XXX: Notice, this value may be empty on an early read. In that case
- // we won't add anything to the return list so that it doesn't get
- // cached in mSystemLocales.
- nsAdoptingCString locale = Preferences::GetCString("intl.locale.os");
- if (!locale.IsEmpty()) {
- aLocaleList.AppendElement(locale);
+ namespace jni = mozilla::jni;
+ namespace java = mozilla::java;
+
+ // Call Locale.getDefault to get the default locale
+ java::sdk::Locale::LocalRef locale;
+ NS_ENSURE_SUCCESS(java::sdk::Locale::GetDefault(&locale), false);
+
+ // Call Locales.getLanguage to get the language string from locale.
+ nsCString language = java::Locales::GetLanguage(locale)->ToCString();
+
+ if (!language.IsEmpty()) {
+ aLocaleList.AppendElement(language);
return true;
}
return false;
}
-bool
-OSPreferences::ReadDateTimePattern(DateTimeFormatStyle aDateStyle,
+bool OSPreferences::ReadDateTimePattern(DateTimeFormatStyle aDateStyle,
DateTimeFormatStyle aTimeStyle,
const nsACString& aLocale, nsAString& aRetVal)
{
return false;
}
--- a/mobile/android/base/java/org/mozilla/gecko/Locales.java
+++ b/mobile/android/base/java/org/mozilla/gecko/Locales.java
@@ -3,16 +3,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
import java.lang.reflect.Method;
import java.util.Locale;
import org.mozilla.gecko.LocaleManager;
+import org.mozilla.gecko.annotation.WrapForJNI;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
@@ -76,16 +77,17 @@ public class Locales {
* Sometimes we want just the language for a locale, not the entire language
* tag. But Java's .getLanguage method is wrong.
*
* This method is equivalent to the first part of
* {@link Locales#getLanguageTag(Locale)}.
*
* @return a language string, such as "he" for the Hebrew locales.
*/
+ @WrapForJNI(calledFrom = "gecko")
public static String getLanguage(final Locale locale) {
// Can, but should never be, an empty string.
final String language = locale.getLanguage();
// Modernize certain language codes.
if (language.equals("iw")) {
return "he";
}
--- a/widget/android/GeneratedJNIWrappers.cpp
+++ b/widget/android/GeneratedJNIWrappers.cpp
@@ -948,16 +948,27 @@ constexpr char GeckoView::Window::Reatta
constexpr char GeckoView::Window::SetState_t::name[];
constexpr char GeckoView::Window::SetState_t::signature[];
auto GeckoView::Window::SetState(mozilla::jni::Object::Param a0) const -> void
{
return mozilla::jni::Method<SetState_t>::Call(Window::mCtx, nullptr, a0);
}
+const char Locales::name[] =
+ "org/mozilla/gecko/Locales";
+
+constexpr char Locales::GetLanguage_t::name[];
+constexpr char Locales::GetLanguage_t::signature[];
+
+auto Locales::GetLanguage(mozilla::jni::Object::Param a0) -> mozilla::jni::String::LocalRef
+{
+ return mozilla::jni::Method<GetLanguage_t>::Call(Locales::Context(), nullptr, a0);
+}
+
const char PrefsHelper::name[] =
"org/mozilla/gecko/PrefsHelper";
constexpr char PrefsHelper::CallPrefHandler_t::name[];
constexpr char PrefsHelper::CallPrefHandler_t::signature[];
auto PrefsHelper::CallPrefHandler(mozilla::jni::Object::Param a0, int32_t a1, mozilla::jni::String::Param a2, bool a3, int32_t a4, mozilla::jni::String::Param a5) -> void
{
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -2914,16 +2914,48 @@ public:
auto SetState(mozilla::jni::Object::Param) const -> void;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;
template<class Impl> class Natives;
};
+class Locales : public mozilla::jni::ObjectBase<Locales>
+{
+public:
+ static const char name[];
+
+ explicit Locales(const Context& ctx) : ObjectBase<Locales>(ctx) {}
+
+ struct GetLanguage_t {
+ typedef Locales Owner;
+ typedef mozilla::jni::String::LocalRef ReturnType;
+ typedef mozilla::jni::String::Param SetterType;
+ typedef mozilla::jni::Args<
+ mozilla::jni::Object::Param> Args;
+ static constexpr char name[] = "getLanguage";
+ static constexpr char signature[] =
+ "(Ljava/util/Locale;)Ljava/lang/String;";
+ static const bool isStatic = true;
+ static const mozilla::jni::ExceptionMode exceptionMode =
+ mozilla::jni::ExceptionMode::ABORT;
+ static const mozilla::jni::CallingThread callingThread =
+ mozilla::jni::CallingThread::GECKO;
+ static const mozilla::jni::DispatchTarget dispatchTarget =
+ mozilla::jni::DispatchTarget::CURRENT;
+ };
+
+ static auto GetLanguage(mozilla::jni::Object::Param) -> mozilla::jni::String::LocalRef;
+
+ static const mozilla::jni::CallingThread callingThread =
+ mozilla::jni::CallingThread::GECKO;
+
+};
+
class PrefsHelper : public mozilla::jni::ObjectBase<PrefsHelper>
{
public:
static const char name[];
explicit PrefsHelper(const Context& ctx) : ObjectBase<PrefsHelper>(ctx) {}
struct CallPrefHandler_t {
new file mode 100644
--- /dev/null
+++ b/widget/android/bindings/Locale-classes.txt
@@ -0,0 +1,1 @@
+[java.util.Locale = exceptionMode:nsresult]
\ No newline at end of file
--- a/widget/android/bindings/moz.build
+++ b/widget/android/bindings/moz.build
@@ -8,16 +8,17 @@ with Files("**"):
BUG_COMPONENT = ("Firefox for Android", "Graphics, Panning and Zooming")
# List of stems to generate .cpp and .h files for. To add a stem, add it to
# this list and ensure that $(stem)-classes.txt exists in this directory.
generated = [
'AndroidBuild',
'AndroidRect',
'KeyEvent',
+ 'Locale',
'MediaCodec',
'MotionEvent',
'SurfaceTexture',
'ViewConfiguration'
]
SOURCES += ['!%s.cpp' % stem for stem in generated]