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.
5 #include "chrome/browser/extensions/api/networking_private/networking_private_event_router.h"
7 #include "base/json/json_writer.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/extensions/api/networking_private/networking_private_api.h"
10 #include "chrome/browser/extensions/event_router_forwarder.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/common/extensions/api/networking_private.h"
13 #include "chromeos/network/network_event_log.h"
14 #include "chromeos/network/network_state.h"
15 #include "chromeos/network/network_state_handler.h"
16 #include "chromeos/network/network_state_handler_observer.h"
17 #include "chromeos/network/onc/onc_signature.h"
18 #include "chromeos/network/onc/onc_translator.h"
19 #include "chromeos/network/portal_detector/network_portal_detector.h"
20 #include "components/keyed_service/content/browser_context_dependency_manager.h"
21 #include "components/onc/onc_constants.h"
22 #include "extensions/browser/extension_system.h"
23 #include "third_party/cros_system_api/dbus/service_constants.h"
25 using chromeos::NetworkHandler;
26 using chromeos::NetworkPortalDetector;
27 using chromeos::NetworkState;
28 using chromeos::NetworkStateHandler;
30 namespace extensions {
32 class NetworkingPrivateEventRouterImpl
33 : public NetworkingPrivateEventRouter,
34 public chromeos::NetworkStateHandlerObserver,
35 public NetworkPortalDetector::Observer {
37 explicit NetworkingPrivateEventRouterImpl(Profile* profile);
38 virtual ~NetworkingPrivateEventRouterImpl();
41 // KeyedService overrides:
42 virtual void Shutdown() override;
44 // EventRouter::Observer overrides:
45 virtual void OnListenerAdded(const EventListenerInfo& details) override;
46 virtual void OnListenerRemoved(const EventListenerInfo& details) override;
48 // NetworkStateHandlerObserver overrides:
49 virtual void NetworkListChanged() override;
50 virtual void NetworkPropertiesUpdated(const NetworkState* network) override;
52 // NetworkPortalDetector::Observer overrides:
53 virtual void OnPortalDetectionCompleted(
54 const NetworkState* network,
55 const NetworkPortalDetector::CaptivePortalState& state) override;
58 // Decide if we should listen for network changes or not. If there are any
59 // JavaScript listeners registered for the onNetworkChanged event, then we
60 // want to register for change notification from the network state handler.
61 // Otherwise, we want to unregister and not be listening to network changes.
62 void StartOrStopListeningForNetworkChanges();
67 DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateEventRouterImpl);
70 NetworkingPrivateEventRouterImpl::NetworkingPrivateEventRouterImpl(
72 : profile_(profile), listening_(false) {
73 // Register with the event router so we know when renderers are listening to
74 // our events. We first check and see if there *is* an event router, because
75 // some unit tests try to create all profile services, but don't initialize
76 // the event router first.
77 EventRouter* event_router = EventRouter::Get(profile_);
79 event_router->RegisterObserver(
80 this, api::networking_private::OnNetworksChanged::kEventName);
81 event_router->RegisterObserver(
82 this, api::networking_private::OnNetworkListChanged::kEventName);
83 event_router->RegisterObserver(
84 this, api::networking_private::OnPortalDetectionCompleted::kEventName);
85 StartOrStopListeningForNetworkChanges();
89 NetworkingPrivateEventRouterImpl::~NetworkingPrivateEventRouterImpl() {
93 void NetworkingPrivateEventRouterImpl::Shutdown() {
94 // Unregister with the event router. We first check and see if there *is* an
95 // event router, because some unit tests try to shutdown all profile services,
96 // but didn't initialize the event router first.
97 EventRouter* event_router = EventRouter::Get(profile_);
99 event_router->UnregisterObserver(this);
102 NetworkHandler::Get()->network_state_handler()->RemoveObserver(
108 void NetworkingPrivateEventRouterImpl::OnListenerAdded(
109 const EventListenerInfo& details) {
110 // Start listening to events from the network state handler.
111 StartOrStopListeningForNetworkChanges();
114 void NetworkingPrivateEventRouterImpl::OnListenerRemoved(
115 const EventListenerInfo& details) {
116 // Stop listening to events from the network state handler if there are no
118 StartOrStopListeningForNetworkChanges();
121 void NetworkingPrivateEventRouterImpl::StartOrStopListeningForNetworkChanges() {
122 EventRouter* event_router = EventRouter::Get(profile_);
124 event_router->HasEventListener(
125 api::networking_private::OnNetworksChanged::kEventName) ||
126 event_router->HasEventListener(
127 api::networking_private::OnNetworkListChanged::kEventName) ||
128 event_router->HasEventListener(
129 api::networking_private::OnPortalDetectionCompleted::kEventName);
131 if (should_listen && !listening_) {
132 NetworkHandler::Get()->network_state_handler()->AddObserver(
134 NetworkPortalDetector::Get()->AddObserver(this);
135 } else if (!should_listen && listening_) {
136 NetworkHandler::Get()->network_state_handler()->RemoveObserver(
138 NetworkPortalDetector::Get()->RemoveObserver(this);
140 listening_ = should_listen;
143 void NetworkingPrivateEventRouterImpl::NetworkListChanged() {
144 EventRouter* event_router = EventRouter::Get(profile_);
145 NetworkStateHandler::NetworkStateList networks;
146 NetworkHandler::Get()->network_state_handler()->GetVisibleNetworkList(
148 if (!event_router->HasEventListener(
149 api::networking_private::OnNetworkListChanged::kEventName)) {
150 // TODO(stevenjb): Remove logging once crbug.com/256881 is fixed
151 // (or at least reduce to LOG_DEBUG). Same with NET_LOG events below.
152 NET_LOG_EVENT("NetworkingPrivate.NetworkListChanged: No Listeners", "");
156 NET_LOG_EVENT("NetworkingPrivate.NetworkListChanged", "");
158 std::vector<std::string> changes;
159 for (NetworkStateHandler::NetworkStateList::const_iterator iter =
161 iter != networks.end();
163 changes.push_back((*iter)->guid());
166 scoped_ptr<base::ListValue> args(
167 api::networking_private::OnNetworkListChanged::Create(changes));
168 scoped_ptr<Event> extension_event(new Event(
169 api::networking_private::OnNetworkListChanged::kEventName, args.Pass()));
170 event_router->BroadcastEvent(extension_event.Pass());
173 void NetworkingPrivateEventRouterImpl::NetworkPropertiesUpdated(
174 const NetworkState* network) {
175 EventRouter* event_router = EventRouter::Get(profile_);
176 if (!event_router->HasEventListener(
177 api::networking_private::OnNetworksChanged::kEventName)) {
178 NET_LOG_EVENT("NetworkingPrivate.NetworkPropertiesUpdated: No Listeners",
182 NET_LOG_EVENT("NetworkingPrivate.NetworkPropertiesUpdated",
184 scoped_ptr<base::ListValue> args(
185 api::networking_private::OnNetworksChanged::Create(
186 std::vector<std::string>(1, network->guid())));
187 scoped_ptr<Event> extension_event(new Event(
188 api::networking_private::OnNetworksChanged::kEventName, args.Pass()));
189 event_router->BroadcastEvent(extension_event.Pass());
192 void NetworkingPrivateEventRouterImpl::OnPortalDetectionCompleted(
193 const NetworkState* network,
194 const NetworkPortalDetector::CaptivePortalState& state) {
195 const std::string path = network ? network->guid() : std::string();
197 EventRouter* event_router = EventRouter::Get(profile_);
198 if (!event_router->HasEventListener(
199 api::networking_private::OnPortalDetectionCompleted::kEventName)) {
200 NET_LOG_EVENT("NetworkingPrivate.OnPortalDetectionCompleted: No Listeners",
204 NET_LOG_EVENT("NetworkingPrivate.OnPortalDetectionCompleted", path);
206 api::networking_private::CaptivePortalStatus status =
207 api::networking_private::CAPTIVE_PORTAL_STATUS_UNKNOWN;
208 switch (state.status) {
209 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN:
210 status = api::networking_private::CAPTIVE_PORTAL_STATUS_UNKNOWN;
212 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE:
213 status = api::networking_private::CAPTIVE_PORTAL_STATUS_OFFLINE;
215 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE:
216 status = api::networking_private::CAPTIVE_PORTAL_STATUS_ONLINE;
218 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL:
219 status = api::networking_private::CAPTIVE_PORTAL_STATUS_PORTAL;
221 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED:
223 api::networking_private::CAPTIVE_PORTAL_STATUS_PROXYAUTHREQUIRED;
230 scoped_ptr<base::ListValue> args(
231 api::networking_private::OnPortalDetectionCompleted::Create(
233 scoped_ptr<Event> extension_event(
234 new Event(api::networking_private::OnPortalDetectionCompleted::kEventName,
236 event_router->BroadcastEvent(extension_event.Pass());
239 NetworkingPrivateEventRouter* NetworkingPrivateEventRouter::Create(
241 return new NetworkingPrivateEventRouterImpl(profile);
244 } // namespace extensions