Save errno for logging before potentially overwriting it.
[chromium-blink-merge.git] / chromeos / dbus / shill_service_client.cc
blobc0f8c7fbd96c057e5530e9a40a6c902b68b8d96d
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.
5 #include "chromeos/dbus/shill_service_client.h"
7 #include "base/bind.h"
8 #include "base/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 "chromeos/dbus/shill_service_client_stub.h"
13 #include "dbus/bus.h"
14 #include "dbus/message.h"
15 #include "dbus/object_proxy.h"
16 #include "third_party/cros_system_api/dbus/service_constants.h"
18 namespace chromeos {
20 namespace {
22 #ifndef DBUS_ERROR_UNKNOWN_OBJECT
23 // The linux_chromeos ASAN builder has an older version of dbus-protocol.h
24 // so make sure this is defined.
25 #define DBUS_ERROR_UNKNOWN_OBJECT "org.freedesktop.DBus.Error.UnknownObject"
26 #endif
28 // Error callback for GetProperties.
29 void OnGetPropertiesError(
30 const dbus::ObjectPath& service_path,
31 const ShillServiceClient::DictionaryValueCallback& callback,
32 const std::string& error_name,
33 const std::string& error_message) {
34 const std::string log_string =
35 "Failed to call org.chromium.shill.Service.GetProperties for: " +
36 service_path.value() + ": " + error_name + ": " + error_message;
38 // Suppress ERROR messages for UnknownMethod/Object" since this can
39 // happen under normal conditions. See crbug.com/130660 and crbug.com/222210.
40 if (error_name == DBUS_ERROR_UNKNOWN_METHOD ||
41 error_name == DBUS_ERROR_UNKNOWN_OBJECT)
42 VLOG(1) << log_string;
43 else
44 LOG(ERROR) << log_string;
46 base::DictionaryValue empty_dictionary;
47 callback.Run(DBUS_METHOD_CALL_FAILURE, empty_dictionary);
50 // The ShillServiceClient implementation.
51 class ShillServiceClientImpl : public ShillServiceClient {
52 public:
53 explicit ShillServiceClientImpl(dbus::Bus* bus)
54 : bus_(bus),
55 helpers_deleter_(&helpers_) {
58 /////////////////////////////////////
59 // ShillServiceClient overrides.
60 virtual void AddPropertyChangedObserver(
61 const dbus::ObjectPath& service_path,
62 ShillPropertyChangedObserver* observer) OVERRIDE {
63 GetHelper(service_path)->AddPropertyChangedObserver(observer);
66 virtual void RemovePropertyChangedObserver(
67 const dbus::ObjectPath& service_path,
68 ShillPropertyChangedObserver* observer) OVERRIDE {
69 GetHelper(service_path)->RemovePropertyChangedObserver(observer);
72 virtual void GetProperties(const dbus::ObjectPath& service_path,
73 const DictionaryValueCallback& callback) OVERRIDE {
74 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
75 flimflam::kGetPropertiesFunction);
76 GetHelper(service_path)->CallDictionaryValueMethodWithErrorCallback(
77 &method_call,
78 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS),
79 base::Bind(&OnGetPropertiesError, service_path, callback));
82 virtual void SetProperty(const dbus::ObjectPath& service_path,
83 const std::string& name,
84 const base::Value& value,
85 const base::Closure& callback,
86 const ErrorCallback& error_callback) OVERRIDE {
87 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
88 flimflam::kSetPropertyFunction);
89 dbus::MessageWriter writer(&method_call);
90 writer.AppendString(name);
91 ShillClientHelper::AppendValueDataAsVariant(&writer, value);
92 GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
93 callback,
94 error_callback);
97 virtual void ClearProperty(const dbus::ObjectPath& service_path,
98 const std::string& name,
99 const base::Closure& callback,
100 const ErrorCallback& error_callback) OVERRIDE {
101 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
102 flimflam::kClearPropertyFunction);
103 dbus::MessageWriter writer(&method_call);
104 writer.AppendString(name);
105 GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
106 callback,
107 error_callback);
111 virtual void ClearProperties(const dbus::ObjectPath& service_path,
112 const std::vector<std::string>& names,
113 const ListValueCallback& callback,
114 const ErrorCallback& error_callback) OVERRIDE {
115 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
116 shill::kClearPropertiesFunction);
117 dbus::MessageWriter writer(&method_call);
118 writer.AppendArrayOfStrings(names);
119 GetHelper(service_path)->CallListValueMethodWithErrorCallback(
120 &method_call,
121 callback,
122 error_callback);
125 virtual void Connect(const dbus::ObjectPath& service_path,
126 const base::Closure& callback,
127 const ErrorCallback& error_callback) OVERRIDE {
128 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
129 flimflam::kConnectFunction);
130 GetHelper(service_path)->CallVoidMethodWithErrorCallback(
131 &method_call, callback, error_callback);
134 virtual void Disconnect(const dbus::ObjectPath& service_path,
135 const base::Closure& callback,
136 const ErrorCallback& error_callback) OVERRIDE {
137 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
138 flimflam::kDisconnectFunction);
139 GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
140 callback,
141 error_callback);
144 virtual void Remove(const dbus::ObjectPath& service_path,
145 const base::Closure& callback,
146 const ErrorCallback& error_callback) OVERRIDE {
147 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
148 flimflam::kRemoveServiceFunction);
149 GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
150 callback,
151 error_callback);
154 virtual void ActivateCellularModem(
155 const dbus::ObjectPath& service_path,
156 const std::string& carrier,
157 const base::Closure& callback,
158 const ErrorCallback& error_callback) OVERRIDE {
159 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
160 flimflam::kActivateCellularModemFunction);
161 dbus::MessageWriter writer(&method_call);
162 writer.AppendString(carrier);
163 GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
164 callback,
165 error_callback);
168 virtual void CompleteCellularActivation(
169 const dbus::ObjectPath& service_path,
170 const base::Closure& callback,
171 const ErrorCallback& error_callback) OVERRIDE {
172 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
173 shill::kCompleteCellularActivationFunction);
174 dbus::MessageWriter writer(&method_call);
175 GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call,
176 callback,
177 error_callback);
180 virtual bool CallActivateCellularModemAndBlock(
181 const dbus::ObjectPath& service_path,
182 const std::string& carrier) OVERRIDE {
183 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface,
184 flimflam::kActivateCellularModemFunction);
185 dbus::MessageWriter writer(&method_call);
186 writer.AppendString(carrier);
187 return GetHelper(service_path)->CallVoidMethodAndBlock(&method_call);
190 virtual ShillServiceClient::TestInterface* GetTestInterface() OVERRIDE {
191 return NULL;
194 private:
195 typedef std::map<std::string, ShillClientHelper*> HelperMap;
197 // Returns the corresponding ShillClientHelper for the profile.
198 ShillClientHelper* GetHelper(const dbus::ObjectPath& service_path) {
199 HelperMap::iterator it = helpers_.find(service_path.value());
200 if (it != helpers_.end())
201 return it->second;
203 // There is no helper for the profile, create it.
204 dbus::ObjectProxy* object_proxy =
205 bus_->GetObjectProxy(flimflam::kFlimflamServiceName, service_path);
206 ShillClientHelper* helper = new ShillClientHelper(bus_, object_proxy);
207 helper->MonitorPropertyChanged(flimflam::kFlimflamServiceInterface);
208 helpers_.insert(HelperMap::value_type(service_path.value(), helper));
209 return helper;
212 dbus::Bus* bus_;
213 HelperMap helpers_;
214 STLValueDeleter<HelperMap> helpers_deleter_;
216 DISALLOW_COPY_AND_ASSIGN(ShillServiceClientImpl);
219 } // namespace
221 ShillServiceClient::ShillServiceClient() {}
223 ShillServiceClient::~ShillServiceClient() {}
225 // static
226 ShillServiceClient* ShillServiceClient::Create(
227 DBusClientImplementationType type,
228 dbus::Bus* bus) {
229 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
230 return new ShillServiceClientImpl(bus);
231 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
232 return new ShillServiceClientStub();
235 } // namespace chromeos