| <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> |
| <html> |
| <head> |
| <script src="../../resources/js-test.js"></script> |
| </head> |
| <body> |
| <script> |
| description("Test adding and removing tracks."); |
| |
| var stream1; |
| var stream2; |
| var stream3; |
| var audioTrack; |
| var videoTrack; |
| |
| function error() { |
| testFailed('Stream generation failed.'); |
| finishJSTest(); |
| } |
| |
| function getUserMedia(dictionary, callback) { |
| try { |
| navigator.webkitGetUserMedia(dictionary, callback, error); |
| } catch (e) { |
| testFailed('webkitGetUserMedia threw exception :' + e); |
| finishJSTest(); |
| } |
| } |
| |
| function tryAddTrack(stream, track) { |
| try { |
| stream.addTrack(track); |
| } catch (exception) { |
| testFailed("addTrack threw an exception."); |
| finishJSTest(); |
| } |
| } |
| |
| function tryRemoveTrack(stream, track) { |
| try { |
| stream.removeTrack(track); |
| } catch (exception) { |
| testFailed("removeTrack threw an exception."); |
| finishJSTest(); |
| } |
| } |
| |
| function shouldNotFire() { |
| testFailed("\"addtrack\" or \"removetrack\" events should not fire as a result of local addTrack() or removeTrack() operations."); |
| } |
| |
| function onStreamInactive() { |
| testPassed('Stream1 inactive.'); |
| shouldBeFalse('stream1.active'); |
| setTimeout(finishJSTest, 0); |
| } |
| |
| function onStreamActive() { |
| testPassed('Stream1 active.'); |
| shouldBeTrue('stream1.active'); |
| stream1.oninactive = onStreamInactive; |
| tryRemoveTrack(stream1, stream3.getAudioTracks()[0]); |
| } |
| |
| function gotStream3(s) { |
| stream3 = s; |
| stream1.onactive = onStreamActive; |
| // onstreamactive doesn't work any more, so this test makes no more sense. |
| // crbug.com/781716 |
| // tryAddTrack(stream1, stream3.getAudioTracks()[0]); |
| finishJSTest(); |
| } |
| |
| function gotStream2(s) { |
| stream2 = s; |
| |
| shouldBe('stream1.getAudioTracks().length', '1'); |
| shouldBe('stream1.getVideoTracks().length', '1'); |
| shouldBe('stream1.getTracks().length', '2'); |
| |
| shouldBe('stream2.getAudioTracks().length', '1'); |
| shouldBe('stream2.getVideoTracks().length', '1'); |
| shouldBe('stream2.getTracks().length', '2'); |
| |
| stream1.onaddtrack = shouldNotFire; |
| stream1.onremovetrack = shouldNotFire; |
| |
| // remove a track of each kind |
| audioTrack = stream1.getAudioTracks()[0]; |
| videoTrack = stream1.getVideoTracks()[0]; |
| |
| tryRemoveTrack(stream1, audioTrack); |
| // verify removed tracks |
| shouldBe('stream1.getAudioTracks().length', '0'); |
| // verify that gettracks length is reduced by 1 |
| shouldBe('stream1.getTracks().length', '1'); |
| shouldBeNull('stream1.getTrackById(audioTrack.id)'); |
| // remove a non-existent (already removed) track (should not throw) |
| tryRemoveTrack(stream1, audioTrack); |
| // (re-)add tracks |
| tryAddTrack(stream1, audioTrack); |
| shouldBeNonNull('stream1.getTrackById(audioTrack.id)'); |
| shouldBe('audioTrack', 'stream1.getAudioTracks()[0]'); |
| |
| tryRemoveTrack(stream1, videoTrack); |
| shouldBe('stream1.getVideoTracks().length', '0'); |
| // verify that gettracks length is reduced by 1 |
| shouldBe('stream1.getTracks().length', '1'); |
| shouldBeNull('stream1.getTrackById(videoTrack.id)'); |
| tryRemoveTrack(stream1, videoTrack); |
| tryAddTrack(stream1, videoTrack); |
| |
| // verify added tracks |
| shouldBe('stream1.getAudioTracks().length', '1'); |
| shouldBe('stream1.getVideoTracks().length', '1'); |
| shouldBe('stream1.getTracks().length', '2'); |
| |
| // verify that kind and label is preserved |
| shouldBe('stream1.getAudioTracks()[0].kind', 'audioTrack.kind'); |
| shouldBe('stream1.getAudioTracks()[0].label', 'audioTrack.label'); |
| shouldBe('stream1.getVideoTracks()[0].kind', 'videoTrack.kind'); |
| shouldBe('stream1.getVideoTracks()[0].label', 'videoTrack.label'); |
| |
| // try adding stream1's own tracks |
| tryAddTrack(stream1, stream1.getAudioTracks()[0]); |
| tryAddTrack(stream1, stream1.getVideoTracks()[0]); |
| |
| // verify that nothing has changed |
| shouldBe('stream1.getAudioTracks().length', '1'); |
| shouldBe('stream1.getVideoTracks().length', '1'); |
| shouldBe('stream1.getTracks().length', '2'); |
| |
| // add new tracks (from stream2) |
| tryAddTrack(stream1, stream2.getAudioTracks()[0]); |
| tryAddTrack(stream1, stream2.getVideoTracks()[0]); |
| |
| // verify added tracks |
| shouldBe('stream1.getAudioTracks().length', '2'); |
| shouldBe('stream1.getVideoTracks().length', '2'); |
| shouldBe('stream1.getTracks().length', '4'); |
| |
| // when all tracks have been removed, stream.active should return false. |
| tryRemoveTrack(stream2, stream2.getAudioTracks()[0]); |
| tryRemoveTrack(stream2, stream2.getVideoTracks()[0]); |
| shouldBeFalse('stream2.active'); |
| |
| // when all tracks have been stopped, stream.active should return false. |
| for (var i = 0; i < stream1.getAudioTracks().length; i++) |
| stream1.getAudioTracks()[i].stop(); |
| for (var i = 0; i < stream1.getVideoTracks().length; i++) |
| stream1.getVideoTracks()[i].stop(); |
| shouldBeFalse('stream1.active'); |
| getUserMedia({audio:true, video:true}, gotStream3); |
| } |
| |
| function gotStream1(s) { |
| stream1 = s; |
| getUserMedia({audio:true, video:true}, gotStream2); |
| } |
| |
| getUserMedia({audio:true, video:true}, gotStream1); |
| |
| window.jsTestIsAsync = true; |
| window.successfullyParsed = true; |
| </script> |
| </body> |
| </html> |