Bug 678694 - (7/7) Interaction between DOM and hal. r=sicking
authorMounir Lamouri <mounir.lamouri@gmail.com>
Wed, 02 Nov 2011 16:27:06 +0100
changeset 79675 64f25813b372
parent 79674 6450bedb1f3c
child 79676 8a71befc6ee9
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)
reviewerssicking
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 - (7/7) Interaction between DOM and hal. r=sicking The battery status is coming from hal and when there is an update, hal informs the DOM which then dispatch the appropriate event.
dom/base/Navigator.cpp
dom/base/Navigator.h
dom/battery/BatteryManager.cpp
dom/battery/BatteryManager.h
dom/battery/Makefile.in
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -97,16 +97,20 @@ Navigator::~Navigator()
 {
   if (mMimeTypes) {
     mMimeTypes->Invalidate();
   }
 
   if (mPlugins) {
     mPlugins->Invalidate();
   }
+
+  if (mBatteryManager) {
+    mBatteryManager->Shutdown();
+  }
 }
 
 NS_INTERFACE_MAP_BEGIN(Navigator)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMClientInformation)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorGeolocation)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorBattery)
@@ -131,16 +135,21 @@ Navigator::SetDocShell(nsIDocShell* aDoc
     mGeolocation->Shutdown();
     mGeolocation = nsnull;
   }
 
   if (mNotification) {
     mNotification->Shutdown();
     mNotification = nsnull;
   }
+
+  if (mBatteryManager) {
+    mBatteryManager->Shutdown();
+    mBatteryManager = nsnull;
+  }
 }
 
 //*****************************************************************************
 //    Navigator::nsIDOMNavigator
 //*****************************************************************************
 
 NS_IMETHODIMP
 Navigator::GetUserAgent(nsAString& aUserAgent)
