Bug 678694 - (6/7) hal code for the Battery API. r=cjones
--- 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();