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

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: Rebased, using .equals(), create compat for forLanguageTag, more tests added 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 getUpdatedLanguageForChromium(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 getUpdatedLocaleForChromium(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 getUpdatedLanguageForAndroid(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 getUpdatedLocaleForAndroid(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 = getUpdatedLanguageForAndroid(tag[0]);
106 if ((language.length() != 2 && language.length() != 3) || language.equal s("und")) {
107 return new Locale("");
108 }
109 if (tag.length == 1) {
110 return new Locale(language);
111 }
112 String country = tag[1];
113 if (country.length() != 2 && country.length() != 3) {
114 return new Locale(language);
115 }
116 return new Locale(language, country);
117 }
118
119 /**
120 * This function creates Locale object from xx-XX style string where xx is l anguage code
121 * and XX is a country code.
122 * @return the locale that best represents the language tag.
123 */
124 public static Locale forLanguageTag(String languageTag) {
125 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
126 Locale locale = Locale.forLanguageTag(languageTag);
127 return getUpdatedLocaleForAndroid(locale);
128 }
129 return forLanguageTagCompat(languageTag);
130 }
131
132 /**
133 * Converts Locale object to the BC47 compliant string format.
jungshik at Google 2016/10/27 06:50:52 nit: BC47 => BCP 47
Yirui Huang 2016/10/27 06:56:12 Done.
134 * This works for API level lower than 24.
135 * @return a well-formed IETF BCP 47 language tag with language and country code that
136 * represents this locale.
137 */
138 public static String toLanguageTagCompat(Locale locale) {
139 String language = getUpdatedLanguageForChromium(locale.getLanguage());
27 String country = locale.getCountry(); 140 String country = locale.getCountry();
28 141 if (language.equals("no") && country.equals("NO") && locale.getVariant() .equals("NY")) {
142 return "nn-NO";
143 }
29 return country.isEmpty() ? language : language + "-" + country; 144 return country.isEmpty() ? language : language + "-" + country;
30 } 145 }
31 146
32 /** 147 /**
33 * @return The language for the given locale, translating Android deprecated languages codes 148 * Converts Locale object to the BC47 compliant string format.
jungshik at Google 2016/10/27 06:50:52 nit: BC47 => BCP 47
Yirui Huang 2016/10/27 06:56:12 Done.
34 * into modern ones used by Chromium. 149 *
150 * Note that for Android M or before, we cannot use Locale.getLanguage() and
151 * Locale.toLanguageTag() for this purpose. Since Locale.getLanguage() retur ns deprecated
152 * language code even if the Locale object is constructed with updated langu age code. As for
153 * Locale.toLanguageTag(), it does a special conversion from deprecated lang uage code to updated
154 * one, but it is only usable for Android N or after.
155 * @return a well-formed IETF BCP 47 language tag with language and country code that
156 * represents this locale.
35 */ 157 */
36 public static String getLanguage(Locale locale) { 158 public static String toLanguageTag(Locale locale) {
37 String language = locale.getLanguage(); 159 // TODO(yirui): use '>= N' once SDK is updated to include the version co de
38 160 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
39 // Android uses deprecated lanuages codes for Hebrew and Indonesian but Chromium uses the 161 locale = getUpdatedLocaleForChromium(locale);
40 // updated codes. Also, Android uses "tl" while Chromium uses "fil" for Tagalog/Filipino. 162 return locale.toLanguageTag();
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 } 163 }
50 return language; 164 return toLanguageTagCompat(locale);
51 } 165 }
52 166
53 /** 167 /**
54 * @return The default locale, translating Android deprecated language codes into the modern 168 * @return a well-formed IETF BCP 47 language tag with language and country code that
55 * ones used by Chromium. 169 * represents a default locale.
56 */ 170 */
57 @CalledByNative 171 @CalledByNative
58 public static String getDefaultLocale() { 172 public static String getDefaultLocaleString() {
59 return getLocale(Locale.getDefault()); 173 Locale locale = Locale.getDefault();
174 return toLanguageTag(locale);
60 } 175 }
61 176
62 /** 177 /**
63 * @return The default country code set during install. 178 * @return The default country code set during install.
64 */ 179 */
65 @CalledByNative 180 @CalledByNative
66 private static String getDefaultCountryCode() { 181 private static String getDefaultCountryCode() {
67 CommandLine commandLine = CommandLine.getInstance(); 182 CommandLine commandLine = CommandLine.getInstance();
68 return commandLine.hasSwitch(BaseSwitches.DEFAULT_COUNTRY_CODE_AT_INSTAL L) 183 return commandLine.hasSwitch(BaseSwitches.DEFAULT_COUNTRY_CODE_AT_INSTAL L)
69 ? commandLine.getSwitchValue(BaseSwitches.DEFAULT_COUNTRY_CODE_A T_INSTALL) 184 ? commandLine.getSwitchValue(BaseSwitches.DEFAULT_COUNTRY_CODE_A T_INSTALL)
70 : Locale.getDefault().getCountry(); 185 : Locale.getDefault().getCountry();
71 } 186 }
72 187
73 } 188 }
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