Bug 1282003 - (Part 1) Add display type/density info and addScreen/removeScreen function. r=snorp
☠☠ backed out by ef345e3b5fa9 ☠ ☠
authorKuoE0 <kuoe0.tw@gmail.com>
Mon, 03 Oct 2016 16:23:23 +0800
changeset 316867 ddf5af982d8b7a4258b3a6e05ee4c76ce66af605
parent 316866 80d979342a04c163156c1b74235cb9c24f850658
child 316868 13db73034f80ba7dba3c0665380b86d23ddb38ea
push id82557
push userphilringnalda@gmail.com
push dateFri, 07 Oct 2016 03:26:33 +0000
treeherdermozilla-inbound@e907031a1612 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1282003
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1282003 - (Part 1) Add display type/density info and addScreen/removeScreen function. r=snorp MozReview-Commit-ID: 52IoWc1xevL
widget/android/nsScreenManagerAndroid.cpp
widget/android/nsScreenManagerAndroid.h
widget/nsIScreen.idl
--- a/widget/android/nsScreenManagerAndroid.cpp
+++ b/widget/android/nsScreenManagerAndroid.cpp
@@ -1,41 +1,65 @@
-/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
+/* -*- Mode: C++; tab-width: 40; 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/. */
 
 #define MOZ_FATAL_ASSERTIONS_FOR_THREAD_SAFETY
 
 #include "nsScreenManagerAndroid.h"
 #include "nsWindow.h"
 #include "GeneratedJNIWrappers.h"
+#include "AndroidBridge.h"
 #include "AndroidRect.h"
 #include <mozilla/jni/Refs.h>
 
+#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "nsScreenManagerAndroid", ## args)
+
 using namespace mozilla;
 
