shill_service_client.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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_service_client.h"
6
7#include "base/bind.h"
8#include "base/chromeos/chromeos_version.h"
9#include "base/message_loop.h"
10#include "base/stl_util.h"
11#include "base/values.h"
12#include "chromeos/dbus/shill_property_changed_observer.h"
13#include "chromeos/dbus/shill_service_client_stub.h"
14#include "dbus/bus.h"
15#include "dbus/message.h"
16#include "dbus/object_proxy.h"
17#include "third_party/cros_system_api/dbus/service_constants.h"
18
19namespace chromeos {
20
21namespace {
22
23// Error callback for GetProperties.
24void OnGetPropertiesError(
25    const dbus::ObjectPath& service_path,
26    const ShillServiceClient::DictionaryValueCallback& callback,
27    const std::string& error_name,
28    const std::string& error_message) {
29  const std::string log_string =
30      "Failed to call org.chromium.shill.Service.GetProperties for: " +
31      service_path.value() + ": " + error_name + ": " + error_message;
32
33  // Suppress ERROR log if error name is
34  // "org.freedesktop.DBus.Error.UnknownMethod". crbug.com/130660
35  if (error_name == DBUS_ERROR_UNKNOWN_METHOD)
36    VLOG(1) << log_string;
37  else
38    LOG(ERROR) << log_string;
39
40  base::DictionaryValue empty_dictionary;
41  callback.Run(DBUS_METHOD_CALL_FAILURE, empty_dictionary);
42}
43
44// The ShillServiceClient implementation.
45class ShillServiceClientImpl : public ShillServiceClient {
46 public:
47  explicit ShillServiceClientImpl(dbus::Bus* bus)
48      : bus_(bus),
49        helpers_deleter_(&helpers_) {
50  }
51
52  /////////////////////////////////////
53  // ShillServiceClient overrides.
54  virtual void AddPropertyChangedObserver(
55      const dbus::ObjectPath& service_path,
56      ShillPropertyChangedObserver* observer) OVERRIDE {
57    GetHelper(service_path)->AddPropertyChangedObserver(observer);
58  }
59
60  virtual void RemovePropertyChangedObserver(
61      const dbus::ObjectPath& service_path,
62      ShillPropertyChangedObserver* observer) OVERRIDE {
63    GetHelper(service_path)->RemovePropertyChangedObserver(observer);
64  }
65
66  virtual void GetProperties(const dbus::ObjectPath& service_path,
67                             const DictionaryValueCallback& callback) OVERRIDE {
68    dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
69                                 flimflam::kGetPropertiesFunction);
70    GetHelper(service_path)->CallDictionaryValueMethodWithErrorCallback(
71        &method_call,
72        base::Bind(callback, DBUS_METHOD_CALL_SUCCESS),
73        base::Bind(&OnGetPropertiesError, service_path, callback));
74  }
75
76  virtual void SetProperty(const dbus::ObjectPath& service_path,
77                           const std::string& name,
78                           const base::Value& value,
79                           const base::Closure& callback,
80                           const ErrorCallback& error_callback) OVERRIDE {
81    dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
82                                 flimflam::kSetPropertyFunction);
83    dbus::MessageWriter writer(&method_call);
84    writer.AppendString(name);
85    ShillClientHelper::AppendValueDataAsVariant(&writer, value);
86    GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
87                                                             callback,
88                                                             error_callback);
89  }
90
91  virtual void ClearProperty(const dbus::ObjectPath& service_path,
92                             const std::string& name,
93                             const base::Closure& callback,
94                             const ErrorCallback& error_callback) OVERRIDE {
95    dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
96                                 flimflam::kClearPropertyFunction);
97    dbus::MessageWriter writer(&method_call);
98    writer.AppendString(name);
99    GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
100                                                             callback,
101                                                             error_callback);
102  }
103
104
105  virtual void ClearProperties(const dbus::ObjectPath& service_path,
106                               const std::vector<std::string>& names,
107                               const ListValueCallback& callback,
108                               const ErrorCallback& error_callback) OVERRIDE {
109    dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
110                                 shill::kClearPropertiesFunction);
111    dbus::MessageWriter writer(&method_call);
112    writer.AppendArrayOfStrings(names);
113    GetHelper(service_path)->CallListValueMethodWithErrorCallback(
114        &method_call,
115        callback,
116        error_callback);
117  }
118
119  virtual void Connect(const dbus::ObjectPath& service_path,
120                       const base::Closure& callback,
121                       const ErrorCallback& error_callback) OVERRIDE {
122    dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
123                                 flimflam::kConnectFunction);
124    GetHelper(service_path)->CallVoidMethodWithErrorCallback(
125        &method_call, callback, error_callback);
126  }
127
128  virtual void Disconnect(const dbus::ObjectPath& service_path,
129                          const base::Closure& callback,
130                          const ErrorCallback& error_callback) OVERRIDE {
131    dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
132                                 flimflam::kDisconnectFunction);
133    GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
134                                                             callback,
135                                                             error_callback);
136  }
137
138  virtual void Remove(const dbus::ObjectPath& service_path,
139                      const base::Closure& callback,
140                      const ErrorCallback& error_callback) OVERRIDE {
141    dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
142                                 flimflam::kRemoveServiceFunction);
143    GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
144                                                             callback,
145                                                             error_callback);
146  }
147
148  virtual void ActivateCellularModem(
149      const dbus::ObjectPath& service_path,
150      const std::string& carrier,
151      const base::Closure& callback,
152      const ErrorCallback& error_callback) OVERRIDE {
153    dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
154                                 flimflam::kActivateCellularModemFunction);
155    dbus::MessageWriter writer(&method_call);
156    writer.AppendString(carrier);
157    GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
158                                                             callback,
159                                                             error_callback);
160  }
161
162  virtual void CompleteCellularActivation(
163      const dbus::ObjectPath& service_path,
164      const base::Closure& callback,
165      const ErrorCallback& error_callback) OVERRIDE {
166    dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
167                                 shill::kCompleteCellularActivationFunction);
168    dbus::MessageWriter writer(&method_call);
169    GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
170                                                             callback,
171                                                             error_callback);
172  }
173
174  virtual bool CallActivateCellularModemAndBlock(
175      const dbus::ObjectPath& service_path,
176      const std::string& carrier) OVERRIDE {
177    dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
178                                 flimflam::kActivateCellularModemFunction);
179    dbus::MessageWriter writer(&method_call);
180    writer.AppendString(carrier);
181    return GetHelper(service_path)->CallVoidMethodAndBlock(&method_call);
182  }
183
184  virtual ShillServiceClient::TestInterface* GetTestInterface() OVERRIDE {
185    return NULL;
186  }
187
188 private:
189  typedef std::map<std::string, ShillClientHelper*> HelperMap;
190
191  // Returns the corresponding ShillClientHelper for the profile.
192  ShillClientHelper* GetHelper(const dbus::ObjectPath& service_path) {
193    HelperMap::iterator it = helpers_.find(service_path.value());
194    if (it != helpers_.end())
195      return it->second;
196
197    // There is no helper for the profile, create it.
198    dbus::ObjectProxy* object_proxy =
199        bus_->GetObjectProxy(flimflam::kFlimflamServiceName, service_path);
200    ShillClientHelper* helper = new ShillClientHelper(bus_, object_proxy);
201    helper->MonitorPropertyChanged(flimflam::kFlimflamServiceInterface);
202    helpers_.insert(HelperMap::value_type(service_path.value(), helper));
203    return helper;
204  }
205
206  dbus::Bus* bus_;
207  HelperMap helpers_;
208  STLValueDeleter<HelperMap> helpers_deleter_;
209
210  DISALLOW_COPY_AND_ASSIGN(ShillServiceClientImpl);
211};
212
213}  // namespace
214
215ShillServiceClient::ShillServiceClient() {}
216
217ShillServiceClient::~ShillServiceClient() {}
218
219// static
220ShillServiceClient* ShillServiceClient::Create(
221    DBusClientImplementationType type,
222    dbus::Bus* bus) {
223  if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
224    return new ShillServiceClientImpl(bus);
225  DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
226  return new ShillServiceClientStub();
227}
228
229}  // namespace chromeos
230