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/chromeos/net/network_portal_detector.h"
10 #include "chrome/browser/extensions/api/networking_private/networking_private_api.h"
11 #include "chrome/browser/extensions/event_router_forwarder.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/common/extensions/api/networking_private.h"
14 #include "chromeos/network/network_event_log.h"
15 #include "chromeos/network/network_state.h"
16 #include "chromeos/network/network_state_handler.h"
17 #include "chromeos/network/network_state_handler_observer.h"
18 #include "chromeos/network/onc/onc_signature.h"
19 #include "chromeos/network/onc/onc_translator.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()->GetNetworkList(&networks);
147 if (!event_router->HasEventListener(
148 api::networking_private::OnNetworkListChanged::kEventName)) {
149 // TODO(stevenjb): Remove logging once crbug.com/256881 is fixed
150 // (or at least reduce to LOG_DEBUG). Same with NET_LOG events below.
151 NET_LOG_EVENT("NetworkingPrivate.NetworkListChanged: No Listeners", "");
155 NET_LOG_EVENT("NetworkingPrivate.NetworkListChanged", "");
157 std::vector<std::string> changes;
158 for (NetworkStateHandler::NetworkStateList::const_iterator iter =
160 iter != networks.end();
162 // TODO(gspencer): Currently the "GUID" is actually the service path. Fix
163 // this to be the real GUID once we're using
164 // ManagedNetworkConfigurationManager.
165 changes.push_back((*iter)->path());
168 scoped_ptr<base::ListValue> args(
169 api::networking_private::OnNetworkListChanged::Create(changes));
170 scoped_ptr<Event> extension_event(new Event(
171 api::networking_private::OnNetworkListChanged::kEventName, args.Pass()));
172 event_router->BroadcastEvent(extension_event.Pass());
175 void NetworkingPrivateEventRouterImpl::NetworkPropertiesUpdated(
176 const NetworkState* network) {
177 EventRouter* event_router = EventRouter::Get(profile_);
178 if (!event_router->HasEventListener(
179 api::networking_private::OnNetworksChanged::kEventName)) {
180 NET_LOG_EVENT("NetworkingPrivate.NetworkPropertiesUpdated: No Listeners",
184 NET_LOG_EVENT("NetworkingPrivate.NetworkPropertiesUpdated",
186 scoped_ptr<base::ListValue> args(
187 api::networking_private::OnNetworksChanged::Create(
188 std::vector<std::string>(1, network->path())));
189 scoped_ptr<Event> extension_event(new Event(
190 api::networking_private::OnNetworksChanged::kEventName, args.Pass()));
191 event_router->BroadcastEvent(extension_event.Pass());
194 void NetworkingPrivateEventRouterImpl::OnPortalDetectionCompleted(
195 const NetworkState* network,
196 const NetworkPortalDetector::CaptivePortalState& state) {
197 const std::string path = network ? network->path() : std::string();
199 EventRouter* event_router = EventRouter::Get(profile_);
200 if (!event_router->HasEventListener(
201 api::networking_private::OnPortalDetectionCompleted::kEventName)) {
202 NET_LOG_EVENT("NetworkingPrivate.OnPortalDetectionCompleted: No Listeners",
206 NET_LOG_EVENT("NetworkingPrivate.OnPortalDetectionCompleted", path);
208 api::networking_private::CaptivePortalStatus status =
209 api::networking_private::CAPTIVE_PORTAL_STATUS_UNKNOWN;
210 switch (state.status) {
211 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN:
212 status = api::networking_private::CAPTIVE_PORTAL_STATUS_UNKNOWN;
214 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE:
215 status = api::networking_private::CAPTIVE_PORTAL_STATUS_OFFLINE;
217 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE:
218 status = api::networking_private::CAPTIVE_PORTAL_STATUS_ONLINE;
220 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL:
221 status = api::networking_private::CAPTIVE_PORTAL_STATUS_PORTAL;
223 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED:
225 api::networking_private::CAPTIVE_PORTAL_STATUS_PROXYAUTHREQUIRED;
232 scoped_ptr<base::ListValue> args(
233 api::networking_private::OnPortalDetectionCompleted::Create(
235 scoped_ptr<Event> extension_event(
236 new Event(api::networking_private::OnPortalDetectionCompleted::kEventName,
238 event_router->BroadcastEvent(extension_event.Pass());
241 NetworkingPrivateEventRouter* NetworkingPrivateEventRouter::Create(
243 return new NetworkingPrivateEventRouterImpl(profile);
246 } // namespace extensions