Bug 720794 - Part 1 (HAL) - Implement reading and event parts of Screen Orientation API. r=cjones
authorMounir Lamouri <mounir.lamouri@gmail.com>
Tue, 13 Mar 2012 17:42:46 +0100
changeset 93054 cf2f1e899ee822570aa80bdd19bb53a82e90e7ae
parent 93053 60b8a96614c81abcd3ddbddbe4dd8e96f63a36be
child 93055 de61f2eaaea4dac6ec013bc6f488e861b3c04b6c
push idunknown
push userunknown
push dateunknown
reviewerscjones
bugs720794
milestone14.0a1
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
@@ -108,16 +108,17 @@ EXPORTS = \
   nsWindowMemoryReporter.h \
   $(NULL)
 
 EXPORTS_NAMESPACES = mozilla/dom
 EXPORTS_mozilla/dom = \
   DOMError.h \
   DOMRequest.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
@@ -14,16 +14,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 {                                      \
@@ -289,16 +290,34 @@ protected:
 
   void DisableNotifications() {
     PROXY_IF_SANDBOXED(DisableWakeLockNotifications());
   }
 };
 
 static WakeLockObserversManager sWakeLockObservers;
 
+class ScreenOrientationObserversManager : public CachingObserversManager<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
@@ -503,10 +522,38 @@ GetWakeLockInfo(const nsAString &aTopic,
 
 void
 NotifyWakeLockChange(const WakeLockInformation& aInfo)
 {
   AssertMainThread();
   sWakeLockObservers.BroadcastInformation(aInfo);
 }
 
+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
@@ -11,16 +11,17 @@
 #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/dom/power/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
@@ -31,18 +32,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 {
@@ -285,16 +295,39 @@ void ModifyWakeLock(const nsAString &aTo
 void GetWakeLockInfo(const nsAString &aTopic, hal::WakeLockInformation *aWakeLockInfo);
 
 /**
  * Notify of a change in the wake lock state.
  * @param aWakeLockInfo The new wake lock information.
  */
 void NotifyWakeLockChange(const hal::WakeLockInformation& aWakeLockInfo);
 
+/**
+ * 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
@@ -66,16 +66,17 @@ EXPORTS_mozilla = \
   HalWakeLock.h \
   $(NULL)
 
 CPPSRCS = \
   Hal.cpp \
   SandboxHal.cpp \
   WindowIdentifier.cpp \
   HalWakeLock.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,23 +37,25 @@
  *
  * ***** 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::hal::WakeLockControl;
+using mozilla::dom::ScreenOrientation;
 
 namespace mozilla {
 
 namespace hal {
   struct BatteryInformation {
     double level;
     bool   charging;
     double remainingTime;
@@ -68,19 +70,17 @@ namespace hal {
     uint32_t color;
   };
 
   struct SensorData {
     SensorType sensor;
     PRTime timestamp;
     float[] values;
   };
-}
 
-namespace hal {
   struct NetworkInformation {
     double bandwidth;
     bool   canBeMetered;
   };
 }
 
 namespace hal {
   struct WakeLockInformation {
@@ -94,16 +94,17 @@ namespace hal_sandbox {
 
 sync protocol PHal {
     manager PContent;
 
 child:
     NotifyBatteryChange(BatteryInformation aBatteryInfo);
     NotifyNetworkChange(NetworkInformation aNetworkInfo);
     NotifyWakeLockChange(WakeLockInformation aWakeLockInfo);
+    NotifyScreenOrientationChange(ScreenOrientation aScreenOrientation);
 
 parent:
     Vibrate(uint32[] pattern, uint64[] id, PBrowser browser);
     CancelVibrate(uint64[] id, PBrowser browser);
 
     EnableBatteryNotifications();
     DisableBatteryNotifications();
     sync GetCurrentBatteryInformation()
@@ -132,16 +133,21 @@ parent:
     PowerOff();
 
     ModifyWakeLock(nsString aTopic, WakeLockControl aLockAdjust, WakeLockControl aHiddenAdjust);
     EnableWakeLockNotifications();
     DisableWakeLockNotifications();
     sync GetWakeLockInfo(nsString aTopic)
       returns (WakeLockInformation aWakeLockInfo);
 
+    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
@@ -7,16 +7,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;
 
@@ -86,16 +87,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;
 }
 
@@ -193,16 +212,17 @@ GetWakeLockInfo(const nsAString &aTopic,
   Hal()->SendGetWakeLockInfo(nsString(aTopic), aWakeLockInfo);
 }
 
 class HalParent : public PHalParent
                 , public BatteryObserver
                 , public NetworkObserver
                 , public ISensorObserver
                 , public WakeLockObserver
+                , 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
@@ -279,16 +299,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)
@@ -422,16 +464,22 @@ public:
     return true;
   }
 
   NS_OVERRIDE virtual bool
   RecvNotifyWakeLockChange(const WakeLockInformation& aWakeLockInfo) {
     hal::NotifyWakeLockChange(aWakeLockInfo);
     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;
 }