Home | History | Annotate | Download | only in bluetooth
      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_notify_session_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 #include "device/bluetooth/bluetooth_gatt_service.h"
     13 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
     14 
     15 namespace chromeos {
     16 
     17 BluetoothGattNotifySessionChromeOS::BluetoothGattNotifySessionChromeOS(
     18     scoped_refptr<device::BluetoothAdapter> adapter,
     19     const std::string& device_address,
     20     const std::string& service_identifier,
     21     const std::string& characteristic_identifier,
     22     const dbus::ObjectPath& characteristic_path)
     23     : active_(true),
     24       adapter_(adapter),
     25       device_address_(device_address),
     26       service_id_(service_identifier),
     27       characteristic_id_(characteristic_identifier),
     28       object_path_(characteristic_path) {
     29   DCHECK(adapter_.get());
     30   DCHECK(!device_address_.empty());
     31   DCHECK(!service_id_.empty());
     32   DCHECK(!characteristic_id_.empty());
     33   DCHECK(object_path_.IsValid());
     34 
     35   DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->AddObserver(
     36       this);
     37 }
     38 
     39 BluetoothGattNotifySessionChromeOS::~BluetoothGattNotifySessionChromeOS() {
     40   DBusThreadManager::Get()
     41       ->GetBluetoothGattCharacteristicClient()
     42       ->RemoveObserver(this);
     43   Stop(base::Bind(&base::DoNothing));
     44 }
     45 
     46 std::string BluetoothGattNotifySessionChromeOS::GetCharacteristicIdentifier()
     47     const {
     48   return characteristic_id_;
     49 }
     50 
     51 bool BluetoothGattNotifySessionChromeOS::IsActive() {
     52   // Determine if the session is active. If |active_| is false, then it's
     53   // been explicitly marked, so return false.
     54   if (!active_)
     55     return false;
     56 
     57   // The fact that |active_| is true doesn't mean that the session is
     58   // actually active, since the characteristic might have stopped sending
     59   // notifications yet this method was called before we processed the
     60   // observer event (e.g. because somebody else called this method in their
     61   // BluetoothGattCharacteristicClient::Observer implementation, which was
     62   // called before ours). Check the client to see if notifications are still
     63   // being sent.
     64   BluetoothGattCharacteristicClient::Properties* properties =
     65       DBusThreadManager::Get()
     66           ->GetBluetoothGattCharacteristicClient()
     67           ->GetProperties(object_path_);
     68   if (!properties || !properties->notifying.value())
     69     active_ = false;
     70 
     71   return active_;
     72 }
     73 
     74 void BluetoothGattNotifySessionChromeOS::Stop(const base::Closure& callback) {
     75   if (!active_) {
     76     VLOG(1) << "Notify session already inactive.";
     77     callback.Run();
     78     return;
     79   }
     80 
     81   // Mark this session as inactive no matter what.
     82   active_ = false;
     83 
     84   device::BluetoothDevice* device = adapter_->GetDevice(device_address_);
     85   if (!device)
     86     return;
     87 
     88   device::BluetoothGattService* service = device->GetGattService(service_id_);
     89   if (!service)
     90     return;
     91 
     92   BluetoothRemoteGattCharacteristicChromeOS* chrc =
     93       static_cast<BluetoothRemoteGattCharacteristicChromeOS*>(
     94           service->GetCharacteristic(characteristic_id_));
     95   if (!chrc)
     96     return;
     97 
     98   chrc->RemoveNotifySession(callback);
     99 }
    100 
    101 void BluetoothGattNotifySessionChromeOS::GattCharacteristicRemoved(
    102     const dbus::ObjectPath& object_path) {
    103   if (object_path != object_path_)
    104     return;
    105 
    106   active_ = false;
    107 }
    108 
    109 void BluetoothGattNotifySessionChromeOS::GattCharacteristicPropertyChanged(
    110     const dbus::ObjectPath& object_path,
    111     const std::string& property_name) {
    112   if (object_path != object_path_)
    113     return;
    114 
    115   if (!active_)
    116     return;
    117 
    118   BluetoothGattCharacteristicClient::Properties* properties =
    119       DBusThreadManager::Get()
    120           ->GetBluetoothGattCharacteristicClient()
    121           ->GetProperties(object_path_);
    122   if (!properties) {
    123     active_ = false;
    124     return;
    125   }
    126 
    127   if (property_name == properties->notifying.name() &&
    128       !properties->notifying.value())
    129     active_ = false;
    130 }
    131 
    132 }  // namespace chromeos
    133