[Telemetry] Rename test methods in page_test_results_unittest to follow existing...
[chromium-blink-merge.git] / chromeos / network / managed_network_configuration_handler_impl.cc
blobbe67c522d1f869fa55fdf5f039b1c7374e91d25a
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/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"
42 namespace chromeos {
44 namespace {
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())
85 return NULL;
86 return it->second;
89 } // namespace
91 struct ManagedNetworkConfigurationHandlerImpl::Policies {
92 ~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);
121 return;
123 network_configuration_handler_->GetProperties(
124 service_path,
125 base::Bind(
126 &ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback,
127 weak_ptr_factory_.GetWeakPtr(),
128 base::Bind(
129 &ManagedNetworkConfigurationHandlerImpl::SendManagedProperties,
130 weak_ptr_factory_.GetWeakPtr(),
131 userhash,
132 callback,
133 error_callback)),
134 error_callback);
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,
145 &profile_path);
146 const NetworkProfile* profile =
147 network_profile_handler_->GetProfileForPath(profile_path);
148 if (!profile)
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.
165 std::string guid;
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;
176 if (profile) {
177 const Policies* policies = GetPoliciesForProfile(*profile);
178 if (!policies) {
179 InvokeErrorCallback(
180 service_path, error_callback, kPoliciesNotInitialized);
181 return;
183 if (!guid.empty())
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,
190 network_policy,
191 user_settings,
192 active_settings.get(),
193 profile));
194 callback.Run(service_path, *augmented_properties);
197 // GetProperties
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(
204 service_path,
205 base::Bind(
206 &ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback,
207 weak_ptr_factory_.GetWeakPtr(),
208 base::Bind(&ManagedNetworkConfigurationHandlerImpl::SendProperties,
209 weak_ptr_factory_.GetWeakPtr(),
210 callback,
211 error_callback)),
212 error_callback);
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);
227 // SetProperties
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 */);
237 if (!state) {
238 InvokeErrorCallback(service_path, error_callback, kUnknownNetwork);
239 return;
242 std::string guid = state->guid();
243 if (guid.empty()) {
244 // TODO(pneubeck): create an initial configuration in this case. As for
245 // CreateConfiguration, user settings from older ChromeOS versions have to
246 // determined here.
247 InvokeErrorCallback(
248 service_path, error_callback, kSetOnUnconfiguredNetwork);
249 return;
252 const std::string& profile_path = state->profile_path();
253 const NetworkProfile *profile =
254 network_profile_handler_->GetProfileForPath(profile_path);
255 if (!profile) {
256 InvokeErrorCallback(service_path, error_callback, kUnknownProfilePath);
257 return;
260 VLOG(2) << "SetProperties: Found GUID " << guid << " and profile "
261 << profile->ToDebugString();
263 const Policies* policies = GetPoliciesForProfile(*profile);
264 if (!policies) {
265 InvokeErrorCallback(service_path, error_callback, kPoliciesNotInitialized);
266 return;
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,
289 *user_settings_copy,
290 &validation_result);
291 if (validation_result == onc::Validator::INVALID) {
292 InvokeErrorCallback(service_path, error_callback, kInvalidUserSettings);
293 return;
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 ")
307 << "managed.";
309 scoped_ptr<base::DictionaryValue> shill_dictionary(
310 policy_util::CreateShillConfiguration(*profile,
311 guid,
312 &policies->global_network_config,
313 network_policy,
314 validated_user_settings.get()));
316 network_configuration_handler_->SetProperties(
317 service_path, *shill_dictionary,
318 NetworkConfigurationObserver::SOURCE_USER_ACTION, callback,
319 error_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);
328 if (!policies) {
329 InvokeErrorCallback("", error_callback, kPoliciesNotInitialized);
330 return;
333 if (policy_util::FindMatchingPolicy(policies->per_network_config,
334 properties)) {
335 InvokeErrorCallback("", error_callback, kNetworkAlreadyConfigured);
336 return;
339 const NetworkProfile* profile =
340 network_profile_handler_->GetProfileForUserhash(userhash);
341 if (!profile) {
342 InvokeErrorCallback("", error_callback, kProfileNotInitialized);
343 return;
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,
355 guid,
356 NULL, // no global policy
357 NULL, // no network policy
358 &properties));
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,
371 error_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)
380 << ".";
382 // |userhash| must be empty for device policies.
383 DCHECK(onc_source != ::onc::ONC_SOURCE_DEVICE_POLICY ||
384 userhash.empty());
385 Policies* policies = NULL;
386 if (ContainsKey(policies_by_user_, userhash)) {
387 policies = policies_by_user_[userhash].get();
388 } else {
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);
405 DCHECK(network);
407 std::string guid;
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()
431 const {
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);
442 if (!profile) {
443 VLOG(1) << "The relevant Shill profile isn't initialized yet, postponing "
444 << "policy application.";
445 // OnProfileAdded will apply all policies for this userhash.
446 return false;
449 if (ContainsKey(policy_applicators_, userhash)) {
450 // A previous policy application is still running. Queue the modified
451 // policies.
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 "
457 "application.";
458 return false;
461 const Policies* policies = policies_by_user_[userhash].get();
462 DCHECK(policies);
464 PolicyApplicator* applicator =
465 new PolicyApplicator(*profile,
466 policies->per_network_config,
467 policies->global_network_config,
468 this,
469 modified_policies);
470 policy_applicators_[userhash] = make_linked_ptr(applicator);
471 applicator->Run();
472 return true;
475 void ManagedNetworkConfigurationHandlerImpl::OnProfileAdded(
476 const NetworkProfile& profile) {
477 VLOG(1) << "Adding profile " << profile.ToDebugString() << "'.";
479 const Policies* policies = GetPoliciesForProfile(profile);
480 if (!policies) {
481 VLOG(1) << "The relevant policy is not initialized, "
482 << "postponing policy application.";
483 // See SetPolicy.
484 return;
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,
508 base::Bind(
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;
520 std::string profile;
521 existing_properties.GetStringWithoutPathExpansion(shill::kProfileProperty,
522 &profile);
523 if (profile.empty()) {
524 NET_LOG_ERROR("Missing profile property",
525 shill_property_util::GetNetworkIdFromProperties(
526 existing_properties));
527 return;
529 shill_properties.SetStringWithoutPathExpansion(shill::kProfileProperty,
530 profile);
532 if (!shill_property_util::CopyIdentifyingProperties(
533 existing_properties,
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,
545 base::Bind(
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);
566 } else {
567 FOR_EACH_OBSERVER(
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);
581 if (user_policies) {
582 const base::DictionaryValue* policy =
583 GetByGUID(user_policies->per_network_config, guid);
584 if (policy) {
585 *onc_source = ::onc::ONC_SOURCE_USER_POLICY;
586 return 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);
595 if (policy) {
596 *onc_source = ::onc::ONC_SOURCE_DEVICE_POLICY;
597 return policy;
601 return NULL;
604 const GuidToPolicyMap*
605 ManagedNetworkConfigurationHandlerImpl::GetNetworkConfigsFromPolicy(
606 const std::string& userhash) const {
607 const Policies* policies = GetPoliciesForUser(userhash);
608 if (!policies)
609 return NULL;
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);
618 if (!policies)
619 return NULL;
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);
630 if (!profile) {
631 NET_LOG_ERROR("Profile path unknown:" + profile_path, guid);
632 return NULL;
635 const Policies* policies = GetPoliciesForProfile(*profile);
636 if (!policies)
637 return NULL;
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())
647 return NULL;
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())
689 return;
690 FOR_EACH_OBSERVER(
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))
703 return;
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.
709 std::string device;
710 properties->GetStringWithoutPathExpansion(shill::kDeviceProperty, &device);
711 const DeviceState* device_state =
712 network_state_handler_->GetDeviceState(device);
713 if (!device_state) {
714 NET_LOG_ERROR("GetDeviceProperties: no device: " + device, service_path);
715 return;
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());
740 std::string guid;
741 shill_properties.GetStringWithoutPathExpansion(shill::kGuidProperty, &guid);
742 if (guid.empty()) {
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,
750 guid);
751 } else {
752 LOG(ERROR) << "Network has no GUID specified: " << service_path;
756 std::string type;
757 shill_properties_copy->GetStringWithoutPathExpansion(shill::kTypeProperty,
758 &type);
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
764 // valid device.
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());
772 return;
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(
780 device_path,
781 base::Bind(&ManagedNetworkConfigurationHandlerImpl::
782 GetDevicePropertiesSuccess,
783 weak_ptr_factory_.GetWeakPtr(),
784 service_path,
785 base::Passed(&shill_properties_copy),
786 send_callback),
787 base::Bind(&ManagedNetworkConfigurationHandlerImpl::
788 GetDevicePropertiesFailure,
789 weak_ptr_factory_.GetWeakPtr(),
790 service_path,
791 base::Passed(&shill_properties_copy_error_copy),
792 send_callback));
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