<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Testing muting video</title>
        <script src="../resources/testharness.js"></script>
        <script src="../resources/testharnessreport.js"></script>
    </head>
    <body>
        <div>Video should be running, go to black and running.</div>
        <div>Following, should be a snapshot of the video, a black frame and a snapshot of the video.</div>
        <video id="video" autoplay playsInline width="320" height="240"></video>
        <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>
var track;
var remoteTrack;
var receivingConnection;
promise_test((test) => {
    if (window.testRunner)
        testRunner.setUserMediaPermission(true);

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

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

promise_test(() => {
    if (receivingConnection.connectionState === "connected")
        return Promise.resolve();
    return new Promise((resolve, reject) => {
        receivingConnection.onconnectionstatechange = () => {
            if (receivingConnection.connectionState === "connected")
                resolve();
        };
        setTimeout(() => reject("Test timed out"), 5000);
    });
}, "Ensuring connection state is connected");

promise_test((test) => {
    return checkVideoBlack(false, canvas1, video);
}, "Track is enabled, video should not be black");

promise_test((test) => {
    track.enabled = false;
    return checkVideoBlack(true, canvas2, video);
}, "Track is disabled, video should be black");

async function getInboundRTPStatsNumberOfDecodedFrames(connection)
{
    var report = await connection.getStats();
    var framesDecoded;
    report.forEach((statItem) => {
        if (statItem.type === "inbound-rtp")
            framesDecoded = statItem.framesDecoded;
    });
    return framesDecoded;
}

async function testFrameDecodedIncreased(connection, count, previousFramesNumber)
{
    if (previousFramesNumber === undefined) {
        let number = await getInboundRTPStatsNumberOfDecodedFrames(connection);
        await waitFor(1000);
        return testFrameDecodedIncreased(connection, 0, number);
    }

    var number = await getInboundRTPStatsNumberOfDecodedFrames(connection);
    if (previousFramesNumber && number > previousFramesNumber)
        return;

    if (count >= 20)
        return Promise.reject("test increasing frame encoded timed out");

    await waitFor(1000);
    return testFrameDecodedIncreased(connection, ++count, previousFramesNumber);
}

promise_test((test) => {
    return testFrameDecodedIncreased(receivingConnection);
}, "If disabled, black frames should still be coming");

promise_test((test) => {
    track.enabled = true;
    return checkVideoBlack(false, canvas2, video);
}, "Track is enabled, video should not be black 2");

        </script>
    </body>
</html>
