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

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: move comments Created 4 years, 8 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
13 namespace device { 14 namespace device {
14 15
15 BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin( 16 BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin(
16 BluetoothRemoteGattServiceWin* parent_service, 17 BluetoothRemoteGattServiceWin* parent_service,
17 BTH_LE_GATT_CHARACTERISTIC* characteristic_info, 18 BTH_LE_GATT_CHARACTERISTIC* characteristic_info,
18 scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) 19 scoped_refptr<base::SequencedTaskRunner>& ui_task_runner)
19 : parent_service_(parent_service), 20 : parent_service_(parent_service),
20 characteristic_info_(characteristic_info), 21 characteristic_info_(characteristic_info),
21 ui_task_runner_(ui_task_runner), 22 ui_task_runner_(ui_task_runner),
22 characteristic_added_notified_(false), 23 characteristic_added_notified_(false),
23 characteristic_value_read_or_write_in_progress_(false), 24 characteristic_value_read_or_write_in_progress_(false),
25 gatt_event_registeration_in_progress_(false),
26 gatt_event_handle_(nullptr),
24 weak_ptr_factory_(this) { 27 weak_ptr_factory_(this) {
25 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 28 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
26 DCHECK(parent_service_); 29 DCHECK(parent_service_);
27 DCHECK(characteristic_info_); 30 DCHECK(characteristic_info_);
28 31
29 task_manager_ = 32 task_manager_ =
30 parent_service_->GetWinAdapter()->GetWinBluetoothTaskManager(); 33 parent_service_->GetWinAdapter()->GetWinBluetoothTaskManager();
31 DCHECK(task_manager_); 34 DCHECK(task_manager_);
32 characteristic_uuid_ = 35 characteristic_uuid_ =
33 BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid( 36 BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid(
34 characteristic_info_->CharacteristicUuid); 37 characteristic_info_->CharacteristicUuid);
35 characteristic_identifier_ = 38 characteristic_identifier_ =
36 parent_service_->GetIdentifier() + "_" + 39 parent_service_->GetIdentifier() + "_" +
37 std::to_string(characteristic_info_->AttributeHandle); 40 std::to_string(characteristic_info_->AttributeHandle);
38 Update(); 41 Update();
39 } 42 }
40 43
41 BluetoothRemoteGattCharacteristicWin::~BluetoothRemoteGattCharacteristicWin() { 44 BluetoothRemoteGattCharacteristicWin::~BluetoothRemoteGattCharacteristicWin() {
42 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 45 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
43 46
47 ClearIncludedDescriptors();
48
49 if (gatt_event_handle_ != nullptr) {
50 task_manager_->PostUnregisterGattCharacteristicValueChangedEvent(
51 gatt_event_handle_);
52 gatt_event_handle_ = nullptr;
53 }
44 parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this); 54 parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this);
55
56 // Clear pending StartNotifySession callbacks.
57 for (const auto& callback : start_notify_session_callbacks_)
58 callback.second.Run(BluetoothGattService::GATT_ERROR_FAILED);
45 } 59 }
46 60
47 std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const { 61 std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const {
48 return characteristic_identifier_; 62 return characteristic_identifier_;
49 } 63 }
50 64
51 BluetoothUUID BluetoothRemoteGattCharacteristicWin::GetUUID() const { 65 BluetoothUUID BluetoothRemoteGattCharacteristicWin::GetUUID() const {
52 return characteristic_uuid_; 66 return characteristic_uuid_;
53 } 67 }
54 68
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 112
99 if (characteristic_info_->IsReadable) 113 if (characteristic_info_->IsReadable)
100 permissions = permissions | PERMISSION_READ; 114 permissions = permissions | PERMISSION_READ;
101 if (characteristic_info_->IsWritable) 115 if (characteristic_info_->IsWritable)
102 permissions = permissions | PERMISSION_WRITE; 116 permissions = permissions | PERMISSION_WRITE;
103 117
104 return permissions; 118 return permissions;
105 } 119 }
106 120
107 bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const { 121 bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const {
108 NOTIMPLEMENTED(); 122 return gatt_event_handle_ != nullptr;
109 return false;
110 } 123 }
111 124
112 std::vector<BluetoothGattDescriptor*> 125 std::vector<BluetoothGattDescriptor*>
113 BluetoothRemoteGattCharacteristicWin::GetDescriptors() const { 126 BluetoothRemoteGattCharacteristicWin::GetDescriptors() const {
114 std::vector<BluetoothGattDescriptor*> descriptors; 127 std::vector<BluetoothGattDescriptor*> descriptors;
115 for (const auto& descriptor : included_descriptors_) 128 for (const auto& descriptor : included_descriptors_)
116 descriptors.push_back(descriptor.second.get()); 129 descriptors.push_back(descriptor.second.get());
117 return descriptors; 130 return descriptors;
118 } 131 }
119 132
(...skipping 13 matching lines...) Expand all
133 146
134 bool BluetoothRemoteGattCharacteristicWin::UpdateValue( 147 bool BluetoothRemoteGattCharacteristicWin::UpdateValue(
135 const std::vector<uint8_t>& value) { 148 const std::vector<uint8_t>& value) {
136 NOTIMPLEMENTED(); 149 NOTIMPLEMENTED();
137 return false; 150 return false;
138 } 151 }
139 152
140 void BluetoothRemoteGattCharacteristicWin::StartNotifySession( 153 void BluetoothRemoteGattCharacteristicWin::StartNotifySession(
141 const NotifySessionCallback& callback, 154 const NotifySessionCallback& callback,
142 const ErrorCallback& error_callback) { 155 const ErrorCallback& error_callback) {
143 NOTIMPLEMENTED(); 156 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
144 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED); 157
158 if (IsNotifying()) {
159 scoped_ptr<BluetoothGattNotifySessionWin> notify_session(
160 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr()));
161 ui_task_runner_->PostTask(
162 FROM_HERE,
163 base::Bind(callback, base::Passed(std::move(notify_session))));
164 return;
165 }
166
167 if (!characteristic_info_->IsNotifiable &&
168 !characteristic_info_->IsIndicatable) {
169 ui_task_runner_->PostTask(
170 FROM_HERE, base::Bind(error_callback,
171 BluetoothGattService::GATT_ERROR_NOT_SUPPORTED));
172 return;
173 }
174
175 std::vector<BluetoothGattDescriptor*> ccc_descriptors = GetDescriptorsByUUID(
176 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid());
177 if (ccc_descriptors.size() < 1) {
178 ui_task_runner_->PostTask(
179 FROM_HERE, base::Bind(error_callback,
180 BluetoothGattService::GATT_ERROR_NOT_SUPPORTED));
181 return;
182 }
183 if (ccc_descriptors.size() > 1) {
184 ui_task_runner_->PostTask(
185 FROM_HERE,
186 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED));
187 return;
188 }
189
190 start_notify_session_callbacks_.push_back(
191 std::make_pair(callback, error_callback));
192 if (gatt_event_registeration_in_progress_)
193 return;
194
195 task_manager_->PostRegisterGattCharacteristicValueChangedEvent(
196 parent_service_->GetServicePath(), characteristic_info_.get(),
197 static_cast<BluetoothRemoteGattDescriptorWin*>(ccc_descriptors[0])
198 ->GetWinDescriptorInfo(),
199 base::Bind(
200 &BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback,
201 weak_ptr_factory_.GetWeakPtr()),
202 base::Bind(&BluetoothRemoteGattCharacteristicWin::
203 OnGattCharacteristicValueChanged,
204 weak_ptr_factory_.GetWeakPtr()));
205 gatt_event_registeration_in_progress_ = true;
145 } 206 }
146 207
147 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( 208 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic(
148 const ValueCallback& callback, 209 const ValueCallback& callback,
149 const ErrorCallback& error_callback) { 210 const ErrorCallback& error_callback) {
150 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 211 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
151 212
152 if (!characteristic_info_.get()->IsReadable) { 213 if (!characteristic_info_.get()->IsReadable) {
153 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); 214 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED);
154 return; 215 return;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 included_descriptors_.clear(); 290 included_descriptors_.clear();
230 return; 291 return;
231 } 292 }
232 293
233 // First, remove descriptors that no longer exist. 294 // First, remove descriptors that no longer exist.
234 std::vector<std::string> to_be_removed; 295 std::vector<std::string> to_be_removed;
235 for (const auto& d : included_descriptors_) { 296 for (const auto& d : included_descriptors_) {
236 if (!DoesDescriptorExist(descriptors, num, d.second.get())) 297 if (!DoesDescriptorExist(descriptors, num, d.second.get()))
237 to_be_removed.push_back(d.second->GetIdentifier()); 298 to_be_removed.push_back(d.second->GetIdentifier());
238 } 299 }
239 for (auto id : to_be_removed) 300 for (auto id : to_be_removed) {
301 included_descriptors_[id].reset();
240 included_descriptors_.erase(id); 302 included_descriptors_.erase(id);
303 }
241 304
242 // Return if no new descriptors have been added. 305 // Return if no new descriptors have been added.
243 if (included_descriptors_.size() == num) 306 if (included_descriptors_.size() == num)
244 return; 307 return;
245 308
246 // Add new descriptors. 309 // Add new descriptors.
247 for (uint16_t i = 0; i < num; i++) { 310 for (uint16_t i = 0; i < num; i++) {
248 if (!IsDescriptorDiscovered(descriptors[i].DescriptorUuid, 311 if (!IsDescriptorDiscovered(descriptors[i].DescriptorUuid,
249 descriptors[i].AttributeHandle)) { 312 descriptors[i].AttributeHandle)) {
250 PBTH_LE_GATT_DESCRIPTOR win_descriptor_info = 313 PBTH_LE_GATT_DESCRIPTOR win_descriptor_info =
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 if (FAILED(hr)) { 380 if (FAILED(hr)) {
318 callbacks.second.Run(HRESULTToGattErrorCode(hr)); 381 callbacks.second.Run(HRESULTToGattErrorCode(hr));
319 } else { 382 } else {
320 callbacks.first.Run(); 383 callbacks.first.Run();
321 } 384 }
322 characteristic_value_read_or_write_in_progress_ = false; 385 characteristic_value_read_or_write_in_progress_ = false;
323 } 386 }
324 387
325 BluetoothGattService::GattErrorCode 388 BluetoothGattService::GattErrorCode
326 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { 389 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) {
390 if (HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER) == hr)
391 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH;
392
327 switch (hr) { 393 switch (hr) {
328 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: 394 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED:
329 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: 395 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED:
330 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED; 396 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED;
331 case E_BLUETOOTH_ATT_UNKNOWN_ERROR: 397 case E_BLUETOOTH_ATT_UNKNOWN_ERROR:
332 return BluetoothGattService::GATT_ERROR_UNKNOWN; 398 return BluetoothGattService::GATT_ERROR_UNKNOWN;
333 case ERROR_INVALID_USER_BUFFER:
334 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: 399 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH:
335 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; 400 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH;
401 case E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED:
402 return BluetoothGattService::GATT_ERROR_NOT_SUPPORTED;
336 default: 403 default:
337 return BluetoothGattService::GATT_ERROR_FAILED; 404 return BluetoothGattService::GATT_ERROR_FAILED;
338 } 405 }
339 } 406 }
340 407
408 void BluetoothRemoteGattCharacteristicWin::OnGattCharacteristicValueChanged(
409 scoped_ptr<std::vector<uint8_t>> new_value) {
410 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
411
412 characteristic_value_.assign(new_value->begin(), new_value->end());
413 parent_service_->GetWinAdapter()->NotifyGattCharacteristicValueChanged(
414 this, characteristic_value_);
415 }
416
417 void BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback(
418 BLUETOOTH_GATT_EVENT_HANDLE event_handle,
419 HRESULT hr) {
420 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
421
422 gatt_event_registeration_in_progress_ = false;
423 std::vector<std::pair<NotifySessionCallback, ErrorCallback>> callbacks;
424 callbacks.swap(start_notify_session_callbacks_);
425 if (SUCCEEDED(hr)) {
426 gatt_event_handle_ = event_handle;
427 for (const auto& callback : callbacks) {
428 callback.first.Run(make_scoped_ptr(
429 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr())));
430 }
431 } else {
432 for (const auto& callback : callbacks)
433 callback.second.Run(HRESULTToGattErrorCode(hr));
434 }
435 }
436
437 void BluetoothRemoteGattCharacteristicWin::ClearIncludedDescriptors() {
438 // Explicitly reset to null to ensure that calling GetDescriptor() on the
439 // removed descriptor in GattDescriptorRemoved() returns null.
440 for (auto& entry : included_descriptors_)
441 entry.second.reset();
442 included_descriptors_.clear();
443 }
444
341 } // namespace device. 445 } // namespace device.
OLDNEW
« no previous file with comments | « device/bluetooth/bluetooth_remote_gatt_characteristic_win.h ('k') | device/bluetooth/bluetooth_remote_gatt_descriptor_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698