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 86523 1fc8123a2ea4afa0f0e27c8e5e0e8b4c100c78f8
parent 86522 24b776d91fdb3877142017c537d100ce1900e981
child 86524 8a4e12d93a23c91074115848182a0738111937cd
push idunknown
push userunknown
push dateunknown
reviewerscjones
bugs720794
milestone13.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
@@ -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;
 }