1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "device/bluetooth/bluetooth_gatt_connection_chromeos.h" 6 7 #include "base/bind.h" 8 #include "base/logging.h" 9 #include "chromeos/dbus/dbus_thread_manager.h" 10 #include "device/bluetooth/bluetooth_adapter.h" 11 #include "device/bluetooth/bluetooth_device.h" 12 13 namespace chromeos { 14 15 BluetoothGattConnectionChromeOS::BluetoothGattConnectionChromeOS( 16 scoped_refptr<device::BluetoothAdapter> adapter, 17 const std::string& device_address, 18 const dbus::ObjectPath& object_path) 19 : connected_(true), 20 adapter_(adapter), 21 device_address_(device_address), 22 object_path_(object_path) { 23 DCHECK(adapter_.get()); 24 DCHECK(!device_address_.empty()); 25 DCHECK(object_path_.IsValid()); 26 27 DBusThreadManager::Get()->GetBluetoothDeviceClient()->AddObserver(this); 28 } 29 30 BluetoothGattConnectionChromeOS::~BluetoothGattConnectionChromeOS() { 31 DBusThreadManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(this); 32 Disconnect(base::Bind(&base::DoNothing)); 33 } 34 35 std::string BluetoothGattConnectionChromeOS::GetDeviceAddress() const { 36 return device_address_; 37 } 38 39 bool BluetoothGattConnectionChromeOS::IsConnected() { 40 // Lazily determine the activity state of the connection. If already 41 // marked as inactive, then return false. Otherwise, explicitly mark 42 // |connected_| as false if the device is removed or disconnected. We do this, 43 // so that if this method is called during a call to DeviceRemoved or 44 // DeviceChanged somewhere else, it returns the correct status. 45 if (!connected_) 46 return false; 47 48 BluetoothDeviceClient::Properties* properties = 49 DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 50 GetProperties(object_path_); 51 if (!properties || !properties->connected.value()) 52 connected_ = false; 53 54 return connected_; 55 } 56 57 void BluetoothGattConnectionChromeOS::Disconnect( 58 const base::Closure& callback) { 59 if (!connected_) { 60 VLOG(1) << "Connection already inactive."; 61 callback.Run(); 62 return; 63 } 64 65 // TODO(armansito): There isn't currently a good way to manage the ownership 66 // of a connection between Chrome and bluetoothd plugins/profiles. Until 67 // a proper reference count is kept by bluetoothd, we might unwittingly kill 68 // a connection that is managed by the daemon (e.g. HoG). For now, just return 69 // success to indicate that this BluetoothGattConnection is no longer active, 70 // even though the underlying connection won't actually be disconnected. This 71 // technically doesn't violate the contract put forth by this API. 72 connected_ = false; 73 callback.Run(); 74 } 75 76 void BluetoothGattConnectionChromeOS::DeviceRemoved( 77 const dbus::ObjectPath& object_path) { 78 if (object_path != object_path_) 79 return; 80 81 connected_ = false; 82 } 83 84 void BluetoothGattConnectionChromeOS::DevicePropertyChanged( 85 const dbus::ObjectPath& object_path, 86 const std::string& property_name) { 87 if (object_path != object_path_) 88 return; 89 90 if (!connected_) 91 return; 92 93 BluetoothDeviceClient::Properties* properties = 94 DBusThreadManager::Get()->GetBluetoothDeviceClient()-> 95 GetProperties(object_path_); 96 97 if (!properties) { 98 connected_ = false; 99 return; 100 } 101 102 if (property_name == properties->connected.name() && 103 !properties->connected.value()) 104 connected_ = false; 105 } 106 107 } // namespace chromeos 108