bluetooth_device_chromeos.cc revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
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" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/metrics/histogram.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_adapter_client.h" 147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_device_client.h" 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chromeos/dbus/bluetooth_gatt_service_client.h" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_input_client.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/bus.h" 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_chromeos.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "device/bluetooth/bluetooth_pairing_chromeos.h" 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "device/bluetooth/bluetooth_profile_chromeos.h" 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "device/bluetooth/bluetooth_socket.h" 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using device::BluetoothDevice; 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Histogram enumerations for pairing results. 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)enum UMAPairingResult { 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_SUCCESS, 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_INPROGRESS, 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_FAILED, 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_AUTH_FAILED, 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_AUTH_CANCELED, 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_AUTH_REJECTED, 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_AUTH_TIMEOUT, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_UNSUPPORTED_DEVICE, 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_UNKNOWN_ERROR, 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // NOTE: Add new pairing results immediately above this line. Make sure to 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // update the enum list in tools/histogram/histograms.xml accordinly. 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_COUNT 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ParseModalias(const dbus::ObjectPath& object_path, 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothDevice::VendorIDSource* vendor_id_source, 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint16* vendor_id, 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint16* product_id, 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint16* device_id) { 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) chromeos::BluetoothDeviceClient::Properties* properties = 527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) chromeos::DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) GetProperties(object_path); 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string modalias = properties->modalias.value(); 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothDevice::VendorIDSource source_value; 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int vendor_value, product_value, device_value; 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (sscanf(modalias.c_str(), "bluetooth:v%04xp%04xd%04x", 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &vendor_value, &product_value, &device_value) == 3) { 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) source_value = BluetoothDevice::VENDOR_ID_BLUETOOTH; 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (sscanf(modalias.c_str(), "usb:v%04xp%04xd%04x", 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &vendor_value, &product_value, &device_value) == 3) { 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) source_value = BluetoothDevice::VENDOR_ID_USB; 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (vendor_id_source != NULL) 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *vendor_id_source = source_value; 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (vendor_id != NULL) 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *vendor_id = vendor_value; 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (product_id != NULL) 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *product_id = product_value; 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (device_id != NULL) 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *device_id = device_value; 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void RecordPairingResult(BluetoothDevice::ConnectErrorCode error_code) { 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMAPairingResult pairing_result; 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (error_code) { 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_INPROGRESS: 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_INPROGRESS; 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_FAILED: 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_FAILED; 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_AUTH_FAILED: 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_AUTH_FAILED; 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_AUTH_CANCELED: 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_AUTH_CANCELED; 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_AUTH_REJECTED: 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_AUTH_REJECTED; 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_AUTH_TIMEOUT: 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_AUTH_TIMEOUT; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case BluetoothDevice::ERROR_UNSUPPORTED_DEVICE: 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_UNSUPPORTED_DEVICE; 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result = UMA_PAIRING_RESULT_UNKNOWN_ERROR; 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingResult", 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pairing_result, 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_COUNT); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos { 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothDeviceChromeOS::BluetoothDeviceChromeOS( 1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothAdapterChromeOS* adapter, 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const dbus::ObjectPath& object_path) 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : adapter_(adapter), 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) object_path_(object_path), 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) num_connecting_calls_(0), 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DBusThreadManager::Get()->GetBluetoothGattServiceClient()->AddObserver(this); 125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Add all known GATT services. 127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::vector<dbus::ObjectPath> gatt_services = 128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetServices(); 129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (std::vector<dbus::ObjectPath>::const_iterator it = gatt_services.begin(); 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it != gatt_services.end(); ++it) { 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GattServiceAdded(*it); 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothDeviceChromeOS::~BluetoothDeviceChromeOS() { 136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DBusThreadManager::Get()->GetBluetoothGattServiceClient()-> 137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch RemoveObserver(this); 138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Copy the GATT services list here and clear the original so that when we 140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // send GattServiceRemoved(), GetGattServices() returns no services. 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GattServiceMap gatt_services = gatt_services_; 142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gatt_services_.clear(); 143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (GattServiceMap::iterator iter = gatt_services.begin(); 144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch iter != gatt_services.end(); ++iter) { 145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FOR_EACH_OBSERVER(BluetoothDevice::Observer, observers_, 146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GattServiceRemoved(this, iter->second)); 147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch delete iter->second; 148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid BluetoothDeviceChromeOS::AddObserver( 152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch device::BluetoothDevice::Observer* observer) { 153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(observer); 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observers_.AddObserver(observer); 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid BluetoothDeviceChromeOS::RemoveObserver( 158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch device::BluetoothDevice::Observer* observer) { 159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(observer); 160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observers_.RemoveObserver(observer); 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 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) 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 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 { 2165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NOTIMPLEMENTED(); 2175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return kUnknownPower; 2185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuint BluetoothDeviceChromeOS::GetCurrentHostTransmitPower() const { 2215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NOTIMPLEMENTED(); 2225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return kUnknownPower; 2235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuint BluetoothDeviceChromeOS::GetMaximumHostTransmitPower() const { 2265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NOTIMPLEMENTED(); 2275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return kUnknownPower; 2285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::IsPaired() const { 2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Trusted devices are devices that don't support pairing but that the 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // user has explicitly connected; it makes no sense for UI purposes to 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // treat them differently from each other. 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return properties->paired.value() || properties->trusted.value(); 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::IsConnected() const { 2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return properties->connected.value(); 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::IsConnectable() const { 2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothInputClient::Properties* input_properties = 2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothInputClient()-> 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // GetProperties returns NULL when the device does not implement the given 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // interface. Non HID devices are normally connectable. 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!input_properties) 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return input_properties->reconnect_mode.value() != "device"; 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::IsConnecting() const { 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return num_connecting_calls_ > 0; 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)BluetoothDeviceChromeOS::UUIDList BluetoothDeviceChromeOS::GetUUIDs() const { 2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 273c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::vector<device::BluetoothUUID> uuids; 274c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::vector<std::string> &dbus_uuids = properties->uuids.value(); 275c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (std::vector<std::string>::const_iterator iter = dbus_uuids.begin(); 276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch iter != dbus_uuids.end(); ++iter) { 277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch device::BluetoothUUID uuid(*iter); 278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(uuid.IsValid()); 279c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch uuids.push_back(uuid); 280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 281c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return uuids; 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::ExpectingPinCode() const { 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return pairing_.get() && pairing_->ExpectingPinCode(); 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::ExpectingPasskey() const { 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return pairing_.get() && pairing_->ExpectingPasskey(); 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothDeviceChromeOS::ExpectingConfirmation() const { 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return pairing_.get() && pairing_->ExpectingConfirmation(); 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::Connect( 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BluetoothDevice::PairingDelegate* pairing_delegate, 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& callback, 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ConnectErrorCallback& error_callback) { 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (num_connecting_calls_++ == 0) 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) adapter_->NotifyDeviceChanged(this); 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Connecting, " << num_connecting_calls_ 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " in progress"; 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsPaired() || !pairing_delegate || !IsPairable()) { 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // No need to pair, or unable to, skip straight to connection. 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConnectInternal(false, callback, error_callback); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initiate high-security connection with pairing. 311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BeginPairing(pairing_delegate); 312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Pair(object_path_, 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnPair, 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback, error_callback), 318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnPairError, 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_callback)); 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::SetPinCode(const std::string& pincode) { 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing_.get()) 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_->SetPinCode(pincode); 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::SetPasskey(uint32 passkey) { 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing_.get()) 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_->SetPasskey(passkey); 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::ConfirmPairing() { 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing_.get()) 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_->ConfirmPairing(); 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::RejectPairing() { 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing_.get()) 347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_->RejectPairing(); 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::CancelPairing() { 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool canceled = false; 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If there is a callback in progress that we can reply to then use that 356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // to cancel the current pairing request. 357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (pairing_.get() && pairing_->CancelPairing()) 358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) canceled = true; 359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If not we have to send an explicit CancelPairing() to the device instead. 361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!canceled) { 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << object_path_.value() << ": No pairing context or callback. " 363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Sending explicit cancel"; 3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CancelPairing( 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) object_path_, 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&base::DoNothing), 3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnCancelPairingError, 3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Since there is no callback to this method it's possible that the pairing 373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // delegate is going to be freed before things complete (indeed it's 374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // documented that this is the method you should call while freeing the 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // pairing delegate), so clear our the context holding on to it. 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EndPairing(); 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::Disconnect(const base::Closure& callback, 3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const ErrorCallback& error_callback) { 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Disconnecting"; 3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Disconnect( 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) object_path_, 3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnDisconnect, 3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback), 3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnDisconnectError, 3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) error_callback)); 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::Forget(const ErrorCallback& error_callback) { 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Removing device"; 3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RemoveDevice( 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) adapter_->object_path_, 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) object_path_, 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&base::DoNothing), 4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnForgetError, 4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) error_callback)); 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::ConnectToProfile( 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) device::BluetoothProfile* profile, 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& callback, 408c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const ConnectToProfileErrorCallback& error_callback) { 4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothProfileChromeOS* profile_chromeos = 4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static_cast<BluetoothProfileChromeOS*>(profile); 411b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Connecting profile: " 412c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << profile_chromeos->uuid().canonical_value(); 4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 414b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ConnectProfile( 415b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) object_path_, 416c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch profile_chromeos->uuid().canonical_value(), 417b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind( 4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) &BluetoothDeviceChromeOS::OnConnectProfile, 419b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 420b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) profile, 421b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) callback), 422b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind( 4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) &BluetoothDeviceChromeOS::OnConnectProfileError, 424b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 425b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) profile, 426b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) error_callback)); 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::SetOutOfBandPairingData( 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const device::BluetoothOutOfBandPairingData& data, 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& callback, 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback) { 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(keybuk): implement 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run(); 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::ClearOutOfBandPairingData( 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& callback, 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback) { 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(keybuk): implement 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run(); 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothPairingChromeOS* BluetoothDeviceChromeOS::BeginPairing( 445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothDevice::PairingDelegate* pairing_delegate) { 446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_.reset(new BluetoothPairingChromeOS(this, pairing_delegate)); 447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return pairing_.get(); 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothDeviceChromeOS::EndPairing() { 451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing_.reset(); 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothPairingChromeOS* BluetoothDeviceChromeOS::GetPairing() const { 455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return pairing_.get(); 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 458c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid BluetoothDeviceChromeOS::GattServiceAdded( 459c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const dbus::ObjectPath& object_path) { 460c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (GetGattService(object_path.value())) { 461c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VLOG(1) << "Remote GATT service already exists: " << object_path.value(); 462c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 463c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 464c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 465c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch BluetoothGattServiceClient::Properties* properties = 466c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DBusThreadManager::Get()->GetBluetoothGattServiceClient()-> 467c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GetProperties(object_path); 468c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(properties); 469c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (properties->device.value() != object_path_) { 470c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VLOG(2) << "Remote GATT service does not belong to this device."; 471c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 472c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 473c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 474c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VLOG(1) << "Adding new remote GATT service for device: " << GetAddress(); 475c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 476c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch BluetoothRemoteGattServiceChromeOS* service = 477c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new BluetoothRemoteGattServiceChromeOS(this, object_path); 478c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gatt_services_[service->GetIdentifier()] = service; 479c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(service->object_path() == object_path); 480c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(service->GetUUID().IsValid()); 481c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 482c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FOR_EACH_OBSERVER(device::BluetoothDevice::Observer, observers_, 483c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GattServiceAdded(this, service)); 484c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 485c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 486c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid BluetoothDeviceChromeOS::GattServiceRemoved( 487c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const dbus::ObjectPath& object_path) { 488c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GattServiceMap::iterator iter = gatt_services_.find(object_path.value()); 489c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (iter == gatt_services_.end()) { 490c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VLOG(2) << "Unknown GATT service removed: " << object_path.value(); 491c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 492c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 493c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 494c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VLOG(1) << "Removing remote GATT service from device: " << GetAddress(); 495c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 496c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch BluetoothRemoteGattServiceChromeOS* service = 497c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch static_cast<BluetoothRemoteGattServiceChromeOS*>(iter->second); 498c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(service->object_path() == object_path); 499c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gatt_services_.erase(iter); 500c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FOR_EACH_OBSERVER(device::BluetoothDevice::Observer, observers_, 501c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GattServiceRemoved(this, service)); 502c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch delete service; 503c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 504c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::ConnectInternal( 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool after_pairing, 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& callback, 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ConnectErrorCallback& error_callback) { 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Connecting"; 5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Connect( 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) object_path_, 5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnConnect, 5147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) after_pairing, 5167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback), 5177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnConnectError, 5187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 5197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) after_pairing, 5207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) error_callback)); 5217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnConnect(bool after_pairing, 5247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::Closure& callback) { 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (--num_connecting_calls_ == 0) 526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) adapter_->NotifyDeviceChanged(this); 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(num_connecting_calls_ >= 0); 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Connected, " << num_connecting_calls_ 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " still in progress"; 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetTrusted(); 533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (after_pairing) 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingResult", 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_SUCCESS, 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_PAIRING_RESULT_COUNT); 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(); 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnConnectError( 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool after_pairing, 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ConnectErrorCallback& error_callback, 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_name, 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (--num_connecting_calls_ == 0) 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) adapter_->NotifyDeviceChanged(this); 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(num_connecting_calls_ >= 0); 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << object_path_.value() << ": Failed to connect device: " 552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error_name << ": " << error_message; 553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": " << num_connecting_calls_ 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " still in progress"; 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Determine the error code from error_name. 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConnectErrorCode error_code = ERROR_UNKNOWN; 558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error_name == bluetooth_device::kErrorFailed) { 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_FAILED; 560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorInProgress) { 561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_INPROGRESS; 562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorNotSupported) { 563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_UNSUPPORTED_DEVICE; 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (after_pairing) 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RecordPairingResult(error_code); 568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run(error_code); 569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnPair( 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& callback, 573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ConnectErrorCallback& error_callback) { 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Paired"; 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EndPairing(); 577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConnectInternal(true, callback, error_callback); 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnPairError( 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ConnectErrorCallback& error_callback, 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_name, 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (--num_connecting_calls_ == 0) 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) adapter_->NotifyDeviceChanged(this); 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(num_connecting_calls_ >= 0); 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << object_path_.value() << ": Failed to pair device: " 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error_name << ": " << error_message; 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": " << num_connecting_calls_ 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " still in progress"; 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 594a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EndPairing(); 595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Determine the error code from error_name. 597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConnectErrorCode error_code = ERROR_UNKNOWN; 598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error_name == bluetooth_device::kErrorConnectionAttemptFailed) { 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_FAILED; 600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorFailed) { 601b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) error_code = ERROR_FAILED; 602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorAuthenticationFailed) { 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_AUTH_FAILED; 604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorAuthenticationCanceled) { 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_AUTH_CANCELED; 606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorAuthenticationRejected) { 607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_AUTH_REJECTED; 608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (error_name == bluetooth_device::kErrorAuthenticationTimeout) { 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_code = ERROR_AUTH_TIMEOUT; 610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RecordPairingResult(error_code); 613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run(error_code); 614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnCancelPairingError( 617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_name, 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << object_path_.value() << ": Failed to cancel pairing: " 620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error_name << ": " << error_message; 621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::SetTrusted() { 624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Unconditionally send the property change, rather than checking the value 625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // first; there's no harm in doing this and it solves any race conditions 626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // with the property becoming true or false and this call happening before 627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // we get the D-Bus signal about the earlier change. 6287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_)->trusted.Set( 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true, 6317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Bind(&BluetoothDeviceChromeOS::OnSetTrusted, 6327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnSetTrusted(bool success) { 636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG_IF(WARNING, !success) << object_path_.value() 637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << ": Failed to set device as trusted"; 638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnDisconnect(const base::Closure& callback) { 641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Disconnected"; 642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(); 643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnDisconnectError( 646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback, 647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_name, 648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << object_path_.value() << ": Failed to disconnect device: " 650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error_name << ": " << error_message; 651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run(); 652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnForgetError( 655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback, 656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_name, 657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << object_path_.value() << ": Failed to remove device: " 659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error_name << ": " << error_message; 660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run(); 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnConnectProfile( 664b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) device::BluetoothProfile* profile, 665b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const base::Closure& callback) { 6667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothProfileChromeOS* profile_chromeos = 6677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static_cast<BluetoothProfileChromeOS*>(profile); 668b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Profile connected: " 669c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << profile_chromeos->uuid().canonical_value(); 670b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) callback.Run(); 671b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 672b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 6737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothDeviceChromeOS::OnConnectProfileError( 674b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) device::BluetoothProfile* profile, 675c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const ConnectToProfileErrorCallback& error_callback, 676b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const std::string& error_name, 677b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const std::string& error_message) { 6787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothProfileChromeOS* profile_chromeos = 6797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static_cast<BluetoothProfileChromeOS*>(profile); 680b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) VLOG(1) << object_path_.value() << ": Profile connection failed: " 681c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << profile_chromeos->uuid().canonical_value() << ": " 682b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) << error_name << ": " << error_message; 683c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch error_callback.Run(error_message); 684b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 685b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace chromeos 687