<!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();
        let devices2 = await navigator.mediaDevices.enumerateDevices();

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

        testRunner.clearMockMediaDevices();
        await new Promise((resolve, reject) => {
            navigator.mediaDevices.ondevicechange = resolve;
            setTimeout(() => {
                reject("event 1 took too long");
            }, 5000);
        });
        devices = await navigator.mediaDevices.enumerateDevices();
        assert_false(!!devices.length, "check there are no more devices");

        testRunner.addMockCameraDevice("id1", "my camera");
        await new Promise((resolve, reject) => {
            navigator.mediaDevices.ondevicechange = resolve;
            setTimeout(() => {
                reject("event 2 took too long");
            }, 5000);
        });

        devices = await navigator.mediaDevices.enumerateDevices();
        assert_equals(devices[0].kind, "videoinput");
        assert_equals(devices[0].label, "my camera");

        testRunner.addMockMicrophoneDevice("id2", "my mic");
        await new Promise((resolve, reject) => {
            navigator.mediaDevices.ondevicechange = resolve;
            setTimeout(() => {
                reject("event 3 took too long");
            }, 5000);
        });
        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>
