• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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