Bug 764228: Add Volume event notifications r=qDot
authorDave Hylands <dhylands@gmail.com>
Mon, 16 Jul 2012 12:38:18 -0400
changeset 104922 d5b8199e06e05e66cfe3e3484b34a580b200ac48
parent 104921 e55d5df611b90273310fc7423c0f99a20adb70fe
child 104923 c0a8cbdb0a7088d1b139cc36e4a307ca1a5b7d96
push id1490
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 18:29:50 +0000
treeherdermozilla-beta@f335e7dacdc1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersqDot
bugs764228
milestone16.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 764228: Add Volume event notifications r=qDot
dom/system/gonk/Volume.cpp
dom/system/gonk/Volume.h
dom/system/gonk/VolumeManager.cpp
--- a/dom/system/gonk/Volume.cpp
+++ b/dom/system/gonk/Volume.cpp
@@ -1,45 +1,50 @@
 /* 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 "Volume.h"
 #include "VolumeCommand.h"
 #include "VolumeManager.h"
 #include "VolumeManagerLog.h"
+#include "nsXULAppAPI.h"
 
 namespace mozilla {
 namespace system {
 
 Volume::Volume(const nsCSubstring &aName)
   : mState(STATE_INIT),
     mName(aName)
 {
   DBG("Volume %s: created", NameStr());
 }
 
 void
 Volume::SetState(Volume::STATE aNewState)
 {
-  if (aNewState != mState) {
-    LOG("Volume %s: changing state from %s to %s",
-         NameStr(), StateStr(mState), StateStr(aNewState));
+  if (aNewState == mState) {
+    return;
+  }
+  LOG("Volume %s: changing state from %s to %s (%d observers)",
+      NameStr(), StateStr(mState),
+      StateStr(aNewState), mEventObserverList.Length());
 
-    mState = aNewState;
-  }
+  mState = aNewState;
+  mEventObserverList.Broadcast(this);
 }
 
 void
 Volume::SetMountPoint(const nsCSubstring &aMountPoint)
 {
-  if (!mMountPoint.Equals(aMountPoint)) {
-    mMountPoint = aMountPoint;
-    DBG("Volume %s: Setting mountpoint to '%s'", NameStr(), mMountPoint.get());
+  if (mMountPoint.Equals(aMountPoint)) {
+    return;
   }
+  mMountPoint = aMountPoint;
+  DBG("Volume %s: Setting mountpoint to '%s'", NameStr(), mMountPoint.get());
 }
 
 void
 Volume::StartMount(VolumeResponseCallback *aCallback)
 {
   StartCommand(new VolumeActionCommand(this, "mount", "", aCallback));
 }
 
@@ -62,10 +67,28 @@ Volume::StartUnshare(VolumeResponseCallb
 }
 
 void
 Volume::StartCommand(VolumeCommand *aCommand)
 {
   VolumeManager::PostCommand(aCommand);
 }
 
+void
+Volume::RegisterObserver(Volume::EventObserver *aObserver)
+{
+  MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
+
+  mEventObserverList.AddObserver(aObserver);
+  // Send an initial event to the observer
+  aObserver->Notify(this);
+}
+
+void
+Volume::UnregisterObserver(Volume::EventObserver *aObserver)
+{
+  MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
+
+  mEventObserverList.RemoveObserver(aObserver);
+}
+
 } // namespace system
 } // namespace mozilla
--- a/dom/system/gonk/Volume.h
+++ b/dom/system/gonk/Volume.h
@@ -1,15 +1,16 @@
 /* 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_system_volume_h__
 #define mozilla_system_volume_h__
 
+#include "mozilla/Observer.h"
 #include "mozilla/RefPtr.h"
 #include "nsString.h"
 #include "VolumeCommand.h"
 
 namespace mozilla {
 namespace system {
 
 /***************************************************************************
@@ -62,34 +63,42 @@ public:
 
   const nsCString &Name() const { return mName; }
   const char *NameStr() const   { return mName.get(); }
 
   // The mount point is the name of the directory where the volume is mounted.
   // (i.e. path that leads to the files stored on the volume).
   const nsCString &MountPoint() const { return mMountPoint; }
 
+  typedef mozilla::Observer<Volume *>     EventObserver;
+  typedef mozilla::ObserverList<Volume *> EventObserverList;
+
+  // NOTE: that observers must live in the IOThread.
+  void RegisterObserver(EventObserver *aObserver);
+  void UnregisterObserver(EventObserver *aObserver);
+
+private:
+  friend class AutoMounter;         // Calls StartXxx
+  friend class VolumeManager;       // Calls SetState
+  friend class VolumeListCallback;  // Calls SetMountPoint, SetState
+
   // The StartXxx functions will queue up a command to the VolumeManager.
   // You can queue up as many commands as you like, and aCallback will
   // be called as each one completes.
   void StartMount(VolumeResponseCallback *aCallback);
   void StartUnmount(VolumeResponseCallback *aCallback);
   void StartShare(VolumeResponseCallback *aCallback);
   void StartUnshare(VolumeResponseCallback *aCallback);
 
-private:
-  friend class VolumeManager;       // Calls SetState
-  friend class VolumeListCallback;  // Calls SetMountPoint, SetState
-
   void SetState(STATE aNewState);
   void SetMountPoint(const nsCSubstring &aMountPoint);
   void StartCommand(VolumeCommand *aCommand);
 
   STATE             mState;
   const nsCString   mName;
-
   nsCString         mMountPoint;
+  EventObserverList mEventObserverList;
 };
 
 } // system
 } // mozilla
 
 #endif  // mozilla_system_volumemanager_h__
--- a/dom/system/gonk/VolumeManager.cpp
+++ b/dom/system/gonk/VolumeManager.cpp
@@ -440,9 +440,8 @@ ShutdownVolumeManager()
 {
   XRE_GetIOMessageLoop()->PostTask(
       FROM_HERE,
       NewRunnableFunction(ShutdownVolumeManagerIOThread));
 }
 
 } // system
 } // mozilla
-