1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/base/l10n/l10n_util_android.h"
6
7 #include <stdint.h>
8
9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h"
11 #include "base/android/scoped_java_ref.h"
12 #include "base/i18n/rtl.h"
13 #include "base/logging.h"
14 #include "base/strings/string_util.h"
15 #include "base/time/time.h"
16 #include "third_party/icu/source/common/unicode/uloc.h"
17 #include "ui/base/l10n/time_format.h"
18 #include "ui/base/ui_base_jni_headers/LocalizationUtils_jni.h"
19
20 using base::android::JavaParamRef;
21 using base::android::ScopedJavaLocalRef;
22
23 namespace l10n_util {
24
JNI_LocalizationUtils_GetFirstStrongCharacterDirection(JNIEnv * env,const JavaParamRef<jstring> & string)25 jint JNI_LocalizationUtils_GetFirstStrongCharacterDirection(
26 JNIEnv* env,
27 const JavaParamRef<jstring>& string) {
28 return base::i18n::GetFirstStrongCharacterDirection(
29 base::android::ConvertJavaStringToUTF16(env, string));
30 }
31
IsLayoutRtl()32 bool IsLayoutRtl() {
33 static bool is_layout_rtl_cached = false;
34 static bool layout_rtl_cache;
35
36 if (!is_layout_rtl_cached) {
37 is_layout_rtl_cached = true;
38 JNIEnv* env = base::android::AttachCurrentThread();
39 layout_rtl_cache =
40 static_cast<bool>(Java_LocalizationUtils_isLayoutRtl(env));
41 }
42
43 return layout_rtl_cache;
44 }
45
46 namespace {
47
48 // Common prototype of ICU uloc_getXXX() functions.
49 typedef int32_t (*UlocGetComponentFunc)(const char*, char*, int32_t,
50 UErrorCode*);
51
GetLocaleComponent(const std::string & locale,UlocGetComponentFunc uloc_func,int32_t max_capacity)52 std::string GetLocaleComponent(const std::string& locale,
53 UlocGetComponentFunc uloc_func,
54 int32_t max_capacity) {
55 std::string result;
56 UErrorCode error = U_ZERO_ERROR;
57 int32_t actual_length = uloc_func(locale.c_str(),
58 base::WriteInto(&result, max_capacity),
59 max_capacity,
60 &error);
61 DCHECK(U_SUCCESS(error));
62 DCHECK(actual_length < max_capacity);
63 result.resize(actual_length);
64 return result;
65 }
66
JNI_LocalizationUtils_NewJavaLocale(JNIEnv * env,const std::string & locale)67 ScopedJavaLocalRef<jobject> JNI_LocalizationUtils_NewJavaLocale(
68 JNIEnv* env,
69 const std::string& locale) {
70 // TODO(wangxianzhu): Use new Locale API once Android supports scripts.
71 std::string language = GetLocaleComponent(
72 locale, uloc_getLanguage, ULOC_LANG_CAPACITY);
73 std::string country = GetLocaleComponent(
74 locale, uloc_getCountry, ULOC_COUNTRY_CAPACITY);
75 std::string variant = GetLocaleComponent(
76 locale, uloc_getVariant, ULOC_FULLNAME_CAPACITY);
77 return Java_LocalizationUtils_getJavaLocale(
78 env, base::android::ConvertUTF8ToJavaString(env, language),
79 base::android::ConvertUTF8ToJavaString(env, country),
80 base::android::ConvertUTF8ToJavaString(env, variant));
81 }
82
83 } // namespace
84
GetDisplayNameForLocale(const std::string & locale,const std::string & display_locale)85 base::string16 GetDisplayNameForLocale(const std::string& locale,
86 const std::string& display_locale) {
87 JNIEnv* env = base::android::AttachCurrentThread();
88 ScopedJavaLocalRef<jobject> java_locale =
89 JNI_LocalizationUtils_NewJavaLocale(env, locale);
90 ScopedJavaLocalRef<jobject> java_display_locale =
91 JNI_LocalizationUtils_NewJavaLocale(env, display_locale);
92
93 ScopedJavaLocalRef<jstring> java_result(
94 Java_LocalizationUtils_getDisplayNameForLocale(env, java_locale,
95 java_display_locale));
96 return ConvertJavaStringToUTF16(java_result);
97 }
98
JNI_LocalizationUtils_GetDurationString(JNIEnv * env,jlong timeInMillis)99 ScopedJavaLocalRef<jstring> JNI_LocalizationUtils_GetDurationString(
100 JNIEnv* env,
101 jlong timeInMillis) {
102 ScopedJavaLocalRef<jstring> jtime_remaining =
103 base::android::ConvertUTF16ToJavaString(
104 env,
105 ui::TimeFormat::Simple(
106 ui::TimeFormat::FORMAT_REMAINING, ui::TimeFormat::LENGTH_SHORT,
107 base::TimeDelta::FromMilliseconds(timeInMillis)));
108 return jtime_remaining;
109 }
110
111 } // namespace l10n_util
112