@@ -508,16 +517,17 @@ Navigator::LoadingNewDocument()
   }
 
   if (mNotification) {
     mNotification->Shutdown();
     mNotification = nsnull;
   }
 
   if (mBatteryManager) {
+    mBatteryManager->Shutdown();
     mBatteryManager = nsnull;
   }
 }
 
 nsresult
 Navigator::RefreshMIMEArray()
 {
   if (mMimeTypes) {
@@ -735,16 +745,17 @@ NS_IMETHODIMP Navigator::GetMozNotificat
 //    Navigator::nsIDOMNavigatorBattery
 //*****************************************************************************
 
 NS_IMETHODIMP
 Navigator::GetMozBattery(nsIDOMBatteryManager** aBattery)
 {
   if (!mBatteryManager) {
     mBatteryManager = new battery::BatteryManager();
+    mBatteryManager->Init();
   }
 
   NS_ADDREF(*aBattery = mBatteryManager);
 
   return NS_OK;
 }
 
 PRInt64
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -44,31 +44,34 @@
 #define mozilla_dom_Navigator_h
 
 #include "nsIDOMNavigator.h"
 #include "nsIDOMNavigatorGeolocation.h"
 #include "nsIDOMNavigatorDesktopNotification.h"
 #include "nsIDOMClientInformation.h"
 #include "nsIDOMNavigatorBattery.h"
 #include "nsAutoPtr.h"
-#include "nsIDOMBatteryManager.h"
 
 class nsPluginArray;
 class nsMimeTypeArray;
 class nsGeolocation;
 class nsDesktopNotificationCenter;
 class nsIDocShell;
 
 //*****************************************************************************
 // Navigator: Script "navigator" object
 //*****************************************************************************
 
 namespace mozilla {
 namespace dom {
 
+namespace battery {
+class BatteryManager;
+} // namespace battery
+
 class Navigator : public nsIDOMNavigator,
                   public nsIDOMClientInformation,
                   public nsIDOMNavigatorGeolocation,
                   public nsIDOMNavigatorDesktopNotification,
                   public nsIDOMNavigatorBattery
 {
 public:
   Navigator(nsIDocShell *aDocShell);
@@ -98,17 +101,17 @@ public:
 
 private:
   static bool sDoNotTrackEnabled;
 
   nsRefPtr<nsMimeTypeArray> mMimeTypes;
   nsRefPtr<nsPluginArray> mPlugins;
   nsRefPtr<nsGeolocation> mGeolocation;
   nsRefPtr<nsDesktopNotificationCenter> mNotification;
-  nsCOMPtr<nsIDOMBatteryManager> mBatteryManager;
+  nsRefPtr<battery::BatteryManager> mBatteryManager;
   nsIDocShell* mDocShell; // weak reference
 };
 
 } // namespace dom
 } // namespace mozilla
 
 nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent);
 nsresult NS_GetNavigatorPlatform(nsAString& aPlatform);
--- a/dom/battery/BatteryManager.cpp
+++ b/dom/battery/BatteryManager.cpp
@@ -30,19 +30,28 @@
  * 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 ***** */
 
+#include "mozilla/Hal.h"
 #include "BatteryManager.h"
 #include "nsIDOMClassInfo.h"
 #include "Constants.h"
+#include "nsDOMEvent.h"
+
+/**
+ * We have to use macros here because our leak analysis tool things we are
+ * leaking strings when we have |static const nsString|. Sad :(
+ */
+#define LEVELCHANGE_EVENT_NAME    NS_LITERAL_STRING("levelchange")
+#define CHARGINGCHANGE_EVENT_NAME NS_LITERAL_STRING("chargingchange")
 
 DOMCI_DATA(BatteryManager, mozilla::dom::battery::BatteryManager)
 
 namespace mozilla {
 namespace dom {
 namespace battery {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(BatteryManager)
@@ -75,16 +84,35 @@ BatteryManager::BatteryManager()
 
 BatteryManager::~BatteryManager()
 {
   if (mListenerManager) {
     mListenerManager->Disconnect();
   }
 }
 
+void
+BatteryManager::Init()
+{
+  hal::RegisterBatteryObserver(this);
+
+  hal::BatteryInformation* batteryInfo = new hal::BatteryInformation();
+  hal::GetCurrentBatteryInformation(batteryInfo);
+
+  UpdateFromBatteryInfo(*batteryInfo);
+
+  delete batteryInfo;
+}
+
+void
+BatteryManager::Shutdown()
+{
+  hal::UnregisterBatteryObserver(this);
+}
+
 NS_IMETHODIMP
 BatteryManager::GetCharging(bool* aCharging)
 {
   *aCharging = mCharging;
 
   return NS_OK;
 }
 
@@ -100,28 +128,69 @@ NS_IMETHODIMP
 BatteryManager::GetOnlevelchange(nsIDOMEventListener** aOnlevelchange)
 {
   return GetInnerEventListener(mOnLevelChangeListener, aOnlevelchange);
 }
 
 NS_IMETHODIMP
 BatteryManager::SetOnlevelchange(nsIDOMEventListener* aOnlevelchange)
 {
-  return RemoveAddEventListener(NS_LITERAL_STRING("levelchange"),
-                                mOnLevelChangeListener, aOnlevelchange);
+  return RemoveAddEventListener(LEVELCHANGE_EVENT_NAME, mOnLevelChangeListener,
+                                aOnlevelchange);
 }
 
 NS_IMETHODIMP
 BatteryManager::GetOnchargingchange(nsIDOMEventListener** aOnchargingchange)
 {
   return GetInnerEventListener(mOnChargingChangeListener, aOnchargingchange);
 }
 
 NS_IMETHODIMP
 BatteryManager::SetOnchargingchange(nsIDOMEventListener* aOnchargingchange)
 {
-  return RemoveAddEventListener(NS_LITERAL_STRING("chargingchange"),
+  return RemoveAddEventListener(CHARGINGCHANGE_EVENT_NAME,
                                 mOnChargingChangeListener, aOnchargingchange);
 }
 
+nsresult
+BatteryManager::DispatchTrustedEventToSelf(const nsAString& aEventName)
+{
+  nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nsnull, nsnull);
+  nsresult rv = event->InitEvent(aEventName, false, false);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = event->SetTrusted(PR_TRUE);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool dummy;
+  rv = DispatchEvent(event, &dummy);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
+void
+BatteryManager::UpdateFromBatteryInfo(const hal::BatteryInformation& aBatteryInfo)
+{
+  mLevel = aBatteryInfo.level();
+  mCharging = aBatteryInfo.charging();
+}
+
+void
+BatteryManager::Notify(const hal::BatteryInformation& aBatteryInfo)
+{
+  float previousLevel = mLevel;
+  bool previousCharging = mCharging;
+
+  UpdateFromBatteryInfo(aBatteryInfo);
+
+  if (previousCharging != mCharging) {
+    DispatchTrustedEventToSelf(CHARGINGCHANGE_EVENT_NAME);
+  }
+
+  if (previousLevel != mLevel) {
+    DispatchTrustedEventToSelf(LEVELCHANGE_EVENT_NAME);
+  }
+}
+
 } // namespace battery
 } // namespace dom
 } // namespace mozilla
--- a/dom/battery/BatteryManager.h
+++ b/dom/battery/BatteryManager.h
@@ -36,36 +36,61 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_dom_battery_BatteryManager_h
 #define mozilla_dom_battery_BatteryManager_h
 
 #include "nsIDOMBatteryManager.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsCycleCollectionParticipant.h"
+#include "mozilla/Observer.h"
+#include "Types.h"
 
 namespace mozilla {
+
+namespace hal {
+class BatteryInformation;
+} // namespace hal
+
 namespace dom {
 namespace battery {
 
 class BatteryManager : public nsIDOMBatteryManager
                      , public nsDOMEventTargetHelper
+                     , public BatteryObserver
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMBATTERYMANAGER
   NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
 
   BatteryManager();
   virtual ~BatteryManager();
 
+  void Init();
+  void Shutdown();
+
+  // For IObserver.
+  void Notify(const hal::BatteryInformation& aBatteryInfo);
+
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BatteryManager,
                                            nsDOMEventTargetHelper)
 
 private:
+  /**
+   * Dispatch a trusted non-cancellable and non-bubbling event to itself.
+   */
+  nsresult DispatchTrustedEventToSelf(const nsAString& aEventName);
+
+  /**
+   * Update the battery information stored in the battery manager object using
+   * a battery information object.
+   */
+  void UpdateFromBatteryInfo(const hal::BatteryInformation& aBatteryInfo);
+
   float mLevel;
   bool  mCharging;
 
   nsRefPtr<nsDOMEventListenerWrapper> mOnLevelChangeListener;
   nsRefPtr<nsDOMEventListenerWrapper> mOnChargingChangeListener;
 };
 
 } // namespace battery
--- a/dom/battery/Makefile.in
+++ b/dom/battery/Makefile.in
@@ -67,9 +67,11 @@ XPIDLSRCS = \
   nsIDOMBatteryManager.idl \
   nsIDOMNavigatorBattery.idl \
   $(NULL)
 
 ifdef ENABLE_TESTS
 DIRS += test
 endif
 
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk