<!-- webkit-test-runner [ enableCaptureAudioInUIProcess=false ] -->
<!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>
    <script>
    promise_test(async (test) => {
        const stream = await navigator.mediaDevices.getUserMedia({audio: true});
        const track = stream.getAudioTracks()[0];
        if (!window.internals)
            return;

        let promise = new Promise((resolve, reject) => { track.onmute = resolve; setTimeout(() => reject("no mute"), 5000) });
        internals.setMediaStreamSourceInterrupted(track, true);
        await promise;

        assert_true(track.muted, "track is muted");
        assert_true(internals.isMediaStreamSourceInterrupted(track), "source is interrupted");

        promise = new Promise((resolve, reject) => { track.onunmute = resolve; setTimeout(() => reject("no unmute"), 5000) });
        internals.setMediaStreamSourceInterrupted(track, false);
        await promise;

        assert_false(track.muted, "track is no longer muted");
        assert_false(internals.isMediaStreamSourceInterrupted(track), "source is not interrupted");

        track.stop();
    }, "Suspend/resume audio track");

    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>
