bluetooth_device_chromeos.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "device/bluetooth/bluetooth_device_chromeos.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <stdio.h> 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/metrics/histogram.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_adapter_client.h" 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_device_client.h" 16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chromeos/dbus/bluetooth_gatt_service_client.h" 177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_input_client.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/bus.h" 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_chromeos.h" 216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "device/bluetooth/bluetooth_gatt_connection_chromeos.h" 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "device/bluetooth/bluetooth_pairing_chromeos.h" 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h" 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "device/bluetooth/bluetooth_socket.h" 25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "device/bluetooth/bluetooth_socket_chromeos.h" 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "device/bluetooth/bluetooth_socket_thread.h" 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "device/bluetooth/bluetooth_uuid.h" 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using device::BluetoothDevice; 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using device::BluetoothSocket; 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using device::BluetoothUUID; 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Histogram enumerations for pairing results. 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)enum UMAPairingResult { 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_SUCCESS, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_INPROGRESS, 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_FAILED, 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_AUTH_FAILED, 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_AUTH_CANCELED, 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_AUTH_REJECTED, 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_AUTH_TIMEOUT, 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_UNSUPPORTED_DEVICE, 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_UNKNOWN_ERROR, 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // NOTE: Add new pairing results immediately above this line. Make sure to 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // update the enum list in tools/histogram/histograms.xml accordinly. 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_COUNT 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ParseModalias(const dbus::ObjectPath& object_path, 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothDevice::VendorIDSource* vendor_id_source, 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint16* vendor_id, 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint16* product_id, 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint16* device_id) { 577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) chromeos::BluetoothDeviceClient::Properties* properties = 587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) chromeos::DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) GetProperties(object_path); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string modalias = properties->modalias.value(); 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothDevice::VendorIDSource source_value; 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int vendor_value, product_value, device_value; 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (sscanf(modalias.c_str(), "bluetooth:v%04xp%04xd%04x", 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &vendor_value, &product_value, &device_value) == 3) { 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) source_value = BluetoothDevice::VENDOR_ID_BLUETOOTH; 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (sscanf(modalias.c_str(), "usb:v%04xp%04xd%04x", 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &vendor_value, &product_value, &device_value) == 3) { 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) source_value = BluetoothDevice::VENDOR_ID_USB; 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (vendor_id_source != NULL) 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *vendor_id_source = source_value; 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (vendor_id != NULL) 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *vendor_id = vendor_value; 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (product_id != NULL) 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *product_id = product_value; 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (device_id != NULL) 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *device_id = device_value; 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RecordPairingResult(BluetoothDevice::ConnectErrorCode error_code) { 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMAPairingResult pairing_result; 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (error_code) { 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_INPROGRESS: 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_INPROGRESS; 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_FAILED: 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_FAILED; 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_AUTH_FAILED: 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_AUTH_FAILED; 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_AUTH_CANCELED: 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_AUTH_CANCELED; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_AUTH_REJECTED: 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_AUTH_REJECTED; 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_AUTH_TIMEOUT: 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_AUTH_TIMEOUT; 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_UNSUPPORTED_DEVICE: 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_UNSUPPORTED_DEVICE; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_UNKNOWN_ERROR; 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingResult", 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result, 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_COUNT); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos { 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothDeviceChromeOS::BluetoothDeviceChromeOS( 1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothAdapterChromeOS* adapter, 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const dbus::ObjectPath& object_path, 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> ui_task_runner, 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<device::BluetoothSocketThread> socket_thread) 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : adapter_(adapter), 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) object_path_(object_path), 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) num_connecting_calls_(0), 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) connection_monitor_started_(false), 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui_task_runner_(ui_task_runner), 133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) socket_thread_(socket_thread), 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DBusThreadManager::Get()->GetBluetoothGattServiceClient()->AddObserver(this); 136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Add all known GATT services. 138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::vector<dbus::ObjectPath> gatt_services = 139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetServices(); 140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (std::vector<dbus::ObjectPath>::const_iterator it = gatt_services.begin(); 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it != gatt_services.end(); ++it) { 142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GattServiceAdded(*it); 143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothDeviceChromeOS::~BluetoothDeviceChromeOS() { 147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DBusThreadManager::Get()->GetBluetoothGattServiceClient()-> 148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch RemoveObserver(this); 149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Copy the GATT services list here and clear the original so that when we 151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // send GattServiceRemoved(), GetGattServices() returns no services. 152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GattServiceMap gatt_services = gatt_services_; 153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gatt_services_.clear(); 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (GattServiceMap::iterator iter = gatt_services.begin(); 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch iter != gatt_services.end(); ++iter) { 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(adapter_); 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) adapter_->NotifyGattServiceRemoved( 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static_cast<BluetoothRemoteGattServiceChromeOS*>(iter->second)); 159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch delete iter->second; 160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)uint32 BluetoothDeviceChromeOS::GetBluetoothClass() const { 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return properties->bluetooth_class.value(); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)std::string BluetoothDeviceChromeOS::GetDeviceName() const { 1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return properties->alias.value(); 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)std::string BluetoothDeviceChromeOS::GetAddress() const { 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return CanonicalizeAddress(properties->address.value()); 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothDevice::VendorIDSource 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothDeviceChromeOS::GetVendorIDSource() const { 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VendorIDSource vendor_id_source = VENDOR_ID_UNKNOWN; 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ParseModalias(object_path_, &vendor_id_source, NULL, NULL, NULL); 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return vendor_id_source; 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)uint16 BluetoothDeviceChromeOS::GetVendorID() const { 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint16 vendor_id = 0; 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ParseModalias(object_path_, NULL, &vendor_id, NULL, NULL); 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return vendor_id; 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)uint16 BluetoothDeviceChromeOS::GetProductID() const { 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint16 product_id = 0; 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ParseModalias(object_path_, NULL, NULL, &product_id, NULL); 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return product_id; 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)uint16 BluetoothDeviceChromeOS::GetDeviceID() const { 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint16 device_id = 0; 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ParseModalias(object_path_, NULL, NULL, NULL, &device_id); 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return device_id; 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuint BluetoothDeviceChromeOS::GetRSSI() const { 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) object_path_); 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(properties); 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!IsConnected()) { 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTIMPLEMENTED(); 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return kUnknownPower; 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return connection_monitor_started_ ? properties->connection_rssi.value() 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : kUnknownPower; 2285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuint BluetoothDeviceChromeOS::GetCurrentHostTransmitPower() const { 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) object_path_); 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(properties); 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return IsConnected() && connection_monitor_started_ 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ? properties->connection_tx_power.value() 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : kUnknownPower; 2395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuint BluetoothDeviceChromeOS::GetMaximumHostTransmitPower() const { 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) object_path_); 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(properties); 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return IsConnected() ? properties->connection_tx_power_max.value() 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : kUnknownPower; 2495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::IsPaired() const { 2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Trusted devices are devices that don't support pairing but that the 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // user has explicitly connected; it makes no sense for UI purposes to 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // treat them differently from each other. 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return properties->paired.value() || properties->trusted.value(); 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::IsConnected() const { 2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 2657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return properties->connected.value(); 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::IsConnectable() const { 2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothInputClient::Properties* input_properties = 2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothInputClient()-> 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // GetProperties returns NULL when the device does not implement the given 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // interface. Non HID devices are normally connectable. 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!input_properties) 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return input_properties->reconnect_mode.value() != "device"; 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::IsConnecting() const { 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return num_connecting_calls_ > 0; 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)BluetoothDeviceChromeOS::UUIDList BluetoothDeviceChromeOS::GetUUIDs() const { 2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::vector<device::BluetoothUUID> uuids; 295c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::vector<std::string> &dbus_uuids = properties->uuids.value(); 296c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (std::vector<std::string>::const_iterator iter = dbus_uuids.begin(); 297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch iter != dbus_uuids.end(); ++iter) { 298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch device::BluetoothUUID uuid(*iter); 299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(uuid.IsValid()); 300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch uuids.push_back(uuid); 301c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return uuids; 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::ExpectingPinCode() const { 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return pairing_.get() && pairing_->ExpectingPinCode(); 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::ExpectingPasskey() const { 310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return pairing_.get() && pairing_->ExpectingPasskey(); 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::ExpectingConfirmation() const { 314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return pairing_.get() && pairing_->ExpectingConfirmation(); 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::Connect( 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BluetoothDevice::PairingDelegate* pairing_delegate, 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& callback, 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ConnectErrorCallback& error_callback) { 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (num_connecting_calls_++ == 0) 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) adapter_->NotifyDeviceChanged(this); 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Connecting, " << num_connecting_calls_ 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " in progress"; 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsPaired() || !pairing_delegate || !IsPairable()) { 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // No need to pair, or unable to, skip straight to connection. 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConnectInternal(false, callback, error_callback); 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initiate high-security connection with pairing. 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BeginPairing(pairing_delegate); 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Pair(object_path_, 336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnPair, 337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback, error_callback), 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnPairError, 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_callback)); 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::SetPinCode(const std::string& pincode) { 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing_.get()) 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_->SetPinCode(pincode); 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::SetPasskey(uint32 passkey) { 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing_.get()) 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_->SetPasskey(passkey); 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::ConfirmPairing() { 360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing_.get()) 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_->ConfirmPairing(); 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::RejectPairing() { 367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing_.get()) 368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_->RejectPairing(); 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::CancelPairing() { 374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool canceled = false; 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If there is a callback in progress that we can reply to then use that 377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // to cancel the current pairing request. 378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (pairing_.get() && pairing_->CancelPairing()) 379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) canceled = true; 380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If not we have to send an explicit CancelPairing() to the device instead. 382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!canceled) { 383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << object_path_.value() << ": No pairing context or callback. " 384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Sending explicit cancel"; 3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CancelPairing( 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) object_path_, 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&base::DoNothing), 3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnCancelPairingError, 3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Since there is no callback to this method it's possible that the pairing 394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // delegate is going to be freed before things complete (indeed it's 395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // documented that this is the method you should call while freeing the 396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // pairing delegate), so clear our the context holding on to it. 397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EndPairing(); 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::Disconnect(const base::Closure& callback, 4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const ErrorCallback& error_callback) { 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Disconnecting"; 4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Disconnect( 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) object_path_, 4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnDisconnect, 4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback), 4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnDisconnectError, 4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) error_callback)); 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::Forget(const ErrorCallback& error_callback) { 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Removing device"; 4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RemoveDevice( 418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) adapter_->object_path(), 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) object_path_, 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&base::DoNothing), 4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnForgetError, 4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) error_callback)); 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 426010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BluetoothDeviceChromeOS::ConnectToService( 427010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const BluetoothUUID& uuid, 428010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const ConnectToServiceCallback& callback, 429010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const ConnectToServiceErrorCallback& error_callback) { 430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) VLOG(1) << object_path_.value() << ": Connecting to service: " 431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << uuid.canonical_value(); 432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<BluetoothSocketChromeOS> socket = 433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BluetoothSocketChromeOS::CreateBluetoothSocket( 4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui_task_runner_, socket_thread_); 43503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) socket->Connect(this, uuid, BluetoothSocketChromeOS::SECURITY_LEVEL_MEDIUM, 43603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Bind(callback, socket), error_callback); 43703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 43803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 43903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void BluetoothDeviceChromeOS::ConnectToServiceInsecurely( 44003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const BluetoothUUID& uuid, 44103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const ConnectToServiceCallback& callback, 44203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const ConnectToServiceErrorCallback& error_callback) { 44303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) VLOG(1) << object_path_.value() << ": Connecting insecurely to service: " 44403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << uuid.canonical_value(); 44503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<BluetoothSocketChromeOS> socket = 44603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) BluetoothSocketChromeOS::CreateBluetoothSocket( 44703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ui_task_runner_, socket_thread_); 44803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) socket->Connect(this, uuid, BluetoothSocketChromeOS::SECURITY_LEVEL_LOW, 44903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Bind(callback, socket), error_callback); 450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 452f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void BluetoothDeviceChromeOS::CreateGattConnection( 453f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const GattConnectionCallback& callback, 454f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ConnectErrorCallback& error_callback) { 4556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // TODO(armansito): Until there is a way to create a reference counted GATT 4566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // connection in bluetoothd, simply do a regular connect. 4576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) Connect(NULL, 4586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnCreateGattConnection, 4596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 4606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) callback), 4616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) error_callback); 462f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 463f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void BluetoothDeviceChromeOS::StartConnectionMonitor( 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& callback, 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback) { 467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()->StartConnectionMonitor( 468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) object_path_, 469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnStartConnectionMonitor, 470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback), 472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnStartConnectionMonitorError, 473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error_callback)); 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothPairingChromeOS* BluetoothDeviceChromeOS::BeginPairing( 478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothDevice::PairingDelegate* pairing_delegate) { 479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_.reset(new BluetoothPairingChromeOS(this, pairing_delegate)); 480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return pairing_.get(); 481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothDeviceChromeOS::EndPairing() { 484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_.reset(); 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothPairingChromeOS* BluetoothDeviceChromeOS::GetPairing() const { 488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return pairing_.get(); 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 491c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid BluetoothDeviceChromeOS::GattServiceAdded( 492c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const dbus::ObjectPath& object_path) { 493c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (GetGattService(object_path.value())) { 494c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VLOG(1) << "Remote GATT service already exists: " << object_path.value(); 495c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 496c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 497c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 498c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch BluetoothGattServiceClient::Properties* properties = 499c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DBusThreadManager::Get()->GetBluetoothGattServiceClient()-> 500c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GetProperties(object_path); 501c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(properties); 502c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (properties->device.value() != object_path_) { 503c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VLOG(2) << "Remote GATT service does not belong to this device."; 504c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 505c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 506c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 507c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VLOG(1) << "Adding new remote GATT service for device: " << GetAddress(); 508c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 509c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch BluetoothRemoteGattServiceChromeOS* service = 510116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new BluetoothRemoteGattServiceChromeOS(adapter_, this, object_path); 511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 512c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gatt_services_[service->GetIdentifier()] = service; 513c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(service->object_path() == object_path); 514c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(service->GetUUID().IsValid()); 515c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(adapter_); 5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) adapter_->NotifyGattServiceAdded(service); 518c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 519c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 520c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid BluetoothDeviceChromeOS::GattServiceRemoved( 521c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const dbus::ObjectPath& object_path) { 522c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GattServiceMap::iterator iter = gatt_services_.find(object_path.value()); 523c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (iter == gatt_services_.end()) { 5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) VLOG(3) << "Unknown GATT service removed: " << object_path.value(); 525c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 526c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 527c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 528c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VLOG(1) << "Removing remote GATT service from device: " << GetAddress(); 529c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 530c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch BluetoothRemoteGattServiceChromeOS* service = 531c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch static_cast<BluetoothRemoteGattServiceChromeOS*>(iter->second); 532c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(service->object_path() == object_path); 533c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gatt_services_.erase(iter); 5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(adapter_); 5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) adapter_->NotifyGattServiceRemoved(service); 5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 538c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch delete service; 539c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 540c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::ConnectInternal( 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool after_pairing, 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& callback, 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ConnectErrorCallback& error_callback) { 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Connecting"; 5467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Connect( 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) object_path_, 5497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnConnect, 5507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 5517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) after_pairing, 5527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback), 5537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnConnectError, 5547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 5557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) after_pairing, 5567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) error_callback)); 5577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnConnect(bool after_pairing, 5607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::Closure& callback) { 561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (--num_connecting_calls_ == 0) 562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) adapter_->NotifyDeviceChanged(this); 563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(num_connecting_calls_ >= 0); 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Connected, " << num_connecting_calls_ 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " still in progress"; 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetTrusted(); 569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (after_pairing) 571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingResult", 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_SUCCESS, 573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_COUNT); 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(); 576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void BluetoothDeviceChromeOS::OnCreateGattConnection( 5796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const GattConnectionCallback& callback) { 5806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) scoped_ptr<device::BluetoothGattConnection> conn( 5816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) new BluetoothGattConnectionChromeOS( 5826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) adapter_, GetAddress(), object_path_)); 5836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) callback.Run(conn.Pass()); 5846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 5856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 5867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnConnectError( 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool after_pairing, 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ConnectErrorCallback& error_callback, 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_name, 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (--num_connecting_calls_ == 0) 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) adapter_->NotifyDeviceChanged(this); 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(num_connecting_calls_ >= 0); 595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << object_path_.value() << ": Failed to connect device: " 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error_name << ": " << error_message; 597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": " << num_connecting_calls_ 598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " still in progress"; 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Determine the error code from error_name. 601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConnectErrorCode error_code = ERROR_UNKNOWN; 602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error_name == bluetooth_device::kErrorFailed) { 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_FAILED; 604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorInProgress) { 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_INPROGRESS; 606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorNotSupported) { 607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_UNSUPPORTED_DEVICE; 608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (after_pairing) 611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RecordPairingResult(error_code); 612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run(error_code); 613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnPair( 616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& callback, 617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ConnectErrorCallback& error_callback) { 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Paired"; 619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EndPairing(); 621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConnectInternal(true, callback, error_callback); 623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnPairError( 626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ConnectErrorCallback& error_callback, 627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_name, 628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (--num_connecting_calls_ == 0) 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) adapter_->NotifyDeviceChanged(this); 631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(num_connecting_calls_ >= 0); 633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << object_path_.value() << ": Failed to pair device: " 634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error_name << ": " << error_message; 635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": " << num_connecting_calls_ 636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " still in progress"; 637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 638a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EndPairing(); 639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Determine the error code from error_name. 641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConnectErrorCode error_code = ERROR_UNKNOWN; 642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error_name == bluetooth_device::kErrorConnectionAttemptFailed) { 643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_FAILED; 644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorFailed) { 645b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) error_code = ERROR_FAILED; 646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorAuthenticationFailed) { 647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_AUTH_FAILED; 648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorAuthenticationCanceled) { 649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_AUTH_CANCELED; 650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorAuthenticationRejected) { 651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_AUTH_REJECTED; 652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorAuthenticationTimeout) { 653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_AUTH_TIMEOUT; 654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RecordPairingResult(error_code); 657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run(error_code); 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnCancelPairingError( 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_name, 662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << object_path_.value() << ": Failed to cancel pairing: " 664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error_name << ": " << error_message; 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::SetTrusted() { 668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Unconditionally send the property change, rather than checking the value 669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // first; there's no harm in doing this and it solves any race conditions 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // with the property becoming true or false and this call happening before 671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // we get the D-Bus signal about the earlier change. 6727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_)->trusted.Set( 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true, 6757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnSetTrusted, 6767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnSetTrusted(bool success) { 680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG_IF(WARNING, !success) << object_path_.value() 681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << ": Failed to set device as trusted"; 682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 684cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void BluetoothDeviceChromeOS::OnStartConnectionMonitor( 685cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::Closure& callback) { 686cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) connection_monitor_started_ = true; 687cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(); 688cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 689cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 690cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void BluetoothDeviceChromeOS::OnStartConnectionMonitorError( 691cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ErrorCallback& error_callback, 692cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_name, 693cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_message) { 694cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(WARNING) << object_path_.value() 695cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << ": Failed to start connection monitor: " << error_name << ": " 696cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << error_message; 697cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error_callback.Run(); 698cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 699cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnDisconnect(const base::Closure& callback) { 701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Disconnected"; 702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(); 703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnDisconnectError( 706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback, 707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_name, 708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << object_path_.value() << ": Failed to disconnect device: " 710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error_name << ": " << error_message; 711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run(); 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnForgetError( 715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback, 716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_name, 717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << object_path_.value() << ": Failed to remove device: " 719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error_name << ": " << error_message; 720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run(); 721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace chromeos 724