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

Side by Side Diff: chrome/browser/android/preferences/pref_service_bridge.cc

Issue 2406203002: Use BCP47 compliant format for locale representation (Closed)
Patch Set: BCP 47, change in description 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
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 #include "chrome/browser/android/preferences/pref_service_bridge.h" 5 #include "chrome/browser/android/preferences/pref_service_bridge.h"
6 6
7 #include <jni.h> 7 #include <jni.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <memory> 10 #include <memory>
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 #include "components/prefs/pref_service.h" 57 #include "components/prefs/pref_service.h"
58 #include "components/safe_browsing_db/safe_browsing_prefs.h" 58 #include "components/safe_browsing_db/safe_browsing_prefs.h"
59 #include "components/signin/core/common/signin_pref_names.h" 59 #include "components/signin/core/common/signin_pref_names.h"
60 #include "components/strings/grit/components_locale_settings.h" 60 #include "components/strings/grit/components_locale_settings.h"
61 #include "components/translate/core/browser/translate_prefs.h" 61 #include "components/translate/core/browser/translate_prefs.h"
62 #include "components/translate/core/common/translate_pref_names.h" 62 #include "components/translate/core/common/translate_pref_names.h"
63 #include "components/version_info/version_info.h" 63 #include "components/version_info/version_info.h"
64 #include "components/web_resource/web_resource_pref_names.h" 64 #include "components/web_resource/web_resource_pref_names.h"
65 #include "content/public/browser/browser_thread.h" 65 #include "content/public/browser/browser_thread.h"
66 #include "jni/PrefServiceBridge_jni.h" 66 #include "jni/PrefServiceBridge_jni.h"
67 #include "third_party/icu/source/common/unicode/uloc.h"
67 #include "ui/base/l10n/l10n_util.h" 68 #include "ui/base/l10n/l10n_util.h"
68 69
69 using base::android::AttachCurrentThread; 70 using base::android::AttachCurrentThread;
70 using base::android::CheckException; 71 using base::android::CheckException;
71 using base::android::ConvertJavaStringToUTF8; 72 using base::android::ConvertJavaStringToUTF8;
72 using base::android::ConvertUTF8ToJavaString; 73 using base::android::ConvertUTF8ToJavaString;
73 using base::android::JavaParamRef; 74 using base::android::JavaParamRef;
74 using base::android::ScopedJavaLocalRef; 75 using base::android::ScopedJavaLocalRef;
75 using base::android::ScopedJavaGlobalRef; 76 using base::android::ScopedJavaGlobalRef;
76 using content::BrowserThread; 77 using content::BrowserThread;
(...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 1141
1141 // static 1142 // static
1142 bool PrefServiceBridge::RegisterPrefServiceBridge(JNIEnv* env) { 1143 bool PrefServiceBridge::RegisterPrefServiceBridge(JNIEnv* env) {
1143 return RegisterNativesImpl(env); 1144 return RegisterNativesImpl(env);
1144 } 1145 }
1145 1146
1146 // static 1147 // static
1147 // This logic should be kept in sync with prependToAcceptLanguagesIfNecessary in 1148 // This logic should be kept in sync with prependToAcceptLanguagesIfNecessary in
1148 // chrome/android/java/src/org/chromium/chrome/browser/ 1149 // chrome/android/java/src/org/chromium/chrome/browser/
1149 // physicalweb/PwsClientImpl.java 1150 // physicalweb/PwsClientImpl.java
1150 // Input |locales| is a comma separated locale representaion. Each locale 1151 // Input |locales| is a comma separated locale representation that consists of
1151 // representation should be xx_XX style, where xx is a 2-letter 1152 // language tags (BCP47 compliant format). Each language tag contains a language
1152 // ISO 639-1 compliant language code and XX is a 2-letter 1153 // code and a country code or a language code only.
1153 // ISO 3166-1 compliant country code.
1154 void PrefServiceBridge::PrependToAcceptLanguagesIfNecessary( 1154 void PrefServiceBridge::PrependToAcceptLanguagesIfNecessary(
1155 const std::string& locales, 1155 const std::string& locales,
1156 std::string* accept_languages) { 1156 std::string* accept_languages) {
1157 std::vector<std::string> locale_list = 1157 std::vector<std::string> locale_list =
1158 base::SplitString(locales + "," + *accept_languages, ",", 1158 base::SplitString(locales + "," + *accept_languages, ",",
1159 base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); 1159 base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
1160 1160
1161 std::set<std::string> seen_tags; 1161 std::set<std::string> seen_tags;
1162 std::vector<std::pair<std::string, std::string>> unique_locale_list; 1162 std::vector<std::pair<std::string, std::string>> unique_locale_list;
1163 for (const std::string& locale_str : locale_list) { 1163 for (const std::string& locale_str : locale_list) {
1164 // TODO(yirui): Support BCP47 compliant format including 3-letter 1164 char locale_ID[ULOC_FULLNAME_CAPACITY] = {};
1165 // country code, '-' separator and missing country case. 1165 char language_code_buffer[ULOC_LANG_CAPACITY] = {};
1166 if (locale_str.size() != 5u || 1166 char country_code_buffer[ULOC_COUNTRY_CAPACITY] = {};
1167 (locale_str[2] != '_' && locale_str[2] != '-'))
1168 continue; // Skip not well formed locale.
1169 1167
1170 std::string lang_code(locale_str.substr(0, 2)); 1168 UErrorCode error = U_ZERO_ERROR;
1171 std::string country_code(locale_str.substr(3, 2)); 1169 uloc_forLanguageTag(locale_str.c_str(), locale_ID, ULOC_FULLNAME_CAPACITY,
1170 nullptr, &error);
1171 if (U_FAILURE(error)) {
1172 LOG(ERROR) << "Ignoring invalid locale representation " << locale_str;
1173 continue;
1174 }
1172 1175
1173 // Java mostly follows ISO-639-1 and ICU, except for the following three. 1176 error = U_ZERO_ERROR;
1174 // See documentation on java.util.Locale constructor for more. 1177 uloc_getLanguage(locale_ID, language_code_buffer, ULOC_LANG_CAPACITY,
1175 if (lang_code == "iw") 1178 &error);
1176 lang_code = "he"; 1179 if (U_FAILURE(error)) {
1177 else if (lang_code == "ji") 1180 LOG(ERROR) << "Ignoring invalid locale representation " << locale_str;
1178 lang_code = "yi"; 1181 continue;
1179 else if (lang_code == "in") 1182 }
1180 lang_code = "id";
1181 1183
1182 std::string language_tag(lang_code + "-" + country_code); 1184 error = U_ZERO_ERROR;
1185 uloc_getCountry(locale_ID, country_code_buffer, ULOC_COUNTRY_CAPACITY,
1186 &error);
1187 if (U_FAILURE(error)) {
1188 LOG(ERROR) << "Ignoring invalid locale representation " << locale_str;
1189 continue;
1190 }
1191
1192 std::string language_code(language_code_buffer);
1193 std::string country_code(country_code_buffer);
1194 std::string language_tag(language_code + "-" + country_code);
1183 1195
1184 if (seen_tags.find(language_tag) != seen_tags.end()) 1196 if (seen_tags.find(language_tag) != seen_tags.end())
1185 continue; 1197 continue;
1186 unique_locale_list.push_back(std::make_pair(lang_code, country_code)); 1198
1187 seen_tags.insert(language_tag); 1199 seen_tags.insert(language_tag);
1200 unique_locale_list.push_back(std::make_pair(language_code, country_code));
1188 } 1201 }
1189 1202
1190 // If language is not in the accept languages list, also add language 1203 // If language is not in the accept languages list, also add language
1191 // code. A language code should only be inserted after the last 1204 // code. A language code should only be inserted after the last
1192 // languageTag that contains that language. 1205 // languageTag that contains that language.
1193 // This will work with the IDS_ACCEPT_LANGUAGE localized strings bundled 1206 // This will work with the IDS_ACCEPT_LANGUAGE localized strings bundled
1194 // with Chrome but may fail on arbitrary lists of language tags due to 1207 // with Chrome but may fail on arbitrary lists of language tags due to
1195 // differences in case and whitespace. 1208 // differences in case and whitespace.
1196 std::set<std::string> seen_languages; 1209 std::set<std::string> seen_languages;
1197 std::vector<std::string> output_list; 1210 std::vector<std::string> output_list;
1198 for (auto it = unique_locale_list.rbegin(); it != unique_locale_list.rend(); 1211 for (auto it = unique_locale_list.rbegin(); it != unique_locale_list.rend();
1199 ++it) { 1212 ++it) {
1200 if (seen_languages.find(it->first) == seen_languages.end()) { 1213 if (seen_languages.find(it->first) == seen_languages.end()) {
1201 output_list.push_back(it->first); 1214 output_list.push_back(it->first);
1202 seen_languages.insert(it->first); 1215 seen_languages.insert(it->first);
1203 } 1216 }
1204 output_list.push_back(it->first + "-" + it->second); 1217 if (!it->second.empty())
1218 output_list.push_back(it->first + "-" + it->second);
1205 } 1219 }
1206 1220
1207 std::reverse(output_list.begin(), output_list.end()); 1221 std::reverse(output_list.begin(), output_list.end());
1208 *accept_languages = base::JoinString(output_list, ","); 1222 *accept_languages = base::JoinString(output_list, ",");
1209 } 1223 }
1210 1224
1211 // static 1225 // static
1212 std::string PrefServiceBridge::GetAndroidPermissionForContentSetting( 1226 std::string PrefServiceBridge::GetAndroidPermissionForContentSetting(
1213 ContentSettingsType content_type) { 1227 ContentSettingsType content_type) {
1214 JNIEnv* env = AttachCurrentThread(); 1228 JNIEnv* env = AttachCurrentThread();
1215 base::android::ScopedJavaLocalRef<jstring> android_permission = 1229 base::android::ScopedJavaLocalRef<jstring> android_permission =
1216 Java_PrefServiceBridge_getAndroidPermissionForContentSetting( 1230 Java_PrefServiceBridge_getAndroidPermissionForContentSetting(
1217 env, content_type); 1231 env, content_type);
1218 if (android_permission.is_null()) 1232 if (android_permission.is_null())
1219 return std::string(); 1233 return std::string();
1220 1234
1221 return ConvertJavaStringToUTF8(android_permission); 1235 return ConvertJavaStringToUTF8(android_permission);
1222 } 1236 }
1223 1237
1224 static void SetSupervisedUserId(JNIEnv* env, 1238 static void SetSupervisedUserId(JNIEnv* env,
1225 const JavaParamRef<jobject>& obj, 1239 const JavaParamRef<jobject>& obj,
1226 const JavaParamRef<jstring>& pref) { 1240 const JavaParamRef<jstring>& pref) {
1227 GetPrefService()->SetString(prefs::kSupervisedUserId, 1241 GetPrefService()->SetString(prefs::kSupervisedUserId,
1228 ConvertJavaStringToUTF8(env, pref)); 1242 ConvertJavaStringToUTF8(env, pref));
1229 } 1243 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698