OLD | NEW |
---|---|
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_mac.h" | 5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/strings/sys_string_conversions.h" | 9 #include "base/strings/sys_string_conversions.h" |
10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
64 } | 64 } |
65 return result; | 65 return result; |
66 } | 66 } |
67 } // namespace | 67 } // namespace |
68 | 68 |
69 BluetoothRemoteGattCharacteristicMac::BluetoothRemoteGattCharacteristicMac( | 69 BluetoothRemoteGattCharacteristicMac::BluetoothRemoteGattCharacteristicMac( |
70 BluetoothRemoteGattServiceMac* gatt_service, | 70 BluetoothRemoteGattServiceMac* gatt_service, |
71 CBCharacteristic* cb_characteristic) | 71 CBCharacteristic* cb_characteristic) |
72 : gatt_service_(gatt_service), | 72 : gatt_service_(gatt_service), |
73 cb_characteristic_(cb_characteristic, base::scoped_policy::RETAIN), | 73 cb_characteristic_(cb_characteristic, base::scoped_policy::RETAIN), |
74 characteristic_value_read_or_write_in_progress_(false), | 74 characteristic_value_read_or_write_in_progress_(false) { |
75 start_notifications_in_progress_(false), | |
76 weak_ptr_factory_(this) { | |
77 uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID( | 75 uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID( |
78 [cb_characteristic_.get() UUID]); | 76 [cb_characteristic_.get() UUID]); |
79 identifier_ = base::SysNSStringToUTF8( | 77 identifier_ = base::SysNSStringToUTF8( |
80 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), | 78 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), |
81 (void*)cb_characteristic_]); | 79 (void*)cb_characteristic_]); |
82 } | 80 } |
83 | 81 |
84 BluetoothRemoteGattCharacteristicMac::~BluetoothRemoteGattCharacteristicMac() { | 82 BluetoothRemoteGattCharacteristicMac::~BluetoothRemoteGattCharacteristicMac() { |
85 if (!read_characteristic_value_callbacks_.first.is_null()) { | 83 if (!read_characteristic_value_callbacks_.first.is_null()) { |
86 std::pair<ValueCallback, ErrorCallback> callbacks; | 84 std::pair<ValueCallback, ErrorCallback> callbacks; |
87 callbacks.swap(read_characteristic_value_callbacks_); | 85 callbacks.swap(read_characteristic_value_callbacks_); |
88 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); | 86 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); |
89 } | 87 } |
90 if (!write_characteristic_value_callbacks_.first.is_null()) { | 88 if (!write_characteristic_value_callbacks_.first.is_null()) { |
91 std::pair<base::Closure, ErrorCallback> callbacks; | 89 std::pair<base::Closure, ErrorCallback> callbacks; |
92 callbacks.swap(write_characteristic_value_callbacks_); | 90 callbacks.swap(write_characteristic_value_callbacks_); |
93 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); | 91 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); |
94 } | 92 } |
93 if (!subscribe_to_notification_callback_.second.is_null()) { | |
ortuno
2017/01/18 01:22:02
Do any tests fail if you remove this? I think the
jlebel
2017/01/18 14:42:32
This code can be removed without breaking unit tes
| |
94 PendingNotifyCallback callbacks; | |
95 callbacks.swap(subscribe_to_notification_callback_); | |
96 callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED); | |
97 } | |
95 } | 98 } |
96 | 99 |
97 std::string BluetoothRemoteGattCharacteristicMac::GetIdentifier() const { | 100 std::string BluetoothRemoteGattCharacteristicMac::GetIdentifier() const { |
98 return identifier_; | 101 return identifier_; |
99 } | 102 } |
100 | 103 |
101 BluetoothUUID BluetoothRemoteGattCharacteristicMac::GetUUID() const { | 104 BluetoothUUID BluetoothRemoteGattCharacteristicMac::GetUUID() const { |
102 return uuid_; | 105 return uuid_; |
103 } | 106 } |
104 | 107 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 BluetoothRemoteGattCharacteristicMac::GetDescriptor( | 146 BluetoothRemoteGattCharacteristicMac::GetDescriptor( |
144 const std::string& identifier) const { | 147 const std::string& identifier) const { |
145 auto searched_pair = gatt_descriptor_macs_.find(identifier); | 148 auto searched_pair = gatt_descriptor_macs_.find(identifier); |
146 if (searched_pair == gatt_descriptor_macs_.end()) { | 149 if (searched_pair == gatt_descriptor_macs_.end()) { |
147 return nullptr; | 150 return nullptr; |
148 } | 151 } |
149 return static_cast<BluetoothRemoteGattDescriptor*>( | 152 return static_cast<BluetoothRemoteGattDescriptor*>( |
150 searched_pair->second.get()); | 153 searched_pair->second.get()); |
151 } | 154 } |
152 | 155 |
153 void BluetoothRemoteGattCharacteristicMac::StartNotifySession( | |
154 const NotifySessionCallback& callback, | |
155 const ErrorCallback& error_callback) { | |
156 if (IsNotifying()) { | |
157 VLOG(2) << "Already notifying. Creating notify session."; | |
158 std::unique_ptr<BluetoothGattNotifySession> notify_session( | |
159 new BluetoothGattNotifySession(weak_ptr_factory_.GetWeakPtr())); | |
160 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
161 FROM_HERE, | |
162 base::Bind(callback, base::Passed(std::move(notify_session)))); | |
163 return; | |
164 } | |
165 | |
166 if (!SupportsNotificationsOrIndications()) { | |
167 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
168 FROM_HERE, | |
169 base::Bind(error_callback, | |
170 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); | |
171 return; | |
172 } | |
173 | |
174 start_notify_session_callbacks_.push_back( | |
175 std::make_pair(callback, error_callback)); | |
176 | |
177 if (start_notifications_in_progress_) { | |
178 VLOG(2) << "Start Notifications already in progress. " | |
179 << "Request has been queued."; | |
180 return; | |
181 } | |
182 | |
183 [GetCBPeripheral() setNotifyValue:YES | |
184 forCharacteristic:cb_characteristic_.get()]; | |
185 start_notifications_in_progress_ = true; | |
186 } | |
187 | |
188 void BluetoothRemoteGattCharacteristicMac::StopNotifySession( | |
189 BluetoothGattNotifySession* session, | |
190 const base::Closure& callback) { | |
191 // TODO(http://crbug.com/633191): Remove this method and use the base version. | |
192 // Instead, we should implement SubscribeToNotifications and | |
193 // UnsubscribeFromNotifications. | |
194 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); | |
195 } | |
196 | |
197 void BluetoothRemoteGattCharacteristicMac::ReadRemoteCharacteristic( | 156 void BluetoothRemoteGattCharacteristicMac::ReadRemoteCharacteristic( |
198 const ValueCallback& callback, | 157 const ValueCallback& callback, |
199 const ErrorCallback& error_callback) { | 158 const ErrorCallback& error_callback) { |
200 if (!IsReadable()) { | 159 if (!IsReadable()) { |
201 base::ThreadTaskRunnerHandle::Get()->PostTask( | 160 base::ThreadTaskRunnerHandle::Get()->PostTask( |
202 FROM_HERE, | 161 FROM_HERE, |
203 base::Bind(error_callback, | 162 base::Bind(error_callback, |
204 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); | 163 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); |
205 return; | 164 return; |
206 } | 165 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
249 FROM_HERE, | 208 FROM_HERE, |
250 base::Bind(&BluetoothRemoteGattCharacteristicMac::DidWriteValue, | 209 base::Bind(&BluetoothRemoteGattCharacteristicMac::DidWriteValue, |
251 base::Unretained(this), nil)); | 210 base::Unretained(this), nil)); |
252 } | 211 } |
253 } | 212 } |
254 | 213 |
255 void BluetoothRemoteGattCharacteristicMac::SubscribeToNotifications( | 214 void BluetoothRemoteGattCharacteristicMac::SubscribeToNotifications( |
256 BluetoothRemoteGattDescriptor* ccc_descriptor, | 215 BluetoothRemoteGattDescriptor* ccc_descriptor, |
257 const base::Closure& callback, | 216 const base::Closure& callback, |
258 const ErrorCallback& error_callback) { | 217 const ErrorCallback& error_callback) { |
259 // TODO(http://crbug.com/633191): Implement this method | 218 DCHECK(subscribe_to_notification_callback_.first.is_null()); |
260 NOTIMPLEMENTED(); | 219 DCHECK(subscribe_to_notification_callback_.second.is_null()); |
220 subscribe_to_notification_callback_ = | |
221 std::make_pair(callback, error_callback); | |
222 [GetCBPeripheral() setNotifyValue:YES | |
223 forCharacteristic:cb_characteristic_.get()]; | |
261 } | 224 } |
262 | 225 |
263 void BluetoothRemoteGattCharacteristicMac::UnsubscribeFromNotifications( | 226 void BluetoothRemoteGattCharacteristicMac::UnsubscribeFromNotifications( |
264 BluetoothRemoteGattDescriptor* ccc_descriptor, | 227 BluetoothRemoteGattDescriptor* ccc_descriptor, |
265 const base::Closure& callback, | 228 const base::Closure& callback, |
266 const ErrorCallback& error_callback) { | 229 const ErrorCallback& error_callback) { |
267 // TODO(http://crbug.com/633191): Implement this method | 230 // TODO(http://crbug.com/633191): Implement this method |
268 NOTIMPLEMENTED(); | 231 NOTIMPLEMENTED(); |
269 } | 232 } |
270 | 233 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
329 BluetoothGattService::GattErrorCode error_code = | 292 BluetoothGattService::GattErrorCode error_code = |
330 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); | 293 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); |
331 callbacks.second.Run(error_code); | 294 callbacks.second.Run(error_code); |
332 return; | 295 return; |
333 } | 296 } |
334 callbacks.first.Run(); | 297 callbacks.first.Run(); |
335 } | 298 } |
336 | 299 |
337 void BluetoothRemoteGattCharacteristicMac::DidUpdateNotificationState( | 300 void BluetoothRemoteGattCharacteristicMac::DidUpdateNotificationState( |
338 NSError* error) { | 301 NSError* error) { |
339 std::vector<std::pair<NotifySessionCallback, ErrorCallback>> | 302 PendingNotifyCallback reentrant_safe_callbacks; |
340 reentrant_safe_callbacks; | 303 reentrant_safe_callbacks.swap(subscribe_to_notification_callback_); |
341 reentrant_safe_callbacks.swap(start_notify_session_callbacks_); | |
342 start_notifications_in_progress_ = false; | |
343 if (error) { | 304 if (error) { |
344 VLOG(1) << "Bluetooth error while modifying notification state for " | 305 VLOG(1) << "Bluetooth error while modifying notification state for " |
345 "characteristic, domain: " | 306 "characteristic, domain: " |
346 << base::SysNSStringToUTF8(error.domain) | 307 << base::SysNSStringToUTF8(error.domain) |
347 << ", error code: " << error.code << ", localized description: " | 308 << ", error code: " << error.code << ", localized description: " |
348 << base::SysNSStringToUTF8(error.localizedDescription); | 309 << base::SysNSStringToUTF8(error.localizedDescription); |
349 BluetoothGattService::GattErrorCode error_code = | 310 BluetoothGattService::GattErrorCode error_code = |
350 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); | 311 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); |
351 for (const auto& callback : reentrant_safe_callbacks) { | 312 if (!reentrant_safe_callbacks.second.is_null()) { |
352 callback.second.Run(error_code); | 313 reentrant_safe_callbacks.second.Run(error_code); |
353 } | 314 } |
354 return; | 315 return; |
355 } | 316 } |
356 for (const auto& callback : reentrant_safe_callbacks) { | 317 if (!reentrant_safe_callbacks.first.is_null()) { |
357 callback.first.Run(base::MakeUnique<BluetoothGattNotifySession>( | 318 reentrant_safe_callbacks.first.Run(); |
358 weak_ptr_factory_.GetWeakPtr())); | |
359 } | 319 } |
360 } | 320 } |
361 | 321 |
362 void BluetoothRemoteGattCharacteristicMac::DidDiscoverDescriptors() { | 322 void BluetoothRemoteGattCharacteristicMac::DidDiscoverDescriptors() { |
363 DCHECK(!is_discovery_complete_); | 323 DCHECK(!is_discovery_complete_); |
364 std::unordered_set<std::string> descriptor_identifier_to_remove; | 324 std::unordered_set<std::string> descriptor_identifier_to_remove; |
365 for (const auto& iter : gatt_descriptor_macs_) { | 325 for (const auto& iter : gatt_descriptor_macs_) { |
366 descriptor_identifier_to_remove.insert(iter.first); | 326 descriptor_identifier_to_remove.insert(iter.first); |
367 } | 327 } |
368 | 328 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
445 pair) { | 405 pair) { |
446 return pair.second->GetCBDescriptor() == cb_descriptor; | 406 return pair.second->GetCBDescriptor() == cb_descriptor; |
447 }); | 407 }); |
448 if (found == gatt_descriptor_macs_.end()) { | 408 if (found == gatt_descriptor_macs_.end()) { |
449 return nullptr; | 409 return nullptr; |
450 } else { | 410 } else { |
451 return found->second.get(); | 411 return found->second.get(); |
452 } | 412 } |
453 } | 413 } |
454 } // namespace device. | 414 } // namespace device. |
OLD | NEW |