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

Side by Side Diff: chromeos/components/tether/ble_advertiser.cc

Issue 2972263002: [CrOS Tether] Do not register a new Bluetooth advertisement until any previous identical advertisem… (Closed)
Patch Set: hansberry@ comment. Created 3 years, 5 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 "chromeos/components/tether/ble_advertiser.h" 5 #include "chromeos/components/tether/ble_advertiser.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "chromeos/components/tether/ble_constants.h" 8 #include "chromeos/components/tether/ble_constants.h"
9 #include "components/cryptauth/local_device_data_provider.h" 9 #include "components/cryptauth/local_device_data_provider.h"
10 #include "components/cryptauth/proto/cryptauth_api.pb.h" 10 #include "components/cryptauth/proto/cryptauth_api.pb.h"
11 #include "components/cryptauth/remote_beacon_seed_fetcher.h" 11 #include "components/cryptauth/remote_beacon_seed_fetcher.h"
12 #include "components/proximity_auth/logging/logging.h" 12 #include "components/proximity_auth/logging/logging.h"
13 #include "device/bluetooth/bluetooth_advertisement.h" 13 #include "device/bluetooth/bluetooth_advertisement.h"
14 14
15 namespace chromeos { 15 namespace chromeos {
16 16
17 namespace tether { 17 namespace tether {
18 18
19 namespace { 19 namespace {
20 20
21 uint8_t kInvertedConnectionFlag = 0x01; 21 uint8_t kInvertedConnectionFlag = 0x01;
22 22
23 } // namespace 23 } // namespace
24 24
25 BleAdvertiser::IndividualAdvertisement::IndividualAdvertisement( 25 BleAdvertiser::IndividualAdvertisement::IndividualAdvertisement(
26 const std::string& device_id, 26 const std::string& device_id,
27 scoped_refptr<device::BluetoothAdapter> adapter, 27 scoped_refptr<device::BluetoothAdapter> adapter,
28 std::unique_ptr<cryptauth::DataWithTimestamp> advertisement_data) 28 std::unique_ptr<cryptauth::DataWithTimestamp> advertisement_data,
29 const base::Closure& on_unregister_advertisement_success_callback,
30 const base::Callback<void(device::BluetoothAdvertisement::ErrorCode)>&
31 on_unregister_advertisement_error_callback,
32 std::unordered_set<std::string>* active_advertisement_device_ids_set)
29 : device_id_(device_id), 33 : device_id_(device_id),
30 adapter_(adapter), 34 adapter_(adapter),
31 advertisement_data_(std::move(advertisement_data)), 35 advertisement_data_(std::move(advertisement_data)),
32 is_initializing_advertising_(false), 36 is_initializing_advertising_(false),
33 advertisement_(nullptr), 37 advertisement_(nullptr),
38 on_unregister_advertisement_success_callback_(
39 on_unregister_advertisement_success_callback),
40 on_unregister_advertisement_error_callback_(
41 on_unregister_advertisement_error_callback),
42 active_advertisement_device_ids_set_(active_advertisement_device_ids_set),
34 weak_ptr_factory_(this) { 43 weak_ptr_factory_(this) {
35 adapter_->AddObserver(this); 44 adapter_->AddObserver(this);
36 AdvertiseIfPossible(); 45 AdvertiseIfPossible();
37 } 46 }
38 47
39 BleAdvertiser::IndividualAdvertisement::~IndividualAdvertisement() { 48 BleAdvertiser::IndividualAdvertisement::~IndividualAdvertisement() {
40 if (advertisement_) { 49 if (advertisement_) {
41 advertisement_->Unregister( 50 advertisement_->Unregister(on_unregister_advertisement_success_callback_,
42 base::Bind(&base::DoNothing), 51 on_unregister_advertisement_error_callback_);
43 base::Bind(&IndividualAdvertisement::OnAdvertisementUnregisterFailure,
44 weak_ptr_factory_.GetWeakPtr()));
45 } 52 }
46 53
47 adapter_->RemoveObserver(this); 54 adapter_->RemoveObserver(this);
48 } 55 }
49 56
57 void BleAdvertiser::IndividualAdvertisement::
58 OnPreviousAdvertisementUnregistered() {
59 DCHECK(active_advertisement_device_ids_set_->find(device_id_) ==
60 active_advertisement_device_ids_set_->end());
61 AdvertiseIfPossible();
62 }
63
50 void BleAdvertiser::IndividualAdvertisement::AdapterPoweredChanged( 64 void BleAdvertiser::IndividualAdvertisement::AdapterPoweredChanged(
51 device::BluetoothAdapter* adapter, 65 device::BluetoothAdapter* adapter,
52 bool powered) { 66 bool powered) {
53 DCHECK(adapter_.get() == adapter); 67 DCHECK(adapter_.get() == adapter);
54 AdvertiseIfPossible(); 68 AdvertiseIfPossible();
55 } 69 }
56 70
57 void BleAdvertiser::IndividualAdvertisement::AdvertisementReleased( 71 void BleAdvertiser::IndividualAdvertisement::AdvertisementReleased(
58 device::BluetoothAdvertisement* advertisement) { 72 device::BluetoothAdvertisement* advertisement) {
59 DCHECK(advertisement_.get() == advertisement); 73 DCHECK(advertisement_.get() == advertisement);
60 74
61 // If the advertisement was released, delete it and try again. Note that this 75 // If the advertisement was released, delete it and try again. Note that this
62 // situation is not expected to occur under normal circumstances. 76 // situation is not expected to occur under normal circumstances.
77 advertisement_->RemoveObserver(this);
63 advertisement_ = nullptr; 78 advertisement_ = nullptr;
79 active_advertisement_device_ids_set_->erase(device_id_);
80
64 AdvertiseIfPossible(); 81 AdvertiseIfPossible();
65 } 82 }
66 83
67 void BleAdvertiser::IndividualAdvertisement::AdvertiseIfPossible() { 84 void BleAdvertiser::IndividualAdvertisement::AdvertiseIfPossible() {
68 if (!adapter_->IsPowered() || is_initializing_advertising_ || 85 if (!adapter_->IsPowered() || is_initializing_advertising_ ||
69 advertisement_) { 86 advertisement_ ||
87 active_advertisement_device_ids_set_->find(device_id_) !=
88 active_advertisement_device_ids_set_->end()) {
89 // It is not possible to advertise if the adapter is not powered. Likewise,
90 // we should not try to advertise if there is an advertisement already in
91 // progress.
70 return; 92 return;
71 } 93 }
72 94
73 is_initializing_advertising_ = true; 95 is_initializing_advertising_ = true;
74 96
75 std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement_data = 97 std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement_data =
76 base::MakeUnique<device::BluetoothAdvertisement::Data>( 98 base::MakeUnique<device::BluetoothAdvertisement::Data>(
77 device::BluetoothAdvertisement::AdvertisementType:: 99 device::BluetoothAdvertisement::AdvertisementType::
78 ADVERTISEMENT_TYPE_BROADCAST); 100 ADVERTISEMENT_TYPE_BROADCAST);
79 advertisement_data->set_service_uuids(CreateServiceUuids()); 101 advertisement_data->set_service_uuids(CreateServiceUuids());
80 advertisement_data->set_service_data(CreateServiceData()); 102 advertisement_data->set_service_data(CreateServiceData());
81 103
82 adapter_->RegisterAdvertisement( 104 adapter_->RegisterAdvertisement(
83 std::move(advertisement_data), 105 std::move(advertisement_data),
84 base::Bind(&IndividualAdvertisement::OnAdvertisementRegisteredCallback, 106 base::Bind(&IndividualAdvertisement::OnAdvertisementRegisteredCallback,
85 weak_ptr_factory_.GetWeakPtr()), 107 weak_ptr_factory_.GetWeakPtr()),
86 base::Bind(&IndividualAdvertisement::OnAdvertisementErrorCallback, 108 base::Bind(&IndividualAdvertisement::OnAdvertisementErrorCallback,
87 weak_ptr_factory_.GetWeakPtr())); 109 weak_ptr_factory_.GetWeakPtr()));
88 } 110 }
89 111
90 void BleAdvertiser::IndividualAdvertisement::OnAdvertisementRegisteredCallback( 112 void BleAdvertiser::IndividualAdvertisement::OnAdvertisementRegisteredCallback(
91 scoped_refptr<device::BluetoothAdvertisement> advertisement) { 113 scoped_refptr<device::BluetoothAdvertisement> advertisement) {
92 is_initializing_advertising_ = false; 114 is_initializing_advertising_ = false;
115
93 advertisement_ = advertisement; 116 advertisement_ = advertisement;
117 advertisement_->AddObserver(this);
118 active_advertisement_device_ids_set_->insert(device_id_);
119
94 PA_LOG(INFO) << "Advertisement registered. " 120 PA_LOG(INFO) << "Advertisement registered. "
95 << "Device ID: \"" 121 << "Device ID: \""
96 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id_) 122 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id_)
97 << "\", Service data: " << advertisement_data_->DataInHex(); 123 << "\", Service data: " << advertisement_data_->DataInHex();
98 } 124 }
99 125
100 void BleAdvertiser::IndividualAdvertisement::OnAdvertisementErrorCallback( 126 void BleAdvertiser::IndividualAdvertisement::OnAdvertisementErrorCallback(
101 device::BluetoothAdvertisement::ErrorCode error_code) { 127 device::BluetoothAdvertisement::ErrorCode error_code) {
102 is_initializing_advertising_ = false; 128 is_initializing_advertising_ = false;
103 PA_LOG(ERROR) << "Error registering advertisement. " 129 PA_LOG(ERROR) << "Error registering advertisement. "
104 << "Device ID: \"" 130 << "Device ID: \""
105 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id_) 131 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id_)
106 << "\", Service data: " << advertisement_data_->DataInHex() 132 << "\", Service data: " << advertisement_data_->DataInHex()
107 << ", Error code: " << error_code; 133 << ", Error code: " << error_code;
108 } 134 }
109 135
110 void BleAdvertiser::IndividualAdvertisement::OnAdvertisementUnregisterFailure(
111 device::BluetoothAdvertisement::ErrorCode error_code) {
112 PA_LOG(ERROR) << "Error unregistering advertisement. "
113 << "Device ID: \""
114 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id_)
115 << "\", Service data: " << advertisement_data_->DataInHex()
116 << " Error code: " << error_code;
117 }
118
119 std::unique_ptr<device::BluetoothAdvertisement::UUIDList> 136 std::unique_ptr<device::BluetoothAdvertisement::UUIDList>
120 BleAdvertiser::IndividualAdvertisement::CreateServiceUuids() const { 137 BleAdvertiser::IndividualAdvertisement::CreateServiceUuids() const {
121 std::unique_ptr<device::BluetoothAdvertisement::UUIDList> list = 138 std::unique_ptr<device::BluetoothAdvertisement::UUIDList> list =
122 base::MakeUnique<device::BluetoothAdvertisement::UUIDList>(); 139 base::MakeUnique<device::BluetoothAdvertisement::UUIDList>();
123 list->push_back(std::string(kAdvertisingServiceUuid)); 140 list->push_back(std::string(kAdvertisingServiceUuid));
124 return list; 141 return list;
125 } 142 }
126 143
127 std::unique_ptr<device::BluetoothAdvertisement::ServiceData> 144 std::unique_ptr<device::BluetoothAdvertisement::ServiceData>
128 BleAdvertiser::IndividualAdvertisement::CreateServiceData() const { 145 BleAdvertiser::IndividualAdvertisement::CreateServiceData() const {
(...skipping 26 matching lines...) Expand all
155 BleAdvertiser::~BleAdvertiser() {} 172 BleAdvertiser::~BleAdvertiser() {}
156 173
157 BleAdvertiser::BleAdvertiser( 174 BleAdvertiser::BleAdvertiser(
158 scoped_refptr<device::BluetoothAdapter> adapter, 175 scoped_refptr<device::BluetoothAdapter> adapter,
159 std::unique_ptr<cryptauth::ForegroundEidGenerator> eid_generator, 176 std::unique_ptr<cryptauth::ForegroundEidGenerator> eid_generator,
160 const cryptauth::RemoteBeaconSeedFetcher* remote_beacon_seed_fetcher, 177 const cryptauth::RemoteBeaconSeedFetcher* remote_beacon_seed_fetcher,
161 const cryptauth::LocalDeviceDataProvider* local_device_data_provider) 178 const cryptauth::LocalDeviceDataProvider* local_device_data_provider)
162 : adapter_(adapter), 179 : adapter_(adapter),
163 eid_generator_(std::move(eid_generator)), 180 eid_generator_(std::move(eid_generator)),
164 remote_beacon_seed_fetcher_(remote_beacon_seed_fetcher), 181 remote_beacon_seed_fetcher_(remote_beacon_seed_fetcher),
165 local_device_data_provider_(local_device_data_provider) {} 182 local_device_data_provider_(local_device_data_provider),
183 weak_ptr_factory_(this) {}
166 184
167 bool BleAdvertiser::StartAdvertisingToDevice( 185 bool BleAdvertiser::StartAdvertisingToDevice(
168 const cryptauth::RemoteDevice& remote_device) { 186 const cryptauth::RemoteDevice& remote_device) {
169 if (device_id_to_advertisement_map_.size() >= kMaxConcurrentAdvertisements) { 187 if (device_id_to_individual_advertisement_map_.size() >=
188 kMaxConcurrentAdvertisements) {
170 PA_LOG(ERROR) << "Attempted to register a device when the maximum number " 189 PA_LOG(ERROR) << "Attempted to register a device when the maximum number "
171 << "of devices have already been registered."; 190 << "of devices have already been registered.";
172 return false; 191 return false;
173 } 192 }
174 193
175 std::string local_device_public_key; 194 std::string local_device_public_key;
176 if (!local_device_data_provider_->GetLocalDeviceData(&local_device_public_key, 195 if (!local_device_data_provider_->GetLocalDeviceData(&local_device_public_key,
177 nullptr)) { 196 nullptr)) {
178 PA_LOG(WARNING) << "Error fetching the local device's public key. Cannot " 197 PA_LOG(WARNING) << "Error fetching the local device's public key. Cannot "
179 << "advertise without the public key."; 198 << "advertise without the public key.";
(...skipping 21 matching lines...) Expand all
201 std::unique_ptr<cryptauth::DataWithTimestamp> advertisement = 220 std::unique_ptr<cryptauth::DataWithTimestamp> advertisement =
202 eid_generator_->GenerateAdvertisement(local_device_public_key, 221 eid_generator_->GenerateAdvertisement(local_device_public_key,
203 remote_beacon_seeds); 222 remote_beacon_seeds);
204 if (!advertisement) { 223 if (!advertisement) {
205 PA_LOG(WARNING) << "Error generating advertisement for device with ID " 224 PA_LOG(WARNING) << "Error generating advertisement for device with ID "
206 << remote_device.GetTruncatedDeviceIdForLogs() << ". " 225 << remote_device.GetTruncatedDeviceIdForLogs() << ". "
207 << "Cannot advertise."; 226 << "Cannot advertise.";
208 return false; 227 return false;
209 } 228 }
210 229
211 device_id_to_advertisement_map_[remote_device.GetDeviceId()] = 230 std::string device_id = remote_device.GetDeviceId();
231 device_id_to_individual_advertisement_map_[device_id] =
212 base::MakeUnique<IndividualAdvertisement>( 232 base::MakeUnique<IndividualAdvertisement>(
213 remote_device.GetDeviceId(), adapter_, std::move(advertisement)); 233 remote_device.GetDeviceId(), adapter_, std::move(advertisement),
234 base::Bind(&BleAdvertiser::OnUnregisterAdvertisementSuccess,
235 weak_ptr_factory_.GetWeakPtr(), device_id),
236 base::Bind(&BleAdvertiser::OnUnregisterAdvertisementError,
237 weak_ptr_factory_.GetWeakPtr(), device_id),
238 &active_advertisement_device_ids_set_);
214 return true; 239 return true;
215 } 240 }
216 241
217 bool BleAdvertiser::StopAdvertisingToDevice( 242 bool BleAdvertiser::StopAdvertisingToDevice(
218 const cryptauth::RemoteDevice& remote_device) { 243 const cryptauth::RemoteDevice& remote_device) {
219 return device_id_to_advertisement_map_.erase(remote_device.GetDeviceId()) > 0; 244 return device_id_to_individual_advertisement_map_.erase(
245 remote_device.GetDeviceId()) > 0;
246 }
247
248 void BleAdvertiser::OnUnregisterAdvertisementSuccess(
249 const std::string& associated_device_id) {
250 RemoveAdvertisingDeviceIdAndRetry(associated_device_id);
251 }
252
253 void BleAdvertiser::OnUnregisterAdvertisementError(
254 const std::string& associated_device_id,
255 device::BluetoothAdvertisement::ErrorCode error_code) {
256 PA_LOG(ERROR) << "Error unregistering advertisement. "
257 << "Device ID: \""
258 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(
259 associated_device_id)
260 << "\", Error code: " << error_code;
261
262 // Even though there was an error unregistering the advertisement, remove it
263 // from the set anyway so that it is possible to try registering the
264 // advertisement again. Note that this situation is not expected to occur
265 // since unregistering an active advertisement should always succeed.
266 RemoveAdvertisingDeviceIdAndRetry(associated_device_id);
267 }
268
269 void BleAdvertiser::RemoveAdvertisingDeviceIdAndRetry(
270 const std::string& device_id) {
271 active_advertisement_device_ids_set_.erase(device_id);
272
273 auto it = device_id_to_individual_advertisement_map_.find(device_id);
274 if (it != device_id_to_individual_advertisement_map_.end())
275 it->second->OnPreviousAdvertisementUnregistered();
220 } 276 }
221 277
222 } // namespace tether 278 } // namespace tether
223 279
224 } // namespace chromeos 280 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/components/tether/ble_advertiser.h ('k') | chromeos/components/tether/ble_advertiser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698