Backout bug 926746 part 3 (replaced with bug 945334) rs=jesup

This commit is contained in:
Randell Jesup 2013-12-05 16:30:50 -05:00
parent cbec85703d
commit aac4f799fe
2 changed files with 74 additions and 89 deletions

View File

@ -142,35 +142,31 @@ static nsresult ValidateTrackConstraints(
} }
ErrorCallbackRunnable::ErrorCallbackRunnable( ErrorCallbackRunnable::ErrorCallbackRunnable(
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback>& aSuccess, already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback>& aError, already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
const nsAString& aErrorMsg, uint64_t aWindowID) const nsAString& aErrorMsg, uint64_t aWindowID)
: mSuccess(aSuccess) : mSuccess(aSuccess)
, mError(aError) , mError(aError)
, mErrorMsg(aErrorMsg) , mErrorMsg(aErrorMsg)
, mWindowID(aWindowID) , mWindowID(aWindowID)
, mManager(MediaManager::GetInstance()){
}
ErrorCallbackRunnable::ErrorCallbackRunnable(
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback>& aError,
const nsAString& aErrorMsg, uint64_t aWindowID)
: mError(aError)
, mErrorMsg(aErrorMsg)
, mWindowID(aWindowID)
, mManager(MediaManager::GetInstance()) { , mManager(MediaManager::GetInstance()) {
} }
NS_IMETHODIMP NS_IMETHODIMP
ErrorCallbackRunnable::Run() ErrorCallbackRunnable::Run()
{ {
// Only run if the window is still active. // Only run if the window is still active.
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
if (mError.get() && mManager->IsWindowStillActive(mWindowID)) {
// This is safe since we're on main-thread, and the windowlist can only nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> success(mSuccess);
// be invalidated from the main-thread (see OnNavigation) nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error(mError);
mError->OnError(mErrorMsg);
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; return NS_OK;
} }
@ -184,8 +180,8 @@ class SuccessCallbackRunnable : public nsRunnable
{ {
public: public:
SuccessCallbackRunnable( SuccessCallbackRunnable(
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback>& aSuccess, already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback>& aError, already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
nsIDOMFile* aFile, uint64_t aWindowID) nsIDOMFile* aFile, uint64_t aWindowID)
: mSuccess(aSuccess) : mSuccess(aSuccess)
, mError(aError) , mError(aError)
@ -199,17 +195,21 @@ public:
// Only run if the window is still active. // Only run if the window is still active.
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
if (mSuccess.get() && mManager->IsWindowStillActive(mWindowID)) { nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> success(mSuccess);
// This is safe since we're on main-thread, and the windowlist can only nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error(mError);
// be invalidated from the main-thread (see OnNavigation)
mSuccess->OnSuccess(mFile); 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; return NS_OK;
} }
private: private:
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback> mSuccess; already_AddRefed<nsIDOMGetUserMediaSuccessCallback> mSuccess;
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback> mError; already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError;
nsCOMPtr<nsIDOMFile> mFile; nsCOMPtr<nsIDOMFile> mFile;
uint64_t mWindowID; uint64_t mWindowID;
nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
@ -459,8 +459,8 @@ class GetUserMediaStreamRunnable : public nsRunnable
{ {
public: public:
GetUserMediaStreamRunnable( GetUserMediaStreamRunnable(
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback>& aSuccess, already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback>& aError, already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
uint64_t aWindowID, uint64_t aWindowID,
GetUserMediaCallbackMediaStreamListener* aListener, GetUserMediaCallbackMediaStreamListener* aListener,
MediaEngineSource* aAudioSource, MediaEngineSource* aAudioSource,
@ -479,9 +479,9 @@ public:
{ {
public: public:
TracksAvailableCallback(MediaManager* aManager, TracksAvailableCallback(MediaManager* aManager,
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback>& aSuccess, nsIDOMGetUserMediaSuccessCallback* aSuccess,
uint64_t aWindowID, uint64_t aWindowID,
DOMMediaStream* aStream) DOMMediaStream* aStream)
: mWindowID(aWindowID), mSuccess(aSuccess), mManager(aManager), : mWindowID(aWindowID), mSuccess(aSuccess), mManager(aManager),
mStream(aStream) {} mStream(aStream) {}
virtual void NotifyTracksAvailable(DOMMediaStream* aStream) MOZ_OVERRIDE virtual void NotifyTracksAvailable(DOMMediaStream* aStream) MOZ_OVERRIDE
@ -501,7 +501,7 @@ public:
mSuccess->OnSuccess(aStream); mSuccess->OnSuccess(aStream);
} }
uint64_t mWindowID; uint64_t mWindowID;
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback> mSuccess; nsRefPtr<nsIDOMGetUserMediaSuccessCallback> mSuccess;
nsRefPtr<MediaManager> mManager; nsRefPtr<MediaManager> mManager;
// Keep the DOMMediaStream alive until the NotifyTracksAvailable callback // Keep the DOMMediaStream alive until the NotifyTracksAvailable callback
// has fired, otherwise we might immediately destroy the DOMMediaStream and // has fired, otherwise we might immediately destroy the DOMMediaStream and
@ -537,8 +537,9 @@ public:
nsRefPtr<nsDOMUserMediaStream> trackunion = nsRefPtr<nsDOMUserMediaStream> trackunion =
nsDOMUserMediaStream::CreateTrackUnionStream(window, hints); nsDOMUserMediaStream::CreateTrackUnionStream(window, hints);
if (!trackunion) { if (!trackunion) {
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> error = mError.forget();
LOG(("Returning error for getUserMedia() - no stream")); LOG(("Returning error for getUserMedia() - no stream"));
mError->OnError(NS_LITERAL_STRING("NO_STREAM")); error->OnError(NS_LITERAL_STRING("NO_STREAM"));
return NS_OK; return NS_OK;
} }
@ -578,7 +579,7 @@ public:
new MediaOperationRunnable(MEDIA_START, mListener, trackunion, new MediaOperationRunnable(MEDIA_START, mListener, trackunion,
tracksAvailableCallback, tracksAvailableCallback,
mAudioSource, mVideoSource, false, mWindowID, mAudioSource, mVideoSource, false, mWindowID,
mError)); mError.forget()));
mediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL); mediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
#ifdef MOZ_WEBRTC #ifdef MOZ_WEBRTC
@ -608,12 +609,14 @@ public:
} }
#endif #endif
// We won't need mError now.
mError = nullptr;
return NS_OK; return NS_OK;
} }
private: private:
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback> mSuccess; nsRefPtr<nsIDOMGetUserMediaSuccessCallback> mSuccess;
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback> mError; nsRefPtr<nsIDOMGetUserMediaErrorCallback> mError;
nsRefPtr<MediaEngineSource> mAudioSource; nsRefPtr<MediaEngineSource> mAudioSource;
nsRefPtr<MediaEngineSource> mVideoSource; nsRefPtr<MediaEngineSource> mVideoSource;
uint64_t mWindowID; uint64_t mWindowID;
@ -741,13 +744,13 @@ class GetUserMediaRunnable : public nsRunnable
public: public:
GetUserMediaRunnable( GetUserMediaRunnable(
const MediaStreamConstraintsInternal& aConstraints, const MediaStreamConstraintsInternal& aConstraints,
nsIDOMGetUserMediaSuccessCallback* aSuccess, already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
nsIDOMGetUserMediaErrorCallback* aError, already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener, uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener,
MediaEnginePrefs &aPrefs) MediaEnginePrefs &aPrefs)
: mConstraints(aConstraints) : mConstraints(aConstraints)
, mSuccess(new nsMainThreadPtrHolder<nsIDOMGetUserMediaSuccessCallback>(aSuccess)) , mSuccess(aSuccess)
, mError(new nsMainThreadPtrHolder<nsIDOMGetUserMediaErrorCallback>(aError)) , mError(aError)
, mWindowID(aWindowID) , mWindowID(aWindowID)
, mListener(aListener) , mListener(aListener)
, mPrefs(aPrefs) , mPrefs(aPrefs)
@ -762,14 +765,14 @@ public:
*/ */
GetUserMediaRunnable( GetUserMediaRunnable(
const MediaStreamConstraintsInternal& aConstraints, const MediaStreamConstraintsInternal& aConstraints,
nsIDOMGetUserMediaSuccessCallback* aSuccess, already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
nsIDOMGetUserMediaErrorCallback* aError, already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener, uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener,
MediaEnginePrefs &aPrefs, MediaEnginePrefs &aPrefs,
MediaEngine* aBackend) MediaEngine* aBackend)
: mConstraints(aConstraints) : mConstraints(aConstraints)
, mSuccess(new nsMainThreadPtrHolder<nsIDOMGetUserMediaSuccessCallback>(aSuccess)) , mSuccess(aSuccess)
, mError(new nsMainThreadPtrHolder<nsIDOMGetUserMediaErrorCallback>(aError)) , mError(aError)
, mWindowID(aWindowID) , mWindowID(aWindowID)
, mListener(aListener) , mListener(aListener)
, mPrefs(aPrefs) , mPrefs(aPrefs)
@ -842,7 +845,8 @@ public:
// This will re-check the window being alive on main-thread // This will re-check the window being alive on main-thread
// Note: we must remove the listener on MainThread as well // Note: we must remove the listener on MainThread as well
NS_DispatchToMainThread(new ErrorCallbackRunnable( NS_DispatchToMainThread(new ErrorCallbackRunnable(
mSuccess, mError, aErrorMsg, mWindowID)); mSuccess, mError, aErrorMsg, mWindowID
));
// MUST happen after ErrorCallbackRunnable Run()s, as it checks the active window list // MUST happen after ErrorCallbackRunnable Run()s, as it checks the active window list
NS_DispatchToMainThread(new GetUserMediaListenerRemove(mWindowID, mListener)); NS_DispatchToMainThread(new GetUserMediaListenerRemove(mWindowID, mListener));
@ -913,8 +917,9 @@ public:
rv = aAudioSource->Allocate(mPrefs); rv = aAudioSource->Allocate(mPrefs);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
LOG(("Failed to allocate audiosource %d",rv)); LOG(("Failed to allocate audiosource %d",rv));
NS_DispatchToMainThread(new ErrorCallbackRunnable(mSuccess, mError, NS_DispatchToMainThread(new ErrorCallbackRunnable(
NS_LITERAL_STRING("HARDWARE_UNAVAILABLE"), mWindowID)); mSuccess, mError, NS_LITERAL_STRING("HARDWARE_UNAVAILABLE"), mWindowID
));
return; return;
} }
} }
@ -925,8 +930,9 @@ public:
if (aAudioSource) { if (aAudioSource) {
aAudioSource->Deallocate(); aAudioSource->Deallocate();
} }
NS_DispatchToMainThread(new ErrorCallbackRunnable(mSuccess, mError, NS_DispatchToMainThread(new ErrorCallbackRunnable(
NS_LITERAL_STRING("HARDWARE_UNAVAILABLE"), mWindowID)); mSuccess, mError, NS_LITERAL_STRING("HARDWARE_UNAVAILABLE"), mWindowID
));
return; return;
} }
} }
@ -946,8 +952,9 @@ public:
{ {
nsresult rv = aSource->Allocate(mPrefs); nsresult rv = aSource->Allocate(mPrefs);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
NS_DispatchToMainThread(new ErrorCallbackRunnable(mSuccess, mError, NS_DispatchToMainThread(new ErrorCallbackRunnable(
NS_LITERAL_STRING("HARDWARE_UNAVAILABLE"), mWindowID)); mSuccess, mError, NS_LITERAL_STRING("HARDWARE_UNAVAILABLE"), mWindowID
));
return; return;
} }
@ -967,8 +974,8 @@ public:
private: private:
MediaStreamConstraintsInternal mConstraints; MediaStreamConstraintsInternal mConstraints;
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback> mSuccess; already_AddRefed<nsIDOMGetUserMediaSuccessCallback> mSuccess;
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback> mError; already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError;
uint64_t mWindowID; uint64_t mWindowID;
nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener; nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener;
nsRefPtr<MediaDevice> mAudioDevice; nsRefPtr<MediaDevice> mAudioDevice;
@ -1312,12 +1319,12 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
*/ */
if (c.mFake) { if (c.mFake) {
// Fake stream from default backend. // Fake stream from default backend.
gUMRunnable = new GetUserMediaRunnable(c, onSuccess, gUMRunnable = new GetUserMediaRunnable(c, onSuccess.forget(),
onError, windowID, listener, mPrefs, new MediaEngineDefault()); onError.forget(), windowID, listener, mPrefs, new MediaEngineDefault());
} else { } else {
// Stream from default device from WebRTC backend. // Stream from default device from WebRTC backend.
gUMRunnable = new GetUserMediaRunnable(c, onSuccess, gUMRunnable = new GetUserMediaRunnable(c, onSuccess.forget(),
onError, windowID, listener, mPrefs); onError.forget(), windowID, listener, mPrefs);
} }
#ifdef MOZ_B2G_CAMERA #ifdef MOZ_B2G_CAMERA
@ -1782,7 +1789,7 @@ GetUserMediaCallbackMediaStreamListener::Invalidate()
runnable = new MediaOperationRunnable(MEDIA_STOP, runnable = new MediaOperationRunnable(MEDIA_STOP,
this, nullptr, nullptr, this, nullptr, nullptr,
mAudioSource, mVideoSource, mAudioSource, mVideoSource,
mFinished, mWindowID); mFinished, mWindowID, nullptr);
mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL); mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
} }

