Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(574)

Side by Side Diff: chromeos/network/network_state_handler.cc

Issue 11192024: Add chromeos::NetworkStateManager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase with dbus tests in trunk Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "chromeos/network/network_state_handler.h"
6
7 #include "base/stl_util.h"
8 #include "base/string_util.h"
9 #include "base/values.h"
10 #include "chromeos/network/device_state.h"
11 #include "chromeos/network/managed_state.h"
12 #include "chromeos/network/network_state.h"
13 #include "chromeos/network/network_state_handler_observer.h"
14 #include "chromeos/network/shill_property_handler.h"
15 #include "third_party/cros_system_api/dbus/service_constants.h"
16
17 namespace chromeos {
18
19 NetworkStateHandler::NetworkStateHandler() {
20 }
21
22 NetworkStateHandler::~NetworkStateHandler() {
23 STLDeleteContainerPointers(network_list_.begin(), network_list_.end());
24 STLDeleteContainerPointers(device_list_.begin(), device_list_.end());
25 }
26
27 void NetworkStateHandler::Init() {
28 shill_property_handler_.reset(new internal::ShillPropertyHandler(this));
29 shill_property_handler_->Init();
30 }
31
32 void NetworkStateHandler::AddObserver(NetworkStateHandlerObserver* observer) {
33 observers_.AddObserver(observer);
34 }
35
36 void NetworkStateHandler::RemoveObserver(
37 NetworkStateHandlerObserver* observer) {
38 observers_.RemoveObserver(observer);
39 }
40
41 bool NetworkStateHandler::TechnologyAvailable(
42 const std::string& technology) const {
43 return available_technologies_.find(technology) !=
44 available_technologies_.end();
45 }
46
47 bool NetworkStateHandler::TechnologyEnabled(
48 const std::string& technology) const {
49 return enabled_technologies_.find(technology) != enabled_technologies_.end();
50 }
51
52 void NetworkStateHandler::SetTechnologyEnabled(const std::string& technology,
53 bool enabled) {
54 shill_property_handler_->SetTechnologyEnabled(technology, enabled);
55 }
56
57 const DeviceState* NetworkStateHandler::GetDeviceState(
58 const std::string& device_path) const {
59 return GetModifiableDeviceState(device_path);
60 }
61
62 const DeviceState* NetworkStateHandler::GetDeviceStateByType(
63 const std::string& type) const {
64 for (ManagedStateList::const_iterator iter = device_list_.begin();
65 iter != device_list_.end(); ++iter) {
66 ManagedState* device = *iter;
67 if (device->type() == type)
68 return device->AsDeviceState();
69 }
70 return NULL;
71 }
72
73 const NetworkState* NetworkStateHandler::GetNetworkState(
74 const std::string& service_path) const {
75 return GetModifiableNetworkState(service_path);
76 }
77
78 const NetworkState* NetworkStateHandler::ActiveNetwork() const {
79 if (network_list_.empty())
80 return NULL;
81 const NetworkState* network = network_list_.front()->AsNetworkState();
82 DCHECK(network);
83 if (!network->IsConnectedState())
84 return NULL;
85 return network;
86 }
87
88 const NetworkState* NetworkStateHandler::ConnectedNetworkByType(
89 const std::string& type) const {
90 for (ManagedStateList::const_iterator iter = network_list_.begin();
91 iter != network_list_.end(); ++iter) {
92 const NetworkState* network = (*iter)->AsNetworkState();
93 DCHECK(network);
94 if (!network->IsConnectedState())
95 break; // Connected networks are listed first.
96 if (network->type() == type)
97 return network;
98 }
99 return NULL;
100 }
101
102 const NetworkState* NetworkStateHandler::ConnectingNetworkByType(
103 const std::string& type) const {
104 for (ManagedStateList::const_iterator iter = network_list_.begin();
105 iter != network_list_.end(); ++iter) {
106 const NetworkState* network = (*iter)->AsNetworkState();
107 DCHECK(network);
108 if (network->IsConnectedState())
109 continue;
110 if (!network->IsConnectingState())
111 break; // Connected and connecting networks are listed first.
112 if (network->type() == type ||
113 (type.empty() && type != flimflam::kTypeEthernet)) {
114 return network;
115 }
116 }
117 return NULL;
118 }
119
120 std::string NetworkStateHandler::HardwareAddressForType(
121 const std::string& type) const {
122 std::string result;
123 const NetworkState* network = ConnectedNetworkByType(type);
124 if (network) {
125 const DeviceState* device = GetDeviceState(network->device_path());
126 if (device)
127 result = device->mac_address();
128 }
129 StringToUpperASCII(&result);
130 return result;
131 }
132
133 std::string NetworkStateHandler::FormattedHardwareAddressForType(
134 const std::string& type) const {
135 std::string address = HardwareAddressForType(type);
136 if (address.size() % 2 != 0)
137 return address;
138 std::string result;
139 for (size_t i = 0; i < address.size(); ++i) {
140 if ((i != 0) && (i % 2 == 0))
141 result.push_back(':');
142 result.push_back(address[i]);
143 }
144 return result;
145 }
146
147 void NetworkStateHandler::GetNetworkList(NetworkStateList* list) const {
148 DCHECK(list);
149 shill_property_handler_->RequestScan();
150 NetworkStateList result;
151 list->clear();
152 for (ManagedStateList::const_iterator iter = network_list_.begin();
153 iter != network_list_.end(); ++iter) {
154 const NetworkState* network = (*iter)->AsNetworkState();
155 DCHECK(network);
156 list->push_back(network);
157 }
158 }
159
160 //------------------------------------------------------------------------------
161 // ShillPropertyHandler::Delegate overrides
162
163 void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type,
164 const base::ListValue& entries) {
165 ManagedStateList* managed_list = GetManagedList(type);
166 VLOG(2) << "UpdateManagedList: " << type;
167 // Create a map of existing entries.
168 std::map<std::string, ManagedState*> managed_map;
169 for (ManagedStateList::iterator iter = managed_list->begin();
170 iter != managed_list->end(); ++iter) {
171 ManagedState* managed = *iter;
172 managed_map[managed->path()] = managed;
173 }
174 // Clear the list (pointers are owned by managed_map).
175 managed_list->clear();
176 // Updates managed_list and request updates for new entries.
177 for (base::ListValue::const_iterator iter = entries.begin();
178 iter != entries.end(); ++iter) {
179 std::string path;
180 (*iter)->GetAsString(&path);
181 if (path.empty())
gauravsh 2012/11/06 01:56:59 This ignores an error in GetAsString() or having a
stevenjb 2012/11/06 03:17:03 Shouldn't happen, changed to DCHECK
pneubeck (no reviews) 2012/11/06 09:18:19 A general question about the usage of DCHECK/NOTRE
182 continue;
183 std::map<std::string, ManagedState*>::iterator found =
184 managed_map.find(path);
185 bool request_properties = false;
186 ManagedState* managed;
187 bool is_observing = shill_property_handler_->IsObservingNetwork(path);
188 if (found == managed_map.end()) {
189 request_properties = true;
190 managed = ManagedState::Create(type, path);
191 managed_list->push_back(managed);
192 } else {
193 managed = found->second;
194 managed_list->push_back(managed);
195 managed_map.erase(found);
196 if (!managed->is_observed() && is_observing)
197 request_properties = true;
198 }
199 if (is_observing)
200 managed->set_is_observed(true);
201 if (request_properties)
202 shill_property_handler_->RequestProperties(type, path);
203 }
204 // Delete any remaning entries in managed_map.
205 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end());
206 }
207
208 void NetworkStateHandler::UpdateAvailableTechnologies(
209 const base::ListValue& technologies) {
210 available_technologies_.clear();
211 for (base::ListValue::const_iterator iter = technologies.begin();
212 iter != technologies.end(); ++iter) {
213 std::string technology;
214 (*iter)->GetAsString(&technology);
215 DCHECK(!technology.empty());
216 available_technologies_.insert(technology);
217 }
218 }
219
220 void NetworkStateHandler::UpdateEnabledTechnologies(
221 const base::ListValue& technologies) {
222 enabled_technologies_.clear();
223 for (base::ListValue::const_iterator iter = technologies.begin();
224 iter != technologies.end(); ++iter) {
225 std::string technology;
226 (*iter)->GetAsString(&technology);
gauravsh 2012/11/06 01:56:59 See my comment in UpdateManagedList. Why is it ok
stevenjb 2012/11/06 03:17:03 Should never happen which is why it's a DCHECK.
227 DCHECK(!technology.empty());
228 enabled_technologies_.insert(technology);
229 }
230 }
231
232 void NetworkStateHandler::UpdateManagedStateProperties(
233 ManagedState::ManagedType type,
234 const std::string& path,
235 const base::DictionaryValue& properties) {
236 ManagedState* managed = GetModifiableManagedState(GetManagedList(type), path);
237 if (!managed) {
238 LOG(ERROR) << "GetPropertiesCallback: " << path << " Not found!";
239 return;
240 }
241 bool property_changed = false;
242 for (base::DictionaryValue::Iterator iter(properties);
243 iter.HasNext(); iter.Advance()) {
244 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
245 if (ParseNetworkServiceProperty(managed->AsNetworkState(),
246 iter.key(), iter.value()))
247 property_changed = true;
248 } else {
249 if (managed->PropertyChanged(iter.key(), iter.value()))
250 property_changed = true;
gauravsh 2012/11/06 01:56:59 Since MANAGED_TYPE_DEVICE type never causes observ
stevenjb 2012/11/06 03:17:03 Renamed
251 }
252 }
253 // Notify observers.
254 if (property_changed && type == ManagedState::MANAGED_TYPE_NETWORK) {
255 NetworkState* network = managed->AsNetworkState();
256 DCHECK(network);
257 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
258 NetworkServiceChanged(network));
259 }
260 }
261
262 void NetworkStateHandler::UpdateNetworkServiceProperty(
263 const std::string& service_path,
264 const std::string& key,
265 const base::Value& value) {
266 NetworkState* network = GetModifiableNetworkState(service_path);
267 if (!network)
268 return;
269 if (ParseNetworkServiceProperty(network, key, value)) {
270 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
271 NetworkServiceChanged(network));
272 }
273 }
274
275 void NetworkStateHandler::UpdateNetworkServiceIPAddress(
276 const std::string& service_path,
277 const std::string& ip_address) {
278 NetworkState* network = GetModifiableNetworkState(service_path);
279 if (!network)
280 return;
281 network->set_ip_address(ip_address);
282 FOR_EACH_OBSERVER(
283 NetworkStateHandlerObserver, observers_,
284 NetworkServiceChanged(network));
285 }
286
287 void NetworkStateHandler::ManagerPropertyChanged() {
288 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
289 NetworkManagerChanged());
290 }
291
292 void NetworkStateHandler::ManagedStateListChanged(
293 ManagedState::ManagedType type) {
294 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
295 // Notify observers that the list of networks has changed.
296 NetworkStateList network_list;
297 GetNetworkList(&network_list);
298 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
299 NetworkListChanged(network_list));
300 // Update the active network and notify observers if it has changed.
301 NetworkState* new_active_network =
302 network_list_.empty() ? NULL : network_list_.front()->AsNetworkState();
303 std::string new_active_network_path;
304 if (new_active_network)
305 new_active_network_path = new_active_network->path();
306 if (new_active_network_path != active_network_path_) {
307 active_network_path_ = new_active_network_path;
308 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
309 ActiveNetworkChanged(new_active_network));
310 }
311 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
312 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
313 DeviceListChanged());
314 } else {
315 NOTREACHED();
316 }
317 }
318
319 //------------------------------------------------------------------------------
320 // Private methods
321
322 DeviceState* NetworkStateHandler::GetModifiableDeviceState(
323 const std::string& device_path) const {
324 ManagedState* managed = GetModifiableManagedState(&device_list_, device_path);
325 if (!managed)
326 return NULL;
327 return managed->AsDeviceState();
328 }
329
330 NetworkState* NetworkStateHandler::GetModifiableNetworkState(
331 const std::string& service_path) const {
332 ManagedState* managed =
333 GetModifiableManagedState(&network_list_, service_path);
334 if (!managed)
335 return NULL;
336 return managed->AsNetworkState();
337 }
338
339 ManagedState* NetworkStateHandler::GetModifiableManagedState(
340 const ManagedStateList* managed_list,
341 const std::string& path) const {
342 for (ManagedStateList::const_iterator iter = managed_list->begin();
343 iter != managed_list->end(); ++iter) {
344 ManagedState* managed = *iter;
345 if (managed->path() == path)
346 return managed;
347 }
348 return NULL;
349 }
350
351 NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList(
352 ManagedState::ManagedType type) {
353 switch(type) {
354 case ManagedState::MANAGED_TYPE_NETWORK:
355 return &network_list_;
356 case ManagedState::MANAGED_TYPE_DEVICE:
357 return &device_list_;
358 }
359 NOTREACHED();
360 return NULL;
361 }
362
363 bool NetworkStateHandler::ParseNetworkServiceProperty(
364 NetworkState* network,
365 const std::string& key,
366 const base::Value& value) {
367 DCHECK(network);
368 bool property_changed = false;
369 // Handle IPConfig here since it requires additional complexity that is
370 // better handled here than in NetworkState::PropertyChanged (e.g.
371 // observer notification).
372 if (key == shill::kIPConfigProperty) {
gauravsh 2012/11/06 01:56:59 Is this something that should be re-factored at so
stevenjb 2012/11/06 03:17:03 Moved the comment inside the if() and clarified it
373 std::string ip_config_path;
374 if (value.GetAsString(&ip_config_path)) {
375 property_changed = true;
376 shill_property_handler_->RequestIPConfig(network->path(), ip_config_path);
377 } else {
378 NOTREACHED();
379 }
380 } else {
381 if (network->PropertyChanged(key, value)) {
382 property_changed = true;
383 if (network->path() == active_network_path_ &&
384 key == flimflam::kStateProperty) {
385 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
386 ActiveNetworkStateChanged(network));
387 }
388 }
389 }
390 return property_changed;
391 }
392
393 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698