Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(269)

Unified Diff: device/bluetooth/bluetooth_remote_gatt_service_win.cc

Issue 1690133002: Implement BluetoothRemoteGattServiceWin and related unit tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address comments Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: device/bluetooth/bluetooth_remote_gatt_service_win.cc
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_win.cc b/device/bluetooth/bluetooth_remote_gatt_service_win.cc
index 0c93588b92d7d7f67b7968a5ec26145569265331..5e22f90458402404a569ef1017d329222142d4ee 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_win.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_service_win.cc
@@ -4,7 +4,233 @@
#include "device/bluetooth/bluetooth_remote_gatt_service_win.h"
+#include "base/bind.h"
+#include "device/bluetooth/bluetooth_adapter_win.h"
+#include "device/bluetooth/bluetooth_device_win.h"
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic_win.h"
+#include "device/bluetooth/bluetooth_task_manager_win.h"
+
namespace device {
+
+void BluetoothRemoteGattServiceWin::NotifyServiceDiscComplIfNecessary() {
+ if (discovery_completed_included_charateristics_.size() ==
+ included_characteristic_.size() &&
+ discovery_completed_included_services_.size() ==
+ included_service_.size() &&
+ included_services_discovered_ && included_characteristics_discovered_ &&
+ !discovery_complete_notified_) {
+ if (is_primary_)
+ adapter_->NotifyGattDiscoveryComplete(this);
+ else
+ parent_service_->GattServiceDiscoverComplete(this);
+ discovery_complete_notified_ = true;
+ }
+}
+
+bool BluetoothRemoteGattServiceWin::IsCharacteristicDiscovered(
+ BTH_LE_UUID& uuid,
+ uint16_t attribute_handle) {
+ BluetoothUUID bt_uuid =
+ task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(uuid);
+ for (const auto& cha : included_characteristic_) {
+ if (bt_uuid == cha.second->GetUUID() &&
+ attribute_handle == cha.second->GetAttributeHandle()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool BluetoothRemoteGattServiceWin::DoesCharacteristicExist(
+ PBTH_LE_GATT_CHARACTERISTIC characteristics,
+ uint16_t num,
+ BluetoothRemoteGattCharacteristicWin* characteristic) {
+ for (uint16_t i = 0; i < num; i++) {
+ BluetoothUUID uuid = task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(
+ characteristics[i].CharacteristicUuid);
+ if (characteristic->GetUUID() == uuid &&
+ characteristic->GetAttributeHandle() ==
+ characteristics[i].AttributeHandle) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void BluetoothRemoteGattServiceWin::RemoveIncludedCharacteristic(
+ std::string identifier) {
+ discovery_completed_included_charateristics_.erase(identifier);
+ included_characteristic_.erase(identifier);
+}
+
+void BluetoothRemoteGattServiceWin::ClearIncludedCharacteristics() {
+ discovery_completed_included_charateristics_.clear();
+ included_characteristic_.clear();
+}
+
+void BluetoothRemoteGattServiceWin::UpdateIncludedCharacteristics(
+ PBTH_LE_GATT_CHARACTERISTIC characteristics,
+ uint16_t num) {
+ if (num == 0) {
+ ClearIncludedCharacteristics();
+ return;
+ }
+
+ // First, remove no longer existed characteristics.
+ std::vector<std::string> to_be_removed;
+ for (const auto& cha : included_characteristic_) {
+ if (!DoesCharacteristicExist(characteristics, num, cha.second.get()))
+ to_be_removed.push_back(cha.second->GetIdentifier());
+ }
+ for (auto id : to_be_removed) {
+ RemoveIncludedCharacteristic(id);
+ }
+
+ // Update previously known characteristics.
+ for (auto& cha : included_characteristic_)
+ cha.second->Update();
+
+ // Return if no new characteristics have been added.
+ if (included_characteristic_.size() == num)
+ return;
+
+ // Add new characteristics.
+ for (uint16_t i = 0; i < num; i++) {
+ if (!IsCharacteristicDiscovered(characteristics[i].CharacteristicUuid,
+ characteristics[i].AttributeHandle)) {
+ PBTH_LE_GATT_CHARACTERISTIC info = new BTH_LE_GATT_CHARACTERISTIC();
+ *info = characteristics[i];
+ BluetoothRemoteGattCharacteristicWin* characteristic_object =
+ new BluetoothRemoteGattCharacteristicWin(this, info, ui_task_runner_);
+ included_characteristic_[characteristic_object->GetIdentifier()] =
+ make_scoped_ptr(characteristic_object);
+ }
+ }
+}
+
+void BluetoothRemoteGattServiceWin::GetIncludedCharacteristicsCallback(
+ scoped_ptr<BTH_LE_GATT_CHARACTERISTIC> characteristics,
+ uint16_t num,
+ HRESULT hr) {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+
+ UpdateIncludedCharacteristics(characteristics.get(), num);
+ included_characteristics_discovered_ = true;
+ NotifyServiceDiscComplIfNecessary();
+}
+
+bool BluetoothRemoteGattServiceWin::IsServiceDiscovered(
+ BluetoothUUID& uuid,
+ uint16_t attribute_handle) {
+ for (const auto& ser : included_service_) {
+ if (uuid == ser.second->GetUUID() &&
+ attribute_handle == ser.second->GetAttributeHandle()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool BluetoothRemoteGattServiceWin::DoesServiceExist(
+ PBTH_LE_GATT_SERVICE services,
+ uint16_t num,
+ BluetoothRemoteGattServiceWin* service) {
+ for (uint16_t i = 0; i < num; i++) {
+ BluetoothUUID uuid = task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(
+ services[i].ServiceUuid);
+ if (service->GetUUID() == uuid &&
+ service->GetAttributeHandle() == services[i].AttributeHandle) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void BluetoothRemoteGattServiceWin::RemoveIncludedService(
+ std::string identifier) {
+ discovery_completed_included_services_.erase(identifier);
+ included_service_.erase(identifier);
+}
+
+void BluetoothRemoteGattServiceWin::ClearIncludedServices() {
+ discovery_completed_included_services_.clear();
+ included_service_.clear();
+}
+
+void BluetoothRemoteGattServiceWin::UpdateIncludedServices(
+ PBTH_LE_GATT_SERVICE services,
+ uint16_t num) {
+ if (num == 0) {
+ ClearIncludedServices();
+ return;
+ }
+
+ // First, remove no longer exist included service.
+ std::vector<std::string> to_be_removed;
+ for (const auto& ser : included_service_) {
+ if (!DoesServiceExist(services, num, ser.second.get())) {
+ to_be_removed.push_back(ser.second->GetIdentifier());
+ }
+ }
+ for (auto id : to_be_removed)
+ RemoveIncludedService(id);
+
+ // Update previously known included services.
+ for (auto& ser : included_service_)
+ ser.second->Update();
+
+ // Return if no new services have been added.
+ if (included_service_.size() == num)
+ return;
+
+ // Add new services.
+ for (uint16_t i = 0; i < num; i++) {
+ BluetoothUUID uuid = task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(
+ services[i].ServiceUuid);
+ if (!IsServiceDiscovered(uuid, services[i].AttributeHandle)) {
+ BluetoothRemoteGattServiceWin* service_object =
+ new BluetoothRemoteGattServiceWin(device_, service_path_, uuid,
+ services[i].AttributeHandle, false,
+ this, ui_task_runner_);
+ included_service_[service_object->GetIdentifier()] =
+ make_scoped_ptr(service_object);
+ }
+ }
+}
+
+void BluetoothRemoteGattServiceWin::GetIncludedServicesCallback(
+ scoped_ptr<BTH_LE_GATT_SERVICE> services,
+ uint16_t num,
+ HRESULT hr) {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+
+ UpdateIncludedServices(services.get(), num);
+ included_services_discovered_ = true;
+ NotifyServiceDiscComplIfNecessary();
+}
+
+void BluetoothRemoteGattServiceWin::GattServiceDiscoverComplete(
+ BluetoothRemoteGattServiceWin* service) {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+ DCHECK(included_service_.find(service->GetIdentifier()) !=
+ included_service_.end());
+
+ discovery_completed_included_services_.insert(service->GetIdentifier());
+ NotifyServiceDiscComplIfNecessary();
+}
+
+void BluetoothRemoteGattServiceWin::GattCharacteristicDiscoverComplete(
+ BluetoothRemoteGattCharacteristicWin* characteristic) {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+ DCHECK(included_characteristic_.find(characteristic->GetIdentifier()) !=
+ included_characteristic_.end());
+
+ discovery_completed_included_charateristics_.insert(
+ characteristic->GetIdentifier());
+ adapter_->NotifyGattCharacteristicAdded(characteristic);
+ NotifyServiceDiscComplIfNecessary();
+}
+
BluetoothRemoteGattServiceWin::BluetoothRemoteGattServiceWin(
BluetoothDeviceWin* device,
base::FilePath service_path,
@@ -13,13 +239,15 @@ BluetoothRemoteGattServiceWin::BluetoothRemoteGattServiceWin(
bool is_primary,
BluetoothRemoteGattServiceWin* parent_service,
scoped_refptr<base::SequencedTaskRunner>& ui_task_runner)
- : service_path_(service_path),
- device_(device),
+ : device_(device),
+ service_path_(service_path),
service_uuid_(service_uuid),
service_attribute_handle_(service_attribute_handle),
is_primary_(is_primary),
parent_service_(parent_service),
- ui_task_runner_(ui_task_runner) {
+ ui_task_runner_(ui_task_runner),
+ discovery_complete_notified_(false),
+ weak_ptr_factory_(this) {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
DCHECK(!service_path_.empty());
DCHECK(service_uuid_.IsValid());
@@ -27,10 +255,21 @@ BluetoothRemoteGattServiceWin::BluetoothRemoteGattServiceWin(
DCHECK(device_);
if (!is_primary_)
DCHECK(parent_service_);
+ adapter_ = static_cast<BluetoothAdapterWin*>(device_->GetAdapter());
+ DCHECK(adapter_);
+ task_manager_ = adapter_->GetWinBluetoothTaskManager();
+ DCHECK(task_manager_);
+
Update();
}
-BluetoothRemoteGattServiceWin::~BluetoothRemoteGattServiceWin() {}
+BluetoothRemoteGattServiceWin::~BluetoothRemoteGattServiceWin() {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+
+ // Only notify adapter for primary service.
+ if (is_primary_)
+ adapter_->NotifyGattServiceRemoved(this);
+}
std::string BluetoothRemoteGattServiceWin::GetIdentifier() const {
std::string identifier =
@@ -59,19 +298,26 @@ BluetoothDevice* BluetoothRemoteGattServiceWin::GetDevice() const {
std::vector<BluetoothGattCharacteristic*>
BluetoothRemoteGattServiceWin::GetCharacteristics() const {
- NOTIMPLEMENTED();
- return std::vector<BluetoothGattCharacteristic*>();
+ std::vector<BluetoothGattCharacteristic*> has_characteristics;
+ for (const auto& cha : included_characteristic_)
+ has_characteristics.push_back(cha.second.get());
+ return has_characteristics;
}
std::vector<BluetoothGattService*>
BluetoothRemoteGattServiceWin::GetIncludedServices() const {
- NOTIMPLEMENTED();
- return std::vector<BluetoothGattService*>();
+ std::vector<BluetoothGattService*> has_services;
+ for (const auto& ser : included_service_)
+ has_services.push_back(ser.second.get());
+ return has_services;
}
BluetoothGattCharacteristic* BluetoothRemoteGattServiceWin::GetCharacteristic(
const std::string& identifier) const {
- NOTIMPLEMENTED();
+ GattCharacteristicsMap::const_iterator it =
+ included_characteristic_.find(identifier);
+ if (it != included_characteristic_.end())
+ return it->second.get();
return nullptr;
}
@@ -103,11 +349,16 @@ void BluetoothRemoteGattServiceWin::Unregister(
void BluetoothRemoteGattServiceWin::Update() {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
- NOTIMPLEMENTED();
-}
-uint16_t BluetoothRemoteGattServiceWin::GetAttributeHandle() {
- return service_attribute_handle_;
+ task_manager_->PostGetGattIncludedServices(
+ service_path_, service_uuid_, service_attribute_handle_,
+ base::Bind(&BluetoothRemoteGattServiceWin::GetIncludedServicesCallback,
+ weak_ptr_factory_.GetWeakPtr()));
+ task_manager_->PostGetGattIncludedCharacteristics(
+ service_path_, service_uuid_, service_attribute_handle_,
+ base::Bind(
+ &BluetoothRemoteGattServiceWin::GetIncludedCharacteristicsCallback,
+ weak_ptr_factory_.GetWeakPtr()));
}
-} // namespace device.
+} // namespace device.

Powered by Google App Engine
This is Rietveld 408576698