| 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/proximity_auth_test_util.h" |
| 13 #include "components/proximity_auth/remote_device.h" | 14 #include "components/proximity_auth/remote_device.h" |
| 14 #include "components/proximity_auth/wire_message.h" | 15 #include "components/proximity_auth/wire_message.h" |
| 15 #include "device/bluetooth/bluetooth_adapter_factory.h" | 16 #include "device/bluetooth/bluetooth_adapter_factory.h" |
| 16 #include "device/bluetooth/bluetooth_uuid.h" | 17 #include "device/bluetooth/bluetooth_uuid.h" |
| 17 #include "device/bluetooth/test/mock_bluetooth_adapter.h" | 18 #include "device/bluetooth/test/mock_bluetooth_adapter.h" |
| 18 #include "device/bluetooth/test/mock_bluetooth_device.h" | 19 #include "device/bluetooth/test/mock_bluetooth_device.h" |
| 19 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 22 |
| 22 using testing::_; | 23 using testing::_; |
| 23 using testing::NiceMock; | 24 using testing::NiceMock; |
| 24 using testing::Return; | 25 using testing::Return; |
| 25 using testing::StrictMock; | 26 using testing::StrictMock; |
| 26 | 27 |
| 27 namespace proximity_auth { | 28 namespace proximity_auth { |
| 28 namespace { | 29 namespace { |
| 29 | 30 |
| 30 const char kDeviceName[] = "Device name"; | |
| 31 const char kPublicKey[] = "Public key"; | |
| 32 const char kBluetoothAddress[] = "11:22:33:44:55:66"; | |
| 33 const char kPersistentSymmetricKey[] = "PSK"; | |
| 34 | |
| 35 const char kUuid[] = "DEADBEEF-CAFE-FEED-FOOD-D15EA5EBEEF"; | 31 const char kUuid[] = "DEADBEEF-CAFE-FEED-FOOD-D15EA5EBEEF"; |
| 36 | 32 |
| 37 RemoteDevice CreateRemoteDevice() { | |
| 38 return RemoteDevice(kDeviceName, kPublicKey, kBluetoothAddress, | |
| 39 kPersistentSymmetricKey); | |
| 40 } | |
| 41 | |
| 42 class MockConnection : public Connection { | 33 class MockConnection : public Connection { |
| 43 public: | 34 public: |
| 44 MockConnection() : Connection(CreateRemoteDevice()), do_not_destroy_(false) {} | 35 MockConnection() |
| 36 : Connection(CreateClassicRemoteDeviceForTest()), |
| 37 do_not_destroy_(false) {} |
| 45 ~MockConnection() override { EXPECT_FALSE(do_not_destroy_); } | 38 ~MockConnection() override { EXPECT_FALSE(do_not_destroy_); } |
| 46 | 39 |
| 47 MOCK_METHOD0(Connect, void()); | 40 MOCK_METHOD0(Connect, void()); |
| 48 | 41 |
| 49 void SetStatus(Connection::Status status) { | 42 void SetStatus(Connection::Status status) { |
| 50 // This object should not be destroyed after setting the status and calling | 43 // This object should not be destroyed after setting the status and calling |
| 51 // observers. | 44 // observers. |
| 52 do_not_destroy_ = true; | 45 do_not_destroy_ = true; |
| 53 Connection::SetStatus(status); | 46 Connection::SetStatus(status); |
| 54 do_not_destroy_ = false; | 47 do_not_destroy_ = false; |
| 55 } | 48 } |
| 56 | 49 |
| 57 private: | 50 private: |
| 58 void Disconnect() override {} | 51 void Disconnect() override {} |
| 59 void SendMessageImpl(scoped_ptr<WireMessage> message) override {} | 52 void SendMessageImpl(scoped_ptr<WireMessage> message) override {} |
| 60 | 53 |
| 61 // If true, we do not expect |this| object to be destroyed until this value is | 54 // If true, we do not expect |this| object to be destroyed until this value is |
| 62 // toggled back to false. | 55 // toggled back to false. |
| 63 bool do_not_destroy_; | 56 bool do_not_destroy_; |
| 64 | 57 |
| 65 DISALLOW_COPY_AND_ASSIGN(MockConnection); | 58 DISALLOW_COPY_AND_ASSIGN(MockConnection); |
| 66 }; | 59 }; |
| 67 | 60 |
| 68 class MockBluetoothConnectionFinder : public BluetoothConnectionFinder { | 61 class MockBluetoothConnectionFinder : public BluetoothConnectionFinder { |
| 69 public: | 62 public: |
| 70 MockBluetoothConnectionFinder() | 63 MockBluetoothConnectionFinder() |
| 71 : BluetoothConnectionFinder(CreateRemoteDevice(), | 64 : BluetoothConnectionFinder(CreateClassicRemoteDeviceForTest(), |
| 72 device::BluetoothUUID(kUuid), | 65 device::BluetoothUUID(kUuid), |
| 73 base::TimeDelta()) {} | 66 base::TimeDelta()) {} |
| 74 ~MockBluetoothConnectionFinder() override {} | 67 ~MockBluetoothConnectionFinder() override {} |
| 75 | 68 |
| 76 MOCK_METHOD0(CreateConnectionProxy, Connection*()); | 69 MOCK_METHOD0(CreateConnectionProxy, Connection*()); |
| 77 | 70 |
| 78 // Creates a mock connection and sets an expectation that the mock connection | 71 // Creates a mock connection and sets an expectation that the mock connection |
| 79 // finder's CreateConnection() method will be called and will return the | 72 // finder's CreateConnection() method will be called and will return the |
| 80 // created connection. Returns a reference to the created connection. | 73 // created connection. Returns a reference to the created connection. |
| 81 // NOTE: The returned connection's lifetime is managed by the connection | 74 // NOTE: The returned connection's lifetime is managed by the connection |
| (...skipping 22 matching lines...) Expand all Loading... |
| 104 protected: | 97 protected: |
| 105 // BluetoothConnectionFinder: | 98 // BluetoothConnectionFinder: |
| 106 scoped_ptr<Connection> CreateConnection() override { | 99 scoped_ptr<Connection> CreateConnection() override { |
| 107 return make_scoped_ptr(CreateConnectionProxy()); | 100 return make_scoped_ptr(CreateConnectionProxy()); |
| 108 } | 101 } |
| 109 | 102 |
| 110 void SeekDeviceByAddress( | 103 void SeekDeviceByAddress( |
| 111 const std::string& bluetooth_address, | 104 const std::string& bluetooth_address, |
| 112 const base::Closure& callback, | 105 const base::Closure& callback, |
| 113 const bluetooth_util::ErrorCallback& error_callback) override { | 106 const bluetooth_util::ErrorCallback& error_callback) override { |
| 114 EXPECT_EQ(kBluetoothAddress, bluetooth_address); | 107 EXPECT_EQ(kTestRemoteDeviceBluetoothAddress, bluetooth_address); |
| 115 seek_callback_ = callback; | 108 seek_callback_ = callback; |
| 116 seek_error_callback_ = error_callback; | 109 seek_error_callback_ = error_callback; |
| 117 } | 110 } |
| 118 | 111 |
| 119 private: | 112 private: |
| 120 base::Closure seek_callback_; | 113 base::Closure seek_callback_; |
| 121 bluetooth_util::ErrorCallback seek_error_callback_; | 114 bluetooth_util::ErrorCallback seek_error_callback_; |
| 122 | 115 |
| 123 DISALLOW_COPY_AND_ASSIGN(MockBluetoothConnectionFinder); | 116 DISALLOW_COPY_AND_ASSIGN(MockBluetoothConnectionFinder); |
| 124 }; | 117 }; |
| 125 | 118 |
| 126 } // namespace | 119 } // namespace |
| 127 | 120 |
| 128 class ProximityAuthBluetoothConnectionFinderTest : public testing::Test { | 121 class ProximityAuthBluetoothConnectionFinderTest : public testing::Test { |
| 129 protected: | 122 protected: |
| 130 ProximityAuthBluetoothConnectionFinderTest() | 123 ProximityAuthBluetoothConnectionFinderTest() |
| 131 : adapter_(new NiceMock<device::MockBluetoothAdapter>), | 124 : adapter_(new NiceMock<device::MockBluetoothAdapter>), |
| 132 bluetooth_device_(new NiceMock<device::MockBluetoothDevice>( | 125 bluetooth_device_(new NiceMock<device::MockBluetoothDevice>( |
| 133 adapter_.get(), | 126 adapter_.get(), |
| 134 device::BluetoothDevice::DEVICE_PHONE, | 127 device::BluetoothDevice::DEVICE_PHONE, |
| 135 kDeviceName, | 128 kTestRemoteDeviceName, |
| 136 kBluetoothAddress, | 129 kTestRemoteDeviceBluetoothAddress, |
| 137 true, | 130 true, |
| 138 false)), | 131 false)), |
| 139 connection_callback_(base::Bind( | 132 connection_callback_(base::Bind( |
| 140 &ProximityAuthBluetoothConnectionFinderTest::OnConnectionFound, | 133 &ProximityAuthBluetoothConnectionFinderTest::OnConnectionFound, |
| 141 base::Unretained(this))) { | 134 base::Unretained(this))) { |
| 142 device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_); | 135 device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_); |
| 143 | 136 |
| 144 // By default, configure the environment to allow polling. Individual tests | 137 // By default, configure the environment to allow polling. Individual tests |
| 145 // can override this as needed. | 138 // can override this as needed. |
| 146 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true)); | 139 ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true)); |
| 147 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true)); | 140 ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true)); |
| 148 | 141 |
| 149 // By default, the remote device is known to |adapter_| so | 142 // By default, the remote device is known to |adapter_| so |
| 150 // |SeekDeviceByAddress()| will not be called. | 143 // |SeekDeviceByAddress()| will not be called. |
| 151 ON_CALL(*adapter_, GetDevice(kBluetoothAddress)) | 144 ON_CALL(*adapter_, GetDevice(kTestRemoteDeviceBluetoothAddress)) |
| 152 .WillByDefault(Return(bluetooth_device_.get())); | 145 .WillByDefault(Return(bluetooth_device_.get())); |
| 153 } | 146 } |
| 154 | 147 |
| 155 MOCK_METHOD1(OnConnectionFoundProxy, void(Connection* connection)); | 148 MOCK_METHOD1(OnConnectionFoundProxy, void(Connection* connection)); |
| 156 void OnConnectionFound(scoped_ptr<Connection> connection) { | 149 void OnConnectionFound(scoped_ptr<Connection> connection) { |
| 157 OnConnectionFoundProxy(connection.get()); | 150 OnConnectionFoundProxy(connection.get()); |
| 158 last_found_connection_ = connection.Pass(); | 151 last_found_connection_ = connection.Pass(); |
| 159 } | 152 } |
| 160 | 153 |
| 161 // Starts |connection_finder_|. If |expect_connection| is true, then we set an | 154 // Starts |connection_finder_|. If |expect_connection| is true, then we set an |
| (...skipping 26 matching lines...) Expand all Loading... |
| 188 scoped_ptr<Connection> last_found_connection_; | 181 scoped_ptr<Connection> last_found_connection_; |
| 189 | 182 |
| 190 base::MessageLoop message_loop_; | 183 base::MessageLoop message_loop_; |
| 191 }; | 184 }; |
| 192 | 185 |
| 193 TEST_F(ProximityAuthBluetoothConnectionFinderTest, | 186 TEST_F(ProximityAuthBluetoothConnectionFinderTest, |
| 194 ConstructAndDestroyDoesntCrash) { | 187 ConstructAndDestroyDoesntCrash) { |
| 195 // Destroying a BluetoothConnectionFinder for which Find() has not been called | 188 // Destroying a BluetoothConnectionFinder for which Find() has not been called |
| 196 // should not crash. | 189 // should not crash. |
| 197 BluetoothConnectionFinder connection_finder( | 190 BluetoothConnectionFinder connection_finder( |
| 198 CreateRemoteDevice(), device::BluetoothUUID(kUuid), | 191 CreateClassicRemoteDeviceForTest(), device::BluetoothUUID(kUuid), |
| 199 base::TimeDelta::FromMilliseconds(1)); | 192 base::TimeDelta::FromMilliseconds(1)); |
| 200 } | 193 } |
| 201 | 194 |
| 202 TEST_F(ProximityAuthBluetoothConnectionFinderTest, Find_NoBluetoothAdapter) { | 195 TEST_F(ProximityAuthBluetoothConnectionFinderTest, Find_NoBluetoothAdapter) { |
| 203 // Some platforms do not support Bluetooth. This test is only meaningful on | 196 // Some platforms do not support Bluetooth. This test is only meaningful on |
| 204 // those platforms. | 197 // those platforms. |
| 205 adapter_ = NULL; | 198 adapter_ = NULL; |
| 206 if (device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) | 199 if (device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) |
| 207 return; | 200 return; |
| 208 | 201 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 // Now that there is no pending task, events should once again trigger new | 308 // Now that there is no pending task, events should once again trigger new |
| 316 // polling iterations. | 309 // polling iterations. |
| 317 connection_finder_.ExpectCreateConnection(); | 310 connection_finder_.ExpectCreateConnection(); |
| 318 connection_finder_.AdapterPresentChanged(adapter_.get(), true); | 311 connection_finder_.AdapterPresentChanged(adapter_.get(), true); |
| 319 } | 312 } |
| 320 | 313 |
| 321 TEST_F(ProximityAuthBluetoothConnectionFinderTest, | 314 TEST_F(ProximityAuthBluetoothConnectionFinderTest, |
| 322 Find_DeviceNotKnown_SeekDeviceSucceeds) { | 315 Find_DeviceNotKnown_SeekDeviceSucceeds) { |
| 323 // If the BluetoothDevice is not known by the adapter, |connection_finder| | 316 // If the BluetoothDevice is not known by the adapter, |connection_finder| |
| 324 // will call SeekDeviceByAddress() first to make it known. | 317 // will call SeekDeviceByAddress() first to make it known. |
| 325 ON_CALL(*adapter_, GetDevice(kBluetoothAddress)) | 318 ON_CALL(*adapter_, GetDevice(kTestRemoteDeviceBluetoothAddress)) |
| 326 .WillByDefault(Return(nullptr)); | 319 .WillByDefault(Return(nullptr)); |
| 327 connection_finder_.Find(connection_callback_); | 320 connection_finder_.Find(connection_callback_); |
| 328 ASSERT_FALSE(connection_finder_.seek_callback().is_null()); | 321 ASSERT_FALSE(connection_finder_.seek_callback().is_null()); |
| 329 EXPECT_FALSE(connection_finder_.seek_error_callback().is_null()); | 322 EXPECT_FALSE(connection_finder_.seek_error_callback().is_null()); |
| 330 | 323 |
| 331 // After seeking is successful, the normal flow should resume. | 324 // After seeking is successful, the normal flow should resume. |
| 332 ON_CALL(*adapter_, GetDevice(kBluetoothAddress)) | 325 ON_CALL(*adapter_, GetDevice(kTestRemoteDeviceBluetoothAddress)) |
| 333 .WillByDefault(Return(bluetooth_device_.get())); | 326 .WillByDefault(Return(bluetooth_device_.get())); |
| 334 MockConnection* connection = connection_finder_.ExpectCreateConnection(); | 327 MockConnection* connection = connection_finder_.ExpectCreateConnection(); |
| 335 connection_finder_.seek_callback().Run(); | 328 connection_finder_.seek_callback().Run(); |
| 336 SimulateDeviceConnection(connection); | 329 SimulateDeviceConnection(connection); |
| 337 } | 330 } |
| 338 | 331 |
| 339 TEST_F(ProximityAuthBluetoothConnectionFinderTest, | 332 TEST_F(ProximityAuthBluetoothConnectionFinderTest, |
| 340 Find_DeviceNotKnown_SeekDeviceFailThenSucceeds) { | 333 Find_DeviceNotKnown_SeekDeviceFailThenSucceeds) { |
| 341 // If the BluetoothDevice is not known by the adapter, |connection_finder| | 334 // If the BluetoothDevice is not known by the adapter, |connection_finder| |
| 342 // will call SeekDeviceByAddress() first to make it known. | 335 // will call SeekDeviceByAddress() first to make it known. |
| 343 ON_CALL(*adapter_, GetDevice(kBluetoothAddress)) | 336 ON_CALL(*adapter_, GetDevice(kTestRemoteDeviceBluetoothAddress)) |
| 344 .WillByDefault(Return(nullptr)); | 337 .WillByDefault(Return(nullptr)); |
| 345 connection_finder_.Find(connection_callback_); | 338 connection_finder_.Find(connection_callback_); |
| 346 EXPECT_FALSE(connection_finder_.seek_callback().is_null()); | 339 EXPECT_FALSE(connection_finder_.seek_callback().is_null()); |
| 347 ASSERT_FALSE(connection_finder_.seek_error_callback().is_null()); | 340 ASSERT_FALSE(connection_finder_.seek_error_callback().is_null()); |
| 348 | 341 |
| 349 // If the seek fails, then |connection_finder| will post a delayed poll to | 342 // If the seek fails, then |connection_finder| will post a delayed poll to |
| 350 // reattempt the seek. | 343 // reattempt the seek. |
| 351 connection_finder_.seek_error_callback().Run("Seek failed for test."); | 344 connection_finder_.seek_error_callback().Run("Seek failed for test."); |
| 352 connection_finder_.ClearSeekCallbacks(); | 345 connection_finder_.ClearSeekCallbacks(); |
| 353 EXPECT_TRUE(connection_finder_.seek_callback().is_null()); | 346 EXPECT_TRUE(connection_finder_.seek_callback().is_null()); |
| 354 EXPECT_TRUE(connection_finder_.seek_error_callback().is_null()); | 347 EXPECT_TRUE(connection_finder_.seek_error_callback().is_null()); |
| 355 | 348 |
| 356 // Check that seek is reattempted. | 349 // Check that seek is reattempted. |
| 357 base::RunLoop run_loop; | 350 base::RunLoop run_loop; |
| 358 run_loop.RunUntilIdle(); | 351 run_loop.RunUntilIdle(); |
| 359 ASSERT_FALSE(connection_finder_.seek_callback().is_null()); | 352 ASSERT_FALSE(connection_finder_.seek_callback().is_null()); |
| 360 EXPECT_FALSE(connection_finder_.seek_error_callback().is_null()); | 353 EXPECT_FALSE(connection_finder_.seek_error_callback().is_null()); |
| 361 | 354 |
| 362 // Successfully connect to the Bluetooth device. | 355 // Successfully connect to the Bluetooth device. |
| 363 ON_CALL(*adapter_, GetDevice(kBluetoothAddress)) | 356 ON_CALL(*adapter_, GetDevice(kTestRemoteDeviceBluetoothAddress)) |
| 364 .WillByDefault(Return(bluetooth_device_.get())); | 357 .WillByDefault(Return(bluetooth_device_.get())); |
| 365 MockConnection* connection = connection_finder_.ExpectCreateConnection(); | 358 MockConnection* connection = connection_finder_.ExpectCreateConnection(); |
| 366 connection_finder_.seek_callback().Run(); | 359 connection_finder_.seek_callback().Run(); |
| 367 SimulateDeviceConnection(connection); | 360 SimulateDeviceConnection(connection); |
| 368 } | 361 } |
| 369 | 362 |
| 370 } // namespace proximity_auth | 363 } // namespace proximity_auth |
| OLD | NEW |