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

Unified Diff: device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc

Issue 1749403002: Implement BluetoothRemoteGattCharacteristicWin::StartNotifySession and related unit tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Enable RememberCharacteristicForSubsequentAction and related tests Created 4 years, 9 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_characteristic_win.cc
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
index d98c0ea8d2fcb7f5709672d03305dee3076abfe7..560a00e25bc1b9d3b5c6fbe9ffd829991adb5a6c 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "device/bluetooth/bluetooth_adapter_win.h"
+#include "device/bluetooth/bluetooth_gatt_notify_session_win.h"
#include "device/bluetooth/bluetooth_remote_gatt_descriptor_win.h"
#include "device/bluetooth/bluetooth_remote_gatt_service_win.h"
#include "device/bluetooth/bluetooth_task_manager_win.h"
@@ -21,6 +22,8 @@ BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin(
ui_task_runner_(ui_task_runner),
characteristic_added_notified_(false),
characteristic_value_read_or_write_in_progress_(false),
+ gatt_event_registeration_in_progress_(false),
+ gatt_event_handle_(nullptr),
weak_ptr_factory_(this) {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
DCHECK(parent_service_);
@@ -41,6 +44,11 @@ BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin(
BluetoothRemoteGattCharacteristicWin::~BluetoothRemoteGattCharacteristicWin() {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+ if (gatt_event_handle_ != nullptr) {
+ task_manager_->PostUnregisterGattCharacteristicValueChangedEvent(
+ gatt_event_handle_);
+ gatt_event_handle_ = nullptr;
+ }
parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this);
}
@@ -105,8 +113,7 @@ BluetoothRemoteGattCharacteristicWin::GetPermissions() const {
}
bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const {
- NOTIMPLEMENTED();
- return false;
+ return gatt_event_handle_ != nullptr;
}
std::vector<BluetoothGattDescriptor*>
@@ -140,8 +147,47 @@ bool BluetoothRemoteGattCharacteristicWin::UpdateValue(
void BluetoothRemoteGattCharacteristicWin::StartNotifySession(
const NotifySessionCallback& callback,
const ErrorCallback& error_callback) {
- NOTIMPLEMENTED();
- error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED);
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+
+ if (IsNotifying()) {
+ scoped_ptr<BluetoothGattNotifySessionWin> notify_session(
+ new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr()));
+ ui_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(callback, base::Passed(std::move(notify_session))));
+ return;
+ }
+
+ if (gatt_event_registeration_in_progress_) {
+ start_notify_session_callbacks_.push_back(
+ std::make_pair(callback, error_callback));
+ return;
+ }
+
+ if (!characteristic_info_->IsNotifiable &&
+ !characteristic_info_->IsIndicatable) {
+ ui_task_runner_->PostTask(
+ FROM_HERE, base::Bind(error_callback,
+ BluetoothGattService::GATT_ERROR_NOT_SUPPORTED));
+ return;
+ }
+
+ // TODO(crbug.com/594697): Check the existence of client characteristic
+ // configuration descriptor.
+ // Note: No need to write client characteristic configuration descriptor
+ // explicitly to start notifications on Windows.
+
+ start_notify_session_callbacks_.push_back(
+ std::make_pair(callback, error_callback));
+ task_manager_->PostRegisterGattCharacteristicValueChangedEvent(
+ parent_service_->GetServicePath(), characteristic_info_.get(),
+ base::Bind(
+ &BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&BluetoothRemoteGattCharacteristicWin::
+ OnGattCharacteristicValueChanged,
+ weak_ptr_factory_.GetWeakPtr()));
+ gatt_event_registeration_in_progress_ = true;
}
void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic(
@@ -324,18 +370,51 @@ void BluetoothRemoteGattCharacteristicWin::
BluetoothGattService::GattErrorCode
BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) {
+ if (HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER) == hr)
+ return BluetoothGattService::GATT_ERROR_INVALID_LENGTH;
+
switch (hr) {
case E_BLUETOOTH_ATT_READ_NOT_PERMITTED:
case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED:
return BluetoothGattService::GATT_ERROR_NOT_PERMITTED;
case E_BLUETOOTH_ATT_UNKNOWN_ERROR:
return BluetoothGattService::GATT_ERROR_UNKNOWN;
- case ERROR_INVALID_USER_BUFFER:
case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH:
return BluetoothGattService::GATT_ERROR_INVALID_LENGTH;
+ case E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED:
+ return BluetoothGattService::GATT_ERROR_NOT_SUPPORTED;
default:
return BluetoothGattService::GATT_ERROR_FAILED;
}
}
+void BluetoothRemoteGattCharacteristicWin::OnGattCharacteristicValueChanged(
+ scoped_ptr<std::vector<uint8_t>> new_value) {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+
+ characteristic_value_.assign(new_value->begin(), new_value->end());
+ parent_service_->GetWinAdapter()->NotifyGattCharacteristicValueChanged(
+ this, characteristic_value_);
+}
+
+void BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback(
+ BLUETOOTH_GATT_EVENT_HANDLE event_handle,
+ HRESULT hr) {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+
+ gatt_event_registeration_in_progress_ = false;
+ std::vector<std::pair<NotifySessionCallback, ErrorCallback>> callbacks;
+ callbacks.swap(start_notify_session_callbacks_);
+ if (SUCCEEDED(hr)) {
+ gatt_event_handle_ = event_handle;
+ for (const auto& callback : callbacks) {
+ callback.first.Run(make_scoped_ptr(
+ new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr())));
+ }
+ } else {
+ for (const auto& callback : callbacks)
+ callback.second.Run(HRESULTToGattErrorCode(hr));
+ }
+}
+
} // namespace device.

Powered by Google App Engine
This is Rietveld 408576698