Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / networking_private / networking_private_event_router_chromeos.cc
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 "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"
24
25 using chromeos::NetworkHandler;
26 using chromeos::NetworkPortalDetector;
27 using chromeos::NetworkState;
28 using chromeos::NetworkStateHandler;
29
30 namespace extensions {
31
32 class NetworkingPrivateEventRouterImpl
33     : public NetworkingPrivateEventRouter,
34       public chromeos::NetworkStateHandlerObserver,
35       public NetworkPortalDetector::Observer {
36  public:
37   explicit NetworkingPrivateEventRouterImpl(Profile* profile);
38   virtual ~NetworkingPrivateEventRouterImpl();
39
40  protected:
41   // KeyedService overrides:
42   virtual void Shutdown() OVERRIDE;
43
44   // EventRouter::Observer overrides:
45   virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
46   virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE;
47
48   // NetworkStateHandlerObserver overrides:
49   virtual void NetworkListChanged() OVERRIDE;
50   virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE;
51
52   // NetworkPortalDetector::Observer overrides:
53   virtual void OnPortalDetectionCompleted(
54       const NetworkState* network,
55       const NetworkPortalDetector::CaptivePortalState& state) OVERRIDE;
56
57  private:
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();
63
64   Profile* profile_;
65   bool listening_;
66
67   DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateEventRouterImpl);
68 };
69
70 NetworkingPrivateEventRouterImpl::NetworkingPrivateEventRouterImpl(
71     Profile* profile)
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_);
78   if (event_router) {
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();
86   }
87 }
88
89 NetworkingPrivateEventRouterImpl::~NetworkingPrivateEventRouterImpl() {
90   DCHECK(!listening_);
91 }
92
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_);
98   if (event_router)
99     event_router->UnregisterObserver(this);
100
101   if (listening_) {
102     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
103         this, FROM_HERE);
104   }
105   listening_ = false;
106 }
107
108 void NetworkingPrivateEventRouterImpl::OnListenerAdded(
109     const EventListenerInfo& details) {
110   // Start listening to events from the network state handler.
111   StartOrStopListeningForNetworkChanges();
112 }
113
114 void NetworkingPrivateEventRouterImpl::OnListenerRemoved(
115     const EventListenerInfo& details) {
116   // Stop listening to events from the network state handler if there are no
117   // more listeners.
118   StartOrStopListeningForNetworkChanges();
119 }
120
121 void NetworkingPrivateEventRouterImpl::StartOrStopListeningForNetworkChanges() {
122   EventRouter* event_router = EventRouter::Get(profile_);
123   bool should_listen =
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);
130
131   if (should_listen && !listening_) {
132     NetworkHandler::Get()->network_state_handler()->AddObserver(
133         this, FROM_HERE);
134     NetworkPortalDetector::Get()->AddObserver(this);
135   } else if (!should_listen && listening_) {
136     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
137         this, FROM_HERE);
138     NetworkPortalDetector::Get()->RemoveObserver(this);
139   }
140   listening_ = should_listen;
141 }
142
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", "");
152     return;
153   }
154
155   NET_LOG_EVENT("NetworkingPrivate.NetworkListChanged", "");
156
157   std::vector<std::string> changes;
158   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
159            networks.begin();
160        iter != networks.end();
161        ++iter) {
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());
166   }
167
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());
173 }
174
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",
181                   network->path());
182     return;
183   }
184   NET_LOG_EVENT("NetworkingPrivate.NetworkPropertiesUpdated",
185                 network->path());
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());
192 }
193
194 void NetworkingPrivateEventRouterImpl::OnPortalDetectionCompleted(
195     const NetworkState* network,
196     const NetworkPortalDetector::CaptivePortalState& state) {
197   const std::string path = network ? network->path() : std::string();
198
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",
203                   path);
204     return;
205   }
206   NET_LOG_EVENT("NetworkingPrivate.OnPortalDetectionCompleted", path);
207
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;
213       break;
214     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE:
215       status = api::networking_private::CAPTIVE_PORTAL_STATUS_OFFLINE;
216       break;
217     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE:
218       status = api::networking_private::CAPTIVE_PORTAL_STATUS_ONLINE;
219       break;
220     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL:
221       status = api::networking_private::CAPTIVE_PORTAL_STATUS_PORTAL;
222       break;
223     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED:
224       status =
225           api::networking_private::CAPTIVE_PORTAL_STATUS_PROXYAUTHREQUIRED;
226       break;
227     default:
228       NOTREACHED();
229       break;
230   }
231
232   scoped_ptr<base::ListValue> args(
233       api::networking_private::OnPortalDetectionCompleted::Create(
234           path, status));
235   scoped_ptr<Event> extension_event(
236       new Event(api::networking_private::OnPortalDetectionCompleted::kEventName,
237                 args.Pass()));
238   event_router->BroadcastEvent(extension_event.Pass());
239 }
240
241 NetworkingPrivateEventRouter* NetworkingPrivateEventRouter::Create(
242     Profile* profile) {
243   return new NetworkingPrivateEventRouterImpl(profile);
244 }
245
246 }  // namespace extensions