Bug 678694 - (6/7) hal code for the Battery API. r=cjones
authorMounir Lamouri <mounir.lamouri@gmail.com>
Wed, 02 Nov 2011 16:14:01 +0100
changeset 79674 6450bedb1f3c
parent 79673 718e0171d5d2
child 79675 64f25813b372
push id21419
push userbmo@edmorley.co.uk
push dateThu, 03 Nov 2011 19:51:58 +0000
treeherdermozilla-central@f8d66a792ddc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs678694
milestone10.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 678694 - (6/7) hal code for the Battery API. r=cjones
dom/battery/Makefile.in
dom/battery/Types.h
hal/Hal.cpp
hal/Hal.h
hal/HalSandbox.h
hal/fallback/FallbackHal.cpp
hal/sandbox/PHal.ipdl
hal/sandbox/SandboxHal.cpp
--- a/dom/battery/Makefile.in
+++ b/dom/battery/Makefile.in
@@ -47,16 +47,17 @@ LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/dom/dom-config.mk
 
 EXPORTS_NAMESPACES = mozilla/dom/battery
 
 EXPORTS_mozilla/dom/battery = \
   Constants.h \
+  Types.h \
   $(NULL)
 
 CPPSRCS = \
   BatteryManager.cpp \
   $(NULL)
 
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/content/events/src \
new file mode 100644
--- /dev/null
+++ b/dom/battery/Types.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mounir Lamouri <mounir.lamouri@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * 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 ***** */
+
+#ifndef mozilla_dom_battery_Types_h
+#define mozilla_dom_battery_Types_h
+
+namespace mozilla {
+namespace hal {
+class BatteryInformation;
+} // namespace hal
+
+template <class T>
+class Observer;
+
+typedef Observer<hal::BatteryInformation> BatteryObserver;
+
+} // namespace mozilla
+
+#endif // mozilla_dom_battery_Types_h
+
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -36,16 +36,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "Hal.h"
 #include "mozilla/Util.h"
 #include "nsThreadUtils.h"
 #include "nsXULAppAPI.h"
+#include "mozilla/Observer.h"
 
 #define PROXY_IF_SANDBOXED(_call)                 \
   do {                                            \
     if (InSandbox()) {                            \
       hal_sandbox::_call;                         \
     } else {                                      \
       hal_impl::_call;                            \
     }                                             \
@@ -68,10 +69,104 @@ InSandbox()
 
 void
 Vibrate(const nsTArray<uint32>& pattern)
 {
   AssertMainThread();
   PROXY_IF_SANDBOXED(Vibrate(pattern));
 }
 
+class BatteryObserversManager
+{
+public:
+  void AddObserver(BatteryObserver* aObserver) {
+    if (!mObservers) {
+      mObservers = new ObserverList<BatteryInformation>();
+    }
+
+    mObservers->AddObserver(aObserver);
+
+    if (mObservers->Length() == 1) {
+      PROXY_IF_SANDBOXED(EnableBatteryNotifications());
+    }
+  }
+
+  void RemoveObserver(BatteryObserver* aObserver) {
+    mObservers->RemoveObserver(aObserver);
+
+    if (mObservers->Length() == 0) {
+      PROXY_IF_SANDBOXED(DisableBatteryNotifications());
+
+      delete mObservers;
+      mObservers = 0;
+
+      delete mBatteryInfo;
+      mBatteryInfo = 0;
+    }
+  }
+
+  void CacheBatteryInformation(const BatteryInformation& aBatteryInfo) {
+    if (mBatteryInfo) {
+      delete mBatteryInfo;
+    }
+    mBatteryInfo = new BatteryInformation(aBatteryInfo);
+  }
+
+  bool HasCachedBatteryInformation() const {
+    return mBatteryInfo;
+  }
+
+  void GetCachedBatteryInformation(BatteryInformation* aBatteryInfo) const {
+    *aBatteryInfo = *mBatteryInfo;
+  }
+
+  void Broadcast(const BatteryInformation& aBatteryInfo) {
+    MOZ_ASSERT(mObservers);
+    mObservers->Broadcast(aBatteryInfo);
+  }
+
+private:
+  ObserverList<BatteryInformation>* mObservers;
+  BatteryInformation*               mBatteryInfo;
+};
+
+static BatteryObserversManager sBatteryObservers;
+
+void
+RegisterBatteryObserver(BatteryObserver* aBatteryObserver)
+{
+  AssertMainThread();
+  sBatteryObservers.AddObserver(aBatteryObserver);
+}
+
+void
+UnregisterBatteryObserver(BatteryObserver* aBatteryObserver)
+{
+  AssertMainThread();
+  sBatteryObservers.RemoveObserver(aBatteryObserver);
+}
+
+// EnableBatteryNotifications isn't defined on purpose.
+// DisableBatteryNotifications isn't defined on purpose.
+
+void
+GetCurrentBatteryInformation(BatteryInformation* aBatteryInfo)
+{
+  AssertMainThread();
+
+  if (sBatteryObservers.HasCachedBatteryInformation()) {
+    sBatteryObservers.GetCachedBatteryInformation(aBatteryInfo);
+  } else {
+    PROXY_IF_SANDBOXED(GetCurrentBatteryInformation(aBatteryInfo));
+    sBatteryObservers.CacheBatteryInformation(*aBatteryInfo);
+  }
+}
+
+void NotifyBatteryChange(const BatteryInformation& aBatteryInfo)
+{
+  AssertMainThread();
+
+  sBatteryObservers.CacheBatteryInformation(aBatteryInfo);
+  sBatteryObservers.Broadcast(aBatteryInfo);
+}
+
 } // namespace hal
 } // namespace mozilla
