network_profile_handler.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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 3// found in the LICENSE file. 4 5#include "chromeos/network/network_profile_handler.h" 6 7#include <algorithm> 8 9#include "base/bind.h" 10#include "base/strings/string_util.h" 11#include "base/values.h" 12#include "chromeos/dbus/dbus_thread_manager.h" 13#include "chromeos/dbus/shill_manager_client.h" 14#include "chromeos/dbus/shill_profile_client.h" 15#include "chromeos/network/network_profile_observer.h" 16#include "dbus/object_path.h" 17#include "third_party/cros_system_api/dbus/service_constants.h" 18 19namespace chromeos { 20 21namespace { 22 23bool ConvertListValueToStringVector(const base::ListValue& string_list, 24 std::vector<std::string>* result) { 25 for (size_t i = 0; i < string_list.GetSize(); ++i) { 26 std::string str; 27 if (!string_list.GetString(i, &str)) 28 return false; 29 result->push_back(str); 30 } 31 return true; 32} 33 34void LogProfileRequestError(const std::string& profile_path, 35 const std::string& error_name, 36 const std::string& error_message) { 37 LOG(ERROR) << "Error when requesting properties for profile " 38 << profile_path << ": " << error_message; 39} 40 41class ProfilePathEquals { 42 public: 43 explicit ProfilePathEquals(const std::string& path) 44 : path_(path) { 45 } 46 47 bool operator()(const NetworkProfile& profile) { 48 return profile.path == path_; 49 } 50 51 private: 52 std::string path_; 53}; 54 55} // namespace 56 57void NetworkProfileHandler::AddObserver(NetworkProfileObserver* observer) { 58 observers_.AddObserver(observer); 59} 60 61void NetworkProfileHandler::RemoveObserver(NetworkProfileObserver* observer) { 62 observers_.RemoveObserver(observer); 63} 64 65void NetworkProfileHandler::GetManagerPropertiesCallback( 66 DBusMethodCallStatus call_status, 67 const base::DictionaryValue& properties) { 68 if (DBUS_METHOD_CALL_FAILURE) { 69 LOG(ERROR) << "Error when requesting manager properties."; 70 return; 71 } 72 73 const base::Value* profiles = NULL; 74 properties.GetWithoutPathExpansion(flimflam::kProfilesProperty, &profiles); 75 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