Bug 745145, part 2: Implement the ScreenConfiguration hal for gonk. r=mounir
authorChris Jones <jones.chris.g@gmail.com>
Tue, 08 May 2012 14:36:07 -0700
changeset 98040 727b2eb545bd4ba23192777c3387f2878ab91d5f
parent 98039 251188d5a55c0fe0cc323505678d041db855bc53
child 98041 3a53cca0a312211934b7e8942e19ff881fa844a7
push id173
push userlsblakk@mozilla.com
push dateFri, 24 Aug 2012 15:39:16 +0000
treeherdermozilla-release@bcc45eb1fb41 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmounir
bugs745145
milestone15.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 745145, part 2: Implement the ScreenConfiguration hal for gonk. r=mounir
hal/Makefile.in
hal/gonk/GonkHal.cpp
widget/gonk/nsAppShell.cpp
widget/gonk/nsScreenManagerGonk.h
widget/gonk/nsWidgetFactory.cpp
widget/gonk/nsWindow.cpp
--- a/hal/Makefile.in
+++ b/hal/Makefile.in
@@ -133,20 +133,28 @@ CPPSRCS += \
   FallbackWakeLocks.cpp \
   FallbackSwitch.cpp \
   FallbackScreenPower.cpp \
   $(NULL)
 endif #}
 
 # Fallbacks for backends implemented on Android only.
 ifneq (android,$(MOZ_WIDGET_TOOLKIT))
-CPPSRCS += \
-  FallbackNetwork.cpp \
-  FallbackScreenOrientation.cpp \
-  $(NULL)
+CPPSRCS += FallbackNetwork.cpp
+endif
+
+# Fallbacks for backends implemented on Gonk and Android only.
+ifeq (,$(filter android gonk,$(MOZ_WIDGET_TOOLKIT)))
+CPPSRCS += FallbackScreenOrientation.cpp
 endif
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 CFLAGS          += $(MOZ_DBUS_GLIB_CFLAGS)
 CXXFLAGS        += $(MOZ_DBUS_GLIB_CFLAGS)
+
+ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
+# So that we can call nsScreenManagerGonk::GetConfiguration().
+LOCAL_INCLUDES += -I$(topsrcdir)/widget/gonk
+LOCAL_INCLUDES += -I$(topsrcdir)/widget/xpwidgets
+endif
\ No newline at end of file
--- a/hal/gonk/GonkHal.cpp
+++ b/hal/gonk/GonkHal.cpp
@@ -1,43 +1,46 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=8 et ft=cpp : */
 /* 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 <errno.h>
+#include <fcntl.h>
+#include <math.h>
+#include <stdio.h>
+#include <sys/syscall.h>
+#include <time.h>
+
+#include "android/log.h"
+#include "cutils/properties.h"
+#include "hardware/hardware.h"
+#include "hardware/lights.h"
+#include "hardware_legacy/uevent.h"
+#include "hardware_legacy/vibrator.h"
+
 #include "base/message_loop.h"
-#include "hardware_legacy/uevent.h"
+
 #include "Hal.h"
 #include "HalImpl.h"
 #include "mozilla/dom/battery/Constants.h"
 #include "mozilla/FileUtils.h"
-#include "nsAlgorithm.h"
-#include "nsThreadUtils.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/Services.h"
-#include "mozilla/FileUtils.h"
-#include "nsThreadUtils.h"
-#include "nsIRunnable.h"
-#include "nsIThread.h"
+#include "nsAlgorithm.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
+#include "nsIRunnable.h"
+#include "nsScreenManagerGonk.h"
+#include "nsThreadUtils.h"
+#include "nsThreadUtils.h"
+#include "nsIThread.h"
 #include "nsXULAppAPI.h"
-#include "hardware/lights.h"
-#include "hardware/hardware.h"
-#include "hardware_legacy/vibrator.h"
 #include "UeventPoller.h"
-#include <stdio.h>
-#include <math.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/syscall.h>
-#include <cutils/properties.h>
-#include <android/log.h>
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
 #define NsecPerMsec  1000000
 #define NsecPerSec   1000000000
 
 
 using mozilla::hal::WindowIdentifier;
 
@@ -587,10 +590,41 @@ void
 SetTimezone(const nsCString& aTimezoneSpec)
 { 
   property_set("persist.sys.timezone", aTimezoneSpec.get());
   // this function is automatically called by the other time conversion 
   // functions that depend on the timezone. To be safe, we call it manually.  
   tzset();
 }
 
+// Nothing to do here.  Gonk widgetry always listens for screen
+// orientation changes.
+void
+EnableScreenConfigurationNotifications()
+{
+}
+
+void
+DisableScreenConfigurationNotifications()
+{
+}
+
+void
+GetCurrentScreenConfiguration(hal::ScreenConfiguration* aScreenConfiguration)
+{
+  *aScreenConfiguration = nsScreenGonk::GetConfiguration();
+}
+
+bool
+LockScreenOrientation(const dom::ScreenOrientation& aOrientation)
+{
+  // FIXME/bug 743638: implement
+  return false;
+}
+
+void
+UnlockScreenOrientation()
+{
+  // FIXME/bug 743638: implement
+}
+
 } // hal_impl
 } // mozilla
--- a/widget/gonk/nsAppShell.cpp
+++ b/widget/gonk/nsAppShell.cpp
@@ -75,19 +75,20 @@
 #ifdef VERBOSE_LOG_ENABLED
 # define VERBOSE_LOG(args...)                           \
     __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
 #else
 # define VERBOSE_LOG(args...)                   \
     (void)0
 #endif
 
+using namespace android;
 using namespace mozilla;
-using namespace android;
-using namespace hal;
+using namespace mozilla::dom;
+using namespace mozilla::hal;
 
 bool gDrawRequest = false;
 static nsAppShell *gAppShell = NULL;
 static int epollfd = 0;
 static int signalfds[2] = {0};
 
 namespace mozilla {
 
@@ -705,9 +706,11 @@ nsAppShell::NotifyScreenInitialized()
     gAppShell->InitInputDevices();
 }
 
 /* static */ void
 nsAppShell::NotifyScreenRotation()
 {
     gAppShell->mReaderPolicy->setDisplayInfo();
     gAppShell->mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+
+    hal::NotifyScreenConfigurationChange(nsScreenGonk::GetConfiguration());
 }
