Chromium Code Reviews| 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() { |
|
scheib
2016/02/25 06:22:43
Please keep member definitions in the same order a
gogerald1
2016/02/25 23:19:18
Done.
|
| + 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_) { |
|
scheib
2016/02/25 06:22:43
Not 'cha'. Perhaps 'entry', 'kv' for 'key / value'
gogerald1
2016/02/25 23:19:18
Done.
|
| + 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. |
|
scheib
2016/02/25 06:22:43
remove characteristics that no longer exist.
gogerald1
2016/02/25 23:19:18
Done.
|
| + std::vector<std::string> to_be_removed; |
| + for (const auto& cha : included_characteristic_) { |
|
scheib
2016/02/25 06:22:44
'cha' again
gogerald1
2016/02/25 23:19:18
Done.
|
| + if (!DoesCharacteristicExist(characteristics, num, cha.second.get())) |
| + to_be_removed.push_back(cha.second->GetIdentifier()); |
| + } |
| + for (auto id : to_be_removed) { |
|
scheib
2016/02/25 06:22:44
const auto&
gogerald1
2016/02/25 23:19:18
Done.
|
| + 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_) { |
|
scheib
2016/02/25 06:22:44
not 'ser'
gogerald1
2016/02/25 23:19:18
Done.
|
| + 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. |
|
scheib
2016/02/25 06:22:44
remove services that no longer exist.
gogerald1
2016/02/25 23:19:17
Done.
|
| + std::vector<std::string> to_be_removed; |
| + for (const auto& ser : included_service_) { |
|
scheib
2016/02/25 06:22:43
not 'ser'
gogerald1
2016/02/25 23:19:18
Done.
|
| + 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. |
|
scheib
2016/02/25 06:22:44
explain in comment why.
gogerald1
2016/02/25 23:19:18
Done.
|
| + if (is_primary_) |
| + adapter_->NotifyGattServiceRemoved(this); |
| +} |
| std::string BluetoothRemoteGattServiceWin::GetIdentifier() const { |
| std::string identifier = |
|
scheib
2016/02/25 06:22:44
The characteristic code that computes the ID once
gogerald1
2016/02/25 23:19:18
Done.
|
| @@ -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. |