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 15 namespace net { 16 17 namespace { 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.) 23 NetworkChangeNotifier* g_network_change_notifier = NULL; 24 25 class MockNetworkChangeNotifier : public NetworkChangeNotifier { 26 public: 27 virtual bool IsCurrentlyOffline() const { return false; } 28 }; 29 30 } // namespace 31 32 NetworkChangeNotifier::~NetworkChangeNotifier() { 33 DCHECK_EQ(this, g_network_change_notifier); 34 g_network_change_notifier = NULL; 35 } 36 37 NetworkChangeNotifier* 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 51 bool NetworkChangeNotifier::IsOffline() { 52 return g_network_change_notifier && 53 g_network_change_notifier->IsCurrentlyOffline(); 54 } 55 56 // static 57 NetworkChangeNotifier* NetworkChangeNotifier::CreateMock() { 58 return new MockNetworkChangeNotifier(); 59 } 60 61 void NetworkChangeNotifier::AddIPAddressObserver(IPAddressObserver* observer) { 62 if (g_network_change_notifier) 63 g_network_change_notifier->ip_address_observer_list_->AddObserver(observer); 64 } 65 66 void 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 74 void 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 82 void 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 90 NetworkChangeNotifier::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 101 void NetworkChangeNotifier::NotifyObserversOfIPAddressChange() { 102 if (g_network_change_notifier) { 103 g_network_change_notifier->ip_address_observer_list_->Notify( 104 &IPAddressObserver::OnIPAddressChanged); 105 } 106 } 107 108 void NetworkChangeNotifier::NotifyObserversOfOnlineStateChange() { 109 online_state_observer_list_->Notify( 110 &OnlineStateObserver::OnOnlineStateChanged, !IsOffline()); 111 } 112 113 } // namespace net 114