--- a/widget/gonk/nsScreenManagerGonk.h
+++ b/widget/gonk/nsScreenManagerGonk.h
@@ -34,35 +34,39 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsScreenManagerGonk_h___
 #define nsScreenManagerGonk_h___
 
+#include "mozilla/Hal.h"
 #include "nsCOMPtr.h"
 
 #include "nsBaseScreen.h"
 #include "nsIScreenManager.h"
 
 class nsScreenGonk : public nsBaseScreen
 {
+    typedef mozilla::hal::ScreenConfiguration ScreenConfiguration;
+
 public:
     nsScreenGonk(void* nativeScreen);
     ~nsScreenGonk();
 
     NS_IMETHOD GetRect(PRInt32* aLeft, PRInt32* aTop, PRInt32* aWidth, PRInt32* aHeight);
     NS_IMETHOD GetAvailRect(PRInt32* aLeft, PRInt32* aTop, PRInt32* aWidth, PRInt32* aHeight);
     NS_IMETHOD GetPixelDepth(PRInt32* aPixelDepth);
     NS_IMETHOD GetColorDepth(PRInt32* aColorDepth);
     NS_IMETHOD GetRotation(PRUint32* aRotation);
     NS_IMETHOD SetRotation(PRUint32  aRotation);
 
     static uint32_t GetRotation();
+    static ScreenConfiguration GetConfiguration();
 };
 
 class nsScreenManagerGonk : public nsIScreenManager
 {
 public:
     nsScreenManagerGonk();
     ~nsScreenManagerGonk();
 
--- a/widget/gonk/nsWidgetFactory.cpp
+++ b/widget/gonk/nsWidgetFactory.cpp
@@ -31,16 +31,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "base/basictypes.h"
+
 #include "mozilla/ModuleUtils.h"
 
 #include "nsCOMPtr.h"
 #include "nsWidgetsCID.h"
 #include "nsAppShell.h"
 
 #include "nsWindow.h"
 #include "nsLookAndFeel.h"
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -57,16 +57,18 @@
 #include "nsTArray.h"
 #include "nsWindow.h"
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
 
 #define IS_TOPLEVEL() (mWindowType == eWindowType_toplevel || mWindowType == eWindowType_dialog)
 
 using namespace mozilla;
+using namespace mozilla::dom;
+using namespace mozilla::hal;
 using namespace mozilla::gl;
 using namespace mozilla::layers;
 using namespace mozilla::widget;
 
 nsIntRect gScreenBounds;
 static uint32_t sScreenRotation;
 static nsIntRect sVirtualBounds;
 static gfxMatrix sRotationMatrix;
@@ -606,21 +608,28 @@ nsScreenGonk::GetRect(PRInt32 *outLeft, 
 
 NS_IMETHODIMP
 nsScreenGonk::GetAvailRect(PRInt32 *outLeft,  PRInt32 *outTop,
                            PRInt32 *outWidth, PRInt32 *outHeight)
 {
     return GetRect(outLeft, outTop, outWidth, outHeight);
 }
 
+static uint32_t
+ColorDepth()
+{
+    return gNativeWindow->getDevice()->format == GGL_PIXEL_FORMAT_RGB_565 ? 16 : 24;
+}
 
 NS_IMETHODIMP
 nsScreenGonk::GetPixelDepth(PRInt32 *aPixelDepth)
 {
-    *aPixelDepth = gNativeWindow->getDevice()->format == GGL_PIXEL_FORMAT_RGB_565 ? 16 : 24;
+    // XXX: this should actually return 32 when we're using 24-bit
+    // color, because we use RGBX.
+    *aPixelDepth = ColorDepth();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsScreenGonk::GetColorDepth(PRInt32 *aColorDepth)
 {
     return GetPixelDepth(aColorDepth);
 }
@@ -675,22 +684,61 @@ nsScreenGonk::SetRotation(PRUint32 aRota
                                sVirtualBounds.height,
                                !i);
 
     nsAppShell::NotifyScreenRotation();
 
     return NS_OK;
 }
 
-uint32_t
+// NB: This isn't gonk-specific, but gonk is the only widget backend
+// that does this calculation itself, currently.
+static ScreenOrientation
+ComputeOrientation(uint32_t aRotation, const nsIntSize& aScreenSize)
+{
+    bool naturallyPortrait = (aScreenSize.height > aScreenSize.width);
+    switch (aRotation) {
+    case nsIScreen::ROTATION_0_DEG:
+        return (naturallyPortrait ? eScreenOrientation_PortraitPrimary : 
+                eScreenOrientation_LandscapePrimary);
+    case nsIScreen::ROTATION_90_DEG:
+        // Arbitrarily choosing 90deg to be primary "unnatural"
+        // rotation.
+        return (naturallyPortrait ? eScreenOrientation_LandscapePrimary : 
+                eScreenOrientation_PortraitPrimary);
+    case nsIScreen::ROTATION_180_DEG:
+        return (naturallyPortrait ? eScreenOrientation_PortraitSecondary : 
+                eScreenOrientation_LandscapeSecondary);
+    case nsIScreen::ROTATION_270_DEG:
+        return (naturallyPortrait ? eScreenOrientation_LandscapeSecondary : 
+                eScreenOrientation_PortraitSecondary);
+    default:
+        MOZ_NOT_REACHED("Gonk screen must always have a known rotation");
+        return eScreenOrientation_None;
+    }
+}
+
+/*static*/ uint32_t
 nsScreenGonk::GetRotation()
 {
     return sScreenRotation;
 }
 
+/*static*/ ScreenConfiguration
+nsScreenGonk::GetConfiguration()
+{
+    ScreenOrientation orientation = ComputeOrientation(sScreenRotation,
+                                                       gScreenBounds.Size());
+    uint32_t colorDepth = ColorDepth();
+    // NB: perpetuating colorDepth == pixelDepth illusion here, for
+    // consistency.
+    return ScreenConfiguration(sVirtualBounds, orientation,
+                               colorDepth, colorDepth);
+}
+
 NS_IMPL_ISUPPORTS1(nsScreenManagerGonk, nsIScreenManager)
 
 nsScreenManagerGonk::nsScreenManagerGonk()
 {
     mOneScreen = new nsScreenGonk(nsnull);
 }
 
 nsScreenManagerGonk::~nsScreenManagerGonk()