0aefa241298ad935ee47d8381280686314cdf498
[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/extensions/extension_system_factory.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/browser_context_keyed_service/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::NetworkState;
27 using chromeos::NetworkStateHandler;
28
29 namespace extensions {
30
31 class NetworkingPrivateEventRouterImpl
32     : public NetworkingPrivateEventRouter,
33       public chromeos::NetworkStateHandlerObserver {
34  public:
35   explicit NetworkingPrivateEventRouterImpl(Profile* profile);
36   virtual ~NetworkingPrivateEventRouterImpl();
37
38  protected:
39   // BrowserContextKeyedService overrides:
40   virtual void Shutdown() OVERRIDE;
41
42   // EventRouter::Observer overrides:
43   virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
44   virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE;
45
46   // NetworkStateHandlerObserver overrides:
47   virtual void NetworkListChanged() OVERRIDE;
48   virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE;
49
50  private:
51   // Decide if we should listen for network changes or not. If there are any
52   // JavaScript listeners registered for the onNetworkChanged event, then we
53   // want to register for change notification from the network state handler.
54   // Otherwise, we want to unregister and not be listening to network changes.
55   void StartOrStopListeningForNetworkChanges();
56
57   Profile* profile_;
58   bool listening_;
59
60   DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateEventRouterImpl);
61 };
62
63 NetworkingPrivateEventRouterImpl::NetworkingPrivateEventRouterImpl(
64     Profile* profile)
65     : profile_(profile), listening_(false) {
66   // Register with the event router so we know when renderers are listening to
67   // our events. We first check and see if there *is* an event router, because
68   // some unit tests try to create all profile services, but don't initialize
69   // the event router first.
70   EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router();
71   if (event_router) {
72     event_router->RegisterObserver(
73         this, api::networking_private::OnNetworksChanged::kEventName);
74     event_router->RegisterObserver(
75         this, api::networking_private::OnNetworkListChanged::kEventName);
76     StartOrStopListeningForNetworkChanges();
77   }
78 }
79
80 NetworkingPrivateEventRouterImpl::~NetworkingPrivateEventRouterImpl() {
81   DCHECK(!listening_);
82 }
83
84 void NetworkingPrivateEventRouterImpl::Shutdown() {
85   // Unregister with the event router. We first check and see if there *is* an
86   // event router, because some unit tests try to shutdown all profile services,
87   // but didn't initialize the event router first.
88   EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router();
89   if (event_router)
90     event_router->UnregisterObserver(this);
91
92   if (listening_) {
93     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
94         this, FROM_HERE);
95   }
96   listening_ = false;
97 }
98
99 void NetworkingPrivateEventRouterImpl::OnListenerAdded(
100     const EventListenerInfo& details) {
101   // Start listening to events from the network state handler.
102   StartOrStopListeningForNetworkChanges();
103 }
104
105 void NetworkingPrivateEventRouterImpl::OnListenerRemoved(
106     const EventListenerInfo& details) {
107   // Stop listening to events from the network state handler if there are no
108   // more listeners.
109   StartOrStopListeningForNetworkChanges();
110 }
111
112 void NetworkingPrivateEventRouterImpl::StartOrStopListeningForNetworkChanges() {
113   EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router();
114   bool should_listen =
115       event_router->HasEventListener(
116           api::networking_private::OnNetworksChanged::kEventName) ||
117       event_router->HasEventListener(
118           api::networking_private::OnNetworkListChanged::kEventName);
119
120   if (should_listen && !listening_) {
121     NetworkHandler::Get()->network_state_handler()->AddObserver(
122         this, FROM_HERE);
123   } else if (!should_listen && listening_) {
124     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
125         this, FROM_HERE);
126   }
127   listening_ = should_listen;
128 }
129
130 void NetworkingPrivateEventRouterImpl::NetworkListChanged() {
131   EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router();
132   NetworkStateHandler::NetworkStateList networks;
133   NetworkHandler::Get()->network_state_handler()->GetNetworkList(&networks);
134   if (!event_router->HasEventListener(
135            api::networking_private::OnNetworkListChanged::kEventName)) {
136     // TODO(stevenjb): Remove logging once crbug.com/256881 is fixed
137     // (or at least reduce to LOG_DEBUG). Same with NET_LOG events below.
138     NET_LOG_EVENT("NetworkingPrivate.NetworkListChanged: No Listeners", "");
139     return;
140   }
141
142   NET_LOG_EVENT("NetworkingPrivate.NetworkListChanged", "");
143
144   std::vector<std::string> changes;
145   for (NetworkStateHandler::NetworkStateList::const_iterator iter =
146            networks.begin();
147        iter != networks.end();
148        ++iter) {
149     // TODO(gspencer): Currently the "GUID" is actually the service path. Fix
150     // this to be the real GUID once we're using
151     // ManagedNetworkConfigurationManager.
152     changes.push_back((*iter)->path());
153   }
154
155   scoped_ptr<base::ListValue> args(
156       api::networking_private::OnNetworkListChanged::Create(changes));
157   scoped_ptr<Event> extension_event(new Event(
158       api::networking_private::OnNetworkListChanged::kEventName, args.Pass()));
159   event_router->BroadcastEvent(extension_event.Pass());
160 }
161
162 void NetworkingPrivateEventRouterImpl::NetworkPropertiesUpdated(
163     const NetworkState* network) {
164   EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router();
165   if (!event_router->HasEventListener(
166            api::networking_private::OnNetworksChanged::kEventName)) {
167     NET_LOG_EVENT("NetworkingPrivate.NetworkPropertiesUpdated: No Listeners",
168                   network->path());
169     return;
170   }
171   NET_LOG_EVENT("NetworkingPrivate.NetworkPropertiesUpdated",
172                 network->path());
173   scoped_ptr<base::ListValue> args(
174       api::networking_private::OnNetworksChanged::Create(
175           std::vector<std::string>(1, network->path())));
176   scoped_ptr<Event> extension_event(new Event(
177       api::networking_private::OnNetworksChanged::kEventName, args.Pass()));
178   event_router->BroadcastEvent(extension_event.Pass());
179 }
180
181 NetworkingPrivateEventRouter* NetworkingPrivateEventRouter::Create(
182     Profile* profile) {
183   return new NetworkingPrivateEventRouterImpl(profile);
184 }
185
186 }  // namespace extensions