View File

@ -14,7 +14,6 @@
#include "nsObserverService.h" #include "nsObserverService.h"
#include "nsIPrefService.h" #include "nsIPrefService.h"
#include "nsIPrefBranch.h" #include "nsIPrefBranch.h"
#include "nsProxyRelease.h"
#include "nsPIDOMWindow.h" #include "nsPIDOMWindow.h"
#include "nsIDOMNavigatorUserMedia.h" #include "nsIDOMNavigatorUserMedia.h"
@ -214,7 +213,7 @@ class GetUserMediaNotificationEvent: public nsRunnable
already_AddRefed<DOMMediaStream> aStream, already_AddRefed<DOMMediaStream> aStream,
DOMMediaStream::OnTracksAvailableCallback* aOnTracksAvailableCallback, DOMMediaStream::OnTracksAvailableCallback* aOnTracksAvailableCallback,
bool aIsAudio, bool aIsVideo, uint64_t aWindowID, bool aIsAudio, bool aIsVideo, uint64_t aWindowID,
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback> aError) already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError)
: mStream(aStream), mOnTracksAvailableCallback(aOnTracksAvailableCallback), : mStream(aStream), mOnTracksAvailableCallback(aOnTracksAvailableCallback),
mStatus(aStatus), mIsAudio(aIsAudio), mIsVideo(aIsVideo), mWindowID(aWindowID), mStatus(aStatus), mIsAudio(aIsAudio), mIsVideo(aIsVideo), mWindowID(aWindowID),
mError(aError) {} mError(aError) {}
@ -233,7 +232,7 @@ class GetUserMediaNotificationEvent: public nsRunnable
bool mIsAudio; bool mIsAudio;
bool mIsVideo; bool mIsVideo;
uint64_t mWindowID; uint64_t mWindowID;
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback> mError; nsRefPtr<nsIDOMGetUserMediaErrorCallback> mError;
}; };
typedef enum { typedef enum {
@ -252,16 +251,13 @@ class ErrorCallbackRunnable : public nsRunnable
{ {
public: public:
ErrorCallbackRunnable( ErrorCallbackRunnable(
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback>& aSuccess, already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback>& aError, already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
const nsAString& aErrorMsg, uint64_t aWindowID);
ErrorCallbackRunnable(
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback>& aError,
const nsAString& aErrorMsg, uint64_t aWindowID); const nsAString& aErrorMsg, uint64_t aWindowID);
NS_IMETHOD Run(); NS_IMETHOD Run();
private: private:
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback> mSuccess; already_AddRefed<nsIDOMGetUserMediaSuccessCallback> mSuccess;
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback> mError; already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError;
const nsString mErrorMsg; const nsString mErrorMsg;
uint64_t mWindowID; uint64_t mWindowID;
nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
@ -295,7 +291,7 @@ public:
MediaEngineSource* aVideoSource, MediaEngineSource* aVideoSource,
bool aNeedsFinish, bool aNeedsFinish,
uint64_t aWindowID, uint64_t aWindowID,
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback> aError) already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError)
: mType(aType) : mType(aType)
, mStream(aStream) , mStream(aStream)
, mOnTracksAvailableCallback(aOnTracksAvailableCallback) , mOnTracksAvailableCallback(aOnTracksAvailableCallback)
@ -307,25 +303,6 @@ public:
, mError(aError) , mError(aError)
{} {}
MediaOperationRunnable(MediaOperation aType,
GetUserMediaCallbackMediaStreamListener* aListener,
DOMMediaStream* aStream,
DOMMediaStream::OnTracksAvailableCallback* aOnTracksAvailableCallback,
MediaEngineSource* aAudioSource,
MediaEngineSource* aVideoSource,
bool aNeedsFinish,
uint64_t aWindowID)
: mType(aType)
, mStream(aStream)
, mOnTracksAvailableCallback(aOnTracksAvailableCallback)
, mAudioSource(aAudioSource)
, mVideoSource(aVideoSource)
, mListener(aListener)
, mFinish(aNeedsFinish)
, mWindowID(aWindowID)
, mError(nullptr)
{}
~MediaOperationRunnable() ~MediaOperationRunnable()
{ {
// MediaStreams can be released on any thread. // MediaStreams can be released on any thread.
@ -339,7 +316,8 @@ public:
nsString log; nsString log;
log.AssignASCII(errorLog, strlen(errorLog)); log.AssignASCII(errorLog, strlen(errorLog));
NS_DispatchToMainThread(new ErrorCallbackRunnable(mError, log, mWindowID)); NS_DispatchToMainThread(new ErrorCallbackRunnable(nullptr, mError.forget(),
log, mWindowID));
return NS_OK; return NS_OK;
} }
@ -390,7 +368,7 @@ public:
mOnTracksAvailableCallback.forget(), mOnTracksAvailableCallback.forget(),
mAudioSource != nullptr, mAudioSource != nullptr,
mVideoSource != nullptr, mVideoSource != nullptr,
mWindowID, mError); mWindowID, mError.forget());
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL); NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
} }
break; break;
@ -437,7 +415,7 @@ private:
nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener; // threadsafe nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener; // threadsafe
bool mFinish; bool mFinish;
uint64_t mWindowID; uint64_t mWindowID;
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback> mError; nsRefPtr<nsIDOMGetUserMediaErrorCallback> mError;
}; };
typedef nsTArray<nsRefPtr<GetUserMediaCallbackMediaStreamListener> > StreamListeners; typedef nsTArray<nsRefPtr<GetUserMediaCallbackMediaStreamListener> > StreamListeners;