Upstream version 11.40.277.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/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"
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()->GetVisibleNetworkList(
147       &networks);
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", "");
153     return;
154   }
155
156   NET_LOG_EVENT("NetworkingPrivate.NetworkListChanged", "");
157
158   std::vector<std::string> changes;
159   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
160            networks.begin();
161        iter != networks.end();
162        ++iter) {
163     changes.push_back((*iter)->guid());
164   }
165
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());
171 }
172
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",
179                   network->path());
180     return;
181   }
182   NET_LOG_EVENT("NetworkingPrivate.NetworkPropertiesUpdated",
183                 network->path());
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());
190 }
191
192 void NetworkingPrivateEventRouterImpl::OnPortalDetectionCompleted(
193     const NetworkState* network,
194     const NetworkPortalDetector::CaptivePortalState& state) {
195   const std::string path = network ? network->guid() : std::string();
196
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",
201                   path);
202     return;
203   }
204   NET_LOG_EVENT("NetworkingPrivate.OnPortalDetectionCompleted", path);
205
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;
211       break;
212     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE:
213       status = api::networking_private::CAPTIVE_PORTAL_STATUS_OFFLINE;
214       break;
215     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE:
216       status = api::networking_private::CAPTIVE_PORTAL_STATUS_ONLINE;
217       break;
218     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL:
219       status = api::networking_private::CAPTIVE_PORTAL_STATUS_PORTAL;
220       break;
221     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED:
222       status =
223           api::networking_private::CAPTIVE_PORTAL_STATUS_PROXYAUTHREQUIRED;
224       break;
225     default:
226       NOTREACHED();
227       break;
228   }
229
230   scoped_ptr<base::ListValue> args(
231       api::networking_private::OnPortalDetectionCompleted::Create(
232           path, status));
233   scoped_ptr<Event> extension_event(
234       new Event(api::networking_private::OnPortalDetectionCompleted::kEventName,
235                 args.Pass()));
236   event_router->BroadcastEvent(extension_event.Pass());
237 }
238
239 NetworkingPrivateEventRouter* NetworkingPrivateEventRouter::Create(
240     Profile* profile) {
241   return new NetworkingPrivateEventRouterImpl(profile);
242 }
243
244 }  // namespace extensions