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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_win.h" 5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_win.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "device/bluetooth/bluetooth_adapter_win.h" 8 #include "device/bluetooth/bluetooth_adapter_win.h"
9 #include "device/bluetooth/bluetooth_gatt_notify_session_win.h"
9 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_win.h" 10 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_win.h"
10 #include "device/bluetooth/bluetooth_remote_gatt_service_win.h" 11 #include "device/bluetooth/bluetooth_remote_gatt_service_win.h"
11 #include "device/bluetooth/bluetooth_task_manager_win.h" 12 #include "device/bluetooth/bluetooth_task_manager_win.h"
12 13
14 namespace {
15
16 // Function to be registered to OS to monitor Bluetooth LE GATT event.
17 void OnGetGattEventWin(BTH_LE_GATT_EVENT_TYPE type,
18 PVOID event_parameter,
19 PVOID context) {
20 device::BluetoothRemoteGattCharacteristicWin* characteristic =
21 (device::BluetoothRemoteGattCharacteristicWin*)context;
22 characteristic->OnGetRemoteGattEvent(type, event_parameter);
23 }
24
25 } // namespace
26
13 namespace device { 27 namespace device {
14 28
15 BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin( 29 BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin(
16 BluetoothRemoteGattServiceWin* parent_service, 30 BluetoothRemoteGattServiceWin* parent_service,
17 BTH_LE_GATT_CHARACTERISTIC* characteristic_info, 31 BTH_LE_GATT_CHARACTERISTIC* characteristic_info,
18 scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) 32 scoped_refptr<base::SequencedTaskRunner>& ui_task_runner)
19 : parent_service_(parent_service), 33 : parent_service_(parent_service),
20 characteristic_info_(characteristic_info), 34 characteristic_info_(characteristic_info),
21 ui_task_runner_(ui_task_runner), 35 ui_task_runner_(ui_task_runner),
22 characteristic_added_notified_(false), 36 characteristic_added_notified_(false),
23 characteristic_value_read_or_write_in_progress_(false), 37 characteristic_value_read_or_write_in_progress_(false),
38 number_of_active_notify_sessions_(0),
39 gatt_event_registeration_in_progress_(false),
40 gatt_event_handle_(NULL),
24 weak_ptr_factory_(this) { 41 weak_ptr_factory_(this) {
25 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 42 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
26 DCHECK(parent_service_); 43 DCHECK(parent_service_);
27 DCHECK(characteristic_info_); 44 DCHECK(characteristic_info_);
28 45
29 task_manager_ = 46 task_manager_ =
30 parent_service_->GetWinAdapter()->GetWinBluetoothTaskManager(); 47 parent_service_->GetWinAdapter()->GetWinBluetoothTaskManager();
31 DCHECK(task_manager_); 48 DCHECK(task_manager_);
32 characteristic_uuid_ = 49 characteristic_uuid_ =
33 BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid( 50 BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid(
34 characteristic_info_->CharacteristicUuid); 51 characteristic_info_->CharacteristicUuid);
35 characteristic_identifier_ = 52 characteristic_identifier_ =
36 parent_service_->GetIdentifier() + "_" + 53 parent_service_->GetIdentifier() + "_" +
37 std::to_string(characteristic_info_->AttributeHandle); 54 std::to_string(characteristic_info_->AttributeHandle);
38 Update(); 55 Update();
39 } 56 }
40 57
41 BluetoothRemoteGattCharacteristicWin::~BluetoothRemoteGattCharacteristicWin() { 58 BluetoothRemoteGattCharacteristicWin::~BluetoothRemoteGattCharacteristicWin() {
42 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 59 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
43 60
61 if (gatt_event_handle_ != NULL) {
62 task_manager_->UnregisterGattCharacteristicValueChangedEvent(
63 gatt_event_handle_);
64 gatt_event_handle_ = NULL;
65 }
44 parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this); 66 parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this);
45 } 67 }
46 68
47 std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const { 69 std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const {
48 return characteristic_identifier_; 70 return characteristic_identifier_;
49 } 71 }
50 72
51 BluetoothUUID BluetoothRemoteGattCharacteristicWin::GetUUID() const { 73 BluetoothUUID BluetoothRemoteGattCharacteristicWin::GetUUID() const {
52 return characteristic_uuid_; 74 return characteristic_uuid_;
53 } 75 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 120
99 if (characteristic_info_->IsReadable) 121 if (characteristic_info_->IsReadable)
100 permissions = permissions | PERMISSION_READ; 122 permissions = permissions | PERMISSION_READ;
101 if (characteristic_info_->IsWritable) 123 if (characteristic_info_->IsWritable)
102 permissions = permissions | PERMISSION_WRITE; 124 permissions = permissions | PERMISSION_WRITE;
103 125
104 return permissions; 126 return permissions;
105 } 127 }
106 128
107 bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const { 129 bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const {
108 NOTIMPLEMENTED(); 130 return gatt_event_handle_ != NULL;
109 return false;
110 } 131 }
111 132
112 std::vector<BluetoothGattDescriptor*> 133 std::vector<BluetoothGattDescriptor*>
113 BluetoothRemoteGattCharacteristicWin::GetDescriptors() const { 134 BluetoothRemoteGattCharacteristicWin::GetDescriptors() const {
114 std::vector<BluetoothGattDescriptor*> descriptors; 135 std::vector<BluetoothGattDescriptor*> descriptors;
115 for (const auto& descriptor : included_descriptors_) 136 for (const auto& descriptor : included_descriptors_)
116 descriptors.push_back(descriptor.second.get()); 137 descriptors.push_back(descriptor.second.get());
117 return descriptors; 138 return descriptors;
118 } 139 }
119 140
(...skipping 13 matching lines...) Expand all
133 154
134 bool BluetoothRemoteGattCharacteristicWin::UpdateValue( 155 bool BluetoothRemoteGattCharacteristicWin::UpdateValue(
135 const std::vector<uint8_t>& value) { 156 const std::vector<uint8_t>& value) {
136 NOTIMPLEMENTED(); 157 NOTIMPLEMENTED();
137 return false; 158 return false;
138 } 159 }
139 160
140 void BluetoothRemoteGattCharacteristicWin::StartNotifySession( 161 void BluetoothRemoteGattCharacteristicWin::StartNotifySession(
141 const NotifySessionCallback& callback, 162 const NotifySessionCallback& callback,
142 const ErrorCallback& error_callback) { 163 const ErrorCallback& error_callback) {
143 NOTIMPLEMENTED(); 164 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
144 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED); 165
166 if (IsNotifying()) {
167 scoped_ptr<BluetoothGattNotifySessionWin> notify_session(
168 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr()));
169 ui_task_runner_->PostTask(
170 FROM_HERE,
171 base::Bind(callback, base::Passed(std::move(notify_session))));
172 number_of_active_notify_sessions_++;
173 return;
174 }
175
176 if (gatt_event_registeration_in_progress_) {
177 start_notify_session_callbacks_.push_back(
178 std::make_pair(callback, error_callback));
179 return;
180 }
181
182 start_notify_session_callbacks_.push_back(
183 std::make_pair(callback, error_callback));
184 task_manager_->PostRegisterGattCharacteristicValueChangedEvent(
185 parent_service_->GetServicePath(), characteristic_info_.get(),
186 base::Bind(
187 &BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback,
188 weak_ptr_factory_.GetWeakPtr()),
189 &OnGetGattEventWin, (PVOID) this);
190 gatt_event_registeration_in_progress_ = true;
145 } 191 }
146 192
147 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( 193 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic(
148 const ValueCallback& callback, 194 const ValueCallback& callback,
149 const ErrorCallback& error_callback) { 195 const ErrorCallback& error_callback) {
150 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 196 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
151 197
152 if (!characteristic_info_.get()->IsReadable) { 198 if (!characteristic_info_.get()->IsReadable) {
153 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); 199 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED);
154 return; 200 return;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 characteristic_value_read_or_write_in_progress_ = true; 234 characteristic_value_read_or_write_in_progress_ = true;
189 write_characteristic_value_callbacks_ = 235 write_characteristic_value_callbacks_ =
190 std::make_pair(callback, error_callback); 236 std::make_pair(callback, error_callback);
191 task_manager_->PostWriteGattCharacteristicValue( 237 task_manager_->PostWriteGattCharacteristicValue(
192 parent_service_->GetServicePath(), characteristic_info_.get(), new_value, 238 parent_service_->GetServicePath(), characteristic_info_.get(), new_value,
193 base::Bind(&BluetoothRemoteGattCharacteristicWin:: 239 base::Bind(&BluetoothRemoteGattCharacteristicWin::
194 OnWriteRemoteCharacteristicValueCallback, 240 OnWriteRemoteCharacteristicValueCallback,
195 weak_ptr_factory_.GetWeakPtr())); 241 weak_ptr_factory_.GetWeakPtr()));
196 } 242 }
197 243
244 void BluetoothRemoteGattCharacteristicWin::OnGetRemoteGattEvent(
245 BTH_LE_GATT_EVENT_TYPE type,
246 PVOID event_parameter) {
247 if (type == CharacteristicValueChangedEvent) {
248 BLUETOOTH_GATT_VALUE_CHANGED_EVENT* event =
249 (BLUETOOTH_GATT_VALUE_CHANGED_EVENT*)event_parameter;
250 PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value_win =
251 event->CharacteristicValue;
252 scoped_ptr<std::vector<uint8_t>> new_value(
253 new std::vector<uint8_t>(new_value_win->DataSize));
254 for (ULONG i = 0; i < new_value_win->DataSize; i++)
255 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
256
257 ui_task_runner_->PostTask(FROM_HERE,
258 base::Bind(&BluetoothRemoteGattCharacteristicWin::
259 OnGattCharacteristicValueChanged,
260 weak_ptr_factory_.GetWeakPtr(),
261 base::Passed(std::move(new_value))));
262 return;
263 }
264 NOTREACHED();
265 }
266
198 void BluetoothRemoteGattCharacteristicWin::Update() { 267 void BluetoothRemoteGattCharacteristicWin::Update() {
199 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 268 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
200 269
201 task_manager_->PostGetGattIncludedDescriptors( 270 task_manager_->PostGetGattIncludedDescriptors(
202 parent_service_->GetServicePath(), characteristic_info_.get(), 271 parent_service_->GetServicePath(), characteristic_info_.get(),
203 base::Bind(&BluetoothRemoteGattCharacteristicWin:: 272 base::Bind(&BluetoothRemoteGattCharacteristicWin::
204 OnGetIncludedDescriptorsCallback, 273 OnGetIncludedDescriptorsCallback,
205 weak_ptr_factory_.GetWeakPtr())); 274 weak_ptr_factory_.GetWeakPtr()));
206 } 275 }
207 276
208 uint16_t BluetoothRemoteGattCharacteristicWin::GetAttributeHandle() const { 277 uint16_t BluetoothRemoteGattCharacteristicWin::GetAttributeHandle() const {
209 return characteristic_info_->AttributeHandle; 278 return characteristic_info_->AttributeHandle;
210 } 279 }
211 280
281 void BluetoothRemoteGattCharacteristicWin::StopNotifySession() {
282 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
283
284 if (!IsNotifying())
285 return;
286
287 if (number_of_active_notify_sessions_ > 1) {
288 number_of_active_notify_sessions_--;
289 return;
290 }
291
292 task_manager_->UnregisterGattCharacteristicValueChangedEvent(
293 gatt_event_handle_);
294 gatt_event_handle_ = NULL;
295 number_of_active_notify_sessions_ = 0;
296 }
297
212 void BluetoothRemoteGattCharacteristicWin::OnGetIncludedDescriptorsCallback( 298 void BluetoothRemoteGattCharacteristicWin::OnGetIncludedDescriptorsCallback(
213 scoped_ptr<BTH_LE_GATT_DESCRIPTOR> descriptors, 299 scoped_ptr<BTH_LE_GATT_DESCRIPTOR> descriptors,
214 uint16_t num, 300 uint16_t num,
215 HRESULT hr) { 301 HRESULT hr) {
216 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 302 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
217 303
218 UpdateIncludedDescriptors(descriptors.get(), num); 304 UpdateIncludedDescriptors(descriptors.get(), num);
219 if (!characteristic_added_notified_) { 305 if (!characteristic_added_notified_) {
220 characteristic_added_notified_ = true; 306 characteristic_added_notified_ = true;
221 parent_service_->GetWinAdapter()->NotifyGattCharacteristicAdded(this); 307 parent_service_->GetWinAdapter()->NotifyGattCharacteristicAdded(this);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { 412 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) {
327 switch (hr) { 413 switch (hr) {
328 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: 414 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED:
329 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: 415 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED:
330 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED; 416 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED;
331 case E_BLUETOOTH_ATT_UNKNOWN_ERROR: 417 case E_BLUETOOTH_ATT_UNKNOWN_ERROR:
332 return BluetoothGattService::GATT_ERROR_UNKNOWN; 418 return BluetoothGattService::GATT_ERROR_UNKNOWN;
333 case ERROR_INVALID_USER_BUFFER: 419 case ERROR_INVALID_USER_BUFFER:
334 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: 420 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH:
335 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; 421 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH;
422 case E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED:
423 return BluetoothGattService::GATT_ERROR_NOT_SUPPORTED;
336 default: 424 default:
337 return BluetoothGattService::GATT_ERROR_FAILED; 425 return BluetoothGattService::GATT_ERROR_FAILED;
338 } 426 }
339 } 427 }
340 428
429 void BluetoothRemoteGattCharacteristicWin::OnGattCharacteristicValueChanged(
430 scoped_ptr<std::vector<uint8_t>> new_value) {
431 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
432
433 characteristic_value_.assign(new_value->begin(), new_value->end());
434 parent_service_->GetWinAdapter()->NotifyGattCharacteristicValueChanged(
435 this, characteristic_value_);
436 }
437
438 void BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback(
439 BLUETOOTH_GATT_EVENT_HANDLE event_handle,
440 HRESULT hr) {
441 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
442
443 gatt_event_registeration_in_progress_ = false;
444 std::vector<std::pair<NotifySessionCallback, ErrorCallback>> callbacks;
445 callbacks.swap(start_notify_session_callbacks_);
446 if (SUCCEEDED(hr)) {
447 gatt_event_handle_ = event_handle;
448 for (const auto& callback : callbacks) {
449 callback.first.Run(make_scoped_ptr(
450 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr())));
451 number_of_active_notify_sessions_++;
452 }
453 } else {
454 for (const auto& callback : callbacks)
455 callback.second.Run(HRESULTToGattErrorCode(hr));
456 }
457 }
458
341 } // namespace device. 459 } // namespace device.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698