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/dbus/shill_device_client.h" 6 7 #include "base/bind.h" 8 #include "base/message_loop/message_loop.h" 9 #include "base/stl_util.h" 10 #include "base/values.h" 11 #include "chromeos/dbus/shill_property_changed_observer.h" 12 #include "dbus/bus.h" 13 #include "dbus/message.h" 14 #include "dbus/object_path.h" 15 #include "dbus/object_proxy.h" 16 #include "dbus/values_util.h" 17 #include "third_party/cros_system_api/dbus/service_constants.h" 18 19 namespace chromeos { 20 21 namespace { 22 23 // The ShillDeviceClient implementation. 24 class ShillDeviceClientImpl : public ShillDeviceClient { 25 public: 26 explicit ShillDeviceClientImpl() 27 : bus_(NULL) { 28 } 29 30 virtual ~ShillDeviceClientImpl() { 31 for (HelperMap::iterator iter = helpers_.begin(); 32 iter != helpers_.end(); ++iter) { 33 // This *should* never happen, yet we're getting crash reports that 34 // seem to imply that it does happen sometimes. Adding CHECKs here 35 // so we can determine more accurately where the problem lies. 36 // See: http://crbug.com/170541 37 CHECK(iter->second) << "NULL Helper found in helper list."; 38 delete iter->second; 39 } 40 helpers_.clear(); 41 } 42 43 /////////////////////////////////////// 44 // ShillDeviceClient overrides. 45 virtual void AddPropertyChangedObserver( 46 const dbus::ObjectPath& device_path, 47 ShillPropertyChangedObserver* observer) OVERRIDE { 48 GetHelper(device_path)->AddPropertyChangedObserver(observer); 49 } 50 51 virtual void RemovePropertyChangedObserver( 52 const dbus::ObjectPath& device_path, 53 ShillPropertyChangedObserver* observer) OVERRIDE { 54 GetHelper(device_path)->RemovePropertyChangedObserver(observer); 55 } 56 57 virtual void GetProperties(const dbus::ObjectPath& device_path, 58 const DictionaryValueCallback& callback) OVERRIDE { 59 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 60 shill::kGetPropertiesFunction); 61 GetHelper(device_path)->CallDictionaryValueMethod(&method_call, callback); 62 } 63 64 virtual void ProposeScan(const dbus::ObjectPath& device_path, 65 const VoidDBusMethodCallback& callback) OVERRIDE { 66 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 67 shill::kProposeScanFunction); 68 GetHelper(device_path)->CallVoidMethod(&method_call, callback); 69 } 70 71 virtual void SetProperty(const dbus::ObjectPath& device_path, 72 const std::string& name, 73 const base::Value& value, 74 const base::Closure& callback, 75 const ErrorCallback& error_callback) OVERRIDE { 76 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 77 shill::kSetPropertyFunction); 78 dbus::MessageWriter writer(&method_call); 79 writer.AppendString(name); 80 ShillClientHelper::AppendValueDataAsVariant(&writer, value); 81 GetHelper(device_path)->CallVoidMethodWithErrorCallback(&method_call, 82 callback, 83 error_callback); 84 } 85 86 virtual void ClearProperty(const dbus::ObjectPath& device_path, 87 const std::string& name, 88 const VoidDBusMethodCallback& callback) OVERRIDE { 89 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 90 shill::kClearPropertyFunction); 91 dbus::MessageWriter writer(&method_call); 92 writer.AppendString(name); 93 GetHelper(device_path)->CallVoidMethod(&method_call, callback); 94 } 95 96 virtual void AddIPConfig( 97 const dbus::ObjectPath& device_path, 98 const std::string& method, 99 const ObjectPathDBusMethodCallback& callback) OVERRIDE { 100 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 101 shill::kAddIPConfigFunction); 102 dbus::MessageWriter writer(&method_call); 103 writer.AppendString(method); 104 GetHelper(device_path)->CallObjectPathMethod(&method_call, callback); 105 } 106 107 virtual void RequirePin(const dbus::ObjectPath& device_path, 108 const std::string& pin, 109 bool require, 110 const base::Closure& callback, 111 const ErrorCallback& error_callback) OVERRIDE { 112 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 113 shill::kRequirePinFunction); 114 dbus::MessageWriter writer(&method_call); 115 writer.AppendString(pin); 116 writer.AppendBool(require); 117 GetHelper(device_path)->CallVoidMethodWithErrorCallback( 118 &method_call, callback, error_callback); 119 } 120 121 virtual void EnterPin(const dbus::ObjectPath& device_path, 122 const std::string& pin, 123 const base::Closure& callback, 124 const ErrorCallback& error_callback) OVERRIDE { 125 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 126 shill::kEnterPinFunction); 127 dbus::MessageWriter writer(&method_call); 128 writer.AppendString(pin); 129 GetHelper(device_path)->CallVoidMethodWithErrorCallback( 130 &method_call, callback, error_callback); 131 } 132 133 virtual void UnblockPin(const dbus::ObjectPath& device_path, 134 const std::string& puk, 135 const std::string& pin, 136 const base::Closure& callback, 137 const ErrorCallback& error_callback) OVERRIDE { 138 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 139 shill::kUnblockPinFunction); 140 dbus::MessageWriter writer(&method_call); 141 writer.AppendString(puk); 142 writer.AppendString(pin); 143 GetHelper(device_path)->CallVoidMethodWithErrorCallback( 144 &method_call, callback, error_callback); 145 } 146 147 virtual void ChangePin(const dbus::ObjectPath& device_path, 148 const std::string& old_pin, 149 const std::string& new_pin, 150 const base::Closure& callback, 151 const ErrorCallback& error_callback) OVERRIDE { 152 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 153 shill::kChangePinFunction); 154 dbus::MessageWriter writer(&method_call); 155 writer.AppendString(old_pin); 156 writer.AppendString(new_pin); 157 GetHelper(device_path)->CallVoidMethodWithErrorCallback( 158 &method_call, callback, error_callback); 159 } 160 161 virtual void Register(const dbus::ObjectPath& device_path, 162 const std::string& network_id, 163 const base::Closure& callback, 164 const ErrorCallback& error_callback) OVERRIDE { 165 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 166 shill::kRegisterFunction); 167 dbus::MessageWriter writer(&method_call); 168 writer.AppendString(network_id); 169 GetHelper(device_path)->CallVoidMethodWithErrorCallback( 170 &method_call, callback, error_callback); 171 } 172 173 virtual void SetCarrier(const dbus::ObjectPath& device_path, 174 const std::string& carrier, 175 const base::Closure& callback, 176 const ErrorCallback& error_callback) OVERRIDE { 177 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 178 shill::kSetCarrierFunction); 179 dbus::MessageWriter writer(&method_call); 180 writer.AppendString(carrier); 181 GetHelper(device_path)->CallVoidMethodWithErrorCallback( 182 &method_call, callback, error_callback); 183 } 184 185 virtual void Reset(const dbus::ObjectPath& device_path, 186 const base::Closure& callback, 187 const ErrorCallback& error_callback) OVERRIDE { 188 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 189 shill::kResetFunction); 190 GetHelper(device_path)->CallVoidMethodWithErrorCallback( 191 &method_call, callback, error_callback); 192 } 193 194 virtual void PerformTDLSOperation( 195 const dbus::ObjectPath& device_path, 196 const std::string& operation, 197 const std::string& peer, 198 const StringCallback& callback, 199 const ErrorCallback& error_callback) OVERRIDE { 200 dbus::MethodCall method_call(shill::kFlimflamDeviceInterface, 201 shill::kPerformTDLSOperationFunction); 202 dbus::MessageWriter writer(&method_call); 203 writer.AppendString(operation); 204 writer.AppendString(peer); 205 GetHelper(device_path)->CallStringMethodWithErrorCallback( 206 &method_call, callback, error_callback); 207 } 208 209 virtual TestInterface* GetTestInterface() OVERRIDE { 210 return NULL; 211 } 212 213 protected: 214 virtual void Init(dbus::Bus* bus) OVERRIDE { 215 bus_ = bus; 216 } 217 218 private: 219 typedef std::map<std::string, ShillClientHelper*> HelperMap; 220 221 // Returns the corresponding ShillClientHelper for the profile. 222 ShillClientHelper* GetHelper(const dbus::ObjectPath& device_path) { 223 HelperMap::iterator it = helpers_.find(device_path.value()); 224 if (it != helpers_.end()) { 225 CHECK(it->second) << "Found a NULL helper in the list."; 226 return it->second; 227 } 228 229 // There is no helper for the profile, create it. 230 dbus::ObjectProxy* object_proxy = 231 bus_->GetObjectProxy(shill::kFlimflamServiceName, device_path); 232 ShillClientHelper* helper = new ShillClientHelper(object_proxy); 233 CHECK(helper) << "Unable to create Shill client helper."; 234 helper->MonitorPropertyChanged(shill::kFlimflamDeviceInterface); 235 helpers_.insert(HelperMap::value_type(device_path.value(), helper)); 236 return helper; 237 } 238 239 dbus::Bus* bus_; 240 HelperMap helpers_; 241 242 DISALLOW_COPY_AND_ASSIGN(ShillDeviceClientImpl); 243 }; 244 245 } // namespace 246 247 ShillDeviceClient::ShillDeviceClient() {} 248 249 ShillDeviceClient::~ShillDeviceClient() {} 250 251 // static 252 ShillDeviceClient* ShillDeviceClient::Create() { 253 return new ShillDeviceClientImpl(); 254 } 255 256 } // namespace chromeos 257