Bug 1328868 - Part 5 - Add a Java-side listener watching the new pref and the Android system font scale. r?sebastian draft
authorJan Henning <jh+bugzilla@buttercookie.de>
Sun, 05 Feb 2017 13:22:49 +0100
changeset 551355 0554509308efc981b6b5a59df1e6d066d594af6f
parent 551348 de70a37fa4106fa84b61c263dfc2f64e86c73f62
child 551356 67cfe2d426a1e2bd34534a78286d37666313d83c
push id51034
push usermozilla@buttercookie.de
push dateSat, 25 Mar 2017 19:48:16 +0000
reviewerssebastian
bugs1328868
milestone55.0a1
Bug 1328868 - Part 5 - Add a Java-side listener watching the new pref and the Android system font scale. r?sebastian The state of the switch added in Part 4 is stored in our Android-side shared preferences. For this to have any actual effect on rendering, we now add a class that is initialised when Gecko starts up and listens to changes of that particular pref. When it is turned on, we enable font inflation and add another listener for the system font scale, which then forwards the current font scale as well as any changes to Gecko, so mobile mode pages can be scaled correspondingly as well. When the setting is turned back off again, the system font scale listener is stopped again and the Gecko font size settings reverted back to their default values. MozReview-Commit-ID: GyffpZTQQX8
mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
mobile/android/base/java/org/mozilla/gecko/GeckoFontScaleListener.java
mobile/android/base/moz.build
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
@@ -125,16 +125,17 @@ public class GeckoApplication extends Ap
 
             GeckoNetworkManager.getInstance().stop();
         }
     }
 
     public void onActivityResume(GeckoActivityStatus activity) {
         if (mIsInitialResume) {
             GeckoBatteryManager.getInstance().start(this);
+            GeckoFontScaleListener.getInstance().initialize(this);
             GeckoNetworkManager.getInstance().start(this);
             mIsInitialResume = false;
         } else if (mPausedGecko) {
             GeckoThread.onResume();
             mPausedGecko = false;
             GeckoNetworkManager.getInstance().start(this);
         }
 
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoFontScaleListener.java
@@ -0,0 +1,134 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * 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.gecko;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.provider.Settings;
+import android.support.annotation.UiThread;
+import android.util.Log;
+
+import org.mozilla.gecko.preferences.GeckoPreferences;
+
+class GeckoFontScaleListener
+        extends ContentObserver
+        implements SharedPreferences.OnSharedPreferenceChangeListener {
+    private static final String LOGTAG = "GeckoFontScaleListener";
+
+    private static final String PREF_SYSTEM_FONT_SCALE = "font.size.systemFontScale";
+    private static final String PREF_FONT_INFLATION = "font.size.inflation.minTwips";
+    private static final int FONT_INFLATION_OFF = 0;
+    private static final int FONT_INFLATION_ON_DEFAULT_VALUE = 120;
+    private static final float DEFAULT_FONT_SCALE = 1.0f;
+
+    private static final GeckoFontScaleListener listenerInstance = new GeckoFontScaleListener();
+
+    private Context applicationContext;
+    private boolean initialized;
+    private boolean running;
+
+    public static GeckoFontScaleListener getInstance() {
+        return listenerInstance;
+    }
+
+    private GeckoFontScaleListener() {
+        super(null);
+    }
+
+    public synchronized void initialize(final Context context) {
+        if (initialized) {
+            Log.w(LOGTAG, "Already initialized!");
+            return;
+        }
+
+        applicationContext = context.getApplicationContext();
+        SharedPreferences prefs = GeckoSharedPrefs.forApp(applicationContext);
+        prefs.registerOnSharedPreferenceChangeListener(this);
+        onPrefChange(prefs);
+        initialized = true;
+    }
+
+    public synchronized void shutdown() {
+        if (!initialized) {
+            Log.w(LOGTAG, "Already shut down!");
+            return;
+        }
+
+        GeckoSharedPrefs.forApp(applicationContext).unregisterOnSharedPreferenceChangeListener(this);
+        stop();
+        applicationContext = null;
+        initialized = false;
+    }
+
+    private synchronized void start() {
+        if (running) {
+            return;
+        }
+
+        ContentResolver contentResolver = applicationContext.getContentResolver();
+        Uri fontSizeSetting = Settings.System.getUriFor(Settings.System.FONT_SCALE);
+        contentResolver.registerContentObserver(fontSizeSetting, false, this);
+        onSystemFontScaleChange(contentResolver, false);
+
+        running = true;
+    }
+
+    private synchronized void stop() {
+        if (!running) {
+            return;
+        }
+
+        ContentResolver contentResolver = applicationContext.getContentResolver();
+        contentResolver.unregisterContentObserver(this);
+        onSystemFontScaleChange(contentResolver, /*stopping*/ true);
+
+        running = false;
+    }
+
+    private void onSystemFontScaleChange(final ContentResolver contentResolver, boolean stopping) {
+        float fontScale;
+        int fontInflation;
+
+        if (!stopping) { // Pref was flipped to "On" or system font scale changed.
+            fontScale = Settings.System.getFloat(contentResolver, Settings.System.FONT_SCALE, DEFAULT_FONT_SCALE);
+            fontInflation = Math.round(FONT_INFLATION_ON_DEFAULT_VALUE * fontScale);
+        } else { // Pref was flipped to "Off".
+            fontScale = DEFAULT_FONT_SCALE;
+            fontInflation = FONT_INFLATION_OFF;
+        }
+
+        PrefsHelper.setPref(PREF_FONT_INFLATION, fontInflation);
+        PrefsHelper.setPref(PREF_SYSTEM_FONT_SCALE, Math.round(fontScale * 100));
+    }
+
+    private void onPrefChange(final SharedPreferences prefs) {
+        boolean useSystemFontScale = prefs.getBoolean(GeckoPreferences.PREFS_SYSTEM_FONT_SIZE, false);
+
+        if (useSystemFontScale) {
+            start();
+        } else {
+            stop();
+        }
+    }
+
+    @Override
+    public void onChange(boolean selfChange) {
+        onSystemFontScaleChange(applicationContext.getContentResolver(), false);
+    }
+
+    @UiThread // According to the docs.
+    @Override
+    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+        if (!GeckoPreferences.PREFS_SYSTEM_FONT_SIZE.equals(key)) {
+            return;
+        }
+
+        onPrefChange(sharedPreferences);
+    }
+}
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -449,16 +449,17 @@ gbjar.sources += ['java/org/mozilla/geck
     'firstrun/RestrictedWelcomePanel.java',
     'firstrun/SyncPanel.java',
     'firstrun/TabQueuePanel.java',
     'FormAssistPopup.java',
     'GeckoActivity.java',
     'GeckoActivityStatus.java',
     'GeckoApp.java',
     'GeckoApplication.java',
+    'GeckoFontScaleListener.java',
     'GeckoJavaSampler.java',
     'GeckoMessageReceiver.java',
     'GeckoProfilesProvider.java',
     'GeckoService.java',
     'GeckoUpdateReceiver.java',
     'GlobalHistory.java',
     'GlobalPageMetadata.java',
     'GuestSession.java',