<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Mute video and audio tracks independently, make sure page state updates correctly.</title>
    <script src="../../resources/testharness.js"></script>
    <script src="../../resources/testharnessreport.js"></script>
    <script>

    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.setMediaStreamTrackMuted(track, false)
                        }
                    })
                }

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

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

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