<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Testing basic video exchange from offerer to receiver</title>
        <script src="../resources/testharness.js"></script>
        <script src="../resources/testharnessreport.js"></script>
    </head>
    <body>
        <video id="video1" autoplay=""></video>
        <video id="video2" autoplay=""></video>
        <canvas id="canvas" width="640" height="480"></canvas>
        <script src ="routines.js"></script>
        <script>
video = document.getElementById("video");
canvas = document.getElementById("canvas");

function testImage(video)
{
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);

    imageData = canvas.getContext('2d').getImageData(10, 325, 250, 1);
    data = imageData.data;

    var index = 20;
    assert_true(data[index] < 100);
    assert_true(data[index + 1] < 100);
    assert_true(data[index + 2] < 100);

    index = 80;
    assert_true(data[index] > 200);
    assert_true(data[index + 1] > 200);
    assert_true(data[index + 2] > 200);

    index += 80;
    assert_true(data[index] > 200);
    assert_true(data[index + 1] > 200);
    assert_true(data[index + 2] < 100);
}

promise_test((test) => {
    if (window.testRunner)
        testRunner.setUserMediaPermission(true);

    var stream;
    return navigator.mediaDevices.getUserMedia({video: {advanced: [{width:{min:640}}, {height:{min:480} } ]}}).then((stream) => {
        return new Promise((resolve, reject) => {
            createConnections((firstConnection) => {
                var track = stream.getVideoTracks()[0];
                firstConnection.addTrack(stream.getVideoTracks()[0], stream);
            }, (secondConnection) => {
                secondConnection.ontrack = (trackEvent) => {
                    assert_true(trackEvent.track instanceof MediaStreamTrack);
                    assert_true(trackEvent.receiver instanceof RTCRtpReceiver);
                    assert_true(Array.isArray(trackEvent.streams), "Array.isArray() should return true");
                    assert_true(Object.isFrozen(trackEvent.streams), "Object.isFrozen() should return true");
                    assert_equals(trackEvent.track.id, stream.getVideoTracks()[0].id);
                    assert_equals(trackEvent.track, trackEvent.streams[0].getVideoTracks()[0]);
                    resolve(trackEvent.streams[0]);
                };
            });
            setTimeout(() => reject("Test timed out"), 5000);
        });
    }).then((s) => {
        stream = s;
        video1.srcObject = stream;
        return video1.play();
    }).then(() => {
        testImage(video1);
    }).then(() => {
        internals.beginMediaSessionInterruption('EnteringBackground');
    }).then(() => {
        internals.endMediaSessionInterruption('');
    }).then(() => {
        video2.srcObject = stream;
        return video2.play();
    }).then(() => {
        testImage(video2);
    });
}, "Basic video exchange with media session interruption");
        </script>
    </body>
</html>
