Bug 820978: keep reference to MediaManager singleton r=derf
authorRandell Jesup <rjesup@jesup.org>
Fri, 28 Dec 2012 15:29:52 -0500
changeset 126282 43187d64eea37a80a1ae14195d101c28d983c26f
parent 126281 35a7f17ac707789e5d16f1730cc09886e9eb9645
child 126283 35a0599d087a817b64c1ac67d550667d6bf6670e
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersderf
bugs820978
milestone20.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 820978: keep reference to MediaManager singleton r=derf
dom/media/MediaManager.cpp
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -54,41 +54,43 @@ class ErrorCallbackRunnable : public nsR
 public:
   ErrorCallbackRunnable(
     already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
     already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
     const nsString& aErrorMsg, uint64_t aWindowID)
     : mSuccess(aSuccess)
     , mError(aError)
     , mErrorMsg(aErrorMsg)
-    , mWindowID(aWindowID) {}
+    , mWindowID(aWindowID)
+    , mManager(MediaManager::GetInstance()) {}
 
   NS_IMETHOD
   Run()
   {
     // Only run if the window is still active.
     NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
     nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> success(mSuccess);
     nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error(mError);
 
-    if (!(MediaManager::Get()->IsWindowStillActive(mWindowID))) {
+    if (!(mManager->IsWindowStillActive(mWindowID))) {
       return NS_OK;
     }
     // This is safe since we're on main-thread, and the windowlist can only
     // be invalidated from the main-thread (see OnNavigation)
     error->OnError(mErrorMsg);
     return NS_OK;
   }
 
 private:
   already_AddRefed<nsIDOMGetUserMediaSuccessCallback> mSuccess;
   already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError;
   const nsString mErrorMsg;
   uint64_t mWindowID;
+  nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
 };
 
 /**
  * Invoke the "onSuccess" callback in content. The callback will take a
  * DOMBlob in the case of {picture:true}, and a MediaStream in the case of
  * {audio:true} or {video:true}. There is a constructor available for each
  * form. Do this only on the main thread.
  */
@@ -97,41 +99,43 @@ class SuccessCallbackRunnable : public n
 public:
   SuccessCallbackRunnable(
     already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
     already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
     nsIDOMFile* aFile, uint64_t aWindowID)
     : mSuccess(aSuccess)
     , mError(aError)
     , mFile(aFile)
-    , mWindowID(aWindowID) {}
+    , mWindowID(aWindowID)
+    , mManager(MediaManager::GetInstance()) {}
 
   NS_IMETHOD
   Run()
   {
     // Only run if the window is still active.
     NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
     nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> success(mSuccess);
     nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error(mError);
 
-    if (!(MediaManager::Get()->IsWindowStillActive(mWindowID))) {
+    if (!(mManager->IsWindowStillActive(mWindowID))) {
       return NS_OK;
     }
     // This is safe since we're on main-thread, and the windowlist can only
     // be invalidated from the main-thread (see OnNavigation)
     success->OnSuccess(mFile);
     return NS_OK;
   }
 
 private:
   already_AddRefed<nsIDOMGetUserMediaSuccessCallback> mSuccess;
   already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError;
   nsCOMPtr<nsIDOMFile> mFile;
   uint64_t mWindowID;
+  nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
 };
 
 /**
  * Invoke the GetUserMediaDevices success callback. Wrapped in a runnable
  * so that it may be called on the main thread. The error callback is also
  * passed so it can be released correctly.
  */
 class DeviceSuccessCallbackRunnable: public nsRunnable
@@ -239,28 +243,29 @@ public:
     already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
     uint64_t aWindowID,
     MediaEngineSource* aAudioSource,
     MediaEngineSource* aVideoSource)
     : mSuccess(aSuccess)
     , mError(aError)
     , mAudioSource(aAudioSource)
     , mVideoSource(aVideoSource)
-    , mWindowID(aWindowID) {}
+    , mWindowID(aWindowID)
+    , mManager(MediaManager::GetInstance()) {}
 
   ~GetUserMediaStreamRunnable() {}
 
   NS_IMETHOD
   Run()
   {
     NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
     // We're on main-thread, and the windowlist can only
     // be invalidated from the main-thread (see OnNavigation)
-    StreamListeners* listeners = MediaManager::Get()->GetWindowListeners(mWindowID);
+    StreamListeners* listeners = mManager->GetWindowListeners(mWindowID);
     if (!listeners) {
       // This window is no longer live.
       return NS_OK;
     }
 
     // Create a media stream.
     nsRefPtr<nsDOMLocalMediaStream> stream;
     uint32_t hints = (mAudioSource ? nsDOMMediaStream::HINT_CONTENTS_AUDIO : 0);
@@ -301,33 +306,34 @@ public:
       new MediaOperationRunnable(MEDIA_START, stream,
                                  mAudioSource, mVideoSource));
     mediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
 
     // We're in the main thread, so no worries here either.
     nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> success(mSuccess);
     nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error(mError);
 
-    if (!(MediaManager::Get()->IsWindowStillActive(mWindowID))) {
+    if (!(mManager->IsWindowStillActive(mWindowID))) {
       return NS_OK;
     }
     // This is safe since we're on main-thread, and the windowlist can only
     // be invalidated from the main-thread (see OnNavigation)
     LOG(("Returning success for getUserMedia()"));
     success->OnSuccess(static_cast<nsIDOMLocalMediaStream*>(stream));
 
     return NS_OK;
   }
 
 private:
   already_AddRefed<nsIDOMGetUserMediaSuccessCallback> mSuccess;
   already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError;
   nsRefPtr<MediaEngineSource> mAudioSource;
   nsRefPtr<MediaEngineSource> mVideoSource;
   uint64_t mWindowID;
