Fix race condition in gyp/ninja builds.
[chromium-blink-merge.git] / chromeos / network / managed_network_configuration_handler_impl.cc
blob21c225a5b3fc48fb65a2f72a2d94cc432a54f278
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 "chromeos/network/managed_network_configuration_handler_impl.h"
7 #include <set>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/guid.h"
12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/stl_util.h"
17 #include "base/values.h"
18 #include "chromeos/dbus/shill_manager_client.h"
19 #include "chromeos/dbus/shill_profile_client.h"
20 #include "chromeos/dbus/shill_service_client.h"
21 #include "chromeos/network/device_state.h"
22 #include "chromeos/network/network_configuration_handler.h"
23 #include "chromeos/network/network_device_handler.h"
24 #include "chromeos/network/network_event_log.h"
25 #include "chromeos/network/network_policy_observer.h"
26 #include "chromeos/network/network_profile.h"
27 #include "chromeos/network/network_profile_handler.h"
28 #include "chromeos/network/network_state.h"
29 #include "chromeos/network/network_state_handler.h"
30 #include "chromeos/network/network_ui_data.h"
31 #include "chromeos/network/onc/onc_merger.h"
32 #include "chromeos/network/onc/onc_signature.h"
33 #include "chromeos/network/onc/onc_translator.h"
34 #include "chromeos/network/onc/onc_validator.h"
35 #include "chromeos/network/policy_util.h"
36 #include "chromeos/network/shill_property_util.h"
37 #include "components/onc/onc_constants.h"
38 #include "third_party/cros_system_api/dbus/service_constants.h"
40 namespace chromeos {
42 namespace {
44 typedef std::map<std::string, const base::DictionaryValue*> GuidToPolicyMap;
46 // These are error strings used for error callbacks. None of these error
47 // messages are user-facing: they should only appear in logs.
48 const char kInvalidUserSettings[] = "InvalidUserSettings";
49 const char kNetworkAlreadyConfigured[] = "NetworkAlreadyConfigured";
50 const char kPoliciesNotInitialized[] = "PoliciesNotInitialized";
51 const char kProfileNotInitialized[] = "ProflieNotInitialized";
52 const char kSetOnUnconfiguredNetwork[] = "SetCalledOnUnconfiguredNetwork";
53 const char kUnknownProfilePath[] = "UnknownProfilePath";
54 const char kUnknownNetwork[] = "UnknownNetwork";
56 std::string ToDebugString(::onc::ONCSource source,
57 const std::string& userhash) {
58 return source == ::onc::ONC_SOURCE_USER_POLICY ?
59 ("user policy of " + userhash) : "device policy";
62 void InvokeErrorCallback(const std::string& service_path,
63 const network_handler::ErrorCallback& error_callback,
64 const std::string& error_name) {
65 std::string error_msg = "ManagedConfig Error: " + error_name;
66 NET_LOG_ERROR(error_msg, service_path);
67 network_handler::RunErrorCallback(
68 error_callback, service_path, error_name, error_msg);
71 void LogErrorWithDict(const tracked_objects::Location& from_where,
72 const std::string& error_name,
73 scoped_ptr<base::DictionaryValue> error_data) {
74 network_event_log::internal::AddEntry(
75 from_where.file_name(), from_where.line_number(),
76 network_event_log::LOG_LEVEL_ERROR,
77 error_name, "");
80 const base::DictionaryValue* GetByGUID(const GuidToPolicyMap& policies,
81 const std::string& guid) {
82 GuidToPolicyMap::const_iterator it = policies.find(guid);
83 if (it == policies.end())
84 return NULL;
85 return it->second;
88 } // namespace
90 struct ManagedNetworkConfigurationHandlerImpl::Policies {
91 ~Policies();
93 GuidToPolicyMap per_network_config;
94 base::DictionaryValue global_network_config;
97 ManagedNetworkConfigurationHandlerImpl::Policies::~Policies() {
98 STLDeleteValues(&per_network_config);
101 void ManagedNetworkConfigurationHandlerImpl::AddObserver(
102 NetworkPolicyObserver* observer) {
103 observers_.AddObserver(observer);
106 void ManagedNetworkConfigurationHandlerImpl::RemoveObserver(
107 NetworkPolicyObserver* observer) {
108 observers_.RemoveObserver(observer);
111 // GetManagedProperties
113 void ManagedNetworkConfigurationHandlerImpl::GetManagedProperties(
114 const std::string& userhash,
115 const std::string& service_path,
116 const network_handler::DictionaryResultCallback& callback,
117 const network_handler::ErrorCallback& error_callback) {
118 if (!GetPoliciesForUser(userhash) || !GetPoliciesForUser(std::string())) {
119 InvokeErrorCallback(service_path, error_callback, kPoliciesNotInitialized);
120 return;
122 network_configuration_handler_->GetProperties(
123 service_path,
124 base::Bind(
125 &ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback,
126 weak_ptr_factory_.GetWeakPtr(),
127 base::Bind(
128 &ManagedNetworkConfigurationHandlerImpl::SendManagedProperties,
129 weak_ptr_factory_.GetWeakPtr(),
130 callback,
131 error_callback)),
132 error_callback);
135 void ManagedNetworkConfigurationHandlerImpl::SendManagedProperties(
136 const network_handler::DictionaryResultCallback& callback,
137 const network_handler::ErrorCallback& error_callback,
138 const std::string& service_path,
139 scoped_ptr<base::DictionaryValue> shill_properties) {
140 std::string profile_path;
141 shill_properties->GetStringWithoutPathExpansion(shill::kProfileProperty,
142 &profile_path);
143 const NetworkProfile* profile =
144 network_profile_handler_->GetProfileForPath(profile_path);
145 if (!profile)
146 NET_LOG_ERROR("No profile for service: " + profile_path, service_path);
148 scoped_ptr<NetworkUIData> ui_data =
149 shill_property_util::GetUIDataFromProperties(*shill_properties);
151 const base::DictionaryValue* user_settings = NULL;
152 const base::DictionaryValue* shared_settings = NULL;
154 if (ui_data && profile) {
155 if (profile->type() == NetworkProfile::TYPE_SHARED)
156 shared_settings = ui_data->user_settings();
157 else if (profile->type() == NetworkProfile::TYPE_USER)
158 user_settings = ui_data->user_settings();
159 else
160 NOTREACHED();
161 } else if (profile) {
162 NET_LOG_ERROR("Service contains empty or invalid UIData", service_path);
163 // TODO(pneubeck): add a conversion of user configured entries of old
164 // ChromeOS versions. We will have to use a heuristic to determine which
165 // properties _might_ be user configured.
168 scoped_ptr<base::DictionaryValue> active_settings(
169 onc::TranslateShillServiceToONCPart(
170 *shill_properties,
171 &onc::kNetworkWithStateSignature));
173 std::string guid;
174 active_settings->GetStringWithoutPathExpansion(::onc::network_config::kGUID,
175 &guid);
177 const base::DictionaryValue* user_policy = NULL;
178 const base::DictionaryValue* device_policy = NULL;
179 if (!guid.empty() && profile) {
180 const Policies* policies = GetPoliciesForProfile(*profile);
181 if (!policies) {
182 InvokeErrorCallback(
183 service_path, error_callback, kPoliciesNotInitialized);
184 return;
186 const base::DictionaryValue* policy =
187 GetByGUID(policies->per_network_config, guid);
188 if (profile->type() == NetworkProfile::TYPE_SHARED)
189 device_policy = policy;
190 else if (profile->type() == NetworkProfile::TYPE_USER)
191 user_policy = policy;
192 else
193 NOTREACHED();
196 // This call also removes credentials from policies.
197 scoped_ptr<base::DictionaryValue> augmented_properties =
198 onc::MergeSettingsAndPoliciesToAugmented(
199 onc::kNetworkConfigurationSignature,
200 user_policy,
201 device_policy,
202 user_settings,
203 shared_settings,
204 active_settings.get());
205 callback.Run(service_path, *augmented_properties);
208 // GetProperties
210 void ManagedNetworkConfigurationHandlerImpl::GetProperties(
211 const std::string& service_path,
212 const network_handler::DictionaryResultCallback& callback,
213 const network_handler::ErrorCallback& error_callback) {
214 network_configuration_handler_->GetProperties(
215 service_path,
216 base::Bind(
217 &ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback,
218 weak_ptr_factory_.GetWeakPtr(),
219 base::Bind(&ManagedNetworkConfigurationHandlerImpl::SendProperties,
220 weak_ptr_factory_.GetWeakPtr(),
221 callback,
222 error_callback)),
223 error_callback);
226 void ManagedNetworkConfigurationHandlerImpl::SendProperties(
227 const network_handler::DictionaryResultCallback& callback,
228 const network_handler::ErrorCallback& error_callback,
229 const std::string& service_path,
230 scoped_ptr<base::DictionaryValue> shill_properties) {
231 scoped_ptr<base::DictionaryValue> onc_network(
232 onc::TranslateShillServiceToONCPart(*shill_properties,
233 &onc::kNetworkWithStateSignature));
234 callback.Run(service_path, *onc_network);
237 // SetProperties
239 void ManagedNetworkConfigurationHandlerImpl::SetProperties(
240 const std::string& service_path,
241 const base::DictionaryValue& user_settings,
242 const base::Closure& callback,
243 const network_handler::ErrorCallback& error_callback) const {
244 const NetworkState* state =
245 network_state_handler_->GetNetworkStateFromServicePath(
246 service_path, true /* configured_only */);
247 if (!state) {
248 InvokeErrorCallback(service_path, error_callback, kUnknownNetwork);
249 return;
252 std::string guid = state->guid();
253 if (guid.empty()) {
254 // TODO(pneubeck): create an initial configuration in this case. As for
255 // CreateConfiguration, user settings from older ChromeOS versions have to
256 // determined here.
257 InvokeErrorCallback(
258 service_path, error_callback, kSetOnUnconfiguredNetwork);
259 return;
262 const std::string& profile_path = state->profile_path();
263 const NetworkProfile *profile =
264 network_profile_handler_->GetProfileForPath(profile_path);
265 if (!profile) {
266 InvokeErrorCallback(service_path, error_callback, kUnknownProfilePath);
267 return;
270 VLOG(2) << "SetProperties: Found GUID " << guid << " and profile "
271 << profile->ToDebugString();
273 const Policies* policies = GetPoliciesForProfile(*profile);
274 if (!policies) {
275 InvokeErrorCallback(service_path, error_callback, kPoliciesNotInitialized);
276 return;
279 // Validate the ONC dictionary. We are liberal and ignore unknown field
280 // names. User settings are only partial ONC, thus we ignore missing fields.
281 onc::Validator validator(false, // Ignore unknown fields.
282 false, // Ignore invalid recommended field names.
283 false, // Ignore missing fields.
284 false); // This ONC does not come from policy.
286 onc::Validator::Result validation_result;
287 scoped_ptr<base::DictionaryValue> validated_user_settings =
288 validator.ValidateAndRepairObject(
289 &onc::kNetworkConfigurationSignature,
290 user_settings,
291 &validation_result);
293 if (validation_result == onc::Validator::INVALID) {
294 InvokeErrorCallback(service_path, error_callback, kInvalidUserSettings);
295 return;
297 if (validation_result == onc::Validator::VALID_WITH_WARNINGS)
298 LOG(WARNING) << "Validation of ONC user settings produced warnings.";
300 const base::DictionaryValue* policy =
301 GetByGUID(policies->per_network_config, guid);
302 VLOG(2) << "This configuration is " << (policy ? "" : "not ") << "managed.";
304 scoped_ptr<base::DictionaryValue> shill_dictionary(
305 policy_util::CreateShillConfiguration(
306 *profile, guid, policy, validated_user_settings.get()));
308 network_configuration_handler_->SetProperties(
309 service_path, *shill_dictionary, callback, error_callback);
312 void ManagedNetworkConfigurationHandlerImpl::CreateConfiguration(
313 const std::string& userhash,
314 const base::DictionaryValue& properties,
315 const network_handler::StringResultCallback& callback,
316 const network_handler::ErrorCallback& error_callback) const {
317 const Policies* policies = GetPoliciesForUser(userhash);
318 if (!policies) {
319 InvokeErrorCallback("", error_callback, kPoliciesNotInitialized);
320 return;
323 if (policy_util::FindMatchingPolicy(policies->per_network_config,
324 properties)) {
325 InvokeErrorCallback("", error_callback, kNetworkAlreadyConfigured);
326 return;
329 const NetworkProfile* profile =
330 network_profile_handler_->GetProfileForUserhash(userhash);
331 if (!profile) {
332 InvokeErrorCallback("", error_callback, kProfileNotInitialized);
333 return;
336 // TODO(pneubeck): In case of WiFi, check that no other configuration for the
337 // same {SSID, mode, security} exists. We don't support such multiple
338 // configurations, yet.
340 // Generate a new GUID for this configuration. Ignore the maybe provided GUID
341 // in |properties| as it is not our own and from an untrusted source.
342 std::string guid = base::GenerateGUID();
343 scoped_ptr<base::DictionaryValue> shill_dictionary(
344 policy_util::CreateShillConfiguration(
345 *profile, guid, NULL /*no policy*/, &properties));
347 network_configuration_handler_->CreateConfiguration(
348 *shill_dictionary, callback, error_callback);
351 void ManagedNetworkConfigurationHandlerImpl::RemoveConfiguration(
352 const std::string& service_path,
353 const base::Closure& callback,
354 const network_handler::ErrorCallback& error_callback) const {
355 network_configuration_handler_->RemoveConfiguration(
356 service_path, callback, error_callback);
359 void ManagedNetworkConfigurationHandlerImpl::SetPolicy(
360 ::onc::ONCSource onc_source,
361 const std::string& userhash,
362 const base::ListValue& network_configs_onc,
363 const base::DictionaryValue& global_network_config) {
364 VLOG(1) << "Setting policies from " << ToDebugString(onc_source, userhash)
365 << ".";
367 // |userhash| must be empty for device policies.
368 DCHECK(onc_source != ::onc::ONC_SOURCE_DEVICE_POLICY ||
369 userhash.empty());
370 Policies* policies = NULL;
371 if (ContainsKey(policies_by_user_, userhash)) {
372 policies = policies_by_user_[userhash].get();
373 } else {
374 policies = new Policies;
375 policies_by_user_[userhash] = make_linked_ptr(policies);
378 policies->global_network_config.MergeDictionary(&global_network_config);
380 GuidToPolicyMap old_per_network_config;
381 policies->per_network_config.swap(old_per_network_config);
383 // This stores all GUIDs of policies that have changed or are new.
384 std::set<std::string> modified_policies;
386 for (base::ListValue::const_iterator it = network_configs_onc.begin();
387 it != network_configs_onc.end(); ++it) {
388 const base::DictionaryValue* network = NULL;
389 (*it)->GetAsDictionary(&network);
390 DCHECK(network);
392 std::string guid;
393 network->GetStringWithoutPathExpansion(::onc::network_config::kGUID, &guid);
394 DCHECK(!guid.empty());
396 if (policies->per_network_config.count(guid) > 0) {
397 NET_LOG_ERROR("ONC from " + ToDebugString(onc_source, userhash) +
398 " contains several entries for the same GUID ", guid);
399 delete policies->per_network_config[guid];
401 const base::DictionaryValue* new_entry = network->DeepCopy();
402 policies->per_network_config[guid] = new_entry;
404 const base::DictionaryValue* old_entry = old_per_network_config[guid];
405 if (!old_entry || !old_entry->Equals(new_entry))
406 modified_policies.insert(guid);
409 STLDeleteValues(&old_per_network_config);
411 const NetworkProfile* profile =
412 network_profile_handler_->GetProfileForUserhash(userhash);
413 if (profile) {
414 scoped_refptr<PolicyApplicator> applicator =
415 new PolicyApplicator(weak_ptr_factory_.GetWeakPtr(),
416 *profile,
417 policies->per_network_config,
418 policies->global_network_config,
419 &modified_policies);
420 applicator->Run();
421 } else {
422 VLOG(1) << "The relevant Shill profile isn't initialized yet, postponing "
423 << "policy application.";
424 // See OnProfileAdded.
427 FOR_EACH_OBSERVER(NetworkPolicyObserver, observers_, PolicyChanged(userhash));
430 void ManagedNetworkConfigurationHandlerImpl::OnProfileAdded(
431 const NetworkProfile& profile) {
432 VLOG(1) << "Adding profile " << profile.ToDebugString() << "'.";
434 const Policies* policies = GetPoliciesForProfile(profile);
435 if (!policies) {
436 VLOG(1) << "The relevant policy is not initialized, "
437 << "postponing policy application.";
438 // See SetPolicy.
439 return;
442 std::set<std::string> policy_guids;
443 for (GuidToPolicyMap::const_iterator it =
444 policies->per_network_config.begin();
445 it != policies->per_network_config.end(); ++it) {
446 policy_guids.insert(it->first);
449 scoped_refptr<PolicyApplicator> applicator =
450 new PolicyApplicator(weak_ptr_factory_.GetWeakPtr(),
451 profile,
452 policies->per_network_config,
453 policies->global_network_config,
454 &policy_guids);
455 applicator->Run();
458 void ManagedNetworkConfigurationHandlerImpl::OnProfileRemoved(
459 const NetworkProfile& profile) {
460 // Nothing to do in this case.
463 void ManagedNetworkConfigurationHandlerImpl::CreateConfigurationFromPolicy(
464 const base::DictionaryValue& shill_properties) {
465 network_configuration_handler_->CreateConfiguration(
466 shill_properties,
467 base::Bind(
468 &ManagedNetworkConfigurationHandlerImpl::OnPolicyAppliedToNetwork,
469 weak_ptr_factory_.GetWeakPtr()),
470 base::Bind(&LogErrorWithDict, FROM_HERE));
473 void ManagedNetworkConfigurationHandlerImpl::
474 UpdateExistingConfigurationWithPropertiesFromPolicy(
475 const base::DictionaryValue& existing_properties,
476 const base::DictionaryValue& new_properties) {
477 base::DictionaryValue shill_properties;
479 std::string profile;
480 existing_properties.GetStringWithoutPathExpansion(shill::kProfileProperty,
481 &profile);
482 if (profile.empty()) {
483 NET_LOG_ERROR("Missing profile property",
484 shill_property_util::GetNetworkIdFromProperties(
485 existing_properties));
486 return;
488 shill_properties.SetStringWithoutPathExpansion(shill::kProfileProperty,
489 profile);
491 if (!shill_property_util::CopyIdentifyingProperties(
492 existing_properties,
493 true /* properties were read from Shill */,
494 &shill_properties)) {
495 NET_LOG_ERROR("Missing identifying properties",
496 shill_property_util::GetNetworkIdFromProperties(
497 existing_properties));
500 shill_properties.MergeDictionary(&new_properties);
502 network_configuration_handler_->CreateConfiguration(
503 shill_properties,
504 base::Bind(
505 &ManagedNetworkConfigurationHandlerImpl::OnPolicyAppliedToNetwork,
506 weak_ptr_factory_.GetWeakPtr()),
507 base::Bind(&LogErrorWithDict, FROM_HERE));
510 void ManagedNetworkConfigurationHandlerImpl::OnPoliciesApplied() {
513 const base::DictionaryValue*
514 ManagedNetworkConfigurationHandlerImpl::FindPolicyByGUID(
515 const std::string userhash,
516 const std::string& guid,
517 ::onc::ONCSource* onc_source) const {
518 *onc_source = ::onc::ONC_SOURCE_NONE;
520 if (!userhash.empty()) {
521 const Policies* user_policies = GetPoliciesForUser(userhash);
522 if (user_policies) {
523 const base::DictionaryValue* policy =
524 GetByGUID(user_policies->per_network_config, guid);
525 if (policy) {
526 *onc_source = ::onc::ONC_SOURCE_USER_POLICY;
527 return policy;
532 const Policies* device_policies = GetPoliciesForUser(std::string());
533 if (device_policies) {
534 const base::DictionaryValue* policy =
535 GetByGUID(device_policies->per_network_config, guid);
536 if (policy) {
537 *onc_source = ::onc::ONC_SOURCE_DEVICE_POLICY;
538 return policy;
542 return NULL;
545 const base::DictionaryValue*
546 ManagedNetworkConfigurationHandlerImpl::GetGlobalConfigFromPolicy(
547 const std::string userhash) const {
548 const Policies* policies = GetPoliciesForUser(userhash);
549 if (!policies)
550 return NULL;
552 return &policies->global_network_config;
554 const base::DictionaryValue*
555 ManagedNetworkConfigurationHandlerImpl::FindPolicyByGuidAndProfile(
556 const std::string& guid,
557 const std::string& profile_path) const {
558 const NetworkProfile* profile =
559 network_profile_handler_->GetProfileForPath(profile_path);
560 if (!profile) {
561 NET_LOG_ERROR("Profile path unknown:" + profile_path, guid);
562 return NULL;
565 const Policies* policies = GetPoliciesForProfile(*profile);
566 if (!policies)
567 return NULL;
569 return GetByGUID(policies->per_network_config, guid);
572 const ManagedNetworkConfigurationHandlerImpl::Policies*
573 ManagedNetworkConfigurationHandlerImpl::GetPoliciesForUser(
574 const std::string& userhash) const {
575 UserToPoliciesMap::const_iterator it = policies_by_user_.find(userhash);
576 if (it == policies_by_user_.end())
577 return NULL;
578 return it->second.get();
581 const ManagedNetworkConfigurationHandlerImpl::Policies*
582 ManagedNetworkConfigurationHandlerImpl::GetPoliciesForProfile(
583 const NetworkProfile& profile) const {
584 DCHECK(profile.type() != NetworkProfile::TYPE_SHARED ||
585 profile.userhash.empty());
586 return GetPoliciesForUser(profile.userhash);
589 ManagedNetworkConfigurationHandlerImpl::ManagedNetworkConfigurationHandlerImpl()
590 : network_state_handler_(NULL),
591 network_profile_handler_(NULL),
592 network_configuration_handler_(NULL),
593 network_device_handler_(NULL),
594 weak_ptr_factory_(this) {}
596 ManagedNetworkConfigurationHandlerImpl::
597 ~ManagedNetworkConfigurationHandlerImpl() {
598 network_profile_handler_->RemoveObserver(this);
601 void ManagedNetworkConfigurationHandlerImpl::Init(
602 NetworkStateHandler* network_state_handler,
603 NetworkProfileHandler* network_profile_handler,
604 NetworkConfigurationHandler* network_configuration_handler,
605 NetworkDeviceHandler* network_device_handler) {
606 network_state_handler_ = network_state_handler;
607 network_profile_handler_ = network_profile_handler;
608 network_configuration_handler_ = network_configuration_handler;
609 network_device_handler_ = network_device_handler;
610 network_profile_handler_->AddObserver(this);
613 void ManagedNetworkConfigurationHandlerImpl::OnPolicyAppliedToNetwork(
614 const std::string& service_path) {
615 if (service_path.empty())
616 return;
617 FOR_EACH_OBSERVER(
618 NetworkPolicyObserver, observers_, PolicyApplied(service_path));
621 // Get{Managed}Properties helpers
623 void ManagedNetworkConfigurationHandlerImpl::GetDeviceStateProperties(
624 const std::string& service_path,
625 base::DictionaryValue* properties) {
626 std::string connection_state;
627 properties->GetStringWithoutPathExpansion(
628 shill::kStateProperty, &connection_state);
629 if (!NetworkState::StateIsConnected(connection_state))
630 return;
632 // Get the IPConfig properties from the device and store them in "IPConfigs"
633 // (plural) in the properties dictionary. (Note: Shill only provides a single
634 // "IPConfig" property for a network service, but a consumer of this API may
635 // want information about all ipv4 and ipv6 IPConfig properties.
636 std::string device;
637 properties->GetStringWithoutPathExpansion(shill::kDeviceProperty, &device);
638 const DeviceState* device_state =
639 network_state_handler_->GetDeviceState(device);
640 if (!device_state) {
641 NET_LOG_ERROR("GetDeviceProperties: no device: " + device, service_path);
642 return;
645 // Get the hardware MAC address from the DeviceState.
646 if (!device_state->mac_address().empty()) {
647 properties->SetStringWithoutPathExpansion(
648 shill::kAddressProperty, device_state->mac_address());
651 // Convert IPConfig dictionary to a ListValue.
652 base::ListValue* ip_configs = new base::ListValue;
653 for (base::DictionaryValue::Iterator iter(device_state->ip_configs());
654 !iter.IsAtEnd(); iter.Advance()) {
655 ip_configs->Append(iter.value().DeepCopy());
657 properties->SetWithoutPathExpansion(shill::kIPConfigsProperty, ip_configs);
660 void ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback(
661 GetDevicePropertiesCallback send_callback,
662 const std::string& service_path,
663 const base::DictionaryValue& shill_properties) {
664 scoped_ptr<base::DictionaryValue> shill_properties_copy(
665 shill_properties.DeepCopy());
667 // Add associated Device properties before the ONC translation.
668 GetDeviceStateProperties(service_path, shill_properties_copy.get());
670 // Only request Device properties for Cellular networks with a valid device.
671 std::string type, device_path;
672 if (!network_device_handler_ ||
673 !shill_properties_copy->GetStringWithoutPathExpansion(
674 shill::kTypeProperty, &type) ||
675 type != shill::kTypeCellular ||
676 !shill_properties_copy->GetStringWithoutPathExpansion(
677 shill::kDeviceProperty, &device_path) ||
678 device_path.empty()) {
679 send_callback.Run(service_path, shill_properties_copy.Pass());
680 return;
683 // Request the device properties. On success or failure pass (a possibly
684 // modified) |shill_properties| to |send_callback|.
685 scoped_ptr<base::DictionaryValue> shill_properties_copy_error_copy(
686 shill_properties_copy->DeepCopy());
687 network_device_handler_->GetDeviceProperties(
688 device_path,
689 base::Bind(&ManagedNetworkConfigurationHandlerImpl::
690 GetDevicePropertiesSuccess,
691 weak_ptr_factory_.GetWeakPtr(),
692 service_path,
693 base::Passed(&shill_properties_copy),
694 send_callback),
695 base::Bind(&ManagedNetworkConfigurationHandlerImpl::
696 GetDevicePropertiesFailure,
697 weak_ptr_factory_.GetWeakPtr(),
698 service_path,
699 base::Passed(&shill_properties_copy_error_copy),
700 send_callback));
703 void ManagedNetworkConfigurationHandlerImpl::GetDevicePropertiesSuccess(
704 const std::string& service_path,
705 scoped_ptr<base::DictionaryValue> network_properties,
706 GetDevicePropertiesCallback send_callback,
707 const std::string& device_path,
708 const base::DictionaryValue& device_properties) {
709 // Create a "Device" dictionary in |network_properties|.
710 network_properties->SetWithoutPathExpansion(
711 shill::kDeviceProperty, device_properties.DeepCopy());
712 send_callback.Run(service_path, network_properties.Pass());
715 void ManagedNetworkConfigurationHandlerImpl::GetDevicePropertiesFailure(
716 const std::string& service_path,
717 scoped_ptr<base::DictionaryValue> network_properties,
718 GetDevicePropertiesCallback send_callback,
719 const std::string& error_name,
720 scoped_ptr<base::DictionaryValue> error_data) {
721 NET_LOG_ERROR("Error getting device properties", service_path);
722 send_callback.Run(service_path, network_properties.Pass());
726 } // namespace chromeos