Bug 1378501 - Tell Gecko when the OS locale changes, even when backgrounded. r=mcomella,gandalf draft
authorRichard Newman <rnewman@mozilla.com>
Fri, 08 Sep 2017 07:54:13 -0700
changeset 662618 8a9c0ceea1cba22703c53c4f97b59a7fd88c3248
parent 662454 0495d0052c24fcc9fb7f3d6d96b06314e8fd3234
child 730919 1eaf236821a7e788d4941c9f9fecb343ef803334
push id79136
push userrnewman@mozilla.com
push dateMon, 11 Sep 2017 21:23:26 +0000
reviewersmcomella, gandalf
bugs1378501, 1397925
milestone57.0a1
Bug 1378501 - Tell Gecko when the OS locale changes, even when backgrounded. r=mcomella,gandalf This ensures that `intl.locale.os` is always set, even if the system locale changes while Fennec is in the background. This commit also restores `Strings.flush()` calls that are necessary to have Fennec's non-Java UI reflect locale changes. With this commit, the geolocation popup still doesn't behave correctly: when the locale system is set to match OS locale, although the pref is set the locale doesn't change. This applies in two scenarios: on first run (the popup is always English) and when the locale changes at runtime (the popup uses an earlier OS locale). Bug 1397925 should complete the fix. MozReview-Commit-ID: 8zeZuYXFYdy
mobile/android/base/java/org/mozilla/gecko/BrowserLocaleManager.java
mobile/android/chrome/content/browser.js
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserLocaleManager.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserLocaleManager.java
@@ -101,16 +101,20 @@ public class BrowserLocaleManager implem
                 // habit of mutating it! Use the one Android supplies, because
                 // that gets regularly reset.
                 // The default value of systemLocale is fine, because we haven't
                 // yet swizzled Locale during static initialization.
                 systemLocale = context.getResources().getConfiguration().locale;
                 systemLocaleDidChange = true;
 
                 Log.d(LOG_TAG, "System locale changed from " + current + " to " + systemLocale);
+
+                // If the OS locale changed, we need to tell Gecko.
+                final SharedPreferences prefs = GeckoSharedPrefs.forProfile(context);
+                BrowserLocaleManager.storeAndNotifyOSLocale(prefs, systemLocale);
             }
         };
         context.registerReceiver(receiver, new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
     }
 
     @Override
     public boolean systemLocaleDidChange() {
         return systemLocaleDidChange;
@@ -203,26 +207,28 @@ public class BrowserLocaleManager implem
         if (osLocale == null) {
             return;
         }
 
         final String lastOSLocale = prefs.getString("osLocale", null);
         final String osLocaleString = osLocale.toString();
 
         if (osLocaleString.equals(lastOSLocale)) {
+            Log.d(LOG_TAG, "Previous locale " + lastOSLocale + " same as new. Doing nothing.");
             return;
         }
 
         // Store the Java-native form.
         prefs.edit().putString("osLocale", osLocaleString).apply();
 
         // The value we send to Gecko should be a language tag, not
         // a Java locale string.
         final GeckoBundle data = new GeckoBundle(1);
         data.putString("languageTag", Locales.getLanguageTag(osLocale));
+
         EventDispatcher.getInstance().dispatch("Locale:OS", data);
     }
 
     @Override
     public String getAndApplyPersistedLocale(Context context) {
         initialize(context);
 
         final long t1 = android.os.SystemClock.uptimeMillis();
@@ -299,16 +305,20 @@ public class BrowserLocaleManager implem
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
             config.setLayoutDirection(locale);
         }
 
         res.updateConfiguration(config, null);
     }
 
     private SharedPreferences getSharedPreferences(Context context) {
+        // We should be using per-profile prefs here, because we're tracking against
+        // a Gecko pref. The same applies to the locale switcher!
+        // Bug 940575, Bug 873166 are relevant, and see Bug 1378501 for the commit
+        // that added this comment.
         return GeckoSharedPrefs.forApp(context);
     }
 
     /**
      * @return the persisted locale in Java format: "en_US".
      */
     private String getPersistedLocale(Context context) {
         final SharedPreferences settings = getSharedPreferences(context);
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1737,26 +1737,34 @@ var BrowserApp = {
         // Ensure that this choice is immediately persisted, because
         // Gecko won't be told again if it forgets.
         Services.prefs.setCharPref("intl.locale.os", languageTag);
         Services.prefs.savePrefFile(null);
 
         let appLocale = this.getUALocalePref();
 
         this.computeAcceptLanguages(languageTag, appLocale);
+
+        // Rebuild strings, in case we're mirroring OS locale.
+        Strings.flush();
         break;
       }
 
       case "Locale:Changed": {
         if (data) {
           Services.locale.setRequestedLocales([data.languageTag]);
         } else {
           Services.locale.setRequestedLocales([]);
         }
 
+        console.log("Gecko display locale: " + this.getUALocalePref());
+
+        // Rebuild strings to reflect the new locale.
+        Strings.flush();
+
         // Make sure we use the right Accept-Language header.
         let osLocale;
         try {
           // This should never not be set at this point, but better safe than sorry.
           osLocale = Services.prefs.getCharPref("intl.locale.os");
         } catch (e) {
         }