Bug 1282003 - (Part 3) Add screen ID to nsWindow and GeckoView to get the correct nsScreen and density. r?snorp draft
authorKuoE0 <kuoe0.tw@gmail.com>
Thu, 29 Sep 2016 14:23:56 +0800
changeset 426463 b85488e82b8dd84bc17a861c3378c46f5f88644f
parent 426462 026d4015c91306f354318445a8fabf4c55a5e57f
child 426464 1ccd6037dd9a43ad9167a2c554c6d35fab7abcdf
push id32690
push userbmo:kuoe0@mozilla.com
push dateTue, 18 Oct 2016 11:34:13 +0000
reviewerssnorp
bugs1282003
milestone52.0a1
Bug 1282003 - (Part 3) Add screen ID to nsWindow and GeckoView to get the correct nsScreen and density. r?snorp MozReview-Commit-ID: Cd9MS2I1RRQ
gfx/src/nsDeviceContext.cpp
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
widget/android/GeneratedJNIWrappers.h
widget/android/nsWindow.cpp
widget/android/nsWindow.h
widget/nsBaseWidget.h
widget/nsIWidget.h
--- a/gfx/src/nsDeviceContext.cpp
+++ b/gfx/src/nsDeviceContext.cpp
@@ -1,9 +1,10 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 ts=4 expandtab: */
 /* 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/. */
 
 #include "nsDeviceContext.h"
 #include <algorithm>                    // for max
 #include "gfxASurface.h"                // for gfxASurface, etc
 #include "gfxContext.h"
