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
NetworkingPrivateEventRouterImpl(Profile * profile)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
~NetworkingPrivateEventRouterImpl()68 NetworkingPrivateEventRouterImpl::~NetworkingPrivateEventRouterImpl() {
69 DCHECK(!listening_);
70 }
71
Shutdown()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
OnListenerAdded(const EventListenerInfo & details)88 void NetworkingPrivateEventRouterImpl::OnListenerAdded(
89 const EventListenerInfo& details) {
90 // Start listening to events from the network state handler.
91 StartOrStopListeningForNetworkChanges();
92 }
93
OnListenerRemoved(const EventListenerInfo & details)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
StartOrStopListeningForNetworkChanges()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
OnNetworksChangedEvent(const std::vector<std::string> & network_guids)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
OnNetworkListChangedEvent(const std::vector<std::string> & network_guids)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
Create(Profile * profile)151 NetworkingPrivateEventRouter* NetworkingPrivateEventRouter::Create(
152 Profile* profile) {
153 return new NetworkingPrivateEventRouterImpl(profile);
154 }
155
156 } // namespace extensions
157