Bug 801227: Patch v2 (unbitrotted) r=anant a=abillings
authorRandell Jesup <rjesup@jesup.org>
Tue, 13 Nov 2012 16:55:02 -0500
changeset 113129 5d28022bc22a
parent 113128 317ad9c88ace
child 113130 e5f393b13acd
push id17966
push userrjesup@wgate.com
push dateTue, 13 Nov 2012 21:55:44 +0000
treeherdermozilla-inbound@5d28022bc22a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersanant, abillings
bugs801227
milestone19.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 801227: Patch v2 (unbitrotted) r=anant a=abillings
dom/media/MediaManager.cpp
dom/media/MediaManager.h
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -224,57 +224,55 @@ MediaDevice::GetSource()
  * one call, to simplify handling of constraints.
  */
 class GetUserMediaStreamRunnable : public nsRunnable
 {
 public:
   GetUserMediaStreamRunnable(
     already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
     already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
-    StreamListeners* aListeners,
     uint64_t aWindowID,
     MediaEngineSource* aAudioSource,
     MediaEngineSource* aVideoSource)
     : mSuccess(aSuccess)
     , mError(aError)
     , mAudioSource(aAudioSource)
     , mVideoSource(aVideoSource)
-    , mListeners(aListeners)
     , mWindowID(aWindowID) {}
 
   ~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);
+    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);
     hints |= (mVideoSource ? nsDOMMediaStream::HINT_CONTENTS_VIDEO : 0);
 
     stream = nsDOMLocalMediaStream::CreateSourceStream(hints);
+    if (!stream) {
+      nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error(mError);
+      LOG(("Returning error for getUserMedia() - no stream"));
+      error->OnError(NS_LITERAL_STRING("NO_STREAM"));
+      return NS_OK;
+    }
 
     nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
       (nsGlobalWindow::GetInnerWindowWithId(mWindowID));
-    {
-      if (!stream) {
-        if (!(MediaManager::Get()->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)
-        nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error(mError);
-        LOG(("Returning error for getUserMedia() - no stream"));
-        error->OnError(NS_LITERAL_STRING("NO_STREAM"));
-        return NS_OK;
-      }
-    }
-
     if (window && window->GetExtantDoc()) {
       stream->CombineWithPrincipal(window->GetExtantDoc()->NodePrincipal());
     }
 
     // Ensure there's a thread for gum to proxy to off main thread
     nsIThread *mediaThread = MediaManager::GetThread();
 
     // Add our listener. We'll call Start() on the source when get a callback
@@ -282,17 +280,17 @@ public:
     // when the page is invalidated (on navigation or close).
     GetUserMediaCallbackMediaStreamListener* listener =
       new GetUserMediaCallbackMediaStreamListener(mediaThread, stream,
                                                   mAudioSource,
                                                   mVideoSource);
     stream->GetStream()->AddListener(listener);
 
     // No need for locking because we always do this in the main thread.
-    mListeners->AppendElement(listener);
+    listeners->AppendElement(listener);
 
     // Dispatch to the media thread to ask it to start the sources,
     // because that can take a while
     nsRefPtr<MediaOperationRunnable> runnable(
       new MediaOperationRunnable(MEDIA_START, stream,
                                  mAudioSource, mVideoSource));
     mediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
 
@@ -311,17 +309,16 @@ public:
     return NS_OK;
   }
 
 private:
   already_AddRefed<nsIDOMGetUserMediaSuccessCallback> mSuccess;
   already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError;
   nsRefPtr<MediaEngineSource> mAudioSource;
   nsRefPtr<MediaEngineSource> mVideoSource;
-  StreamListeners* mListeners;
   uint64_t mWindowID;
 };
 
 /**
  * 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.
@@ -334,64 +331,60 @@ class GetUserMediaRunnable : public nsRu
 public:
   /**
    * The caller can choose to provide a MediaDevice as the last argument,
    * if one is not provided, a default device is automatically chosen.
    */
   GetUserMediaRunnable(bool aAudio, bool aVideo, bool aPicture,
     already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
     already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
-    StreamListeners* aListeners, uint64_t aWindowID,
-    MediaDevice* aAudioDevice, MediaDevice* aVideoDevice)
+    uint64_t aWindowID, MediaDevice* aAudioDevice, MediaDevice* aVideoDevice)
     : mAudio(aAudio)
     , mVideo(aVideo)
     , mPicture(aPicture)
     , mSuccess(aSuccess)
     , mError(aError)
-    , mListeners(aListeners)
     , mWindowID(aWindowID)
     , mDeviceChosen(true)
     , mBackendChosen(false)
     {
       if (mAudio) {
         mAudioDevice = aAudioDevice;
       }
       if (mVideo) {
         mVideoDevice = aVideoDevice;
       }
     }
 
   GetUserMediaRunnable(bool aAudio, bool aVideo, bool aPicture,
     already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
     already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
-    StreamListeners* aListeners, uint64_t aWindowID)
+    uint64_t aWindowID)
     : mAudio(aAudio)
     , mVideo(aVideo)
     , mPicture(aPicture)
     , mSuccess(aSuccess)
     , mError(aError)
