shill_device_client.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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
20namespace chromeos {
21
22namespace {
23
24// The ShillDeviceClient implementation.
25class ShillDeviceClientImpl : public ShillDeviceClient {
26 public:
27  explicit ShillDeviceClientImpl()
28      : bus_(NULL) {
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(shill::kFlimflamDeviceInterface,
61                                 shill::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(shill::kFlimflamDeviceInterface,
68                                 shill::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(shill::kFlimflamDeviceInterface,
78                                 shill::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(shill::kFlimflamDeviceInterface,
91                                 shill::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(shill::kFlimflamDeviceInterface,
102                                 shill::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(shill::kFlimflamDeviceInterface,
114                                 shill::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(shill::kFlimflamDeviceInterface,
127                                 shill::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(shill::kFlimflamDeviceInterface,
140                                 shill::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(shill::kFlimflamDeviceInterface,
154                                 shill::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(shill::kFlimflamDeviceInterface,
167                                 shill::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(shill::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(shill::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 protected:
200  virtual void Init(dbus::Bus* bus) OVERRIDE {
201    bus_ = bus;
202  }
203
204 private:
205  typedef std::map<std::string, ShillClientHelper*> HelperMap;
206
207  // Returns the corresponding ShillClientHelper for the profile.
208  ShillClientHelper* GetHelper(const dbus::ObjectPath& device_path) {
209    HelperMap::iterator it = helpers_.find(device_path.value());
210    if (it != helpers_.end()) {
211      CHECK(it->second) << "Found a NULL helper in the list.";
212      return it->second;
213    }
214
215    // There is no helper for the profile, create it.
216    dbus::ObjectProxy* object_proxy =
217        bus_->GetObjectProxy(shill::kFlimflamServiceName, device_path);
218    ShillClientHelper* helper = new ShillClientHelper(object_proxy);
219    CHECK(helper) << "Unable to create Shill client helper.";
220    helper->MonitorPropertyChanged(shill::kFlimflamDeviceInterface);
221    helpers_.insert(HelperMap::value_type(device_path.value(), helper));
222    return helper;
223  }
224
225  dbus::Bus* bus_;
226  HelperMap helpers_;
227
228  DISALLOW_COPY_AND_ASSIGN(ShillDeviceClientImpl);
229};
230
231}  // namespace
232
233ShillDeviceClient::ShillDeviceClient() {}
234
235ShillDeviceClient::~ShillDeviceClient() {}
236
237// static
238ShillDeviceClient* ShillDeviceClient::Create(
239    DBusClientImplementationType type) {
240  if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
241    return new ShillDeviceClientImpl();
242  DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
243  return new ShillDeviceClientStub();
244}
245
246}  // namespace chromeos
247