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

Side by Side Diff: components/proximity_auth/bluetooth_low_energy_connection_finder_unittest.cc

Issue 2845473002: Revert of [EasyUnlock] Update BluetoothLowEnergyConnectionFinder to look for EIDs. (Closed)
Patch Set: Created 3 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
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/proximity_auth/bluetooth_low_energy_connection_finder.h"
6
7 #include <memory>
8 #include <string>
9 #include <utility>
10
11 #include "base/bind.h"
12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/time/time.h"
19 #include "components/cryptauth/connection.h"
20 #include "components/cryptauth/cryptauth_test_util.h"
21 #include "components/cryptauth/fake_connection.h"
22 #include "components/cryptauth/remote_device.h"
23 #include "components/cryptauth/wire_message.h"
24 #include "components/proximity_auth/logging/logging.h"
25 #include "device/bluetooth/bluetooth_adapter_factory.h"
26 #include "device/bluetooth/bluetooth_uuid.h"
27 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
28 #include "device/bluetooth/test/mock_bluetooth_device.h"
29 #include "device/bluetooth/test/mock_bluetooth_discovery_session.h"
30 #include "device/bluetooth/test/mock_bluetooth_gatt_connection.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33
34 using testing::_;
35 using testing::AtLeast;
36 using testing::NiceMock;
37 using testing::Return;
38 using testing::StrictMock;
39 using testing::SaveArg;
40
41 using device::BluetoothDevice;
42 using device::MockBluetoothDevice;
43
44 namespace proximity_auth {
45 namespace {
46
47 const char kAdvertisementUUID[] = "0000fe50-0000-1000-8000-00805f9b34fb";
48 const int8_t kRssi = -30;
49 const char kEidForPreviousTimeQuantum[] = "\x12\x34";
50 const char kEidForCurrentTimeQuantum[] = "\xab\xcd";
51 const char kEidForNextTimeQuantum[] = "\x56\x78";
52 const char kWrongEid[] = "\xff\xff";
53
54 std::vector<cryptauth::BeaconSeed> CreateBeaconSeeds() {
55 std::vector<cryptauth::BeaconSeed> beacon_seeds;
56 cryptauth::BeaconSeed seed;
57 seed.set_data("\xab\xcd");
58 seed.set_start_time_millis(0);
59 seed.set_end_time_millis(10000000);
60 beacon_seeds.push_back(seed);
61 return beacon_seeds;
62 }
63
64 class MockBluetoothLowEnergyConnectionFinder;
65 class FakeEidGenerator : public cryptauth::BackgroundEidGenerator {
66 public:
67 FakeEidGenerator(MockBluetoothLowEnergyConnectionFinder* connection_finder)
68 : connection_finder_(connection_finder) {}
69 ~FakeEidGenerator() override {}
70
71 std::vector<std::string> GenerateNearestEids(
72 const std::vector<cryptauth::BeaconSeed>& beacon_seed) const override;
73
74 private:
75 MockBluetoothLowEnergyConnectionFinder* connection_finder_;
76
77 DISALLOW_COPY_AND_ASSIGN(FakeEidGenerator);
78 };
79
80 class MockBluetoothLowEnergyConnectionFinder
81 : public BluetoothLowEnergyConnectionFinder {
82 public:
83 MockBluetoothLowEnergyConnectionFinder()
84 : BluetoothLowEnergyConnectionFinder(
85 cryptauth::CreateLERemoteDeviceForTest(),
86 CreateBeaconSeeds(),
87 base::MakeUnique<FakeEidGenerator>(this),
88 nullptr) {}
89
90 ~MockBluetoothLowEnergyConnectionFinder() override {}
91
92 // Mock methods don't support return type std::unique_ptr<>. This is a
93 // possible workaround: mock a proxy method to be called by the target
94 // overridden method (CreateConnection).
95 MOCK_METHOD0(CreateConnectionProxy, cryptauth::Connection*());
96
97 // Creates a mock connection and sets an expectation that the mock connection
98 // finder's CreateConnection() method will be called and will return the
99 // created connection. Returns a reference to the created connection.
100 // NOTE: The returned connection's lifetime is managed by the connection
101 // finder.
102 cryptauth::FakeConnection* ExpectCreateConnection() {
103 std::unique_ptr<cryptauth::FakeConnection> connection(
104 new cryptauth::FakeConnection(
105 cryptauth::CreateLERemoteDeviceForTest()));
106 cryptauth::FakeConnection* connection_alias = connection.get();
107 EXPECT_CALL(*this, CreateConnectionProxy())
108 .WillOnce(Return(connection.release()));
109 return connection_alias;
110 }
111
112 void SetNearestEids(const std::vector<std::string>& eids) {
113 nearest_eids_ = eids;
114 }
115
116 const std::vector<std::string>& nearest_eids() { return nearest_eids_; }
117
118 protected:
119 std::unique_ptr<cryptauth::Connection> CreateConnection(
120 const std::string& device_address) override {
121 return base::WrapUnique(CreateConnectionProxy());
122 }
123
124 private:
125 std::vector<std::string> nearest_eids_;
126
127 DISALLOW_COPY_AND_ASSIGN(MockBluetoothLowEnergyConnectionFinder);
128 };
129
130 // Not declared in-line due to dependency on
131 // MockBluetoothLowEnergyConnectionFinder.
132 std::vector<std::string> FakeEidGenerator::GenerateNearestEids(
133 const std::vector<cryptauth::BeaconSeed>& beacon_seed) const {
134 return connection_finder_->nearest_eids();
135 }
136
137 } // namespace
138
139 class ProximityAuthBluetoothLowEnergyConnectionFinderTest
140 : public testing::Test {
141 protected:
142 ProximityAuthBluetoothLowEnergyConnectionFinderTest()
143 : adapter_(new NiceMock<device::MockBluetoothAdapter>),
144 connection_callback_(
145 base::Bind(&ProximityAuthBluetoothLowEnergyConnectionFinderTest::
146 OnConnectionFound,
147 base::Unretained(this))),
148 device_(new NiceMock<device::MockBluetoothDevice>(
149 adapter_.get(),
150 0,
151 cryptauth::kTestRemoteDeviceName,
152 cryptauth::kTestRemoteDeviceBluetoothAddress,
153 false,
154 false)),
155 last_discovery_session_alias_(nullptr) {
156 device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
157
158 std::vector<const device::BluetoothDevice*> devices;
159 ON_CALL(*adapter_, GetDevices()).WillByDefault(Return(devices));
160
161 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true));
162 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true));
163
164 std::vector<std::string> nearest_eids;
165 nearest_eids.push_back(kEidForPreviousTimeQuantum);
166 nearest_eids.push_back(kEidForCurrentTimeQuantum);
167 nearest_eids.push_back(kEidForNextTimeQuantum);
168 connection_finder_.SetNearestEids(nearest_eids);
169 }
170
171 void OnConnectionFound(std::unique_ptr<cryptauth::Connection> connection) {
172 last_found_connection_ = std::move(connection);
173 }
174
175 void FindAndExpectStartDiscovery() {
176 device::BluetoothAdapter::DiscoverySessionCallback discovery_callback;
177 std::unique_ptr<device::MockBluetoothDiscoverySession> discovery_session(
178 new NiceMock<device::MockBluetoothDiscoverySession>());
179 last_discovery_session_alias_ = discovery_session.get();
180
181 // Starting a discovery session. StartDiscoveryWithFilterRaw is a proxy for
182 // StartDiscoveryWithFilter.
183 EXPECT_CALL(*adapter_, StartDiscoverySessionWithFilterRaw(_, _, _))
184 .WillOnce(SaveArg<1>(&discovery_callback));
185 EXPECT_CALL(*adapter_, AddObserver(_));
186 ON_CALL(*last_discovery_session_alias_, IsActive())
187 .WillByDefault(Return(true));
188 connection_finder_.Find(connection_callback_);
189 ASSERT_FALSE(discovery_callback.is_null());
190 discovery_callback.Run(std::move(discovery_session));
191
192 EXPECT_CALL(*adapter_, RemoveObserver(_)).Times(AtLeast(1));
193 }
194
195 // Prepare |device_| with the given EID.
196 void PrepareDevice(const std::string& eid) {
197 PrepareDevice(device_.get(), eid);
198 }
199
200 void PrepareDevice(MockBluetoothDevice* device, const std::string& eid) {
201 device::BluetoothUUID advertisement_uuid(kAdvertisementUUID);
202 std::vector<uint8_t> eid_vector(eid.c_str(), eid.c_str() + eid.length());
203 device::BluetoothDevice::UUIDList uuid_list;
204 uuid_list.push_back(advertisement_uuid);
205 device::BluetoothDevice::ServiceDataMap service_data_map;
206 service_data_map[advertisement_uuid] = eid_vector;
207
208 device_->UpdateAdvertisementData(kRssi, uuid_list, service_data_map,
209 nullptr);
210 }
211
212 scoped_refptr<device::MockBluetoothAdapter> adapter_;
213 cryptauth::ConnectionFinder::ConnectionCallback connection_callback_;
214 std::unique_ptr<device::MockBluetoothDevice> device_;
215 std::unique_ptr<cryptauth::Connection> last_found_connection_;
216 device::MockBluetoothDiscoverySession* last_discovery_session_alias_;
217 StrictMock<MockBluetoothLowEnergyConnectionFinder> connection_finder_;
218
219 private:
220 base::MessageLoop message_loop_;
221 };
222
223 TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
224 Find_StartsDiscoverySession) {
225 EXPECT_CALL(*adapter_, StartDiscoverySessionWithFilterRaw(_, _, _));
226 EXPECT_CALL(*adapter_, AddObserver(_));
227 connection_finder_.Find(connection_callback_);
228 }
229
230 TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
231 Find_StopsDiscoverySessionBeforeDestroying) {
232 device::BluetoothAdapter::DiscoverySessionCallback discovery_callback;
233 std::unique_ptr<device::MockBluetoothDiscoverySession> discovery_session(
234 new NiceMock<device::MockBluetoothDiscoverySession>());
235 device::MockBluetoothDiscoverySession* discovery_session_alias =
236 discovery_session.get();
237
238 EXPECT_CALL(*adapter_, StartDiscoverySessionWithFilterRaw(_, _, _))
239 .WillOnce(SaveArg<1>(&discovery_callback));
240 ON_CALL(*discovery_session_alias, IsActive()).WillByDefault(Return(true));
241 EXPECT_CALL(*adapter_, AddObserver(_));
242 connection_finder_.Find(connection_callback_);
243
244 ASSERT_FALSE(discovery_callback.is_null());
245 discovery_callback.Run(std::move(discovery_session));
246
247 EXPECT_CALL(*adapter_, RemoveObserver(_));
248 }
249
250 TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
251 Find_DeviceAdded_EidMatches) {
252 FindAndExpectStartDiscovery();
253
254 connection_finder_.ExpectCreateConnection();
255 PrepareDevice(kEidForCurrentTimeQuantum);
256 connection_finder_.DeviceAdded(adapter_.get(), device_.get());
257 }
258
259 TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
260 Find_DeviceChanged_EidMatches) {
261 FindAndExpectStartDiscovery();
262
263 connection_finder_.DeviceAdded(adapter_.get(), device_.get());
264
265 connection_finder_.ExpectCreateConnection();
266 PrepareDevice(kEidForPreviousTimeQuantum);
267 connection_finder_.DeviceChanged(adapter_.get(), device_.get());
268 }
269
270 TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
271 Find_DeviceAdded_EidDoesNotMatch) {
272 FindAndExpectStartDiscovery();
273
274 PrepareDevice(kWrongEid);
275
276 EXPECT_CALL(connection_finder_, CreateConnectionProxy()).Times(0);
277 connection_finder_.DeviceAdded(adapter_.get(), device_.get());
278 }
279
280 TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
281 Find_DeviceChanged_EidDoesNotMatch) {
282 FindAndExpectStartDiscovery();
283
284 PrepareDevice(kWrongEid);
285 connection_finder_.DeviceAdded(adapter_.get(), device_.get());
286
287 EXPECT_CALL(connection_finder_, CreateConnectionProxy()).Times(0);
288 connection_finder_.DeviceChanged(adapter_.get(), device_.get());
289 }
290
291 TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
292 Find_CreatesOnlyOneConnection) {
293 FindAndExpectStartDiscovery();
294
295 // Prepare first device with valid EID.
296 PrepareDevice(kEidForCurrentTimeQuantum);
297
298 // Prepare second device with valid EID.
299 NiceMock<device::MockBluetoothDevice> other_device(
300 adapter_.get(), 0, cryptauth::kTestRemoteDeviceName,
301 cryptauth::kTestRemoteDeviceBluetoothAddress, false, false);
302 PrepareDevice(&other_device, kEidForPreviousTimeQuantum);
303
304 // Add the devices. Only one connection is expected.
305 connection_finder_.ExpectCreateConnection();
306 connection_finder_.DeviceAdded(adapter_.get(), device_.get());
307 connection_finder_.DeviceAdded(adapter_.get(), &other_device);
308 }
309
310 TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
311 Find_EidMatches_ConnectionSucceeds) {
312 // Starting discovery.
313 FindAndExpectStartDiscovery();
314
315 // Finding and creating a connection to the right device.
316 cryptauth::FakeConnection* connection =
317 connection_finder_.ExpectCreateConnection();
318 PrepareDevice(kEidForCurrentTimeQuantum);
319 connection_finder_.DeviceAdded(adapter_.get(), device_.get());
320
321 // Creating a connection.
322 base::RunLoop run_loop;
323 EXPECT_FALSE(last_found_connection_);
324 connection->SetStatus(cryptauth::Connection::IN_PROGRESS);
325 connection->SetStatus(cryptauth::Connection::CONNECTED);
326 run_loop.RunUntilIdle();
327 EXPECT_TRUE(last_found_connection_);
328 }
329
330 TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
331 Find_ConnectionFails_RestartDiscoveryAndConnectionSucceeds) {
332 // Starting discovery.
333 FindAndExpectStartDiscovery();
334
335 // Preparing to create a GATT connection to the right device.
336 PrepareDevice(kEidForNextTimeQuantum);
337 cryptauth::FakeConnection* connection =
338 connection_finder_.ExpectCreateConnection();
339
340 // Trying to create a connection.
341 connection_finder_.DeviceAdded(adapter_.get(), device_.get());
342 ASSERT_FALSE(last_found_connection_);
343 connection->SetStatus(cryptauth::Connection::IN_PROGRESS);
344
345 // Preparing to restart the discovery session.
346 device::BluetoothAdapter::DiscoverySessionCallback discovery_callback;
347 std::vector<const device::BluetoothDevice*> devices;
348 ON_CALL(*adapter_, GetDevices()).WillByDefault(Return(devices));
349 EXPECT_CALL(*adapter_, StartDiscoverySessionWithFilterRaw(_, _, _))
350 .WillOnce(SaveArg<1>(&discovery_callback));
351
352 // Connection fails.
353 {
354 base::RunLoop run_loop;
355 connection->SetStatus(cryptauth::Connection::DISCONNECTED);
356 run_loop.RunUntilIdle();
357 }
358
359 // Restarting the discovery session.
360 std::unique_ptr<device::MockBluetoothDiscoverySession> discovery_session(
361 new NiceMock<device::MockBluetoothDiscoverySession>());
362 last_discovery_session_alias_ = discovery_session.get();
363 ON_CALL(*last_discovery_session_alias_, IsActive())
364 .WillByDefault(Return(true));
365 ASSERT_FALSE(discovery_callback.is_null());
366 discovery_callback.Run(std::move(discovery_session));
367
368 // Connect again.
369 PrepareDevice(kEidForNextTimeQuantum);
370 connection = connection_finder_.ExpectCreateConnection();
371 connection_finder_.DeviceAdded(adapter_.get(), device_.get());
372
373 // Completing the connection.
374 {
375 base::RunLoop run_loop;
376 EXPECT_FALSE(last_found_connection_);
377 connection->SetStatus(cryptauth::Connection::IN_PROGRESS);
378 connection->SetStatus(cryptauth::Connection::CONNECTED);
379 run_loop.RunUntilIdle();
380 }
381 EXPECT_TRUE(last_found_connection_);
382 }
383
384 TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
385 Find_AdapterRemoved_RestartDiscoveryAndConnectionSucceeds) {
386 // Starting discovery.
387 FindAndExpectStartDiscovery();
388
389 // Removing the adapter.
390 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(false));
391 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(false));
392 ON_CALL(*last_discovery_session_alias_, IsActive())
393 .WillByDefault(Return(false));
394 connection_finder_.AdapterPoweredChanged(adapter_.get(), false);
395 connection_finder_.AdapterPresentChanged(adapter_.get(), false);
396
397 // Adding the adapter.
398 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true));
399 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true));
400
401 device::BluetoothAdapter::DiscoverySessionCallback discovery_callback;
402 std::unique_ptr<device::MockBluetoothDiscoverySession> discovery_session(
403 new NiceMock<device::MockBluetoothDiscoverySession>());
404 last_discovery_session_alias_ = discovery_session.get();
405
406 // Restarting the discovery session.
407 EXPECT_CALL(*adapter_, StartDiscoverySessionWithFilterRaw(_, _, _))
408 .WillOnce(SaveArg<1>(&discovery_callback));
409 connection_finder_.AdapterPresentChanged(adapter_.get(), true);
410 connection_finder_.AdapterPoweredChanged(adapter_.get(), true);
411 ON_CALL(*last_discovery_session_alias_, IsActive())
412 .WillByDefault(Return(true));
413
414 ASSERT_FALSE(discovery_callback.is_null());
415 discovery_callback.Run(std::move(discovery_session));
416
417 // Preparing to create a GATT connection to the right device.
418 PrepareDevice(kEidForPreviousTimeQuantum);
419 cryptauth::FakeConnection* connection =
420 connection_finder_.ExpectCreateConnection();
421
422 // Trying to create a connection.
423 connection_finder_.DeviceAdded(adapter_.get(), device_.get());
424
425 // Completing the connection.
426 base::RunLoop run_loop;
427 ASSERT_FALSE(last_found_connection_);
428 connection->SetStatus(cryptauth::Connection::IN_PROGRESS);
429 connection->SetStatus(cryptauth::Connection::CONNECTED);
430 run_loop.RunUntilIdle();
431 EXPECT_TRUE(last_found_connection_);
432 }
433
434 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698