Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: device/bluetooth/bluetooth_profile_chromeos.cc

Issue 276573004: Bluetooth: Implement new socket API for Chrome OS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix DCHECK nits Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 "device/bluetooth/bluetooth_profile_chromeos.h"
6
7 #include <string>
8
9 #include "base/basictypes.h"
10 #include "base/bind.h"
11 #include "base/callback.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/strings/string_util.h"
17 #include "base/task_runner_util.h"
18 #include "base/threading/thread_restrictions.h"
19 #include "base/threading/worker_pool.h"
20 #include "chromeos/dbus/bluetooth_profile_manager_client.h"
21 #include "chromeos/dbus/bluetooth_profile_service_provider.h"
22 #include "chromeos/dbus/dbus_thread_manager.h"
23 #include "dbus/bus.h"
24 #include "dbus/file_descriptor.h"
25 #include "dbus/object_path.h"
26 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
27 #include "device/bluetooth/bluetooth_adapter_factory.h"
28 #include "device/bluetooth/bluetooth_device.h"
29 #include "device/bluetooth/bluetooth_device_chromeos.h"
30 #include "device/bluetooth/bluetooth_profile.h"
31 #include "device/bluetooth/bluetooth_socket.h"
32 #include "device/bluetooth/bluetooth_socket_chromeos.h"
33 #include "device/bluetooth/bluetooth_socket_thread.h"
34 #include "third_party/cros_system_api/dbus/service_constants.h"
35
36 using device::BluetoothAdapter;
37 using device::BluetoothAdapterFactory;
38 using device::BluetoothDevice;
39 using device::BluetoothProfile;
40 using device::BluetoothSocket;
41
42 namespace {
43
44 // Check the validity of a file descriptor received from D-Bus. Must be run
45 // on a thread where i/o is permitted.
46 scoped_ptr<dbus::FileDescriptor> CheckValidity(
47 scoped_ptr<dbus::FileDescriptor> fd) {
48 base::ThreadRestrictions::AssertIOAllowed();
49 fd->CheckValidity();
50 return fd.Pass();
51 }
52
53 } // namespace
54
55
56 namespace chromeos {
57
58 BluetoothProfileChromeOS::BluetoothProfileChromeOS(
59 scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
60 scoped_refptr<device::BluetoothSocketThread> socket_thread)
61 : ui_task_runner_(ui_task_runner),
62 socket_thread_(socket_thread),
63 weak_ptr_factory_(this) {
64 }
65
66 BluetoothProfileChromeOS::~BluetoothProfileChromeOS() {
67 DCHECK(object_path_.value().empty());
68 DCHECK(profile_.get() == NULL);
69
70 if (adapter_.get()) {
71 adapter_->RemoveObserver(this);
72 adapter_ = NULL;
73 }
74 }
75
76 void BluetoothProfileChromeOS::Init(
77 const device::BluetoothUUID& uuid,
78 const device::BluetoothProfile::Options& options,
79 const ProfileCallback& callback) {
80 DCHECK(object_path_.value().empty());
81 DCHECK(profile_.get() == NULL);
82
83 if (!uuid.IsValid()) {
84 callback.Run(NULL);
85 return;
86 }
87
88 uuid_ = uuid;
89
90 options_.name = options.name;
91 options_.service = uuid.canonical_value();
92 options_.channel = options.channel;
93 options_.psm = options.psm;
94 options_.require_authentication = options.require_authentication;
95 options_.require_authorization = options.require_authorization;
96 options_.auto_connect = options.auto_connect;
97 options_.version = options.version;
98 options_.features = options.features;
99
100 // The object path is relatively meaningless, but has to be unique, so we
101 // use the UUID of the profile.
102 std::string uuid_path;
103 base::ReplaceChars(uuid.canonical_value(), ":-", "_", &uuid_path);
104
105 object_path_ = dbus::ObjectPath("/org/chromium/bluetooth_profile/" +
106 uuid_path);
107
108 dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
109 profile_.reset(BluetoothProfileServiceProvider::Create(
110 system_bus, object_path_, this));
111 DCHECK(profile_.get());
112
113 // Now the profile object is registered we need an adapter to register it
114 // with.
115 BluetoothAdapterFactory::GetAdapter(
116 base::Bind(&BluetoothProfileChromeOS::OnGetAdapter,
117 weak_ptr_factory_.GetWeakPtr(),
118 callback));
119 }
120
121 void BluetoothProfileChromeOS::Unregister() {
122 DCHECK(!object_path_.value().empty());
123 DCHECK(profile_.get());
124
125 profile_.reset();
126
127 VLOG(1) << object_path_.value() << ": Unregister profile";
128 DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->
129 UnregisterProfile(
130 object_path_,
131 base::Bind(&BluetoothProfileChromeOS::OnUnregisterProfile,
132 weak_ptr_factory_.GetWeakPtr()),
133 base::Bind(&BluetoothProfileChromeOS::OnUnregisterProfileError,
134 weak_ptr_factory_.GetWeakPtr()));
135 }
136
137 void BluetoothProfileChromeOS::SetConnectionCallback(
138 const ConnectionCallback& callback) {
139 connection_callback_ = callback;
140 }
141
142 void BluetoothProfileChromeOS::AdapterPresentChanged(BluetoothAdapter* adapter,
143 bool present) {
144 if (!present)
145 return;
146
147 VLOG(1) << object_path_.value() << ": Register profile";
148 DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->
149 RegisterProfile(
150 object_path_,
151 uuid_.canonical_value(),
152 options_,
153 base::Bind(&BluetoothProfileChromeOS::OnInternalRegisterProfile,
154 weak_ptr_factory_.GetWeakPtr()),
155 base::Bind(&BluetoothProfileChromeOS::OnInternalRegisterProfileError,
156 weak_ptr_factory_.GetWeakPtr()));
157 }
158
159 void BluetoothProfileChromeOS::OnGetAdapter(
160 const ProfileCallback& callback,
161 scoped_refptr<device::BluetoothAdapter> adapter) {
162 DCHECK(!adapter_.get());
163 adapter_ = adapter;
164 adapter_->AddObserver(this);
165
166 VLOG(1) << object_path_.value() << ": Register profile";
167 DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->
168 RegisterProfile(
169 object_path_,
170 uuid_.canonical_value(),
171 options_,
172 base::Bind(&BluetoothProfileChromeOS::OnRegisterProfile,
173 weak_ptr_factory_.GetWeakPtr(),
174 callback),
175 base::Bind(&BluetoothProfileChromeOS::OnRegisterProfileError,
176 weak_ptr_factory_.GetWeakPtr(),
177 callback));
178 }
179
180 void BluetoothProfileChromeOS::Released() {
181 VLOG(1) << object_path_.value() << ": Release";
182 }
183
184 void BluetoothProfileChromeOS::NewConnection(
185 const dbus::ObjectPath& device_path,
186 scoped_ptr<dbus::FileDescriptor> fd,
187 const BluetoothProfileServiceProvider::Delegate::Options& options,
188 const ConfirmationCallback& callback) {
189 VLOG(1) << object_path_.value() << ": New connection from device: "
190 << device_path.value();
191 if (connection_callback_.is_null()) {
192 callback.Run(REJECTED);
193 return;
194 }
195
196 // Punt descriptor validity check to a worker thread where i/o is permitted;
197 // on return we'll call the connection callback.
198 //
199 // base::Passed is used to take ownership of the file descriptor during the
200 // CheckValidity() call and pass that ownership to callback.
201 base::PostTaskAndReplyWithResult(
202 base::WorkerPool::GetTaskRunner(false).get(),
203 FROM_HERE,
204 base::Bind(&CheckValidity, base::Passed(&fd)),
205 base::Bind(&BluetoothProfileChromeOS::OnCheckValidity,
206 weak_ptr_factory_.GetWeakPtr(),
207 device_path,
208 options,
209 callback));
210 }
211
212 void BluetoothProfileChromeOS::RequestDisconnection(
213 const dbus::ObjectPath& device_path,
214 const ConfirmationCallback& callback) {
215 VLOG(1) << object_path_.value() << ": Request disconnection";
216 callback.Run(SUCCESS);
217 }
218
219 void BluetoothProfileChromeOS::Cancel() {
220 VLOG(1) << object_path_.value() << ": Cancel";
221 }
222
223 void BluetoothProfileChromeOS::OnInternalRegisterProfile() {
224 VLOG(1) << object_path_.value() << ": Profile registered";
225 }
226
227 void BluetoothProfileChromeOS::OnInternalRegisterProfileError(
228 const std::string& error_name,
229 const std::string& error_message) {
230 // It's okay if the profile already exists, it means we registered it on
231 // initialization.
232 if (error_name == bluetooth_profile_manager::kErrorAlreadyExists)
233 return;
234
235 LOG(WARNING) << object_path_.value() << ": Failed to register profile: "
236 << error_name << ": " << error_message;
237 }
238
239 void BluetoothProfileChromeOS::OnRegisterProfile(
240 const ProfileCallback& callback) {
241 VLOG(1) << object_path_.value() << ": Profile registered";
242 callback.Run(this);
243 }
244
245 void BluetoothProfileChromeOS::OnRegisterProfileError(
246 const ProfileCallback& callback,
247 const std::string& error_name,
248 const std::string& error_message) {
249 // It's okay if the profile already exists, it means we registered it when
250 // we first saw the adapter.
251 if (error_name == bluetooth_profile_manager::kErrorAlreadyExists)
252 return;
253
254 LOG(WARNING) << object_path_.value() << ": Failed to register profile: "
255 << error_name << ": " << error_message;
256 callback.Run(NULL);
257 }
258
259 void BluetoothProfileChromeOS::OnUnregisterProfile() {
260 VLOG(1) << object_path_.value() << ": Profile unregistered";
261 object_path_ = dbus::ObjectPath("");
262 delete this;
263 }
264
265 void BluetoothProfileChromeOS::OnUnregisterProfileError(
266 const std::string& error_name,
267 const std::string& error_message) {
268 // It's okay if the profile didn't exist, it means we never saw an adapter.
269 if (error_name == bluetooth_profile_manager::kErrorDoesNotExist)
270 return;
271
272 LOG(WARNING) << object_path_.value() << ": Failed to unregister profile: "
273 << error_name << ": " << error_message;
274 object_path_ = dbus::ObjectPath("");
275 delete this;
276 }
277
278 void BluetoothProfileChromeOS::OnCheckValidity(
279 const dbus::ObjectPath& device_path,
280 const BluetoothProfileServiceProvider::Delegate::Options& options,
281 const ConfirmationCallback& callback,
282 scoped_ptr<dbus::FileDescriptor> fd) {
283 VLOG(1) << object_path_.value() << ": Validity check complete";
284 if (!fd->is_valid()) {
285 callback.Run(REJECTED);
286 return;
287 }
288
289 scoped_refptr<BluetoothSocketChromeOS> socket =
290 BluetoothSocketChromeOS::CreateBluetoothSocket(
291 ui_task_runner_,
292 socket_thread_,
293 NULL,
294 net::NetLog::Source());
295 socket->Connect(fd.Pass(),
296 base::Bind(&BluetoothProfileChromeOS::OnConnect,
297 weak_ptr_factory_.GetWeakPtr(),
298 device_path,
299 socket,
300 callback),
301 base::Bind(&BluetoothProfileChromeOS::OnConnectError,
302 weak_ptr_factory_.GetWeakPtr(),
303 callback));
304 }
305
306 void BluetoothProfileChromeOS::OnConnect(
307 const dbus::ObjectPath& device_path,
308 scoped_refptr<BluetoothSocketChromeOS> socket,
309 const ConfirmationCallback& callback) {
310 VLOG(1) << object_path_.value() << ": Profile connection complete";
311
312 BluetoothDeviceChromeOS* device =
313 static_cast<BluetoothAdapterChromeOS*>(adapter_.get())->
314 GetDeviceWithPath(device_path);
315 DCHECK(device);
316
317 connection_callback_.Run(device, socket);
318 callback.Run(SUCCESS);
319 }
320
321 void BluetoothProfileChromeOS::OnConnectError(
322 const ConfirmationCallback& callback,
323 const std::string& error_message) {
324 VLOG(1) << object_path_.value() << ": Profile connection failed: "
325 << error_message;
326
327 callback.Run(REJECTED);
328 }
329
330 } // namespace chromeos
OLDNEW
« no previous file with comments | « device/bluetooth/bluetooth_profile_chromeos.h ('k') | device/bluetooth/bluetooth_profile_chromeos_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698