<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Capture source interruption.</title>
    <script src="../../resources/testharness.js"></script>
    <script src="../../resources/testharnessreport.js"></script>
 </head>
<body>
    <video width=320 height=240></video>

    <script>

    let video;

   if (window.testRunner)
        testRunner.setUserMediaPermission(true);

    function waitForPageStateChange(numberOfTries, originalState, resolve, reject)
    {
        let newState = internals.pageMediaState();
        if (newState != originalState) {
            resolve(newState);
            return;
        }

        if (numberOfTries <= 0) {
            reject('Page state did not change in time.');
            return;
        }

        setTimeout(() => { waitForPageStateChange(--numberOfTries, originalState, resolve, reject); }, 10);
    }

    function testTrack(track, title)
    {
        promise_test((test) => {
            return new Promise((resolve, reject) => {
                let isVideo = track.kind == "video";
                if (window.internals) {
                    assert_false(internals.pageMediaState().includes('HasMutedVideoCaptureDevice'));
                    assert_false(internals.pageMediaState().includes('HasMutedAudioCaptureDevice'));
                }

                track.onunmute = () => reject("Got 'unmute' event unexpectedly!");
                track.onmute = () => {
                    new Promise((innerResolve, innerReject) => {
                        waitForPageStateChange(10, pageState, innerResolve, innerReject)
                    }).then((pageMediaState) => {

                        track.onunmute = (evt) => {
                            waitForPageStateChange(10, pageState, resolve, reject)
                        }

                        if (window.internals) {
                            assert_true(pageMediaState.includes(isVideo ? 'HasMutedVideoCaptureDevice' : 'HasMutedAudioCaptureDevice'));
                            assert_false(pageMediaState.includes(isVideo ? 'HasMutedAudioCaptureDevice' : 'HasMutedVideoCaptureDevice'));
                            assert_true(pageMediaState.includes(isVideo ? 'HasActiveAudioCaptureDevice' : 'HasActiveVideoCaptureDevice'));
                            assert_false(pageMediaState.includes(isVideo ? 'HasActiveVideoCaptureDevice' : 'HasActiveAudioCaptureDevice'));
                            pageState = internals.pageMediaState();
                            internals.setMediaStreamSourceInterrupted(track, false)
                        }
                    })
                }

                if (window.internals) {
                    pageState = internals.pageMediaState();
                    internals.setMediaStreamSourceInterrupted(track, true);
                }
                setTimeout(() => reject("Muted state did not change in 1 second"), 1000);
            });
        }, title);
    }

    promise_test((test) => {
        return navigator.mediaDevices.getUserMedia({ video: true, audio: true})
            .then((stream) => {
                testTrack(stream.getVideoTracks()[0], "Interrupt video track");
                testTrack(stream.getAudioTracks()[0], "Interrupt audio track");
            });
    }, "Create stream");


    </script>

</body>
</html>
