Index: chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java |
index 2bd35ad4d8e3bba2dd24ddf461955c3a54641e7d..c618d54f9f1d96765077dcc65d5b6d3fc252bca9 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/PwsClientImpl.java |
@@ -8,6 +8,11 @@ import android.content.Context; |
import android.graphics.Bitmap; |
import android.os.AsyncTask; |
import android.os.Build; |
+import android.text.TextUtils; |
+ |
+import org.json.JSONArray; |
+import org.json.JSONException; |
+import org.json.JSONObject; |
import org.chromium.base.Log; |
import org.chromium.base.ThreadUtils; |
@@ -18,14 +23,12 @@ import org.chromium.chrome.browser.ChromeVersionInfo; |
import org.chromium.chrome.browser.physicalweb.PwsClient.FetchIconCallback; |
import org.chromium.chrome.browser.physicalweb.PwsClient.ResolveScanCallback; |
-import org.json.JSONArray; |
-import org.json.JSONException; |
-import org.json.JSONObject; |
- |
import java.net.MalformedURLException; |
import java.util.ArrayList; |
import java.util.Collection; |
+import java.util.Collections; |
import java.util.Formatter; |
+import java.util.HashSet; |
import java.util.Locale; |
/** |
@@ -263,35 +266,55 @@ class PwsClientImpl implements PwsClient { |
* Get the language code for the default locale and prepend it to the Accept-Language string if |
* it isn't already present. The logic should match PrependToAcceptLanguagesIfNecessary in |
* chrome/browser/android/preferences/pref_service_bridge.cc |
- * @param locale A string representing the default locale. |
+ * @param locales A string representing a default locale or a list of default locales. |
* @param acceptLanguages The default language list for the language of the user's locale. |
* @return An updated language list. |
*/ |
@VisibleForTesting |
- static String prependToAcceptLanguagesIfNecessary(String locale, String acceptLanguages) |
- { |
- if (locale.length() != 5 || locale.charAt(2) != '_') { |
- return acceptLanguages; |
- } |
+ static String prependToAcceptLanguagesIfNecessary(String locales, String acceptLanguages) { |
+ String localeString = locales + "," + acceptLanguages; |
+ String[] localeList = localeString.split(","); |
+ |
+ HashSet<String> seenLocales = new HashSet<>(); |
+ ArrayList<String> uniqueList = new ArrayList<>(); |
+ for (String locale : localeList) { |
+ // TODO(yirui): Support BCP47 compliant format including 3-letter country code, |
+ // '-' separator and missing country case. |
+ if (locale.length() != 5 || (locale.charAt(2) != '_' && locale.charAt(2) != '-')) { |
+ // Skip checking not well formed locales. |
+ continue; |
+ } |
- String language = locale.substring(0, 2); |
- String region = locale.substring(3); |
- String languageTag = makeLanguageTag(language, region); |
+ String language = locale.substring(0, 2); |
+ String country = locale.substring(3); |
+ String languageTag = makeLanguageTag(language, country); |
- if (acceptLanguages.contains(languageTag)) { |
- return acceptLanguages; |
+ if (seenLocales.contains(languageTag)) { |
+ continue; |
+ } |
+ uniqueList.add(languageTag); |
+ seenLocales.add(languageTag); |
} |
- Formatter parts = new Formatter(); |
- parts.format("%s,", languageTag); |
// If language is not in the accept languages list, also add language code. |
- // This will work with the IDS_ACCEPT_LANGUAGES localized strings bundled with Chrome but |
- // may fail on arbitrary lists of language tags due to differences in case and whitespace. |
- if (!acceptLanguages.contains(language + ",") && !acceptLanguages.endsWith(language)) { |
- parts.format("%s,", language); |
+ // A language code should only be inserted after the last languageTag that |
+ // contains that language. |
+ // This will work with the IDS_ACCEPT_LANGUAGE localized strings bundled |
+ // with Chrome but may fail on arbitrary lists of language tags due to |
+ // differences in case and whitespace. |
+ HashSet<String> seenLanguages = new HashSet<>(); |
+ ArrayList<String> outputList = new ArrayList<>(); |
+ for (int i = uniqueList.size() - 1; i >= 0; i--) { |
+ String localeAdd = uniqueList.get(i); |
+ String languageAdd = localeAdd.substring(0, 2); |
+ if (!seenLanguages.contains(languageAdd)) { |
+ seenLanguages.add(languageAdd); |
+ outputList.add(languageAdd); |
+ } |
+ outputList.add(localeAdd); |
} |
- parts.format("%s", acceptLanguages); |
- return parts.toString(); |
+ Collections.reverse(outputList); |
+ return TextUtils.join(",", outputList); |
} |
/** |