OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/proximity_auth/bluetooth_connection_finder.h" | 5 #include "components/proximity_auth/bluetooth_connection_finder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
13 #include "components/proximity_auth/remote_device.h" | 13 #include "components/proximity_auth/remote_device.h" |
14 #include "components/proximity_auth/wire_message.h" | 14 #include "components/proximity_auth/wire_message.h" |
15 #include "device/bluetooth/bluetooth_adapter_factory.h" | 15 #include "device/bluetooth/bluetooth_adapter_factory.h" |
16 #include "device/bluetooth/bluetooth_uuid.h" | 16 #include "device/bluetooth/bluetooth_uuid.h" |
17 #include "device/bluetooth/test/mock_bluetooth_adapter.h" | 17 #include "device/bluetooth/test/mock_bluetooth_adapter.h" |
18 #include "device/bluetooth/test/mock_bluetooth_device.h" | |
18 #include "testing/gmock/include/gmock/gmock.h" | 19 #include "testing/gmock/include/gmock/gmock.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
20 | 21 |
21 using testing::_; | 22 using testing::_; |
22 using testing::NiceMock; | 23 using testing::NiceMock; |
23 using testing::Return; | 24 using testing::Return; |
24 using testing::StrictMock; | 25 using testing::StrictMock; |
25 | 26 |
26 namespace proximity_auth { | 27 namespace proximity_auth { |
27 namespace { | 28 namespace { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
73 scoped_ptr<MockConnection> connection(new NiceMock<MockConnection>()); | 74 scoped_ptr<MockConnection> connection(new NiceMock<MockConnection>()); |
74 MockConnection* connection_alias = connection.get(); | 75 MockConnection* connection_alias = connection.get(); |
75 EXPECT_CALL(*this, CreateConnectionProxy()) | 76 EXPECT_CALL(*this, CreateConnectionProxy()) |
76 .WillOnce(Return(connection.release())); | 77 .WillOnce(Return(connection.release())); |
77 return connection_alias; | 78 return connection_alias; |
78 } | 79 } |
79 | 80 |
80 using BluetoothConnectionFinder::AdapterPresentChanged; | 81 using BluetoothConnectionFinder::AdapterPresentChanged; |
81 using BluetoothConnectionFinder::AdapterPoweredChanged; | 82 using BluetoothConnectionFinder::AdapterPoweredChanged; |
82 | 83 |
84 void ClearSeekCallbacks() { | |
85 seek_callback_ = base::Closure(); | |
86 seek_error_callback_ = bluetooth_util::ErrorCallback(); | |
87 } | |
88 | |
89 const base::Closure& seek_callback() { return seek_callback_; } | |
90 const bluetooth_util::ErrorCallback& seek_error_callback() { | |
91 return seek_error_callback_; | |
92 } | |
93 | |
83 protected: | 94 protected: |
95 // BluetoothConnectionFinder: | |
84 scoped_ptr<Connection> CreateConnection() override { | 96 scoped_ptr<Connection> CreateConnection() override { |
85 return make_scoped_ptr(CreateConnectionProxy()); | 97 return make_scoped_ptr(CreateConnectionProxy()); |
86 } | 98 } |
87 | 99 |
100 void SeekDeviceByAddress( | |
101 const std::string& bluetooth_address, | |
102 const base::Closure& callback, | |
103 const bluetooth_util::ErrorCallback& error_callback) override { | |
104 EXPECT_EQ(kBluetoothAddress, bluetooth_address); | |
105 seek_callback_ = callback; | |
106 seek_error_callback_ = error_callback; | |
107 } | |
108 | |
88 private: | 109 private: |
110 base::Closure seek_callback_; | |
111 bluetooth_util::ErrorCallback seek_error_callback_; | |
112 | |
89 DISALLOW_COPY_AND_ASSIGN(MockBluetoothConnectionFinder); | 113 DISALLOW_COPY_AND_ASSIGN(MockBluetoothConnectionFinder); |
90 }; | 114 }; |
91 | 115 |
92 } // namespace | 116 } // namespace |
93 | 117 |
94 class ProximityAuthBluetoothConnectionFinderTest : public testing::Test { | 118 class ProximityAuthBluetoothConnectionFinderTest : public testing::Test { |
95 protected: | 119 protected: |
96 ProximityAuthBluetoothConnectionFinderTest() | 120 ProximityAuthBluetoothConnectionFinderTest() |
97 : adapter_(new NiceMock<device::MockBluetoothAdapter>), | 121 : adapter_(new NiceMock<device::MockBluetoothAdapter>), |
122 bluetooth_device_(new NiceMock<device::MockBluetoothDevice>( | |
123 adapter_.get(), | |
124 device::BluetoothDevice::DEVICE_PHONE, | |
125 kDeviceName, | |
126 kBluetoothAddress, | |
127 true, | |
128 false)), | |
98 connection_callback_(base::Bind( | 129 connection_callback_(base::Bind( |
99 &ProximityAuthBluetoothConnectionFinderTest::OnConnectionFound, | 130 &ProximityAuthBluetoothConnectionFinderTest::OnConnectionFound, |
100 base::Unretained(this))) { | 131 base::Unretained(this))) { |
101 device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_); | 132 device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_); |
102 | 133 |
103 // By default, configure the environment to allow polling. Individual tests | 134 // By default, configure the environment to allow polling. Individual tests |
104 // can override this as needed. | 135 // can override this as needed. |
105 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true)); | 136 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true)); |
106 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true)); | 137 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true)); |
138 ON_CALL(*adapter_, GetDevice(kBluetoothAddress)) | |
139 .WillByDefault(Return(bluetooth_device_.get())); | |
sacomoto
2015/08/10 19:40:28
nit: add a comment that by default the device is k
Tim Song
2015/08/10 22:17:55
Done.
| |
107 } | 140 } |
108 | 141 |
109 MOCK_METHOD1(OnConnectionFoundProxy, void(Connection* connection)); | 142 MOCK_METHOD1(OnConnectionFoundProxy, void(Connection* connection)); |
110 void OnConnectionFound(scoped_ptr<Connection> connection) { | 143 void OnConnectionFound(scoped_ptr<Connection> connection) { |
111 OnConnectionFoundProxy(connection.get()); | 144 OnConnectionFoundProxy(connection.get()); |
112 last_found_connection_ = connection.Pass(); | 145 last_found_connection_ = connection.Pass(); |
113 } | 146 } |
114 | 147 |
115 scoped_refptr<device::MockBluetoothAdapter> adapter_; | 148 scoped_refptr<device::MockBluetoothAdapter> adapter_; |
149 scoped_ptr<device::MockBluetoothDevice> bluetooth_device_; | |
116 ConnectionFinder::ConnectionCallback connection_callback_; | 150 ConnectionFinder::ConnectionCallback connection_callback_; |
117 | 151 |
118 private: | 152 private: |
119 // Save a pointer to the last found connection, to extend its lifetime. | 153 // Save a pointer to the last found connection, to extend its lifetime. |
120 scoped_ptr<Connection> last_found_connection_; | 154 scoped_ptr<Connection> last_found_connection_; |
121 | 155 |
122 base::MessageLoop message_loop_; | 156 base::MessageLoop message_loop_; |
123 }; | 157 }; |
124 | 158 |
125 TEST_F(ProximityAuthBluetoothConnectionFinderTest, | 159 TEST_F(ProximityAuthBluetoothConnectionFinderTest, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 StrictMock<MockBluetoothConnectionFinder> connection_finder; | 191 StrictMock<MockBluetoothConnectionFinder> connection_finder; |
158 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(false)); | 192 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(false)); |
159 connection_finder.Find(connection_callback_); | 193 connection_finder.Find(connection_callback_); |
160 } | 194 } |
161 | 195 |
162 TEST_F(ProximityAuthBluetoothConnectionFinderTest, Find_ConnectionSucceeds) { | 196 TEST_F(ProximityAuthBluetoothConnectionFinderTest, Find_ConnectionSucceeds) { |
163 StrictMock<MockBluetoothConnectionFinder> connection_finder; | 197 StrictMock<MockBluetoothConnectionFinder> connection_finder; |
164 | 198 |
165 MockConnection* connection = connection_finder.ExpectCreateConnection(); | 199 MockConnection* connection = connection_finder.ExpectCreateConnection(); |
166 connection_finder.Find(connection_callback_); | 200 connection_finder.Find(connection_callback_); |
201 EXPECT_TRUE(connection_finder.seek_callback().is_null()); | |
202 EXPECT_TRUE(connection_finder.seek_error_callback().is_null()); | |
167 | 203 |
168 connection->SetStatus(Connection::IN_PROGRESS); | 204 connection->SetStatus(Connection::IN_PROGRESS); |
169 | 205 |
206 base::RunLoop run_loop; | |
170 EXPECT_CALL(*this, OnConnectionFoundProxy(_)); | 207 EXPECT_CALL(*this, OnConnectionFoundProxy(_)); |
171 connection->SetStatus(Connection::CONNECTED); | 208 connection->SetStatus(Connection::CONNECTED); |
209 run_loop.RunUntilIdle(); | |
172 } | 210 } |
173 | 211 |
174 TEST_F(ProximityAuthBluetoothConnectionFinderTest, | 212 TEST_F(ProximityAuthBluetoothConnectionFinderTest, |
175 Find_ConnectionSucceeds_UnregistersAsObserver) { | 213 Find_ConnectionSucceeds_UnregistersAsObserver) { |
176 StrictMock<MockBluetoothConnectionFinder> connection_finder; | 214 StrictMock<MockBluetoothConnectionFinder> connection_finder; |
177 | 215 |
178 MockConnection* connection = connection_finder.ExpectCreateConnection(); | 216 MockConnection* connection = connection_finder.ExpectCreateConnection(); |
179 connection_finder.Find(connection_callback_); | 217 connection_finder.Find(connection_callback_); |
180 | 218 |
181 connection->SetStatus(Connection::IN_PROGRESS); | 219 connection->SetStatus(Connection::IN_PROGRESS); |
182 | 220 |
183 EXPECT_CALL(*this, OnConnectionFoundProxy(_)); | 221 { |
184 EXPECT_CALL(*adapter_, RemoveObserver(&connection_finder)); | 222 base::RunLoop run_loop; |
185 connection->SetStatus(Connection::CONNECTED); | 223 EXPECT_CALL(*this, OnConnectionFoundProxy(_)); |
224 EXPECT_CALL(*adapter_, RemoveObserver(&connection_finder)); | |
225 connection->SetStatus(Connection::CONNECTED); | |
226 run_loop.RunUntilIdle(); | |
227 } | |
186 | 228 |
187 // If for some reason the connection sends more status updates, they should be | 229 { |
188 // ignored. | 230 // If for some reason the connection sends more status updates, they should |
189 EXPECT_CALL(*this, OnConnectionFoundProxy(_)).Times(0); | 231 // be |
sacomoto
2015/08/10 19:40:28
nit: kill the extra line.
Tim Song
2015/08/10 22:17:55
Done.
| |
190 connection->SetStatus(Connection::IN_PROGRESS); | 232 // ignored. |
191 connection->SetStatus(Connection::CONNECTED); | 233 base::RunLoop run_loop; |
234 EXPECT_CALL(*this, OnConnectionFoundProxy(_)).Times(0); | |
235 connection->SetStatus(Connection::IN_PROGRESS); | |
236 connection->SetStatus(Connection::CONNECTED); | |
237 run_loop.RunUntilIdle(); | |
238 } | |
192 } | 239 } |
193 | 240 |
194 TEST_F(ProximityAuthBluetoothConnectionFinderTest, | 241 TEST_F(ProximityAuthBluetoothConnectionFinderTest, |
195 Find_ConnectionFails_PostsTaskToPollAgain) { | 242 Find_ConnectionFails_PostsTaskToPollAgain) { |
196 StrictMock<MockBluetoothConnectionFinder> connection_finder; | 243 StrictMock<MockBluetoothConnectionFinder> connection_finder; |
197 | 244 |
198 MockConnection* connection = connection_finder.ExpectCreateConnection(); | 245 MockConnection* connection = connection_finder.ExpectCreateConnection(); |
199 connection_finder.Find(connection_callback_); | 246 connection_finder.Find(connection_callback_); |
200 | 247 |
201 // Simulate a connection that fails to connect. | 248 // Simulate a connection that fails to connect. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
272 base::RunLoop run_loop; | 319 base::RunLoop run_loop; |
273 run_loop.RunUntilIdle(); | 320 run_loop.RunUntilIdle(); |
274 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true)); | 321 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true)); |
275 | 322 |
276 // Now that there is no pending task, events should once again trigger new | 323 // Now that there is no pending task, events should once again trigger new |
277 // polling iterations. | 324 // polling iterations. |
278 connection_finder.ExpectCreateConnection(); | 325 connection_finder.ExpectCreateConnection(); |
279 connection_finder.AdapterPresentChanged(adapter_.get(), true); | 326 connection_finder.AdapterPresentChanged(adapter_.get(), true); |
280 } | 327 } |
281 | 328 |
329 TEST_F(ProximityAuthBluetoothConnectionFinderTest, | |
330 Find_DeviceNotKnown_SeekDeviceSucceeds) { | |
331 // If the BluetoothDevice is not known by the adapter, |connection_finder| | |
332 // will call SeekDeviceByAddress() first to make it known. | |
333 ON_CALL(*adapter_, GetDevice(kBluetoothAddress)) | |
334 .WillByDefault(Return(nullptr)); | |
335 StrictMock<MockBluetoothConnectionFinder> connection_finder; | |
336 connection_finder.Find(connection_callback_); | |
337 ASSERT_FALSE(connection_finder.seek_callback().is_null()); | |
338 EXPECT_FALSE(connection_finder.seek_error_callback().is_null()); | |
339 | |
340 // After seeking is successful, the normal flow should resume. | |
sacomoto
2015/08/10 19:40:28
optional: you could refactor this in a helper meth
Tim Song
2015/08/10 22:17:55
Done.
| |
341 ON_CALL(*adapter_, GetDevice(kBluetoothAddress)) | |
342 .WillByDefault(Return(bluetooth_device_.get())); | |
343 MockConnection* connection = connection_finder.ExpectCreateConnection(); | |
344 connection_finder.seek_callback().Run(); | |
345 | |
346 connection->SetStatus(Connection::IN_PROGRESS); | |
347 base::RunLoop run_loop; | |
348 EXPECT_CALL(*this, OnConnectionFoundProxy(_)); | |
349 connection->SetStatus(Connection::CONNECTED); | |
350 run_loop.RunUntilIdle(); | |
351 } | |
352 | |
353 TEST_F(ProximityAuthBluetoothConnectionFinderTest, | |
354 Find_DeviceNotKnown_SeekDeviceFailThenSucceeds) { | |
355 // If the BluetoothDevice is not known by the adapter, |connection_finder| | |
356 // will call SeekDeviceByAddress() first to make it known. | |
357 ON_CALL(*adapter_, GetDevice(kBluetoothAddress)) | |
358 .WillByDefault(Return(nullptr)); | |
359 StrictMock<MockBluetoothConnectionFinder> connection_finder; | |
360 connection_finder.Find(connection_callback_); | |
361 EXPECT_FALSE(connection_finder.seek_callback().is_null()); | |
362 ASSERT_FALSE(connection_finder.seek_error_callback().is_null()); | |
363 | |
364 // If the seek fails, then |connection_finder| will post a delayed poll to | |
365 // reattempt the seek. | |
366 connection_finder.seek_error_callback().Run("Seek failed for test."); | |
367 connection_finder.ClearSeekCallbacks(); | |
368 EXPECT_TRUE(connection_finder.seek_callback().is_null()); | |
369 EXPECT_TRUE(connection_finder.seek_error_callback().is_null()); | |
370 | |
371 // Check that seek is reattempted. | |
372 { | |
373 base::RunLoop run_loop; | |
374 run_loop.RunUntilIdle(); | |
375 ASSERT_FALSE(connection_finder.seek_callback().is_null()); | |
376 EXPECT_FALSE(connection_finder.seek_error_callback().is_null()); | |
377 } | |
378 | |
379 // Successfully connect to the Bluetooth device. | |
380 ON_CALL(*adapter_, GetDevice(kBluetoothAddress)) | |
381 .WillByDefault(Return(bluetooth_device_.get())); | |
382 MockConnection* connection = connection_finder.ExpectCreateConnection(); | |
383 connection_finder.seek_callback().Run(); | |
384 | |
385 connection->SetStatus(Connection::IN_PROGRESS); | |
386 { | |
387 base::RunLoop run_loop; | |
388 EXPECT_CALL(*this, OnConnectionFoundProxy(_)); | |
389 connection->SetStatus(Connection::CONNECTED); | |
390 run_loop.RunUntilIdle(); | |
391 } | |
392 } | |
393 | |
282 } // namespace proximity_auth | 394 } // namespace proximity_auth |
OLD | NEW |