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:
ShillDeviceClientImpl()26 explicit ShillDeviceClientImpl()
27 : bus_(NULL) {
28 }
29
~ShillDeviceClientImpl()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.
AddPropertyChangedObserver(const dbus::ObjectPath & device_path,ShillPropertyChangedObserver * observer)45 virtual void AddPropertyChangedObserver(
46 const dbus::ObjectPath& device_path,
47 ShillPropertyChangedObserver* observer) OVERRIDE {
48 GetHelper(device_path)->AddPropertyChangedObserver(observer);
49 }
50
RemovePropertyChangedObserver(const dbus::ObjectPath & device_path,ShillPropertyChangedObserver * observer)51 virtual void RemovePropertyChangedObserver(
52 const dbus::ObjectPath& device_path,
53 ShillPropertyChangedObserver* observer) OVERRIDE {
54 GetHelper(device_path)->RemovePropertyChangedObserver(observer);
55 }
56
GetProperties(const dbus::ObjectPath & device_path,const DictionaryValueCallback & callback)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
ProposeScan(const dbus::ObjectPath & device_path,const VoidDBusMethodCallback & callback)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
SetProperty(const dbus::ObjectPath & device_path,const std::string & name,const base::Value & value,const base::Closure & callback,const ErrorCallback & error_callback)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
ClearProperty(const dbus::ObjectPath & device_path,const std::string & name,const VoidDBusMethodCallback & callback)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
AddIPConfig(const dbus::ObjectPath & device_path,const std::string & method,const ObjectPathDBusMethodCallback & callback)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
RequirePin(const dbus::ObjectPath & device_path,const std::string & pin,bool require,const base::Closure & callback,const ErrorCallback & error_callback)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
EnterPin(const dbus::ObjectPath & device_path,const std::string & pin,const base::Closure & callback,const ErrorCallback & error_callback)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
UnblockPin(const dbus::ObjectPath & device_path,const std::string & puk,const std::string & pin,const base::Closure & callback,const ErrorCallback & error_callback)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
ChangePin(const dbus::ObjectPath & device_path,const std::string & old_pin,const std::string & new_pin,const base::Closure & callback,const ErrorCallback & error_callback)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
Register(const dbus::ObjectPath & device_path,const std::string & network_id,const base::Closure & callback,const ErrorCallback & error_callback)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
SetCarrier(const dbus::ObjectPath & device_path,const std::string & carrier,const base::Closure & callback,const ErrorCallback & error_callback)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
Reset(const dbus::ObjectPath & device_path,const base::Closure & callback,const ErrorCallback & error_callback)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
PerformTDLSOperation(const dbus::ObjectPath & device_path,const std::string & operation,const std::string & peer,const StringCallback & callback,const ErrorCallback & error_callback)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
GetTestInterface()209 virtual TestInterface* GetTestInterface() OVERRIDE {
210 return NULL;
211 }
212
213 protected:
Init(dbus::Bus * bus)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.
GetHelper(const dbus::ObjectPath & device_path)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
ShillDeviceClient()247 ShillDeviceClient::ShillDeviceClient() {}
248
~ShillDeviceClient()249 ShillDeviceClient::~ShillDeviceClient() {}
250
251 // static
Create()252 ShillDeviceClient* ShillDeviceClient::Create() {
253 return new ShillDeviceClientImpl();
254 }
255
256 } // namespace chromeos
257