--- a/hal/Hal.h
+++ b/hal/Hal.h
@@ -38,16 +38,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_Hal_h
 #define mozilla_Hal_h 1
 
 #include "base/basictypes.h"
 #include "mozilla/Types.h"
 #include "nsTArray.h"
+#include "mozilla/dom/battery/Types.h"
 
 #ifndef MOZ_HAL_NAMESPACE
 // This goop plays some cpp tricks to ensure a uniform API across the
 // API entry point, "sandbox" implementations (for content processes),
 // and "impl" backends where the real work happens.  After this runs
 // through cpp, there will be three sets of identical APIs
 //   hal_impl:: --- the platform-specific implementation of an API.
 //   hal_sandbox:: --- forwards calls up to the parent process
@@ -58,28 +59,74 @@
 // directly.
 # include "HalImpl.h"
 # include "HalSandbox.h"
 # define MOZ_HAL_NAMESPACE hal
 # define MOZ_DEFINED_HAL_NAMESPACE 1
 #endif
 
 namespace mozilla {
+
+namespace hal {
+class BatteryInformation;
+} // namespace hal
+
 namespace MOZ_HAL_NAMESPACE /*hal*/ {
 
 /**
  * Turn the default vibrator device on/off per the pattern specified
  * by |pattern|.  Each element in the pattern is the number of
  * milliseconds to turn the vibrator on or off.  The first element in
  * |pattern| is an "on" element, the next is "off", and so on.
  *
  * If |pattern| is empty, any in-progress vibration is canceled.
  */
 void Vibrate(const nsTArray<uint32>& pattern);
 
+/**
+ * Inform the battery backend there is a new battery observer.
+ * @param aBatteryObserver The observer that should be added.
+ */
+void RegisterBatteryObserver(BatteryObserver* aBatteryObserver);
+
+/**
+ * Inform the battery backend a battery observer unregistered.
+ * @param aBatteryObserver The observer that should be removed.
+ */
+void UnregisterBatteryObserver(BatteryObserver* aBatteryObserver);
+
+/**
+ * Enables battery notifications from the backend.
+ *
+ * This method is semi-private in the sense of it is visible in the hal
+ * namespace but should not be used. Calls to this method from the hal
+ * namespace will produce a link error because it is not defined.
+ */
+void EnableBatteryNotifications();
+
+/**
+ * Disables battery notifications from the backend.
+ *
+ * This method is semi-private in the sense of it is visible in the hal
+ * namespace but should not be used. Calls to this method from the hal
+ * namespace will produce a link error because it is not defined.
+ */
+void DisableBatteryNotifications();
+
+/**
+ * Returns the current battery information.
+ */
+void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo);
+
+/**
+ * Notify of a change in the battery state.
+ * @param aBatteryInfo The new battery information.
+ */
+void NotifyBatteryChange(const hal::BatteryInformation& aBatteryInfo);
+
 }
 }
 
 #ifdef MOZ_DEFINED_HAL_NAMESPACE
 # undef MOZ_DEFINED_HAL_NAMESPACE
 # undef MOZ_HAL_NAMESPACE
 #endif
 
--- a/hal/HalSandbox.h
+++ b/hal/HalSandbox.h
@@ -39,9 +39,10 @@
 
 #ifndef mozilla_Hal_h
 # error "This is an internal file, don't include it"
 #endif
 
 #undef mozilla_Hal_h
 #define MOZ_HAL_NAMESPACE hal_sandbox
 #include "Hal.h"