@@ -606,17 +607,25 @@ nsDeviceContext::FindScreen(nsIScreen** 
     if (mWidget->GetOwningTabChild()) {
         mScreenManager->ScreenForNativeWidget((void *)mWidget->GetOwningTabChild(),
                                               outScreen);
     }
     else if (mWidget->GetNativeData(NS_NATIVE_WINDOW)) {
         mScreenManager->ScreenForNativeWidget(mWidget->GetNativeData(NS_NATIVE_WINDOW),
                                               outScreen);
     }
-    else {
+
+#ifdef MOZ_WIDGET_ANDROID
+    if (!(*outScreen)) {
+        nsCOMPtr<nsIScreen> screen = mWidget->GetWidgetScreen();
+        screen.forget(outScreen);
+    }
+#endif
+
+    if (!(*outScreen)) {
         mScreenManager->GetPrimaryScreen(outScreen);
     }
 }
 
 bool
 nsDeviceContext::CalcPrintingSize()
 {
     if (!mPrintTarget) {
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
@@ -1,9 +1,10 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * vim: ts=4 sw=4 expandtab:
  * 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 java.util.Set;
 
@@ -43,16 +44,17 @@ public class GeckoView extends LayerView
     private static final String LOGTAG = "GeckoView";
 
     private ChromeDelegate mChromeDelegate;
     private ContentDelegate mContentDelegate;
 
     private InputConnectionListener mInputConnectionListener;
 
     private boolean onAttachedToWindowCalled;
+    private int screenId = 0; // default to the primary screen
 
     @Override
     public void handleMessage(final String event, final JSONObject message) {
         ThreadUtils.postToUiThread(new Runnable() {
             @Override
             public void run() {
                 try {
                     if (event.equals("Gecko:Ready")) {
@@ -109,17 +111,17 @@ public class GeckoView extends LayerView
     }
 
     @WrapForJNI(dispatchTo = "proxy")
     private static final class Window extends JNIObject {
         @WrapForJNI(skip = true)
         /* package */ Window() {}
 
         static native void open(Window instance, GeckoView view, Object compositor,
-                                String chromeURI);
+                                String chromeURI, int screenId);
 
         @Override protected native void disposeNative();
         native void close();
         native void reattach(GeckoView view, Object compositor);
         native void loadUri(String uri, int flags);
     }
 
     // Object to hold onto our nsWindow connection when GeckoView gets destroyed.
@@ -224,21 +226,21 @@ public class GeckoView extends LayerView
         super.onRestoreInstanceState(stateBinder.superState);
     }
 
     private void openWindow() {
         final String chromeURI = getGeckoInterface().getDefaultChromeURI();
 
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
             Window.open(window, this, getCompositor(),
-                        chromeURI);
+                        chromeURI, screenId);
         } else {
             GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY, Window.class,
                     "open", window, GeckoView.class, this, Object.class, getCompositor(),
-                    String.class, chromeURI);
+                    String.class, chromeURI, screenId);
         }
     }
 
     private void reattachWindow() {
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
             window.reattach(this, getCompositor());
         } else {
             GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -3269,20 +3269,21 @@ public:
     struct Open_t {
         typedef Window Owner;
         typedef void ReturnType;
         typedef void SetterType;
         typedef mozilla::jni::Args<
                 Window::Param,
                 GeckoView::Param,
                 mozilla::jni::Object::Param,
-                mozilla::jni::String::Param> Args;
+                mozilla::jni::String::Param,
+                int32_t> Args;
         static constexpr char name[] = "open";
         static constexpr char signature[] =
-                "(Lorg/mozilla/gecko/GeckoView$Window;Lorg/mozilla/gecko/GeckoView;Ljava/lang/Object;Ljava/lang/String;)V";
+                "(Lorg/mozilla/gecko/GeckoView$Window;Lorg/mozilla/gecko/GeckoView;Ljava/lang/Object;Ljava/lang/String;I)V";
         static const bool isStatic = true;
         static const mozilla::jni::ExceptionMode exceptionMode =
                 mozilla::jni::ExceptionMode::ABORT;
         static const mozilla::jni::CallingThread callingThread =
                 mozilla::jni::CallingThread::ANY;
         static const mozilla::jni::DispatchTarget dispatchTarget =
                 mozilla::jni::DispatchTarget::PROXY;
     };
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -1,9 +1,10 @@
 /* -*- Mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * vim: set sw=4 ts=4 expandtab:
  * 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/. */
 
 #include <android/log.h>
 #include <android/native_window.h>
 #include <android/native_window_jni.h>
 #include <math.h>
@@ -340,17 +341,18 @@ public:
 private:
     nsCOMPtr<nsPIDOMWindowOuter> mDOMWindow;
 
 public:
     // Create and attach a window.
     static void Open(const jni::Class::LocalRef& aCls,
                      GeckoView::Window::Param aWindow,
                      GeckoView::Param aView, jni::Object::Param aCompositor,
-                     jni::String::Param aChromeURI);
+                     jni::String::Param aChromeURI,
+                     int32_t screenId);
 
     // Close and destroy the nsWindow.
     void Close();
 
     // Reattach this nsWindow to a new GeckoView.
     void Reattach(const GeckoView::Window::LocalRef& inst,
                   GeckoView::Param aView, jni::Object::Param aCompositor);
 
@@ -1314,17 +1316,18 @@ nsWindow::GeckoViewSupport::~GeckoViewSu
     }
 }
 
 /* static */ void
 nsWindow::GeckoViewSupport::Open(const jni::Class::LocalRef& aCls,
                                  GeckoView::Window::Param aWindow,
                                  GeckoView::Param aView,
                                  jni::Object::Param aCompositor,
-                                 jni::String::Param aChromeURI)
+                                 jni::String::Param aChromeURI,
+                                 int32_t aScreenId)
 {
     MOZ_ASSERT(NS_IsMainThread());
 
     PROFILER_LABEL("nsWindow", "GeckoViewSupport::Open",
                    js::ProfileEntry::Category::OTHER);
 
     nsCOMPtr<nsIWindowWatcher> ww = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
     MOZ_RELEASE_ASSERT(ww);
@@ -1345,16 +1348,17 @@ nsWindow::GeckoViewSupport::Open(const j
     MOZ_RELEASE_ASSERT(domWindow);
 
     nsCOMPtr<nsPIDOMWindowOuter> pdomWindow =
             nsPIDOMWindowOuter::From(domWindow);
     nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(pdomWindow);
     MOZ_ASSERT(widget);
 
     const auto window = static_cast<nsWindow*>(widget.get());
+    window->SetScreenId(aScreenId);
 
     // Attach a new GeckoView support object to the new window.
     window->mGeckoViewSupport  = mozilla::MakeUnique<GeckoViewSupport>(
             window, GeckoView::Window::LocalRef(aCls.Env(), aWindow), aView);
 
     window->mGeckoViewSupport->mDOMWindow = pdomWindow;
 
     // Attach the Compositor to the new window.
@@ -1487,16 +1491,17 @@ nsWindow::DumpWindows(const nsTArray<nsW
     for (uint32_t i = 0; i < wins.Length(); ++i) {
         nsWindow *w = wins[i];
         LogWindow(w, i, indent);
         DumpWindows(w->mChildren, indent+1);
     }
 }
 
 nsWindow::nsWindow() :
+    mScreenId(0), // Use 0 (primary screen) as the default value.
     mIsVisible(false),
     mParent(nullptr),
     mAwaitingFullScreen(false),
     mIsFullScreen(false)
 {
 }
 
 nsWindow::~nsWindow()
@@ -1648,29 +1653,21 @@ nsWindow::GetDPI()
     if (AndroidBridge::Bridge())
         return AndroidBridge::Bridge()->GetDPI();
     return 160.0f;
 }
 
 double
 nsWindow::GetDefaultScaleInternal()
 {
-    static double density = 0.0;
-
-    if (density != 0.0) {
-        return density;
-    }
-
-    density = GeckoAppShell::GetDensity();
-
-    if (!density) {
-        density = 1.0;
-    }
-
-    return density;
+
+    nsCOMPtr<nsIScreen> screen = GetWidgetScreen();
+    MOZ_ASSERT(screen);
+    RefPtr<nsScreenAndroid> screenAndroid = (nsScreenAndroid*) screen.get();
+    return screenAndroid->GetDensity();
 }
 
 NS_IMETHODIMP
 nsWindow::Show(bool aState)
 {
     ALOG("nsWindow[%p]::Show %d", (void*)this, aState);
 
     if (mWindowType == eWindowType_invisible) {
@@ -3592,17 +3589,30 @@ nsWindow::UpdateZoomConstraints(const ui
                                 const mozilla::Maybe<ZoomConstraints>& aConstraints)
 {
     nsBaseWidget::UpdateZoomConstraints(aPresShellId, aViewId, aConstraints);
 }
 
 CompositorBridgeParent*
 nsWindow::GetCompositorBridgeParent() const
 {
-  return mCompositorSession ? mCompositorSession->GetInProcessBridge() : nullptr;
+    return mCompositorSession ? mCompositorSession->GetInProcessBridge() : nullptr;
+}
+
+already_AddRefed<nsIScreen>
+nsWindow::GetWidgetScreen()
+{
+    nsCOMPtr<nsIScreenManager> screenMgr =
+        do_GetService("@mozilla.org/gfx/screenmanager;1");
+    MOZ_ASSERT(screenMgr, "Failed to get nsIScreenManager");
+
+    nsCOMPtr<nsIScreen> screen;
+    screenMgr->ScreenForId(mScreenId, getter_AddRefs(screen));
+
+    return screen.forget();
 }
 
 jni::DependentRef<java::GeckoLayerClient>
 nsWindow::GetLayerClient()
 {
     if (NativePtr<LayerViewSupport>::Locked lvs{mLayerViewSupport}) {
         return lvs->GetLayerClient().Get();
     }
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -1,9 +1,10 @@
 /* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * vim: set sw=4 ts=4 expandtab:
  * 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/. */
 
 #ifndef NSWINDOW_H_
 #define NSWINDOW_H_
 
 #include "nsBaseWidget.h"
@@ -40,18 +41,21 @@ private:
 public:
     using nsBaseWidget::GetLayerManager;
 
     nsWindow();
 
     NS_DECL_ISUPPORTS_INHERITED
 
     static void InitNatives();
+    void SetScreenId(uint32_t aScreenId) { mScreenId = aScreenId; }
 
 private:
+    uint32_t mScreenId;
+
     // An Event subclass that guards against stale events.
     template<typename Lambda,
              bool IsStatic = Lambda::isStatic,
              typename InstanceType = typename Lambda::ThisArgType,
              class Impl = typename Lambda::TargetClass>
     class WindowEvent;
 
     // Smart pointer for holding a pointer back to the nsWindow inside a native
@@ -160,16 +164,17 @@ public:
     virtual bool IsEnabled() const override;
     NS_IMETHOD Invalidate(const LayoutDeviceIntRect& aRect) override;
     NS_IMETHOD SetFocus(bool aRaise = false) override;
     virtual LayoutDeviceIntRect GetScreenBounds() override;
     virtual LayoutDeviceIntPoint WidgetToScreenOffset() override;
     NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
                              nsEventStatus& aStatus) override;
     nsEventStatus DispatchEvent(mozilla::WidgetGUIEvent* aEvent);
+    virtual already_AddRefed<nsIScreen> GetWidgetScreen() override;
     virtual nsresult MakeFullScreen(bool aFullScreen,
                                     nsIScreen* aTargetScreen = nullptr)
                                     override;
 
     NS_IMETHOD SetCursor(nsCursor aCursor) override { return NS_ERROR_NOT_IMPLEMENTED; }
     NS_IMETHOD SetCursor(imgIContainer* aCursor,
                          uint32_t aHotspotX,
                          uint32_t aHotspotY) override { return NS_ERROR_NOT_IMPLEMENTED; }
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -178,16 +178,17 @@ public:
   virtual void            SetShowsFullScreenButton(bool aShow) override {}
   virtual void            SetWindowAnimationType(WindowAnimationType aType) override {}
   NS_IMETHOD              HideWindowChrome(bool aShouldHide) override;
   virtual bool PrepareForFullscreenTransition(nsISupports** aData) override { return false; }
   virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage,
                                            uint16_t aDuration,
                                            nsISupports* aData,
                                            nsIRunnable* aCallback) override;
+  virtual already_AddRefed<nsIScreen> GetWidgetScreen() override;
   virtual nsresult        MakeFullScreen(bool aFullScreen,
                                          nsIScreen* aScreen = nullptr) override;
   void                    InfallibleMakeFullScreen(bool aFullScreen,
                                                    nsIScreen* aScreen = nullptr);
 
   virtual LayerManager*   GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr,
                                           LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
                                           LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT) override;
@@ -334,19 +335,16 @@ public:
   nsPopupLevel PopupLevel() { return mPopupLevel; }
 
   virtual LayoutDeviceIntSize
   ClientToWindowSize(const LayoutDeviceIntSize& aClientSize) override
   {
     return aClientSize;
   }
 
-  // return the screen the widget is in.
-  already_AddRefed<nsIScreen> GetWidgetScreen();
-
   // return true if this is a popup widget with a native titlebar
   bool IsPopupWithTitleBar() const
   {
     return (mWindowType == eWindowType_popup &&
             mBorderStyle != eBorderStyle_default &&
             mBorderStyle & eBorderStyle_title);
   }
 
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -1187,16 +1187,21 @@ class nsIWidget : public nsISupports
      * finishes.
      */
     virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage,
                                              uint16_t aDuration,
                                              nsISupports* aData,
                                              nsIRunnable* aCallback) = 0;
 
     /**
+     * Return the screen the widget is in, or null if we don't know.
+     */
+    virtual already_AddRefed<nsIScreen> GetWidgetScreen() = 0;
+
+    /**
      * Put the toplevel window into or out of fullscreen mode.
      * If aTargetScreen is given, attempt to go fullscreen on that screen,
      * if possible.  (If not, it behaves as if aTargetScreen is null.)
      * If !aFullScreen, aTargetScreen is ignored.
      * aTargetScreen support is currently only implemented on Windows.
      *
      * @return NS_OK if the widget is setup properly for fullscreen and
      * FullscreenChanged callback has been or will be called. If other