Commit 801a41d0 authored by Bailey Forrest's avatar Bailey Forrest Committed by Commit Bot

[chromecast] Add mocks for BLE API

This CL just adds virtual interfaces around the existing classes for the
BLE interfaces. No other code changes should be made.

BUG=internal b/77282414
TEST=cast_bluetooth_unittests cast_internal_bluetooth_unittests

Change-Id: I3891eebb61dd187709ec15bbaac32b962e4c2d9e
Reviewed-on: https://chromium-review.googlesource.com/987374
Commit-Queue: Bailey Forrest <bcf@chromium.org>
Reviewed-by: default avatarConley Owens <cco3@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarStephen Lanham <slan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#547343}
parent 433c1c50
......@@ -6,18 +6,25 @@ import("//chromecast/chromecast.gni")
cast_source_set("le") {
sources = [
"gatt_client_manager.cc",
"gatt_client_manager.h",
"le_scan_manager.cc",
"gatt_client_manager_impl.cc",
"gatt_client_manager_impl.h",
"le_scan_manager.h",
"remote_characteristic.cc",
"le_scan_manager_impl.cc",
"le_scan_manager_impl.h",
"remote_characteristic.h",
"remote_characteristic_impl.cc",
"remote_characteristic_impl.h",
"remote_descriptor.cc",
"remote_descriptor.h",
"remote_device.cc",
"remote_descriptor_impl.cc",
"remote_descriptor_impl.h",
"remote_device.h",
"remote_service.cc",
"remote_device_impl.cc",
"remote_device_impl.h",
"remote_service.h",
"remote_service_impl.cc",
"remote_service_impl.h",
]
public_deps = [
......@@ -32,15 +39,41 @@ cast_source_set("le") {
]
}
cast_source_set("test_support") {
testonly = true
sources = [
"mock_gatt_client_manager.cc",
"mock_gatt_client_manager.h",
"mock_le_scan_manager.cc",
"mock_le_scan_manager.h",
"mock_remote_characteristic.cc",
"mock_remote_characteristic.h",
"mock_remote_descriptor.cc",
"mock_remote_descriptor.h",
"mock_remote_device.cc",
"mock_remote_device.h",
"mock_remote_service.cc",
"mock_remote_service.h",
]
deps = [
":le",
"//chromecast/public",
"//testing/gmock",
]
}
cast_source_set("unittests") {
testonly = true
sources = [
"gatt_client_manager_test.cc",
"le_scan_manager_test.cc",
"gatt_client_manager_impl_test.cc",
"instantiate_mocks.cc",
"le_scan_manager_impl_test.cc",
]
deps = [
":le",
":test_support",
"//base",
"//base/test:test_support",
"//chromecast/device/bluetooth:test_support",
......
......@@ -9,11 +9,10 @@
#include <set>
#include <vector>
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list_threadsafe.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "chromecast/device/bluetooth/shlib/gatt_client.h"
#include "chromecast/public/bluetooth/bluetooth_types.h"
namespace chromecast {
namespace bluetooth {
......@@ -22,7 +21,7 @@ class RemoteCharacteristic;
class RemoteDevice;
class RemoteService;
class GattClientManager : public bluetooth_v2_shlib::Gatt::Client::Delegate {
class GattClientManager {
public:
class Observer {
public:
......@@ -51,14 +50,10 @@ class GattClientManager : public bluetooth_v2_shlib::Gatt::Client::Delegate {
virtual ~Observer() = default;
};
explicit GattClientManager(bluetooth_v2_shlib::GattClient* gatt_client);
~GattClientManager() override;
virtual ~GattClientManager() = default;
void Initialize(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
void Finalize();
void AddObserver(Observer* o);
void RemoveObserver(Observer* o);
virtual void AddObserver(Observer* o) = 0;
virtual void RemoveObserver(Observer* o) = 0;
// TODO(bcf/slan): Add new method:
// void GetDevices(Callback<void(vector<scoped_refptr<RemoteDevice>>)> cb);
......@@ -68,86 +63,23 @@ class GattClientManager : public bluetooth_v2_shlib::Gatt::Client::Delegate {
// methods on RemoteDevice and its subobjects (RemoteService,
// RemoteCharacteristic, RemoteDescriptor) will also be run on the thread
// which called the specific method.
void GetDevice(const bluetooth_v2_shlib::Addr& addr,
base::OnceCallback<void(scoped_refptr<RemoteDevice>)> cb);
virtual void GetDevice(
const bluetooth_v2_shlib::Addr& addr,
base::OnceCallback<void(scoped_refptr<RemoteDevice>)> cb) = 0;
// TODO(bcf): Deprecated. Replace usage with async version.
scoped_refptr<RemoteDevice> GetDeviceSync(
const bluetooth_v2_shlib::Addr& addr);
virtual scoped_refptr<RemoteDevice> GetDeviceSync(
const bluetooth_v2_shlib::Addr& addr) = 0;
// TODO(bcf): Make async.
// Returns the number of devices which are currently connected.
size_t GetNumConnected() const;
virtual size_t GetNumConnected() const = 0;
void NotifyConnect(const bluetooth_v2_shlib::Addr& addr);
virtual void NotifyConnect(const bluetooth_v2_shlib::Addr& addr) = 0;
// TODO(bcf): Deprecated. Should be removed now that this class may be used
// from any thread.
scoped_refptr<base::SingleThreadTaskRunner> task_runner() {
return io_task_runner_;
}
// TODO(bcf): Should be private and passed into objects which need it (e.g.
// RemoteDevice, RemoteCharacteristic).
bluetooth_v2_shlib::GattClient* gatt_client() const { return gatt_client_; }
private:
// bluetooth_v2_shlib::Gatt::Client::Delegate implementation:
void OnConnectChanged(const bluetooth_v2_shlib::Addr& addr,
bool status,
bool connected) override;
void OnNotification(const bluetooth_v2_shlib::Addr& addr,
uint16_t handle,
const std::vector<uint8_t>& value) override;
void OnCharacteristicReadResponse(const bluetooth_v2_shlib::Addr& addr,
bool status,
uint16_t handle,
const std::vector<uint8_t>& value) override;
void OnCharacteristicWriteResponse(const bluetooth_v2_shlib::Addr& addr,
bool status,
uint16_t handle) override;
void OnDescriptorReadResponse(const bluetooth_v2_shlib::Addr& addr,
bool status,
uint16_t handle,
const std::vector<uint8_t>& value) override;
void OnDescriptorWriteResponse(const bluetooth_v2_shlib::Addr& addr,
bool status,
uint16_t handle) override;
void OnReadRemoteRssi(const bluetooth_v2_shlib::Addr& addr,
bool status,
int rssi) override;
void OnMtuChanged(const bluetooth_v2_shlib::Addr& addr,
bool status,
int mtu) override;
void OnGetServices(
const bluetooth_v2_shlib::Addr& addr,
const std::vector<bluetooth_v2_shlib::Gatt::Service>& services) override;
void OnServicesRemoved(const bluetooth_v2_shlib::Addr& addr,
uint16_t start_handle,
uint16_t end_handle) override;
void OnServicesAdded(
const bluetooth_v2_shlib::Addr& addr,
const std::vector<bluetooth_v2_shlib::Gatt::Service>& services) override;
static void FinalizeOnIoThread(
std::unique_ptr<base::WeakPtrFactory<GattClientManager>> weak_factory);
bluetooth_v2_shlib::GattClient* const gatt_client_;
scoped_refptr<base::ObserverListThreadSafe<Observer>> observers_;
// All bluetooth_v2_shlib calls are run on this task_runner. Following members
// must only be accessed on this task runner.
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
// TODO(bcf): Need to delete on disconnect.
std::map<bluetooth_v2_shlib::Addr, scoped_refptr<RemoteDevice>>
addr_to_device_;
std::set<bluetooth_v2_shlib::Addr> connected_devices_;
base::WeakPtr<GattClientManager> weak_this_;
std::unique_ptr<base::WeakPtrFactory<GattClientManager>> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(GattClientManager);
virtual scoped_refptr<base::SingleThreadTaskRunner> task_runner() = 0;
};
} // namespace bluetooth
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_GATT_CLIENT_MANAGER_IMPL_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_GATT_CLIENT_MANAGER_IMPL_H_
#include <map>
#include <set>
#include <vector>
#include "base/observer_list_threadsafe.h"
#include "chromecast/device/bluetooth/le/gatt_client_manager.h"
#include "chromecast/device/bluetooth/shlib/gatt_client.h"
namespace chromecast {
namespace bluetooth {
class RemoteDeviceImpl;
class GattClientManagerImpl
: public GattClientManager,
public bluetooth_v2_shlib::Gatt::Client::Delegate {
public:
explicit GattClientManagerImpl(bluetooth_v2_shlib::GattClient* gatt_client);
~GattClientManagerImpl() override;
void Initialize(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
void Finalize();
// GattClientManager implementation:
void AddObserver(Observer* o) override;
void RemoveObserver(Observer* o) override;
void GetDevice(
const bluetooth_v2_shlib::Addr& addr,
base::OnceCallback<void(scoped_refptr<RemoteDevice>)> cb) override;
scoped_refptr<RemoteDevice> GetDeviceSync(
const bluetooth_v2_shlib::Addr& addr) override;
size_t GetNumConnected() const override;
void NotifyConnect(const bluetooth_v2_shlib::Addr& addr) override;
scoped_refptr<base::SingleThreadTaskRunner> task_runner() override;
// TODO(bcf): Should be private and passed into objects which need it (e.g.
// RemoteDevice, RemoteCharacteristic).
bluetooth_v2_shlib::GattClient* gatt_client() const { return gatt_client_; }
private:
// bluetooth_v2_shlib::Gatt::Client::Delegate implementation:
void OnConnectChanged(const bluetooth_v2_shlib::Addr& addr,
bool status,
bool connected) override;
void OnNotification(const bluetooth_v2_shlib::Addr& addr,
uint16_t handle,
const std::vector<uint8_t>& value) override;
void OnCharacteristicReadResponse(const bluetooth_v2_shlib::Addr& addr,
bool status,
uint16_t handle,
const std::vector<uint8_t>& value) override;
void OnCharacteristicWriteResponse(const bluetooth_v2_shlib::Addr& addr,
bool status,
uint16_t handle) override;
void OnDescriptorReadResponse(const bluetooth_v2_shlib::Addr& addr,
bool status,
uint16_t handle,
const std::vector<uint8_t>& value) override;
void OnDescriptorWriteResponse(const bluetooth_v2_shlib::Addr& addr,
bool status,
uint16_t handle) override;
void OnReadRemoteRssi(const bluetooth_v2_shlib::Addr& addr,
bool status,
int rssi) override;
void OnMtuChanged(const bluetooth_v2_shlib::Addr& addr,
bool status,
int mtu) override;
void OnGetServices(
const bluetooth_v2_shlib::Addr& addr,
const std::vector<bluetooth_v2_shlib::Gatt::Service>& services) override;
void OnServicesRemoved(const bluetooth_v2_shlib::Addr& addr,
uint16_t start_handle,
uint16_t end_handle) override;
void OnServicesAdded(
const bluetooth_v2_shlib::Addr& addr,
const std::vector<bluetooth_v2_shlib::Gatt::Service>& services) override;
static void FinalizeOnIoThread(
std::unique_ptr<base::WeakPtrFactory<GattClientManagerImpl>>
weak_factory);
bluetooth_v2_shlib::GattClient* const gatt_client_;
scoped_refptr<base::ObserverListThreadSafe<Observer>> observers_;
// All bluetooth_v2_shlib calls are run on this task_runner. Following members
// must only be accessed on this task runner.
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
// TODO(bcf): Need to delete on disconnect.
std::map<bluetooth_v2_shlib::Addr, scoped_refptr<RemoteDeviceImpl>>
addr_to_device_;
std::set<bluetooth_v2_shlib::Addr> connected_devices_;
base::WeakPtr<GattClientManagerImpl> weak_this_;
std::unique_ptr<base::WeakPtrFactory<GattClientManagerImpl>> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(GattClientManagerImpl);
};
} // namespace bluetooth
} // namespace chromecast
#endif // CHROMECAST_DEVICE_BLUETOOTH_LE_GATT_CLIENT_MANAGER_IMPL_H_
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/device/bluetooth/le/gatt_client_manager.h"
#include "chromecast/device/bluetooth/le/gatt_client_manager_impl.h"
#include "base/bind.h"
#include "base/memory/ptr_util.h"
......@@ -105,7 +105,7 @@ class GattClientManagerTest : public ::testing::Test {
std::make_unique<base::MessageLoop>(base::MessageLoop::TYPE_DEFAULT);
gatt_client_ = std::make_unique<bluetooth_v2_shlib::MockGattClient>();
gatt_client_manager_ =
std::make_unique<GattClientManager>(gatt_client_.get());
std::make_unique<GattClientManagerImpl>(gatt_client_.get());
observer_ = std::make_unique<MockGattClientManagerObserver>();
// Normally bluetooth_manager does this.
......@@ -171,7 +171,7 @@ class GattClientManagerTest : public ::testing::Test {
StatusCallbackChecker cb_checker_;
std::unique_ptr<base::MessageLoop> message_loop_;
std::unique_ptr<GattClientManager> gatt_client_manager_;
std::unique_ptr<GattClientManagerImpl> gatt_client_manager_;
std::unique_ptr<bluetooth_v2_shlib::MockGattClient> gatt_client_;
std::unique_ptr<MockGattClientManagerObserver> observer_;
};
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file just instantiates mocks to verify they can compile since no one
// uses them yet.
#include "chromecast/device/bluetooth/le/mock_gatt_client_manager.h"
#include "chromecast/device/bluetooth/le/mock_le_scan_manager.h"
#include "chromecast/device/bluetooth/le/mock_remote_characteristic.h"
#include "chromecast/device/bluetooth/le/mock_remote_descriptor.h"
#include "chromecast/device/bluetooth/le/mock_remote_device.h"
#include "chromecast/device/bluetooth/le/mock_remote_service.h"
namespace chromecast {
namespace bluetooth {
void InstantiateMocks() {
MockGattClientManager a;
MockLeScanManager b;
scoped_refptr<MockRemoteCharacteristic> c = new MockRemoteCharacteristic;
scoped_refptr<MockRemoteDescriptor> d = new MockRemoteDescriptor;
scoped_refptr<MockRemoteDevice> e = new MockRemoteDevice;
scoped_refptr<MockRemoteService> f = new MockRemoteService;
}
} // namespace bluetooth
} // namespace chromecast
......@@ -11,14 +11,13 @@
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/observer_list_threadsafe.h"
#include "chromecast/device/bluetooth/shlib/le_scanner.h"
#include "base/optional.h"
#include "chromecast/public/bluetooth/bluetooth_types.h"
namespace chromecast {
namespace bluetooth {
class LeScanManager : public bluetooth_v2_shlib::LeScanner::Delegate {
class LeScanManager {
public:
struct ScanResult {
ScanResult();
......@@ -45,20 +44,14 @@ class LeScanManager : public bluetooth_v2_shlib::LeScanner::Delegate {
virtual ~Observer() = default;
};
explicit LeScanManager(bluetooth_v2_shlib::LeScannerImpl* le_scanner);
~LeScanManager() override;
void Initialize(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
void Finalize();
void AddObserver(Observer* o);
void RemoveObserver(Observer* o);
virtual void AddObserver(Observer* o) = 0;
virtual void RemoveObserver(Observer* o) = 0;
// Enable or disable BLE scnaning. Can be called on any thread. |cb| is
// called on the thread that calls this method. |success| is false iff the
// operation failed.
using SetScanEnableCallback = base::OnceCallback<void(bool success)>;
void SetScanEnable(bool enable, SetScanEnableCallback cb);
virtual void SetScanEnable(bool enable, SetScanEnableCallback cb) = 0;
// Asynchronously get the most recent scan results. Can be called on any
// thread. |cb| is called on the calling thread with the results. If
......@@ -66,31 +59,14 @@ class LeScanManager : public bluetooth_v2_shlib::LeScanner::Delegate {
// |service_uuid| will be returned.
using GetScanResultsCallback =
base::OnceCallback<void(std::vector<ScanResult>)>;
void GetScanResults(GetScanResultsCallback cb,
base::Optional<uint16_t> service_uuid = base::nullopt);
void ClearScanResults();
private:
// Returns a list of all BLE scan results. The results are sorted by RSSI.
// Must be called on |io_task_runner|.
std::vector<ScanResult> GetScanResultsInternal(
base::Optional<uint16_t> service_uuid);
// bluetooth_v2_shlib::LeScanner::Delegate implementation:
void OnScanResult(const bluetooth_v2_shlib::LeScanner::ScanResult&
scan_result_shlib) override;
bluetooth_v2_shlib::LeScannerImpl* const le_scanner_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
scoped_refptr<base::ObserverListThreadSafe<Observer>> observers_;
std::map<bluetooth_v2_shlib::Addr, std::list<ScanResult>>
addr_to_scan_results_;
virtual void GetScanResults(
GetScanResultsCallback cb,
base::Optional<uint16_t> service_uuid = base::nullopt) = 0;
base::WeakPtrFactory<LeScanManager> weak_factory_;
virtual void ClearScanResults() = 0;
DISALLOW_COPY_AND_ASSIGN(LeScanManager);
protected:
virtual ~LeScanManager() = default;
};
} // namespace bluetooth
......
......@@ -2,16 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/device/bluetooth/le/le_scan_manager.h"
#include "chromecast/device/bluetooth/le/le_scan_manager_impl.h"
#include <algorithm>
#include "chromecast/base/bind_to_task_runner.h"
#include "chromecast/public/cast_media_shlib.h"
#define RUN_ON_IO_THREAD(method, ...) \
io_task_runner_->PostTask( \
FROM_HERE, base::BindOnce(&LeScanManager::method, \
#define RUN_ON_IO_THREAD(method, ...) \
io_task_runner_->PostTask( \
FROM_HERE, base::BindOnce(&LeScanManagerImpl::method, \
weak_factory_.GetWeakPtr(), ##__VA_ARGS__));
#define MAKE_SURE_IO_THREAD(method, ...) \
......@@ -61,7 +61,7 @@ bool DataContainsUuid(const std::vector<uint8_t>& data, uint16_t uuid) {
return false;
}
bool ScanResultHasServiceUuid(const LeScanManager::ScanResult& scan_result,
bool ScanResultHasServiceUuid(const LeScanManagerImpl::ScanResult& scan_result,
uint16_t service_uuid) {
auto it = scan_result.type_to_data.find(kGapIncomplete16BitServiceUuids);
if (it != scan_result.type_to_data.end() &&
......@@ -80,34 +80,35 @@ bool ScanResultHasServiceUuid(const LeScanManager::ScanResult& scan_result,
} // namespace
LeScanManager::ScanResult::ScanResult() = default;
LeScanManager::ScanResult::ScanResult(const LeScanManager::ScanResult& other) =
default;
LeScanManager::ScanResult::~ScanResult() = default;
LeScanManagerImpl::ScanResult::ScanResult() = default;
LeScanManagerImpl::ScanResult::ScanResult(
const LeScanManagerImpl::ScanResult& other) = default;
LeScanManagerImpl::ScanResult::~ScanResult() = default;
LeScanManager::LeScanManager(bluetooth_v2_shlib::LeScannerImpl* le_scanner)
LeScanManagerImpl::LeScanManagerImpl(
bluetooth_v2_shlib::LeScannerImpl* le_scanner)
: le_scanner_(le_scanner),
observers_(new base::ObserverListThreadSafe<Observer>()),
weak_factory_(this) {}
LeScanManager::~LeScanManager() = default;
LeScanManagerImpl::~LeScanManagerImpl() = default;
void LeScanManager::Initialize(
void LeScanManagerImpl::Initialize(
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) {
io_task_runner_ = std::move(io_task_runner);
}
void LeScanManager::Finalize() {}
void LeScanManagerImpl::Finalize() {}
void LeScanManager::AddObserver(Observer* observer) {
void LeScanManagerImpl::AddObserver(Observer* observer) {
observers_->AddObserver(observer);
}
void LeScanManager::RemoveObserver(Observer* observer) {
void LeScanManagerImpl::RemoveObserver(Observer* observer) {
observers_->RemoveObserver(observer);
}
void LeScanManager::SetScanEnable(bool enable, SetScanEnableCallback cb) {
void LeScanManagerImpl::SetScanEnable(bool enable, SetScanEnableCallback cb) {
MAKE_SURE_IO_THREAD(SetScanEnable, enable,
BindToCurrentSequence(std::move(cb)));
bool success;
......@@ -127,15 +128,16 @@ void LeScanManager::SetScanEnable(bool enable, SetScanEnableCallback cb) {
EXEC_CB_AND_RET(cb, true);
}
void LeScanManager::GetScanResults(GetScanResultsCallback cb,
base::Optional<uint16_t> service_uuid) {
void LeScanManagerImpl::GetScanResults(GetScanResultsCallback cb,
base::Optional<uint16_t> service_uuid) {
MAKE_SURE_IO_THREAD(GetScanResults, BindToCurrentSequence(std::move(cb)),
service_uuid);
std::move(cb).Run(GetScanResultsInternal(service_uuid));
}
// Returns a list of all scan results. The results are sorted by RSSI.
std::vector<LeScanManager::ScanResult> LeScanManager::GetScanResultsInternal(
std::vector<LeScanManagerImpl::ScanResult>
LeScanManagerImpl::GetScanResultsInternal(
base::Optional<uint16_t> service_uuid) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
std::vector<ScanResult> results;
......@@ -156,12 +158,12 @@ std::vector<LeScanManager::ScanResult> LeScanManager::GetScanResultsInternal(
return results;
}
void LeScanManager::ClearScanResults() {
void LeScanManagerImpl::ClearScanResults() {
MAKE_SURE_IO_THREAD(ClearScanResults);
addr_to_scan_results_.clear();
}
void LeScanManager::OnScanResult(
void LeScanManagerImpl::OnScanResult(
const bluetooth_v2_shlib::LeScanner::ScanResult& scan_result_shlib) {
ScanResult scan_result;
scan_result.addr = scan_result_shlib.addr;
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_LE_SCAN_MANAGER_IMPL_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_LE_SCAN_MANAGER_IMPL_H_
#include <list>
#include <map>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/observer_list_threadsafe.h"
#include "chromecast/device/bluetooth/le/le_scan_manager.h"
#include "chromecast/device/bluetooth/shlib/le_scanner.h"
namespace chromecast {
namespace bluetooth {
class LeScanManagerImpl : public LeScanManager,
public bluetooth_v2_shlib::LeScanner::Delegate {
public:
explicit LeScanManagerImpl(bluetooth_v2_shlib::LeScannerImpl* le_scanner);
~LeScanManagerImpl() override;
void Initialize(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
void Finalize();
// LeScanManager implementation:
void AddObserver(Observer* o) override;
void RemoveObserver(Observer* o) override;
void SetScanEnable(bool enable, SetScanEnableCallback cb) override;
void GetScanResults(
GetScanResultsCallback cb,
base::Optional<uint16_t> service_uuid = base::nullopt) override;
void ClearScanResults() override;
private:
// Returns a list of all BLE scan results. The results are sorted by RSSI.
// Must be called on |io_task_runner|.
std::vector<ScanResult> GetScanResultsInternal(
base::Optional<uint16_t> service_uuid);
// bluetooth_v2_shlib::LeScanner::Delegate implementation:
void OnScanResult(const bluetooth_v2_shlib::LeScanner::ScanResult&
scan_result_shlib) override;
bluetooth_v2_shlib::LeScannerImpl* const le_scanner_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
scoped_refptr<base::ObserverListThreadSafe<Observer>> observers_;
std::map<bluetooth_v2_shlib::Addr, std::list<ScanResult>>
addr_to_scan_results_;
base::WeakPtrFactory<LeScanManagerImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(LeScanManagerImpl);
};
} // namespace bluetooth
} // namespace chromecast
#endif // CHROMECAST_DEVICE_BLUETOOTH_LE_LE_SCAN_MANAGER_IMPL_H_
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/device/bluetooth/le/le_scan_manager.h"
#include "chromecast/device/bluetooth/le/le_scan_manager_impl.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
......@@ -89,7 +89,7 @@ class LeScanManagerTest : public ::testing::Test {
base::test::ScopedTaskEnvironment scoped_task_environment_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
FakeLeScannerImpl fake_le_scan_manager_impl_;
LeScanManager le_scan_manager_;
LeScanManagerImpl le_scan_manager_;
MockLeScanManagerObserver mock_observer_;
private:
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/device/bluetooth/le/mock_gatt_client_manager.h"
namespace chromecast {
namespace bluetooth {
MockGattClientManager::MockGattClientManager() = default;
MockGattClientManager::~MockGattClientManager() = default;
} // namespace bluetooth
} // namespace chromecast
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_GATT_CLIENT_MANAGER_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_GATT_CLIENT_MANAGER_H_
#include "chromecast/device/bluetooth/le/gatt_client_manager.h"
#include "chromecast/device/bluetooth/le/remote_device.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace chromecast {
namespace bluetooth {
class MockGattClientManager : public GattClientManager {
public:
MockGattClientManager();
~MockGattClientManager();
MOCK_METHOD1(AddObserver, void(Observer* o));
MOCK_METHOD1(RemoveObserver, void(Observer* o));
void GetDevice(
const bluetooth_v2_shlib::Addr& addr,
base::OnceCallback<void(scoped_refptr<RemoteDevice>)> cb) override {}
MOCK_METHOD1(
GetDeviceSync,
scoped_refptr<RemoteDevice>(const bluetooth_v2_shlib::Addr& addr));
MOCK_CONST_METHOD0(GetNumConnected, size_t());
MOCK_METHOD1(NotifyConnect, void(const bluetooth_v2_shlib::Addr& addr));
MOCK_METHOD0(task_runner, scoped_refptr<base::SingleThreadTaskRunner>());
};
} // namespace bluetooth
} // namespace chromecast
#endif // CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_GATT_CLIENT_MANAGER_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/device/bluetooth/le/mock_le_scan_manager.h"
namespace chromecast {
namespace bluetooth {
MockLeScanManager::MockLeScanManager() = default;
MockLeScanManager::~MockLeScanManager() = default;
} // namespace bluetooth
} // namespace chromecast
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_LE_SCAN_MANAGER_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_LE_SCAN_MANAGER_H_
#include <vector>
#include "chromecast/device/bluetooth/le/le_scan_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace chromecast {
namespace bluetooth {
class MockLeScanManager : public LeScanManager {
public:
MockLeScanManager();
~MockLeScanManager();
MOCK_METHOD1(AddObserver, void(Observer* o));
MOCK_METHOD1(RemoveObserver, void(Observer* o));
void SetScanEnable(bool enable, SetScanEnableCallback cb) override {}
void GetScanResults(GetScanResultsCallback cb,
base::Optional<uint16_t> service_uuid) override {}
MOCK_METHOD0(ClearScanResults, void());
};
} // namespace bluetooth
} // namespace chromecast
#endif // CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_LE_SCAN_MANAGER_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/device/bluetooth/le/mock_remote_characteristic.h"
namespace chromecast {
namespace bluetooth {
MockRemoteCharacteristic::MockRemoteCharacteristic() = default;
MockRemoteCharacteristic::~MockRemoteCharacteristic() = default;
} // namespace bluetooth
} // namespace chromecast
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_REMOTE_CHARACTERISTIC_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_REMOTE_CHARACTERISTIC_H_
#include <vector>
#include "chromecast/device/bluetooth/le/remote_characteristic.h"
#include "chromecast/device/bluetooth/le/remote_descriptor.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace chromecast {
namespace bluetooth {
class MockRemoteCharacteristic : public RemoteCharacteristic {
public:
MockRemoteCharacteristic();
MOCK_METHOD0(GetDescriptors, std::vector<scoped_refptr<RemoteDescriptor>>());
MOCK_METHOD1(
GetDescriptorByUuid,
scoped_refptr<RemoteDescriptor>(const bluetooth_v2_shlib::Uuid& uuid));
void SetRegisterNotification(bool enable, StatusCallback cb) override {}
void SetNotification(bool enable, StatusCallback cb) override {}
void ReadAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
ReadCallback callback) override {}
void Read(ReadCallback callback) override {}
void WriteAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
bluetooth_v2_shlib::Gatt::WriteType write_type,
const std::vector<uint8_t>& value,
StatusCallback callback) override {}
void Write(bluetooth_v2_shlib::Gatt::WriteType write_type,
const std::vector<uint8_t>& value,
StatusCallback callback) override {}
MOCK_METHOD0(NotificationEnabled, bool());
MOCK_CONST_METHOD0(characteristic,
const bluetooth_v2_shlib::Gatt::Characteristic&());
MOCK_CONST_METHOD0(uuid, const bluetooth_v2_shlib::Uuid&());
MOCK_CONST_METHOD0(handle, uint16_t());
MOCK_CONST_METHOD0(permissions, bluetooth_v2_shlib::Gatt::Permissions());
MOCK_CONST_METHOD0(properties, bluetooth_v2_shlib::Gatt::Properties());
private:
~MockRemoteCharacteristic();
};
} // namespace bluetooth
} // namespace chromecast
#endif // CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_REMOTE_CHARACTERISTIC_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/device/bluetooth/le/mock_remote_descriptor.h"
namespace chromecast {
namespace bluetooth {
MockRemoteDescriptor::MockRemoteDescriptor() = default;
MockRemoteDescriptor::~MockRemoteDescriptor() = default;
} // namespace bluetooth
} // namespace chromecast
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_REMOTE_DESCRIPTOR_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_REMOTE_DESCRIPTOR_H_
#include <vector>
#include "chromecast/device/bluetooth/le/remote_descriptor.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace chromecast {
namespace bluetooth {
class MockRemoteDescriptor : public RemoteDescriptor {
public:
MockRemoteDescriptor();
void ReadAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
ReadCallback callback) override {}
void Read(ReadCallback callback) override {}
void WriteAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
const std::vector<uint8_t>& value,
StatusCallback callback) override {}
void Write(const std::vector<uint8_t>& value,
StatusCallback callback) override {}
MOCK_CONST_METHOD0(descriptor, const bluetooth_v2_shlib::Gatt::Descriptor&());
MOCK_CONST_METHOD0(uuid, const bluetooth_v2_shlib::Uuid());
MOCK_CONST_METHOD0(handle, uint16_t());
MOCK_CONST_METHOD0(permissions, bluetooth_v2_shlib::Gatt::Permissions());
private:
~MockRemoteDescriptor();
};
} // namespace bluetooth
} // namespace chromecast
#endif // CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_REMOTE_DESCRIPTOR_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/device/bluetooth/le/mock_remote_device.h"
namespace chromecast {
namespace bluetooth {
MockRemoteDevice::MockRemoteDevice() = default;
MockRemoteDevice::~MockRemoteDevice() = default;
} // namespace bluetooth
} // namespace chromecast
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_REMOTE_DEVICE_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_REMOTE_DEVICE_H_
#include <vector>
#include "chromecast/device/bluetooth/le/remote_device.h"
#include "chromecast/device/bluetooth/le/remote_service.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace chromecast {
namespace bluetooth {
class MockRemoteDevice : public RemoteDevice {
public:
MockRemoteDevice();
void Connect(StatusCallback cb) override {}
MOCK_METHOD0(ConnectSync, bool());
void Disconnect(StatusCallback cb) override {}
MOCK_METHOD0(DisconnectSync, bool());
void ReadRemoteRssi(RssiCallback cb) override {}
void RequestMtu(int mtu, StatusCallback cb) override {}
void ConnectionParameterUpdate(int min_interval,
int max_interval,
int latency,
int timeout,
StatusCallback cb) override {}
void DiscoverServices(DiscoverServicesCb cb) override {}
MOCK_METHOD0(IsConnected, bool());
MOCK_METHOD0(GetMtu, int());
void GetServices(
base::OnceCallback<void(std::vector<scoped_refptr<RemoteService>>)> cb)
override {}
MOCK_METHOD0(GetServicesSync, std::vector<scoped_refptr<RemoteService>>());
void GetServiceByUuid(
const bluetooth_v2_shlib::Uuid& uuid,
base::OnceCallback<void(scoped_refptr<RemoteService>)> cb) override {}
MOCK_METHOD1(
GetServiceByUuidSync,
scoped_refptr<RemoteService>(const bluetooth_v2_shlib::Uuid& uuid));
MOCK_CONST_METHOD0(addr, const bluetooth_v2_shlib::Addr&());
private:
~MockRemoteDevice();
};
} // namespace bluetooth
} // namespace chromecast
#endif // CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_REMOTE_DEVICE_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/device/bluetooth/le/mock_remote_service.h"
namespace chromecast {
namespace bluetooth {
MockRemoteService::MockRemoteService() = default;
MockRemoteService::~MockRemoteService() = default;
} // namespace bluetooth
} // namespace chromecast
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_REMOTE_SERVICE_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_REMOTE_SERVICE_H_
#include <vector>
#include "chromecast/device/bluetooth/le/remote_characteristic.h"
#include "chromecast/device/bluetooth/le/remote_device.h"
#include "chromecast/device/bluetooth/le/remote_service.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace chromecast {
namespace bluetooth {
class MockRemoteService : public RemoteService {
public:
MockRemoteService();
MOCK_METHOD0(GetCharacteristics,
std::vector<scoped_refptr<RemoteCharacteristic>>());
MOCK_METHOD1(GetCharacteristicByUuid,
scoped_refptr<RemoteCharacteristic>(
const bluetooth_v2_shlib::Uuid& uuid));
MOCK_CONST_METHOD0(uuid, const bluetooth_v2_shlib::Uuid&());
MOCK_CONST_METHOD0(handle, uint16_t());
MOCK_CONST_METHOD0(primary, bool());
private:
~MockRemoteService();
};
} // namespace bluetooth
} // namespace chromecast
#endif // CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_REMOTE_SERVICE_H_
......@@ -13,16 +13,12 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "chromecast/public/bluetooth/gatt.h"
namespace chromecast {
namespace bluetooth {
class GattClientManager;
class RemoteDescriptor;
class RemoteDevice;
// A proxy for a remote characteristic on a RemoteDevice. Unless otherwise
// specified, all callbacks are run on the caller's thread.
......@@ -34,103 +30,55 @@ class RemoteCharacteristic
using StatusCallback = base::OnceCallback<void(bool)>;
// Return a list of all descriptors.
std::vector<scoped_refptr<RemoteDescriptor>> GetDescriptors();
virtual std::vector<scoped_refptr<RemoteDescriptor>> GetDescriptors() = 0;
// Retrieves the descriptor with |uuid|, or nullptr if it doesn't exist.
scoped_refptr<RemoteDescriptor> GetDescriptorByUuid(
const bluetooth_v2_shlib::Uuid& uuid);
virtual scoped_refptr<RemoteDescriptor> GetDescriptorByUuid(
const bluetooth_v2_shlib::Uuid& uuid) = 0;
// Register or deregister from a notification. Calls |SetNotification| and
// writes the cccd.
void SetRegisterNotification(bool enable, StatusCallback cb);
virtual void SetRegisterNotification(bool enable, StatusCallback cb) = 0;
// Enable notifications for this characteristic. Client must still write to
// the CCCD seperately (or use |SetRegisterNotification| instead).
void SetNotification(bool enable, StatusCallback cb);
virtual void SetNotification(bool enable, StatusCallback cb) = 0;
// Read the characteristic with |auth_req|. When completed, |callback| will be
// called.
void ReadAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
ReadCallback callback);
virtual void ReadAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
ReadCallback callback) = 0;
// Read the characteristic. Will retry if auth_req isn't met. When completed,
// |callback| will be called.
void Read(ReadCallback callback);
virtual void Read(ReadCallback callback) = 0;
// Write |value| to the characteristic with |auth_req| and |write_type|. When
// completed, |callback| will be called.
void WriteAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
bluetooth_v2_shlib::Gatt::WriteType write_type,
const std::vector<uint8_t>& value,
StatusCallback callback);
virtual void WriteAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
bluetooth_v2_shlib::Gatt::WriteType write_type,
const std::vector<uint8_t>& value,
StatusCallback callback) = 0;
// Write |value| to the characteristic with |write_type|. Will retry if
// auth_req isn't met. When completed, |callback| will be called.
void Write(bluetooth_v2_shlib::Gatt::WriteType write_type,
const std::vector<uint8_t>& value,
StatusCallback callback);
virtual void Write(bluetooth_v2_shlib::Gatt::WriteType write_type,
const std::vector<uint8_t>& value,
StatusCallback callback) = 0;
// Returns true if notifications are enabled.
bool NotificationEnabled();
const bluetooth_v2_shlib::Gatt::Characteristic& characteristic() const {
return *characteristic_;
}
const bluetooth_v2_shlib::Uuid& uuid() const { return characteristic_->uuid; }
uint16_t handle() const { return characteristic_->handle; }
bluetooth_v2_shlib::Gatt::Permissions permissions() const {
return characteristic_->permissions;
}
bluetooth_v2_shlib::Gatt::Properties properties() const {
return characteristic_->properties;
}
private:
friend class GattClientManager;
friend class RemoteDevice;
friend class RemoteService;
friend class base::RefCountedThreadSafe<RemoteCharacteristic>;
static std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteDescriptor>>
CreateDescriptorMap(
RemoteDevice* device,
base::WeakPtr<GattClientManager> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Characteristic* characteristic,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
RemoteCharacteristic(
RemoteDevice* device,
base::WeakPtr<GattClientManager> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Characteristic* characteristic,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
~RemoteCharacteristic();
void OnConnectChanged(bool connected);
void OnReadComplete(bool status, const std::vector<uint8_t>& value);
void OnWriteComplete(bool status);
// Weak reference to avoid refcount loop.
RemoteDevice* const device_;
const base::WeakPtr<GattClientManager> gatt_client_manager_;
const bluetooth_v2_shlib::Gatt::Characteristic* const characteristic_;
virtual bool NotificationEnabled() = 0;
// All bluetooth_v2_shlib calls are run on this task_runner. All members must
// be accessed on this task_runner.
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
virtual const bluetooth_v2_shlib::Gatt::Characteristic& characteristic()
const = 0;
virtual const bluetooth_v2_shlib::Uuid& uuid() const = 0;
virtual uint16_t handle() const = 0;
virtual bluetooth_v2_shlib::Gatt::Permissions permissions() const = 0;
virtual bluetooth_v2_shlib::Gatt::Properties properties() const = 0;
const std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteDescriptor>>
uuid_to_descriptor_;
ReadCallback read_callback_;
StatusCallback write_callback_;
std::atomic<bool> notification_enabled_{false};
bool pending_read_ = false;
bool pending_write_ = false;
DISALLOW_COPY_AND_ASSIGN(RemoteCharacteristic);
protected:
friend class base::RefCountedThreadSafe<RemoteCharacteristic>;
virtual ~RemoteCharacteristic() = default;
};
} // namespace bluetooth
......
......@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/device/bluetooth/le/remote_characteristic.h"
#include "chromecast/device/bluetooth/le/remote_characteristic_impl.h"
#include "chromecast/base/bind_to_task_runner.h"
#include "chromecast/device/bluetooth/le/gatt_client_manager.h"
#include "chromecast/device/bluetooth/le/remote_descriptor.h"
#include "chromecast/device/bluetooth/le/gatt_client_manager_impl.h"
#include "chromecast/device/bluetooth/le/remote_descriptor_impl.h"
#include "chromecast/device/bluetooth/le/remote_device.h"
#define EXEC_CB_AND_RET(cb, ret, ...) \
......@@ -20,7 +20,7 @@
#define RUN_ON_IO_THREAD(method, ...) \
io_task_runner_->PostTask( \
FROM_HERE, \
base::BindOnce(&RemoteCharacteristic::method, this, ##__VA_ARGS__));
base::BindOnce(&RemoteCharacteristicImpl::method, this, ##__VA_ARGS__));
#define MAKE_SURE_IO_THREAD(method, ...) \
DCHECK(io_task_runner_); \
......@@ -47,23 +47,23 @@ std::vector<uint8_t> GetDescriptorNotificationValue(bool enable) {
// static
std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteDescriptor>>
RemoteCharacteristic::CreateDescriptorMap(
RemoteCharacteristicImpl::CreateDescriptorMap(
RemoteDevice* device,
base::WeakPtr<GattClientManager> gatt_client_manager,
base::WeakPtr<GattClientManagerImpl> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Characteristic* characteristic,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) {
std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteDescriptor>> ret;
for (const auto& descriptor : characteristic->descriptors) {
ret[descriptor.uuid] = new RemoteDescriptor(device, gatt_client_manager,
&descriptor, io_task_runner);
ret[descriptor.uuid] = new RemoteDescriptorImpl(
device, gatt_client_manager, &descriptor, io_task_runner);
}
return ret;
}
RemoteCharacteristic::RemoteCharacteristic(
RemoteCharacteristicImpl::RemoteCharacteristicImpl(
RemoteDevice* device,
base::WeakPtr<GattClientManager> gatt_client_manager,
base::WeakPtr<GattClientManagerImpl> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Characteristic* characteristic,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
: device_(device),
......@@ -79,10 +79,10 @@ RemoteCharacteristic::RemoteCharacteristic(
DCHECK(io_task_runner_->BelongsToCurrentThread());
}
RemoteCharacteristic::~RemoteCharacteristic() = default;
RemoteCharacteristicImpl::~RemoteCharacteristicImpl() = default;
std::vector<scoped_refptr<RemoteDescriptor>>
RemoteCharacteristic::GetDescriptors() {
RemoteCharacteristicImpl::GetDescriptors() {
std::vector<scoped_refptr<RemoteDescriptor>> ret;
ret.reserve(uuid_to_descriptor_.size());
for (const auto& pair : uuid_to_descriptor_) {
......@@ -92,7 +92,7 @@ RemoteCharacteristic::GetDescriptors() {
return ret;
}
scoped_refptr<RemoteDescriptor> RemoteCharacteristic::GetDescriptorByUuid(
scoped_refptr<RemoteDescriptor> RemoteCharacteristicImpl::GetDescriptorByUuid(
const bluetooth_v2_shlib::Uuid& uuid) {
auto it = uuid_to_descriptor_.find(uuid);
if (it == uuid_to_descriptor_.end()) {
......@@ -102,8 +102,8 @@ scoped_refptr<RemoteDescriptor> RemoteCharacteristic::GetDescriptorByUuid(
return it->second;
}
void RemoteCharacteristic::SetRegisterNotification(bool enable,
StatusCallback cb) {
void RemoteCharacteristicImpl::SetRegisterNotification(bool enable,
StatusCallback cb) {
MAKE_SURE_IO_THREAD(SetRegisterNotification, enable,
BindToCurrentSequence(std::move(cb)));
if (!gatt_client_manager_) {
......@@ -127,7 +127,7 @@ void RemoteCharacteristic::SetRegisterNotification(bool enable,
GetDescriptorNotificationValue(enable), std::move(cb));
}
void RemoteCharacteristic::SetNotification(bool enable, StatusCallback cb) {
void RemoteCharacteristicImpl::SetNotification(bool enable, StatusCallback cb) {
MAKE_SURE_IO_THREAD(SetNotification, enable,
BindToCurrentSequence(std::move(cb)));
if (!gatt_client_manager_) {
......@@ -144,7 +144,7 @@ void RemoteCharacteristic::SetNotification(bool enable, StatusCallback cb) {
EXEC_CB_AND_RET(cb, true);
}
void RemoteCharacteristic::ReadAuth(
void RemoteCharacteristicImpl::ReadAuth(
bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
ReadCallback callback) {
MAKE_SURE_IO_THREAD(ReadAuth, auth_req,
......@@ -166,12 +166,12 @@ void RemoteCharacteristic::ReadAuth(
read_callback_ = std::move(callback);
}
void RemoteCharacteristic::Read(ReadCallback callback) {
void RemoteCharacteristicImpl::Read(ReadCallback callback) {
ReadAuth(bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_INVALID,
std::move(callback));
}
void RemoteCharacteristic::WriteAuth(
void RemoteCharacteristicImpl::WriteAuth(
bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
bluetooth_v2_shlib::Gatt::WriteType write_type,
const std::vector<uint8_t>& value,
......@@ -196,18 +196,42 @@ void RemoteCharacteristic::WriteAuth(
write_callback_ = std::move(callback);
}
void RemoteCharacteristic::Write(bluetooth_v2_shlib::Gatt::WriteType write_type,
const std::vector<uint8_t>& value,
StatusCallback callback) {
void RemoteCharacteristicImpl::Write(
bluetooth_v2_shlib::Gatt::WriteType write_type,
const std::vector<uint8_t>& value,
StatusCallback callback) {
return WriteAuth(bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_NONE, write_type,
value, std::move(callback));
}
bool RemoteCharacteristic::NotificationEnabled() {
bool RemoteCharacteristicImpl::NotificationEnabled() {
return notification_enabled_;
}
void RemoteCharacteristic::OnConnectChanged(bool connected) {
const bluetooth_v2_shlib::Gatt::Characteristic&
RemoteCharacteristicImpl::characteristic() const {
return *characteristic_;
}
const bluetooth_v2_shlib::Uuid& RemoteCharacteristicImpl::uuid() const {
return characteristic_->uuid;
}
uint16_t RemoteCharacteristicImpl::handle() const {
return characteristic_->handle;
}
bluetooth_v2_shlib::Gatt::Permissions RemoteCharacteristicImpl::permissions()
const {
return characteristic_->permissions;
}
bluetooth_v2_shlib::Gatt::Properties RemoteCharacteristicImpl::properties()
const {
return characteristic_->properties;
}
void RemoteCharacteristicImpl::OnConnectChanged(bool connected) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
if (connected) {
return;
......@@ -227,8 +251,9 @@ void RemoteCharacteristic::OnConnectChanged(bool connected) {
}
}
void RemoteCharacteristic::OnReadComplete(bool status,
const std::vector<uint8_t>& value) {
void RemoteCharacteristicImpl::OnReadComplete(
bool status,
const std::vector<uint8_t>& value) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
pending_read_ = false;
if (read_callback_) {
......@@ -236,7 +261,7 @@ void RemoteCharacteristic::OnReadComplete(bool status,
}
}
void RemoteCharacteristic::OnWriteComplete(bool status) {
void RemoteCharacteristicImpl::OnWriteComplete(bool status) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
pending_write_ = false;
if (write_callback_)
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_CHARACTERISTIC_IMPL_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_CHARACTERISTIC_IMPL_H_
#include <atomic>
#include <map>
#include <memory>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "chromecast/device/bluetooth/le/remote_characteristic.h"
namespace chromecast {
namespace bluetooth {
class GattClientManagerImpl;
class RemoteDevice;
// A proxy for a remote characteristic on a RemoteDevice. Unless otherwise
// specified, all callbacks are run on the caller's thread.
class RemoteCharacteristicImpl : public RemoteCharacteristic {
public:
// RemoteCharacteristic impl:
std::vector<scoped_refptr<RemoteDescriptor>> GetDescriptors() override;
scoped_refptr<RemoteDescriptor> GetDescriptorByUuid(
const bluetooth_v2_shlib::Uuid& uuid) override;
void SetRegisterNotification(bool enable, StatusCallback cb) override;
void SetNotification(bool enable, StatusCallback cb) override;
void ReadAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
ReadCallback callback) override;
void Read(ReadCallback callback) override;
void WriteAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
bluetooth_v2_shlib::Gatt::WriteType write_type,
const std::vector<uint8_t>& value,
StatusCallback callback) override;
void Write(bluetooth_v2_shlib::Gatt::WriteType write_type,
const std::vector<uint8_t>& value,
StatusCallback callback) override;
bool NotificationEnabled() override;
const bluetooth_v2_shlib::Gatt::Characteristic& characteristic()
const override;
const bluetooth_v2_shlib::Uuid& uuid() const override;
uint16_t handle() const override;
bluetooth_v2_shlib::Gatt::Permissions permissions() const override;
bluetooth_v2_shlib::Gatt::Properties properties() const override;
private:
friend class GattClientManagerImpl;
friend class RemoteDeviceImpl;
friend class RemoteServiceImpl;
static std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteDescriptor>>
CreateDescriptorMap(
RemoteDevice* device,
base::WeakPtr<GattClientManagerImpl> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Characteristic* characteristic,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
RemoteCharacteristicImpl(
RemoteDevice* device,
base::WeakPtr<GattClientManagerImpl> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Characteristic* characteristic,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
~RemoteCharacteristicImpl() override;
void OnConnectChanged(bool connected);
void OnReadComplete(bool status, const std::vector<uint8_t>& value);
void OnWriteComplete(bool status);
// Weak reference to avoid refcount loop.
RemoteDevice* const device_;
const base::WeakPtr<GattClientManagerImpl> gatt_client_manager_;
const bluetooth_v2_shlib::Gatt::Characteristic* const characteristic_;
// All bluetooth_v2_shlib calls are run on this task_runner. All members must
// be accessed on this task_runner.
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
const std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteDescriptor>>
uuid_to_descriptor_;
ReadCallback read_callback_;
StatusCallback write_callback_;
std::atomic<bool> notification_enabled_{false};
bool pending_read_ = false;
bool pending_write_ = false;
DISALLOW_COPY_AND_ASSIGN(RemoteCharacteristicImpl);
};
} // namespace bluetooth
} // namespace chromecast
#endif // CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_CHARACTERISTIC_IMPL_H_
......@@ -4,30 +4,6 @@
#include "chromecast/device/bluetooth/le/remote_descriptor.h"
#include "chromecast/base/bind_to_task_runner.h"
#include "chromecast/device/bluetooth/le/remote_characteristic.h"
#include "chromecast/device/bluetooth/le/remote_device.h"
#define EXEC_CB_AND_RET(cb, ret, ...) \
do { \
if (cb) { \
std::move(cb).Run(ret, ##__VA_ARGS__); \
} \
return; \
} while (0)
#define RUN_ON_IO_THREAD(method, ...) \
io_task_runner_->PostTask( \
FROM_HERE, \
base::BindOnce(&RemoteDescriptor::method, this, ##__VA_ARGS__));
#define MAKE_SURE_IO_THREAD(method, ...) \
DCHECK(io_task_runner_); \
if (!io_task_runner_->BelongsToCurrentThread()) { \
RUN_ON_IO_THREAD(method, ##__VA_ARGS__) \
return; \
}
namespace chromecast {
namespace bluetooth {
......@@ -40,114 +16,5 @@ const bluetooth_v2_shlib::Uuid RemoteDescriptor::kCccdUuid = {
{0x00, 0x00, 0x29, 0x02, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80,
0x5f, 0x9b, 0x34, 0xfb}};
RemoteDescriptor::RemoteDescriptor(
RemoteDevice* device,
base::WeakPtr<GattClientManager> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Descriptor* descriptor,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
: device_(device),
gatt_client_manager_(std::move(gatt_client_manager)),
descriptor_(descriptor),
io_task_runner_(io_task_runner) {
DCHECK(device);
DCHECK(gatt_client_manager_);
DCHECK(descriptor);
DCHECK(io_task_runner_->BelongsToCurrentThread());
}
RemoteDescriptor::~RemoteDescriptor() = default;
void RemoteDescriptor::ReadAuth(
bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
ReadCallback callback) {
MAKE_SURE_IO_THREAD(ReadAuth, auth_req,
BindToCurrentSequence(std::move(callback)));
if (!gatt_client_manager_) {
LOG(ERROR) << __func__ << " failed: Destroyed";
EXEC_CB_AND_RET(callback, false, {});
}
if (pending_read_) {
LOG(ERROR) << "Read already pending";
EXEC_CB_AND_RET(callback, false, {});
}
if (!gatt_client_manager_->gatt_client()->ReadDescriptor(
device_->addr(), *descriptor_, auth_req)) {
EXEC_CB_AND_RET(callback, false, {});
}
pending_read_ = true;
read_callback_ = std::move(callback);
}
void RemoteDescriptor::Read(ReadCallback callback) {
ReadAuth(bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_INVALID,
std::move(callback));
}
void RemoteDescriptor::WriteAuth(
bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
const std::vector<uint8_t>& value,
StatusCallback callback) {
MAKE_SURE_IO_THREAD(WriteAuth, auth_req, value,
BindToCurrentSequence(std::move(callback)));
if (!gatt_client_manager_) {
LOG(ERROR) << __func__ << " failed: Destroyed";
EXEC_CB_AND_RET(callback, false);
}
if (pending_write_) {
LOG(ERROR) << "Write already pending";
EXEC_CB_AND_RET(callback, false);
}
if (!gatt_client_manager_->gatt_client()->WriteDescriptor(
device_->addr(), *descriptor_, auth_req, value)) {
EXEC_CB_AND_RET(callback, false);
}
pending_write_ = true;
write_callback_ = std::move(callback);
}
void RemoteDescriptor::Write(const std::vector<uint8_t>& value,
StatusCallback callback) {
WriteAuth(bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_INVALID, value,
std::move(callback));
}
void RemoteDescriptor::OnConnectChanged(bool connected) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
if (connected) {
return;
}
pending_read_ = false;
pending_write_ = false;
if (read_callback_) {
LOG(ERROR) << "Read failed: Device disconnected";
std::move(read_callback_).Run(false, std::vector<uint8_t>());
}
if (write_callback_) {
LOG(ERROR) << "Write failed: Device disconnected";
std::move(write_callback_).Run(false);
}
}
void RemoteDescriptor::OnReadComplete(bool status,
const std::vector<uint8_t>& value) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
pending_read_ = false;
if (read_callback_)
std::move(read_callback_).Run(status, value);
}
void RemoteDescriptor::OnWriteComplete(bool status) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
pending_write_ = false;
if (write_callback_)
std::move(write_callback_).Run(status);
}
} // namespace bluetooth
} // namespace chromecast
......@@ -11,9 +11,6 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "chromecast/device/bluetooth/le/gatt_client_manager.h"
#include "chromecast/public/bluetooth/gatt.h"
namespace chromecast {
......@@ -36,62 +33,31 @@ class RemoteDescriptor : public base::RefCountedThreadSafe<RemoteDescriptor> {
// Read the descriptor with |auth_req|. When completed, |callback| will be
// called.
void ReadAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
ReadCallback callback);
virtual void ReadAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
ReadCallback callback) = 0;
// Read the descriptor. When completed, |callback| will be called.
void Read(ReadCallback callback);
virtual void Read(ReadCallback callback) = 0;
// Write |value| to the descriptor with |auth_req|. When completed, |callback|
// will be called.
void WriteAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
const std::vector<uint8_t>& value,
StatusCallback callback);
virtual void WriteAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
const std::vector<uint8_t>& value,
StatusCallback callback) = 0;
// Write |value| to the descriptor. Will retry if auth_req isn't met. When
// completed, |callback| will be called.
void Write(const std::vector<uint8_t>& value, StatusCallback callback);
virtual void Write(const std::vector<uint8_t>& value,
StatusCallback callback) = 0;
const bluetooth_v2_shlib::Gatt::Descriptor& descriptor() const {
return *descriptor_;
}
const bluetooth_v2_shlib::Uuid uuid() const { return descriptor_->uuid; }
uint16_t handle() const { return descriptor_->handle; }
bluetooth_v2_shlib::Gatt::Permissions permissions() const {
return descriptor_->permissions;
}
virtual const bluetooth_v2_shlib::Gatt::Descriptor& descriptor() const = 0;
virtual const bluetooth_v2_shlib::Uuid uuid() const = 0;
virtual uint16_t handle() const = 0;
virtual bluetooth_v2_shlib::Gatt::Permissions permissions() const = 0;
private:
friend class GattClientManager;
friend class RemoteCharacteristic;
friend class RemoteDevice;
protected:
friend class base::RefCountedThreadSafe<RemoteDescriptor>;
RemoteDescriptor(RemoteDevice* device,
base::WeakPtr<GattClientManager> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Descriptor* characteristic,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
~RemoteDescriptor();
void OnConnectChanged(bool connected);
void OnReadComplete(bool status, const std::vector<uint8_t>& value);
void OnWriteComplete(bool status);
RemoteDevice* const device_;
const base::WeakPtr<GattClientManager> gatt_client_manager_;
const bluetooth_v2_shlib::Gatt::Descriptor* const descriptor_;
// All bluetooth_v2_shlib calls are run on this task_runner. All members must
// be accessed on this task_runner.
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
ReadCallback read_callback_;
StatusCallback write_callback_;
bool pending_read_ = false;
bool pending_write_ = false;
DISALLOW_COPY_AND_ASSIGN(RemoteDescriptor);
virtual ~RemoteDescriptor() = default;
};
} // namespace bluetooth
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/device/bluetooth/le/remote_descriptor_impl.h"
#include "chromecast/base/bind_to_task_runner.h"
#include "chromecast/device/bluetooth/le/gatt_client_manager_impl.h"
#include "chromecast/device/bluetooth/le/remote_device.h"
#define EXEC_CB_AND_RET(cb, ret, ...) \
do { \
if (cb) { \
std::move(cb).Run(ret, ##__VA_ARGS__); \
} \
return; \
} while (0)
#define RUN_ON_IO_THREAD(method, ...) \
io_task_runner_->PostTask( \
FROM_HERE, \
base::BindOnce(&RemoteDescriptorImpl::method, this, ##__VA_ARGS__));
#define MAKE_SURE_IO_THREAD(method, ...) \
DCHECK(io_task_runner_); \
if (!io_task_runner_->BelongsToCurrentThread()) { \
RUN_ON_IO_THREAD(method, ##__VA_ARGS__) \
return; \
}
namespace chromecast {
namespace bluetooth {
RemoteDescriptorImpl::RemoteDescriptorImpl(
RemoteDevice* device,
base::WeakPtr<GattClientManagerImpl> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Descriptor* descriptor,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
: device_(device),
gatt_client_manager_(std::move(gatt_client_manager)),
descriptor_(descriptor),
io_task_runner_(std::move(io_task_runner)) {
DCHECK(device);
DCHECK(gatt_client_manager_);
DCHECK(descriptor);
DCHECK(io_task_runner_->BelongsToCurrentThread());
}
RemoteDescriptorImpl::~RemoteDescriptorImpl() = default;
void RemoteDescriptorImpl::ReadAuth(
bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
ReadCallback callback) {
MAKE_SURE_IO_THREAD(ReadAuth, auth_req,
BindToCurrentSequence(std::move(callback)));
if (!gatt_client_manager_) {
LOG(ERROR) << __func__ << " failed: Destroyed";
EXEC_CB_AND_RET(callback, false, {});
}
if (pending_read_) {
LOG(ERROR) << "Read already pending";
EXEC_CB_AND_RET(callback, false, {});
}
if (!gatt_client_manager_->gatt_client()->ReadDescriptor(
device_->addr(), *descriptor_, auth_req)) {
EXEC_CB_AND_RET(callback, false, {});
}
pending_read_ = true;
read_callback_ = std::move(callback);
}
void RemoteDescriptorImpl::Read(ReadCallback callback) {
ReadAuth(bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_INVALID,
std::move(callback));
}
void RemoteDescriptorImpl::WriteAuth(
bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
const std::vector<uint8_t>& value,
StatusCallback callback) {
MAKE_SURE_IO_THREAD(WriteAuth, auth_req, value,
BindToCurrentSequence(std::move(callback)));
if (!gatt_client_manager_) {
LOG(ERROR) << __func__ << " failed: Destroyed";
EXEC_CB_AND_RET(callback, false);
}
if (pending_write_) {
LOG(ERROR) << "Write already pending";
EXEC_CB_AND_RET(callback, false);
}
if (!gatt_client_manager_->gatt_client()->WriteDescriptor(
device_->addr(), *descriptor_, auth_req, value)) {
EXEC_CB_AND_RET(callback, false);
}
pending_write_ = true;
write_callback_ = std::move(callback);
}
void RemoteDescriptorImpl::Write(const std::vector<uint8_t>& value,
StatusCallback callback) {
WriteAuth(bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_INVALID, value,
std::move(callback));
}
const bluetooth_v2_shlib::Gatt::Descriptor& RemoteDescriptorImpl::descriptor()
const {
return *descriptor_;
}
const bluetooth_v2_shlib::Uuid RemoteDescriptorImpl::uuid() const {
return descriptor_->uuid;
}
uint16_t RemoteDescriptorImpl::handle() const {
return descriptor_->handle;
}
bluetooth_v2_shlib::Gatt::Permissions RemoteDescriptorImpl::permissions()
const {
return descriptor_->permissions;
}
void RemoteDescriptorImpl::OnConnectChanged(bool connected) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
if (connected) {
return;
}
pending_read_ = false;
pending_write_ = false;
if (read_callback_) {
LOG(ERROR) << "Read failed: Device disconnected";
std::move(read_callback_).Run(false, std::vector<uint8_t>());
}
if (write_callback_) {
LOG(ERROR) << "Write failed: Device disconnected";
std::move(write_callback_).Run(false);
}
}
void RemoteDescriptorImpl::OnReadComplete(bool status,
const std::vector<uint8_t>& value) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
pending_read_ = false;
if (read_callback_)
std::move(read_callback_).Run(status, value);
}
void RemoteDescriptorImpl::OnWriteComplete(bool status) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
pending_write_ = false;
if (write_callback_)
std::move(write_callback_).Run(status);
}
} // namespace bluetooth
} // namespace chromecast
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_DESCRIPTOR_IMPL_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_DESCRIPTOR_IMPL_H_
#include <map>
#include <memory>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "chromecast/device/bluetooth/le/remote_descriptor.h"
#include "chromecast/public/bluetooth/gatt.h"
namespace chromecast {
namespace bluetooth {
class GattClientManagerImpl;
class RemoteDescriptorImpl : public RemoteDescriptor {
public:
// RemoteDescriptorImpl implementation:
void ReadAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
ReadCallback callback) override;
void Read(ReadCallback callback) override;
void WriteAuth(bluetooth_v2_shlib::Gatt::Client::AuthReq auth_req,
const std::vector<uint8_t>& value,
StatusCallback callback) override;
void Write(const std::vector<uint8_t>& value,
StatusCallback callback) override;
const bluetooth_v2_shlib::Gatt::Descriptor& descriptor() const override;
const bluetooth_v2_shlib::Uuid uuid() const override;
uint16_t handle() const override;
bluetooth_v2_shlib::Gatt::Permissions permissions() const override;
private:
friend class GattClientManagerImpl;
friend class RemoteCharacteristicImpl;
friend class RemoteDeviceImpl;
RemoteDescriptorImpl(
RemoteDevice* device,
base::WeakPtr<GattClientManagerImpl> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Descriptor* characteristic,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
~RemoteDescriptorImpl() override;
void OnConnectChanged(bool connected);
void OnReadComplete(bool status, const std::vector<uint8_t>& value);
void OnWriteComplete(bool status);
RemoteDevice* const device_;
const base::WeakPtr<GattClientManagerImpl> gatt_client_manager_;
const bluetooth_v2_shlib::Gatt::Descriptor* const descriptor_;
// All bluetooth_v2_shlib calls are run on this task_runner. All members must
// be accessed on this task_runner.
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
ReadCallback read_callback_;
StatusCallback write_callback_;
bool pending_read_ = false;
bool pending_write_ = false;
DISALLOW_COPY_AND_ASSIGN(RemoteDescriptorImpl);
};
} // namespace bluetooth
} // namespace chromecast
#endif // CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_DESCRIPTOR_IMPL_H_
......@@ -5,149 +5,94 @@
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_DEVICE_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_DEVICE_H_
#include <atomic>
#include <map>
#include <vector>
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "chromecast/public/bluetooth/gatt.h"
namespace chromecast {
namespace bluetooth {
class GattClientManager;
class RemoteCharacteristic;
class RemoteDescriptor;
class RemoteService;
// A proxy to for a remote GATT server device.
class RemoteDevice : public base::RefCountedThreadSafe<RemoteDevice> {
public:
static constexpr int kDefaultMtu = 20;
enum : int {
kDefaultMtu = 20,
};
using StatusCallback = base::OnceCallback<void(bool)>;
// Initiate a connection to this device. Callback will return |true| if
// connected successfully, otherwise false. Only one pending call is allowed
// at a time.
void Connect(StatusCallback cb);
virtual void Connect(StatusCallback cb) = 0;
// TODO(bcf): Deprecated. Replace usage with async version.
bool ConnectSync();
virtual bool ConnectSync() = 0;
// Disconnect from this device. Callback will return |true| if disconnected
// successfully, otherwise false. Only one pending call is allowed at a time.
void Disconnect(StatusCallback cb);
virtual void Disconnect(StatusCallback cb) = 0;
// TODO(bcf): Deprecated. Replace usage with async version.
bool DisconnectSync();
virtual bool DisconnectSync() = 0;
// Read this device's RSSI. The result will be sent in |callback|. Only one
// pending call is allowed at a time.
using RssiCallback = base::OnceCallback<void(bool success, int rssi)>;
void ReadRemoteRssi(RssiCallback cb);
virtual void ReadRemoteRssi(RssiCallback cb) = 0;
// Request an MTU update to |mtu|. Callback will return |true| if MTU is
// updated successfully, otherwise false. Only one pending call is allowed at
// a time.
void RequestMtu(int mtu, StatusCallback cb);
virtual void RequestMtu(int mtu, StatusCallback cb) = 0;
// Request an update to connection parameters.
void ConnectionParameterUpdate(int min_interval,
int max_interval,
int latency,
int timeout,
StatusCallback cb);
virtual void ConnectionParameterUpdate(int min_interval,
int max_interval,
int latency,
int timeout,
StatusCallback cb) = 0;
// Initiate service discovery on this device. If it fails, the result will be
// empty.
using DiscoverServicesCb = base::OnceCallback<
void(bool success, std::vector<scoped_refptr<RemoteService>> services)>;
void DiscoverServices(DiscoverServicesCb cb);
virtual void DiscoverServices(DiscoverServicesCb cb) = 0;
// Returns true if this device is connected.
bool IsConnected();
virtual bool IsConnected() = 0;
// Returns the current MTU of the connection with this device.
int GetMtu();
virtual int GetMtu() = 0;
// Returns a list of all discovered services on this device. After
// GattClientManager::Observer::OnServicesUpdated is called, these may point
// to old services, so services need to be reobtained.
void GetServices(
base::OnceCallback<void(std::vector<scoped_refptr<RemoteService>>)> cb);
virtual void GetServices(
base::OnceCallback<void(std::vector<scoped_refptr<RemoteService>>)>
cb) = 0;
// TODO(bcf): Deprecated. Replace usage with async version.
std::vector<scoped_refptr<RemoteService>> GetServicesSync();
virtual std::vector<scoped_refptr<RemoteService>> GetServicesSync() = 0;
// Returns the service corresponding to |uuid|, or nullptr if none exist.
void GetServiceByUuid(
virtual void GetServiceByUuid(
const bluetooth_v2_shlib::Uuid& uuid,
base::OnceCallback<void(scoped_refptr<RemoteService>)> cb);
base::OnceCallback<void(scoped_refptr<RemoteService>)> cb) = 0;
// TODO(bcf): Deprecated. Replace usage with async version.
scoped_refptr<RemoteService> GetServiceByUuidSync(
const bluetooth_v2_shlib::Uuid& uuid);
virtual scoped_refptr<RemoteService> GetServiceByUuidSync(
const bluetooth_v2_shlib::Uuid& uuid) = 0;
const bluetooth_v2_shlib::Addr& addr() const { return addr_; }
virtual const bluetooth_v2_shlib::Addr& addr() const = 0;
private:
friend class GattClientManager;
protected:
friend base::RefCountedThreadSafe<RemoteDevice>;
RemoteDevice(const bluetooth_v2_shlib::Addr& addr,
base::WeakPtr<GattClientManager> gatt_client_manager,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
~RemoteDevice();
// Friend methods for GattClientManager
void SetConnected(bool connected);
void SetMtu(int mtu);
scoped_refptr<RemoteCharacteristic> CharacteristicFromHandle(uint16_t handle);
scoped_refptr<RemoteDescriptor> DescriptorFromHandle(uint16_t handle);
void OnGetServices(
const std::vector<bluetooth_v2_shlib::Gatt::Service>& services);
void OnServicesRemoved(uint16_t start_handle, uint16_t end_handle);
void OnServicesAdded(
const std::vector<bluetooth_v2_shlib::Gatt::Service>& services);
void OnReadRemoteRssiComplete(bool status, int rssi);
// end Friend methods for GattClientManager
const base::WeakPtr<GattClientManager> gatt_client_manager_;
const bluetooth_v2_shlib::Addr addr_;
// All bluetooth_v2_shlib calls are run on this task_runner. Below members
// should only be accessed on this task_runner.
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
bool connect_pending_ = false;
StatusCallback connect_cb_;
bool disconnect_pending_ = false;
StatusCallback disconnect_cb_;
bool rssi_pending_ = false;
RssiCallback rssi_cb_;
bool mtu_pending_ = false;
StatusCallback mtu_cb_;
bool discover_services_pending_ = false;
DiscoverServicesCb discover_services_cb_;
std::atomic<bool> connected_{false};
std::atomic<int> mtu_{kDefaultMtu};
std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteService>>
uuid_to_service_;
std::map<uint16_t, scoped_refptr<RemoteCharacteristic>>
handle_to_characteristic_;
std::map<uint16_t, scoped_refptr<RemoteDescriptor>> handle_to_descriptor_;
DISALLOW_COPY_AND_ASSIGN(RemoteDevice);
virtual ~RemoteDevice() = default;
};
} // namespace bluetooth
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_DEVICE_IMPL_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_DEVICE_IMPL_H_
#include <atomic>
#include <map>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "chromecast/device/bluetooth/le/remote_device.h"
namespace chromecast {
namespace bluetooth {
class GattClientManagerImpl;
class RemoteCharacteristic;
class RemoteDescriptor;
class RemoteDeviceImpl : public RemoteDevice {
public:
// RemoteDevice implementation
void Connect(StatusCallback cb) override;
bool ConnectSync() override;
void Disconnect(StatusCallback cb) override;
bool DisconnectSync() override;
void ReadRemoteRssi(RssiCallback cb) override;
void RequestMtu(int mtu, StatusCallback cb) override;
void ConnectionParameterUpdate(int min_interval,
int max_interval,
int latency,
int timeout,
StatusCallback cb) override;
void DiscoverServices(DiscoverServicesCb cb) override;
bool IsConnected() override;
int GetMtu() override;
void GetServices(
base::OnceCallback<void(std::vector<scoped_refptr<RemoteService>>)> cb)
override;
std::vector<scoped_refptr<RemoteService>> GetServicesSync() override;
void GetServiceByUuid(
const bluetooth_v2_shlib::Uuid& uuid,
base::OnceCallback<void(scoped_refptr<RemoteService>)> cb) override;
scoped_refptr<RemoteService> GetServiceByUuidSync(
const bluetooth_v2_shlib::Uuid& uuid) override;
const bluetooth_v2_shlib::Addr& addr() const override;
private:
friend class GattClientManagerImpl;
RemoteDeviceImpl(const bluetooth_v2_shlib::Addr& addr,
base::WeakPtr<GattClientManagerImpl> gatt_client_manager,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
~RemoteDeviceImpl() override;
// Friend methods for GattClientManagerImpl
void SetConnected(bool connected);
void SetMtu(int mtu);
scoped_refptr<RemoteCharacteristic> CharacteristicFromHandle(uint16_t handle);
scoped_refptr<RemoteDescriptor> DescriptorFromHandle(uint16_t handle);
void OnGetServices(
const std::vector<bluetooth_v2_shlib::Gatt::Service>& services);
void OnServicesRemoved(uint16_t start_handle, uint16_t end_handle);
void OnServicesAdded(
const std::vector<bluetooth_v2_shlib::Gatt::Service>& services);
void OnReadRemoteRssiComplete(bool status, int rssi);
// end Friend methods for GattClientManagerImpl
const base::WeakPtr<GattClientManagerImpl> gatt_client_manager_;
const bluetooth_v2_shlib::Addr addr_;
// All bluetooth_v2_shlib calls are run on this task_runner. Below members
// should only be accessed on this task_runner.
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
bool connect_pending_ = false;
StatusCallback connect_cb_;
bool disconnect_pending_ = false;
StatusCallback disconnect_cb_;
bool rssi_pending_ = false;
RssiCallback rssi_cb_;
bool mtu_pending_ = false;
StatusCallback mtu_cb_;
bool discover_services_pending_ = false;
DiscoverServicesCb discover_services_cb_;
std::atomic<bool> connected_{false};
std::atomic<int> mtu_{kDefaultMtu};
std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteService>>
uuid_to_service_;
std::map<uint16_t, scoped_refptr<RemoteCharacteristic>>
handle_to_characteristic_;
std::map<uint16_t, scoped_refptr<RemoteDescriptor>> handle_to_descriptor_;
DISALLOW_COPY_AND_ASSIGN(RemoteDeviceImpl);
};
} // namespace bluetooth
} // namespace chromecast
#endif // CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_DEVICE_IMPL_H_
......@@ -11,14 +11,11 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "chromecast/public/bluetooth/gatt.h"
namespace chromecast {
namespace bluetooth {
class GattClientManager;
class RemoteCharacteristic;
class RemoteDevice;
......@@ -27,43 +24,19 @@ class RemoteDevice;
class RemoteService : public base::RefCountedThreadSafe<RemoteService> {
public:
// Returns a list of characteristics in this service.
void GetCharacteristics(
base::OnceCallback<void(std::vector<scoped_refptr<RemoteCharacteristic>>)>
cb);
virtual std::vector<scoped_refptr<RemoteCharacteristic>>
GetCharacteristics() = 0;
std::vector<scoped_refptr<RemoteCharacteristic>> GetCharacteristics();
virtual scoped_refptr<RemoteCharacteristic> GetCharacteristicByUuid(
const bluetooth_v2_shlib::Uuid& uuid) = 0;
scoped_refptr<RemoteCharacteristic> GetCharacteristicByUuid(
const bluetooth_v2_shlib::Uuid& uuid);
virtual const bluetooth_v2_shlib::Uuid& uuid() const = 0;
virtual uint16_t handle() const = 0;
virtual bool primary() const = 0;
const bluetooth_v2_shlib::Uuid& uuid() const { return service_.uuid; }
uint16_t handle() const { return service_.handle; }
bool primary() const { return service_.primary; }
private:
friend class RemoteDevice;
protected:
friend class base::RefCountedThreadSafe<RemoteService>;
static std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteCharacteristic>>
CreateCharMap(RemoteDevice* remote_device,
base::WeakPtr<GattClientManager> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Service& service,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
// May only be constructed by RemoteDevice.
explicit RemoteService(
RemoteDevice* remote_device,
base::WeakPtr<GattClientManager> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Service& service,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
~RemoteService();
const bluetooth_v2_shlib::Gatt::Service service_;
const std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteCharacteristic>>
uuid_to_characteristic_;
DISALLOW_COPY_AND_ASSIGN(RemoteService);
virtual ~RemoteService() = default;
};
} // namespace bluetooth
......
......@@ -2,32 +2,32 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/device/bluetooth/le/remote_service.h"
#include "chromecast/device/bluetooth/le/remote_service_impl.h"
#include "chromecast/base/bind_to_task_runner.h"
#include "chromecast/device/bluetooth/le/remote_characteristic.h"
#include "chromecast/device/bluetooth/le/remote_characteristic_impl.h"
namespace chromecast {
namespace bluetooth {
// static
std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteCharacteristic>>
RemoteService::CreateCharMap(
RemoteServiceImpl::CreateCharMap(
RemoteDevice* remote_device,
base::WeakPtr<GattClientManager> gatt_client_manager,
base::WeakPtr<GattClientManagerImpl> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Service& service,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) {
std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteCharacteristic>> ret;
for (const auto& characteristic : service.characteristics) {
ret[characteristic.uuid] = new RemoteCharacteristic(
ret[characteristic.uuid] = new RemoteCharacteristicImpl(
remote_device, gatt_client_manager, &characteristic, io_task_runner);
}
return ret;
}
RemoteService::RemoteService(
RemoteServiceImpl::RemoteServiceImpl(
RemoteDevice* remote_device,
base::WeakPtr<GattClientManager> gatt_client_manager,
base::WeakPtr<GattClientManagerImpl> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Service& service,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
: service_(service),
......@@ -40,10 +40,10 @@ RemoteService::RemoteService(
DCHECK(io_task_runner->BelongsToCurrentThread());
}
RemoteService::~RemoteService() = default;
RemoteServiceImpl::~RemoteServiceImpl() = default;
std::vector<scoped_refptr<RemoteCharacteristic>>
RemoteService::GetCharacteristics() {
RemoteServiceImpl::GetCharacteristics() {
std::vector<scoped_refptr<RemoteCharacteristic>> ret;
ret.reserve(uuid_to_characteristic_.size());
for (const auto& pair : uuid_to_characteristic_) {
......@@ -53,7 +53,7 @@ RemoteService::GetCharacteristics() {
return ret;
}
scoped_refptr<RemoteCharacteristic> RemoteService::GetCharacteristicByUuid(
scoped_refptr<RemoteCharacteristic> RemoteServiceImpl::GetCharacteristicByUuid(
const bluetooth_v2_shlib::Uuid& uuid) {
auto it = uuid_to_characteristic_.find(uuid);
if (it == uuid_to_characteristic_.end())
......@@ -61,5 +61,15 @@ scoped_refptr<RemoteCharacteristic> RemoteService::GetCharacteristicByUuid(
return it->second;
}
const bluetooth_v2_shlib::Uuid& RemoteServiceImpl::uuid() const {
return service_.uuid;
}
uint16_t RemoteServiceImpl::handle() const {
return service_.handle;
}
bool RemoteServiceImpl::primary() const {
return service_.primary;
}
} // namespace bluetooth
} // namespace chromecast
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_SERVICE_IMPL_H_
#define CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_SERVICE_IMPL_H_
#include <map>
#include <memory>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "chromecast/device/bluetooth/le/remote_service.h"
namespace chromecast {
namespace bluetooth {
class GattClientManagerImpl;
class RemoteServiceImpl : public RemoteService {
public:
// RemoteService implementation:
std::vector<scoped_refptr<RemoteCharacteristic>> GetCharacteristics()
override;
scoped_refptr<RemoteCharacteristic> GetCharacteristicByUuid(
const bluetooth_v2_shlib::Uuid& uuid) override;
const bluetooth_v2_shlib::Uuid& uuid() const override;
uint16_t handle() const override;
bool primary() const override;
private:
friend class RemoteDeviceImpl;
static std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteCharacteristic>>
CreateCharMap(RemoteDevice* remote_device,
base::WeakPtr<GattClientManagerImpl> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Service& service,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
// May only be constructed by RemoteDevice.
explicit RemoteServiceImpl(
RemoteDevice* remote_device,
base::WeakPtr<GattClientManagerImpl> gatt_client_manager,
const bluetooth_v2_shlib::Gatt::Service& service,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
~RemoteServiceImpl() override;
const bluetooth_v2_shlib::Gatt::Service service_;
const std::map<bluetooth_v2_shlib::Uuid, scoped_refptr<RemoteCharacteristic>>
uuid_to_characteristic_;
DISALLOW_COPY_AND_ASSIGN(RemoteServiceImpl);
};
} // namespace bluetooth
} // namespace chromecast
#endif // CHROMECAST_DEVICE_BLUETOOTH_LE_REMOTE_SERVICE_IMPL_H_
......@@ -4,6 +4,7 @@
#include "device/bluetooth/cast/bluetooth_device_cast.h"
#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "chromecast/device/bluetooth/bluetooth_util.h"
......
......@@ -16,6 +16,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/strings/string16.h"
#include "build/build_config.h"
......@@ -128,4 +129,4 @@ class BluetoothDeviceCast : public BluetoothDevice {
} // namespace device
#endif // DEVICE_BLUETOOTH_CAST_BLUETOOTH_DEVICE_CAST_H_
\ No newline at end of file
#endif // DEVICE_BLUETOOTH_CAST_BLUETOOTH_DEVICE_CAST_H_
......@@ -4,6 +4,7 @@
#include "device/bluetooth/cast/bluetooth_remote_gatt_characteristic_cast.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_forward.h"
#include "base/containers/queue.h"
......
......@@ -19,12 +19,16 @@ namespace device {
BluetoothRemoteGattServiceCast::BluetoothRemoteGattServiceCast(
BluetoothDeviceCast* device,
scoped_refptr<chromecast::bluetooth::RemoteService> remote_service)
: device_(device),
remote_service_(std::move(remote_service)),
weak_factory_(this) {
remote_service_->GetCharacteristics(
base::BindOnce(&BluetoothRemoteGattServiceCast::OnGetCharacteristics,
weak_factory_.GetWeakPtr()));
: device_(device), remote_service_(std::move(remote_service)) {
std::vector<scoped_refptr<chromecast::bluetooth::RemoteCharacteristic>>
characteristics = remote_service_->GetCharacteristics();
characteristics_.reserve(characteristics.size());
for (auto& characteristic : characteristics) {
characteristics_.push_back(
std::make_unique<BluetoothRemoteGattCharacteristicCast>(
this, characteristic));
}
SetDiscoveryComplete(true);
}
BluetoothRemoteGattServiceCast::~BluetoothRemoteGattServiceCast() {}
......@@ -71,16 +75,4 @@ BluetoothRemoteGattServiceCast::GetCharacteristic(
return nullptr;
}
void BluetoothRemoteGattServiceCast::OnGetCharacteristics(
std::vector<scoped_refptr<chromecast::bluetooth::RemoteCharacteristic>>
characteristics) {
characteristics_.reserve(characteristics.size());
for (auto& characteristic : characteristics) {
characteristics_.push_back(
std::make_unique<BluetoothRemoteGattCharacteristicCast>(
this, characteristic));
}
SetDiscoveryComplete(true);
}
} // namespace device
......@@ -12,12 +12,10 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "device/bluetooth/bluetooth_remote_gatt_service.h"
namespace chromecast {
namespace bluetooth {
class RemoteCharacteristic;
class RemoteService;
} // namespace bluetooth
} // namespace chromecast
......@@ -48,20 +46,15 @@ class BluetoothRemoteGattServiceCast : public BluetoothRemoteGattService {
const std::string& identifier) const override;
private:
void OnGetCharacteristics(
std::vector<scoped_refptr<chromecast::bluetooth::RemoteCharacteristic>>);
BluetoothDeviceCast* const device_;
scoped_refptr<chromecast::bluetooth::RemoteService> remote_service_;
std::vector<std::unique_ptr<BluetoothRemoteGattCharacteristicCast>>
characteristics_;
base::WeakPtrFactory<BluetoothRemoteGattServiceCast> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattServiceCast);
};
} // namespace device
#endif // DEVICE_BLUETOOTH_CAST_BLUETOOTH_REMOTE_GATT_SERVICE_CAST_H_
\ No newline at end of file
#endif // DEVICE_BLUETOOTH_CAST_BLUETOOTH_REMOTE_GATT_SERVICE_CAST_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment