1 // Copyright 2013 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 "chrome/browser/extensions/api/networking_private/networking_private_event_router.h" 6 7 #include "chrome/browser/extensions/api/networking_private/networking_private_api.h" 8 #include "chrome/browser/extensions/api/networking_private/networking_private_service_client.h" 9 #include "chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.h" 10 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/common/extensions/api/networking_private.h" 12 13 namespace extensions { 14 15 // This is an event router that will observe listeners to |NetworksChanged| and 16 // |NetworkListChanged| events. 17 class NetworkingPrivateEventRouterImpl 18 : public NetworkingPrivateEventRouter, 19 NetworkingPrivateServiceClient::Observer { 20 public: 21 explicit NetworkingPrivateEventRouterImpl(Profile* profile); 22 virtual ~NetworkingPrivateEventRouterImpl(); 23 24 protected: 25 // KeyedService overrides: 26 virtual void Shutdown() OVERRIDE; 27 28 // EventRouter::Observer overrides: 29 virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE; 30 virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE; 31 32 // NetworkingPrivateServiceClient::Observer overrides: 33 virtual void OnNetworksChangedEvent( 34 const std::vector<std::string>& network_guids) OVERRIDE; 35 virtual void OnNetworkListChangedEvent( 36 const std::vector<std::string>& network_guids) OVERRIDE; 37 38 private: 39 // Decide if we should listen for network changes or not. If there are any 40 // JavaScript listeners registered for the onNetworkChanged event, then we 41 // want to register for change notification from the network state handler. 42 // Otherwise, we want to unregister and not be listening to network changes. 43 void StartOrStopListeningForNetworkChanges(); 44 45 Profile* profile_; 46 bool listening_; 47 48 DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateEventRouterImpl); 49 }; 50 51 NetworkingPrivateEventRouterImpl::NetworkingPrivateEventRouterImpl( 52 Profile* profile) 53 : profile_(profile), listening_(false) { 54 // Register with the event router so we know when renderers are listening to 55 // our events. We first check and see if there *is* an event router, because 56 // some unit tests try to create all profile services, but don't initialize 57 // the event router first. 58 EventRouter* event_router = EventRouter::Get(profile_); 59 if (!event_router) 60 return; 61 event_router->RegisterObserver( 62 this, api::networking_private::OnNetworksChanged::kEventName); 63 event_router->RegisterObserver( 64 this, api::networking_private::OnNetworkListChanged::kEventName); 65 StartOrStopListeningForNetworkChanges(); 66 } 67 68 NetworkingPrivateEventRouterImpl::~NetworkingPrivateEventRouterImpl() { 69 DCHECK(!listening_); 70 } 71 72 void NetworkingPrivateEventRouterImpl::Shutdown() { 73 // Unregister with the event router. We first check and see if there *is* an 74 // event router, because some unit tests try to shutdown all profile services, 75 // but didn't initialize the event router first. 76 EventRouter* event_router = EventRouter::Get(profile_); 77 if (event_router) 78 event_router->UnregisterObserver(this); 79 80 if (!listening_) 81 return; 82 listening_ = false; 83 NetworkingPrivateServiceClient* process_client = 84 NetworkingPrivateServiceClientFactory::GetForProfile(profile_); 85 process_client->RemoveObserver(this); 86 } 87 88 void NetworkingPrivateEventRouterImpl::OnListenerAdded( 89 const EventListenerInfo& details) { 90 // Start listening to events from the network state handler. 91 StartOrStopListeningForNetworkChanges(); 92 } 93 94 void NetworkingPrivateEventRouterImpl::OnListenerRemoved( 95 const EventListenerInfo& details) { 96 // Stop listening to events from the network state handler if there are no 97 // more listeners. 98 StartOrStopListeningForNetworkChanges(); 99 } 100 101 void NetworkingPrivateEventRouterImpl::StartOrStopListeningForNetworkChanges() { 102 EventRouter* event_router = EventRouter::Get(profile_); 103 if (!event_router) 104 return; 105 bool should_listen = 106 event_router->HasEventListener( 107 api::networking_private::OnNetworksChanged::kEventName) || 108 event_router->HasEventListener( 109 api::networking_private::OnNetworkListChanged::kEventName); 110 111 if (should_listen && !listening_) { 112 NetworkingPrivateServiceClient* process_client = 113 NetworkingPrivateServiceClientFactory::GetForProfile(profile_); 114 process_client->AddObserver(this); 115 } 116 117 if (!should_listen && listening_) { 118 NetworkingPrivateServiceClient* process_client = 119 NetworkingPrivateServiceClientFactory::GetForProfile(profile_); 120 process_client->RemoveObserver(this); 121 } 122 123 listening_ = should_listen; 124 } 125 126 void NetworkingPrivateEventRouterImpl::OnNetworksChangedEvent( 127 const std::vector<std::string>& network_guids) { 128 EventRouter* event_router = EventRouter::Get(profile_); 129 if (!event_router) 130 return; 131 scoped_ptr<base::ListValue> args( 132 api::networking_private::OnNetworksChanged::Create(network_guids)); 133 scoped_ptr<extensions::Event> netchanged_event(new extensions::Event( 134 api::networking_private::OnNetworksChanged::kEventName, args.Pass())); 135 event_router->BroadcastEvent(netchanged_event.Pass()); 136 } 137 138 void NetworkingPrivateEventRouterImpl::OnNetworkListChangedEvent( 139 const std::vector<std::string>& network_guids) { 140 EventRouter* event_router = EventRouter::Get(profile_); 141 if (!event_router) 142 return; 143 scoped_ptr<base::ListValue> args( 144 api::networking_private::OnNetworkListChanged::Create(network_guids)); 145 scoped_ptr<extensions::Event> netlistchanged_event(new extensions::Event( 146 api::networking_private::OnNetworkListChanged::kEventName, 147 args.Pass())); 148 event_router->BroadcastEvent(netlistchanged_event.Pass()); 149 } 150 151 NetworkingPrivateEventRouter* NetworkingPrivateEventRouter::Create( 152 Profile* profile) { 153 return new NetworkingPrivateEventRouterImpl(profile); 154 } 155 156 } // namespace extensions 157