network_profile_handler.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chromeos/network/network_profile_handler.h" 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <algorithm> 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/bind.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/string_util.h" 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/values.h" 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h" 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chromeos/dbus/shill_manager_client.h" 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chromeos/dbus/shill_profile_client.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chromeos/network/network_profile_observer.h" 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "dbus/object_path.h" 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace chromeos { 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace { 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ConvertListValueToStringVector(const base::ListValue& string_list, 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::vector<std::string>* result) { 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t i = 0; i < string_list.GetSize(); ++i) { 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string str; 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!string_list.GetString(i, &str)) 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) result->push_back(str); 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void LogProfileRequestError(const std::string& profile_path, 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& error_name, 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& error_message) { 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LOG(ERROR) << "Error when requesting properties for profile " 383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << profile_path << ": " << error_message; 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class ProfilePathEquals { 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public: 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) explicit ProfilePathEquals(const std::string& path) 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : path_(path) { 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool operator()(const NetworkProfile& profile) { 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return profile.path == path_; 493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private: 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string path_; 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void NetworkProfileHandler::AddObserver(NetworkProfileObserver* observer) { 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observers_.AddObserver(observer); 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void NetworkProfileHandler::RemoveObserver(NetworkProfileObserver* observer) { 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observers_.RemoveObserver(observer); 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void NetworkProfileHandler::GetManagerPropertiesCallback( 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DBusMethodCallStatus call_status, 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::DictionaryValue& properties) { 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (DBUS_METHOD_CALL_FAILURE) { 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LOG(ERROR) << "Error when requesting manager properties."; 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::Value* profiles = NULL; 743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) properties.GetWithoutPathExpansion(flimflam::kProfilesProperty, &profiles); 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!profiles) { 76 LOG(ERROR) << "Manager properties returned from Shill don't contain " 77 << "the field " << flimflam::kProfilesProperty; 78 return; 79 } 80 OnPropertyChanged(flimflam::kProfilesProperty, *profiles); 81} 82 83void NetworkProfileHandler::OnPropertyChanged(const std::string& name, 84 const base::Value& value) { 85 if (name != flimflam::kProfilesProperty) 86 return; 87 88 const base::ListValue* profiles_value = NULL; 89 value.GetAsList(&profiles_value); 90 DCHECK(profiles_value); 91 92 std::vector<std::string> new_profile_paths; 93 bool result = ConvertListValueToStringVector(*profiles_value, 94 &new_profile_paths); 95 DCHECK(result); 96 97 VLOG(2) << "Profiles: " << profiles_.size(); 98 // Search for removed profiles. 99 std::vector<std::string> removed_profile_paths; 100 for (ProfileList::const_iterator it = profiles_.begin(); 101 it != profiles_.end(); ++it) { 102 if (std::find(new_profile_paths.begin(), 103 new_profile_paths.end(), 104 it->path) == new_profile_paths.end()) { 105 removed_profile_paths.push_back(it->path); 106 } 107 } 108 109 for (std::vector<std::string>::const_iterator it = 110 removed_profile_paths.begin(); 111 it != removed_profile_paths.end(); ++it) { 112 RemoveProfile(*it); 113 } 114 115 for (std::vector<std::string>::const_iterator it = new_profile_paths.begin(); 116 it != new_profile_paths.end(); ++it) { 117 // Skip known profiles. The associated userhash should never change. 118 if (GetProfileForPath(*it)) 119 continue; 120 121 VLOG(2) << "Requesting properties of profile path " << *it << "."; 122 DBusThreadManager::Get()->GetShillProfileClient()->GetProperties( 123 dbus::ObjectPath(*it), 124 base::Bind(&NetworkProfileHandler::GetProfilePropertiesCallback, 125 weak_ptr_factory_.GetWeakPtr(), 126 *it), 127 base::Bind(&LogProfileRequestError, *it)); 128 } 129} 130 131void NetworkProfileHandler::GetProfilePropertiesCallback( 132 const std::string& profile_path, 133 const base::DictionaryValue& properties) { 134 std::string userhash; 135 properties.GetStringWithoutPathExpansion(shill::kUserHashProperty, 136 &userhash); 137 138 AddProfile(NetworkProfile(profile_path, userhash)); 139} 140 141void NetworkProfileHandler::AddProfile(const NetworkProfile& profile) { 142 VLOG(2) << "Adding profile " << profile.ToDebugString() << "."; 143 profiles_.push_back(profile); 144 FOR_EACH_OBSERVER(NetworkProfileObserver, observers_, 145 OnProfileAdded(profiles_.back())); 146} 147 148void NetworkProfileHandler::RemoveProfile(const std::string& profile_path) { 149 VLOG(2) << "Removing profile for path " << profile_path << "."; 150 ProfileList::iterator found = std::find_if(profiles_.begin(), profiles_.end(), 151 ProfilePathEquals(profile_path)); 152 if (found == profiles_.end()) 153 return; 154 NetworkProfile profile = *found; 155 profiles_.erase(found); 156 FOR_EACH_OBSERVER(NetworkProfileObserver, observers_, 157 OnProfileRemoved(profile)); 158} 159 160const NetworkProfile* NetworkProfileHandler::GetProfileForPath( 161 const std::string& profile_path) const { 162 ProfileList::const_iterator found = 163 std::find_if(profiles_.begin(), profiles_.end(), 164 ProfilePathEquals(profile_path)); 165 166 if (found == profiles_.end()) 167 return NULL; 168 return &*found; 169} 170 171const NetworkProfile* NetworkProfileHandler::GetProfileForUserhash( 172 const std::string& userhash) const { 173 for (NetworkProfileHandler::ProfileList::const_iterator it = 174 profiles_.begin(); 175 it != profiles_.end(); ++it) { 176 if (it->userhash == userhash) 177 return &*it; 178 } 179 return NULL; 180} 181 182NetworkProfileHandler::NetworkProfileHandler() 183 : weak_ptr_factory_(this) { 184 DBusThreadManager::Get()->GetShillManagerClient()-> 185 AddPropertyChangedObserver(this); 186 187 // Request the initial profile list. 188 DBusThreadManager::Get()->GetShillManagerClient()->GetProperties( 189 base::Bind(&NetworkProfileHandler::GetManagerPropertiesCallback, 190 weak_ptr_factory_.GetWeakPtr())); 191} 192 193NetworkProfileHandler::~NetworkProfileHandler() { 194 DBusThreadManager::Get()->GetShillManagerClient()-> 195 RemovePropertyChangedObserver(this); 196} 197 198} // namespace chromeos 199