From 70707f7c8543b28fe64238463497af000dd50167 Mon Sep 17 00:00:00 2001 From: Andreas Pehrson Date: Thu, 14 Jan 2016 18:34:39 +0800 Subject: [PATCH] Bug 1208371 - Make HTMLMediaElement::CaptureStream pass its principal to MediaStreamTrack. r=mt MozReview-Commit-ID: 7ERLRSM8fz6 --HG-- extra : rebase_source : 99504bb19ac35eea6889a507589710c3575e8b0f --- dom/html/HTMLMediaElement.cpp | 127 ++++++++++++++++++++++++++++------ dom/html/HTMLMediaElement.h | 3 + dom/media/DOMMediaStream.h | 1 + 3 files changed, 109 insertions(+), 22 deletions(-) diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index df2f576cac9d..3ce47fc04067 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -1864,23 +1864,108 @@ NS_IMETHODIMP HTMLMediaElement::SetMuted(bool aMuted) return NS_OK; } +class HTMLMediaElement::CaptureStreamTrackSource : + public MediaStreamTrackSource, + public DecoderPrincipalChangeObserver +{ +public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CaptureStreamTrackSource, + MediaStreamTrackSource) + + explicit CaptureStreamTrackSource(HTMLMediaElement* aElement) + : MediaStreamTrackSource(nsCOMPtr(aElement->GetCurrentPrincipal()), true) + , mElement(aElement) + { + MOZ_ASSERT(mElement); + mElement->AddDecoderPrincipalChangeObserver(this); + } + + MediaSourceEnum GetMediaSource() const override + { + return MediaSourceEnum::Other; + } + + void Stop() override + { + NS_ERROR("We're reporting remote=true to not be stoppable. " + "Stop() should not be called."); + } + + void NotifyDecoderPrincipalChanged() override + { + nsCOMPtr newPrincipal = mElement->GetCurrentPrincipal(); + if (nsContentUtils::CombineResourcePrincipals(&mPrincipal, newPrincipal)) { + PrincipalChanged(); + } + } + +protected: + virtual ~CaptureStreamTrackSource() + { + if (mElement) { + DebugOnly res = mElement->RemoveDecoderPrincipalChangeObserver(this); + NS_ASSERTION(res, "Removing decoder principal changed observer failed. " + "Had it already been removed?"); + } + } + + RefPtr mElement; +}; + +NS_IMPL_ADDREF_INHERITED(HTMLMediaElement::CaptureStreamTrackSource, + MediaStreamTrackSource) +NS_IMPL_RELEASE_INHERITED(HTMLMediaElement::CaptureStreamTrackSource, + MediaStreamTrackSource) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLMediaElement::CaptureStreamTrackSource) +NS_INTERFACE_MAP_END_INHERITING(MediaStreamTrackSource) +NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLMediaElement::CaptureStreamTrackSource, + MediaStreamTrackSource, + mElement) + +class HTMLMediaElement::CaptureStreamTrackSourceGetter : + public MediaStreamTrackSourceGetter +{ +public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CaptureStreamTrackSourceGetter, + MediaStreamTrackSourceGetter) + + explicit CaptureStreamTrackSourceGetter(HTMLMediaElement* aElement) + : mElement(aElement) {} + + already_AddRefed + GetMediaStreamTrackSource(TrackID aInputTrackID) override + { + // We can return a new source each time here, even for different streams, + // since the sources don't keep any internal state and all of them call + // through to the same HTMLMediaElement. + // If this changes (after implementing Stop()?) we'll have to ensure we + // return the same source for all requests to the same TrackID, and only + // have one getter. + return do_AddRef(new CaptureStreamTrackSource(mElement)); + } + +protected: + virtual ~CaptureStreamTrackSourceGetter() {} + + RefPtr mElement; +}; + +NS_IMPL_ADDREF_INHERITED(HTMLMediaElement::CaptureStreamTrackSourceGetter, + MediaStreamTrackSourceGetter) +NS_IMPL_RELEASE_INHERITED(HTMLMediaElement::CaptureStreamTrackSourceGetter, + MediaStreamTrackSourceGetter) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLMediaElement::CaptureStreamTrackSourceGetter) +NS_INTERFACE_MAP_END_INHERITING(MediaStreamTrackSourceGetter) +NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLMediaElement::CaptureStreamTrackSourceGetter, + MediaStreamTrackSourceGetter, + mElement) + already_AddRefed HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded, MediaStreamGraph* aGraph) { - class CaptureStreamTrackSourceGetter : public MediaStreamTrackSourceGetter - { - public: - already_AddRefed - GetMediaStreamTrackSource(TrackID aInputTrackID) override - { - return do_AddRef(new BasicUnstoppableTrackSource()); - } - - protected: - virtual ~CaptureStreamTrackSourceGetter() {} - }; - nsPIDOMWindowInner* window = OwnerDoc()->GetInnerWindow(); if (!window) { return nullptr; @@ -1904,10 +1989,8 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded, } OutputMediaStream* out = mOutputStreams.AppendElement(); - MediaStreamTrackSourceGetter* getter = new CaptureStreamTrackSourceGetter(); + MediaStreamTrackSourceGetter* getter = new CaptureStreamTrackSourceGetter(this); out->mStream = DOMMediaStream::CreateTrackUnionStream(window, aGraph, getter); - RefPtr principal = GetCurrentPrincipal(); - out->mStream->CombineWithPrincipal(principal); out->mStream->SetCORSMode(mCORSMode); out->mFinishWhenEnded = aFinishWhenEnded; @@ -1919,13 +2002,15 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded, // Expose the tracks to JS directly. if (HasAudio()) { TrackID audioTrackId = mMediaInfo.mAudio.mTrackId; - RefPtr trackSource = new BasicUnstoppableTrackSource(); + RefPtr trackSource = + getter->GetMediaStreamTrackSource(audioTrackId); out->mStream->CreateOwnDOMTrack(audioTrackId, MediaSegment::AUDIO, nsString(), trackSource); } if (HasVideo()) { TrackID videoTrackId = mMediaInfo.mVideo.mTrackId; - RefPtr trackSource = new BasicUnstoppableTrackSource(); + RefPtr trackSource = + getter->GetMediaStreamTrackSource(videoTrackId); out->mStream->CreateOwnDOMTrack(videoTrackId, MediaSegment::VIDEO, nsString(), trackSource); } @@ -4186,10 +4271,8 @@ void HTMLMediaElement::NotifyDecoderPrincipalChanged() mDecoder->UpdateSameOriginStatus(!principal || IsCORSSameOrigin()); - for (uint32_t i = 0; i < mOutputStreams.Length(); ++i) { - OutputMediaStream* ms = &mOutputStreams[i]; - ms->mStream->SetCORSMode(mCORSMode); - ms->mStream->CombineWithPrincipal(principal); + for (OutputMediaStream& ms : mOutputStreams) { + ms.mStream->SetCORSMode(mCORSMode); } for (DecoderPrincipalChangeObserver* observer : diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h index 3b7a82799adf..d2881eeb263e 100644 --- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -290,6 +290,9 @@ public: */ bool RemoveDecoderPrincipalChangeObserver(DecoderPrincipalChangeObserver* aObserver); + class CaptureStreamTrackSource; + class CaptureStreamTrackSourceGetter; + // Update the visual size of the media. Called from the decoder on the // main thread when/if the size changes. void UpdateMediaSize(const nsIntSize& aSize); diff --git a/dom/media/DOMMediaStream.h b/dom/media/DOMMediaStream.h index ea1058dd0e8a..388e0962fe06 100644 --- a/dom/media/DOMMediaStream.h +++ b/dom/media/DOMMediaStream.h @@ -210,6 +210,7 @@ class DOMMediaStream : public DOMEventTargetHelper, public dom::PrincipalChangeObserver { friend class DOMLocalMediaStream; + friend class dom::MediaStreamTrack; typedef dom::MediaStreamTrack MediaStreamTrack; typedef dom::AudioStreamTrack AudioStreamTrack; typedef dom::VideoStreamTrack VideoStreamTrack;