Bug 720794 - Part 1 (HAL) - Implement reading and event parts of Screen Orientation API. r=cjones
authorMounir Lamouri <mounir.lamouri@gmail.com>
Tue, 07 Feb 2012 13:23:45 +0100
changeset 89372 4a7c7c6b9b11222baf05ecc430d03e7e5b93789a
parent 89371 83fe06023fd0f8034a683ef8248cf3bdb4ef5486
child 89373 e965486f4b5079ab6cd0e386a4d8861b53717de8
push id783
push userlsblakk@mozilla.com
push dateTue, 24 Apr 2012 17:33:42 +0000
treeherdermozilla-beta@11faed19f136 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs720794
milestone13.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 720794 - Part 1 (HAL) - Implement reading and event parts of Screen Orientation API. r=cjones
dom/base/Makefile.in
dom/base/ScreenOrientation.h
hal/Hal.cpp
hal/Hal.h
hal/HalInternal.h
hal/Makefile.in
hal/fallback/ScreenOrientationFallback.cpp
hal/sandbox/PHal.ipdl
hal/sandbox/SandboxHal.cpp
--- a/dom/base/Makefile.in
+++ b/dom/base/Makefile.in
@@ -101,16 +101,17 @@ EXPORTS = \
   nsStructuredCloneContainer.h \
   nsDOMMemoryReporter.h \
   $(NULL)
 
 EXPORTS_NAMESPACES = mozilla/dom
 EXPORTS_mozilla/dom = \
   DOMError.h \
   StructuredCloneTags.h \
+  ScreenOrientation.h \
   $(NULL)
 
 CPPSRCS =			\
 	nsBarProps.cpp          \
 	nsDOMException.cpp 	\
 	nsDOMWindowUtils.cpp 	\
 	nsJSEnvironment.cpp	\
 	nsJSTimeoutHandler.cpp	\
new file mode 100644
--- /dev/null
+++ b/dom/base/ScreenOrientation.h
@@ -0,0 +1,59 @@
+/* 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 mozilla_dom_ScreenOrientation_h
+#define mozilla_dom_ScreenOrientation_h
+
+namespace mozilla {
+namespace dom {
+
+enum ScreenOrientation {
+  eScreenOrientation_Current            = 0,
+  eScreenOrientation_PortraitPrimary    = 1,  // 00000001
+  eScreenOrientation_PortraitSecondary  = 2,  // 00000010
+  eScreenOrientation_Portrait           = 3,  // 00000011
+  eScreenOrientation_LandscapePrimary   = 4,  // 00000100
+  eScreenOrientation_LandscapeSecondary = 8,  // 00001000
+  eScreenOrientation_Landscape          = 12, // 00001100
+  eScreenOrientation_EndGuard
+};
+
+/**
+ * ScreenOrientationWrapper is a class wrapping ScreenOrientation so it can be
+ * used with Observer<T> which is taking a class, not an enum.
+ * C++11 should make this useless.
+ */
+class ScreenOrientationWrapper {
+public:
+  ScreenOrientationWrapper()
+    : orientation(eScreenOrientation_Current)
+  {}
+
+  ScreenOrientationWrapper(ScreenOrientation aOrientation)
+    : orientation(aOrientation)
+  {}
+
+  ScreenOrientation orientation;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+namespace IPC {
+
+/**
+ * Screen orientation serializer.
+ * Note that technically, 5, 6, 7, 9, 10 and 11 are illegal values but will
+ * not make the serializer to fail. We might want to write our own serializer.
+ */
+template <>
+struct ParamTraits<mozilla::dom::ScreenOrientation>
+  : public EnumSerializer<mozilla::dom::ScreenOrientation,
+                          mozilla::dom::eScreenOrientation_Current,
+                          mozilla::dom::eScreenOrientation_EndGuard>
+{};
+
+} // namespace IPC
+
+#endif // mozilla_dom_ScreenOrientation_h
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -20,16 +20,17 @@
 #include "nsIDOMDocument.h"
 #include "nsIDOMWindow.h"
 #include "mozilla/Services.h"
 #include "nsIWebNavigation.h"
 #include "nsITabChild.h"
 #include "nsIDocShell.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "WindowIdentifier.h"
+#include "mozilla/dom/ScreenOrientation.h"
 
 using namespace mozilla::services;
 
 #define PROXY_IF_SANDBOXED(_call)                 \
   do {                                            \
     if (InSandbox()) {                            \
       hal_sandbox::_call;                         \
     } else {                                      \
@@ -259,16 +260,34 @@ protected:
 
   void GetCurrentInformationInternal(NetworkInformation* aInfo) {
     PROXY_IF_SANDBOXED(GetCurrentNetworkInformation(aInfo));
   }
 };
 
 static NetworkObserversManager sNetworkObservers;
 
+class ScreenOrientationObserversManager : public ObserversManager<dom::ScreenOrientationWrapper>
+{
+protected:
+  void EnableNotifications() {
+    PROXY_IF_SANDBOXED(EnableScreenOrientationNotifications());
+  }
+
+  void DisableNotifications() {
+    PROXY_IF_SANDBOXED(DisableScreenOrientationNotifications());
+  }
+
+  void GetCurrentInformationInternal(dom::ScreenOrientationWrapper* aInfo) {
+    PROXY_IF_SANDBOXED(GetCurrentScreenOrientation(&(aInfo->orientation)));
+  }
+};
+
+static ScreenOrientationObserversManager sScreenOrientationObservers;
+
 void
 RegisterBatteryObserver(BatteryObserver* aObserver)
 {
   AssertMainThread();
   sBatteryObservers.AddObserver(aObserver);
 }
 
 void
@@ -421,10 +440,38 @@ void Reboot()
 }
 
 void PowerOff()
 {
   AssertMainThread();
   PROXY_IF_SANDBOXED(PowerOff());
 }
 
+void
+RegisterScreenOrientationObserver(hal::ScreenOrientationObserver* aObserver)
+{
+  AssertMainThread();
+  sScreenOrientationObservers.AddObserver(aObserver);
+}
+
+void
+UnregisterScreenOrientationObserver(hal::ScreenOrientationObserver* aObserver)
+{
+  AssertMainThread();
+  sScreenOrientationObservers.RemoveObserver(aObserver);
+}
+
+void
+GetCurrentScreenOrientation(dom::ScreenOrientation* aScreenOrientation)
+{
+  AssertMainThread();
+  *aScreenOrientation = sScreenOrientationObservers.GetCurrentInformation().orientation;
+}
+
+void
+NotifyScreenOrientationChange(const dom::ScreenOrientation& aScreenOrientation)
+{
+  sScreenOrientationObservers.CacheInformation(dom::ScreenOrientationWrapper(aScreenOrientation));
+  sScreenOrientationObservers.BroadcastCachedInformation();
+}
+
 } // namespace hal
 } // namespace mozilla
