OLD | NEW |
| (Empty) |
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 "chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h" | |
6 | |
7 #include <map> | |
8 #include <string> | |
9 #include <vector> | |
10 | |
11 #include "base/bind.h" | |
12 #include "base/command_line.h" | |
13 #include "base/logging.h" | |
14 #include "base/memory/scoped_vector.h" | |
15 #include "base/memory/weak_ptr.h" | |
16 #include "base/string16.h" | |
17 #include "base/string_util.h" | |
18 #include "base/values.h" | |
19 #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h" | |
20 #include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" | |
21 #include "chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.h" | |
22 #include "chrome/browser/chromeos/bluetooth/bluetooth_utils.h" | |
23 #include "chromeos/dbus/bluetooth_adapter_client.h" | |
24 #include "chromeos/dbus/bluetooth_agent_service_provider.h" | |
25 #include "chromeos/dbus/bluetooth_device_client.h" | |
26 #include "chromeos/dbus/bluetooth_input_client.h" | |
27 #include "chromeos/dbus/bluetooth_out_of_band_client.h" | |
28 #include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h" | |
29 #include "chromeos/dbus/dbus_thread_manager.h" | |
30 #include "chromeos/dbus/introspectable_client.h" | |
31 #include "dbus/bus.h" | |
32 #include "dbus/object_path.h" | |
33 #include "third_party/cros_system_api/dbus/service_constants.h" | |
34 | |
35 namespace chromeos { | |
36 | |
37 BluetoothDeviceChromeOs::BluetoothDeviceChromeOs( | |
38 BluetoothAdapterChromeOs* adapter) | |
39 : BluetoothDevice(), | |
40 adapter_(adapter), | |
41 pairing_delegate_(NULL), | |
42 connecting_applications_counter_(0), | |
43 weak_ptr_factory_(this) { | |
44 } | |
45 | |
46 BluetoothDeviceChromeOs::~BluetoothDeviceChromeOs() { | |
47 } | |
48 | |
49 bool BluetoothDeviceChromeOs::IsPaired() const { | |
50 return !object_path_.value().empty(); | |
51 } | |
52 | |
53 const BluetoothDevice::ServiceList& | |
54 BluetoothDeviceChromeOs::GetServices() const { | |
55 return service_uuids_; | |
56 } | |
57 | |
58 void BluetoothDeviceChromeOs::GetServiceRecords( | |
59 const ServiceRecordsCallback& callback, | |
60 const ErrorCallback& error_callback) { | |
61 DBusThreadManager::Get()->GetBluetoothDeviceClient()-> | |
62 DiscoverServices( | |
63 object_path_, | |
64 "", // empty pattern to browse all services | |
65 base::Bind(&BluetoothDeviceChromeOs::CollectServiceRecordsCallback, | |
66 weak_ptr_factory_.GetWeakPtr(), | |
67 callback, | |
68 error_callback)); | |
69 } | |
70 | |
71 bool BluetoothDeviceChromeOs::ProvidesServiceWithUUID( | |
72 const std::string& uuid) const { | |
73 const BluetoothDevice::ServiceList& services = GetServices(); | |
74 for (BluetoothDevice::ServiceList::const_iterator iter = services.begin(); | |
75 iter != services.end(); | |
76 ++iter) { | |
77 if (bluetooth_utils::CanonicalUuid(*iter) == uuid) | |
78 return true; | |
79 } | |
80 return false; | |
81 } | |
82 | |
83 void BluetoothDeviceChromeOs::ProvidesServiceWithName( | |
84 const std::string& name, | |
85 const ProvidesServiceCallback& callback) { | |
86 GetServiceRecords( | |
87 base::Bind(&BluetoothDeviceChromeOs::SearchServicesForNameCallback, | |
88 weak_ptr_factory_.GetWeakPtr(), | |
89 name, | |
90 callback), | |
91 base::Bind(&BluetoothDeviceChromeOs::SearchServicesForNameErrorCallback, | |
92 weak_ptr_factory_.GetWeakPtr(), | |
93 callback)); | |
94 } | |
95 | |
96 bool BluetoothDeviceChromeOs::ExpectingPinCode() const { | |
97 return !pincode_callback_.is_null(); | |
98 } | |
99 | |
100 bool BluetoothDeviceChromeOs::ExpectingPasskey() const { | |
101 return !passkey_callback_.is_null(); | |
102 } | |
103 | |
104 bool BluetoothDeviceChromeOs::ExpectingConfirmation() const { | |
105 return !confirmation_callback_.is_null(); | |
106 } | |
107 | |
108 void BluetoothDeviceChromeOs::Connect(PairingDelegate* pairing_delegate, | |
109 const base::Closure& callback, | |
110 const ErrorCallback& error_callback) { | |
111 if (IsPaired() || IsBonded() || IsConnected()) { | |
112 // Connection to already paired or connected device. | |
113 ConnectApplications(callback, error_callback); | |
114 | |
115 } else if (!pairing_delegate) { | |
116 // No pairing delegate supplied, initiate low-security connection only. | |
117 DBusThreadManager::Get()->GetBluetoothAdapterClient()-> | |
118 CreateDevice(adapter_->object_path_, | |
119 address_, | |
120 base::Bind(&BluetoothDeviceChromeOs::ConnectCallback, | |
121 weak_ptr_factory_.GetWeakPtr(), | |
122 callback, | |
123 error_callback), | |
124 base::Bind(&BluetoothDeviceChromeOs::ConnectErrorCallback, | |
125 weak_ptr_factory_.GetWeakPtr(), | |
126 error_callback)); | |
127 } else { | |
128 // Initiate high-security connection with pairing. | |
129 DCHECK(!pairing_delegate_); | |
130 pairing_delegate_ = pairing_delegate; | |
131 | |
132 // The agent path is relatively meaningless, we use the device address | |
133 // to generate it as we only support one pairing attempt at a time for | |
134 // a given bluetooth device. | |
135 DCHECK(agent_.get() == NULL); | |
136 | |
137 std::string agent_path_basename; | |
138 ReplaceChars(address_, ":", "_", &agent_path_basename); | |
139 dbus::ObjectPath agent_path("/org/chromium/bluetooth_agent/" + | |
140 agent_path_basename); | |
141 | |
142 dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); | |
143 if (system_bus) { | |
144 agent_.reset(BluetoothAgentServiceProvider::Create(system_bus, | |
145 agent_path, | |
146 this)); | |
147 } else { | |
148 agent_.reset(NULL); | |
149 } | |
150 | |
151 DVLOG(1) << "Pairing: " << address_; | |
152 DBusThreadManager::Get()->GetBluetoothAdapterClient()-> | |
153 CreatePairedDevice( | |
154 adapter_->object_path_, | |
155 address_, | |
156 agent_path, | |
157 bluetooth_agent::kDisplayYesNoCapability, | |
158 base::Bind(&BluetoothDeviceChromeOs::ConnectCallback, | |
159 weak_ptr_factory_.GetWeakPtr(), | |
160 callback, | |
161 error_callback), | |
162 base::Bind(&BluetoothDeviceChromeOs::ConnectErrorCallback, | |
163 weak_ptr_factory_.GetWeakPtr(), | |
164 error_callback)); | |
165 } | |
166 } | |
167 | |
168 void BluetoothDeviceChromeOs::SetPinCode(const std::string& pincode) { | |
169 if (!agent_.get() || pincode_callback_.is_null()) | |
170 return; | |
171 | |
172 pincode_callback_.Run(SUCCESS, pincode); | |
173 pincode_callback_.Reset(); | |
174 } | |
175 | |
176 void BluetoothDeviceChromeOs::SetPasskey(uint32 passkey) { | |
177 if (!agent_.get() || passkey_callback_.is_null()) | |
178 return; | |
179 | |
180 passkey_callback_.Run(SUCCESS, passkey); | |
181 passkey_callback_.Reset(); | |
182 } | |
183 | |
184 void BluetoothDeviceChromeOs::ConfirmPairing() { | |
185 if (!agent_.get() || confirmation_callback_.is_null()) | |
186 return; | |
187 | |
188 confirmation_callback_.Run(SUCCESS); | |
189 confirmation_callback_.Reset(); | |
190 } | |
191 | |
192 void BluetoothDeviceChromeOs::RejectPairing() { | |
193 if (!agent_.get()) | |
194 return; | |
195 | |
196 if (!pincode_callback_.is_null()) { | |
197 pincode_callback_.Run(REJECTED, ""); | |
198 pincode_callback_.Reset(); | |
199 } | |
200 if (!passkey_callback_.is_null()) { | |
201 passkey_callback_.Run(REJECTED, 0); | |
202 passkey_callback_.Reset(); | |
203 } | |
204 if (!confirmation_callback_.is_null()) { | |
205 confirmation_callback_.Run(REJECTED); | |
206 confirmation_callback_.Reset(); | |
207 } | |
208 } | |
209 | |
210 void BluetoothDeviceChromeOs::CancelPairing() { | |
211 if (!agent_.get()) | |
212 return; | |
213 | |
214 if (!pincode_callback_.is_null()) { | |
215 pincode_callback_.Run(CANCELLED, ""); | |
216 pincode_callback_.Reset(); | |
217 } | |
218 if (!passkey_callback_.is_null()) { | |
219 passkey_callback_.Run(CANCELLED, 0); | |
220 passkey_callback_.Reset(); | |
221 } | |
222 if (!confirmation_callback_.is_null()) { | |
223 confirmation_callback_.Run(CANCELLED); | |
224 confirmation_callback_.Reset(); | |
225 } | |
226 } | |
227 | |
228 void BluetoothDeviceChromeOs::Disconnect(const base::Closure& callback, | |
229 const ErrorCallback& error_callback) { | |
230 DBusThreadManager::Get()->GetBluetoothDeviceClient()-> | |
231 Disconnect(object_path_, | |
232 base::Bind(&BluetoothDeviceChromeOs::DisconnectCallback, | |
233 weak_ptr_factory_.GetWeakPtr(), | |
234 callback, | |
235 error_callback)); | |
236 | |
237 } | |
238 | |
239 void BluetoothDeviceChromeOs::Forget(const ErrorCallback& error_callback) { | |
240 DBusThreadManager::Get()->GetBluetoothAdapterClient()-> | |
241 RemoveDevice(adapter_->object_path_, | |
242 object_path_, | |
243 base::Bind(&BluetoothDeviceChromeOs::ForgetCallback, | |
244 weak_ptr_factory_.GetWeakPtr(), | |
245 error_callback)); | |
246 } | |
247 | |
248 void BluetoothDeviceChromeOs::ConnectToService(const std::string& service_uuid, | |
249 const SocketCallback& callback) { | |
250 GetServiceRecords( | |
251 base::Bind(&BluetoothDeviceChromeOs::GetServiceRecordsForConnectCallback, | |
252 weak_ptr_factory_.GetWeakPtr(), | |
253 service_uuid, | |
254 callback), | |
255 base::Bind( | |
256 &BluetoothDeviceChromeOs::GetServiceRecordsForConnectErrorCallback, | |
257 weak_ptr_factory_.GetWeakPtr(), | |
258 callback)); | |
259 } | |
260 | |
261 void BluetoothDeviceChromeOs::SetOutOfBandPairingData( | |
262 const chromeos::BluetoothOutOfBandPairingData& data, | |
263 const base::Closure& callback, | |
264 const ErrorCallback& error_callback) { | |
265 DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> | |
266 AddRemoteData( | |
267 object_path_, | |
268 address(), | |
269 data, | |
270 base::Bind(&BluetoothDeviceChromeOs::OnRemoteDataCallback, | |
271 weak_ptr_factory_.GetWeakPtr(), | |
272 callback, | |
273 error_callback)); | |
274 } | |
275 | |
276 void BluetoothDeviceChromeOs::ClearOutOfBandPairingData( | |
277 const base::Closure& callback, | |
278 const ErrorCallback& error_callback) { | |
279 DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> | |
280 RemoveRemoteData( | |
281 object_path_, | |
282 address(), | |
283 base::Bind(&BluetoothDeviceChromeOs::OnRemoteDataCallback, | |
284 weak_ptr_factory_.GetWeakPtr(), | |
285 callback, | |
286 error_callback)); | |
287 } | |
288 | |
289 void BluetoothDeviceChromeOs::SetObjectPath( | |
290 const dbus::ObjectPath& object_path) { | |
291 DCHECK(object_path_ == dbus::ObjectPath("")); | |
292 object_path_ = object_path; | |
293 } | |
294 | |
295 void BluetoothDeviceChromeOs::RemoveObjectPath() { | |
296 DCHECK(object_path_ != dbus::ObjectPath("")); | |
297 object_path_ = dbus::ObjectPath(""); | |
298 } | |
299 | |
300 void BluetoothDeviceChromeOs::Update( | |
301 const BluetoothDeviceClient::Properties* properties, | |
302 bool update_state) { | |
303 std::string address = properties->address.value(); | |
304 std::string name = properties->name.value(); | |
305 uint32 bluetooth_class = properties->bluetooth_class.value(); | |
306 const std::vector<std::string>& uuids = properties->uuids.value(); | |
307 | |
308 if (!address.empty()) | |
309 address_ = address; | |
310 if (!name.empty()) | |
311 name_ = name; | |
312 if (bluetooth_class) | |
313 bluetooth_class_ = bluetooth_class; | |
314 if (!uuids.empty()) { | |
315 service_uuids_.clear(); | |
316 service_uuids_.assign(uuids.begin(), uuids.end()); | |
317 } | |
318 | |
319 if (update_state) { | |
320 // BlueZ uses paired to mean link keys exchanged, whereas the Bluetooth | |
321 // spec refers to this as bonded. Use the spec name for our interface. | |
322 bonded_ = properties->paired.value(); | |
323 connected_ = properties->connected.value(); | |
324 } | |
325 } | |
326 | |
327 void BluetoothDeviceChromeOs::ConnectCallback( | |
328 const base::Closure& callback, | |
329 const ErrorCallback& error_callback, | |
330 const dbus::ObjectPath& device_path) { | |
331 DVLOG(1) << "Connection successful: " << device_path.value(); | |
332 if (object_path_.value().empty()) { | |
333 object_path_ = device_path; | |
334 } else { | |
335 LOG_IF(WARNING, object_path_ != device_path) | |
336 << "Conflicting device paths for objects, result gave: " | |
337 << device_path.value() << " but signal gave: " | |
338 << object_path_.value(); | |
339 } | |
340 | |
341 // Mark the device trusted so it can connect to us automatically, and | |
342 // we can connect after rebooting. This information is part of the | |
343 // pairing information of the device, and is unique to the combination | |
344 // of our bluetooth address and the device's bluetooth address. A | |
345 // different host needs a new pairing, so it's not useful to sync. | |
346 DBusThreadManager::Get()->GetBluetoothDeviceClient()-> | |
347 GetProperties(object_path_)->trusted.Set( | |
348 true, | |
349 base::Bind(&BluetoothDeviceChromeOs::OnSetTrusted, | |
350 weak_ptr_factory_.GetWeakPtr(), | |
351 callback, | |
352 error_callback)); | |
353 | |
354 // Connect application-layer protocols. | |
355 ConnectApplications(callback, error_callback); | |
356 } | |
357 | |
358 void BluetoothDeviceChromeOs::ConnectErrorCallback( | |
359 const ErrorCallback& error_callback, | |
360 const std::string& error_name, | |
361 const std::string& error_message) { | |
362 LOG(WARNING) << "Connection failed: " << address_ | |
363 << ": " << error_name << ": " << error_message; | |
364 error_callback.Run(); | |
365 } | |
366 | |
367 void BluetoothDeviceChromeOs::CollectServiceRecordsCallback( | |
368 const ServiceRecordsCallback& callback, | |
369 const ErrorCallback& error_callback, | |
370 const dbus::ObjectPath& device_path, | |
371 const BluetoothDeviceClient::ServiceMap& service_map, | |
372 bool success) { | |
373 if (!success) { | |
374 error_callback.Run(); | |
375 return; | |
376 } | |
377 | |
378 ScopedVector<BluetoothServiceRecord> records; | |
379 for (BluetoothDeviceClient::ServiceMap::const_iterator i = | |
380 service_map.begin(); i != service_map.end(); ++i) { | |
381 records.push_back( | |
382 new BluetoothServiceRecord(address(), i->second)); | |
383 } | |
384 callback.Run(records); | |
385 } | |
386 | |
387 void BluetoothDeviceChromeOs::OnSetTrusted(const base::Closure& callback, | |
388 const ErrorCallback& error_callback, | |
389 bool success) { | |
390 if (success) { | |
391 callback.Run(); | |
392 } else { | |
393 LOG(WARNING) << "Failed to set device as trusted: " << address_; | |
394 error_callback.Run(); | |
395 } | |
396 } | |
397 | |
398 void BluetoothDeviceChromeOs::ConnectApplications( | |
399 const base::Closure& callback, | |
400 const ErrorCallback& error_callback) { | |
401 // Introspect the device object to determine supported applications. | |
402 DBusThreadManager::Get()->GetIntrospectableClient()-> | |
403 Introspect(bluetooth_device::kBluetoothDeviceServiceName, | |
404 object_path_, | |
405 base::Bind(&BluetoothDeviceChromeOs::OnIntrospect, | |
406 weak_ptr_factory_.GetWeakPtr(), | |
407 callback, | |
408 error_callback)); | |
409 } | |
410 | |
411 void BluetoothDeviceChromeOs::OnIntrospect(const base::Closure& callback, | |
412 const ErrorCallback& error_callback, | |
413 const std::string& service_name, | |
414 const dbus::ObjectPath& device_path, | |
415 const std::string& xml_data, | |
416 bool success) { | |
417 if (!success) { | |
418 LOG(WARNING) << "Failed to determine supported applications: " << address_; | |
419 error_callback.Run(); | |
420 return; | |
421 } | |
422 | |
423 // The introspection data for the device object may list one or more | |
424 // additional D-Bus interfaces that BlueZ supports for this particular | |
425 // device. Send appropraite Connect calls for each of those interfaces | |
426 // to connect all of the application protocols for this device. | |
427 std::vector<std::string> interfaces = | |
428 IntrospectableClient::GetInterfacesFromIntrospectResult(xml_data); | |
429 | |
430 DCHECK_EQ(0, connecting_applications_counter_); | |
431 connecting_applications_counter_ = 0; | |
432 for (std::vector<std::string>::iterator iter = interfaces.begin(); | |
433 iter != interfaces.end(); ++iter) { | |
434 if (*iter == bluetooth_input::kBluetoothInputInterface) { | |
435 connecting_applications_counter_++; | |
436 // Supports Input interface. | |
437 DBusThreadManager::Get()->GetBluetoothInputClient()-> | |
438 Connect(object_path_, | |
439 base::Bind(&BluetoothDeviceChromeOs::OnConnect, | |
440 weak_ptr_factory_.GetWeakPtr(), | |
441 callback, | |
442 *iter), | |
443 base::Bind(&BluetoothDeviceChromeOs::OnConnectError, | |
444 weak_ptr_factory_.GetWeakPtr(), | |
445 error_callback, *iter)); | |
446 } | |
447 } | |
448 | |
449 // If OnConnect has been called for every call to Connect above, then this | |
450 // will decrement the counter to -1. In that case, call the callback | |
451 // directly as it has not been called by any of the OnConnect callbacks. | |
452 // This is safe because OnIntrospect and OnConnect run on the same thread. | |
453 connecting_applications_counter_--; | |
454 if (connecting_applications_counter_ == -1) | |
455 callback.Run(); | |
456 } | |
457 | |
458 void BluetoothDeviceChromeOs::OnConnect(const base::Closure& callback, | |
459 const std::string& interface_name, | |
460 const dbus::ObjectPath& device_path) { | |
461 DVLOG(1) << "Application connection successful: " << device_path.value() | |
462 << ": " << interface_name; | |
463 | |
464 connecting_applications_counter_--; | |
465 // |callback| should only be called once, meaning it cannot be called before | |
466 // all requests have been started. The extra decrement after all requests | |
467 // have been started, and the check for -1 instead of 0 below, insure only a | |
468 // single call to |callback| will occur (provided OnConnect and OnIntrospect | |
469 // run on the same thread, which is true). | |
470 if (connecting_applications_counter_ == -1) { | |
471 connecting_applications_counter_ = 0; | |
472 callback.Run(); | |
473 } | |
474 } | |
475 | |
476 void BluetoothDeviceChromeOs::OnConnectError( | |
477 const ErrorCallback& error_callback, | |
478 const std::string& interface_name, | |
479 const dbus::ObjectPath& device_path, | |
480 const std::string& error_name, | |
481 const std::string& error_message) { | |
482 LOG(WARNING) << "Connection failed: " << address_ << ": " << interface_name | |
483 << ": " << error_name << ": " << error_message; | |
484 error_callback.Run(); | |
485 } | |
486 | |
487 void BluetoothDeviceChromeOs::DisconnectCallback( | |
488 const base::Closure& callback, | |
489 const ErrorCallback& error_callback, | |
490 const dbus::ObjectPath& device_path, | |
491 bool success) { | |
492 DCHECK(device_path == object_path_); | |
493 if (success) { | |
494 DVLOG(1) << "Disconnection successful: " << address_; | |
495 callback.Run(); | |
496 } else { | |
497 LOG(WARNING) << "Disconnection failed: " << address_; | |
498 error_callback.Run(); | |
499 } | |
500 } | |
501 | |
502 void BluetoothDeviceChromeOs::ForgetCallback( | |
503 const ErrorCallback& error_callback, | |
504 const dbus::ObjectPath& adapter_path, | |
505 bool success) { | |
506 // It's quite normal that this path never gets called on success; we use a | |
507 // weak pointer, and bluetoothd might send the DeviceRemoved signal before | |
508 // the method reply, in which case this object is deleted and the | |
509 // callback never takes place. Therefore don't do anything here for the | |
510 // success case. | |
511 if (!success) { | |
512 LOG(WARNING) << "Forget failed: " << address_; | |
513 error_callback.Run(); | |
514 } | |
515 } | |
516 | |
517 void BluetoothDeviceChromeOs::SearchServicesForNameErrorCallback( | |
518 const ProvidesServiceCallback& callback) { | |
519 callback.Run(false); | |
520 } | |
521 | |
522 void BluetoothDeviceChromeOs::SearchServicesForNameCallback( | |
523 const std::string& name, | |
524 const ProvidesServiceCallback& callback, | |
525 const ServiceRecordList& list) { | |
526 for (ServiceRecordList::const_iterator i = list.begin(); | |
527 i != list.end(); ++i) { | |
528 if ((*i)->name() == name) { | |
529 callback.Run(true); | |
530 return; | |
531 } | |
532 } | |
533 callback.Run(false); | |
534 } | |
535 | |
536 void BluetoothDeviceChromeOs::GetServiceRecordsForConnectErrorCallback( | |
537 const SocketCallback& callback) { | |
538 callback.Run(NULL); | |
539 } | |
540 | |
541 void BluetoothDeviceChromeOs::GetServiceRecordsForConnectCallback( | |
542 const std::string& service_uuid, | |
543 const SocketCallback& callback, | |
544 const ServiceRecordList& list) { | |
545 for (ServiceRecordList::const_iterator i = list.begin(); | |
546 i != list.end(); ++i) { | |
547 if ((*i)->uuid() == service_uuid) { | |
548 // If multiple service records are found, use the first one that works. | |
549 scoped_refptr<BluetoothSocket> socket( | |
550 BluetoothSocketChromeOs::CreateBluetoothSocket(**i)); | |
551 if (socket.get() != NULL) { | |
552 callback.Run(socket); | |
553 return; | |
554 } | |
555 } | |
556 } | |
557 callback.Run(NULL); | |
558 } | |
559 | |
560 void BluetoothDeviceChromeOs::OnRemoteDataCallback( | |
561 const base::Closure& callback, | |
562 const ErrorCallback& error_callback, | |
563 bool success) { | |
564 if (success) | |
565 callback.Run(); | |
566 else | |
567 error_callback.Run(); | |
568 } | |
569 | |
570 void BluetoothDeviceChromeOs::DisconnectRequested( | |
571 const dbus::ObjectPath& object_path) { | |
572 DCHECK(object_path == object_path_); | |
573 } | |
574 | |
575 void BluetoothDeviceChromeOs::Release() { | |
576 DCHECK(agent_.get()); | |
577 DVLOG(1) << "Release: " << address_; | |
578 | |
579 DCHECK(pairing_delegate_); | |
580 pairing_delegate_->DismissDisplayOrConfirm(); | |
581 pairing_delegate_ = NULL; | |
582 | |
583 pincode_callback_.Reset(); | |
584 passkey_callback_.Reset(); | |
585 confirmation_callback_.Reset(); | |
586 | |
587 agent_.reset(); | |
588 } | |
589 | |
590 void BluetoothDeviceChromeOs::RequestPinCode( | |
591 const dbus::ObjectPath& device_path, | |
592 const PinCodeCallback& callback) { | |
593 DCHECK(agent_.get()); | |
594 DVLOG(1) << "RequestPinCode: " << device_path.value(); | |
595 | |
596 DCHECK(pairing_delegate_); | |
597 DCHECK(pincode_callback_.is_null()); | |
598 pincode_callback_ = callback; | |
599 pairing_delegate_->RequestPinCode(this); | |
600 } | |
601 | |
602 void BluetoothDeviceChromeOs::RequestPasskey( | |
603 const dbus::ObjectPath& device_path, | |
604 const PasskeyCallback& callback) { | |
605 DCHECK(agent_.get()); | |
606 DCHECK(device_path == object_path_); | |
607 DVLOG(1) << "RequestPasskey: " << device_path.value(); | |
608 | |
609 DCHECK(pairing_delegate_); | |
610 DCHECK(passkey_callback_.is_null()); | |
611 passkey_callback_ = callback; | |
612 pairing_delegate_->RequestPasskey(this); | |
613 } | |
614 | |
615 void BluetoothDeviceChromeOs::DisplayPinCode( | |
616 const dbus::ObjectPath& device_path, | |
617 const std::string& pincode) { | |
618 DCHECK(agent_.get()); | |
619 DCHECK(device_path == object_path_); | |
620 DVLOG(1) << "DisplayPinCode: " << device_path.value() << " " << pincode; | |
621 | |
622 DCHECK(pairing_delegate_); | |
623 pairing_delegate_->DisplayPinCode(this, pincode); | |
624 } | |
625 | |
626 void BluetoothDeviceChromeOs::DisplayPasskey( | |
627 const dbus::ObjectPath& device_path, | |
628 uint32 passkey) { | |
629 DCHECK(agent_.get()); | |
630 DCHECK(device_path == object_path_); | |
631 DVLOG(1) << "DisplayPasskey: " << device_path.value() << " " << passkey; | |
632 | |
633 DCHECK(pairing_delegate_); | |
634 pairing_delegate_->DisplayPasskey(this, passkey); | |
635 } | |
636 | |
637 void BluetoothDeviceChromeOs::RequestConfirmation( | |
638 const dbus::ObjectPath& device_path, | |
639 uint32 passkey, | |
640 const ConfirmationCallback& callback) { | |
641 DCHECK(agent_.get()); | |
642 DCHECK(device_path == object_path_); | |
643 DVLOG(1) << "RequestConfirmation: " << device_path.value() << " " << passkey; | |
644 | |
645 DCHECK(pairing_delegate_); | |
646 DCHECK(confirmation_callback_.is_null()); | |
647 confirmation_callback_ = callback; | |
648 pairing_delegate_->ConfirmPasskey(this, passkey); | |
649 } | |
650 | |
651 void BluetoothDeviceChromeOs::Authorize(const dbus::ObjectPath& device_path, | |
652 const std::string& uuid, | |
653 const ConfirmationCallback& callback) { | |
654 DCHECK(agent_.get()); | |
655 DCHECK(device_path == object_path_); | |
656 LOG(WARNING) << "Rejected authorization for service: " << uuid | |
657 << " requested from device: " << device_path.value(); | |
658 callback.Run(REJECTED); | |
659 } | |
660 | |
661 void BluetoothDeviceChromeOs::ConfirmModeChange( | |
662 Mode mode, | |
663 const ConfirmationCallback& callback) { | |
664 DCHECK(agent_.get()); | |
665 LOG(WARNING) << "Rejected adapter-level mode change: " << mode | |
666 << " made on agent for device: " << address_; | |
667 callback.Run(REJECTED); | |
668 } | |
669 | |
670 void BluetoothDeviceChromeOs::Cancel() { | |
671 DCHECK(agent_.get()); | |
672 DVLOG(1) << "Cancel: " << address_; | |
673 | |
674 DCHECK(pairing_delegate_); | |
675 pairing_delegate_->DismissDisplayOrConfirm(); | |
676 } | |
677 | |
678 | |
679 // static | |
680 BluetoothDeviceChromeOs* BluetoothDeviceChromeOs::Create( | |
681 BluetoothAdapterChromeOs* adapter) { | |
682 return new BluetoothDeviceChromeOs(adapter); | |
683 } | |
684 | |
685 } // namespace chromeos | |
OLD | NEW |