Implement ScreenOrientationDelegate on ChromeOS
[chromium-blink-merge.git] / chromeos / network / managed_network_configuration_handler_impl.cc
blobebe5d542193f61795141c4711827b82b7c960a4e
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/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 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,
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 userhash,
131 callback,
132 error_callback)),
133 error_callback);
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,
144 &profile_path);
145 const NetworkProfile* profile =
146 network_profile_handler_->GetProfileForPath(profile_path);
147 if (!profile)
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.
164 std::string guid;
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;
175 if (profile) {
176 const Policies* policies = GetPoliciesForProfile(*profile);
177 if (!policies) {
178 InvokeErrorCallback(
179 service_path, error_callback, kPoliciesNotInitialized);
180 return;
182 if (!guid.empty())
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,
189 network_policy,
190 user_settings,
191 active_settings.get(),
192 profile));
193 callback.Run(service_path, *augmented_properties);
196 // GetProperties
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(
203 service_path,
204 base::Bind(
205 &ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback,
206 weak_ptr_factory_.GetWeakPtr(),
207 base::Bind(&ManagedNetworkConfigurationHandlerImpl::SendProperties,
208 weak_ptr_factory_.GetWeakPtr(),
209 callback,
210 error_callback)),
211 error_callback);
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);
226 // SetProperties
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 */);
236 if (!state) {
237 InvokeErrorCallback(service_path, error_callback, kUnknownNetwork);
238 return;
241 std::string guid = state->guid();
242 if (guid.empty()) {
243 // TODO(pneubeck): create an initial configuration in this case. As for
244 // CreateConfiguration, user settings from older ChromeOS versions have to
245 // determined here.
246 InvokeErrorCallback(
247 service_path, error_callback, kSetOnUnconfiguredNetwork);
248 return;
251 const std::string& profile_path = state->profile_path();
252 const NetworkProfile *profile =
253 network_profile_handler_->GetProfileForPath(profile_path);
254 if (!profile) {
255 InvokeErrorCallback(service_path, error_callback, kUnknownProfilePath);
256 return;
259 VLOG(2) << "SetProperties: Found GUID " << guid << " and profile "
260 << profile->ToDebugString();
262 const Policies* policies = GetPoliciesForProfile(*profile);
263 if (!policies) {
264 InvokeErrorCallback(service_path, error_callback, kPoliciesNotInitialized);
265 return;
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,
279 user_settings,
280 &validation_result);
282 if (validation_result == onc::Validator::INVALID) {
283 InvokeErrorCallback(service_path, error_callback, kInvalidUserSettings);
284 return;
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 ")
292 << "managed.";
294 scoped_ptr<base::DictionaryValue> shill_dictionary(
295 policy_util::CreateShillConfiguration(*profile,
296 guid,
297 &policies->global_network_config,
298 network_policy,
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);
311 if (!policies) {
312 InvokeErrorCallback("", error_callback, kPoliciesNotInitialized);
313 return;
316 if (policy_util::FindMatchingPolicy(policies->per_network_config,
317 properties)) {
318 InvokeErrorCallback("", error_callback, kNetworkAlreadyConfigured);
319 return;
322 const NetworkProfile* profile =
323 network_profile_handler_->GetProfileForUserhash(userhash);
324 if (!profile) {
325 InvokeErrorCallback("", error_callback, kProfileNotInitialized);
326 return;
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,
338 guid,
339 NULL, // no global policy
340 NULL, // no network policy
341 &properties));
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)
361 << ".";
363 // |userhash| must be empty for device policies.
364 DCHECK(onc_source != ::onc::ONC_SOURCE_DEVICE_POLICY ||
365 userhash.empty());
366 Policies* policies = NULL;
367 if (ContainsKey(policies_by_user_, userhash)) {
368 policies = policies_by_user_[userhash].get();
369 } else {
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);
386 DCHECK(network);
388 std::string guid;
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()
412 const {
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);
423 if (!profile) {
424 VLOG(1) << "The relevant Shill profile isn't initialized yet, postponing "
425 << "policy application.";
426 // OnProfileAdded will apply all policies for this userhash.
427 return false;
430 if (ContainsKey(policy_applicators_, userhash)) {
431 // A previous policy application is still running. Queue the modified
432 // policies.
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 "
438 "application.";
439 return false;
442 const Policies* policies = policies_by_user_[userhash].get();
443 DCHECK(policies);
445 PolicyApplicator* applicator =
446 new PolicyApplicator(*profile,
447 policies->per_network_config,
448 policies->global_network_config,
449 this,
450 modified_policies);
451 policy_applicators_[userhash] = make_linked_ptr(applicator);
452 applicator->Run();
453 return true;
456 void ManagedNetworkConfigurationHandlerImpl::OnProfileAdded(
457 const NetworkProfile& profile) {
458 VLOG(1) << "Adding profile " << profile.ToDebugString() << "'.";
460 const Policies* policies = GetPoliciesForProfile(profile);
461 if (!policies) {
462 VLOG(1) << "The relevant policy is not initialized, "
463 << "postponing policy application.";
464 // See SetPolicy.
465 return;
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(
488 shill_properties,
489 base::Bind(
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;
501 std::string profile;
502 existing_properties.GetStringWithoutPathExpansion(shill::kProfileProperty,
503 &profile);
504 if (profile.empty()) {
505 NET_LOG_ERROR("Missing profile property",
506 shill_property_util::GetNetworkIdFromProperties(
507 existing_properties));
508 return;
510 shill_properties.SetStringWithoutPathExpansion(shill::kProfileProperty,
511 profile);
513 if (!shill_property_util::CopyIdentifyingProperties(
514 existing_properties,
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(
525 shill_properties,
526 base::Bind(
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);
547 } else {
548 FOR_EACH_OBSERVER(
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);
562 if (user_policies) {
563 const base::DictionaryValue* policy =
564 GetByGUID(user_policies->per_network_config, guid);
565 if (policy) {
566 *onc_source = ::onc::ONC_SOURCE_USER_POLICY;
567 return 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);
576 if (policy) {
577 *onc_source = ::onc::ONC_SOURCE_DEVICE_POLICY;
578 return policy;
582 return NULL;
585 const GuidToPolicyMap*
586 ManagedNetworkConfigurationHandlerImpl::GetNetworkConfigsFromPolicy(
587 const std::string& userhash) const {
588 const Policies* policies = GetPoliciesForUser(userhash);
589 if (!policies)
590 return NULL;
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);
599 if (!policies)
600 return NULL;
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);
611 if (!profile) {
612 NET_LOG_ERROR("Profile path unknown:" + profile_path, guid);
613 return NULL;
616 const Policies* policies = GetPoliciesForProfile(*profile);
617 if (!policies)
618 return NULL;
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())
628 return NULL;
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())
669 return;
670 FOR_EACH_OBSERVER(
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))
683 return;
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.
689 std::string device;
690 properties->GetStringWithoutPathExpansion(shill::kDeviceProperty, &device);
691 const DeviceState* device_state =
692 network_state_handler_->GetDeviceState(device);
693 if (!device_state) {
694 NET_LOG_ERROR("GetDeviceProperties: no device: " + device, service_path);
695 return;
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());
733 return;
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(
741 device_path,
742 base::Bind(&ManagedNetworkConfigurationHandlerImpl::
743 GetDevicePropertiesSuccess,
744 weak_ptr_factory_.GetWeakPtr(),
745 service_path,
746 base::Passed(&shill_properties_copy),
747 send_callback),
748 base::Bind(&ManagedNetworkConfigurationHandlerImpl::
749 GetDevicePropertiesFailure,
750 weak_ptr_factory_.GetWeakPtr(),
751 service_path,
752 base::Passed(&shill_properties_copy_error_copy),
753 send_callback));
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