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/network_util.h"
32 #include "chromeos/network/onc/onc_merger.h"
33 #include "chromeos/network/onc/onc_signature.h"
34 #include "chromeos/network/onc/onc_translator.h"
35 #include "chromeos/network/onc/onc_utils.h"
36 #include "chromeos/network/onc/onc_validator.h"
37 #include "chromeos/network/policy_util.h"
38 #include "chromeos/network/shill_property_util.h"
39 #include "components/onc/onc_constants.h"
40 #include "third_party/cros_system_api/dbus/service_constants.h"
46 using GuidToPolicyMap
= ManagedNetworkConfigurationHandler::GuidToPolicyMap
;
48 // These are error strings used for error callbacks. None of these error
49 // messages are user-facing: they should only appear in logs.
50 const char kInvalidUserSettings
[] = "InvalidUserSettings";
51 const char kNetworkAlreadyConfigured
[] = "NetworkAlreadyConfigured";
52 const char kPoliciesNotInitialized
[] = "PoliciesNotInitialized";
53 const char kProfileNotInitialized
[] = "ProfileNotInitialized";
54 const char kSetOnUnconfiguredNetwork
[] = "SetCalledOnUnconfiguredNetwork";
55 const char kUnknownProfilePath
[] = "UnknownProfilePath";
56 const char kUnknownNetwork
[] = "UnknownNetwork";
58 std::string
ToDebugString(::onc::ONCSource source
,
59 const std::string
& userhash
) {
60 return source
== ::onc::ONC_SOURCE_USER_POLICY
?
61 ("user policy of " + userhash
) : "device policy";
64 void InvokeErrorCallback(const std::string
& service_path
,
65 const network_handler::ErrorCallback
& error_callback
,
66 const std::string
& error_name
) {
67 std::string error_msg
= "ManagedConfig Error: " + error_name
;
68 NET_LOG_ERROR(error_msg
, service_path
);
69 network_handler::RunErrorCallback(
70 error_callback
, service_path
, error_name
, error_msg
);
73 void LogErrorWithDict(const tracked_objects::Location
& from_where
,
74 const std::string
& error_name
,
75 scoped_ptr
<base::DictionaryValue
> error_data
) {
76 device_event_log::AddEntry(from_where
.file_name(), from_where
.line_number(),
77 device_event_log::LOG_TYPE_NETWORK
,
78 device_event_log::LOG_LEVEL_ERROR
, error_name
);
81 const base::DictionaryValue
* GetByGUID(const GuidToPolicyMap
& policies
,
82 const std::string
& guid
) {
83 GuidToPolicyMap::const_iterator it
= policies
.find(guid
);
84 if (it
== policies
.end())
91 struct ManagedNetworkConfigurationHandlerImpl::Policies
{
94 GuidToPolicyMap per_network_config
;
95 base::DictionaryValue global_network_config
;
98 ManagedNetworkConfigurationHandlerImpl::Policies::~Policies() {
99 STLDeleteValues(&per_network_config
);
102 void ManagedNetworkConfigurationHandlerImpl::AddObserver(
103 NetworkPolicyObserver
* observer
) {
104 observers_
.AddObserver(observer
);
107 void ManagedNetworkConfigurationHandlerImpl::RemoveObserver(
108 NetworkPolicyObserver
* observer
) {
109 observers_
.RemoveObserver(observer
);
112 // GetManagedProperties
114 void ManagedNetworkConfigurationHandlerImpl::GetManagedProperties(
115 const std::string
& userhash
,
116 const std::string
& service_path
,
117 const network_handler::DictionaryResultCallback
& callback
,
118 const network_handler::ErrorCallback
& error_callback
) {
119 if (!GetPoliciesForUser(userhash
) || !GetPoliciesForUser(std::string())) {
120 InvokeErrorCallback(service_path
, error_callback
, kPoliciesNotInitialized
);
123 network_configuration_handler_
->GetProperties(
126 &ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback
,
127 weak_ptr_factory_
.GetWeakPtr(),
129 &ManagedNetworkConfigurationHandlerImpl::SendManagedProperties
,
130 weak_ptr_factory_
.GetWeakPtr(),
137 void ManagedNetworkConfigurationHandlerImpl::SendManagedProperties(
138 const std::string
& userhash
,
139 const network_handler::DictionaryResultCallback
& callback
,
140 const network_handler::ErrorCallback
& error_callback
,
141 const std::string
& service_path
,
142 scoped_ptr
<base::DictionaryValue
> shill_properties
) {
143 std::string profile_path
;
144 shill_properties
->GetStringWithoutPathExpansion(shill::kProfileProperty
,
146 const NetworkProfile
* profile
=
147 network_profile_handler_
->GetProfileForPath(profile_path
);
149 NET_LOG_ERROR("No profile for service: " + profile_path
, service_path
);
151 scoped_ptr
<NetworkUIData
> ui_data
=
152 shill_property_util::GetUIDataFromProperties(*shill_properties
);
154 const base::DictionaryValue
* user_settings
= NULL
;
156 if (ui_data
&& profile
) {
157 user_settings
= ui_data
->user_settings();
158 } else if (profile
) {
159 NET_LOG_ERROR("Service contains empty or invalid UIData", service_path
);
160 // TODO(pneubeck): add a conversion of user configured entries of old
161 // ChromeOS versions. We will have to use a heuristic to determine which
162 // properties _might_ be user configured.
166 shill_properties
->GetStringWithoutPathExpansion(shill::kGuidProperty
, &guid
);
168 ::onc::ONCSource onc_source
;
169 FindPolicyByGUID(userhash
, guid
, &onc_source
);
170 scoped_ptr
<base::DictionaryValue
> active_settings(
171 onc::TranslateShillServiceToONCPart(
172 *shill_properties
, onc_source
, &onc::kNetworkWithStateSignature
));
174 const base::DictionaryValue
* network_policy
= NULL
;
175 const base::DictionaryValue
* global_policy
= NULL
;
177 const Policies
* policies
= GetPoliciesForProfile(*profile
);
180 service_path
, error_callback
, kPoliciesNotInitialized
);
184 network_policy
= GetByGUID(policies
->per_network_config
, guid
);
185 global_policy
= &policies
->global_network_config
;
188 scoped_ptr
<base::DictionaryValue
> augmented_properties(
189 policy_util::CreateManagedONC(global_policy
,
192 active_settings
.get(),
194 callback
.Run(service_path
, *augmented_properties
);
199 void ManagedNetworkConfigurationHandlerImpl::GetProperties(
200 const std::string
& service_path
,
201 const network_handler::DictionaryResultCallback
& callback
,
202 const network_handler::ErrorCallback
& error_callback
) {
203 network_configuration_handler_
->GetProperties(
206 &ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback
,
207 weak_ptr_factory_
.GetWeakPtr(),
208 base::Bind(&ManagedNetworkConfigurationHandlerImpl::SendProperties
,
209 weak_ptr_factory_
.GetWeakPtr(),
215 void ManagedNetworkConfigurationHandlerImpl::SendProperties(
216 const network_handler::DictionaryResultCallback
& callback
,
217 const network_handler::ErrorCallback
& error_callback
,
218 const std::string
& service_path
,
219 scoped_ptr
<base::DictionaryValue
> shill_properties
) {
220 scoped_ptr
<base::DictionaryValue
> onc_network(
221 onc::TranslateShillServiceToONCPart(
222 *shill_properties
, ::onc::ONC_SOURCE_UNKNOWN
,
223 &onc::kNetworkWithStateSignature
));
224 callback
.Run(service_path
, *onc_network
);
229 void ManagedNetworkConfigurationHandlerImpl::SetProperties(
230 const std::string
& service_path
,
231 const base::DictionaryValue
& user_settings
,
232 const base::Closure
& callback
,
233 const network_handler::ErrorCallback
& error_callback
) const {
234 const NetworkState
* state
=
235 network_state_handler_
->GetNetworkStateFromServicePath(
236 service_path
, true /* configured_only */);
238 InvokeErrorCallback(service_path
, error_callback
, kUnknownNetwork
);
242 std::string guid
= state
->guid();
244 // TODO(pneubeck): create an initial configuration in this case. As for
245 // CreateConfiguration, user settings from older ChromeOS versions have to
248 service_path
, error_callback
, kSetOnUnconfiguredNetwork
);
252 const std::string
& profile_path
= state
->profile_path();
253 const NetworkProfile
*profile
=
254 network_profile_handler_
->GetProfileForPath(profile_path
);
256 InvokeErrorCallback(service_path
, error_callback
, kUnknownProfilePath
);
260 VLOG(2) << "SetProperties: Found GUID " << guid
<< " and profile "
261 << profile
->ToDebugString();
263 const Policies
* policies
= GetPoliciesForProfile(*profile
);
265 InvokeErrorCallback(service_path
, error_callback
, kPoliciesNotInitialized
);
269 // We need to ensure that required configuration properties (e.g. Type) are
270 // included for ONC validation and translation to Shill properties.
271 scoped_ptr
<base::DictionaryValue
> user_settings_copy(
272 user_settings
.DeepCopy());
273 user_settings_copy
->SetStringWithoutPathExpansion(
274 ::onc::network_config::kType
,
275 network_util::TranslateShillTypeToONC(state
->type()));
276 user_settings_copy
->MergeDictionary(&user_settings
);
278 // Validate the ONC dictionary. We are liberal and ignore unknown field
279 // names. User settings are only partial ONC, thus we ignore missing fields.
280 onc::Validator
validator(false, // Ignore unknown fields.
281 false, // Ignore invalid recommended field names.
282 false, // Ignore missing fields.
283 false); // This ONC does not come from policy.
285 onc::Validator::Result validation_result
;
286 scoped_ptr
<base::DictionaryValue
> validated_user_settings
=
287 validator
.ValidateAndRepairObject(
288 &onc::kNetworkConfigurationSignature
,
291 if (validation_result
== onc::Validator::INVALID
) {
292 InvokeErrorCallback(service_path
, error_callback
, kInvalidUserSettings
);
295 if (validation_result
== onc::Validator::VALID_WITH_WARNINGS
)
296 LOG(WARNING
) << "Validation of ONC user settings produced warnings.";
298 // Fill in HexSSID field from contents of SSID field if not set already.
299 if (user_settings_copy
) {
300 onc::FillInHexSSIDFieldsInOncObject(onc::kNetworkConfigurationSignature
,
301 validated_user_settings
.get());
304 const base::DictionaryValue
* network_policy
=
305 GetByGUID(policies
->per_network_config
, guid
);
306 VLOG(2) << "This configuration is " << (network_policy
? "" : "not ")
309 scoped_ptr
<base::DictionaryValue
> shill_dictionary(
310 policy_util::CreateShillConfiguration(*profile
,
312 &policies
->global_network_config
,
314 validated_user_settings
.get()));
316 network_configuration_handler_
->SetProperties(
317 service_path
, *shill_dictionary
,
318 NetworkConfigurationObserver::SOURCE_USER_ACTION
, callback
,
322 void ManagedNetworkConfigurationHandlerImpl::CreateConfiguration(
323 const std::string
& userhash
,
324 const base::DictionaryValue
& properties
,
325 const network_handler::StringResultCallback
& callback
,
326 const network_handler::ErrorCallback
& error_callback
) const {
327 const Policies
* policies
= GetPoliciesForUser(userhash
);
329 InvokeErrorCallback("", error_callback
, kPoliciesNotInitialized
);
333 if (policy_util::FindMatchingPolicy(policies
->per_network_config
,
335 InvokeErrorCallback("", error_callback
, kNetworkAlreadyConfigured
);
339 const NetworkProfile
* profile
=
340 network_profile_handler_
->GetProfileForUserhash(userhash
);
342 InvokeErrorCallback("", error_callback
, kProfileNotInitialized
);
346 // TODO(pneubeck): In case of WiFi, check that no other configuration for the
347 // same {SSID, mode, security} exists. We don't support such multiple
348 // configurations, yet.
350 // Generate a new GUID for this configuration. Ignore the maybe provided GUID
351 // in |properties| as it is not our own and from an untrusted source.
352 std::string guid
= base::GenerateGUID();
353 scoped_ptr
<base::DictionaryValue
> shill_dictionary(
354 policy_util::CreateShillConfiguration(*profile
,
356 NULL
, // no global policy
357 NULL
, // no network policy
360 network_configuration_handler_
->CreateConfiguration(
361 *shill_dictionary
, NetworkConfigurationObserver::SOURCE_USER_ACTION
,
362 callback
, error_callback
);
365 void ManagedNetworkConfigurationHandlerImpl::RemoveConfiguration(
366 const std::string
& service_path
,
367 const base::Closure
& callback
,
368 const network_handler::ErrorCallback
& error_callback
) const {
369 network_configuration_handler_
->RemoveConfiguration(
370 service_path
, NetworkConfigurationObserver::SOURCE_USER_ACTION
, callback
,
374 void ManagedNetworkConfigurationHandlerImpl::SetPolicy(
375 ::onc::ONCSource onc_source
,
376 const std::string
& userhash
,
377 const base::ListValue
& network_configs_onc
,
378 const base::DictionaryValue
& global_network_config
) {
379 VLOG(1) << "Setting policies from " << ToDebugString(onc_source
, userhash
)
382 // |userhash| must be empty for device policies.
383 DCHECK(onc_source
!= ::onc::ONC_SOURCE_DEVICE_POLICY
||
385 Policies
* policies
= NULL
;
386 if (ContainsKey(policies_by_user_
, userhash
)) {
387 policies
= policies_by_user_
[userhash
].get();
389 policies
= new Policies
;
390 policies_by_user_
[userhash
] = make_linked_ptr(policies
);
393 policies
->global_network_config
.MergeDictionary(&global_network_config
);
395 GuidToPolicyMap old_per_network_config
;
396 policies
->per_network_config
.swap(old_per_network_config
);
398 // This stores all GUIDs of policies that have changed or are new.
399 std::set
<std::string
> modified_policies
;
401 for (base::ListValue::const_iterator it
= network_configs_onc
.begin();
402 it
!= network_configs_onc
.end(); ++it
) {
403 const base::DictionaryValue
* network
= NULL
;
404 (*it
)->GetAsDictionary(&network
);
408 network
->GetStringWithoutPathExpansion(::onc::network_config::kGUID
, &guid
);
409 DCHECK(!guid
.empty());
411 if (policies
->per_network_config
.count(guid
) > 0) {
412 NET_LOG_ERROR("ONC from " + ToDebugString(onc_source
, userhash
) +
413 " contains several entries for the same GUID ", guid
);
414 delete policies
->per_network_config
[guid
];
416 const base::DictionaryValue
* new_entry
= network
->DeepCopy();
417 policies
->per_network_config
[guid
] = new_entry
;
419 const base::DictionaryValue
* old_entry
= old_per_network_config
[guid
];
420 if (!old_entry
|| !old_entry
->Equals(new_entry
))
421 modified_policies
.insert(guid
);
424 STLDeleteValues(&old_per_network_config
);
425 ApplyOrQueuePolicies(userhash
, &modified_policies
);
426 FOR_EACH_OBSERVER(NetworkPolicyObserver
, observers_
,
427 PoliciesChanged(userhash
));
430 bool ManagedNetworkConfigurationHandlerImpl::IsAnyPolicyApplicationRunning()
432 return !policy_applicators_
.empty() || !queued_modified_policies_
.empty();
435 bool ManagedNetworkConfigurationHandlerImpl::ApplyOrQueuePolicies(
436 const std::string
& userhash
,
437 std::set
<std::string
>* modified_policies
) {
438 DCHECK(modified_policies
);
440 const NetworkProfile
* profile
=
441 network_profile_handler_
->GetProfileForUserhash(userhash
);
443 VLOG(1) << "The relevant Shill profile isn't initialized yet, postponing "
444 << "policy application.";
445 // OnProfileAdded will apply all policies for this userhash.
449 if (ContainsKey(policy_applicators_
, userhash
)) {
450 // A previous policy application is still running. Queue the modified
452 // Note, even if |modified_policies| is empty, this means that a policy
453 // application will be queued.
454 queued_modified_policies_
[userhash
].insert(modified_policies
->begin(),
455 modified_policies
->end());
456 VLOG(1) << "Previous PolicyApplicator still running. Postponing policy "
461 const Policies
* policies
= policies_by_user_
[userhash
].get();
464 PolicyApplicator
* applicator
=
465 new PolicyApplicator(*profile
,
466 policies
->per_network_config
,
467 policies
->global_network_config
,
470 policy_applicators_
[userhash
] = make_linked_ptr(applicator
);
475 void ManagedNetworkConfigurationHandlerImpl::OnProfileAdded(
476 const NetworkProfile
& profile
) {
477 VLOG(1) << "Adding profile " << profile
.ToDebugString() << "'.";
479 const Policies
* policies
= GetPoliciesForProfile(profile
);
481 VLOG(1) << "The relevant policy is not initialized, "
482 << "postponing policy application.";
487 std::set
<std::string
> policy_guids
;
488 for (GuidToPolicyMap::const_iterator it
=
489 policies
->per_network_config
.begin();
490 it
!= policies
->per_network_config
.end(); ++it
) {
491 policy_guids
.insert(it
->first
);
494 const bool started_policy_application
=
495 ApplyOrQueuePolicies(profile
.userhash
, &policy_guids
);
496 DCHECK(started_policy_application
);
499 void ManagedNetworkConfigurationHandlerImpl::OnProfileRemoved(
500 const NetworkProfile
& profile
) {
501 // Nothing to do in this case.
504 void ManagedNetworkConfigurationHandlerImpl::CreateConfigurationFromPolicy(
505 const base::DictionaryValue
& shill_properties
) {
506 network_configuration_handler_
->CreateConfiguration(
507 shill_properties
, NetworkConfigurationObserver::SOURCE_POLICY
,
509 &ManagedNetworkConfigurationHandlerImpl::OnPolicyAppliedToNetwork
,
510 weak_ptr_factory_
.GetWeakPtr()),
511 base::Bind(&LogErrorWithDict
, FROM_HERE
));
514 void ManagedNetworkConfigurationHandlerImpl::
515 UpdateExistingConfigurationWithPropertiesFromPolicy(
516 const base::DictionaryValue
& existing_properties
,
517 const base::DictionaryValue
& new_properties
) {
518 base::DictionaryValue shill_properties
;
521 existing_properties
.GetStringWithoutPathExpansion(shill::kProfileProperty
,
523 if (profile
.empty()) {
524 NET_LOG_ERROR("Missing profile property",
525 shill_property_util::GetNetworkIdFromProperties(
526 existing_properties
));
529 shill_properties
.SetStringWithoutPathExpansion(shill::kProfileProperty
,
532 if (!shill_property_util::CopyIdentifyingProperties(
534 true /* properties were read from Shill */,
535 &shill_properties
)) {
536 NET_LOG_ERROR("Missing identifying properties",
537 shill_property_util::GetNetworkIdFromProperties(
538 existing_properties
));
541 shill_properties
.MergeDictionary(&new_properties
);
543 network_configuration_handler_
->CreateConfiguration(
544 shill_properties
, NetworkConfigurationObserver::SOURCE_POLICY
,
546 &ManagedNetworkConfigurationHandlerImpl::OnPolicyAppliedToNetwork
,
547 weak_ptr_factory_
.GetWeakPtr()),
548 base::Bind(&LogErrorWithDict
, FROM_HERE
));
551 void ManagedNetworkConfigurationHandlerImpl::OnPoliciesApplied(
552 const NetworkProfile
& profile
) {
553 const std::string
& userhash
= profile
.userhash
;
554 VLOG(1) << "Policy application for user '" << userhash
<< "' finished.";
556 base::MessageLoop::current()->DeleteSoon(
557 FROM_HERE
, policy_applicators_
[userhash
].release());
558 policy_applicators_
.erase(userhash
);
560 if (ContainsKey(queued_modified_policies_
, userhash
)) {
561 std::set
<std::string
> modified_policies
;
562 queued_modified_policies_
[userhash
].swap(modified_policies
);
563 // Remove |userhash| from the queue.
564 queued_modified_policies_
.erase(userhash
);
565 ApplyOrQueuePolicies(userhash
, &modified_policies
);
568 NetworkPolicyObserver
, observers_
, PoliciesApplied(userhash
));
572 const base::DictionaryValue
*
573 ManagedNetworkConfigurationHandlerImpl::FindPolicyByGUID(
574 const std::string userhash
,
575 const std::string
& guid
,
576 ::onc::ONCSource
* onc_source
) const {
577 *onc_source
= ::onc::ONC_SOURCE_NONE
;
579 if (!userhash
.empty()) {
580 const Policies
* user_policies
= GetPoliciesForUser(userhash
);
582 const base::DictionaryValue
* policy
=
583 GetByGUID(user_policies
->per_network_config
, guid
);
585 *onc_source
= ::onc::ONC_SOURCE_USER_POLICY
;
591 const Policies
* device_policies
= GetPoliciesForUser(std::string());
592 if (device_policies
) {
593 const base::DictionaryValue
* policy
=
594 GetByGUID(device_policies
->per_network_config
, guid
);
596 *onc_source
= ::onc::ONC_SOURCE_DEVICE_POLICY
;
604 const GuidToPolicyMap
*
605 ManagedNetworkConfigurationHandlerImpl::GetNetworkConfigsFromPolicy(
606 const std::string
& userhash
) const {
607 const Policies
* policies
= GetPoliciesForUser(userhash
);
611 return &policies
->per_network_config
;
614 const base::DictionaryValue
*
615 ManagedNetworkConfigurationHandlerImpl::GetGlobalConfigFromPolicy(
616 const std::string
& userhash
) const {
617 const Policies
* policies
= GetPoliciesForUser(userhash
);
621 return &policies
->global_network_config
;
624 const base::DictionaryValue
*
625 ManagedNetworkConfigurationHandlerImpl::FindPolicyByGuidAndProfile(
626 const std::string
& guid
,
627 const std::string
& profile_path
) const {
628 const NetworkProfile
* profile
=
629 network_profile_handler_
->GetProfileForPath(profile_path
);
631 NET_LOG_ERROR("Profile path unknown:" + profile_path
, guid
);
635 const Policies
* policies
= GetPoliciesForProfile(*profile
);
639 return GetByGUID(policies
->per_network_config
, guid
);
642 const ManagedNetworkConfigurationHandlerImpl::Policies
*
643 ManagedNetworkConfigurationHandlerImpl::GetPoliciesForUser(
644 const std::string
& userhash
) const {
645 UserToPoliciesMap::const_iterator it
= policies_by_user_
.find(userhash
);
646 if (it
== policies_by_user_
.end())
648 return it
->second
.get();
651 const ManagedNetworkConfigurationHandlerImpl::Policies
*
652 ManagedNetworkConfigurationHandlerImpl::GetPoliciesForProfile(
653 const NetworkProfile
& profile
) const {
654 DCHECK(profile
.type() != NetworkProfile::TYPE_SHARED
||
655 profile
.userhash
.empty());
656 return GetPoliciesForUser(profile
.userhash
);
659 ManagedNetworkConfigurationHandlerImpl::ManagedNetworkConfigurationHandlerImpl()
660 : network_state_handler_(NULL
),
661 network_profile_handler_(NULL
),
662 network_configuration_handler_(NULL
),
663 network_device_handler_(NULL
),
664 weak_ptr_factory_(this) {
665 CHECK(base::MessageLoop::current());
668 ManagedNetworkConfigurationHandlerImpl::
669 ~ManagedNetworkConfigurationHandlerImpl() {
670 if (network_profile_handler_
)
671 network_profile_handler_
->RemoveObserver(this);
674 void ManagedNetworkConfigurationHandlerImpl::Init(
675 NetworkStateHandler
* network_state_handler
,
676 NetworkProfileHandler
* network_profile_handler
,
677 NetworkConfigurationHandler
* network_configuration_handler
,
678 NetworkDeviceHandler
* network_device_handler
) {
679 network_state_handler_
= network_state_handler
;
680 network_profile_handler_
= network_profile_handler
;
681 network_configuration_handler_
= network_configuration_handler
;
682 network_device_handler_
= network_device_handler
;
683 network_profile_handler_
->AddObserver(this);
686 void ManagedNetworkConfigurationHandlerImpl::OnPolicyAppliedToNetwork(
687 const std::string
& service_path
) {
688 if (service_path
.empty())
691 NetworkPolicyObserver
, observers_
, PolicyAppliedToNetwork(service_path
));
694 // Get{Managed}Properties helpers
696 void ManagedNetworkConfigurationHandlerImpl::GetDeviceStateProperties(
697 const std::string
& service_path
,
698 base::DictionaryValue
* properties
) {
699 std::string connection_state
;
700 properties
->GetStringWithoutPathExpansion(
701 shill::kStateProperty
, &connection_state
);
702 if (!NetworkState::StateIsConnected(connection_state
))
705 // Get the IPConfig properties from the device and store them in "IPConfigs"
706 // (plural) in the properties dictionary. (Note: Shill only provides a single
707 // "IPConfig" property for a network service, but a consumer of this API may
708 // want information about all ipv4 and ipv6 IPConfig properties.
710 properties
->GetStringWithoutPathExpansion(shill::kDeviceProperty
, &device
);
711 const DeviceState
* device_state
=
712 network_state_handler_
->GetDeviceState(device
);
714 NET_LOG_ERROR("GetDeviceProperties: no device: " + device
, service_path
);
718 // Get the hardware MAC address from the DeviceState.
719 if (!device_state
->mac_address().empty()) {
720 properties
->SetStringWithoutPathExpansion(
721 shill::kAddressProperty
, device_state
->mac_address());
724 // Convert IPConfig dictionary to a ListValue.
725 base::ListValue
* ip_configs
= new base::ListValue
;
726 for (base::DictionaryValue::Iterator
iter(device_state
->ip_configs());
727 !iter
.IsAtEnd(); iter
.Advance()) {
728 ip_configs
->Append(iter
.value().DeepCopy());
730 properties
->SetWithoutPathExpansion(shill::kIPConfigsProperty
, ip_configs
);
733 void ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback(
734 GetDevicePropertiesCallback send_callback
,
735 const std::string
& service_path
,
736 const base::DictionaryValue
& shill_properties
) {
737 scoped_ptr
<base::DictionaryValue
> shill_properties_copy(
738 shill_properties
.DeepCopy());
741 shill_properties
.GetStringWithoutPathExpansion(shill::kGuidProperty
, &guid
);
743 // Unmanaged networks are assigned a GUID in NetworkState. Provide this
744 // value in the ONC dictionary.
745 const NetworkState
* state
=
746 network_state_handler_
->GetNetworkState(service_path
);
747 if (state
&& !state
->guid().empty()) {
748 guid
= state
->guid();
749 shill_properties_copy
->SetStringWithoutPathExpansion(shill::kGuidProperty
,
752 LOG(ERROR
) << "Network has no GUID specified: " << service_path
;
757 shill_properties_copy
->GetStringWithoutPathExpansion(shill::kTypeProperty
,
759 // Add associated DeviceState properties for non-VPN networks.
760 if (type
!= shill::kTypeVPN
)
761 GetDeviceStateProperties(service_path
, shill_properties_copy
.get());
763 // Only request additional Device properties for Cellular networks with a
765 std::string device_path
;
766 if (!network_device_handler_
||
767 type
!= shill::kTypeCellular
||
768 !shill_properties_copy
->GetStringWithoutPathExpansion(
769 shill::kDeviceProperty
, &device_path
) ||
770 device_path
.empty()) {
771 send_callback
.Run(service_path
, shill_properties_copy
.Pass());
775 // Request the device properties. On success or failure pass (a possibly
776 // modified) |shill_properties| to |send_callback|.
777 scoped_ptr
<base::DictionaryValue
> shill_properties_copy_error_copy(
778 shill_properties_copy
->DeepCopy());
779 network_device_handler_
->GetDeviceProperties(
781 base::Bind(&ManagedNetworkConfigurationHandlerImpl::
782 GetDevicePropertiesSuccess
,
783 weak_ptr_factory_
.GetWeakPtr(),
785 base::Passed(&shill_properties_copy
),
787 base::Bind(&ManagedNetworkConfigurationHandlerImpl::
788 GetDevicePropertiesFailure
,
789 weak_ptr_factory_
.GetWeakPtr(),
791 base::Passed(&shill_properties_copy_error_copy
),
795 void ManagedNetworkConfigurationHandlerImpl::GetDevicePropertiesSuccess(
796 const std::string
& service_path
,
797 scoped_ptr
<base::DictionaryValue
> network_properties
,
798 GetDevicePropertiesCallback send_callback
,
799 const std::string
& device_path
,
800 const base::DictionaryValue
& device_properties
) {
801 // Create a "Device" dictionary in |network_properties|.
802 network_properties
->SetWithoutPathExpansion(
803 shill::kDeviceProperty
, device_properties
.DeepCopy());
804 send_callback
.Run(service_path
, network_properties
.Pass());
807 void ManagedNetworkConfigurationHandlerImpl::GetDevicePropertiesFailure(
808 const std::string
& service_path
,
809 scoped_ptr
<base::DictionaryValue
> network_properties
,
810 GetDevicePropertiesCallback send_callback
,
811 const std::string
& error_name
,
812 scoped_ptr
<base::DictionaryValue
> error_data
) {
813 NET_LOG_ERROR("Error getting device properties", service_path
);
814 send_callback
.Run(service_path
, network_properties
.Pass());
818 } // namespace chromeos