1 // Copyright 2013 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/bluetooth_profile_manager_client.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "dbus/bus.h"
10 #include "dbus/message.h"
11 #include "dbus/object_path.h"
12 #include "dbus/object_proxy.h"
13 #include "third_party/cros_system_api/dbus/service_constants.h"
14
15 namespace chromeos {
16
17 const char BluetoothProfileManagerClient::kNoResponseError[] =
18 "org.chromium.Error.NoResponse";
19
20
Options()21 BluetoothProfileManagerClient::Options::Options() {
22 }
23
~Options()24 BluetoothProfileManagerClient::Options::~Options() {
25 }
26
27 // The BluetoothProfileManagerClient implementation used in production.
28 class BluetoothProfileManagerClientImpl
29 : public BluetoothProfileManagerClient {
30 public:
BluetoothProfileManagerClientImpl()31 BluetoothProfileManagerClientImpl() : weak_ptr_factory_(this) {}
32
~BluetoothProfileManagerClientImpl()33 virtual ~BluetoothProfileManagerClientImpl() {
34 }
35
36 // BluetoothProfileManagerClient override.
RegisterProfile(const dbus::ObjectPath & profile_path,const std::string & uuid,const Options & options,const base::Closure & callback,const ErrorCallback & error_callback)37 virtual void RegisterProfile(const dbus::ObjectPath& profile_path,
38 const std::string& uuid,
39 const Options& options,
40 const base::Closure& callback,
41 const ErrorCallback& error_callback) OVERRIDE {
42 dbus::MethodCall method_call(
43 bluetooth_profile_manager::kBluetoothProfileManagerInterface,
44 bluetooth_profile_manager::kRegisterProfile);
45
46 dbus::MessageWriter writer(&method_call);
47 writer.AppendObjectPath(profile_path);
48 writer.AppendString(uuid);
49
50 dbus::MessageWriter array_writer(NULL);
51 writer.OpenArray("{sv}", &array_writer);
52
53 dbus::MessageWriter dict_writer(NULL);
54
55 // Send Name if provided.
56 if (options.name.get() != NULL) {
57 array_writer.OpenDictEntry(&dict_writer);
58 dict_writer.AppendString(bluetooth_profile_manager::kNameOption);
59 dict_writer.AppendVariantOfString(*(options.name));
60 array_writer.CloseContainer(&dict_writer);
61 }
62
63 // Send Service if provided.
64 if (options.service.get() != NULL) {
65 dbus::MessageWriter dict_writer(NULL);
66 array_writer.OpenDictEntry(&dict_writer);
67 dict_writer.AppendString(bluetooth_profile_manager::kServiceOption);
68 dict_writer.AppendVariantOfString(*(options.service));
69 array_writer.CloseContainer(&dict_writer);
70 }
71
72 // Send Role if not the default value.
73 if (options.role != SYMMETRIC) {
74 dbus::MessageWriter dict_writer(NULL);
75 array_writer.OpenDictEntry(&dict_writer);
76 dict_writer.AppendString(bluetooth_profile_manager::kRoleOption);
77 if (options.role == CLIENT)
78 dict_writer.AppendVariantOfString(
79 bluetooth_profile_manager::kClientRoleOption);
80 else if (options.role == SERVER)
81 dict_writer.AppendVariantOfString(
82 bluetooth_profile_manager::kServerRoleOption);
83 else
84 dict_writer.AppendVariantOfString("");
85 array_writer.CloseContainer(&dict_writer);
86 }
87
88 // Send Channel if provided.
89 if (options.channel.get() != NULL) {
90 dbus::MessageWriter dict_writer(NULL);
91 array_writer.OpenDictEntry(&dict_writer);
92 dict_writer.AppendString(bluetooth_profile_manager::kChannelOption);
93 dict_writer.AppendVariantOfUint16(*(options.channel));
94 array_writer.CloseContainer(&dict_writer);
95 }
96
97 // Send PSM if provided.
98 if (options.psm.get() != NULL) {
99 dbus::MessageWriter dict_writer(NULL);
100 array_writer.OpenDictEntry(&dict_writer);
101 dict_writer.AppendString(bluetooth_profile_manager::kPSMOption);
102 dict_writer.AppendVariantOfUint16(*(options.psm));
103 array_writer.CloseContainer(&dict_writer);
104 }
105
106 // Send RequireAuthentication if provided.
107 if (options.require_authentication.get() != NULL) {
108 array_writer.OpenDictEntry(&dict_writer);
109 dict_writer.AppendString(
110 bluetooth_profile_manager::kRequireAuthenticationOption);
111 dict_writer.AppendVariantOfBool(*(options.require_authentication));
112 array_writer.CloseContainer(&dict_writer);
113 }
114
115 // Send RequireAuthorization if provided.
116 if (options.require_authorization.get() != NULL) {
117 array_writer.OpenDictEntry(&dict_writer);
118 dict_writer.AppendString(
119 bluetooth_profile_manager::kRequireAuthorizationOption);
120 dict_writer.AppendVariantOfBool(*(options.require_authorization));
121 array_writer.CloseContainer(&dict_writer);
122 }
123
124 // Send AutoConnect if provided.
125 if (options.auto_connect.get() != NULL) {
126 array_writer.OpenDictEntry(&dict_writer);
127 dict_writer.AppendString(
128 bluetooth_profile_manager::kAutoConnectOption);
129 dict_writer.AppendVariantOfBool(*(options.auto_connect));
130 array_writer.CloseContainer(&dict_writer);
131 }
132
133 // Send ServiceRecord if provided.
134 if (options.service_record.get() != NULL) {
135 dbus::MessageWriter dict_writer(NULL);
136 array_writer.OpenDictEntry(&dict_writer);
137 dict_writer.AppendString(bluetooth_profile_manager::kServiceRecordOption);
138 dict_writer.AppendVariantOfString(*(options.service_record));
139 array_writer.CloseContainer(&dict_writer);
140 }
141
142 // Send Version if provided.
143 if (options.version.get() != NULL) {
144 dbus::MessageWriter dict_writer(NULL);
145 array_writer.OpenDictEntry(&dict_writer);
146 dict_writer.AppendString(bluetooth_profile_manager::kVersionOption);
147 dict_writer.AppendVariantOfUint16(*(options.version));
148 array_writer.CloseContainer(&dict_writer);
149 }
150
151 // Send Features if provided.
152 if (options.features.get() != NULL) {
153 dbus::MessageWriter dict_writer(NULL);
154 array_writer.OpenDictEntry(&dict_writer);
155 dict_writer.AppendString(bluetooth_profile_manager::kFeaturesOption);
156 dict_writer.AppendVariantOfUint16(*(options.features));
157 array_writer.CloseContainer(&dict_writer);
158 }
159
160 writer.CloseContainer(&array_writer);
161
162 object_proxy_->CallMethodWithErrorCallback(
163 &method_call,
164 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
165 base::Bind(&BluetoothProfileManagerClientImpl::OnSuccess,
166 weak_ptr_factory_.GetWeakPtr(), callback),
167 base::Bind(&BluetoothProfileManagerClientImpl::OnError,
168 weak_ptr_factory_.GetWeakPtr(), error_callback));
169 }
170
171 // BluetoothProfileManagerClient override.
UnregisterProfile(const dbus::ObjectPath & profile_path,const base::Closure & callback,const ErrorCallback & error_callback)172 virtual void UnregisterProfile(const dbus::ObjectPath& profile_path,
173 const base::Closure& callback,
174 const ErrorCallback& error_callback) OVERRIDE {
175 dbus::MethodCall method_call(
176 bluetooth_profile_manager::kBluetoothProfileManagerInterface,
177 bluetooth_profile_manager::kUnregisterProfile);
178
179 dbus::MessageWriter writer(&method_call);
180 writer.AppendObjectPath(profile_path);
181
182 object_proxy_->CallMethodWithErrorCallback(
183 &method_call,
184 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
185 base::Bind(&BluetoothProfileManagerClientImpl::OnSuccess,
186 weak_ptr_factory_.GetWeakPtr(), callback),
187 base::Bind(&BluetoothProfileManagerClientImpl::OnError,
188 weak_ptr_factory_.GetWeakPtr(), error_callback));
189 }
190
191 protected:
Init(dbus::Bus * bus)192 virtual void Init(dbus::Bus* bus) OVERRIDE {
193 DCHECK(bus);
194 object_proxy_ = bus->GetObjectProxy(
195 bluetooth_profile_manager::kBluetoothProfileManagerServiceName,
196 dbus::ObjectPath(
197 bluetooth_profile_manager::kBluetoothProfileManagerServicePath));
198 }
199
200 private:
201 // Called when a response for successful method call is received.
OnSuccess(const base::Closure & callback,dbus::Response * response)202 void OnSuccess(const base::Closure& callback,
203 dbus::Response* response) {
204 DCHECK(response);
205 callback.Run();
206 }
207
208 // Called when a response for a failed method call is received.
OnError(const ErrorCallback & error_callback,dbus::ErrorResponse * response)209 void OnError(const ErrorCallback& error_callback,
210 dbus::ErrorResponse* response) {
211 // Error response has optional error message argument.
212 std::string error_name;
213 std::string error_message;
214 if (response) {
215 dbus::MessageReader reader(response);
216 error_name = response->GetErrorName();
217 reader.PopString(&error_message);
218 } else {
219 error_name = kNoResponseError;
220 error_message = "";
221 }
222 error_callback.Run(error_name, error_message);
223 }
224
225 dbus::ObjectProxy* object_proxy_;
226
227 // Weak pointer factory for generating 'this' pointers that might live longer
228 // than we do.
229 // Note: This should remain the last member so it'll be destroyed and
230 // invalidate its weak pointers before any other members are destroyed.
231 base::WeakPtrFactory<BluetoothProfileManagerClientImpl> weak_ptr_factory_;
232
233 DISALLOW_COPY_AND_ASSIGN(BluetoothProfileManagerClientImpl);
234 };
235
BluetoothProfileManagerClient()236 BluetoothProfileManagerClient::BluetoothProfileManagerClient() {
237 }
238
~BluetoothProfileManagerClient()239 BluetoothProfileManagerClient::~BluetoothProfileManagerClient() {
240 }
241
Create()242 BluetoothProfileManagerClient* BluetoothProfileManagerClient::Create() {
243 return new BluetoothProfileManagerClientImpl();
244 }
245
246 } // namespace chromeos
247