1/*
2 * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "NetworkStateNotifier.h"
28
29#include <wtf/NeverDestroyed.h>
30
31#if USE(WEB_THREAD)
32#include "WebCoreThread.h"
33#endif
34
35namespace WebCore {
36
37static const Seconds updateStateSoonInterval { 2_s };
38
39static bool shouldSuppressThreadSafetyCheck()
40{
41#if USE(WEB_THREAD)
42 return WebThreadIsEnabled();
43#else
44 return false;
45#endif
46}
47
48NetworkStateNotifier& NetworkStateNotifier::singleton()
49{
50 RELEASE_ASSERT(shouldSuppressThreadSafetyCheck() || isMainThread());
51 static NeverDestroyed<NetworkStateNotifier> networkStateNotifier;
52 return networkStateNotifier;
53}
54
55NetworkStateNotifier::NetworkStateNotifier()
56 : m_updateStateTimer([] {
57 singleton().updateState();
58 })
59{
60}
61
62bool NetworkStateNotifier::onLine()
63{
64 if (!m_isOnLine)
65 updateState();
66 return m_isOnLine.valueOr(true);
67}
68
69void NetworkStateNotifier::addListener(WTF::Function<void(bool)>&& listener)
70{
71 ASSERT(listener);
72 if (m_listeners.isEmpty())
73 startObserving();
74 m_listeners.append(WTFMove(listener));
75}
76
77void NetworkStateNotifier::updateState()
78{
79 auto wasOnLine = m_isOnLine;
80 updateStateWithoutNotifying();
81 if (m_isOnLine == wasOnLine)
82 return;
83 for (auto& listener : m_listeners)
84 listener(m_isOnLine.value());
85}
86
87void NetworkStateNotifier::updateStateSoon()
88{
89 m_updateStateTimer.startOneShot(updateStateSoonInterval);
90}
91
92} // namespace WebCore
93