<!-- webkit-test-runner [ enableCaptureAudioInGPUProcess=true enableCaptureVideoInGPUProcess=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(() => {
                    test(() => {
                        if (window.internals)
                            window.internals.setPageVisibility(false);
                        assert_true(audioTrack.muted, "audio track is muted");
                        assert_true(videoTrack.muted, "video track is muted");
                    }, "Hide page, video and audio should be muted");
                })

                .then(() => {
                    test(() => {
                        if (window.internals)
                            window.internals.setPageVisibility(true);
                        assert_false(audioTrack.muted, "audio track is active");
                        assert_false(videoTrack.muted, "video track is active");
                    }, "Show page, video and audio should be unmuted");
                })

                .then(() => {
                    test(() => {
                        if (window.internals) {
                            window.internals.setPageVisibility(false);
                            window.internals.setPageMuted("capturedevices");
                        }
                        assert_true(audioTrack.muted, "audio track is muted");
                        assert_true(videoTrack.muted, "video track is muted");
                    }, "Hide and mute page, video and audio should be muted");
                })

                .then(() => {
                    test(() => {
                        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>