--- a/hal/Hal.h
+++ b/hal/Hal.h
@@ -16,16 +16,17 @@
 #include "mozilla/hal_sandbox/PHal.h"
 #include "base/basictypes.h"
 #include "mozilla/Types.h"
 #include "nsTArray.h"
 #include "prlog.h"
 #include "mozilla/dom/battery/Types.h"
 #include "mozilla/dom/network/Types.h"
 #include "mozilla/hal_sandbox/PHal.h"
+#include "mozilla/dom/ScreenOrientation.h"
 
 /*
  * Hal.h contains the public Hal API.
  *
  * By default, this file defines its functions in the hal namespace, but if
  * MOZ_HAL_NAMESPACE is defined, we'll define our functions in that namespace.
  *
  * This is used by HalImpl.h and HalSandbox.h, which define copies of all the
@@ -36,18 +37,27 @@ class nsIDOMWindow;
 
 #ifndef MOZ_HAL_NAMESPACE
 # define MOZ_HAL_NAMESPACE hal
 # define MOZ_DEFINED_HAL_NAMESPACE 1
 #endif
 
 namespace mozilla {
 
+template <class T>
+class Observer;
+
+namespace dom {
+class ScreenOrientationWrapper;
+}
+
 namespace hal {
 
+typedef Observer<dom::ScreenOrientationWrapper> ScreenOrientationObserver;
+
 class WindowIdentifier;
 
 extern PRLogModuleInfo *sHalLog;
 #define HAL_LOG(msg) PR_LOG(mozilla::hal::sHalLog, PR_LOG_DEBUG, msg)
 
 } // namespace hal
 
 namespace MOZ_HAL_NAMESPACE {
@@ -228,16 +238,39 @@ void NotifyNetworkChange(const hal::Netw
  */
 void Reboot();
 
 /**
  * Power off the device.
  */
 void PowerOff();
 
+/**
+ * Inform the backend there is a new screen orientation observer.
+ * @param aScreenOrientationObserver The observer that should be added.
+ */
+void RegisterScreenOrientationObserver(hal::ScreenOrientationObserver* aScreenOrientationObserver);
+
+/**
+ * Inform the backend a screen orientation observer unregistered.
+ * @param aScreenOrientationObserver The observer that should be removed.
+ */
+void UnregisterScreenOrientationObserver(hal::ScreenOrientationObserver* aScreenOrientationObserver);
+
+/**
+ * Returns the current screen orientation.
+ */
+void GetCurrentScreenOrientation(dom::ScreenOrientation* aScreenOrientation);
+
+/**
+ * Notify of a change in the screen orientation.
+ * @param aScreenOrientation The new screen orientation.
+ */
+void NotifyScreenOrientationChange(const dom::ScreenOrientation& aScreenOrientation);
+
 } // namespace MOZ_HAL_NAMESPACE
 } // namespace mozilla
 
 #ifdef MOZ_DEFINED_HAL_NAMESPACE
 # undef MOZ_DEFINED_HAL_NAMESPACE
 # undef MOZ_HAL_NAMESPACE
 #endif
 
