<!-- webkit-test-runner [ CaptureAudioInGPUProcessEnabled=true CaptureVideoInGPUProcessEnabled=true ] -->
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Don't unmute audio when a tab becomes visible unless it was muted when the tab was hidden</title>
        <script src="../../../resources/testharness.js"></script>
        <script src="../../../resources/testharnessreport.js"></script>
    </head>
    <body>
        <script>
            let audioTrack;
            let videoTrack;

            promise_test((t) => {
                if (window.testRunner)
                    testRunner.setUserMediaPermission(true);
                if (!window.internals)
                    return Promise.reject("this test needs internals API");

                internals.setShouldInterruptAudioOnPageVisibilityChange(true);

                return navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then((stream) => {
                    audioTrack = stream.getAudioTracks()[0];
                    videoTrack = stream.getVideoTracks()[0];

                    assert_false(audioTrack.muted, "audio track is active");
                    assert_false(videoTrack.muted, "video track is active");
                })

                .then(() => {
                    promise_test(async () => {
                        if (window.internals)
                            window.internals.setPageVisibility(false);
                        if (!audioTrack.muted)
                            await new Promise(resolve => audioTrack.onmute = resolve);
                        assert_true(audioTrack.muted, "audio track is muted");
                        if (!videoTrack.muted)
                            await new Promise(resolve => videoTrack.onmute = resolve);
                        assert_true(videoTrack.muted, "video track is muted");
                    }, "Hide page, video and audio should be muted");
                })

                .then(() => {
                    promise_test(async () => {
                        if (window.internals)
                            window.internals.setPageVisibility(true);
                        if (audioTrack.muted)
                            await new Promise(resolve => audioTrack.onunmute = resolve);
                        assert_false(audioTrack.muted, "audio track is active");
                        if (videoTrack.muted)
                            await new Promise(resolve => videoTrack.onunmute = resolve);
                        assert_false(videoTrack.muted, "video track is active");
                    }, "Show page, video and audio should be unmuted");
                })

                .then(() => {
                    promise_test(async () => {
                        if (window.internals) {
                            window.internals.setPageVisibility(false);
                            window.internals.setPageMuted("capturedevices");
                        }
                        if (!audioTrack.muted)
                            await new Promise(resolve => audioTrack.onmute = resolve);
                        assert_true(audioTrack.muted, "audio track is muted");
                        if (!videoTrack.muted)
                            await new Promise(resolve => videoTrack.onmute = resolve);
                        assert_true(videoTrack.muted, "video track is muted");
                    }, "Hide and mute page, video and audio should be muted");
                })

                .then(() => {
                    promise_test(async () => {
                        if (window.internals)
                            window.internals.setPageVisibility(true);
                        assert_true(audioTrack.muted, "audio track is muted");
                        assert_true(videoTrack.muted, "video track is muted");
                    }, "Show page, video and audio should remain muted");
                })
            }, "Setup stream");

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