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

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: address comments 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..34d464bdc2f9db7ab842a5273a01dc7cef3c4714 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.cc
@@ -6,10 +6,24 @@
#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"
+namespace {
+
+// Function to be registered to OS to monitor Bluetooth LE GATT event.
+void OnGetGattEventWin(BTH_LE_GATT_EVENT_TYPE type,
+ PVOID event_parameter,
+ PVOID context) {
+ device::BluetoothRemoteGattCharacteristicWin* characteristic =
+ (device::BluetoothRemoteGattCharacteristicWin*)context;
+ characteristic->OnGetRemoteGattEvent(type, event_parameter);
+}
+
+} // namespace
+
namespace device {
BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin(
@@ -21,6 +35,9 @@ BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin(
ui_task_runner_(ui_task_runner),
characteristic_added_notified_(false),
characteristic_value_read_or_write_in_progress_(false),
+ number_of_active_notify_sessions_(0),
+ gatt_event_registeration_in_progress_(false),
+ gatt_event_handle_(NULL),
weak_ptr_factory_(this) {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
DCHECK(parent_service_);
@@ -41,6 +58,11 @@ BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin(
BluetoothRemoteGattCharacteristicWin::~BluetoothRemoteGattCharacteristicWin() {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+ if (gatt_event_handle_ != NULL) {
+ task_manager_->UnregisterGattCharacteristicValueChangedEvent(
+ gatt_event_handle_);
+ gatt_event_handle_ = NULL;
+ }
parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this);
}
@@ -105,8 +127,7 @@ BluetoothRemoteGattCharacteristicWin::GetPermissions() const {
}
bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const {
- NOTIMPLEMENTED();
- return false;
+ return gatt_event_handle_ != NULL;
}
std::vector<BluetoothGattDescriptor*>
@@ -140,8 +161,33 @@ 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))));
+ number_of_active_notify_sessions_++;
+ return;
+ }
+
+ if (gatt_event_registeration_in_progress_) {
+ start_notify_session_callbacks_.push_back(
+ std::make_pair(callback, error_callback));
+ return;
+ }
+
+ 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()),
+ &OnGetGattEventWin, (PVOID) this);
+ gatt_event_registeration_in_progress_ = true;
}
void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic(
@@ -195,6 +241,29 @@ void BluetoothRemoteGattCharacteristicWin::WriteRemoteCharacteristic(
weak_ptr_factory_.GetWeakPtr()));
}
+void BluetoothRemoteGattCharacteristicWin::OnGetRemoteGattEvent(
+ BTH_LE_GATT_EVENT_TYPE type,
+ PVOID event_parameter) {
+ if (type == CharacteristicValueChangedEvent) {
+ BLUETOOTH_GATT_VALUE_CHANGED_EVENT* event =
+ (BLUETOOTH_GATT_VALUE_CHANGED_EVENT*)event_parameter;
+ PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value_win =
+ event->CharacteristicValue;
+ scoped_ptr<std::vector<uint8_t>> new_value(
+ new std::vector<uint8_t>(new_value_win->DataSize));
+ for (ULONG i = 0; i < new_value_win->DataSize; i++)
+ new_value->at(i) = new_value_win->Data[i];
ortuno 2016/03/08 00:05:36 nit: You can just use the [] operator: new_value.g
gogerald1 2016/03/08 19:22:23 Acknowledged.
ortuno 2016/03/09 16:53:59 Rather than just saying "Ackowledged", you should
gogerald1 2016/03/10 16:10:54 I suppose nit means optional, ->at(i) looks neat a
ortuno 2016/03/14 01:37:37 Yes nit means optional. But it's important you com
scheib 2016/03/14 17:54:46 nit == nitpick == a small, possibly trivial, probl
+
+ ui_task_runner_->PostTask(FROM_HERE,
+ base::Bind(&BluetoothRemoteGattCharacteristicWin::
+ OnGattCharacteristicValueChanged,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(std::move(new_value))));
+ return;
+ }
+ NOTREACHED();
+}
+
void BluetoothRemoteGattCharacteristicWin::Update() {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
@@ -209,6 +278,23 @@ uint16_t BluetoothRemoteGattCharacteristicWin::GetAttributeHandle() const {
return characteristic_info_->AttributeHandle;
}
+void BluetoothRemoteGattCharacteristicWin::StopNotifySession() {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+
+ if (!IsNotifying())
+ return;
+
+ if (number_of_active_notify_sessions_ > 1) {
+ number_of_active_notify_sessions_--;
+ return;
+ }
+
+ task_manager_->UnregisterGattCharacteristicValueChangedEvent(
+ gatt_event_handle_);
+ gatt_event_handle_ = NULL;
+ number_of_active_notify_sessions_ = 0;
+}
+
void BluetoothRemoteGattCharacteristicWin::OnGetIncludedDescriptorsCallback(
scoped_ptr<BTH_LE_GATT_DESCRIPTOR> descriptors,
uint16_t num,
@@ -333,9 +419,41 @@ BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) {
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())));
+ number_of_active_notify_sessions_++;
+ }
+ } else {
+ for (const auto& callback : callbacks)
+ callback.second.Run(HRESULTToGattErrorCode(hr));
+ }
+}
+
} // namespace device.

Powered by Google App Engine
This is Rietveld 408576698