network_configuration_handler.cc revision a93a17c8d99d686bd4a1511e5504e5e6cc9fcadf
1// Copyright (c) 2012 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_configuration_handler.h" 6 7#include <string> 8#include <vector> 9 10#include "base/bind.h" 11#include "base/logging.h" 12#include "base/memory/ref_counted.h" 13#include "base/memory/scoped_ptr.h" 14#include "base/values.h" 15#include "chromeos/dbus/dbus_method_call_status.h" 16#include "chromeos/dbus/dbus_thread_manager.h" 17#include "chromeos/dbus/shill_manager_client.h" 18#include "chromeos/dbus/shill_service_client.h" 19#include "dbus/object_path.h" 20#include "third_party/cros_system_api/dbus/service_constants.h" 21 22namespace chromeos { 23 24namespace { 25 26const char kLogModule[] = "NetworkConfigurationHandler"; 27 28NetworkConfigurationHandler* g_configuration_handler_instance = NULL; 29 30// None of these error messages are user-facing: they should only appear in 31// logs. 32const char kErrorsListTag[] = "errors"; 33const char kClearPropertiesFailedError[] = "Error.ClearPropertiesFailed"; 34const char kClearPropertiesFailedErrorMessage[] = "Clear properties failed"; 35const char kDBusFailedError[] = "Error.DBusFailed"; 36const char kDBusFailedErrorMessage[] = "DBus call failed."; 37 38void ClearPropertiesCallback( 39 const std::vector<std::string>& names, 40 const std::string& service_path, 41 const base::Closure& callback, 42 const network_handler::ErrorCallback& error_callback, 43 const base::ListValue& result) { 44 bool some_failed = false; 45 for (size_t i = 0; i < result.GetSize(); ++i) { 46 bool success; 47 if (result.GetBoolean(i, &success)) { 48 if (!success) { 49 some_failed = true; 50 break; 51 } 52 } else { 53 NOTREACHED() << "Result garbled from ClearProperties"; 54 } 55 } 56 57 if (some_failed) { 58 DCHECK(names.size() == result.GetSize()) 59 << "Result wrong size from ClearProperties."; 60 scoped_ptr<base::DictionaryValue> error_data( 61 network_handler::CreateErrorData(service_path, 62 kClearPropertiesFailedError, 63 kClearPropertiesFailedErrorMessage)); 64 LOG(ERROR) << "ClearPropertiesCallback failed for service path: " 65 << service_path; 66 error_data->Set("errors", result.DeepCopy()); 67 scoped_ptr<base::ListValue> name_list(new base::ListValue); 68 name_list->AppendStrings(names); 69 error_data->Set("names", name_list.release()); 70 error_callback.Run(kClearPropertiesFailedError, error_data.Pass()); 71 } else { 72 callback.Run(); 73 } 74} 75 76// Used to translate the dbus dictionary callback into one that calls 77// the error callback if we have a failure. 78void RunCallbackWithDictionaryValue( 79 const network_handler::DictionaryResultCallback& callback, 80 const network_handler::ErrorCallback& error_callback, 81 const std::string& service_path, 82 DBusMethodCallStatus call_status, 83 const base::DictionaryValue& value) { 84 if (call_status != DBUS_METHOD_CALL_SUCCESS) { 85 scoped_ptr<base::DictionaryValue> error_data( 86 network_handler::CreateErrorData(service_path, 87 kDBusFailedError, 88 kDBusFailedErrorMessage)); 89 LOG(ERROR) << "CallbackWithDictionaryValue failed for service path: " 90 << service_path; 91 error_callback.Run(kDBusFailedError, error_data.Pass()); 92 } else { 93 callback.Run(service_path, value); 94 } 95} 96 97void RunCreateNetworkCallback( 98 const network_handler::StringResultCallback& callback, 99 const dbus::ObjectPath& service_path) { 100 callback.Run(service_path.value()); 101} 102 103void IgnoreObjectPathCallback(const base::Closure& callback, 104 const dbus::ObjectPath& object_path) { 105 callback.Run(); 106} 107 108} // namespace 109 110// static 111void NetworkConfigurationHandler::Initialize() { 112 CHECK(!g_configuration_handler_instance); 113 g_configuration_handler_instance = new NetworkConfigurationHandler; 114} 115 116// static 117void NetworkConfigurationHandler::Shutdown() { 118 CHECK(g_configuration_handler_instance); 119 delete g_configuration_handler_instance; 120 g_configuration_handler_instance = NULL; 121} 122 123// static 124NetworkConfigurationHandler* NetworkConfigurationHandler::Get() { 125 CHECK(g_configuration_handler_instance) 126 << "NetworkConfigurationHandler::Get() called before Initialize()"; 127 return g_configuration_handler_instance; 128} 129 130void NetworkConfigurationHandler::GetProperties( 131 const std::string& service_path, 132 const network_handler::DictionaryResultCallback& callback, 133 const network_handler::ErrorCallback& error_callback) const { 134 DBusThreadManager::Get()->GetShillServiceClient()->GetProperties( 135 dbus::ObjectPath(service_path), 136 base::Bind(&RunCallbackWithDictionaryValue, 137 callback, 138 error_callback, 139 service_path)); 140} 141 142void NetworkConfigurationHandler::SetProperties( 143 const std::string& service_path, 144 const base::DictionaryValue& properties, 145 const base::Closure& callback, 146 const network_handler::ErrorCallback& error_callback) const { 147 DBusThreadManager::Get()->GetShillManagerClient()->ConfigureService( 148 properties, 149 base::Bind(&IgnoreObjectPathCallback, callback), 150 base::Bind(&network_handler::ShillErrorCallbackFunction, 151 kLogModule, service_path, error_callback)); 152} 153 154void NetworkConfigurationHandler::ClearProperties( 155 const std::string& service_path, 156 const std::vector<std::string>& names, 157 const base::Closure& callback, 158 const network_handler::ErrorCallback& error_callback) { 159 DBusThreadManager::Get()->GetShillServiceClient()->ClearProperties( 160 dbus::ObjectPath(service_path), 161 names, 162 base::Bind(&ClearPropertiesCallback, 163 names, 164 service_path, 165 callback, 166 error_callback), 167 base::Bind(&network_handler::ShillErrorCallbackFunction, 168 kLogModule, service_path, error_callback)); 169} 170 171void NetworkConfigurationHandler::CreateConfiguration( 172 const base::DictionaryValue& properties, 173 const network_handler::StringResultCallback& callback, 174 const network_handler::ErrorCallback& error_callback) const { 175 ShillManagerClient* manager = 176 DBusThreadManager::Get()->GetShillManagerClient(); 177 178 std::string type; 179 properties.GetStringWithoutPathExpansion(flimflam::kTypeProperty, &type); 180 // Shill supports ConfigureServiceForProfile only for network type WiFi. In 181 // all other cases, we have to rely on GetService for now. This is 182 // unproblematic for VPN (user profile only), but will lead to inconsistencies 183 // with WiMax, for example. 184 if (type == flimflam::kTypeWifi) { 185 std::string profile; 186 properties.GetStringWithoutPathExpansion(flimflam::kProfileProperty, 187 &profile); 188 manager->ConfigureServiceForProfile( 189 dbus::ObjectPath(profile), 190 properties, 191 base::Bind(&RunCreateNetworkCallback, callback), 192 base::Bind(&network_handler::ShillErrorCallbackFunction, 193 kLogModule, "", error_callback)); 194 } else { 195 manager->GetService( 196 properties, 197 base::Bind(&RunCreateNetworkCallback, callback), 198 base::Bind(&network_handler::ShillErrorCallbackFunction, 199 kLogModule, "", error_callback)); 200 } 201} 202 203void NetworkConfigurationHandler::RemoveConfiguration( 204 const std::string& service_path, 205 const base::Closure& callback, 206 const network_handler::ErrorCallback& error_callback) const { 207 DBusThreadManager::Get()->GetShillServiceClient()->Remove( 208 dbus::ObjectPath(service_path), 209 callback, 210 base::Bind(&network_handler::ShillErrorCallbackFunction, 211 kLogModule, service_path, error_callback)); 212} 213 214NetworkConfigurationHandler::NetworkConfigurationHandler() { 215} 216 217NetworkConfigurationHandler::~NetworkConfigurationHandler() { 218} 219 220} // namespace chromeos 221