-nsScreenAndroid::nsScreenAndroid(void *nativeScreen)
+static uint32_t sScreenId = 0;
+const uint32_t PRIMARY_SCREEN_ID = 0;
+
+nsScreenAndroid::nsScreenAndroid(DisplayType aDisplayType, nsIntRect aRect)
+    : mId(sScreenId++)
+    , mDisplayType(aDisplayType)
+    , mRect(aRect)
+    , mDensity(mozilla::java::GeckoAppShell::GetDensity())
 {
+    // ensure that the ID of the primary screen would be PRIMARY_SCREEN_ID.
+    if (mDisplayType == DisplayType::DISPLAY_PRIMARY) {
+        mId = PRIMARY_SCREEN_ID;
+    }
 }
 
 nsScreenAndroid::~nsScreenAndroid()
 {
 }
 
 NS_IMETHODIMP
 nsScreenAndroid::GetId(uint32_t *outId)
 {
-    *outId = 1;
+    *outId = mId;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenAndroid::GetRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight)
 {
+    if (mDisplayType != DisplayType::DISPLAY_PRIMARY) {
+        *outLeft   = mRect.x;
+        *outTop    = mRect.y;
+        *outWidth  = mRect.width;
+        *outHeight = mRect.height;
+
+        return NS_OK;
+    }
+
     if (!mozilla::jni::IsAvailable()) {
       // xpcshell most likely
       *outLeft = *outTop = *outWidth = *outHeight = 0;
       return NS_ERROR_FAILURE;
     }
 
     java::sdk::Rect::LocalRef rect = java::GeckoAppShell::GetScreenSize();
     rect->Left(outLeft);
@@ -70,70 +94,106 @@ nsScreenAndroid::GetPixelDepth(int32_t *
 
 
 NS_IMETHODIMP
 nsScreenAndroid::GetColorDepth(int32_t *aColorDepth)
 {
     return GetPixelDepth(aColorDepth);
 }
 
+
 void
 nsScreenAndroid::ApplyMinimumBrightness(uint32_t aBrightness)
 {
-    if (mozilla::jni::IsAvailable()) {
-      java::GeckoAppShell::SetKeepScreenOn(aBrightness == BRIGHTNESS_FULL);
+    if (mDisplayType == DisplayType::DISPLAY_PRIMARY &&
+        mozilla::jni::IsAvailable()) {
+        java::GeckoAppShell::SetKeepScreenOn(aBrightness == BRIGHTNESS_FULL);
     }
 }
 
 NS_IMPL_ISUPPORTS(nsScreenManagerAndroid, nsIScreenManager)
 
 nsScreenManagerAndroid::nsScreenManagerAndroid()
 {
-    mOneScreen = new nsScreenAndroid(nullptr);
+    nsCOMPtr<nsIScreen> screen = AddScreen(DisplayType::DISPLAY_PRIMARY);
+    MOZ_ASSERT(screen);
 }
 
 nsScreenManagerAndroid::~nsScreenManagerAndroid()
 {
 }
 
 NS_IMETHODIMP
 nsScreenManagerAndroid::GetPrimaryScreen(nsIScreen **outScreen)
 {
-    NS_IF_ADDREF(*outScreen = mOneScreen.get());
+    ScreenForId(PRIMARY_SCREEN_ID, outScreen);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenManagerAndroid::ScreenForId(uint32_t aId,
                                     nsIScreen **outScreen)
 {
-    return GetPrimaryScreen(outScreen);
+    for (size_t i = 0; i < mScreens.Length(); ++i) {
+        if (aId == mScreens[i]->GetId()) {
+            nsCOMPtr<nsIScreen> screen = (nsIScreen*) mScreens[i];
+            screen.forget(outScreen);
+            return NS_OK;
+        }
+    }
+
+    *outScreen = nullptr;
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenManagerAndroid::ScreenForRect(int32_t inLeft,
                                       int32_t inTop,
                                       int32_t inWidth,
                                       int32_t inHeight,
                                       nsIScreen **outScreen)
 {
+    // Not support to query non-primary screen with rect.
     return GetPrimaryScreen(outScreen);
 }
 
 NS_IMETHODIMP
 nsScreenManagerAndroid::ScreenForNativeWidget(void *aWidget, nsIScreen **outScreen)
 {
+    // Not support to query non-primary screen with native widget.
     return GetPrimaryScreen(outScreen);
 }
 
 NS_IMETHODIMP
 nsScreenManagerAndroid::GetNumberOfScreens(uint32_t *aNumberOfScreens)
 {
-    *aNumberOfScreens = 1;
+    *aNumberOfScreens = mScreens.Length();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenManagerAndroid::GetSystemDefaultScale(float *aDefaultScale)
 {
     *aDefaultScale = 1.0f;
     return NS_OK;
 }
+
+already_AddRefed<nsScreenAndroid>
+nsScreenManagerAndroid::AddScreen(DisplayType aDisplayType, nsIntRect aRect)
+{
+    ALOG("nsScreenManagerAndroid: add %s screen",
+        (aDisplayType == DisplayType::DISPLAY_PRIMARY  ? "PRIMARY"  :
+        (aDisplayType == DisplayType::DISPLAY_EXTERNAL ? "EXTERNAL" :
+                                                         "VIRTUAL")));
+    RefPtr<nsScreenAndroid> screen = new nsScreenAndroid(aDisplayType, aRect);
+    mScreens.AppendElement(screen);
+    return screen.forget();
+}
+
+void
+nsScreenManagerAndroid::RemoveScreen(uint32_t aScreenId)
+{
+    for (size_t i = 0; i < mScreens.Length(); i++) {
+        if (aScreenId == mScreens[i]->GetId()) {
+            mScreens.RemoveElementAt(i);
+        }
+    }
+}
--- a/widget/android/nsScreenManagerAndroid.h
+++ b/widget/android/nsScreenManagerAndroid.h
@@ -1,46 +1,64 @@
-/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
+/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * 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/. */
 
 #ifndef nsScreenManagerAndroid_h___
 #define nsScreenManagerAndroid_h___
 
 #include "nsCOMPtr.h"
 
 #include "nsBaseScreen.h"
 #include "nsIScreenManager.h"
-#include "WidgetUtils.h"
+#include "nsRect.h"
+#include "mozilla/WidgetUtils.h"
 
 class nsScreenAndroid final : public nsBaseScreen
 {
 public:
-    nsScreenAndroid(void *nativeScreen);
+    nsScreenAndroid(DisplayType aDisplayType, nsIntRect aRect);
     ~nsScreenAndroid();
 
     NS_IMETHOD GetId(uint32_t* aId) override;
     NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) override;
     NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) override;
     NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override;
     NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override;
 
+    uint32_t GetId() const { return mId; };
+    DisplayType GetDisplayType() const { return mDisplayType; }
+
+    void SetDensity(double aDensity) { mDensity = aDensity; }
+    float GetDensity() const { return mDensity; }
+
 protected:
     virtual void ApplyMinimumBrightness(uint32_t aBrightness) override;
+
+private:
+    uint32_t mId;
+    DisplayType mDisplayType;
+    nsIntRect mRect;
+    float mDensity;
 };
 
 class nsScreenManagerAndroid final : public nsIScreenManager
 {
 private:
     ~nsScreenManagerAndroid();
 
 public:
     nsScreenManagerAndroid();
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSISCREENMANAGER
 
+    already_AddRefed<nsScreenAndroid> AddScreen(DisplayType aDisplayType,
+                                                nsIntRect aRect = nsIntRect());
+    void RemoveScreen(uint32_t aScreenId);
+
 protected:
-    nsCOMPtr<nsIScreen> mOneScreen;
+    nsTArray<RefPtr<nsScreenAndroid>> mScreens;
 };
 
 #endif /* nsScreenManagerAndroid_h___ */
--- a/widget/nsIScreen.idl
+++ b/widget/nsIScreen.idl
@@ -1,16 +1,27 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * 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 "nsISupports.idl"
 
+%{C++
+/**
+ * The display type of nsIScreen belongs to.
+ */
+enum class DisplayType: int32_t {
+  DISPLAY_PRIMARY,  // primary screen
+  DISPLAY_EXTERNAL, // wired displays, such as HDMI, DisplayPort, etc.
+  DISPLAY_VIRTUAL   // wireless displays, such as Chromecast, WiFi-Display, etc.
+};
+%}
+
 [scriptable, uuid(826e80c8-d70f-42e2-8aa9-82c05f2a370a)]
 interface nsIScreen : nsISupports
 {
   /**
    * Levels of brightness for the screen, from off to full brightness.
    */
   const unsigned long BRIGHTNESS_DIM = 0;
   const unsigned long BRIGHTNESS_FULL = 1;