1// Copyright (c) 2010 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. 4 5#include "net/base/network_change_notifier.h" 6#include "build/build_config.h" 7#if defined(OS_WIN) 8#include "net/base/network_change_notifier_win.h" 9#elif defined(OS_LINUX) 10#include "net/base/network_change_notifier_linux.h" 11#elif defined(OS_MACOSX) 12#include "net/base/network_change_notifier_mac.h" 13#endif 14 15namespace net { 16 17namespace { 18 19// The actual singleton notifier. The class contract forbids usage of the API 20// in ways that would require us to place locks around access to this object. 21// (The prohibition on global non-POD objects makes it tricky to do such a thing 22// anyway.) 23NetworkChangeNotifier* g_network_change_notifier = NULL; 24 25class MockNetworkChangeNotifier : public NetworkChangeNotifier { 26 public: 27 virtual bool IsCurrentlyOffline() const { return false; } 28}; 29 30} // namespace 31 32NetworkChangeNotifier::~NetworkChangeNotifier() { 33 DCHECK_EQ(this, g_network_change_notifier); 34 g_network_change_notifier = NULL; 35} 36 37NetworkChangeNotifier* NetworkChangeNotifier::Create() { 38#if defined(OS_WIN) 39 return new NetworkChangeNotifierWin(); 40#elif defined(OS_LINUX) 41 return new NetworkChangeNotifierLinux(); 42#elif defined(OS_MACOSX) 43 return new NetworkChangeNotifierMac(); 44#else 45 NOTIMPLEMENTED(); 46 return NULL; 47#endif 48} 49 50// static 51bool NetworkChangeNotifier::IsOffline() { 52 return g_network_change_notifier && 53 g_network_change_notifier->IsCurrentlyOffline(); 54} 55 56// static 57NetworkChangeNotifier* NetworkChangeNotifier::CreateMock() { 58 return new MockNetworkChangeNotifier(); 59} 60 61void NetworkChangeNotifier::AddIPAddressObserver(IPAddressObserver* observer) { 62 if (g_network_change_notifier) 63 g_network_change_notifier->ip_address_observer_list_->AddObserver(observer); 64} 65 66void NetworkChangeNotifier::AddOnlineStateObserver( 67 OnlineStateObserver* observer) { 68 if (g_network_change_notifier) { 69 g_network_change_notifier->online_state_observer_list_->AddObserver( 70 observer); 71 } 72} 73 74void NetworkChangeNotifier::RemoveIPAddressObserver( 75 IPAddressObserver* observer) { 76 if (g_network_change_notifier) { 77 g_network_change_notifier->ip_address_observer_list_->RemoveObserver( 78 observer); 79 } 80} 81 82void NetworkChangeNotifier::RemoveOnlineStateObserver( 83 OnlineStateObserver* observer) { 84 if (g_network_change_notifier) { 85 g_network_change_notifier->online_state_observer_list_->RemoveObserver( 86 observer); 87 } 88} 89 90NetworkChangeNotifier::NetworkChangeNotifier() 91 : ip_address_observer_list_( 92 new ObserverListThreadSafe<IPAddressObserver>( 93 ObserverListBase<IPAddressObserver>::NOTIFY_EXISTING_ONLY)), 94 online_state_observer_list_( 95 new ObserverListThreadSafe<OnlineStateObserver>( 96 ObserverListBase<OnlineStateObserver>::NOTIFY_EXISTING_ONLY)) { 97 DCHECK(!g_network_change_notifier); 98 g_network_change_notifier = this; 99} 100 101void NetworkChangeNotifier::NotifyObserversOfIPAddressChange() { 102 if (g_network_change_notifier) { 103 g_network_change_notifier->ip_address_observer_list_->Notify( 104 &IPAddressObserver::OnIPAddressChanged); 105 } 106} 107 108void NetworkChangeNotifier::NotifyObserversOfOnlineStateChange() { 109 online_state_observer_list_->Notify( 110 &OnlineStateObserver::OnOnlineStateChanged, !IsOffline()); 111} 112 113} // namespace net 114