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_adapter_chromeos.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/metrics/histogram.h" 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/sequenced_task_runner.h" 13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/single_thread_task_runner.h" 141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/sys_info.h" 15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/thread_task_runner_handle.h" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_adapter_client.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chromeos/dbus/bluetooth_agent_manager_client.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chromeos/dbus/bluetooth_agent_service_provider.h" 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_device_client.h" 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_input_client.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "device/bluetooth/bluetooth_device.h" 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "device/bluetooth/bluetooth_device_chromeos.h" 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "device/bluetooth/bluetooth_pairing_chromeos.h" 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h" 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h" 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h" 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "device/bluetooth/bluetooth_socket_chromeos.h" 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "device/bluetooth/bluetooth_socket_thread.h" 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "device/bluetooth/bluetooth_uuid.h" 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using device::BluetoothAdapter; 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using device::BluetoothDevice; 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using device::BluetoothSocket; 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using device::BluetoothUUID; 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// The agent path is relatively meaningless since BlueZ only permits one to 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// exist per D-Bus connection, it just has to be unique within Chromium. 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char kAgentPath[] = "/org/chromium/bluetooth_agent"; 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void OnUnregisterAgentError(const std::string& error_name, 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& error_message) { 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // It's okay if the agent didn't exist, it means we never saw an adapter. 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error_name == bluetooth_agent_manager::kErrorDoesNotExist) 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(WARNING) << "Failed to unregister pairing agent: " 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << error_name << ": " << error_message; 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace device { 570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// static 590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter( 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const InitCallback& init_callback) { 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return chromeos::BluetoothAdapterChromeOS::CreateAdapter(); 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos { 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// static 690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::WeakPtr<BluetoothAdapter> BluetoothAdapterChromeOS::CreateAdapter() { 700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch BluetoothAdapterChromeOS* adapter = new BluetoothAdapterChromeOS(); 710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return adapter->weak_ptr_factory_.GetWeakPtr(); 720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothAdapterChromeOS::BluetoothAdapterChromeOS() 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : num_discovery_sessions_(0), 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) discovery_request_pending_(false), 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_(this) { 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) socket_thread_ = device::BluetoothSocketThread::Get(); 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()->AddObserver(this); 827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()->AddObserver(this); 837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothInputClient()->AddObserver(this); 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Register the pairing agent. 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) agent_.reset(BluetoothAgentServiceProvider::Create( 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) system_bus, dbus::ObjectPath(kAgentPath), this)); 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(agent_.get()); 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<dbus::ObjectPath> object_paths = 927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetAdapters(); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!object_paths.empty()) { 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_paths.size() << " Bluetooth adapter(s) available."; 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetAdapter(object_paths[0]); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothAdapterChromeOS::~BluetoothAdapterChromeOS() { 1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()->RemoveObserver(this); 1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(this); 1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothInputClient()->RemoveObserver(this); 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Unregistering pairing agent"; 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAgentManagerClient()-> 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UnregisterAgent( 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dbus::ObjectPath(kAgentPath), 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&base::DoNothing), 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&OnUnregisterAgentError)); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::AddObserver( 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BluetoothAdapter::Observer* observer) { 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(observer); 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) observers_.AddObserver(observer); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::RemoveObserver( 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BluetoothAdapter::Observer* observer) { 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(observer); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) observers_.RemoveObserver(observer); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)std::string BluetoothAdapterChromeOS::GetAddress() const { 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsPresent()) 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothAdapterClient::Properties* properties = 1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return BluetoothDevice::CanonicalizeAddress(properties->address.value()); 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)std::string BluetoothAdapterChromeOS::GetName() const { 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsPresent()) 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothAdapterClient::Properties* properties = 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(properties); 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return properties->alias.value(); 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BluetoothAdapterChromeOS::SetName(const std::string& name, 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Closure& callback, 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ErrorCallback& error_callback) { 1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!IsPresent()) 1535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu error_callback.Run(); 1545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetProperties(object_path_)->alias.Set( 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) name, 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&BluetoothAdapterChromeOS::OnPropertyChangeCompleted, 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback, 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_callback)); 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothAdapterChromeOS::IsInitialized() const { 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothAdapterChromeOS::IsPresent() const { 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return !object_path_.value().empty(); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothAdapterChromeOS::IsPowered() const { 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsPresent()) 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothAdapterClient::Properties* properties = 1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return properties->powered.value(); 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::SetPowered( 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool powered, 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Closure& callback, 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback) { 1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!IsPresent()) 1885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu error_callback.Run(); 1895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_)->powered.Set( 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) powered, 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&BluetoothAdapterChromeOS::OnPropertyChangeCompleted, 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback, 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_callback)); 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool BluetoothAdapterChromeOS::IsDiscoverable() const { 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!IsPresent()) 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BluetoothAdapterClient::Properties* properties = 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetProperties(object_path_); 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return properties->discoverable.value(); 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BluetoothAdapterChromeOS::SetDiscoverable( 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool discoverable, 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Closure& callback, 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ErrorCallback& error_callback) { 2145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!IsPresent()) 2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu error_callback.Run(); 2165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetProperties(object_path_)->discoverable.Set( 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) discoverable, 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoverable, 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback, 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback)); 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool BluetoothAdapterChromeOS::IsDiscovering() const { 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsPresent()) 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothAdapterClient::Properties* properties = 2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return properties->discovering.value(); 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void BluetoothAdapterChromeOS::CreateRfcommService( 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const BluetoothUUID& uuid, 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ServiceOptions& options, 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const CreateServiceCallback& callback, 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const CreateServiceErrorCallback& error_callback) { 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) VLOG(1) << object_path_.value() << ": Creating RFCOMM service: " 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << uuid.canonical_value(); 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<BluetoothSocketChromeOS> socket = 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BluetoothSocketChromeOS::CreateBluetoothSocket( 2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui_task_runner_, socket_thread_); 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) socket->Listen(this, 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BluetoothSocketChromeOS::kRfcomm, 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uuid, 250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch options, 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(callback, socket), 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error_callback); 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void BluetoothAdapterChromeOS::CreateL2capService( 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const BluetoothUUID& uuid, 257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ServiceOptions& options, 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const CreateServiceCallback& callback, 259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const CreateServiceErrorCallback& error_callback) { 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) VLOG(1) << object_path_.value() << ": Creating L2CAP service: " 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << uuid.canonical_value(); 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<BluetoothSocketChromeOS> socket = 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BluetoothSocketChromeOS::CreateBluetoothSocket( 2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui_task_runner_, socket_thread_); 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) socket->Listen(this, 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BluetoothSocketChromeOS::kL2cap, 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uuid, 268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch options, 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(callback, socket), 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error_callback); 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::RemovePairingDelegateInternal( 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothDevice::PairingDelegate* pairing_delegate) { 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Before removing a pairing delegate make sure that there aren't any devices 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // currently using it; if there are, clear the pairing context which will 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // make any responses no-ops. 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (DevicesMap::iterator iter = devices_.begin(); 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) iter != devices_.end(); ++iter) { 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothDeviceChromeOS* device_chromeos = 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static_cast<BluetoothDeviceChromeOS*>(iter->second); 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothPairingChromeOS* pairing = device_chromeos->GetPairing(); 284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (pairing && pairing->GetPairingDelegate() == pairing_delegate) 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_chromeos->EndPairing(); 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::AdapterAdded( 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const dbus::ObjectPath& object_path) { 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set the adapter to the newly added adapter only if no adapter is present. 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsPresent()) 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetAdapter(object_path); 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::AdapterRemoved( 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const dbus::ObjectPath& object_path) { 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (object_path == object_path_) 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RemoveAdapter(); 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::AdapterPropertyChanged( 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const dbus::ObjectPath& object_path, 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& property_name) { 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (object_path != object_path_) 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothAdapterClient::Properties* properties = 3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (property_name == properties->powered.name()) 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PoweredChanged(properties->powered.value()); 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (property_name == properties->discoverable.name()) 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DiscoverableChanged(properties->discoverable.value()); 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else if (property_name == properties->discovering.name()) 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DiscoveringChanged(properties->discovering.value()); 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::DeviceAdded( 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const dbus::ObjectPath& object_path) { 3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path); 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (properties->adapter.value() != object_path_) 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceChromeOS* device_chromeos = 329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new BluetoothDeviceChromeOS(this, 330010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) object_path, 331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui_task_runner_, 332010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) socket_thread_); 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(devices_.find(device_chromeos->GetAddress()) == devices_.end()); 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) devices_[device_chromeos->GetAddress()] = device_chromeos; 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeviceAdded(this, device_chromeos)); 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::DeviceRemoved( 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const dbus::ObjectPath& object_path) { 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (DevicesMap::iterator iter = devices_.begin(); 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) iter != devices_.end(); ++iter) { 3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceChromeOS* device_chromeos = 3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static_cast<BluetoothDeviceChromeOS*>(iter->second); 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (device_chromeos->object_path() == object_path) { 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) devices_.erase(iter); 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeviceRemoved(this, device_chromeos)); 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delete device_chromeos; 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::DevicePropertyChanged( 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const dbus::ObjectPath& object_path, 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& property_name) { 3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(object_path); 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!device_chromeos) 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceClient::Properties* properties = 3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path); 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (property_name == properties->bluetooth_class.name() || 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) property_name == properties->address.name() || 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) property_name == properties->alias.name() || 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) property_name == properties->paired.name() || 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) property_name == properties->trusted.name() || 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) property_name == properties->connected.name() || 375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) property_name == properties->uuids.name() || 376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) property_name == properties->rssi.name() || 377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) property_name == properties->connection_rssi.name() || 378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) property_name == properties->connection_tx_power.name()) 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NotifyDeviceChanged(device_chromeos); 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // When a device becomes paired, mark it as trusted so that the user does 382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // not need to approve every incoming connection 383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (property_name == properties->paired.name() && 384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) properties->paired.value() && !properties->trusted.value()) 385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_chromeos->SetTrusted(); 386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // UMA connection counting 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (property_name == properties->connected.name()) { 389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // PlayStation joystick tries to reconnect after disconnection from USB. 390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // If it is still not trusted, set it, so it becomes available on the 391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // list of known devices. 392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (properties->connected.value() && device_chromeos->IsTrustable() && 393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !properties->trusted.value()) 394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) device_chromeos->SetTrusted(); 395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int count = 0; 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (DevicesMap::iterator iter = devices_.begin(); 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) iter != devices_.end(); ++iter) { 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (iter->second->IsPaired() && iter->second->IsConnected()) 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++count; 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_HISTOGRAM_COUNTS_100("Bluetooth.ConnectedDeviceCount", count); 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::InputPropertyChanged( 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const dbus::ObjectPath& object_path, 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& property_name) { 4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(object_path); 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!device_chromeos) 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothInputClient::Properties* properties = 4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothInputClient()-> 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path); 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Properties structure can be removed, which triggers a change in the 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // BluetoothDevice::IsConnectable() property, as does a change in the 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // actual reconnect_mode property. 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!properties || 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) property_name == properties->reconnect_mode.name()) 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NotifyDeviceChanged(device_chromeos); 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 427a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid BluetoothAdapterChromeOS::Released() { 428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(agent_.get()); 429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Release"; 430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Called after we unregister the pairing agent, e.g. when changing I/O 432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // capabilities. Nothing much to be done right now. 433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::RequestPinCode( 436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const dbus::ObjectPath& device_path, 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const PinCodeCallback& callback) { 438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(agent_.get()); 439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << device_path.value() << ": RequestPinCode"; 440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothPairingChromeOS* pairing = GetPairing(device_path); 442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing) { 443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(REJECTED, ""); 444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing->RequestPinCode(callback); 448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::DisplayPinCode( 451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const dbus::ObjectPath& device_path, 452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& pincode) { 453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(agent_.get()); 454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << device_path.value() << ": DisplayPinCode: " << pincode; 455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 456a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothPairingChromeOS* pairing = GetPairing(device_path); 457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing) 458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing->DisplayPinCode(pincode); 461a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::RequestPasskey( 464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const dbus::ObjectPath& device_path, 465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const PasskeyCallback& callback) { 466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(agent_.get()); 467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << device_path.value() << ": RequestPasskey"; 468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothPairingChromeOS* pairing = GetPairing(device_path); 470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing) { 471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(REJECTED, 0); 472a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing->RequestPasskey(callback); 476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::DisplayPasskey( 479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const dbus::ObjectPath& device_path, 480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint32 passkey, 481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint16 entered) { 482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(agent_.get()); 483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << device_path.value() << ": DisplayPasskey: " << passkey 484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " (" << entered << " entered)"; 485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 486a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothPairingChromeOS* pairing = GetPairing(device_path); 487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing) 488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (entered == 0) 491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing->DisplayPasskey(passkey); 492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 493a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing->KeysEntered(entered); 494a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 495a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::RequestConfirmation( 497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const dbus::ObjectPath& device_path, 498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint32 passkey, 499a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ConfirmationCallback& callback) { 500a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(agent_.get()); 501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << device_path.value() << ": RequestConfirmation: " << passkey; 502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothPairingChromeOS* pairing = GetPairing(device_path); 504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing) { 505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(REJECTED); 506a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 507a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 508a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 509a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing->RequestConfirmation(passkey, callback); 510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 511a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 512a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::RequestAuthorization( 513a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const dbus::ObjectPath& device_path, 514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ConfirmationCallback& callback) { 515a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(agent_.get()); 516a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << device_path.value() << ": RequestAuthorization"; 517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothPairingChromeOS* pairing = GetPairing(device_path); 519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing) { 520a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(REJECTED); 521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 524a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) pairing->RequestAuthorization(callback); 525a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 526a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 527a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::AuthorizeService( 528a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const dbus::ObjectPath& device_path, 529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& uuid, 530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ConfirmationCallback& callback) { 531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(agent_.get()); 532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << device_path.value() << ": AuthorizeService: " << uuid; 533a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 53446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(device_path); 53546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!device_chromeos) { 53646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback.Run(CANCELLED); 53746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 53846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 53946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 54046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // We always set paired devices to Trusted, so the only reason that this 54146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // method call would ever be called is in the case of a race condition where 54246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // our "Set('Trusted', true)" method call is still pending in the Bluetooth 54346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // daemon because it's busy handling the incoming connection. 54446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (device_chromeos->IsPaired()) { 54546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback.Run(SUCCESS); 54646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 54746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 54846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 54946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // TODO(keybuk): reject service authorizations when not paired, determine 55046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // whether this is acceptable long-term. 55146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) LOG(WARNING) << "Rejecting service connection from unpaired device " 55246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) << device_chromeos->GetAddress() << " for UUID " << uuid; 55346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback.Run(REJECTED); 554a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 555a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 556a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::Cancel() { 557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(agent_.get()); 558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Cancel"; 559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::OnRegisterAgent() { 562a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Pairing agent registered, requesting to be made default"; 563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 564a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAgentManagerClient()-> 565a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RequestDefaultAgent( 566a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dbus::ObjectPath(kAgentPath), 567a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothAdapterChromeOS::OnRequestDefaultAgent, 568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 569a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothAdapterChromeOS::OnRequestDefaultAgentError, 570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 571a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 572a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 573a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::OnRegisterAgentError( 575a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& error_name, 576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& error_message) { 577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Our agent being already registered isn't an error. 578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error_name == bluetooth_agent_manager::kErrorAlreadyExists) 579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 581a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(WARNING) << ": Failed to register pairing agent: " 582a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << error_name << ": " << error_message; 583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 584a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::OnRequestDefaultAgent() { 586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Pairing agent now default"; 587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::OnRequestDefaultAgentError( 590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& error_name, 591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& error_message) { 592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(WARNING) << ": Failed to make pairing agent default: " 593a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << error_name << ": " << error_message; 594a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothDeviceChromeOS* 5977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothAdapterChromeOS::GetDeviceWithPath( 598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const dbus::ObjectPath& object_path) { 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (DevicesMap::iterator iter = devices_.begin(); 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) iter != devices_.end(); ++iter) { 6017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceChromeOS* device_chromeos = 6027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static_cast<BluetoothDeviceChromeOS*>(iter->second); 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (device_chromeos->object_path() == object_path) 604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return device_chromeos; 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 610a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BluetoothPairingChromeOS* BluetoothAdapterChromeOS::GetPairing( 611a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const dbus::ObjectPath& object_path) 612a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 613a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothDeviceChromeOS* device_chromeos = GetDeviceWithPath(object_path); 614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!device_chromeos) { 615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(WARNING) << "Pairing Agent request for unknown device: " 616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << object_path.value(); 617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NULL; 618a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothPairingChromeOS* pairing = device_chromeos->GetPairing(); 621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (pairing) 622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return pairing; 623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 624a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The device doesn't have its own pairing context, so this is an incoming 625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // pairing request that should use our best default delegate (if we have one). 626a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BluetoothDevice::PairingDelegate* pairing_delegate = DefaultPairingDelegate(); 627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!pairing_delegate) 628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NULL; 629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 630a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return device_chromeos->BeginPairing(pairing_delegate); 631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 6337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::SetAdapter(const dbus::ObjectPath& object_path) { 634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!IsPresent()); 635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) object_path_ = object_path; 636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": using adapter."; 638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 639a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Registering pairing agent"; 640a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAgentManagerClient()-> 641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RegisterAgent( 642a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dbus::ObjectPath(kAgentPath), 643a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bluetooth_agent_manager::kKeyboardDisplayCapability, 644a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgent, 645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 646a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgentError, 647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 648a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetDefaultAdapterName(); 650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothAdapterClient::Properties* properties = 6527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PresentChanged(true); 656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (properties->powered.value()) 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PoweredChanged(true); 6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (properties->discoverable.value()) 6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DiscoverableChanged(true); 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (properties->discovering.value()) 662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DiscoveringChanged(true); 663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<dbus::ObjectPath> device_paths = 6657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDevicesForAdapter(object_path_); 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (std::vector<dbus::ObjectPath>::iterator iter = device_paths.begin(); 669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) iter != device_paths.end(); ++iter) { 670010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DeviceAdded(*iter); 671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BluetoothAdapterChromeOS::SetDefaultAdapterName() { 6751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string board = base::SysInfo::GetLsbReleaseBoard(); 676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string alias; 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (board.substr(0, 6) == "stumpy") { 678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) alias = "Chromebox"; 679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (board.substr(0, 4) == "link") { 680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) alias = "Chromebook Pixel"; 681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) alias = "Chromebook"; 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetName(alias, base::Bind(&base::DoNothing), base::Bind(&base::DoNothing)); 686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::RemoveAdapter() { 689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(IsPresent()); 690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << object_path_.value() << ": adapter removed."; 691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothAdapterClient::Properties* properties = 6937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetProperties(object_path_); 695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) object_path_ = dbus::ObjectPath(""); 697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (properties->powered.value()) 699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PoweredChanged(false); 7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (properties->discoverable.value()) 7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DiscoverableChanged(false); 702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (properties->discovering.value()) 703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DiscoveringChanged(false); 704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Copy the devices list here and clear the original so that when we 706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // send DeviceRemoved(), GetDevices() returns no devices. 707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DevicesMap devices = devices_; 708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) devices_.clear(); 709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (DevicesMap::iterator iter = devices.begin(); 711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) iter != devices.end(); ++iter) { 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, 713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeviceRemoved(this, iter->second)); 714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delete iter->second; 715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PresentChanged(false); 718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::PoweredChanged(bool powered) { 721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, 722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AdapterPoweredChanged(this, powered)); 723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BluetoothAdapterChromeOS::DiscoverableChanged(bool discoverable) { 7265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, 7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AdapterDiscoverableChanged(this, discoverable)); 7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::DiscoveringChanged( 731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool discovering) { 732a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If the adapter stopped discovery due to a reason other than a request by 733a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // us, reset the count to 0. 734a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Discovering changed: " << discovering; 735a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!discovering && !discovery_request_pending_ 736a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) && num_discovery_sessions_ > 0) { 737a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Marking sessions as inactive."; 738a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) num_discovery_sessions_ = 0; 739a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MarkDiscoverySessionsAsInactive(); 740a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, 742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AdapterDiscoveringChanged(this, discovering)); 743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::PresentChanged(bool present) { 746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, 747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AdapterPresentChanged(this, present)); 748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::NotifyDeviceChanged( 7517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BluetoothDeviceChromeOS* device) { 752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(device->adapter_ == this); 753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, 755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeviceChanged(this, device)); 756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BluetoothAdapterChromeOS::NotifyGattServiceAdded( 7595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BluetoothRemoteGattServiceChromeOS* service) { 7605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(service->GetAdapter(), this); 7615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ( 7625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static_cast<BluetoothDeviceChromeOS*>(service->GetDevice())->adapter_, 7635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this); 7645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, 7665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) observers_, 7675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GattServiceAdded(this, service->GetDevice(), service)); 7685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 7695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BluetoothAdapterChromeOS::NotifyGattServiceRemoved( 7715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BluetoothRemoteGattServiceChromeOS* service) { 7725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(service->GetAdapter(), this); 7735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ( 7745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static_cast<BluetoothDeviceChromeOS*>(service->GetDevice())->adapter_, 7755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this); 7765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, 7785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) observers_, 7795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GattServiceRemoved(this, service->GetDevice(), service)); 7805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 7815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BluetoothAdapterChromeOS::NotifyGattServiceChanged( 7835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BluetoothRemoteGattServiceChromeOS* service) { 7845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(service->GetAdapter(), this); 7855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, 7875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) observers_, 7885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GattServiceChanged(this, service)); 7895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 7905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BluetoothAdapterChromeOS::NotifyGattDiscoveryComplete( 7925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BluetoothRemoteGattServiceChromeOS* service) { 7935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(service->GetAdapter(), this); 7945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, 7965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) observers_, 7975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GattDiscoveryCompleteForService(this, service)); 7985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 7995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BluetoothAdapterChromeOS::NotifyGattCharacteristicAdded( 8015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BluetoothRemoteGattCharacteristicChromeOS* characteristic) { 8025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>( 8035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) characteristic->GetService())->GetAdapter(), 8045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this); 8055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, 8075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) observers_, 8085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GattCharacteristicAdded(this, characteristic)); 8095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 8105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BluetoothAdapterChromeOS::NotifyGattCharacteristicRemoved( 8125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BluetoothRemoteGattCharacteristicChromeOS* characteristic) { 8135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>( 8145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) characteristic->GetService())->GetAdapter(), 8155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this); 8165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, 8185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) observers_, 8195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GattCharacteristicRemoved(this, characteristic)); 8205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 8215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BluetoothAdapterChromeOS::NotifyGattDescriptorAdded( 8235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BluetoothRemoteGattDescriptorChromeOS* descriptor) { 8245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>( 8255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) descriptor->GetCharacteristic()->GetService())->GetAdapter(), 8265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this); 8275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, 8295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) observers_, 8305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GattDescriptorAdded(this, descriptor)); 8315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 8325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BluetoothAdapterChromeOS::NotifyGattDescriptorRemoved( 8345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BluetoothRemoteGattDescriptorChromeOS* descriptor) { 8355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>( 8365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) descriptor->GetCharacteristic()->GetService())->GetAdapter(), 8375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this); 8385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, 8405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) observers_, 8415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GattDescriptorRemoved(this, descriptor)); 8425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 8435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BluetoothAdapterChromeOS::NotifyGattCharacteristicValueChanged( 8455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BluetoothRemoteGattCharacteristicChromeOS* characteristic, 8465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<uint8>& value) { 8475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>( 8485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) characteristic->GetService())->GetAdapter(), 8495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this); 8505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FOR_EACH_OBSERVER( 8525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BluetoothAdapter::Observer, 8535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) observers_, 8545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GattCharacteristicValueChanged(this, characteristic, value)); 8555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 8565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BluetoothAdapterChromeOS::NotifyGattDescriptorValueChanged( 8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BluetoothRemoteGattDescriptorChromeOS* descriptor, 8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<uint8>& value) { 8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(static_cast<BluetoothRemoteGattServiceChromeOS*>( 8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) descriptor->GetCharacteristic()->GetService())->GetAdapter(), 8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this); 8635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FOR_EACH_OBSERVER(BluetoothAdapter::Observer, 8655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) observers_, 8665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GattDescriptorValueChanged(this, descriptor, value)); 8675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 8685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BluetoothAdapterChromeOS::OnSetDiscoverable( 8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Closure& callback, 8715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ErrorCallback& error_callback, 8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool success) { 8735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Set the discoverable_timeout property to zero so the adapter remains 8745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // discoverable forever. 8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetProperties(object_path_)->discoverable_timeout.Set( 8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&BluetoothAdapterChromeOS::OnPropertyChangeCompleted, 8795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 8805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback, 8815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_callback)); 8825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 8835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BluetoothAdapterChromeOS::OnPropertyChangeCompleted( 8855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Closure& callback, 8865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ErrorCallback& error_callback, 8875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool success) { 888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (success) 889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(); 890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run(); 892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 894a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::AddDiscoverySession( 895a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::Closure& callback, 896a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ErrorCallback& error_callback) { 897a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << __func__; 898a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (discovery_request_pending_) { 899a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The pending request is either to stop a previous session or to start a 900a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // new one. Either way, queue this one. 901a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(num_discovery_sessions_ == 1 || num_discovery_sessions_ == 0); 902a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Pending request to start/stop device discovery. Queueing " 903a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "request to start a new discovery session."; 904a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) discovery_request_queue_.push(std::make_pair(callback, error_callback)); 905a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 906a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 907a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 908a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The adapter is already discovering. 909a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (num_discovery_sessions_ > 0) { 910a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(IsDiscovering()); 911a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!discovery_request_pending_); 912a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) num_discovery_sessions_++; 913a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(); 914a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 915a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 916a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 917a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There are no active discovery sessions. 918a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(num_discovery_sessions_ == 0); 919a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 920a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This is the first request to start device discovery. 921a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) discovery_request_pending_ = true; 922a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 923a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StartDiscovery( 924a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_path_, 925a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothAdapterChromeOS::OnStartDiscovery, 926a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 927a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback), 928a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothAdapterChromeOS::OnStartDiscoveryError, 929a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 930a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback, 931a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_callback)); 932a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 933a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 934a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::RemoveDiscoverySession( 935a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::Closure& callback, 936a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ErrorCallback& error_callback) { 937a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << __func__; 938a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There are active sessions other than the one currently being removed. 939a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (num_discovery_sessions_ > 1) { 940a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(IsDiscovering()); 941a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!discovery_request_pending_); 942a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) num_discovery_sessions_--; 943a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(); 944a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 945a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 946a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 947a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If there is a pending request to BlueZ, then queue this request. 948a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (discovery_request_pending_) { 949a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Pending request to start/stop device discovery. Queueing " 950a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "request to stop discovery session."; 951a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_callback.Run(); 952a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 953a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 954a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 955a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There are no active sessions. Return error. 956a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (num_discovery_sessions_ == 0) { 957a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(armansito): This should never happen once we have the 958a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // DiscoverySession API. Replace this case with an assert once it's 959a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // the deprecated methods have been removed. (See crbug.com/3445008). 960a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "No active discovery sessions. Returning error."; 961a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_callback.Run(); 962a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 963a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 964a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 965a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There is exactly one active discovery session. Request BlueZ to stop 966a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // discovery. 967a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(num_discovery_sessions_ == 1); 968a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) discovery_request_pending_ = true; 969a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 970a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StopDiscovery( 971a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_path_, 972a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothAdapterChromeOS::OnStopDiscovery, 973a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 974a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback), 975a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BluetoothAdapterChromeOS::OnStopDiscoveryError, 976a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 977a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_callback)); 978a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 979a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 9807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::OnStartDiscovery(const base::Closure& callback) { 981a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Report success on the original request and increment the count. 982a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << __func__; 983a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(discovery_request_pending_); 984a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(num_discovery_sessions_ == 0); 985a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) discovery_request_pending_ = false; 986a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) num_discovery_sessions_++; 987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(); 988a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 989a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Try to add a new discovery session for each queued request. 990a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProcessQueuedDiscoveryRequests(); 991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::OnStartDiscoveryError( 994a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::Closure& callback, 995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback, 996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_name, 997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << object_path_.value() << ": Failed to start discovery: " 999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error_name << ": " << error_message; 1000a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1001a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Failed to start discovery. This can only happen if the count is at 0. 1002a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(num_discovery_sessions_ == 0); 1003a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(discovery_request_pending_); 1004a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) discovery_request_pending_ = false; 1005a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1006a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Discovery request may fail if discovery was previously initiated by Chrome, 1007a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // but the session were invalidated due to the discovery state unexpectedly 1008a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // changing to false and then back to true. In this case, report success. 1009a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error_name == bluetooth_device::kErrorInProgress && IsDiscovering()) { 1010a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Discovery previously initiated. Reporting success."; 1011a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) num_discovery_sessions_++; 1012a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback.Run(); 1013a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 1014a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_callback.Run(); 1015a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1016a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1017a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Try to add a new discovery session for each queued request. 1018a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProcessQueuedDiscoveryRequests(); 1019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::OnStopDiscovery(const base::Closure& callback) { 1022a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Report success on the original request and decrement the count. 1023a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << __func__; 1024a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(discovery_request_pending_); 1025a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(num_discovery_sessions_ == 1); 1026a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) discovery_request_pending_ = false; 1027a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) num_discovery_sessions_--; 1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(); 1029a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1030a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Try to add a new discovery session for each queued request. 1031a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProcessQueuedDiscoveryRequests(); 1032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BluetoothAdapterChromeOS::OnStopDiscoveryError( 1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ErrorCallback& error_callback, 1036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_name, 1037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << object_path_.value() << ": Failed to stop discovery: " 1039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error_name << ": " << error_message; 1040a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1041a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Failed to stop discovery. This can only happen if the count is at 1. 1042a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(discovery_request_pending_); 1043a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(num_discovery_sessions_ == 1); 1044a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) discovery_request_pending_ = false; 1045c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_callback.Run(); 1046a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1047a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Try to add a new discovery session for each queued request. 1048a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProcessQueuedDiscoveryRequests(); 1049a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 1050a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1051a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BluetoothAdapterChromeOS::ProcessQueuedDiscoveryRequests() { 1052a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (!discovery_request_queue_.empty()) { 1053a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Process queued discovery request."; 1054a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DiscoveryCallbackPair callbacks = discovery_request_queue_.front(); 1055a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) discovery_request_queue_.pop(); 1056a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddDiscoverySession(callbacks.first, callbacks.second); 1057a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1058a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If the queued request resulted in a pending call, then let it 1059a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // asynchonously process the remaining queued requests once the pending 1060a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // call returns. 1061a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (discovery_request_pending_) 1062a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 1063a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace chromeos 1067