diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java index 82ab1df6c217..8c97b4e68087 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java @@ -13,6 +13,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.PipedInputStream; import java.io.PipedOutputStream; +import java.lang.IllegalStateException; import java.net.MalformedURLException; import java.net.Proxy; import java.net.URLConnection; @@ -238,6 +239,8 @@ public class GeckoAppShell @WrapForJNI(dispatchTo = "gecko") public static native void notifyUriVisited(String uri); + private static Rect sScreenSizeOverride; + @WrapForJNI(stubName = "NotifyObservers", dispatchTo = "gecko") private static native void nativeNotifyObservers(String topic, String data); @@ -983,16 +986,30 @@ public class GeckoAppShell getNotificationListener().closeNotification(name); } + public static synchronized void setDisplayDpiOverride(final Integer dpi) { + if (dpi == null) { + return; + } + if (sDensityDpi != 0) { + Log.e(LOGTAG, "Tried to override screen DPI after it's already been set"); + throw new IllegalStateException(); + } + sDensityDpi = dpi; + } + @WrapForJNI(calledFrom = "gecko") - public static int getDpi() { + public static synchronized int getDpi() { if (sDensityDpi == 0) { sDensityDpi = getApplicationContext().getResources().getDisplayMetrics().densityDpi; } - return sDensityDpi; } public static synchronized void setDisplayDensityOverride(@Nullable Float density) { + if (sDensity != null) { + Log.e(LOGTAG, "Tried to override screen density after it's already been set"); + throw new IllegalStateException(); + } sDensity = density; } @@ -1033,7 +1050,7 @@ public class GeckoAppShell private static synchronized void setScreenDepthOverride(int aScreenDepth) { if (sScreenDepth != 0) { Log.e(LOGTAG, "Tried to override screen depth after it's already been set"); - return; + throw new IllegalStateException(); } sScreenDepth = aScreenDepth; @@ -1823,8 +1840,15 @@ public class GeckoAppShell return 0; } + public static synchronized void setScreenSizeOverride(final Rect size) { + sScreenSizeOverride = size; + } + @WrapForJNI(calledFrom = "gecko") - private static Rect getScreenSize() { + private static synchronized Rect getScreenSize() { + if (sScreenSizeOverride != null) { + return sScreenSizeOverride; + } final WindowManager wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE); final Display disp = wm.getDefaultDisplay(); diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java index 70fb49d70860..ac444f1233bf 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java @@ -109,6 +109,8 @@ public final class GeckoRuntime implements Parcelable { } GeckoAppShell.setDisplayDensityOverride(settings.getDisplayDensityOverride()); + GeckoAppShell.setDisplayDpiOverride(settings.getDisplayDpiOverride()); + GeckoAppShell.setScreenSizeOverride(settings.getScreenSizeOverride()); final int crashReportingJobId = settings.getCrashReportingServiceJobId(); settings.getExtras().putInt( diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java index b20149fe49fb..c1c194b27af9 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java @@ -9,6 +9,7 @@ package org.mozilla.geckoview; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import android.graphics.Rect; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -278,6 +279,30 @@ public final class GeckoRuntimeSettings implements Parcelable { mSettings.mSafebrowsingPhishing.set(enabled); return this; } + + /** + * Set the display DPI override. + * + * @param dpi The display DPI value to use for overriding the system default. + * @return The builder instance. + */ + public @NonNull Builder displayDpiOverride(int dpi) { + mSettings.mDisplayDpiOverride = dpi; + return this; + } + + /** + * Set the screen size override. + * + * @param width The screen width value to use for overriding the system default. + * @param height The screen height value to use for overriding the system default. + * @return The builder instance. + */ + public @NonNull Builder screenSizeOverride(int width, int height) { + mSettings.mScreenWidthOverride = width; + mSettings.mScreenHeightOverride = height; + return this; + } } /* package */ GeckoRuntime runtime; @@ -346,6 +371,9 @@ public final class GeckoRuntimeSettings implements Parcelable { /* package */ int mCrashReportingJobId; /* package */ boolean mDebugPause; /* package */ float mDisplayDensityOverride = -1.0f; + /* package */ int mDisplayDpiOverride; + /* package */ int mScreenWidthOverride; + /* package */ int mScreenHeightOverride; private final Pref[] mPrefs = new Pref[] { mCookieBehavior, mCookieLifetime, mConsoleOutput, @@ -387,6 +415,9 @@ public final class GeckoRuntimeSettings implements Parcelable { mCrashReportingJobId = settings.mCrashReportingJobId; mDebugPause = settings.mDebugPause; mDisplayDensityOverride = settings.mDisplayDensityOverride; + mDisplayDpiOverride = settings.mDisplayDpiOverride; + mScreenWidthOverride = settings.mScreenWidthOverride; + mScreenHeightOverride = settings.mScreenHeightOverride; } /* package */ void flush() { @@ -521,7 +552,32 @@ public final class GeckoRuntimeSettings implements Parcelable { */ public Float getDisplayDensityOverride() { if (mDisplayDensityOverride > 0.0f) { - return new Float(mDisplayDensityOverride); + return mDisplayDensityOverride; + } + return null; + } + + /** + * Gets the display DPI override value. + * + * @return Returns a positive number. Will return null if not set. + */ + public Integer getDisplayDpiOverride() { + if (mDisplayDpiOverride > 0) { + return mDisplayDpiOverride; + } + return null; + } + + /** + * Gets the screen size override value. + * + * @return Returns a Rect containing the dimensions to use for the window size. + * Will return null if not set. + */ + public Rect getScreenSizeOverride() { + if ((mScreenWidthOverride > 0) && (mScreenHeightOverride > 0)) { + return new Rect(0, 0, mScreenWidthOverride, mScreenHeightOverride); } return null; } @@ -733,6 +789,9 @@ public final class GeckoRuntimeSettings implements Parcelable { out.writeInt(mCrashReportingJobId); ParcelableUtils.writeBoolean(out, mDebugPause); out.writeFloat(mDisplayDensityOverride); + out.writeInt(mDisplayDpiOverride); + out.writeInt(mScreenWidthOverride); + out.writeInt(mScreenHeightOverride); } // AIDL code may call readFromParcel even though it's not part of Parcelable. @@ -753,6 +812,9 @@ public final class GeckoRuntimeSettings implements Parcelable { mCrashReportingJobId = source.readInt(); mDebugPause = ParcelableUtils.readBoolean(source); mDisplayDensityOverride = source.readFloat(); + mDisplayDpiOverride = source.readInt(); + mScreenWidthOverride = source.readInt(); + mScreenHeightOverride = source.readInt(); } public static final Parcelable.Creator CREATOR