+  nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
 };
 
 /**
  * Runs on a seperate thread and is responsible for enumerating devices.
  * Depending on whether a picture or stream was asked for, either
  * ProcessGetUserMedia or ProcessGetUserMediaSnapshot is called, and the results
  * are sent back to the DOM.
  *
@@ -348,16 +354,17 @@ public:
     : mAudio(aAudio)
     , mVideo(aVideo)
     , mPicture(aPicture)
     , mSuccess(aSuccess)
     , mError(aError)
     , mWindowID(aWindowID)
     , mDeviceChosen(true)
     , mBackendChosen(false)
+    , mManager(MediaManager::GetInstance())
     {
       if (mAudio) {
         mAudioDevice = aAudioDevice;
       }
       if (mVideo) {
         mVideoDevice = aVideoDevice;
       }
     }
@@ -368,17 +375,18 @@ public:
     uint64_t aWindowID)
     : mAudio(aAudio)
     , mVideo(aVideo)
     , mPicture(aPicture)
     , mSuccess(aSuccess)
     , mError(aError)
     , mWindowID(aWindowID)
     , mDeviceChosen(false)
-    , mBackendChosen(false) {}
+    , mBackendChosen(false)
+    , mManager(MediaManager::GetInstance()) {}
 
   /**
    * The caller can also choose to provide their own backend instead of
    * using the one provided by MediaManager::GetBackend.
    */
   GetUserMediaRunnable(bool aAudio, bool aVideo,
     already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
     already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
@@ -386,31 +394,30 @@ public:
     : mAudio(aAudio)
     , mVideo(aVideo)
     , mPicture(false)
     , mSuccess(aSuccess)
     , mError(aError)
     , mWindowID(aWindowID)
     , mDeviceChosen(false)
     , mBackendChosen(true)
-    , mBackend(aBackend) {}
+    , mBackend(aBackend)
+    , mManager(MediaManager::GetInstance()) {}
 
   ~GetUserMediaRunnable() {
     if (mBackendChosen) {
       delete mBackend;
     }
   }
 
   NS_IMETHOD
   Run()
   {
     NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
 
-    mManager = MediaManager::Get();
-
     // Was a backend provided?
     if (!mBackendChosen) {
       mBackend = mManager->GetBackend();
     }
 
     // Was a device provided?
     if (!mDeviceChosen) {
       nsresult rv = SelectDevice();
@@ -618,49 +625,50 @@ private:
   uint64_t mWindowID;
   nsRefPtr<MediaDevice> mAudioDevice;
   nsRefPtr<MediaDevice> mVideoDevice;
 
   bool mDeviceChosen;
   bool mBackendChosen;
 
   MediaEngine* mBackend;
-  MediaManager* mManager;
+  nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
 };
 
 /**
  * Similar to GetUserMediaRunnable, but used for the chrome-only
  * GetUserMediaDevices function. Enumerates a list of audio & video devices,
  * wraps them up in nsIMediaDevice objects and returns it to the success
  * callback.
  */
 class GetUserMediaDevicesRunnable : public nsRunnable
 {
 public:
   GetUserMediaDevicesRunnable(
     already_AddRefed<nsIGetUserMediaDevicesSuccessCallback> aSuccess,
     already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError)
     : mSuccess(aSuccess)
-    , mError(aError) {}
+    , mError(aError)
+    , mManager(MediaManager::GetInstance())
+    {}
   ~GetUserMediaDevicesRunnable() {}
 
   NS_IMETHOD
   Run()
   {
     NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
 
     uint32_t audioCount, videoCount, i;
-    MediaManager* manager = MediaManager::Get();
 
     nsTArray<nsRefPtr<MediaEngineVideoSource> > videoSources;
-    manager->GetBackend()->EnumerateVideoDevices(&videoSources);
+    mManager->GetBackend()->EnumerateVideoDevices(&videoSources);
     videoCount = videoSources.Length();
 
     nsTArray<nsRefPtr<MediaEngineAudioSource> > audioSources;
-    manager->GetBackend()->EnumerateAudioDevices(&audioSources);
+    mManager->GetBackend()->EnumerateAudioDevices(&audioSources);
     audioCount = audioSources.Length();
 
     nsTArray<nsCOMPtr<nsIMediaDevice> > *devices =
       new nsTArray<nsCOMPtr<nsIMediaDevice> >;
 
     /**
      * We only display available devices in the UI for now. We can easily
      * change this later, when we implement a more sophisticated UI that
@@ -684,16 +692,17 @@ public:
       mSuccess, mError, *devices
     ));
     return NS_OK;
   }
 
 private:
   already_AddRefed<nsIGetUserMediaDevicesSuccessCallback> mSuccess;
   already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError;
+  nsRefPtr<MediaManager> mManager;
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS2(MediaManager, nsIMediaManagerService, nsIObserver)
 
 /* static */ StaticRefPtr<MediaManager> MediaManager::sSingleton;
 
 /* static */ already_AddRefed<MediaManager>
 MediaManager::GetInstance()