+#include "mozilla/hal_sandbox/PHal.h"
 #undef MOZ_HAL_NAMESPACE
--- a/hal/fallback/FallbackHal.cpp
+++ b/hal/fallback/FallbackHal.cpp
@@ -33,18 +33,34 @@
  * 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 "Hal.h"
+#include "mozilla/dom/battery/Constants.h"
 
 namespace mozilla {
 namespace hal_impl {
 
 void
 Vibrate(const nsTArray<uint32>& pattern)
 {}
 
+void
+EnableBatteryNotifications()
+{}
+
+void
+DisableBatteryNotifications()
+{}
+
+void
+GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
+{
+  aBatteryInfo->level() = dom::battery::kDefaultLevel;
+  aBatteryInfo->charging() = dom::battery::kDefaultCharging;
+}
+
 } // hal_impl
 } // namespace mozilla
--- a/hal/sandbox/PHal.ipdl
+++ b/hal/sandbox/PHal.ipdl
@@ -35,21 +35,37 @@
  * 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 protocol PContent;
 
 namespace mozilla {
+
+namespace hal {
+  struct BatteryInformation {
+    float level;
+    bool  charging;
+  };
+}
+
 namespace hal_sandbox {
 
-protocol PHal {
+sync protocol PHal {
     manager PContent;
 
+child:
+    NotifyBatteryChange(BatteryInformation aBatteryInfo);
+
 parent:
     Vibrate(uint32[] pattern);
 
+    EnableBatteryNotifications();
+    DisableBatteryNotifications();
+    sync GetCurrentBatteryInformation()
+      returns (BatteryInformation aBatteryInfo);
+
     __delete__();
 };
 
 } // namespace hal
 } // namespace mozilla
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -36,16 +36,19 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "Hal.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/hal_sandbox/PHalChild.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
+#include "mozilla/dom/battery/Types.h"
+#include "mozilla/Observer.h"
+#include "mozilla/unused.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::hal;
 
 namespace mozilla {
 namespace hal_sandbox {
 
@@ -61,30 +64,76 @@ Hal()
 
 void
 Vibrate(const nsTArray<uint32>& pattern)
 {
   AutoInfallibleTArray<uint32, 8> p(pattern);
   Hal()->SendVibrate(p);
 }
 
-class HalParent : public PHalParent {
+void
+EnableBatteryNotifications()
+{
+  Hal()->SendEnableBatteryNotifications();
+}
+
+void
+DisableBatteryNotifications()
+{
+  Hal()->SendDisableBatteryNotifications();
+}
+
+void
+GetCurrentBatteryInformation(BatteryInformation* aBatteryInfo)
+{
+  Hal()->SendGetCurrentBatteryInformation(aBatteryInfo);
+}
+
+class HalParent : public PHalParent
+                , public BatteryObserver {
 public:
   NS_OVERRIDE virtual bool
   RecvVibrate(const InfallibleTArray<unsigned int>& pattern) {
     // Forward to hal::, not hal_impl::, because we might be a
     // subprocess of another sandboxed process.  The hal:: entry point
     // will do the right thing.
     hal::Vibrate(pattern);
     return true;
   }
+
+  NS_OVERRIDE virtual bool
+  RecvEnableBatteryNotifications() {
+    hal::RegisterBatteryObserver(this);
+    return true;
+  }
+
+  NS_OVERRIDE virtual bool
+  RecvDisableBatteryNotifications() {
+    hal::UnregisterBatteryObserver(this);
+    return true;
+  }
+
+  NS_OVERRIDE virtual bool
+  RecvGetCurrentBatteryInformation(BatteryInformation* aBatteryInfo) {
+    hal::GetCurrentBatteryInformation(aBatteryInfo);
+    return true;
+  }
+
+  void Notify(const BatteryInformation& aBatteryInfo) {
+    unused << SendNotifyBatteryChange(aBatteryInfo);
+  }
 };
 
 class HalChild : public PHalChild {
 public:
+  NS_OVERRIDE virtual bool
+  RecvNotifyBatteryChange(const BatteryInformation& aBatteryInfo) {
+    hal::NotifyBatteryChange(aBatteryInfo);
+    return true;
+  }
 };
 
 PHalChild* CreateHalChild() {
   return new HalChild();
 }
 
 PHalParent* CreateHalParent() {
   return new HalParent();