| 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; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 BluetoothRemoteGattCharacteristicMac::GetDescriptor( | 141 BluetoothRemoteGattCharacteristicMac::GetDescriptor( |
| 144 const std::string& identifier) const { | 142 const std::string& identifier) const { |
| 145 auto searched_pair = gatt_descriptor_macs_.find(identifier); | 143 auto searched_pair = gatt_descriptor_macs_.find(identifier); |
| 146 if (searched_pair == gatt_descriptor_macs_.end()) { | 144 if (searched_pair == gatt_descriptor_macs_.end()) { |
| 147 return nullptr; | 145 return nullptr; |
| 148 } | 146 } |
| 149 return static_cast<BluetoothRemoteGattDescriptor*>( | 147 return static_cast<BluetoothRemoteGattDescriptor*>( |
| 150 searched_pair->second.get()); | 148 searched_pair->second.get()); |
| 151 } | 149 } |
| 152 | 150 |
| 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( | 151 void BluetoothRemoteGattCharacteristicMac::ReadRemoteCharacteristic( |
| 198 const ValueCallback& callback, | 152 const ValueCallback& callback, |
| 199 const ErrorCallback& error_callback) { | 153 const ErrorCallback& error_callback) { |
| 200 if (!IsReadable()) { | 154 if (!IsReadable()) { |
| 201 base::ThreadTaskRunnerHandle::Get()->PostTask( | 155 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 202 FROM_HERE, | 156 FROM_HERE, |
| 203 base::Bind(error_callback, | 157 base::Bind(error_callback, |
| 204 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); | 158 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); |
| 205 return; | 159 return; |
| 206 } | 160 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 FROM_HERE, | 203 FROM_HERE, |
| 250 base::Bind(&BluetoothRemoteGattCharacteristicMac::DidWriteValue, | 204 base::Bind(&BluetoothRemoteGattCharacteristicMac::DidWriteValue, |
| 251 base::Unretained(this), nil)); | 205 base::Unretained(this), nil)); |
| 252 } | 206 } |
| 253 } | 207 } |
| 254 | 208 |
| 255 void BluetoothRemoteGattCharacteristicMac::SubscribeToNotifications( | 209 void BluetoothRemoteGattCharacteristicMac::SubscribeToNotifications( |
| 256 BluetoothRemoteGattDescriptor* ccc_descriptor, | 210 BluetoothRemoteGattDescriptor* ccc_descriptor, |
| 257 const base::Closure& callback, | 211 const base::Closure& callback, |
| 258 const ErrorCallback& error_callback) { | 212 const ErrorCallback& error_callback) { |
| 259 // TODO(http://crbug.com/633191): Implement this method | 213 DCHECK(subscribe_to_notification_callback_.first.is_null()); |
| 260 NOTIMPLEMENTED(); | 214 DCHECK(subscribe_to_notification_callback_.second.is_null()); |
| 215 subscribe_to_notification_callback_ = |
| 216 std::make_pair(callback, error_callback); |
| 217 [GetCBPeripheral() setNotifyValue:YES |
| 218 forCharacteristic:cb_characteristic_.get()]; |
| 261 } | 219 } |
| 262 | 220 |
| 263 void BluetoothRemoteGattCharacteristicMac::UnsubscribeFromNotifications( | 221 void BluetoothRemoteGattCharacteristicMac::UnsubscribeFromNotifications( |
| 264 BluetoothRemoteGattDescriptor* ccc_descriptor, | 222 BluetoothRemoteGattDescriptor* ccc_descriptor, |
| 265 const base::Closure& callback, | 223 const base::Closure& callback, |
| 266 const ErrorCallback& error_callback) { | 224 const ErrorCallback& error_callback) { |
| 267 // TODO(http://crbug.com/633191): Implement this method | 225 // TODO(http://crbug.com/633191): Implement this method |
| 268 NOTIMPLEMENTED(); | 226 NOTIMPLEMENTED(); |
| 269 } | 227 } |
| 270 | 228 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 BluetoothGattService::GattErrorCode error_code = | 287 BluetoothGattService::GattErrorCode error_code = |
| 330 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); | 288 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); |
| 331 callbacks.second.Run(error_code); | 289 callbacks.second.Run(error_code); |
| 332 return; | 290 return; |
| 333 } | 291 } |
| 334 callbacks.first.Run(); | 292 callbacks.first.Run(); |
| 335 } | 293 } |
| 336 | 294 |
| 337 void BluetoothRemoteGattCharacteristicMac::DidUpdateNotificationState( | 295 void BluetoothRemoteGattCharacteristicMac::DidUpdateNotificationState( |
| 338 NSError* error) { | 296 NSError* error) { |
| 339 std::vector<std::pair<NotifySessionCallback, ErrorCallback>> | 297 PendingNotifyCallback reentrant_safe_callbacks; |
| 340 reentrant_safe_callbacks; | 298 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) { | 299 if (error) { |
| 344 VLOG(1) << "Bluetooth error while modifying notification state for " | 300 VLOG(1) << "Bluetooth error while modifying notification state for " |
| 345 "characteristic, domain: " | 301 "characteristic, domain: " |
| 346 << base::SysNSStringToUTF8(error.domain) | 302 << base::SysNSStringToUTF8(error.domain) |
| 347 << ", error code: " << error.code << ", localized description: " | 303 << ", error code: " << error.code << ", localized description: " |
| 348 << base::SysNSStringToUTF8(error.localizedDescription); | 304 << base::SysNSStringToUTF8(error.localizedDescription); |
| 349 BluetoothGattService::GattErrorCode error_code = | 305 BluetoothGattService::GattErrorCode error_code = |
| 350 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); | 306 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); |
| 351 for (const auto& callback : reentrant_safe_callbacks) { | 307 if (!reentrant_safe_callbacks.second.is_null()) { |
| 352 callback.second.Run(error_code); | 308 reentrant_safe_callbacks.second.Run(error_code); |
| 353 } | 309 } |
| 354 return; | 310 return; |
| 355 } | 311 } |
| 356 for (const auto& callback : reentrant_safe_callbacks) { | 312 if (!reentrant_safe_callbacks.first.is_null()) { |
| 357 callback.first.Run(base::MakeUnique<BluetoothGattNotifySession>( | 313 reentrant_safe_callbacks.first.Run(); |
| 358 weak_ptr_factory_.GetWeakPtr())); | |
| 359 } | 314 } |
| 360 } | 315 } |
| 361 | 316 |
| 362 void BluetoothRemoteGattCharacteristicMac::DidDiscoverDescriptors() { | 317 void BluetoothRemoteGattCharacteristicMac::DidDiscoverDescriptors() { |
| 363 DCHECK(!is_discovery_complete_); | 318 DCHECK(!is_discovery_complete_); |
| 364 std::unordered_set<std::string> descriptor_identifier_to_remove; | 319 std::unordered_set<std::string> descriptor_identifier_to_remove; |
| 365 for (const auto& iter : gatt_descriptor_macs_) { | 320 for (const auto& iter : gatt_descriptor_macs_) { |
| 366 descriptor_identifier_to_remove.insert(iter.first); | 321 descriptor_identifier_to_remove.insert(iter.first); |
| 367 } | 322 } |
| 368 | 323 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 pair) { | 400 pair) { |
| 446 return pair.second->GetCBDescriptor() == cb_descriptor; | 401 return pair.second->GetCBDescriptor() == cb_descriptor; |
| 447 }); | 402 }); |
| 448 if (found == gatt_descriptor_macs_.end()) { | 403 if (found == gatt_descriptor_macs_.end()) { |
| 449 return nullptr; | 404 return nullptr; |
| 450 } else { | 405 } else { |
| 451 return found->second.get(); | 406 return found->second.get(); |
| 452 } | 407 } |
| 453 } | 408 } |
| 454 } // namespace device. | 409 } // namespace device. |
| OLD | NEW |