Commit fa714c67 authored by Henrik Boström's avatar Henrik Boström Committed by Commit Bot

Fix crash: add/remove track on an addStream()-stream after pc.close().

MediaStreams added to an RTCPeerConnection using the legacy addStream()
API is wired up such that the RTCPeerConnection is informed when tracks
are added or removed from the MediaStream so that the corresponding
sender can be added/removed from the PC.

OnStreamAddTrack/OnStreamRemoveTrack was wired up to call addTrack() and
removeTrack(), the crash occurred if these operations were to throw an
exception even though we just want to suppress any exceptions thrown.
The ExceptionState is updated to allow an exception to be thrown before
being cleared. This fixes the referenced bug.

Bug: 814139
Change-Id: I7798d7cf43bb71d42b7b8108f40ffba36dc95946
Reviewed-on: https://chromium-review.googlesource.com/992321Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Commit-Queue: Henrik Boström <hbos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#547754}
parent 3400947e
......@@ -9,7 +9,7 @@
// This is not an external/wpt/webrtc/ test because it tests APIs and behaviors
// that are not in the spec.
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true});
pc.addStream(stream);
......@@ -18,7 +18,7 @@ promise_test(async function() {
assert_equals(pc.getSenders()[0].track, stream.getTracks()[0]);
}, 'addStream() adds to local streams and senders.');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true});
let sender = pc.addTrack(stream.getTracks()[0], stream);
......@@ -26,7 +26,7 @@ promise_test(async function() {
assert_array_equals(pc.getSenders(), [ sender ]);
}, 'addTrack() adds to local streams and senders.');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true});
pc.addStream(stream);
......@@ -39,7 +39,7 @@ promise_test(async function() {
};
}, 'addTrack() fails after addStream().');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true,
video:true});
......@@ -55,7 +55,7 @@ promise_test(async function() {
assert_equals(pc.getSenders().length, 2);
}, 'addStream() after addTrack() adds the remaining track.');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true,
video:true});
......@@ -72,7 +72,7 @@ promise_test(async function() {
'PC knows about the videoTrack after stream.addTrack()');
}, 'Adding a track to an addStream()-stream adds it to the PC.');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true,
video:true});
......@@ -87,7 +87,30 @@ promise_test(async function() {
'PC does not know about the track after stream.removeTrack()');
}, 'Removing a track from an addStream()-stream removes it from the PC.');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true,
video:true});
let videoTrack = stream.getVideoTracks()[0];
stream.removeTrack(videoTrack);
pc.addStream(stream);
pc.close();
stream.addTrack(videoTrack);
}, 'Adding a track to an addStream()-stream after the PC closed is safe.');
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true,
video:true});
let videoTrack = stream.getVideoTracks()[0];
pc.addStream(stream);
pc.close();
stream.removeTrack(videoTrack);
}, 'Removing a track from an addStream()-stream after the PC closed is safe.');
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true,
video:true});
......@@ -105,7 +128,7 @@ promise_test(async function() {
'PC does not know about the videoTrack after stream.addTrack()');
}, 'The PC stops observing the stream after removeStream().');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true});
pc.addStream(stream);
......@@ -116,7 +139,7 @@ promise_test(async function() {
assert_array_equals(pc.getSenders(), []);
}, 'removeStream() after addStream() removes from local streams and senders.');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true});
pc.addTrack(stream.getTracks()[0], stream);
......@@ -127,7 +150,7 @@ promise_test(async function() {
assert_array_equals(pc.getSenders(), []);
}, 'removeStream() after addTrack() removes from local streams and senders.');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true,
video:true});
......@@ -143,7 +166,7 @@ promise_test(async function() {
assert_array_equals(pc.getSenders(), []);
}, 'removeStream() after removeTrack() removes remaining tracks.');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true});
pc.addStream(stream);
......@@ -154,7 +177,7 @@ promise_test(async function() {
assert_array_equals(pc.getSenders(), []);
}, 'removeTrack() after addStream() removes from local streams and senders.');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true});
let sender = pc.addTrack(stream.getTracks()[0], stream);
......@@ -165,14 +188,14 @@ promise_test(async function() {
assert_array_equals(pc.getSenders(), []);
}, 'removeTrack() after addTrack() removes from local streams and senders.');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true});
pc.addStream(stream);
pc.createDTMFSender(stream.getTracks()[0]);
}, 'createDTMFSender() with addStream()-track.');
promise_test(async function() {
promise_test(async t => {
let pc = new RTCPeerConnection();
let stream = await navigator.mediaDevices.getUserMedia({audio:true});
let track = stream.getTracks()[0];
......
......@@ -1515,8 +1515,9 @@ void RTCPeerConnection::NoteSdpCreated(const RTCSessionDescription& desc) {
void RTCPeerConnection::OnStreamAddTrack(MediaStream* stream,
MediaStreamTrack* track) {
ExceptionState exception_state(nullptr, ExceptionState::kUnknownContext,
nullptr, nullptr);
ExceptionState exception_state(v8::Isolate::GetCurrent(),
ExceptionState::kExecutionContext, nullptr,
nullptr);
MediaStreamVector streams;
streams.push_back(stream);
addTrack(track, streams, exception_state);
......@@ -1530,8 +1531,9 @@ void RTCPeerConnection::OnStreamRemoveTrack(MediaStream* stream,
MediaStreamTrack* track) {
auto sender = FindSenderForTrackAndStream(track, stream);
if (sender) {
ExceptionState exception_state(nullptr, ExceptionState::kUnknownContext,
nullptr, nullptr);
ExceptionState exception_state(v8::Isolate::GetCurrent(),
ExceptionState::kExecutionContext, nullptr,
nullptr);
removeTrack(sender, exception_state);
// If removeTracl() failed most likely the connection is closed. The
// exception can be suppressed, there is nothing to do.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment