replaceTrack triggers negotiationneeded
[WebKit-https.git] / LayoutTests / webrtc / video-replace-track.html
1 <!doctype html>
2 <html>
3     <head>
4         <meta charset="utf-8">
5         <title>Testing basic video exchange from offerer to receiver</title>
6         <script src="../resources/testharness.js"></script>
7         <script src="../resources/testharnessreport.js"></script>
8         <script src="routines.js"></script>
9     </head>
10     <body>
11 <div id="log"></div>
12         <video id="video" autoplay=""></video>
13         <canvas id="canvas" width="640" height="480"></canvas>
14         <script src ="routines.js"></script>
15         <script>
16 video = document.getElementById("video");
17 canvas = document.getElementById("canvas");
18
19 function grabImagePixels()
20 {
21     canvas.width = video.videoWidth;
22     canvas.height = video.videoHeight;
23     canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
24
25     imageData = canvas.getContext('2d').getImageData(20, 20, 2, 2);
26     return imageData.data;
27  }
28
29 async function testFrontCameraImage(counter)
30 {
31     if (!counter)
32         counter = 0;
33
34     if (isVideoBlack(canvas, video, 20, 20, 2 ,2))
35         return;
36
37     if (counter >= 20)
38         return Promise.reject("testFrontCameraImage timed out");
39
40     await waitFor(50);
41     return testFrontCameraImage(++counter);
42 }
43
44 function isBetween100And200(value)
45 {
46      return data[0] > 100 && data[0] < 200;
47 }
48
49 async function testBackCameraImage(counter)
50 {
51     if (!counter)
52         counter = 0;
53
54     data = grabImagePixels();
55
56     if(isBetween100And200(data[0]) && isBetween100And200(data[1]) && isBetween100And200(data[2]))
57         return;
58
59     if (counter >= 20)
60         return Promise.reject("testFrontCameraImage timed out");
61
62     await waitFor(50);
63     return testBackCameraImage(++counter);
64 }
65
66 promise_test((test) => {
67     if (window.testRunner)
68         testRunner.setUserMediaPermission(true);
69
70     var sender;
71     var frontStream;
72     var backStream;
73     return navigator.mediaDevices.getUserMedia({ video: { facingMode: { exact: ["user"] } } }).then((stream) => {
74         frontStream = stream;
75         return new Promise((resolve, reject) => {
76             createConnections((firstConnection) => {
77                 sender = firstConnection.addTrack(frontStream.getVideoTracks()[0], frontStream);
78            }, (secondConnection) => {
79                 secondConnection.ontrack = (trackEvent) => {
80                     resolve(trackEvent.streams[0]);
81                 };
82             });
83             setTimeout(() => reject("Test timed out"), 5000);
84         });
85     }).then((remoteStream) => {
86         video.srcObject = remoteStream;
87         return video.play();
88     }).then(() => {
89         return testFrontCameraImage();
90     }).then(() => {
91         return navigator.mediaDevices.getUserMedia({ video: { facingMode: { exact: ["environment"] } } });
92     }).then((stream) => {
93         backStream = stream;
94         var currentTrack = sender.track;
95         promise = sender.replaceTrack(backStream.getVideoTracks()[0]);
96         assert_true(currentTrack === sender.track);
97         return promise;
98     }).then(() => {
99         assert_true(sender.track === backStream.getVideoTracks()[0]);
100         return testBackCameraImage();
101     });
102 }, "Switching from front to back camera");
103
104 var didReplaceTrack = false;
105 promise_test((test) => {
106     if (window.testRunner)
107         testRunner.setUserMediaPermission(true);
108
109     var sender;
110     var frontStream;
111     var backStream;
112
113     return navigator.mediaDevices.getUserMedia({ video: { width: 640, height: 480, facingMode: { exact: ["user"] } } }).then((stream) => {
114         frontStream = stream;
115         assert_true(frontStream.getVideoTracks()[0].getSettings().height === 480, "frontStream should be big");
116         return new Promise((resolve, reject) => {
117             createConnections((firstConnection) => {
118                 sender = firstConnection.addTrack(frontStream.getVideoTracks()[0], frontStream);
119                 firstConnection.addEventListener('negotiationneeded', test.step_func(() => {
120                     assert_false(didReplaceTrack, 'negotiationeeded should not be called after replacing an ongoing track');
121                 }));
122             }, (secondConnection) => {
123                 secondConnection.ontrack = (trackEvent) => {
124                     resolve(trackEvent.streams[0]);
125                 };
126             });
127             setTimeout(() => reject("Test timed out"), 5000);
128         });
129     }).then((remoteStream) => {
130         video.srcObject = remoteStream;
131         return video.play();
132     }).then(() => {
133         return testFrontCameraImage();
134     }).then(() => {
135         return navigator.mediaDevices.getUserMedia({ video: { width: 320, height: 240, facingMode: { exact: ["environment"] } } });
136     }).then((stream) => {
137         backStream = stream;
138         assert_true(backStream.getVideoTracks()[0].getSettings().height === 240, "backStream should be small");
139         didReplaceTrack = true;
140         return sender.replaceTrack(backStream.getVideoTracks()[0]);
141     }).then(() => {
142         return testBackCameraImage();
143     });
144 }, "Switching from front to back camera, with lower resolution");
145
146 promise_test((test) => {
147     if (window.testRunner)
148         testRunner.setUserMediaPermission(true);
149
150     var sender;
151     var frontStream;
152     var backStream;
153
154     return navigator.mediaDevices.getUserMedia({ video: { width: 320, height: 240, facingMode: { exact: ["user"] } } }).then((stream) => {
155         frontStream = stream;
156         assert_true(frontStream.getVideoTracks()[0].getSettings().height === 240, "front stream should be small");
157     }).then(() => {
158         return new Promise((resolve, reject) => {
159             createConnections((firstConnection) => {
160                 sender = firstConnection.addTrack(frontStream.getVideoTracks()[0], frontStream);
161             }, (secondConnection) => {
162                 secondConnection.ontrack = (trackEvent) => {
163                     resolve(trackEvent.streams[0]);
164                 };
165             });
166             setTimeout(() => reject("Test timed out"), 5000);
167         });
168     }).then((remoteStream) => {
169         video.srcObject = remoteStream;
170         return video.play();
171     }).then(() => {
172         return testFrontCameraImage();
173     }).then(() => {
174         return navigator.mediaDevices.getUserMedia({ video: { width: 640, height: 480 , facingMode: { exact: ["environment"] } } });
175     }).then((stream) => {
176         backStream = stream;
177         assert_true(backStream.getVideoTracks()[0].getSettings().height === 480, "back stream should be big");
178         return sender.replaceTrack(backStream.getVideoTracks()[0]);
179     }).then(() => {
180         return testBackCameraImage();
181     });
182
183 }, "Switching from front to back camera, with higher resolution");
184         </script>
185     </body>
186 </html>