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