<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Testing 'devicechange' event is fired correctly.</title>
    <script src="../../resources/testharness.js"></script>
    <script src="../../resources/testharnessreport.js"></script>
    <script>
    let stream = null;
    
    let setup = async (test) => {
        if (!window.testRunner)
            return Promise.reject("test requires internal API");

        test.add_cleanup(() => { testRunner.resetMockMediaDevices(); });

        testRunner.setUserMediaPermission(true);
        
        stream = null;
    }

    promise_test(async (test) => {
    
        await setup(test);

        await navigator.mediaDevices.getUserMedia({ audio:true, video:true })
            .then(s => stream = s)

        let devices = await navigator.mediaDevices.enumerateDevices();

        assert_true(!!devices.length, "check there are some devices");

        testRunner.clearMockMediaDevices();

        devices = await navigator.mediaDevices.enumerateDevices();
        assert_false(!!devices.length, "check there are no more devices");

        await new Promise((resolve, reject) => {
            navigator.mediaDevices.ondevicechange = resolve;
            setTimeout(() => {
                console.log("event 1 took too long");
                resolve();
            }, 5000);
            testRunner.addMockCameraDevice("id1", "my camera");
        });
        devices = await navigator.mediaDevices.enumerateDevices();
        assert_equals(devices[0].kind, "videoinput");
        assert_equals(devices[0].label, "my camera");

        await new Promise((resolve, reject) => {
            navigator.mediaDevices.ondevicechange = resolve;
            setTimeout(() => {
                console.log("event 2 took too long");
                resolve();
            }, 5000);
            testRunner.addMockMicrophoneDevice("id2", "my mic");
        });
        devices = await navigator.mediaDevices.enumerateDevices();
        assert_equals(devices[0].kind, "audioinput");
        assert_equals(devices[0].label, "my mic");

    }, "'devicechange' event fired when device list changes");

    promise_test(async (test) => {

        await setup(test);

        let eventCount = 0;
        await new Promise((resolve, reject) => {
            navigator.mediaDevices.ondevicechange = (evt) => {
                ++eventCount;
                setTimeout(() => {
                    resolve();
                }, 500);
            }

            setTimeout(() => {
                console.log("navigator.mediaDevices.ondevicechange took too long");
                resolve();
            }, 4000);

            testRunner.addMockMicrophoneDevice("id4", "microphone 3");
            testRunner.addMockMicrophoneDevice("id5", "microphone 4");
        });
        assert_equals(eventCount, 1, "one event fired");

    }, "'devicechange' events fired quickly are coalesced");


    promise_test(async (test) => {

        await setup(test);

        await new Promise((resolve, reject) => {
            let timeout = setTimeout(() => {
                console.log("window.onblur took too long");
                resolve();
            }, 5000);

            window.onblur = () => {
                clearTimeout(timeout);
                resolve();
            }
        
            internals.setPageIsFocusedAndActive(false);
        });

        await new Promise((resolve, reject) => {
            assert_false(document.hasFocus(), "document.hasFocus()");

            navigator.mediaDevices.ondevicechange = () => {
                assert_true(document.hasFocus(), "devicechange should only fire when the document is focused and active");
                resolve();
            };

            setTimeout(() => {
                internals.setPageIsFocusedAndActive(true);
            }, 200);

            testRunner.addMockMicrophoneDevice("id3", "microphone 2");
        });

    }, "'devicechange' event is not fired when the document doesn't has focus or permission to capture");

    promise_test(async (test) => {

        await setup(test);

        await navigator.mediaDevices.getUserMedia({ audio:true, video:true })
            .then(s => stream = s);

        await new Promise((resolve, reject) => {
            let timeout = setTimeout(() => {
                console.log("window.onblur took too long");
                resolve();
            }, 5000);

            window.onblur = () => {
                clearTimeout(timeout);
                resolve();
            }
        
            internals.setPageIsFocusedAndActive(false);
        });

        await new Promise((resolve, reject) => {
            assert_false(document.hasFocus(), "document.hasFocus()");

            navigator.mediaDevices.ondevicechange = () => {
                assert_false(document.hasFocus(), "devicechange should fire when the document is not focused but can capture");
                resolve();
            };

            testRunner.addMockMicrophoneDevice("id3", "microphone 2");
        });

    }, "'devicechange' event is fired when the document doesn't has focus but has permission to capture");

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