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