Bug 1299515 - Remove GetUserMediaNotificationEvent. r=jib

MozReview-Commit-ID: 3ecH5vCce17

--HG--
extra : rebase_source : 37843f4438a61e2415296d608a2506eba100b5b9
This commit is contained in:
Andreas Pehrson 2017-11-14 11:50:07 +01:00
Родитель 85ded5b958
Коммит c7709bb25d
2 изменённых файлов: 47 добавлений и 116 удалений

Просмотреть файл

@ -11,6 +11,7 @@
#include "MediaStreamListener.h"
#include "nsArray.h"
#include "nsContentUtils.h"
#include "nsGlobalWindow.h"
#include "nsHashPropertyBag.h"
#include "nsIEventTarget.h"
#include "nsIUUIDGenerator.h"
@ -30,6 +31,7 @@
#include "nsAppDirectoryServiceDefs.h"
#include "nsIInputStream.h"
#include "nsILineInputStream.h"
#include "nsPIDOMWindow.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Types.h"
@ -527,15 +529,16 @@ public:
void StopRawID(const nsString& removedDeviceID);
/**
* Called by one of our SourceListeners when one of its tracks has stopped.
* Called by one of our SourceListeners when one of its tracks has changed so
* that chrome state is affected.
* Schedules an event for the next stable state to update chrome.
*/
void NotifySourceTrackStopped();
void ChromeAffectingStateChanged();
/**
* Called in stable state to send a notification to update chrome.
*/
void NotifyChromeOfTrackStops();
void NotifyChrome();
bool CapturingVideo() const
{
@ -1225,9 +1228,8 @@ public:
// Dispatch to the media thread to ask it to start the sources,
// because that can take a while.
// Pass ownership of domStream through the lambda to
// GetUserMediaNotificationEvent to ensure it's kept alive until the
// GetUserMediaNotificationEvent runs or is discarded.
// Pass ownership of domStream through the lambda to the nested chrome
// notification lambda to ensure it's kept alive until that lambda runs or is discarded.
RefPtr<GetUserMediaStreamRunnable> self = this;
MediaManager::PostTask(NewTaskFrom([self, domStream, callback]() mutable {
MOZ_ASSERT(MediaManager::IsInMediaThread());
@ -1285,24 +1287,30 @@ public:
LOG(("started all sources"));
// Forward onTracksAvailableCallback to GetUserMediaNotificationEvent,
// because onTracksAvailableCallback needs to be added to domStream
// on the main thread.
// The event runnable must always be released on mainthread due to the JS
// callbacks in the TracksAvailableCallback.
NS_DispatchToMainThread(do_AddRef(
new GetUserMediaNotificationEvent(
GetUserMediaNotificationEvent::STARTING,
domStream.forget(),
callback.forget(),
self->mWindowID,
self->mOnFailure.forget())));
NS_DispatchToMainThread(NS_NewRunnableFunction("MediaManager::SendPendingGUMRequest",
[]() -> void {
// onTracksAvailableCallback must be added to domStream on the main thread.
uint64_t windowID = self->mWindowID;
NS_DispatchToMainThread(NS_NewRunnableFunction("MediaManager::NotifyChromeOfStart",
[domStream, callback, windowID]() mutable {
MediaManager* manager = MediaManager::GetIfExists();
if (!manager) {
return;
}
nsGlobalWindowInner* window =
nsGlobalWindowInner::GetInnerWindowWithId(windowID);
if (!window) {
MOZ_ASSERT_UNREACHABLE("Should have window");
return;
}
domStream->OnTracksAvailable(callback->release());
nsresult rv = MediaManager::NotifyRecordingStatusChange(window->AsInner());
if (NS_FAILED(rv)) {
MOZ_ASSERT_UNREACHABLE("Should be able to notify chrome");
return;
}
manager->SendPendingGUMRequest();
}));
return NS_OK;
@ -2014,8 +2022,7 @@ MediaManager::PostTask(already_AddRefed<Runnable> task)
}
/* static */ nsresult
MediaManager::NotifyRecordingStatusChange(nsPIDOMWindowInner* aWindow,
const nsString& aMsg)
MediaManager::NotifyRecordingStatusChange(nsPIDOMWindowInner* aWindow)
{
NS_ENSURE_ARG(aWindow);
@ -2040,7 +2047,7 @@ MediaManager::NotifyRecordingStatusChange(nsPIDOMWindowInner* aWindow,
obs->NotifyObservers(static_cast<nsIPropertyBag2*>(props),
"recording-device-events",
aMsg.get());
nullptr);
return NS_OK;
}
@ -3834,7 +3841,7 @@ SourceListener::StopTrack(TrackID aTrackID)
MOZ_ASSERT(false, "Should still have window listener");
return;
}
mWindowListener->NotifySourceTrackStopped();
mWindowListener->ChromeAffectingStateChanged();
}
void
@ -4288,7 +4295,7 @@ GetUserMediaWindowListener::StopRawID(const nsString& removedDeviceID)
}
void
GetUserMediaWindowListener::NotifySourceTrackStopped()
GetUserMediaWindowListener::ChromeAffectingStateChanged()
{
MOZ_ASSERT(NS_IsMainThread());
@ -4300,76 +4307,31 @@ GetUserMediaWindowListener::NotifySourceTrackStopped()
}
nsCOMPtr<nsIRunnable> runnable =
NewRunnableMethod("GetUserMediaWindowListener::NotifyChromeOfTrackStops",
NewRunnableMethod("GetUserMediaWindowListener::NotifyChrome",
this,
&GetUserMediaWindowListener::NotifyChromeOfTrackStops);
&GetUserMediaWindowListener::NotifyChrome);
nsContentUtils::RunInStableState(runnable.forget());
mChromeNotificationTaskPosted = true;
}
void
GetUserMediaWindowListener::NotifyChromeOfTrackStops()
GetUserMediaWindowListener::NotifyChrome()
{
MOZ_ASSERT(mChromeNotificationTaskPosted);
mChromeNotificationTaskPosted = false;
NS_DispatchToMainThread(do_AddRef(new GetUserMediaNotificationEvent(
GetUserMediaNotificationEvent::STOPPING, mWindowID)));
}
NS_DispatchToMainThread(NS_NewRunnableFunction("MediaManager::NotifyChrome",
[windowID = mWindowID]() {
nsGlobalWindowInner* window =
nsGlobalWindowInner::GetInnerWindowWithId(windowID);
if (!window) {
MOZ_ASSERT_UNREACHABLE("Should have window");
return;
}
GetUserMediaNotificationEvent::GetUserMediaNotificationEvent(
GetUserMediaStatus aStatus,
uint64_t aWindowID)
: Runnable("GetUserMediaNotificationEvent")
, mStatus(aStatus)
, mWindowID(aWindowID)
{
}
GetUserMediaNotificationEvent::GetUserMediaNotificationEvent(
GetUserMediaStatus aStatus,
already_AddRefed<DOMMediaStream> aStream,
already_AddRefed<Refcountable<UniquePtr<OnTracksAvailableCallback>>>
aOnTracksAvailableCallback,
uint64_t aWindowID,
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError)
: Runnable("GetUserMediaNotificationEvent")
, mStream(aStream)
, mOnTracksAvailableCallback(aOnTracksAvailableCallback)
, mStatus(aStatus)
, mWindowID(aWindowID)
, mOnFailure(aError)
{
}
GetUserMediaNotificationEvent::~GetUserMediaNotificationEvent()
{
}
NS_IMETHODIMP
GetUserMediaNotificationEvent::Run()
{
MOZ_ASSERT(NS_IsMainThread());
// Make sure mStream is cleared and our reference to the DOMMediaStream
// is dropped on the main thread, no matter what happens in this method.
// Otherwise this object might be destroyed off the main thread,
// releasing DOMMediaStream off the main thread, which is not allowed.
RefPtr<DOMMediaStream> stream = mStream.forget();
nsString msg;
switch (mStatus) {
case STARTING:
msg = NS_LITERAL_STRING("starting");
stream->OnTracksAvailable(mOnTracksAvailableCallback->release());
break;
case STOPPING:
msg = NS_LITERAL_STRING("shutdown");
break;
}
RefPtr<nsGlobalWindowInner> window = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
return MediaManager::NotifyRecordingStatusChange(window->AsInner(), msg);
DebugOnly<nsresult> rv = MediaManager::NotifyRecordingStatusChange(window->AsInner());
MOZ_ASSERT(NS_SUCCEEDED(rv), "Should be able to notify chrome");
}));
}
} // namespace mozilla

Просмотреть файл

@ -14,14 +14,12 @@
#include "nsIMediaManager.h"
#include "nsHashKeys.h"
#include "nsGlobalWindow.h"
#include "nsClassHashtable.h"
#include "nsRefPtrHashtable.h"
#include "nsIObserver.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMNavigatorUserMedia.h"
#include "nsXULAppAPI.h"
#include "mozilla/Attributes.h"
@ -129,34 +127,6 @@ public:
Source* GetSource() override;
};
class GetUserMediaNotificationEvent: public Runnable
{
public:
enum GetUserMediaStatus {
STARTING,
STOPPING,
};
GetUserMediaNotificationEvent(GetUserMediaStatus aStatus,
uint64_t aWindowID);
GetUserMediaNotificationEvent(GetUserMediaStatus aStatus,
already_AddRefed<DOMMediaStream> aStream,
already_AddRefed<media::Refcountable<UniquePtr<OnTracksAvailableCallback>>> aOnTracksAvailableCallback,
uint64_t aWindowID,
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError);
virtual ~GetUserMediaNotificationEvent();
NS_IMETHOD Run() override;
protected:
RefPtr<GetUserMediaWindowListener> mListener; // threadsafe
RefPtr<DOMMediaStream> mStream;
RefPtr<media::Refcountable<UniquePtr<OnTracksAvailableCallback>>> mOnTracksAvailableCallback;
GetUserMediaStatus mStatus;
uint64_t mWindowID;
RefPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
};
typedef enum {
MEDIA_STOP,
MEDIA_STOP_TRACK,
@ -213,8 +183,7 @@ public:
return !!sSingleton;
}
static nsresult NotifyRecordingStatusChange(nsPIDOMWindowInner* aWindow,
const nsString& aMsg);
static nsresult NotifyRecordingStatusChange(nsPIDOMWindowInner* aWindow);
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOBSERVER