<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Testing video rotation in basic video exchange </title>
        <script src="../resources/testharness.js"></script>
        <script src="../resources/testharnessreport.js"></script>
    </head>
    <body>
        <video id="localVideo" autoplay playsInline width="320" height="240"></video>
        <video id="remoteVideo" autoplay playsInline width="320" height="240"></video>
        <canvas id="canvas0" width="320" height="240"></canvas>
        <canvas id="canvas1" width="320" height="240"></canvas>
        <canvas id="canvas2" width="320" height="240"></canvas>
        <canvas id="canvas3" width="320" height="240"></canvas>
        <script src ="routines.js"></script>
        <script>
function isVideoBlack(video, canvasId)
{
    var canvas = document.getElementById(canvasId);
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);

    imageData = canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);
    data = imageData.data;
    for (var cptr = 0; cptr < canvas.width * canvas.height; ++cptr) {
        // Approximatively black pixels.
        if (data[4 * cptr] > 30 || data[4 * cptr + 1] > 30 || data[4 * cptr + 2] > 30)
            return false;
    }
    return true;
}

function pollVideoBlackCheck(expected, video, canvasId, resolve)
{
    if (isVideoBlack(video, canvasId) === expected) {
        resolve();
        return;
    }

    setTimeout(() => pollVideoBlackCheck(expected, video, canvasId, resolve), 100);
}

function checkVideoBlack(expected, video, canvasId)
{
    return new Promise((resolve, reject) => {
        pollVideoBlackCheck(expected, video, canvasId, resolve);
        setTimeout(() => reject("checkVideoBlack timed out for '" + canvasId + "', expected " + expected), 5000);
    });
}

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

    return navigator.mediaDevices.getUserMedia({video: {width: 320, height: 240, facingMode: "environment"}}).then((localStream) => {
        localVideo.srcObject = localStream;
        return new Promise((resolve, reject) => {
            track = localStream.getVideoTracks()[0];

            createConnections((firstConnection) => {
                firstConnection.addTrack(track, localStream);
                if (window.internals)
                    internals.applyRotationForOutgoingVideoSources(firstConnection);
            }, (secondConnection) => {
                secondConnection.ontrack = (trackEvent) => {
                    resolve(trackEvent.streams[0]);
                };
            });
            setTimeout(() => reject("Test timed out"), 5000);
        });
    }).then((remoteStream) => {
        remoteVideo.srcObject = remoteStream;
        return remoteVideo.play();
    });
}, "Setting video exchange");

promise_test(async (test) => {
   await checkVideoBlack(false, remoteVideo, "canvas0");
   await waitForVideoSize(remoteVideo, 320, 240);
}, "Track is enabled, video should not be black");

promise_test(async (test) => {
    await checkVideoBlack(false, localVideo, "canvas0");
    await waitForVideoSize(localVideo, 320, 240);

    if (window.internals)
        window.internals.setCameraMediaStreamTrackOrientation(track, 90);

    await checkVideoBlack(false, localVideo, "canvas1");
    await waitForVideoSize(localVideo, 240, 320);
}, "Track is enabled and rotated, local video should not be black and should change size");

promise_test((test) => {
    if (window.internals)
        window.internals.setCameraMediaStreamTrackOrientation(track, 90);

    return checkVideoBlack(false, remoteVideo, "canvas2").then(() => {
        return waitForVideoSize(remoteVideo, 240, 320);
    });
}, "Track is enabled and rotated, remote video should not be black and should change size");

promise_test((test) => {
    if (window.internals)
        window.internals.setCameraMediaStreamTrackOrientation(track, 180);

    return checkVideoBlack(false, remoteVideo, "canvas3").then(() => {
        return waitForVideoSize(remoteVideo, 320, 240);
    });
}, "Track is enabled and rotated again, video should not be black and should change size");
        </script>
    </body>
</html>
