Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(687)

Side by Side Diff: chromeos/network/managed_network_configuration_handler.cc

Issue 14729017: Add NetworkHandler to own network handlers in src/chromeos/network (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase + elim LoginState dependency Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chromeos/network/managed_network_configuration_handler.h" 5 #include "chromeos/network/managed_network_configuration_handler.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 const base::DictionaryValue& shill_properties) { 287 const base::DictionaryValue& shill_properties) {
288 scoped_ptr<base::DictionaryValue> onc_network( 288 scoped_ptr<base::DictionaryValue> onc_network(
289 onc::TranslateShillServiceToONCPart( 289 onc::TranslateShillServiceToONCPart(
290 shill_properties, 290 shill_properties,
291 &onc::kNetworkWithStateSignature)); 291 &onc::kNetworkWithStateSignature));
292 callback.Run(service_path, *onc_network); 292 callback.Run(service_path, *onc_network);
293 } 293 }
294 294
295 } // namespace 295 } // namespace
296 296
297 static ManagedNetworkConfigurationHandler*
298 g_configuration_handler_instance = NULL;
299
300 // static
301 void ManagedNetworkConfigurationHandler::Initialize(
302 NetworkProfileHandler* profile_handler) {
303 CHECK(!g_configuration_handler_instance);
304 g_configuration_handler_instance =
305 new ManagedNetworkConfigurationHandler(profile_handler);
306 }
307
308 // static
309 bool ManagedNetworkConfigurationHandler::IsInitialized() {
310 return g_configuration_handler_instance;
311 }
312
313 // static
314 void ManagedNetworkConfigurationHandler::Shutdown() {
315 CHECK(g_configuration_handler_instance);
316 delete g_configuration_handler_instance;
317 g_configuration_handler_instance = NULL;
318 }
319
320 // static
321 ManagedNetworkConfigurationHandler* ManagedNetworkConfigurationHandler::Get() {
322 CHECK(g_configuration_handler_instance);
323 return g_configuration_handler_instance;
324 }
325 297
326 // static 298 // static
327 scoped_ptr<NetworkUIData> ManagedNetworkConfigurationHandler::GetUIData( 299 scoped_ptr<NetworkUIData> ManagedNetworkConfigurationHandler::GetUIData(
328 const base::DictionaryValue& shill_dictionary) { 300 const base::DictionaryValue& shill_dictionary) {
329 std::string ui_data_blob; 301 std::string ui_data_blob;
330 if (shill_dictionary.GetStringWithoutPathExpansion( 302 if (shill_dictionary.GetStringWithoutPathExpansion(
331 flimflam::kUIDataProperty, 303 flimflam::kUIDataProperty,
332 &ui_data_blob) && 304 &ui_data_blob) &&
333 !ui_data_blob.empty()) { 305 !ui_data_blob.empty()) {
334 scoped_ptr<base::DictionaryValue> ui_data_dict = 306 scoped_ptr<base::DictionaryValue> ui_data_dict =
(...skipping 12 matching lines...) Expand all
347 const std::string& service_path, 319 const std::string& service_path,
348 const network_handler::DictionaryResultCallback& callback, 320 const network_handler::DictionaryResultCallback& callback,
349 const network_handler::ErrorCallback& error_callback) { 321 const network_handler::ErrorCallback& error_callback) {
350 if (!GetPoliciesForUser(userhash) || !GetPoliciesForUser(std::string())) { 322 if (!GetPoliciesForUser(userhash) || !GetPoliciesForUser(std::string())) {
351 RunErrorCallback(service_path, 323 RunErrorCallback(service_path,
352 kPoliciesNotInitialized, 324 kPoliciesNotInitialized,
353 kPoliciesNotInitializedMessage, 325 kPoliciesNotInitializedMessage,
354 error_callback); 326 error_callback);
355 return; 327 return;
356 } 328 }
357 NetworkConfigurationHandler::Get()->GetProperties( 329 network_configuration_handler_->GetProperties(
358 service_path, 330 service_path,
359 base::Bind( 331 base::Bind(
360 &ManagedNetworkConfigurationHandler::GetManagedPropertiesCallback, 332 &ManagedNetworkConfigurationHandler::GetManagedPropertiesCallback,
361 weak_ptr_factory_.GetWeakPtr(), 333 weak_ptr_factory_.GetWeakPtr(),
362 callback, 334 callback,
363 error_callback), 335 error_callback),
364 error_callback); 336 error_callback);
365 } 337 }
366 338
367 void ManagedNetworkConfigurationHandler::GetManagedPropertiesCallback( 339 void ManagedNetworkConfigurationHandler::GetManagedPropertiesCallback(
368 const network_handler::DictionaryResultCallback& callback, 340 const network_handler::DictionaryResultCallback& callback,
369 const network_handler::ErrorCallback& error_callback, 341 const network_handler::ErrorCallback& error_callback,
370 const std::string& service_path, 342 const std::string& service_path,
371 const base::DictionaryValue& shill_properties) { 343 const base::DictionaryValue& shill_properties) {
372 std::string profile_path; 344 std::string profile_path;
373 shill_properties.GetStringWithoutPathExpansion(flimflam::kProfileProperty, 345 shill_properties.GetStringWithoutPathExpansion(flimflam::kProfileProperty,
374 &profile_path); 346 &profile_path);
375 const NetworkProfile* profile = 347 const NetworkProfile* profile =
376 profile_handler_->GetProfileForPath(profile_path); 348 network_profile_handler_->GetProfileForPath(profile_path);
377 if (!profile) { 349 if (!profile) {
378 VLOG(1) << "No or no known profile received for service " 350 VLOG(1) << "No or no known profile received for service "
379 << service_path << "."; 351 << service_path << ".";
380 } 352 }
381 353
382 scoped_ptr<NetworkUIData> ui_data = GetUIData(shill_properties); 354 scoped_ptr<NetworkUIData> ui_data = GetUIData(shill_properties);
383 355
384 const base::DictionaryValue* user_settings = NULL; 356 const base::DictionaryValue* user_settings = NULL;
385 const base::DictionaryValue* shared_settings = NULL; 357 const base::DictionaryValue* shared_settings = NULL;
386 358
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 user_settings, 409 user_settings,
438 shared_settings, 410 shared_settings,
439 active_settings.get()); 411 active_settings.get());
440 callback.Run(service_path, *augmented_properties); 412 callback.Run(service_path, *augmented_properties);
441 } 413 }
442 414
443 void ManagedNetworkConfigurationHandler::GetProperties( 415 void ManagedNetworkConfigurationHandler::GetProperties(
444 const std::string& service_path, 416 const std::string& service_path,
445 const network_handler::DictionaryResultCallback& callback, 417 const network_handler::DictionaryResultCallback& callback,
446 const network_handler::ErrorCallback& error_callback) const { 418 const network_handler::ErrorCallback& error_callback) const {
447 NetworkConfigurationHandler::Get()->GetProperties( 419 network_configuration_handler_->GetProperties(
448 service_path, 420 service_path,
449 base::Bind(&TranslatePropertiesToOncAndRunCallback, callback), 421 base::Bind(&TranslatePropertiesToOncAndRunCallback, callback),
450 error_callback); 422 error_callback);
451 } 423 }
452 424
453 void ManagedNetworkConfigurationHandler::SetProperties( 425 void ManagedNetworkConfigurationHandler::SetProperties(
454 const std::string& service_path, 426 const std::string& service_path,
455 const base::DictionaryValue& user_settings, 427 const base::DictionaryValue& user_settings,
456 const base::Closure& callback, 428 const base::Closure& callback,
457 const network_handler::ErrorCallback& error_callback) const { 429 const network_handler::ErrorCallback& error_callback) const {
458 const NetworkState* state = 430 const NetworkState* state =
459 NetworkStateHandler::Get()->GetNetworkState(service_path); 431 network_state_handler_->GetNetworkState(service_path);
460 432
461 if (!state) { 433 if (!state) {
462 RunErrorCallback(service_path, 434 RunErrorCallback(service_path,
463 kUnknownServicePath, 435 kUnknownServicePath,
464 kUnknownServicePathMessage, 436 kUnknownServicePathMessage,
465 error_callback); 437 error_callback);
466 return; 438 return;
467 } 439 }
468 440
469 std::string guid = state->guid(); 441 std::string guid = state->guid();
470 if (guid.empty()) { 442 if (guid.empty()) {
471 // TODO(pneubeck): create an initial configuration in this case. As for 443 // TODO(pneubeck): create an initial configuration in this case. As for
472 // CreateConfiguration, user settings from older ChromeOS versions have to 444 // CreateConfiguration, user settings from older ChromeOS versions have to
473 // determined here. 445 // determined here.
474 RunErrorCallback(service_path, 446 RunErrorCallback(service_path,
475 kSetOnUnconfiguredNetwork, 447 kSetOnUnconfiguredNetwork,
476 kSetOnUnconfiguredNetworkMessage, 448 kSetOnUnconfiguredNetworkMessage,
477 error_callback); 449 error_callback);
478 return; 450 return;
479 } 451 }
480 452
481 const std::string& profile_path = state->profile_path(); 453 const std::string& profile_path = state->profile_path();
482 const NetworkProfile *profile = 454 const NetworkProfile *profile =
483 profile_handler_->GetProfileForPath(profile_path); 455 network_profile_handler_->GetProfileForPath(profile_path);
484 if (!profile) { 456 if (!profile) {
485 RunErrorCallback(service_path, 457 RunErrorCallback(service_path,
486 kUnknownProfilePath, 458 kUnknownProfilePath,
487 kUnknownProfilePathMessage, 459 kUnknownProfilePathMessage,
488 error_callback); 460 error_callback);
489 return; 461 return;
490 } 462 }
491 463
492 VLOG(2) << "SetProperties: Found GUID " << guid << " and profile " 464 VLOG(2) << "SetProperties: Found GUID " << guid << " and profile "
493 << profile->ToDebugString(); 465 << profile->ToDebugString();
(...skipping 30 matching lines...) Expand all
524 } 496 }
525 if (validation_result == onc::Validator::VALID_WITH_WARNINGS) 497 if (validation_result == onc::Validator::VALID_WITH_WARNINGS)
526 LOG(WARNING) << "Validation of ONC user settings produced warnings."; 498 LOG(WARNING) << "Validation of ONC user settings produced warnings.";
527 499
528 const base::DictionaryValue* policy = GetByGUID(*policies, guid); 500 const base::DictionaryValue* policy = GetByGUID(*policies, guid);
529 VLOG(2) << "This configuration is " << (policy ? "" : "not ") << "managed."; 501 VLOG(2) << "This configuration is " << (policy ? "" : "not ") << "managed.";
530 502
531 scoped_ptr<base::DictionaryValue> shill_dictionary( 503 scoped_ptr<base::DictionaryValue> shill_dictionary(
532 CreateShillConfiguration(*profile, guid, policy, &user_settings)); 504 CreateShillConfiguration(*profile, guid, policy, &user_settings));
533 505
534 NetworkConfigurationHandler::Get()->SetProperties(service_path, 506 network_configuration_handler_->SetProperties(
535 *shill_dictionary, 507 service_path, *shill_dictionary, callback, error_callback);
536 callback,
537 error_callback);
538 } 508 }
539 509
540 void ManagedNetworkConfigurationHandler::CreateConfiguration( 510 void ManagedNetworkConfigurationHandler::CreateConfiguration(
541 const std::string& userhash, 511 const std::string& userhash,
542 const base::DictionaryValue& properties, 512 const base::DictionaryValue& properties,
543 const network_handler::StringResultCallback& callback, 513 const network_handler::StringResultCallback& callback,
544 const network_handler::ErrorCallback& error_callback) const { 514 const network_handler::ErrorCallback& error_callback) const {
545 const GuidToPolicyMap* policies = GetPoliciesForUser(userhash); 515 const GuidToPolicyMap* policies = GetPoliciesForUser(userhash);
546 if (!policies) { 516 if (!policies) {
547 RunErrorCallback("", 517 RunErrorCallback("",
548 kPoliciesNotInitialized, 518 kPoliciesNotInitialized,
549 kPoliciesNotInitializedMessage, 519 kPoliciesNotInitializedMessage,
550 error_callback); 520 error_callback);
551 return; 521 return;
552 } 522 }
553 523
554 if (FindMatchingPolicy(*policies, properties)) { 524 if (FindMatchingPolicy(*policies, properties)) {
555 RunErrorCallback("", 525 RunErrorCallback("",
556 kNetworkAlreadyConfigured, 526 kNetworkAlreadyConfigured,
557 kNetworkAlreadyConfiguredMessage, 527 kNetworkAlreadyConfiguredMessage,
558 error_callback); 528 error_callback);
559 } 529 }
560 530
561 const NetworkProfile* profile = 531 const NetworkProfile* profile =
562 profile_handler_->GetProfileForUserhash(userhash); 532 network_profile_handler_->GetProfileForUserhash(userhash);
563 if (!profile) { 533 if (!profile) {
564 RunErrorCallback("", 534 RunErrorCallback("",
565 kProfileNotInitialized, 535 kProfileNotInitialized,
566 kProfileNotInitializedMessage, 536 kProfileNotInitializedMessage,
567 error_callback); 537 error_callback);
568 } 538 }
569 539
570 // TODO(pneubeck): In case of WiFi, check that no other configuration for the 540 // TODO(pneubeck): In case of WiFi, check that no other configuration for the
571 // same {SSID, mode, security} exists. We don't support such multiple 541 // same {SSID, mode, security} exists. We don't support such multiple
572 // configurations, yet. 542 // configurations, yet.
573 543
574 // Generate a new GUID for this configuration. Ignore the maybe provided GUID 544 // Generate a new GUID for this configuration. Ignore the maybe provided GUID
575 // in |properties| as it is not our own and from an untrusted source. 545 // in |properties| as it is not our own and from an untrusted source.
576 std::string guid = base::GenerateGUID(); 546 std::string guid = base::GenerateGUID();
577 scoped_ptr<base::DictionaryValue> shill_dictionary( 547 scoped_ptr<base::DictionaryValue> shill_dictionary(
578 CreateShillConfiguration(*profile, guid, NULL /*no policy*/, 548 CreateShillConfiguration(*profile, guid, NULL /*no policy*/,
579 &properties)); 549 &properties));
580 550
581 NetworkConfigurationHandler::Get()->CreateConfiguration(*shill_dictionary, 551 network_configuration_handler_->CreateConfiguration(
582 callback, 552 *shill_dictionary, callback, error_callback);
583 error_callback);
584 } 553 }
585 554
586 void ManagedNetworkConfigurationHandler::RemoveConfiguration( 555 void ManagedNetworkConfigurationHandler::RemoveConfiguration(
587 const std::string& service_path, 556 const std::string& service_path,
588 const base::Closure& callback, 557 const base::Closure& callback,
589 const network_handler::ErrorCallback& error_callback) const { 558 const network_handler::ErrorCallback& error_callback) const {
590 NetworkConfigurationHandler::Get()->RemoveConfiguration(service_path, 559 network_configuration_handler_->RemoveConfiguration(
591 callback, 560 service_path, callback, error_callback);
592 error_callback);
593 } 561 }
594 562
595 // This class compares (entry point is Run()) |modified_policies| with the 563 // This class compares (entry point is Run()) |modified_policies| with the
596 // existing entries in the provided Shill profile |profile|. It fetches all 564 // existing entries in the provided Shill profile |profile|. It fetches all
597 // entries in parallel (GetProfileProperties), compares each entry with the 565 // entries in parallel (GetProfileProperties), compares each entry with the
598 // current policies (GetEntry) and adds all missing policies 566 // current policies (GetEntry) and adds all missing policies
599 // (~PolicyApplicator). 567 // (~PolicyApplicator).
600 class ManagedNetworkConfigurationHandler::PolicyApplicator 568 class ManagedNetworkConfigurationHandler::PolicyApplicator
601 : public base::RefCounted<PolicyApplicator> { 569 : public base::RefCounted<PolicyApplicator> {
602 public: 570 public:
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 } else { 697 } else {
730 VLOG_IF(1, old_guid == new_guid) 698 VLOG_IF(1, old_guid == new_guid)
731 << "Updating previously managed configuration with the updated " 699 << "Updating previously managed configuration with the updated "
732 << "policy " << new_guid << "."; 700 << "policy " << new_guid << ".";
733 701
734 // Update the existing configuration with the maybe changed 702 // Update the existing configuration with the maybe changed
735 // policy. Thereby the GUID might change. 703 // policy. Thereby the GUID might change.
736 scoped_ptr<base::DictionaryValue> shill_dictionary = 704 scoped_ptr<base::DictionaryValue> shill_dictionary =
737 CreateShillConfiguration(profile_, new_guid, new_policy, 705 CreateShillConfiguration(profile_, new_guid, new_policy,
738 ui_data->user_settings()); 706 ui_data->user_settings());
739 NetworkConfigurationHandler::Get()->CreateConfiguration( 707 handler_->network_configuration_handler()->
740 *shill_dictionary, 708 CreateConfiguration(*shill_dictionary,
741 base::Bind(&IgnoreString), 709 base::Bind(&IgnoreString),
742 base::Bind(&LogErrorWithDict, FROM_HERE)); 710 base::Bind(&LogErrorWithDict, FROM_HERE));
743 remaining_policies_.erase(new_guid); 711 remaining_policies_.erase(new_guid);
744 } 712 }
745 } else if (was_managed) { 713 } else if (was_managed) {
746 VLOG(1) << "Removing configuration previously managed by policy " 714 VLOG(1) << "Removing configuration previously managed by policy "
747 << old_guid << ", because the policy was removed."; 715 << old_guid << ", because the policy was removed.";
748 716
749 // Remove the entry, because the network was managed but isn't anymore. 717 // Remove the entry, because the network was managed but isn't anymore.
750 // Note: An alternative might be to preserve the user settings, but it's 718 // Note: An alternative might be to preserve the user settings, but it's
751 // unclear which values originating the policy should be removed. 719 // unclear which values originating the policy should be removed.
752 DeleteEntry(entry); 720 DeleteEntry(entry);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 LOG(ERROR) << "Policy " << *it << " doesn't exist anymore."; 762 LOG(ERROR) << "Policy " << *it << " doesn't exist anymore.";
795 continue; 763 continue;
796 } 764 }
797 765
798 VLOG(1) << "Creating new configuration managed by policy " << *it 766 VLOG(1) << "Creating new configuration managed by policy " << *it
799 << " in profile " << profile_.ToDebugString() << "."; 767 << " in profile " << profile_.ToDebugString() << ".";
800 768
801 scoped_ptr<base::DictionaryValue> shill_dictionary = 769 scoped_ptr<base::DictionaryValue> shill_dictionary =
802 CreateShillConfiguration(profile_, *it, policy, 770 CreateShillConfiguration(profile_, *it, policy,
803 NULL /* no user settings */); 771 NULL /* no user settings */);
804 NetworkConfigurationHandler::Get()->CreateConfiguration( 772 handler_->network_configuration_handler()->CreateConfiguration(
805 *shill_dictionary, 773 *shill_dictionary,
806 base::Bind(&IgnoreString), 774 base::Bind(&IgnoreString),
807 base::Bind(&LogErrorWithDict, FROM_HERE)); 775 base::Bind(&LogErrorWithDict, FROM_HERE));
808 } 776 }
809 } 777 }
810 778
811 std::set<std::string> remaining_policies_; 779 std::set<std::string> remaining_policies_;
812 base::WeakPtr<ManagedNetworkConfigurationHandler> handler_; 780 base::WeakPtr<ManagedNetworkConfigurationHandler> handler_;
813 NetworkProfile profile_; 781 NetworkProfile profile_;
814 782
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 policies[guid] = new_entry; 821 policies[guid] = new_entry;
854 822
855 const base::DictionaryValue* old_entry = old_policies[guid]; 823 const base::DictionaryValue* old_entry = old_policies[guid];
856 if (!old_entry || !old_entry->Equals(new_entry)) 824 if (!old_entry || !old_entry->Equals(new_entry))
857 modified_policies.insert(guid); 825 modified_policies.insert(guid);
858 } 826 }
859 827
860 STLDeleteValues(&old_policies); 828 STLDeleteValues(&old_policies);
861 829
862 const NetworkProfile* profile = 830 const NetworkProfile* profile =
863 profile_handler_->GetProfileForUserhash(userhash); 831 network_profile_handler_->GetProfileForUserhash(userhash);
864 if (!profile) { 832 if (!profile) {
865 VLOG(1) << "The relevant Shill profile isn't initialized yet, postponing " 833 VLOG(1) << "The relevant Shill profile isn't initialized yet, postponing "
866 << "policy application."; 834 << "policy application.";
867 return; 835 return;
868 } 836 }
869 837
870 scoped_refptr<PolicyApplicator> applicator = new PolicyApplicator( 838 scoped_refptr<PolicyApplicator> applicator = new PolicyApplicator(
871 weak_ptr_factory_.GetWeakPtr(), 839 weak_ptr_factory_.GetWeakPtr(),
872 *profile, 840 *profile,
873 &modified_policies); 841 &modified_policies);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 } 881 }
914 882
915 const ManagedNetworkConfigurationHandler::GuidToPolicyMap* 883 const ManagedNetworkConfigurationHandler::GuidToPolicyMap*
916 ManagedNetworkConfigurationHandler::GetPoliciesForProfile( 884 ManagedNetworkConfigurationHandler::GetPoliciesForProfile(
917 const NetworkProfile& profile) const { 885 const NetworkProfile& profile) const {
918 DCHECK(profile.type() != NetworkProfile::TYPE_SHARED || 886 DCHECK(profile.type() != NetworkProfile::TYPE_SHARED ||
919 profile.userhash.empty()); 887 profile.userhash.empty());
920 return GetPoliciesForUser(profile.userhash); 888 return GetPoliciesForUser(profile.userhash);
921 } 889 }
922 890
923 ManagedNetworkConfigurationHandler::ManagedNetworkConfigurationHandler( 891 ManagedNetworkConfigurationHandler::ManagedNetworkConfigurationHandler()
924 NetworkProfileHandler* profile_handler) 892 : network_state_handler_(NULL),
925 : profile_handler_(profile_handler), 893 network_profile_handler_(NULL),
894 network_configuration_handler_(NULL),
926 weak_ptr_factory_(this) { 895 weak_ptr_factory_(this) {
927 profile_handler_->AddObserver(this);
928 } 896 }
929 897
930 ManagedNetworkConfigurationHandler::~ManagedNetworkConfigurationHandler() { 898 ManagedNetworkConfigurationHandler::~ManagedNetworkConfigurationHandler() {
931 profile_handler_->RemoveObserver(this); 899 network_profile_handler_->RemoveObserver(this);
932 for (UserToPoliciesMap::iterator it = policies_by_user_.begin(); 900 for (UserToPoliciesMap::iterator it = policies_by_user_.begin();
933 it != policies_by_user_.end(); ++it) { 901 it != policies_by_user_.end(); ++it) {
934 STLDeleteValues(&it->second); 902 STLDeleteValues(&it->second);
935 } 903 }
936 } 904 }
937 905
906 void ManagedNetworkConfigurationHandler::Init(
907 NetworkStateHandler* network_state_handler,
908 NetworkProfileHandler* network_profile_handler,
909 NetworkConfigurationHandler* network_configuration_handler) {
910 network_state_handler_ = network_state_handler;
911 network_profile_handler_ = network_profile_handler;
912 network_configuration_handler_ = network_configuration_handler;
913 network_profile_handler_->AddObserver(this);
914 }
915
938 } // namespace chromeos 916 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698