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