--- a/hal/HalInternal.h
+++ b/hal/HalInternal.h
@@ -72,12 +72,22 @@ void DisableBatteryNotifications();
  */
 void EnableNetworkNotifications();
 
 /**
  * Disables network notifications from the backend.
  */
 void DisableNetworkNotifications();
 
+/**
+ * Enables screen orientation notifications from the backend.
+ */
+void EnableScreenOrientationNotifications();
+
+/**
+ * Disables screen orientation notifications from the backend.
+ */
+void DisableScreenOrientationNotifications();
+
 } // namespace MOZ_HAL_NAMESPACE
 } // namespace mozilla
 
 #endif  // mozilla_HalInternal_h
--- a/hal/Makefile.in
+++ b/hal/Makefile.in
@@ -64,16 +64,17 @@ EXPORTS_mozilla = \
   HalSensor.h \
   HalTypes.h \
   $(NULL)
 
 CPPSRCS = \
   Hal.cpp \
   SandboxHal.cpp \
   WindowIdentifier.cpp \
+  ScreenOrientationFallback.cpp \
   $(NULL)
 
 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += \
   AndroidHal.cpp \
   AndroidSensor.cpp \
   $(NULL)
 else ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
new file mode 100644
--- /dev/null
+++ b/hal/fallback/ScreenOrientationFallback.cpp
@@ -0,0 +1,45 @@
+/* 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 "Hal.h"
+#include "mozilla/dom/ScreenOrientation.h"
+#include "nsIScreenManager.h"
+
+namespace mozilla {
+namespace hal_impl {
+
+void
+EnableScreenOrientationNotifications()
+{
+}
+
+void
+DisableScreenOrientationNotifications()
+{
+}
+
+void
+GetCurrentScreenOrientation(dom::ScreenOrientation* aScreenOrientation)
+{
+  nsresult result;
+  nsCOMPtr<nsIScreenManager> screenMgr =
+    do_GetService("@mozilla.org/gfx/screenmanager;1", &result);
+  if (NS_FAILED(result)) {
+    NS_ERROR("Can't find nsIScreenManager!");
+    return;
+  }
+
+  PRInt32 screenLeft, screenTop, screenWidth, screenHeight;
+  nsCOMPtr<nsIScreen> screen;
+
+  screenMgr->GetPrimaryScreen(getter_AddRefs(screen));
+  screen->GetRect(&screenLeft, &screenTop, &screenWidth, &screenHeight);
+
+  *aScreenOrientation = screenWidth >= screenHeight
+                          ? dom::eScreenOrientation_LandscapePrimary
+                          : dom::eScreenOrientation_PortraitPrimary;
+}
+
+} // hal_impl
+} // mozilla
--- a/hal/sandbox/PHal.ipdl
+++ b/hal/sandbox/PHal.ipdl
@@ -37,22 +37,24 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 include protocol PContent;
 include protocol PBrowser;
 include "nspr/prtime.h";
 include "mozilla/HalSensor.h";
 include "mozilla/HalTypes.h";
+include "mozilla/dom/ScreenOrientation.h";
 
 using PRTime;
 using mozilla::hal::FlashMode;
 using mozilla::hal::LightType;
 using mozilla::hal::LightMode;
 using mozilla::hal::SensorType;
+using mozilla::dom::ScreenOrientation;
 
 namespace mozilla {
 
 namespace hal {
   struct BatteryInformation {
     double level;
     bool   charging;
     double remainingTime;
@@ -67,33 +69,32 @@ namespace hal {
     uint32_t color;
   };
 
   struct SensorData {
     SensorType sensor;
     PRTime timestamp;
     float[] values;
   };
-}
 
-namespace hal {
   struct NetworkInformation {
     double bandwidth;
     bool   canBeMetered;
   };
 }
 
 namespace hal_sandbox {
 
 sync protocol PHal {
     manager PContent;
 
 child:
     NotifyBatteryChange(BatteryInformation aBatteryInfo);
     NotifyNetworkChange(NetworkInformation aNetworkInfo);
+    NotifyScreenOrientationChange(ScreenOrientation aScreenOrientation);
 
 parent:
     Vibrate(uint32[] pattern, uint64[] id, PBrowser browser);
     CancelVibrate(uint64[] id, PBrowser browser);
 
     EnableBatteryNotifications();
     DisableBatteryNotifications();
     sync GetCurrentBatteryInformation()
@@ -113,16 +114,21 @@ parent:
     sync SetLight(LightType light, LightConfiguration aConfig)
       returns (bool status);
     sync GetLight(LightType light)
       returns (LightConfiguration aConfig, bool status);
 
     Reboot();
     PowerOff();
 
+    EnableScreenOrientationNotifications();
+    DisableScreenOrientationNotifications();
+    sync GetCurrentScreenOrientation()
+      returns (ScreenOrientation aScreenOrientation);
+
 child:
     NotifySensorChange(SensorData aSensorData);
 
 parent:    
     EnableSensorNotifications(SensorType aSensor);
     DisableSensorNotifications(SensorType aSensor);
 
     __delete__();
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -13,16 +13,17 @@
 #include "Hal.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/hal_sandbox/PHalChild.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/battery/Types.h"
 #include "mozilla/dom/network/Types.h"
+#include "mozilla/dom/ScreenOrientation.h"
 #include "mozilla/Observer.h"
 #include "mozilla/unused.h"
 #include "WindowIdentifier.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::hal;
 
@@ -92,16 +93,34 @@ DisableNetworkNotifications()
 }
 
 void
 GetCurrentNetworkInformation(NetworkInformation* aNetworkInfo)
 {
   Hal()->SendGetCurrentNetworkInformation(aNetworkInfo);
 }
 
+void
+EnableScreenOrientationNotifications()
+{
+  Hal()->SendEnableScreenOrientationNotifications();
+}
+
+void
+DisableScreenOrientationNotifications()
+{
+  Hal()->SendDisableScreenOrientationNotifications();
+}
+
+void
+GetCurrentScreenOrientation(ScreenOrientation* aScreenOrientation)
+{
+  Hal()->SendGetCurrentScreenOrientation(aScreenOrientation);
+}
+
 bool
 GetScreenEnabled()
 {
   bool enabled = false;
   Hal()->SendGetScreenEnabled(&enabled);
   return enabled;
 }
 
@@ -162,16 +181,17 @@ void
 DisableSensorNotifications(SensorType aSensor) {
   Hal()->SendDisableSensorNotifications(aSensor);
 }
 
 class HalParent : public PHalParent
                 , public BatteryObserver
                 , public NetworkObserver
                 , public ISensorObserver
+                , public ScreenOrientationObserver
 {
 public:
   NS_OVERRIDE virtual bool
   RecvVibrate(const InfallibleTArray<unsigned int>& pattern,
               const InfallibleTArray<uint64> &id,
               PBrowserParent *browserParent)
   {
     // Check whether browserParent is active.  We should have already
@@ -248,16 +268,38 @@ public:
     return true;
   }
 
   void Notify(const NetworkInformation& aNetworkInfo) {
     unused << SendNotifyNetworkChange(aNetworkInfo);
   }
 
   NS_OVERRIDE virtual bool
+  RecvEnableScreenOrientationNotifications() {
+    hal::RegisterScreenOrientationObserver(this);
+    return true;
+  }
+
+  NS_OVERRIDE virtual bool
+  RecvDisableScreenOrientationNotifications() {
+    hal::UnregisterScreenOrientationObserver(this);
+    return true;
+  }
+
+  NS_OVERRIDE virtual bool
+  RecvGetCurrentScreenOrientation(ScreenOrientation* aScreenOrientation) {
+    hal::GetCurrentScreenOrientation(aScreenOrientation);
+    return true;
+  }
+
+  void Notify(const ScreenOrientationWrapper& aScreenOrientation) {
+    unused << SendNotifyScreenOrientationChange(aScreenOrientation.orientation);
+  }
+
+  NS_OVERRIDE virtual bool
   RecvGetScreenEnabled(bool *enabled)
   {
     *enabled = hal::GetScreenEnabled();
     return true;
   }
 
   NS_OVERRIDE virtual bool
   RecvSetScreenEnabled(const bool &enabled)
@@ -336,16 +378,22 @@ public:
   NS_OVERRIDE virtual bool
   RecvNotifySensorChange(const hal::SensorData &aSensorData);
 
   NS_OVERRIDE virtual bool
   RecvNotifyNetworkChange(const NetworkInformation& aNetworkInfo) {
     hal::NotifyNetworkChange(aNetworkInfo);
     return true;
   }
+
+  NS_OVERRIDE virtual bool
+  RecvNotifyScreenOrientationChange(const ScreenOrientation& aScreenOrientation) {
+    hal::NotifyScreenOrientationChange(aScreenOrientation);
+    return true;
+  }
 };
 
 bool
 HalChild::RecvNotifySensorChange(const hal::SensorData &aSensorData) {
   hal::NotifySensorChange(aSensorData);
   
   return true;
 }