-    , mListeners(aListeners)
     , mWindowID(aWindowID)
     , mDeviceChosen(false)
     , mBackendChosen(false) {}
 
   /**
    * 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,
-    StreamListeners* aListeners, uint64_t aWindowID, MediaEngine* aBackend)
+    uint64_t aWindowID, MediaEngine* aBackend)
     : mAudio(aAudio)
     , mVideo(aVideo)
     , mPicture(false)
     , mSuccess(aSuccess)
     , mError(aError)
-    , mListeners(aListeners)
     , mWindowID(aWindowID)
     , mDeviceChosen(false)
     , mBackendChosen(true)
     , mBackend(aBackend) {}
 
   ~GetUserMediaRunnable() {
     if (mBackendChosen) {
       delete mBackend;
@@ -566,17 +559,17 @@ public:
         NS_DispatchToMainThread(new ErrorCallbackRunnable(
           mSuccess, mError, NS_LITERAL_STRING("HARDWARE_UNAVAILABLE"), mWindowID
                                                           ));
         return;
       }
     }
 
     NS_DispatchToMainThread(new GetUserMediaStreamRunnable(
-      mSuccess, mError, mListeners, mWindowID, aAudioSource, aVideoSource
+      mSuccess, mError, mWindowID, aAudioSource, aVideoSource
     ));
     return;
   }
 
   /**
    * Allocates a video device, takes a snapshot and returns a DOMFile via
    * a SuccessRunnable or an error via the ErrorRunnable. Off the main thread.
    */
@@ -606,17 +599,16 @@ public:
 
 private:
   bool mAudio;
   bool mVideo;
   bool mPicture;
 
   already_AddRefed<nsIDOMGetUserMediaSuccessCallback> mSuccess;
   already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError;
-  StreamListeners* mListeners;
   uint64_t mWindowID;
   nsRefPtr<MediaDevice> mAudioDevice;
   nsRefPtr<MediaDevice> mVideoDevice;
 
   bool mDeviceChosen;
   bool mBackendChosen;
 
   MediaEngine* mBackend;
@@ -819,32 +811,30 @@ MediaManager::GetUserMedia(bool aPrivile
    * selected by the user via the UI, or was provided by privileged code
    * via the device: attribute via nsIMediaStreamOptions.
    *
    * If a fake stream was requested, we force the use of the default backend.
    */
   if (fake) {
     // Fake stream from default backend.
     gUMRunnable = new GetUserMediaRunnable(
-      audio, video, onSuccess.forget(), onError.forget(), listeners,
-      windowID, new MediaEngineDefault()
+      audio, video, onSuccess.forget(), onError.forget(), windowID,
+      new MediaEngineDefault()
                                            );
   } else if (audiodevice || videodevice) {
     // Stream from provided device.
     gUMRunnable = new GetUserMediaRunnable(
-      audio, video, picture, onSuccess.forget(), onError.forget(), listeners,
-      windowID,
+      audio, video, picture, onSuccess.forget(), onError.forget(), windowID,
       static_cast<MediaDevice*>(audiodevice.get()),
       static_cast<MediaDevice*>(videodevice.get())
                                            );
   } else {
     // Stream from default device from WebRTC backend.
     gUMRunnable = new GetUserMediaRunnable(
-      audio, video, picture, onSuccess.forget(), onError.forget(), listeners,
-      windowID
+      audio, video, picture, onSuccess.forget(), onError.forget(), windowID
                                            );
   }
 
 #ifdef ANDROID
   if (picture) {
     // ShowFilePickerForMimeType() must run on the Main Thread! (on Android)
     NS_DispatchToMainThread(gUMRunnable);
   }
@@ -943,17 +933,17 @@ MediaManager::OnNavigation(uint64_t aWin
 {
   NS_ASSERTION(NS_IsMainThread(), "OnNavigation called off main thread");
 
   // Invalidate this window. The runnables check this value before making
   // a call to content.
 
   // This is safe since we're on main-thread, and the windowlist can only
   // be added to from the main-thread (see OnNavigation)
-  StreamListeners* listeners = GetActiveWindows()->Get(aWindowID);
+  StreamListeners* listeners = GetWindowListeners(aWindowID);
   if (!listeners) {
     return;
   }
 
   uint32_t length = listeners->Length();
   for (uint32_t i = 0; i < length; i++) {
     nsRefPtr<GetUserMediaCallbackMediaStreamListener> listener =
       listeners->ElementAt(i);
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -289,20 +289,23 @@ public:
   static nsIThread* GetThread() {
     return Get()->mMediaThread;
   }
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   MediaEngine* GetBackend();
-  bool IsWindowStillActive(uint64_t aWindowId) {
+  StreamListeners *GetWindowListeners(uint64_t aWindowId) {
     NS_ASSERTION(NS_IsMainThread(), "Only access windowlist on main thread");
 
-    return !!mActiveWindows.Get(aWindowId);
+    return mActiveWindows.Get(aWindowId);
+  }
+  bool IsWindowStillActive(uint64_t aWindowId) {
+    return !!GetWindowListeners(aWindowId);
   }
 
   nsresult GetUserMedia(bool aPrivileged, nsPIDOMWindow* aWindow,
     nsIMediaStreamOptions* aParams,
     nsIDOMGetUserMediaSuccessCallback* onSuccess,
     nsIDOMGetUserMediaErrorCallback* onError);
   nsresult GetUserMediaDevices(nsPIDOMWindow* aWindow,
     nsIGetUserMediaDevicesSuccessCallback* onSuccess,