Bug 1110555 - Use real device dimensions when calculating LWT bitmap sizes. r=mhaigh, a=sledru
authorMichael Comella <michael.l.comella@gmail.com>
Fri, 23 Jan 2015 12:30:05 -0800
changeset 243021 2745f66dac6f
parent 243020 d6baa06d52b4
child 243022 e4e2855e992c
push id4364
push userryanvm@gmail.com
push date2015-01-24 16:33 +0000
treeherdermozilla-beta@34330baf2af6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhaigh, sledru
bugs1110555
milestone36.0
Bug 1110555 - Use real device dimensions when calculating LWT bitmap sizes. r=mhaigh, a=sledru Before we used DisplayMetrics.width/heightPixels, which does not include the system bars.
mobile/android/base/lwt/LightweightTheme.java
mobile/android/base/moz.build
mobile/android/base/util/WindowUtils.java
--- a/mobile/android/base/lwt/LightweightTheme.java
+++ b/mobile/android/base/lwt/LightweightTheme.java
@@ -9,31 +9,31 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.json.JSONObject;
 import org.mozilla.gecko.AppConstants.Versions;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoSharedPrefs;
 import org.mozilla.gecko.gfx.BitmapUtils;
 import org.mozilla.gecko.util.GeckoEventListener;
+import org.mozilla.gecko.util.WindowUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.util.ThreadUtils.AssertBehavior;
 
 import android.app.Application;
 import android.content.SharedPreferences;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.Shader;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
-import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewParent;
 
 public class LightweightTheme implements GeckoEventListener {
     private static final String LOGTAG = "GeckoLightweightTheme";
 
@@ -199,18 +199,17 @@ public class LightweightTheme implements
      */
     private void setLightweightTheme(Bitmap bitmap, String color) {
         if (bitmap == null || bitmap.getWidth() == 0 || bitmap.getHeight() == 0) {
             mBitmap = null;
             return;
         }
 
         // Get the max display dimension so we can crop or expand the theme.
-        DisplayMetrics dm = mApplication.getResources().getDisplayMetrics();
-        int maxWidth = Math.max(dm.widthPixels, dm.heightPixels);
+        final int maxWidth = WindowUtils.getLargestDimension(mApplication);
 
         // The lightweight theme image's width and height.
         final int bitmapWidth = bitmap.getWidth();
         final int bitmapHeight = bitmap.getHeight();
 
         try {
             mColor = Color.parseColor(color);
         } catch (Exception e) {
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -79,16 +79,17 @@ gujar.sources += [
     'util/NonEvictingLruCache.java',
     'util/PrefUtils.java',
     'util/ProxySelector.java',
     'util/RawResource.java',
     'util/StringUtils.java',
     'util/ThreadUtils.java',
     'util/UIAsyncTask.java',
     'util/WebActivityMapper.java',
+    'util/WindowUtils.java',
 ]
 gujar.extra_jars = [
     'constants.jar',
     'gecko-mozglue.jar',
 ]
 gujar.javac_flags += ['-Xlint:all,-deprecation']
 
 stjar = add_java_jar('sync-thirdparty')
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/util/WindowUtils.java
@@ -0,0 +1,62 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; 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.util;
+
+import org.mozilla.gecko.AppConstants.Versions;
+
+import android.content.Context;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Display;
+import android.view.WindowManager;
+
+import java.lang.reflect.Method;
+
+public class WindowUtils {
+    private static final String LOGTAG = "Gecko" + WindowUtils.class.getSimpleName();
+
+    private WindowUtils() { /* To prevent instantiation */ }
+
+    /**
+     * Returns the best-guess physical device dimensions, including the system status bars. Note
+     * that DisplayMetrics.height/widthPixels does not include the system bars.
+     *
+     * via http://stackoverflow.com/a/23861333
+     *
+     * @param context the calling Activity's Context
+     * @return The number of pixels of the device's largest dimension, ignoring software status bars
+     */
+    public static int getLargestDimension(final Context context) {
+        final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
+
+        if (Versions.feature17Plus) {
+            final DisplayMetrics realMetrics = new DisplayMetrics();
+            display.getRealMetrics(realMetrics);
+            return Math.max(realMetrics.widthPixels, realMetrics.heightPixels);
+
+        } else if (Versions.feature14Plus) {
+            int tempWidth;
+            int tempHeight;
+            try {
+                final Method getRawH = Display.class.getMethod("getRawHeight");
+                final Method getRawW = Display.class.getMethod("getRawWidth");
+                tempWidth = (Integer) getRawW.invoke(display);
+                tempHeight = (Integer) getRawH.invoke(display);
+            } catch (Exception e) {
+                // This is the best we can do.
+                tempWidth = display.getWidth();
+                tempHeight = display.getHeight();
+                Log.w(LOGTAG, "Couldn't use reflection to get the real display metrics.");
+            }
+
+            return Math.max(tempWidth, tempHeight);
+
+        } else {
+            // This should be close, as lower API devices should not have window navigation bars.
+            return Math.max(display.getWidth(), display.getHeight());
+        }
+    }
+}