<!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:1280}}, {height:{min:720} } ]}}).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>
