1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/base/network_change_notifier.h"
6 #include "net/base/network_change_notifier_factory.h"
7 #include "build/build_config.h"
9 #include "net/base/network_change_notifier_win.h"
10 #elif defined(OS_LINUX) || defined(OS_ANDROID)
11 #include "net/base/network_change_notifier_linux.h"
12 #elif defined(OS_MACOSX)
13 #include "net/base/network_change_notifier_mac.h"
20 // The actual singleton notifier. The class contract forbids usage of the API
21 // in ways that would require us to place locks around access to this object.
22 // (The prohibition on global non-POD objects makes it tricky to do such a thing
24 NetworkChangeNotifier
* g_network_change_notifier
= NULL
;
26 // Class factory singleton.
27 NetworkChangeNotifierFactory
* g_network_change_notifier_factory
= NULL
;
29 class MockNetworkChangeNotifier
: public NetworkChangeNotifier
{
31 virtual bool IsCurrentlyOffline() const { return false; }
36 NetworkChangeNotifier::~NetworkChangeNotifier() {
37 DCHECK_EQ(this, g_network_change_notifier
);
38 g_network_change_notifier
= NULL
;
42 void NetworkChangeNotifier::SetFactory(
43 NetworkChangeNotifierFactory
* factory
) {
44 CHECK(!g_network_change_notifier_factory
);
45 g_network_change_notifier_factory
= factory
;
49 NetworkChangeNotifier
* NetworkChangeNotifier::Create() {
50 if (g_network_change_notifier_factory
)
51 return g_network_change_notifier_factory
->CreateInstance();
54 NetworkChangeNotifierWin
* network_change_notifier
=
55 new NetworkChangeNotifierWin();
56 network_change_notifier
->WatchForAddressChange();
57 return network_change_notifier
;
58 #elif defined(OS_CHROMEOS)
59 // ChromeOS builds MUST use its own class factory.
62 #elif defined(OS_LINUX) || defined(OS_ANDROID)
63 return NetworkChangeNotifierLinux::Create();
64 #elif defined(OS_MACOSX)
65 return new NetworkChangeNotifierMac();
73 bool NetworkChangeNotifier::IsOffline() {
74 return g_network_change_notifier
&&
75 g_network_change_notifier
->IsCurrentlyOffline();
79 NetworkChangeNotifier
* NetworkChangeNotifier::CreateMock() {
80 return new MockNetworkChangeNotifier();
83 void NetworkChangeNotifier::AddIPAddressObserver(IPAddressObserver
* observer
) {
84 if (g_network_change_notifier
)
85 g_network_change_notifier
->ip_address_observer_list_
->AddObserver(observer
);
88 void NetworkChangeNotifier::AddOnlineStateObserver(
89 OnlineStateObserver
* observer
) {
90 if (g_network_change_notifier
) {
91 g_network_change_notifier
->online_state_observer_list_
->AddObserver(
96 void NetworkChangeNotifier::AddDNSObserver(DNSObserver
* observer
) {
97 if (g_network_change_notifier
) {
98 g_network_change_notifier
->resolver_state_observer_list_
->AddObserver(
103 void NetworkChangeNotifier::RemoveIPAddressObserver(
104 IPAddressObserver
* observer
) {
105 if (g_network_change_notifier
) {
106 g_network_change_notifier
->ip_address_observer_list_
->RemoveObserver(
111 void NetworkChangeNotifier::RemoveOnlineStateObserver(
112 OnlineStateObserver
* observer
) {
113 if (g_network_change_notifier
) {
114 g_network_change_notifier
->online_state_observer_list_
->RemoveObserver(
119 void NetworkChangeNotifier::RemoveDNSObserver(DNSObserver
* observer
) {
120 if (g_network_change_notifier
) {
121 g_network_change_notifier
->resolver_state_observer_list_
->RemoveObserver(
126 NetworkChangeNotifier::NetworkChangeNotifier()
127 : ip_address_observer_list_(
128 new ObserverListThreadSafe
<IPAddressObserver
>(
129 ObserverListBase
<IPAddressObserver
>::NOTIFY_EXISTING_ONLY
)),
130 online_state_observer_list_(
131 new ObserverListThreadSafe
<OnlineStateObserver
>(
132 ObserverListBase
<OnlineStateObserver
>::NOTIFY_EXISTING_ONLY
)),
133 resolver_state_observer_list_(
134 new ObserverListThreadSafe
<DNSObserver
>(
135 ObserverListBase
<DNSObserver
>::NOTIFY_EXISTING_ONLY
)) {
136 DCHECK(!g_network_change_notifier
);
137 g_network_change_notifier
= this;
140 void NetworkChangeNotifier::NotifyObserversOfIPAddressChange() {
141 if (g_network_change_notifier
) {
142 g_network_change_notifier
->ip_address_observer_list_
->Notify(
143 &IPAddressObserver::OnIPAddressChanged
);
147 void NetworkChangeNotifier::NotifyObserversOfDNSChange() {
148 if (g_network_change_notifier
) {
149 g_network_change_notifier
->resolver_state_observer_list_
->Notify(
150 &DNSObserver::OnDNSChanged
);
154 void NetworkChangeNotifier::NotifyObserversOfOnlineStateChange() {
155 if (g_network_change_notifier
) {
156 g_network_change_notifier
->online_state_observer_list_
->Notify(
157 &OnlineStateObserver::OnOnlineStateChanged
, !IsOffline());
161 NetworkChangeNotifier::DisableForTest::DisableForTest()
162 : network_change_notifier_(g_network_change_notifier
) {
163 DCHECK(g_network_change_notifier
);
164 g_network_change_notifier
= NULL
;
167 NetworkChangeNotifier::DisableForTest::~DisableForTest() {
168 DCHECK(!g_network_change_notifier
);
169 g_network_change_notifier
= network_change_notifier_
;