Bug 1208371 - Make PeerConnectionImpl pass its principal to MediaStreamTrack through a new RemoteTrackSource. r?mt
MozReview-Commit-ID: BxjQCHnmbDd
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -490,33 +490,16 @@ already_AddRefed<DOMMediaStream>
PeerConnectionImpl::MakeMediaStream()
{
MediaStreamGraph* graph =
MediaStreamGraph::GetInstance(MediaStreamGraph::AUDIO_THREAD_DRIVER,
AudioChannel::Normal);
RefPtr<DOMMediaStream> stream =
DOMMediaStream::CreateSourceStream(GetWindow(), graph);
-#if !defined(MOZILLA_EXTERNAL_LINKAGE)
- // Make the stream data (audio/video samples) accessible to the receiving page.
- // We're only certain that privacy hasn't been requested if we're connected.
- if (mDtlsConnected && !PrivacyRequested()) {
- nsIDocument* doc = GetWindow()->GetExtantDoc();
- if (!doc) {
- return nullptr;
- }
- stream->CombineWithPrincipal(doc->NodePrincipal());
- } else {
- // we're either certain that we need isolation for the streams, OR
- // we're not sure and we can fix the stream in SetDtlsConnected
- nsCOMPtr<nsIPrincipal> principal =
- do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID);
- stream->CombineWithPrincipal(principal);
- }
-#endif
CSFLogDebug(logTag, "Created media stream %p, inner: %p", stream.get(), stream->GetInputStream());
return stream.forget();
}
nsresult
PeerConnectionImpl::CreateRemoteSourceStreamInfo(RefPtr<RemoteSourceStreamInfo>*
@@ -1790,39 +1773,63 @@ PeerConnectionImpl::CreateNewRemoteTrack
info->GetMediaStream()->AssignId((streamId));
#endif
}
size_t numNewAudioTracks = 0;
size_t numNewVideoTracks = 0;
size_t numPreexistingTrackIds = 0;
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
+ // Set the principal used for creating the tracks. This makes the stream
+ // data (audio/video samples) accessible to the receiving page. We're
+ // only certain that privacy hasn't been requested if we're connected.
+ nsCOMPtr<nsIPrincipal> principal;
+ if (mDtlsConnected && !PrivacyRequested()) {
+ nsIDocument* doc = GetWindow()->GetExtantDoc();
+ MOZ_ASSERT(doc);
+ if (doc) {
+ principal = doc->NodePrincipal();
+ }
+ } else {
+ // we're either certain that we need isolation for the streams, OR
+ // we're not sure and we can fix the stream in SetDtlsConnected
+ principal = do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID);
+ }
+#endif
+
for (auto j = tracks.begin(); j != tracks.end(); ++j) {
RefPtr<JsepTrack> track = *j;
if (!info->HasTrack(track->GetTrackId())) {
if (track->GetMediaType() == SdpMediaSection::kAudio) {
++numNewAudioTracks;
} else if (track->GetMediaType() == SdpMediaSection::kVideo) {
++numNewVideoTracks;
} else {
MOZ_ASSERT(false);
continue;
}
info->AddTrack(track->GetTrackId());
#if !defined(MOZILLA_EXTERNAL_LINKAGE)
- RefPtr<MediaStreamTrackSource> source =
- new BasicUnstoppableTrackSource(MediaSourceEnum::Other);
+ RefPtr<RemoteTrackSource> source = new RemoteTrackSource(principal);
+ DebugOnly<bool> sourceSet =
+ info->SetTrackSource(track->GetTrackId(), source);
+ NS_ASSERTION(sourceSet, "TrackSource was added in the wrong order. "
+ "Did someone add a track from elsewhere?");
+ TrackID trackID = info->GetNumericTrackId(track->GetTrackId());
if (track->GetMediaType() == SdpMediaSection::kAudio) {
- info->GetMediaStream()->CreateOwnDOMTrack(
- info->GetNumericTrackId(track->GetTrackId()),
- MediaSegment::AUDIO, nsString(), source);
+ info->GetMediaStream()->CreateOwnDOMTrack(trackID,
+ MediaSegment::AUDIO,
+ nsString(),
+ source);
} else {
- info->GetMediaStream()->CreateOwnDOMTrack(
- info->GetNumericTrackId(track->GetTrackId()),
- MediaSegment::VIDEO, nsString(), source);
+ info->GetMediaStream()->CreateOwnDOMTrack(trackID,
+ MediaSegment::VIDEO,
+ nsString(),
+ source);
}
#endif
CSFLogDebug(logTag, "Added remote track %s/%s",
info->GetId().c_str(), track->GetTrackId().c_str());
} else {
++numPreexistingTrackIds;
}
}
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -1216,20 +1216,23 @@ LocalSourceStreamInfo::UpdateSinkIdentit
MediaPipelineTransmit* pipeline =
static_cast<MediaPipelineTransmit*>((*it).second.get());
pipeline->UpdateSinkIdentity_m(aPrincipal, aSinkIdentity);
}
}
void RemoteSourceStreamInfo::UpdatePrincipal_m(nsIPrincipal* aPrincipal)
{
- // this blasts away the existing principal
- // we only do this when we become certain that the stream is safe to make
- // accessible to the script principal
- mMediaStream->SetPrincipal(aPrincipal);
+ // This blasts away the existing principal.
+ // We only do this when we become certain that the all tracks are safe to make
+ // accessible to the script principal.
+ for (RefPtr<RemoteTrackSource>& source : mTrackSources) {
+ MOZ_RELEASE_ASSERT(source);
+ source->SetPrincipal(aPrincipal);
+ }
}
#endif // MOZILLA_INTERNAL_API
bool
PeerConnectionMedia::AnyCodecHasPluginID(uint64_t aPluginID)
{
for (uint32_t i=0; i < mLocalSourceStreams.Length(); ++i) {
if (mLocalSourceStreams[i]->AnyCodecHasPluginID(aPluginID)) {
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
@@ -141,31 +141,68 @@ public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(LocalSourceStreamInfo)
private:
already_AddRefed<MediaPipeline> ForgetPipelineByTrackId_m(
const std::string& trackId);
};
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
+class RemoteTrackSource : public dom::MediaStreamTrackSource
+{
+public:
+ explicit RemoteTrackSource(nsIPrincipal* aPrincipal)
+ : dom::MediaStreamTrackSource(aPrincipal, true) {}
+
+ dom::MediaSourceEnum GetMediaSource() const override
+ {
+ return dom::MediaSourceEnum::Other;
+ }
+
+ void Stop() override { NS_ERROR("Can't stop a remote source!"); }
+
+ void SetPrincipal(nsIPrincipal* aPrincipal)
+ {
+ mPrincipal = aPrincipal;
+ PrincipalChanged();
+ }
+
+protected:
+ virtual ~RemoteTrackSource() {}
+};
+#endif
+
class RemoteSourceStreamInfo : public SourceStreamInfo {
~RemoteSourceStreamInfo() {}
public:
RemoteSourceStreamInfo(already_AddRefed<DOMMediaStream> aMediaStream,
PeerConnectionMedia *aParent,
const std::string& aId)
: SourceStreamInfo(aMediaStream, aParent, aId),
mReceiving(false)
{
}
void SyncPipeline(RefPtr<MediaPipelineReceive> aPipeline);
#if !defined(MOZILLA_EXTERNAL_LINKAGE)
void UpdatePrincipal_m(nsIPrincipal* aPrincipal);
+
+ // Track sources may only be set in the same order as tracks were added.
+ // Returns true if the source was added, false otherwise.
+ bool SetTrackSource(const std::string& track, RemoteTrackSource* source)
+ {
+ size_t nextIndex = mTrackSources.size();
+ if (mTrackIdMap.size() < nextIndex || mTrackIdMap[nextIndex] != track) {
+ return false;
+ }
+ mTrackSources.push_back(source);
+ return true;
+ }
#endif
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteSourceStreamInfo)
virtual void AddTrack(const std::string& track) override
{
mTrackIdMap.push_back(track);
SourceStreamInfo::AddTrack(track);
@@ -208,16 +245,22 @@ class RemoteSourceStreamInfo : public So
// numeric track id before creation of the MediaStreamTrack, and does not
// allow us to specify a string-based id until later. We cannot simply use
// something based on mline index, since renegotiation can move tracks
// around. Hopefully someday we'll be able to specify the string id up-front,
// and have the numeric track id selected for us, in which case this variable
// and its dependencies can go away.
std::vector<std::string> mTrackIdMap;
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
+ // MediaStreamTrackSources associated with this remote stream.
+ // We use them for updating their principal if that's needed.
+ std::vector<RefPtr<RemoteTrackSource>> mTrackSources;
+#endif
+
// True iff SetPullEnabled(true) has been called on the DOMMediaStream. This
// happens when offer/answer concludes.
bool mReceiving;
};
class PeerConnectionMedia : public sigslot::has_slots<> {
~PeerConnectionMedia()
{