1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "device/bluetooth/bluetooth_gatt_notify_session_chromeos.h" 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/bind.h" 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/logging.h" 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/dbus/dbus_thread_manager.h" 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "device/bluetooth/bluetooth_adapter.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "device/bluetooth/bluetooth_device.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "device/bluetooth/bluetooth_gatt_service.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace chromeos { 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 17116680a4aac90f2aa7413d9095a592090648e557Ben MurdochBluetoothGattNotifySessionChromeOS::BluetoothGattNotifySessionChromeOS( 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<device::BluetoothAdapter> adapter, 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& device_address, 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& service_identifier, 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& characteristic_identifier, 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const dbus::ObjectPath& characteristic_path) 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : active_(true), 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch adapter_(adapter), 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch device_address_(device_address), 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch service_id_(service_identifier), 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch characteristic_id_(characteristic_identifier), 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch object_path_(characteristic_path) { 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(adapter_.get()); 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!device_address_.empty()); 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!service_id_.empty()); 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!characteristic_id_.empty()); 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(object_path_.IsValid()); 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->AddObserver( 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this); 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 39116680a4aac90f2aa7413d9095a592090648e557Ben MurdochBluetoothGattNotifySessionChromeOS::~BluetoothGattNotifySessionChromeOS() { 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DBusThreadManager::Get() 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ->GetBluetoothGattCharacteristicClient() 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ->RemoveObserver(this); 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Stop(base::Bind(&base::DoNothing)); 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstd::string BluetoothGattNotifySessionChromeOS::GetCharacteristicIdentifier() 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const { 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return characteristic_id_; 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool BluetoothGattNotifySessionChromeOS::IsActive() { 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Determine if the session is active. If |active_| is false, then it's 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // been explicitly marked, so return false. 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!active_) 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The fact that |active_| is true doesn't mean that the session is 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // actually active, since the characteristic might have stopped sending 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // notifications yet this method was called before we processed the 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // observer event (e.g. because somebody else called this method in their 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // BluetoothGattCharacteristicClient::Observer implementation, which was 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // called before ours). Check the client to see if notifications are still 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // being sent. 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch BluetoothGattCharacteristicClient::Properties* properties = 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DBusThreadManager::Get() 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ->GetBluetoothGattCharacteristicClient() 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ->GetProperties(object_path_); 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!properties || !properties->notifying.value()) 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch active_ = false; 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return active_; 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid BluetoothGattNotifySessionChromeOS::Stop(const base::Closure& callback) { 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!active_) { 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch VLOG(1) << "Notify session already inactive."; 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback.Run(); 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Mark this session as inactive no matter what. 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch active_ = false; 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch device::BluetoothDevice* device = adapter_->GetDevice(device_address_); 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!device) 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch device::BluetoothGattService* service = device->GetGattService(service_id_); 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!service) 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch BluetoothRemoteGattCharacteristicChromeOS* chrc = 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static_cast<BluetoothRemoteGattCharacteristicChromeOS*>( 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch service->GetCharacteristic(characteristic_id_)); 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!chrc) 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch chrc->RemoveNotifySession(callback); 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid BluetoothGattNotifySessionChromeOS::GattCharacteristicRemoved( 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const dbus::ObjectPath& object_path) { 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (object_path != object_path_) 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch active_ = false; 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid BluetoothGattNotifySessionChromeOS::GattCharacteristicPropertyChanged( 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const dbus::ObjectPath& object_path, 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& property_name) { 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (object_path != object_path_) 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!active_) 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch BluetoothGattCharacteristicClient::Properties* properties = 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DBusThreadManager::Get() 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ->GetBluetoothGattCharacteristicClient() 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ->GetProperties(object_path_); 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!properties) { 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch active_ = false; 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (property_name == properties->notifying.name() && 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch !properties->notifying.value()) 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch active_ = false; 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace chromeos 133