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

Side by Side Diff: device/bluetooth/bluetooth_remote_gatt_service_mac.mm

Issue 2638653002: Bluetooth: macOS: DidModifyServices can happens while scanning (Closed)
Patch Set: Merge Created 3 years, 7 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_service_mac.h" 5 #include "device/bluetooth/bluetooth_remote_gatt_service_mac.h"
6 6
7 #import <CoreBluetooth/CoreBluetooth.h> 7 #import <CoreBluetooth/CoreBluetooth.h>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "device/bluetooth/bluetooth_adapter_mac.h" 12 #include "device/bluetooth/bluetooth_adapter_mac.h"
13 #include "device/bluetooth/bluetooth_low_energy_device_mac.h" 13 #include "device/bluetooth/bluetooth_low_energy_device_mac.h"
14 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h" 14 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h"
15 #include "device/bluetooth/bluetooth_uuid.h" 15 #include "device/bluetooth/bluetooth_uuid.h"
16 16
17 namespace device { 17 namespace device {
18 18
19 BluetoothRemoteGattServiceMac::BluetoothRemoteGattServiceMac( 19 BluetoothRemoteGattServiceMac::BluetoothRemoteGattServiceMac(
20 BluetoothLowEnergyDeviceMac* bluetooth_device_mac, 20 BluetoothLowEnergyDeviceMac* bluetooth_device_mac,
21 CBService* service, 21 CBService* service,
22 bool is_primary) 22 bool is_primary)
23 : bluetooth_device_mac_(bluetooth_device_mac), 23 : bluetooth_device_mac_(bluetooth_device_mac),
24 service_(service, base::scoped_policy::RETAIN), 24 service_(service, base::scoped_policy::RETAIN),
25 is_primary_(is_primary), 25 is_primary_(is_primary),
26 is_discovery_complete_(false) { 26 is_discovery_complete_(false),
27 discovery_pending_count_(0) {
27 uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID([service_.get() UUID]); 28 uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID([service_.get() UUID]);
28 identifier_ = 29 identifier_ =
29 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(), 30 [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(),
30 (void*)service_] 31 (void*)service_]
31 .UTF8String; 32 .UTF8String;
32 } 33 }
33 34
34 BluetoothRemoteGattServiceMac::~BluetoothRemoteGattServiceMac() {} 35 BluetoothRemoteGattServiceMac::~BluetoothRemoteGattServiceMac() {}
35 36
36 std::string BluetoothRemoteGattServiceMac::GetIdentifier() const { 37 std::string BluetoothRemoteGattServiceMac::GetIdentifier() const {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 if (searched_pair == gatt_characteristic_macs_.end()) { 74 if (searched_pair == gatt_characteristic_macs_.end()) {
74 return nullptr; 75 return nullptr;
75 } 76 }
76 return static_cast<BluetoothRemoteGattCharacteristic*>( 77 return static_cast<BluetoothRemoteGattCharacteristic*>(
77 searched_pair->second.get()); 78 searched_pair->second.get());
78 } 79 }
79 80
80 void BluetoothRemoteGattServiceMac::DiscoverCharacteristics() { 81 void BluetoothRemoteGattServiceMac::DiscoverCharacteristics() {
81 VLOG(1) << *this << ": DiscoverCharacteristics."; 82 VLOG(1) << *this << ": DiscoverCharacteristics.";
82 is_discovery_complete_ = false; 83 is_discovery_complete_ = false;
84 ++discovery_pending_count_;
83 [GetCBPeripheral() discoverCharacteristics:nil forService:GetService()]; 85 [GetCBPeripheral() discoverCharacteristics:nil forService:GetService()];
84 } 86 }
85 87
86 void BluetoothRemoteGattServiceMac::DidDiscoverCharacteristics() { 88 void BluetoothRemoteGattServiceMac::DidDiscoverCharacteristics() {
87 DCHECK(!is_discovery_complete_); 89 if (is_discovery_complete_ || discovery_pending_count_ == 0) {
90 // This should never happen, just in case it happens with a device, this
91 // notification should be ignored.
92 VLOG(1)
93 << *this
94 << ": Unmatch DiscoverCharacteristics and DidDiscoverCharacteristics.";
95 return;
96 }
88 VLOG(1) << *this << ": DidDiscoverCharacteristics."; 97 VLOG(1) << *this << ": DidDiscoverCharacteristics.";
98 --discovery_pending_count_;
89 std::unordered_set<std::string> characteristic_identifier_to_remove; 99 std::unordered_set<std::string> characteristic_identifier_to_remove;
90 for (const auto& iter : gatt_characteristic_macs_) { 100 for (const auto& iter : gatt_characteristic_macs_) {
91 characteristic_identifier_to_remove.insert(iter.first); 101 characteristic_identifier_to_remove.insert(iter.first);
92 } 102 }
93 103
94 for (CBCharacteristic* cb_characteristic in GetService().characteristics) { 104 for (CBCharacteristic* cb_characteristic in GetService().characteristics) {
95 BluetoothRemoteGattCharacteristicMac* gatt_characteristic_mac = 105 BluetoothRemoteGattCharacteristicMac* gatt_characteristic_mac =
96 GetBluetoothRemoteGattCharacteristicMac(cb_characteristic); 106 GetBluetoothRemoteGattCharacteristicMac(cb_characteristic);
97 if (gatt_characteristic_mac) { 107 if (gatt_characteristic_mac) {
98 VLOG(1) << *gatt_characteristic_mac 108 VLOG(1) << *gatt_characteristic_mac
99 << ": Known characteristic, properties " 109 << ": Known characteristic, properties "
100 << gatt_characteristic_mac->GetProperties(); 110 << gatt_characteristic_mac->GetProperties();
101 const std::string& identifier = gatt_characteristic_mac->GetIdentifier(); 111 const std::string& identifier = gatt_characteristic_mac->GetIdentifier();
102 characteristic_identifier_to_remove.erase(identifier); 112 characteristic_identifier_to_remove.erase(identifier);
103 gatt_characteristic_mac->DiscoverDescriptors(); 113 gatt_characteristic_mac->DiscoverDescriptors();
104 continue; 114 continue;
105 } 115 }
106 gatt_characteristic_mac = 116 gatt_characteristic_mac =
107 new BluetoothRemoteGattCharacteristicMac(this, cb_characteristic); 117 new BluetoothRemoteGattCharacteristicMac(this, cb_characteristic);
108 const std::string& identifier = gatt_characteristic_mac->GetIdentifier(); 118 const std::string& identifier = gatt_characteristic_mac->GetIdentifier();
109 auto result_iter = gatt_characteristic_macs_.insert( 119 auto result_iter = gatt_characteristic_macs_.insert(
110 {identifier, base::WrapUnique(gatt_characteristic_mac)}); 120 {identifier, base::WrapUnique(gatt_characteristic_mac)});
111 DCHECK(result_iter.second); 121 DCHECK(result_iter.second);
112 VLOG(1) << *gatt_characteristic_mac << ": New characteristic, properties " 122 VLOG(1) << *gatt_characteristic_mac << ": New characteristic, properties "
113 << gatt_characteristic_mac->GetProperties(); 123 << gatt_characteristic_mac->GetProperties();
114 gatt_characteristic_mac->DiscoverDescriptors(); 124 if (discovery_pending_count_ == 0) {
125 gatt_characteristic_mac->DiscoverDescriptors();
126 }
115 GetMacAdapter()->NotifyGattCharacteristicAdded(gatt_characteristic_mac); 127 GetMacAdapter()->NotifyGattCharacteristicAdded(gatt_characteristic_mac);
116 } 128 }
117 129
118 for (const std::string& identifier : characteristic_identifier_to_remove) { 130 for (const std::string& identifier : characteristic_identifier_to_remove) {
119 auto pair_to_remove = gatt_characteristic_macs_.find(identifier); 131 auto pair_to_remove = gatt_characteristic_macs_.find(identifier);
120 std::unique_ptr<BluetoothRemoteGattCharacteristicMac> 132 std::unique_ptr<BluetoothRemoteGattCharacteristicMac>
121 characteristic_to_remove; 133 characteristic_to_remove;
122 pair_to_remove->second.swap(characteristic_to_remove); 134 pair_to_remove->second.swap(characteristic_to_remove);
123 VLOG(1) << *characteristic_to_remove << ": Removed characteristic."; 135 VLOG(1) << *characteristic_to_remove << ": Removed characteristic.";
124 gatt_characteristic_macs_.erase(pair_to_remove); 136 gatt_characteristic_macs_.erase(pair_to_remove);
125 GetMacAdapter()->NotifyGattCharacteristicRemoved( 137 GetMacAdapter()->NotifyGattCharacteristicRemoved(
126 characteristic_to_remove.get()); 138 characteristic_to_remove.get());
127 } 139 }
128 SendNotificationIfComplete(); 140 SendNotificationIfComplete();
129 } 141 }
130 142
131 void BluetoothRemoteGattServiceMac::DidDiscoverDescriptors( 143 void BluetoothRemoteGattServiceMac::DidDiscoverDescriptors(
132 CBCharacteristic* characteristic) { 144 CBCharacteristic* characteristic) {
133 DCHECK(!is_discovery_complete_); 145 if (is_discovery_complete_) {
146 // This should never happen, just in case it happens with a device, this
147 // notification should be ignored.
148 VLOG(1) << *this
149 << ": Discovery complete, ignoring DidDiscoverDescriptors.";
150 return;
151 }
134 BluetoothRemoteGattCharacteristicMac* gatt_characteristic = 152 BluetoothRemoteGattCharacteristicMac* gatt_characteristic =
135 GetBluetoothRemoteGattCharacteristicMac(characteristic); 153 GetBluetoothRemoteGattCharacteristicMac(characteristic);
136 DCHECK(gatt_characteristic); 154 DCHECK(gatt_characteristic);
137 gatt_characteristic->DidDiscoverDescriptors(); 155 gatt_characteristic->DidDiscoverDescriptors();
138 SendNotificationIfComplete(); 156 SendNotificationIfComplete();
139 } 157 }
140 158
141 void BluetoothRemoteGattServiceMac::SendNotificationIfComplete() { 159 void BluetoothRemoteGattServiceMac::SendNotificationIfComplete() {
142 DCHECK(!is_discovery_complete_); 160 DCHECK(!is_discovery_complete_);
143 // Notify when all characteristics have been fully discovered. 161 // Notify when all characteristics have been fully discovered.
144 is_discovery_complete_ = 162 is_discovery_complete_ =
163 discovery_pending_count_ == 0 &&
145 std::find_if_not( 164 std::find_if_not(
146 gatt_characteristic_macs_.begin(), gatt_characteristic_macs_.end(), 165 gatt_characteristic_macs_.begin(), gatt_characteristic_macs_.end(),
147 [](const std::pair< 166 [](const std::pair<
148 const std::string, 167 const std::string,
149 std::unique_ptr<BluetoothRemoteGattCharacteristicMac>>& pair) { 168 std::unique_ptr<BluetoothRemoteGattCharacteristicMac>>& pair) {
150 return pair.second->IsDiscoveryComplete(); 169 return pair.second->IsDiscoveryComplete();
151 }) == gatt_characteristic_macs_.end(); 170 }) == gatt_characteristic_macs_.end();
152 if (is_discovery_complete_) { 171 if (is_discovery_complete_) {
153 VLOG(1) << *this << ": Discovery complete."; 172 VLOG(1) << *this << ": Discovery complete.";
154 GetMacAdapter()->NotifyGattServiceChanged(this); 173 GetMacAdapter()->NotifyGattServiceChanged(this);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 const BluetoothRemoteGattServiceMac& service) { 240 const BluetoothRemoteGattServiceMac& service) {
222 const BluetoothLowEnergyDeviceMac* bluetooth_device_mac_ = 241 const BluetoothLowEnergyDeviceMac* bluetooth_device_mac_ =
223 static_cast<const BluetoothLowEnergyDeviceMac*>(service.GetDevice()); 242 static_cast<const BluetoothLowEnergyDeviceMac*>(service.GetDevice());
224 return out << "<BluetoothRemoteGattServiceMac " 243 return out << "<BluetoothRemoteGattServiceMac "
225 << service.GetUUID().canonical_value() << "/" << &service 244 << service.GetUUID().canonical_value() << "/" << &service
226 << ", device: " << bluetooth_device_mac_->GetAddress() << "/" 245 << ", device: " << bluetooth_device_mac_->GetAddress() << "/"
227 << bluetooth_device_mac_ << ">"; 246 << bluetooth_device_mac_ << ">";
228 } 247 }
229 248
230 } // namespace device 249 } // namespace device
OLDNEW
« no previous file with comments | « device/bluetooth/bluetooth_remote_gatt_service_mac.h ('k') | device/bluetooth/bluetooth_remote_gatt_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698