Chromium Code Reviews| 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 |