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"
10 #include "base/bind.h"
11 #include "base/guid.h"
12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/message_loop/message_loop.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"
44 using GuidToPolicyMap
= ManagedNetworkConfigurationHandler::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
,
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())
90 struct ManagedNetworkConfigurationHandlerImpl::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
);
122 network_configuration_handler_
->GetProperties(
125 &ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback
,
126 weak_ptr_factory_
.GetWeakPtr(),
128 &ManagedNetworkConfigurationHandlerImpl::SendManagedProperties
,
129 weak_ptr_factory_
.GetWeakPtr(),
136 void ManagedNetworkConfigurationHandlerImpl::SendManagedProperties(
137 const std::string
& userhash
,
138 const network_handler::DictionaryResultCallback
& callback
,
139 const network_handler::ErrorCallback
& error_callback
,
140 const std::string
& service_path
,
141 scoped_ptr
<base::DictionaryValue
> shill_properties
) {
142 std::string profile_path
;
143 shill_properties
->GetStringWithoutPathExpansion(shill::kProfileProperty
,
145 const NetworkProfile
* profile
=
146 network_profile_handler_
->GetProfileForPath(profile_path
);
148 NET_LOG_ERROR("No profile for service: " + profile_path
, service_path
);
150 scoped_ptr
<NetworkUIData
> ui_data
=
151 shill_property_util::GetUIDataFromProperties(*shill_properties
);
153 const base::DictionaryValue
* user_settings
= NULL
;
155 if (ui_data
&& profile
) {
156 user_settings
= ui_data
->user_settings();
157 } else if (profile
) {
158 NET_LOG_ERROR("Service contains empty or invalid UIData", service_path
);
159 // TODO(pneubeck): add a conversion of user configured entries of old
160 // ChromeOS versions. We will have to use a heuristic to determine which
161 // properties _might_ be user configured.
165 shill_properties
->GetStringWithoutPathExpansion(shill::kGuidProperty
, &guid
);
167 ::onc::ONCSource onc_source
;
168 FindPolicyByGUID(userhash
, guid
, &onc_source
);
169 scoped_ptr
<base::DictionaryValue
> active_settings(
170 onc::TranslateShillServiceToONCPart(
171 *shill_properties
, onc_source
, &onc::kNetworkWithStateSignature
));
173 const base::DictionaryValue
* network_policy
= NULL
;
174 const base::DictionaryValue
* global_policy
= NULL
;
176 const Policies
* policies
= GetPoliciesForProfile(*profile
);
179 service_path
, error_callback
, kPoliciesNotInitialized
);
183 network_policy
= GetByGUID(policies
->per_network_config
, guid
);
184 global_policy
= &policies
->global_network_config
;
187 scoped_ptr
<base::DictionaryValue
> augmented_properties(
188 policy_util::CreateManagedONC(global_policy
,
191 active_settings
.get(),
193 callback
.Run(service_path
, *augmented_properties
);
198 void ManagedNetworkConfigurationHandlerImpl::GetProperties(
199 const std::string
& service_path
,
200 const network_handler::DictionaryResultCallback
& callback
,
201 const network_handler::ErrorCallback
& error_callback
) {
202 network_configuration_handler_
->GetProperties(
205 &ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback
,
206 weak_ptr_factory_
.GetWeakPtr(),
207 base::Bind(&ManagedNetworkConfigurationHandlerImpl::SendProperties
,
208 weak_ptr_factory_
.GetWeakPtr(),
214 void ManagedNetworkConfigurationHandlerImpl::SendProperties(
215 const network_handler::DictionaryResultCallback
& callback
,
216 const network_handler::ErrorCallback
& error_callback
,
217 const std::string
& service_path
,
218 scoped_ptr
<base::DictionaryValue
> shill_properties
) {
219 scoped_ptr
<base::DictionaryValue
> onc_network(
220 onc::TranslateShillServiceToONCPart(
221 *shill_properties
, ::onc::ONC_SOURCE_UNKNOWN
,
222 &onc::kNetworkWithStateSignature
));
223 callback
.Run(service_path
, *onc_network
);
228 void ManagedNetworkConfigurationHandlerImpl::SetProperties(
229 const std::string
& service_path
,
230 const base::DictionaryValue
& user_settings
,
231 const base::Closure
& callback
,
232 const network_handler::ErrorCallback
& error_callback
) const {
233 const NetworkState
* state
=
234 network_state_handler_
->GetNetworkStateFromServicePath(
235 service_path
, true /* configured_only */);
237 InvokeErrorCallback(service_path
, error_callback
, kUnknownNetwork
);
241 std::string guid
= state
->guid();
243 // TODO(pneubeck): create an initial configuration in this case. As for
244 // CreateConfiguration, user settings from older ChromeOS versions have to
247 service_path
, error_callback
, kSetOnUnconfiguredNetwork
);
251 const std::string
& profile_path
= state
->profile_path();
252 const NetworkProfile
*profile
=
253 network_profile_handler_
->GetProfileForPath(profile_path
);
255 InvokeErrorCallback(service_path
, error_callback
, kUnknownProfilePath
);
259 VLOG(2) << "SetProperties: Found GUID " << guid
<< " and profile "
260 << profile
->ToDebugString();
262 const Policies
* policies
= GetPoliciesForProfile(*profile
);
264 InvokeErrorCallback(service_path
, error_callback
, kPoliciesNotInitialized
);
268 // Validate the ONC dictionary. We are liberal and ignore unknown field
269 // names. User settings are only partial ONC, thus we ignore missing fields.
270 onc::Validator
validator(false, // Ignore unknown fields.
271 false, // Ignore invalid recommended field names.
272 false, // Ignore missing fields.
273 false); // This ONC does not come from policy.
275 onc::Validator::Result validation_result
;
276 scoped_ptr
<base::DictionaryValue
> validated_user_settings
=
277 validator
.ValidateAndRepairObject(
278 &onc::kNetworkConfigurationSignature
,
282 if (validation_result
== onc::Validator::INVALID
) {
283 InvokeErrorCallback(service_path
, error_callback
, kInvalidUserSettings
);
286 if (validation_result
== onc::Validator::VALID_WITH_WARNINGS
)
287 LOG(WARNING
) << "Validation of ONC user settings produced warnings.";
289 const base::DictionaryValue
* network_policy
=
290 GetByGUID(policies
->per_network_config
, guid
);
291 VLOG(2) << "This configuration is " << (network_policy
? "" : "not ")
294 scoped_ptr
<base::DictionaryValue
> shill_dictionary(
295 policy_util::CreateShillConfiguration(*profile
,
297 &policies
->global_network_config
,
299 validated_user_settings
.get()));
301 network_configuration_handler_
->SetProperties(
302 service_path
, *shill_dictionary
, callback
, error_callback
);
305 void ManagedNetworkConfigurationHandlerImpl::CreateConfiguration(
306 const std::string
& userhash
,
307 const base::DictionaryValue
& properties
,
308 const network_handler::StringResultCallback
& callback
,
309 const network_handler::ErrorCallback
& error_callback
) const {
310 const Policies
* policies
= GetPoliciesForUser(userhash
);
312 InvokeErrorCallback("", error_callback
, kPoliciesNotInitialized
);
316 if (policy_util::FindMatchingPolicy(policies
->per_network_config
,
318 InvokeErrorCallback("", error_callback
, kNetworkAlreadyConfigured
);
322 const NetworkProfile
* profile
=
323 network_profile_handler_
->GetProfileForUserhash(userhash
);
325 InvokeErrorCallback("", error_callback
, kProfileNotInitialized
);
329 // TODO(pneubeck): In case of WiFi, check that no other configuration for the
330 // same {SSID, mode, security} exists. We don't support such multiple
331 // configurations, yet.
333 // Generate a new GUID for this configuration. Ignore the maybe provided GUID
334 // in |properties| as it is not our own and from an untrusted source.
335 std::string guid
= base::GenerateGUID();
336 scoped_ptr
<base::DictionaryValue
> shill_dictionary(
337 policy_util::CreateShillConfiguration(*profile
,
339 NULL
, // no global policy
340 NULL
, // no network policy
343 network_configuration_handler_
->CreateConfiguration(
344 *shill_dictionary
, callback
, error_callback
);
347 void ManagedNetworkConfigurationHandlerImpl::RemoveConfiguration(
348 const std::string
& service_path
,
349 const base::Closure
& callback
,
350 const network_handler::ErrorCallback
& error_callback
) const {
351 network_configuration_handler_
->RemoveConfiguration(
352 service_path
, callback
, error_callback
);
355 void ManagedNetworkConfigurationHandlerImpl::SetPolicy(
356 ::onc::ONCSource onc_source
,
357 const std::string
& userhash
,
358 const base::ListValue
& network_configs_onc
,
359 const base::DictionaryValue
& global_network_config
) {
360 VLOG(1) << "Setting policies from " << ToDebugString(onc_source
, userhash
)
363 // |userhash| must be empty for device policies.
364 DCHECK(onc_source
!= ::onc::ONC_SOURCE_DEVICE_POLICY
||
366 Policies
* policies
= NULL
;
367 if (ContainsKey(policies_by_user_
, userhash
)) {
368 policies
= policies_by_user_
[userhash
].get();
370 policies
= new Policies
;
371 policies_by_user_
[userhash
] = make_linked_ptr(policies
);
374 policies
->global_network_config
.MergeDictionary(&global_network_config
);
376 GuidToPolicyMap old_per_network_config
;
377 policies
->per_network_config
.swap(old_per_network_config
);
379 // This stores all GUIDs of policies that have changed or are new.
380 std::set
<std::string
> modified_policies
;
382 for (base::ListValue::const_iterator it
= network_configs_onc
.begin();
383 it
!= network_configs_onc
.end(); ++it
) {
384 const base::DictionaryValue
* network
= NULL
;
385 (*it
)->GetAsDictionary(&network
);
389 network
->GetStringWithoutPathExpansion(::onc::network_config::kGUID
, &guid
);
390 DCHECK(!guid
.empty());
392 if (policies
->per_network_config
.count(guid
) > 0) {
393 NET_LOG_ERROR("ONC from " + ToDebugString(onc_source
, userhash
) +
394 " contains several entries for the same GUID ", guid
);
395 delete policies
->per_network_config
[guid
];
397 const base::DictionaryValue
* new_entry
= network
->DeepCopy();
398 policies
->per_network_config
[guid
] = new_entry
;
400 const base::DictionaryValue
* old_entry
= old_per_network_config
[guid
];
401 if (!old_entry
|| !old_entry
->Equals(new_entry
))
402 modified_policies
.insert(guid
);
405 STLDeleteValues(&old_per_network_config
);
406 ApplyOrQueuePolicies(userhash
, &modified_policies
);
407 FOR_EACH_OBSERVER(NetworkPolicyObserver
, observers_
,
408 PoliciesChanged(userhash
));
411 bool ManagedNetworkConfigurationHandlerImpl::IsAnyPolicyApplicationRunning()
413 return !policy_applicators_
.empty() || !queued_modified_policies_
.empty();
416 bool ManagedNetworkConfigurationHandlerImpl::ApplyOrQueuePolicies(
417 const std::string
& userhash
,
418 std::set
<std::string
>* modified_policies
) {
419 DCHECK(modified_policies
);
421 const NetworkProfile
* profile
=
422 network_profile_handler_
->GetProfileForUserhash(userhash
);
424 VLOG(1) << "The relevant Shill profile isn't initialized yet, postponing "
425 << "policy application.";
426 // OnProfileAdded will apply all policies for this userhash.
430 if (ContainsKey(policy_applicators_
, userhash
)) {
431 // A previous policy application is still running. Queue the modified
433 // Note, even if |modified_policies| is empty, this means that a policy
434 // application will be queued.
435 queued_modified_policies_
[userhash
].insert(modified_policies
->begin(),
436 modified_policies
->end());
437 VLOG(1) << "Previous PolicyApplicator still running. Postponing policy "
442 const Policies
* policies
= policies_by_user_
[userhash
].get();
445 PolicyApplicator
* applicator
=
446 new PolicyApplicator(*profile
,
447 policies
->per_network_config
,
448 policies
->global_network_config
,
451 policy_applicators_
[userhash
] = make_linked_ptr(applicator
);
456 void ManagedNetworkConfigurationHandlerImpl::OnProfileAdded(
457 const NetworkProfile
& profile
) {
458 VLOG(1) << "Adding profile " << profile
.ToDebugString() << "'.";
460 const Policies
* policies
= GetPoliciesForProfile(profile
);
462 VLOG(1) << "The relevant policy is not initialized, "
463 << "postponing policy application.";
468 std::set
<std::string
> policy_guids
;
469 for (GuidToPolicyMap::const_iterator it
=
470 policies
->per_network_config
.begin();
471 it
!= policies
->per_network_config
.end(); ++it
) {
472 policy_guids
.insert(it
->first
);
475 const bool started_policy_application
=
476 ApplyOrQueuePolicies(profile
.userhash
, &policy_guids
);
477 DCHECK(started_policy_application
);
480 void ManagedNetworkConfigurationHandlerImpl::OnProfileRemoved(
481 const NetworkProfile
& profile
) {
482 // Nothing to do in this case.
485 void ManagedNetworkConfigurationHandlerImpl::CreateConfigurationFromPolicy(
486 const base::DictionaryValue
& shill_properties
) {
487 network_configuration_handler_
->CreateConfiguration(
490 &ManagedNetworkConfigurationHandlerImpl::OnPolicyAppliedToNetwork
,
491 weak_ptr_factory_
.GetWeakPtr()),
492 base::Bind(&LogErrorWithDict
, FROM_HERE
));
495 void ManagedNetworkConfigurationHandlerImpl::
496 UpdateExistingConfigurationWithPropertiesFromPolicy(
497 const base::DictionaryValue
& existing_properties
,
498 const base::DictionaryValue
& new_properties
) {
499 base::DictionaryValue shill_properties
;
502 existing_properties
.GetStringWithoutPathExpansion(shill::kProfileProperty
,
504 if (profile
.empty()) {
505 NET_LOG_ERROR("Missing profile property",
506 shill_property_util::GetNetworkIdFromProperties(
507 existing_properties
));
510 shill_properties
.SetStringWithoutPathExpansion(shill::kProfileProperty
,
513 if (!shill_property_util::CopyIdentifyingProperties(
515 true /* properties were read from Shill */,
516 &shill_properties
)) {
517 NET_LOG_ERROR("Missing identifying properties",
518 shill_property_util::GetNetworkIdFromProperties(
519 existing_properties
));
522 shill_properties
.MergeDictionary(&new_properties
);
524 network_configuration_handler_
->CreateConfiguration(
527 &ManagedNetworkConfigurationHandlerImpl::OnPolicyAppliedToNetwork
,
528 weak_ptr_factory_
.GetWeakPtr()),
529 base::Bind(&LogErrorWithDict
, FROM_HERE
));
532 void ManagedNetworkConfigurationHandlerImpl::OnPoliciesApplied(
533 const NetworkProfile
& profile
) {
534 const std::string
& userhash
= profile
.userhash
;
535 VLOG(1) << "Policy application for user '" << userhash
<< "' finished.";
537 base::MessageLoop::current()->DeleteSoon(
538 FROM_HERE
, policy_applicators_
[userhash
].release());
539 policy_applicators_
.erase(userhash
);
541 if (ContainsKey(queued_modified_policies_
, userhash
)) {
542 std::set
<std::string
> modified_policies
;
543 queued_modified_policies_
[userhash
].swap(modified_policies
);
544 // Remove |userhash| from the queue.
545 queued_modified_policies_
.erase(userhash
);
546 ApplyOrQueuePolicies(userhash
, &modified_policies
);
549 NetworkPolicyObserver
, observers_
, PoliciesApplied(userhash
));
553 const base::DictionaryValue
*
554 ManagedNetworkConfigurationHandlerImpl::FindPolicyByGUID(
555 const std::string userhash
,
556 const std::string
& guid
,
557 ::onc::ONCSource
* onc_source
) const {
558 *onc_source
= ::onc::ONC_SOURCE_NONE
;
560 if (!userhash
.empty()) {
561 const Policies
* user_policies
= GetPoliciesForUser(userhash
);
563 const base::DictionaryValue
* policy
=
564 GetByGUID(user_policies
->per_network_config
, guid
);
566 *onc_source
= ::onc::ONC_SOURCE_USER_POLICY
;
572 const Policies
* device_policies
= GetPoliciesForUser(std::string());
573 if (device_policies
) {
574 const base::DictionaryValue
* policy
=
575 GetByGUID(device_policies
->per_network_config
, guid
);
577 *onc_source
= ::onc::ONC_SOURCE_DEVICE_POLICY
;
585 const GuidToPolicyMap
*
586 ManagedNetworkConfigurationHandlerImpl::GetNetworkConfigsFromPolicy(
587 const std::string
& userhash
) const {
588 const Policies
* policies
= GetPoliciesForUser(userhash
);
592 return &policies
->per_network_config
;
595 const base::DictionaryValue
*
596 ManagedNetworkConfigurationHandlerImpl::GetGlobalConfigFromPolicy(
597 const std::string
& userhash
) const {
598 const Policies
* policies
= GetPoliciesForUser(userhash
);
602 return &policies
->global_network_config
;
605 const base::DictionaryValue
*
606 ManagedNetworkConfigurationHandlerImpl::FindPolicyByGuidAndProfile(
607 const std::string
& guid
,
608 const std::string
& profile_path
) const {
609 const NetworkProfile
* profile
=
610 network_profile_handler_
->GetProfileForPath(profile_path
);
612 NET_LOG_ERROR("Profile path unknown:" + profile_path
, guid
);
616 const Policies
* policies
= GetPoliciesForProfile(*profile
);
620 return GetByGUID(policies
->per_network_config
, guid
);
623 const ManagedNetworkConfigurationHandlerImpl::Policies
*
624 ManagedNetworkConfigurationHandlerImpl::GetPoliciesForUser(
625 const std::string
& userhash
) const {
626 UserToPoliciesMap::const_iterator it
= policies_by_user_
.find(userhash
);
627 if (it
== policies_by_user_
.end())
629 return it
->second
.get();
632 const ManagedNetworkConfigurationHandlerImpl::Policies
*
633 ManagedNetworkConfigurationHandlerImpl::GetPoliciesForProfile(
634 const NetworkProfile
& profile
) const {
635 DCHECK(profile
.type() != NetworkProfile::TYPE_SHARED
||
636 profile
.userhash
.empty());
637 return GetPoliciesForUser(profile
.userhash
);
640 ManagedNetworkConfigurationHandlerImpl::ManagedNetworkConfigurationHandlerImpl()
641 : network_state_handler_(NULL
),
642 network_profile_handler_(NULL
),
643 network_configuration_handler_(NULL
),
644 network_device_handler_(NULL
),
645 weak_ptr_factory_(this) {
646 CHECK(base::MessageLoop::current());
649 ManagedNetworkConfigurationHandlerImpl::
650 ~ManagedNetworkConfigurationHandlerImpl() {
651 network_profile_handler_
->RemoveObserver(this);
654 void ManagedNetworkConfigurationHandlerImpl::Init(
655 NetworkStateHandler
* network_state_handler
,
656 NetworkProfileHandler
* network_profile_handler
,
657 NetworkConfigurationHandler
* network_configuration_handler
,
658 NetworkDeviceHandler
* network_device_handler
) {
659 network_state_handler_
= network_state_handler
;
660 network_profile_handler_
= network_profile_handler
;
661 network_configuration_handler_
= network_configuration_handler
;
662 network_device_handler_
= network_device_handler
;
663 network_profile_handler_
->AddObserver(this);
666 void ManagedNetworkConfigurationHandlerImpl::OnPolicyAppliedToNetwork(
667 const std::string
& service_path
) {
668 if (service_path
.empty())
671 NetworkPolicyObserver
, observers_
, PolicyAppliedToNetwork(service_path
));
674 // Get{Managed}Properties helpers
676 void ManagedNetworkConfigurationHandlerImpl::GetDeviceStateProperties(
677 const std::string
& service_path
,
678 base::DictionaryValue
* properties
) {
679 std::string connection_state
;
680 properties
->GetStringWithoutPathExpansion(
681 shill::kStateProperty
, &connection_state
);
682 if (!NetworkState::StateIsConnected(connection_state
))
685 // Get the IPConfig properties from the device and store them in "IPConfigs"
686 // (plural) in the properties dictionary. (Note: Shill only provides a single
687 // "IPConfig" property for a network service, but a consumer of this API may
688 // want information about all ipv4 and ipv6 IPConfig properties.
690 properties
->GetStringWithoutPathExpansion(shill::kDeviceProperty
, &device
);
691 const DeviceState
* device_state
=
692 network_state_handler_
->GetDeviceState(device
);
694 NET_LOG_ERROR("GetDeviceProperties: no device: " + device
, service_path
);
698 // Get the hardware MAC address from the DeviceState.
699 if (!device_state
->mac_address().empty()) {
700 properties
->SetStringWithoutPathExpansion(
701 shill::kAddressProperty
, device_state
->mac_address());
704 // Convert IPConfig dictionary to a ListValue.
705 base::ListValue
* ip_configs
= new base::ListValue
;
706 for (base::DictionaryValue::Iterator
iter(device_state
->ip_configs());
707 !iter
.IsAtEnd(); iter
.Advance()) {
708 ip_configs
->Append(iter
.value().DeepCopy());
710 properties
->SetWithoutPathExpansion(shill::kIPConfigsProperty
, ip_configs
);
713 void ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback(
714 GetDevicePropertiesCallback send_callback
,
715 const std::string
& service_path
,
716 const base::DictionaryValue
& shill_properties
) {
717 scoped_ptr
<base::DictionaryValue
> shill_properties_copy(
718 shill_properties
.DeepCopy());
720 // Add associated Device properties before the ONC translation.
721 GetDeviceStateProperties(service_path
, shill_properties_copy
.get());
723 // Only request Device properties for Cellular networks with a valid device.
724 std::string type
, device_path
;
725 if (!network_device_handler_
||
726 !shill_properties_copy
->GetStringWithoutPathExpansion(
727 shill::kTypeProperty
, &type
) ||
728 type
!= shill::kTypeCellular
||
729 !shill_properties_copy
->GetStringWithoutPathExpansion(
730 shill::kDeviceProperty
, &device_path
) ||
731 device_path
.empty()) {
732 send_callback
.Run(service_path
, shill_properties_copy
.Pass());
736 // Request the device properties. On success or failure pass (a possibly
737 // modified) |shill_properties| to |send_callback|.
738 scoped_ptr
<base::DictionaryValue
> shill_properties_copy_error_copy(
739 shill_properties_copy
->DeepCopy());
740 network_device_handler_
->GetDeviceProperties(
742 base::Bind(&ManagedNetworkConfigurationHandlerImpl::
743 GetDevicePropertiesSuccess
,
744 weak_ptr_factory_
.GetWeakPtr(),
746 base::Passed(&shill_properties_copy
),
748 base::Bind(&ManagedNetworkConfigurationHandlerImpl::
749 GetDevicePropertiesFailure
,
750 weak_ptr_factory_
.GetWeakPtr(),
752 base::Passed(&shill_properties_copy_error_copy
),
756 void ManagedNetworkConfigurationHandlerImpl::GetDevicePropertiesSuccess(
757 const std::string
& service_path
,
758 scoped_ptr
<base::DictionaryValue
> network_properties
,
759 GetDevicePropertiesCallback send_callback
,
760 const std::string
& device_path
,
761 const base::DictionaryValue
& device_properties
) {
762 // Create a "Device" dictionary in |network_properties|.
763 network_properties
->SetWithoutPathExpansion(
764 shill::kDeviceProperty
, device_properties
.DeepCopy());
765 send_callback
.Run(service_path
, network_properties
.Pass());
768 void ManagedNetworkConfigurationHandlerImpl::GetDevicePropertiesFailure(
769 const std::string
& service_path
,
770 scoped_ptr
<base::DictionaryValue
> network_properties
,
771 GetDevicePropertiesCallback send_callback
,
772 const std::string
& error_name
,
773 scoped_ptr
<base::DictionaryValue
> error_data
) {
774 NET_LOG_ERROR("Error getting device properties", service_path
);
775 send_callback
.Run(service_path
, network_properties
.Pass());
779 } // namespace chromeos