<!DOCTYPE html><!-- webkit-test-runner [ CaptureAudioInGPUProcessEnabled=true CaptureVideoInGPUProcessEnabled=true MuteCameraOnMicrophoneInterruptionEnabled=false ] -->
<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.testRunner)
            return;

        let promise = new Promise((resolve, reject) => { track.onmute = resolve; setTimeout(() => reject("no mute"), 5000) });
        testRunner.setMockCaptureDevicesInterrupted(false, 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) });
        testRunner.setMockCaptureDevicesInterrupted(false, 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();
                            testRunner.setMockCaptureDevicesInterrupted(false, false);
                        }
                    })
                }

                if (window.testRunner) {
                    pageState = internals.pageMediaState();
                    testRunner.setMockCaptureDevicesInterrupted(isVideo, !isVideo);
                }
                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>
