Bug 1543823 - Compute Accept-Language header based on app and OS prefs. r=snorp
authorMatt Brubeck <mbrubeck@mozilla.com>
Mon, 13 May 2019 20:52:10 +0000
changeset 532973 357afb47596887ce6037200334ba7e2d1360bc52
parent 532972 2c5b7adbd1b03ca6e2fb36dbe52dba5633a66973
child 532974 45917510825962e52348c2d3abc18ae84d2ae6ee
push id11276
push userrgurzau@mozilla.com
push dateMon, 20 May 2019 13:11:24 +0000
treeherdermozilla-beta@847755a7c325 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1543823
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1543823 - Compute Accept-Language header based on app and OS prefs. r=snorp Differential Revision: https://phabricator.services.mozilla.com/D30946
mobile/android/components/geckoview/GeckoViewStartup.js
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java
--- a/mobile/android/components/geckoview/GeckoViewStartup.js
+++ b/mobile/android/components/geckoview/GeckoViewStartup.js
@@ -159,15 +159,20 @@ GeckoViewStartup.prototype = {
             prefs.set(name, aData[name]);
           } catch (e) {
             warn `Failed to set preference ${name}: ${e}`;
           }
         }
         break;
       }
       case "GeckoView:SetLocale":
-        Services.locale.requestedLocales = aData.requestedLocales;
+        if (aData.requestedLocales) {
+          Services.locale.requestedLocales = aData.requestedLocales;
+        }
+        let pls = Cc["@mozilla.org/pref-localizedstring;1"].createInstance(Ci.nsIPrefLocalizedString);
+        pls.data = aData.acceptLanguages;
+        Services.prefs.setComplexValue("intl.accept_languages", Ci.nsIPrefLocalizedString, pls);
         break;
     }
   },
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([GeckoViewStartup]);
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java
@@ -3,26 +3,31 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.geckoview;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Locale;
 
 import android.app.Service;
 import android.graphics.Rect;
+import android.os.Build;
 import android.os.Bundle;
+import android.os.LocaleList;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.support.annotation.AnyThread;
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.text.TextUtils;
 
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.util.GeckoBundle;
 
 @AnyThread
 public final class GeckoRuntimeSettings extends RuntimeSettings {
     /**
      * Settings builder used to construct the settings object.
@@ -646,24 +651,76 @@ public final class GeckoRuntimeSettings 
      * @param requestedLocales An ordered list of locales in Gecko format ("en-US").
      */
     public void setLocales(final @Nullable String[] requestedLocales) {
         mRequestedLocales = requestedLocales;
         commitLocales();
     }
 
     private void commitLocales() {
-        if (mRequestedLocales == null) {
-            return;
-        }
         final GeckoBundle data = new GeckoBundle(1);
         data.putStringArray("requestedLocales", mRequestedLocales);
+        data.putString("acceptLanguages", computeAcceptLanguages());
         EventDispatcher.getInstance().dispatch("GeckoView:SetLocale", data);
     }
 
+    private String computeAcceptLanguages() {
+        ArrayList<String> locales = new ArrayList<String>();
+
+        // Explicitly-set app prefs come first:
+        if (mRequestedLocales != null) {
+            for (String locale : mRequestedLocales) {
+                locales.add(locale.toLowerCase());
+            }
+        }
+        // OS prefs come second:
+        for (String locale : getDefaultLocales()) {
+            locale = locale.toLowerCase();
+            if (!locales.contains(locale)) {
+                locales.add(locale);
+            }
+        }
+
+        return TextUtils.join(",", locales);
+    }
+
+    private static String[] getDefaultLocales() {
+        if (Build.VERSION.SDK_INT >= 24) {
+            final LocaleList localeList = LocaleList.getDefault();
+            String[] locales = new String[localeList.size()];
+            for (int i = 0; i < localeList.size(); i++) {
+                locales[i] = localeList.get(i).toLanguageTag();
+            }
+            return locales;
+        }
+        String[] locales = new String[1];
+        final Locale locale = Locale.getDefault();
+        if (Build.VERSION.SDK_INT >= 21) {
+            locales[0] = locale.toLanguageTag();
+            return locales;
+        }
+
+        locales[0] = getLanguageTag(locale);
+        return locales;
+    }
+
+    private static String getLanguageTag(final Locale locale) {
+        final StringBuilder out = new StringBuilder(locale.getLanguage());
+        final String country = locale.getCountry();
+        final String variant = locale.getVariant();
+        if (!TextUtils.isEmpty(country)) {
+            out.append('-').append(country);
+        }
+        if (!TextUtils.isEmpty(variant)) {
+            out.append('-').append(variant);
+        }
+        // e.g. "en", "en-US", or "en-US-POSIX".
+        return out.toString();
+    }
+
     /**
      * Set whether or not web console messages should go to logcat.
      *
      * Note: If enabled, Gecko performance may be negatively impacted if
      * content makes heavy use of the console API.
      *
      * @param enabled A flag determining whether or not web console messages should be
      *                printed to logcat.