| // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/base/network_change_notifier.h" |
| #include "build/build_config.h" |
| #if defined(OS_WIN) |
| #include "net/base/network_change_notifier_win.h" |
| #elif defined(OS_LINUX) |
| #include "net/base/network_change_notifier_linux.h" |
| #elif defined(OS_MACOSX) |
| #include "net/base/network_change_notifier_mac.h" |
| #endif |
| |
| namespace net { |
| |
| namespace { |
| |
| // The actual singleton notifier. The class contract forbids usage of the API |
| // in ways that would require us to place locks around access to this object. |
| // (The prohibition on global non-POD objects makes it tricky to do such a thing |
| // anyway.) |
| NetworkChangeNotifier* g_network_change_notifier = NULL; |
| |
| class MockNetworkChangeNotifier : public NetworkChangeNotifier { |
| public: |
| virtual bool IsCurrentlyOffline() const { return false; } |
| }; |
| |
| } // namespace |
| |
| NetworkChangeNotifier::~NetworkChangeNotifier() { |
| DCHECK_EQ(this, g_network_change_notifier); |
| g_network_change_notifier = NULL; |
| } |
| |
| NetworkChangeNotifier* NetworkChangeNotifier::Create() { |
| #if defined(OS_WIN) |
| return new NetworkChangeNotifierWin(); |
| #elif defined(OS_LINUX) |
| return new NetworkChangeNotifierLinux(); |
| #elif defined(OS_MACOSX) |
| return new NetworkChangeNotifierMac(); |
| /* ARC MOD BEGIN */ |
| #elif defined(__native_client__) |
| // TODO(crbug.com/196960) Hook this up to real network state. |
| return NULL; |
| /* ARC MOD END */ |
| #else |
| NOTIMPLEMENTED(); |
| return NULL; |
| #endif |
| } |
| |
| // static |
| bool NetworkChangeNotifier::IsOffline() { |
| return g_network_change_notifier && |
| g_network_change_notifier->IsCurrentlyOffline(); |
| } |
| |
| // static |
| NetworkChangeNotifier* NetworkChangeNotifier::CreateMock() { |
| return new MockNetworkChangeNotifier(); |
| } |
| |
| void NetworkChangeNotifier::AddIPAddressObserver(IPAddressObserver* observer) { |
| if (g_network_change_notifier) |
| g_network_change_notifier->ip_address_observer_list_->AddObserver(observer); |
| } |
| |
| void NetworkChangeNotifier::AddOnlineStateObserver( |
| OnlineStateObserver* observer) { |
| if (g_network_change_notifier) { |
| g_network_change_notifier->online_state_observer_list_->AddObserver( |
| observer); |
| } |
| } |
| |
| void NetworkChangeNotifier::RemoveIPAddressObserver( |
| IPAddressObserver* observer) { |
| if (g_network_change_notifier) { |
| g_network_change_notifier->ip_address_observer_list_->RemoveObserver( |
| observer); |
| } |
| } |
| |
| void NetworkChangeNotifier::RemoveOnlineStateObserver( |
| OnlineStateObserver* observer) { |
| if (g_network_change_notifier) { |
| g_network_change_notifier->online_state_observer_list_->RemoveObserver( |
| observer); |
| } |
| } |
| |
| NetworkChangeNotifier::NetworkChangeNotifier() |
| : ip_address_observer_list_( |
| new ObserverListThreadSafe<IPAddressObserver>( |
| ObserverListBase<IPAddressObserver>::NOTIFY_EXISTING_ONLY)), |
| online_state_observer_list_( |
| new ObserverListThreadSafe<OnlineStateObserver>( |
| ObserverListBase<OnlineStateObserver>::NOTIFY_EXISTING_ONLY)) { |
| DCHECK(!g_network_change_notifier); |
| g_network_change_notifier = this; |
| } |
| |
| void NetworkChangeNotifier::NotifyObserversOfIPAddressChange() { |
| if (g_network_change_notifier) { |
| g_network_change_notifier->ip_address_observer_list_->Notify( |
| &IPAddressObserver::OnIPAddressChanged); |
| } |
| } |
| |
| void NetworkChangeNotifier::NotifyObserversOfOnlineStateChange() { |
| online_state_observer_list_->Notify( |
| &OnlineStateObserver::OnOnlineStateChanged, !IsOffline()); |
| } |
| |
| } // namespace net |