Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1250)

Side by Side Diff: base/android/java/src/org/chromium/base/LocaleUtils.java

Issue 2406203002: Use BCP47 compliant format for locale representation (Closed)
Patch Set: Add mapping from Chromium to Android for forLanguageTag Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/BUILD.gn ('k') | base/android/java/src/org/chromium/base/ResourceExtractor.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.base; 5 package org.chromium.base;
6 6
7 import android.annotation.TargetApi;
8 import android.os.Build;
9
7 import org.chromium.base.annotations.CalledByNative; 10 import org.chromium.base.annotations.CalledByNative;
8 11
12 import java.util.Collections;
13 import java.util.HashMap;
9 import java.util.Locale; 14 import java.util.Locale;
15 import java.util.Map;
10 16
11 /** 17 /**
12 * This class provides the locale related methods. 18 * This class provides the locale related methods.
13 */ 19 */
14 public class LocaleUtils { 20 public class LocaleUtils {
15 /** 21 /**
16 * Guards this class from being instantiated. 22 * Guards this class from being instantiated.
17 */ 23 */
18 private LocaleUtils() { 24 private LocaleUtils() {
19 } 25 }
20 26
27 private static final Map<String, String> LANGUAGE_MAP_FOR_CHROMIUM;
28 private static final Map<String, String> LANGUAGE_MAP_FOR_ANDROID;
29
30 static {
31 HashMap<String, String> mapForChromium = new HashMap<>();
32 mapForChromium.put("iw", "he"); // Hebrew
33 mapForChromium.put("ji", "yi"); // Yiddish
34 mapForChromium.put("in", "id"); // Indonesian
35 mapForChromium.put("tl", "fil"); // Filipino
36 LANGUAGE_MAP_FOR_CHROMIUM = Collections.unmodifiableMap(mapForChromium);
37 }
38
39 static {
40 HashMap<String, String> mapForAndroid = new HashMap<>();
41 mapForAndroid.put("und", ""); // Undefined
42 mapForAndroid.put("fil", "tl"); // Filipino
43 LANGUAGE_MAP_FOR_ANDROID = Collections.unmodifiableMap(mapForAndroid);
44 }
45
21 /** 46 /**
22 * @return The string for the given locale, translating Android deprecated l anguage codes 47 * Java keeps deprecated language codes for Hebrew, Yiddish and Indonesian b ut Chromium uses
23 * into the modern ones used by Chromium. 48 * updated ones. Similarly, Android uses "tl" while Chromium uses "fil" for Tagalog/Filipino.
49 * So apply a mapping here.
50 * See http://developer.android.com/reference/java/util/Locale.html
51 * @return a updated language code for Chromium with given language string.
24 */ 52 */
25 public static String getLocale(Locale locale) { 53 public static String getUpdateLanguageForChromium(String language) {
26 String language = getLanguage(locale); 54 String updatedLanguageCode = LANGUAGE_MAP_FOR_CHROMIUM.get(language);
55 return updatedLanguageCode == null ? language : updatedLanguageCode;
56 }
57
58 /**
59 * @return a locale with updated language codes for Chromium, with translate d modern language
60 * codes used by Chromium.
61 */
62 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
63 private static Locale getUpdateLocaleForChromium(Locale locale) {
64 String languageForChrome = LANGUAGE_MAP_FOR_CHROMIUM.get(locale.getLangu age());
65 if (languageForChrome == null) {
66 return locale;
67 }
68 return new Locale.Builder().setLocale(locale).setLanguage(languageForChr ome).build();
69 }
70
71 /**
72 * Android uses "tl" while Chromium uses "fil" for Tagalog/Filipino.
73 * So apply a mapping here.
74 * See http://developer.android.com/reference/java/util/Locale.html
75 * @return a updated language code for Android with given language string.
76 */
77 public static String getUpdateLanguageForAndroid(String language) {
78 String updatedLanguageCode = LANGUAGE_MAP_FOR_ANDROID.get(language);
79 return updatedLanguageCode == null ? language : updatedLanguageCode;
80 }
81
82 /**
83 * @return a locale with updated language codes for Android, from translated modern language
84 * codes used by Chromium.
85 */
86 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
87 private static Locale getUpdateLocaleForAndroid(Locale locale) {
88 String languageForAndroid = LANGUAGE_MAP_FOR_ANDROID.get(locale.getLangu age());
89 if (languageForAndroid == null) {
90 return locale;
91 }
92 return new Locale.Builder().setLocale(locale).setLanguage(languageForAnd roid).build();
93 }
94
95 /**
96 * This function creates Locale object from xx-XX style string where xx is l anguage code
97 * and XX is a country code. This works for API level lower than 21.
98 * @return the locale that best represents the language tag.
99 */
100 public static Locale forLanguageTagCompat(String languageTag) {
101 String[] tag = languageTag.split("-");
102 if (tag.length == 0) {
103 return new Locale("");
104 }
105 String language = getUpdateLanguageForAndroid(tag[0]);
106 // Check the case where language code is "und".
Bernhard Bauer 2016/10/25 09:46:29 This case would already be caught in line 110, bec
Yirui Huang 2016/10/26 03:18:43 Oh actually, what I should check is "language == '
107 if (language == "") {
108 return new Locale("");
109 }
110 if (language.length() != 2 && language.length() != 3) {
111 return new Locale("");
112 }
113 if (tag.length == 1) {
114 return new Locale(language);
115 }
116 String country = tag[1];
117 if (country.length() != 2 && country.length() != 3) {
118 return new Locale(language);
119 }
120 return new Locale(language, country);
121 }
122
123 /**
124 * This function creates Locale object from xx-XX style string where xx is l anguage code
125 * and XX is a country code.
126 * @return the locale that best represents the language tag.
127 */
128 public static Locale forLanguageTag(String languageTag) {
129 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
130 Locale locale = Locale.forLanguageTag(languageTag);
131 return getUpdateLocaleForAndroid(locale);
132 }
133 return forLanguageTagCompat(languageTag);
134 }
135
136 /**
137 * Converts Locale object to the BC47 compliant string format.
138 *
139 * Note that for Android M or before, we cannot use Locale.getLanguage() and
140 * Locale.toLanguageTag() for this purpose. Since Locale.getLanguage() retur ns deprecated
141 * language code even if the Locale object is constructed with updated langu age code. As for
142 * Locale.toLanguageTag(), it does a special conversion from deprecated lang uage code to updated
143 * one, but it is only usable for Android N or after.
144 * @return a well-formed IETF BCP 47 language tag with language and country code that
145 * represents this locale.
146 */
147 public static String toLanguageTag(Locale locale) {
148 // TODO(yirui): use '>= N' once SDK is updated to include the version co de
149 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
150 locale = getUpdateLocaleForChromium(locale);
151 return locale.toLanguageTag();
152 }
153 String language = getUpdateLanguageForChromium(locale.getLanguage());
27 String country = locale.getCountry(); 154 String country = locale.getCountry();
28 155 if (language == "no" && country == "NO" && locale.getVariant() == "NY") {
156 return "nn-NO";
157 }
29 return country.isEmpty() ? language : language + "-" + country; 158 return country.isEmpty() ? language : language + "-" + country;
30 } 159 }
31 160
32 /** 161 /**
33 * @return The language for the given locale, translating Android deprecated languages codes 162 * @return a well-formed IETF BCP 47 language tag with language and country code that
34 * into modern ones used by Chromium. 163 * represents a default locale.
35 */ 164 */
36 public static String getLanguage(Locale locale) { 165 @CalledByNative
37 String language = locale.getLanguage(); 166 public static String getDefaultLocaleString() {
38 167 Locale locale = Locale.getDefault();
39 // Android uses deprecated lanuages codes for Hebrew and Indonesian but Chromium uses the 168 return toLanguageTag(locale);
40 // updated codes. Also, Android uses "tl" while Chromium uses "fil" for Tagalog/Filipino.
41 // So apply a mapping.
42 // See http://developer.android.com/reference/java/util/Locale.html
43 if ("iw".equals(language)) {
44 language = "he";
45 } else if ("in".equals(language)) {
46 language = "id";
47 } else if ("tl".equals(language)) {
48 language = "fil";
49 }
50 return language;
51 } 169 }
52 170
53 /** 171 /**
54 * @return The default locale, translating Android deprecated language codes into the modern
55 * ones used by Chromium.
56 */
57 @CalledByNative
58 public static String getDefaultLocale() {
59 return getLocale(Locale.getDefault());
60 }
61
62 /**
63 * @return The default country code set during install. 172 * @return The default country code set during install.
64 */ 173 */
65 @CalledByNative 174 @CalledByNative
66 private static String getDefaultCountryCode() { 175 private static String getDefaultCountryCode() {
67 CommandLine commandLine = CommandLine.getInstance(); 176 CommandLine commandLine = CommandLine.getInstance();
68 return commandLine.hasSwitch(BaseSwitches.DEFAULT_COUNTRY_CODE_AT_INSTAL L) 177 return commandLine.hasSwitch(BaseSwitches.DEFAULT_COUNTRY_CODE_AT_INSTAL L)
69 ? commandLine.getSwitchValue(BaseSwitches.DEFAULT_COUNTRY_CODE_A T_INSTALL) 178 ? commandLine.getSwitchValue(BaseSwitches.DEFAULT_COUNTRY_CODE_A T_INSTALL)
70 : Locale.getDefault().getCountry(); 179 : Locale.getDefault().getCountry();
71 } 180 }
72 181
73 } 182 }
OLDNEW
« no previous file with comments | « base/BUILD.gn ('k') | base/android/java/src/org/chromium/base/ResourceExtractor.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698