OLD | NEW |
(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/ble/bluetooth_low_energy_connection.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/memory/ref_counted.h" |
| 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "components/proximity_auth/ble/bluetooth_low_energy_characteristics_fin
der.h" |
| 11 #include "components/proximity_auth/connection_finder.h" |
| 12 #include "components/proximity_auth/remote_device.h" |
| 13 #include "components/proximity_auth/wire_message.h" |
| 14 #include "device/bluetooth/bluetooth_adapter_factory.h" |
| 15 #include "device/bluetooth/bluetooth_gatt_characteristic.h" |
| 16 #include "device/bluetooth/bluetooth_uuid.h" |
| 17 #include "device/bluetooth/test/mock_bluetooth_adapter.h" |
| 18 #include "device/bluetooth/test/mock_bluetooth_device.h" |
| 19 #include "device/bluetooth/test/mock_bluetooth_discovery_session.h" |
| 20 #include "device/bluetooth/test/mock_bluetooth_gatt_characteristic.h" |
| 21 #include "device/bluetooth/test/mock_bluetooth_gatt_connection.h" |
| 22 #include "device/bluetooth/test/mock_bluetooth_gatt_notify_session.h" |
| 23 #include "testing/gmock/include/gmock/gmock.h" |
| 24 #include "testing/gtest/include/gtest/gtest.h" |
| 25 |
| 26 using testing::_; |
| 27 using testing::AtLeast; |
| 28 using testing::NiceMock; |
| 29 using testing::Return; |
| 30 using testing::StrictMock; |
| 31 using testing::SaveArg; |
| 32 |
| 33 namespace proximity_auth { |
| 34 namespace { |
| 35 |
| 36 const char kDeviceName[] = "Device name"; |
| 37 const char kBluetoothAddress[] = "11:22:33:44:55:66"; |
| 38 |
| 39 const char kServiceUUID[] = "DEADBEEF-CAFE-FEED-FOOD-D15EA5EBEEEF"; |
| 40 const char kToPeripheralCharUUID[] = "FBAE09F2-0482-11E5-8418-1697F925EC7B"; |
| 41 const char kFromPeripheralCharUUID[] = "5539ED10-0483-11E5-8418-1697F925EC7B"; |
| 42 |
| 43 const char kServiceID[] = "service id"; |
| 44 const char kToPeripheralCharID[] = "to peripheral char id"; |
| 45 const char kFromPeripheralCharID[] = "from peripheral char id"; |
| 46 |
| 47 const device::BluetoothGattCharacteristic::Properties |
| 48 kCharacteristicProperties = |
| 49 device::BluetoothGattCharacteristic::PROPERTY_BROADCAST | |
| 50 device::BluetoothGattCharacteristic::PROPERTY_READ | |
| 51 device::BluetoothGattCharacteristic::PROPERTY_WRITE_WITHOUT_RESPONSE | |
| 52 device::BluetoothGattCharacteristic::PROPERTY_INDICATE; |
| 53 |
| 54 const int kMaxNumberOfTries = 3; |
| 55 |
| 56 class MockBluetoothLowEnergyCharacteristicsFinder |
| 57 : public BluetoothLowEnergyCharacteristicsFinder { |
| 58 public: |
| 59 MockBluetoothLowEnergyCharacteristicsFinder() {} |
| 60 ~MockBluetoothLowEnergyCharacteristicsFinder() override {} |
| 61 }; |
| 62 |
| 63 class MockBluetoothLowEnergyConnection : public BluetoothLowEnergyConnection { |
| 64 public: |
| 65 MockBluetoothLowEnergyConnection( |
| 66 const RemoteDevice& remote_device, |
| 67 scoped_refptr<device::BluetoothAdapter> adapter, |
| 68 const device::BluetoothUUID remote_service_uuid, |
| 69 const device::BluetoothUUID to_peripheral_char_uuid, |
| 70 const device::BluetoothUUID from_peripheral_char_uuid, |
| 71 scoped_ptr<device::BluetoothGattConnection> gatt_connection, |
| 72 int max_number_of_write_attempts) |
| 73 : BluetoothLowEnergyConnection(remote_device, |
| 74 adapter, |
| 75 remote_service_uuid, |
| 76 to_peripheral_char_uuid, |
| 77 from_peripheral_char_uuid, |
| 78 gatt_connection.Pass(), |
| 79 max_number_of_write_attempts) {} |
| 80 |
| 81 ~MockBluetoothLowEnergyConnection() override {} |
| 82 |
| 83 MOCK_METHOD2( |
| 84 CreateCharacteristicsFinder, |
| 85 BluetoothLowEnergyCharacteristicsFinder*( |
| 86 const BluetoothLowEnergyCharacteristicsFinder::SuccessCallback& |
| 87 success, |
| 88 const BluetoothLowEnergyCharacteristicsFinder::ErrorCallback& error)); |
| 89 |
| 90 MOCK_METHOD2(OnDidSendMessage, |
| 91 void(const WireMessage& message, bool success)); |
| 92 |
| 93 // Exposing inherited protected methods for testing. |
| 94 using BluetoothLowEnergyConnection::GattCharacteristicValueChanged; |
| 95 |
| 96 // Exposing inherited protected fields for testing. |
| 97 using BluetoothLowEnergyConnection::status; |
| 98 using BluetoothLowEnergyConnection::sub_status; |
| 99 }; |
| 100 |
| 101 } // namespace |
| 102 |
| 103 class ProximityAuthBluetoothLowEnergyConnectionTest : public testing::Test { |
| 104 public: |
| 105 ProximityAuthBluetoothLowEnergyConnectionTest() |
| 106 : adapter_(new NiceMock<device::MockBluetoothAdapter>), |
| 107 remote_device_({kDeviceName, kBluetoothAddress}), |
| 108 service_uuid_(device::BluetoothUUID(kServiceUUID)), |
| 109 to_peripheral_char_uuid_(device::BluetoothUUID(kToPeripheralCharUUID)), |
| 110 from_peripheral_char_uuid_( |
| 111 device::BluetoothUUID(kFromPeripheralCharUUID)), |
| 112 gatt_connection_(new NiceMock<device::MockBluetoothGattConnection>( |
| 113 kBluetoothAddress)), |
| 114 gatt_connection_alias_(gatt_connection_.get()), |
| 115 notify_session_alias_(NULL) {} |
| 116 |
| 117 void SetUp() override { |
| 118 device_ = make_scoped_ptr(new NiceMock<device::MockBluetoothDevice>( |
| 119 adapter_.get(), 0, kDeviceName, kBluetoothAddress, false, false)); |
| 120 |
| 121 service_ = make_scoped_ptr(new NiceMock<device::MockBluetoothGattService>( |
| 122 device_.get(), kServiceID, service_uuid_, true, false)); |
| 123 to_peripheral_char_ = |
| 124 make_scoped_ptr(new NiceMock<device::MockBluetoothGattCharacteristic>( |
| 125 service_.get(), kToPeripheralCharID, to_peripheral_char_uuid_, |
| 126 false, kCharacteristicProperties, |
| 127 device::BluetoothGattCharacteristic::PERMISSION_NONE)); |
| 128 |
| 129 from_peripheral_char_ = |
| 130 make_scoped_ptr(new NiceMock<device::MockBluetoothGattCharacteristic>( |
| 131 service_.get(), kFromPeripheralCharID, from_peripheral_char_uuid_, |
| 132 false, kCharacteristicProperties, |
| 133 device::BluetoothGattCharacteristic::PERMISSION_NONE)); |
| 134 |
| 135 device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_); |
| 136 |
| 137 ON_CALL(*adapter_, GetDevice(kBluetoothAddress)) |
| 138 .WillByDefault(Return(device_.get())); |
| 139 ON_CALL(*device_, GetGattService(kServiceID)) |
| 140 .WillByDefault(Return(service_.get())); |
| 141 ON_CALL(*service_, GetCharacteristic(kFromPeripheralCharID)) |
| 142 .WillByDefault(Return(from_peripheral_char_.get())); |
| 143 ON_CALL(*service_, GetCharacteristic(kToPeripheralCharID)) |
| 144 .WillByDefault(Return(to_peripheral_char_.get())); |
| 145 } |
| 146 |
| 147 // Creates a BluetoothLowEnergyConnection and verifies it's in DISCONNECTED |
| 148 // state. |
| 149 scoped_ptr<MockBluetoothLowEnergyConnection> CreateConnection() { |
| 150 EXPECT_CALL(*adapter_, AddObserver(_)); |
| 151 EXPECT_CALL(*adapter_, RemoveObserver(_)); |
| 152 |
| 153 scoped_ptr<MockBluetoothLowEnergyConnection> connection( |
| 154 new MockBluetoothLowEnergyConnection( |
| 155 remote_device_, adapter_, service_uuid_, to_peripheral_char_uuid_, |
| 156 from_peripheral_char_uuid_, gatt_connection_.Pass(), |
| 157 kMaxNumberOfTries)); |
| 158 |
| 159 EXPECT_EQ(connection->sub_status(), |
| 160 BluetoothLowEnergyConnection::SubStatus::DISCONNECTED); |
| 161 EXPECT_EQ(connection->status(), Connection::DISCONNECTED); |
| 162 |
| 163 return connection.Pass(); |
| 164 } |
| 165 |
| 166 // Transitions |connection| from DISCONNECTED to WAITING_CHARACTERISTICS |
| 167 // state, using an existing GATT connection. |
| 168 void ConnectWithExistingGattConnection( |
| 169 MockBluetoothLowEnergyConnection* connection) { |
| 170 EXPECT_CALL(*gatt_connection_alias_, IsConnected()).WillOnce(Return(true)); |
| 171 EXPECT_CALL(*connection, CreateCharacteristicsFinder(_, _)) |
| 172 .WillOnce( |
| 173 DoAll(SaveArg<0>(&characteristics_finder_success_callback_), |
| 174 SaveArg<1>(&characteristics_finder_error_callback_), |
| 175 Return(new MockBluetoothLowEnergyCharacteristicsFinder))); |
| 176 |
| 177 connection->Connect(); |
| 178 |
| 179 EXPECT_EQ(connection->sub_status(), |
| 180 BluetoothLowEnergyConnection::SubStatus::WAITING_CHARACTERISTICS); |
| 181 EXPECT_EQ(connection->status(), Connection::IN_PROGRESS); |
| 182 } |
| 183 |
| 184 // Transitions |connection| from DISCONNECTED to WAITING_CHARACTERISTICS |
| 185 // state, without an existing GATT connection. |
| 186 void ConnectWithoutExistingGattConnection( |
| 187 MockBluetoothLowEnergyConnection* connection) { |
| 188 // Preparing |connection| for a CreateGattConnection call. |
| 189 EXPECT_CALL(*gatt_connection_alias_, IsConnected()).WillOnce(Return(false)); |
| 190 EXPECT_CALL(*device_, CreateGattConnection(_, _)) |
| 191 .WillOnce(DoAll(SaveArg<0>(&create_gatt_connection_success_callback_), |
| 192 SaveArg<1>(&create_gatt_connection_error_callback_))); |
| 193 |
| 194 connection->Connect(); |
| 195 |
| 196 EXPECT_EQ(connection->sub_status(), |
| 197 BluetoothLowEnergyConnection::SubStatus::WAITING_GATT_CONNECTION); |
| 198 EXPECT_EQ(connection->status(), Connection::IN_PROGRESS); |
| 199 |
| 200 // Preparing |connection| to run |create_gatt_connection_success_callback_|. |
| 201 EXPECT_FALSE(create_gatt_connection_error_callback_.is_null()); |
| 202 ASSERT_FALSE(create_gatt_connection_success_callback_.is_null()); |
| 203 EXPECT_CALL(*connection, CreateCharacteristicsFinder(_, _)) |
| 204 .WillOnce(DoAll( |
| 205 SaveArg<0>(&characteristics_finder_success_callback_), |
| 206 SaveArg<1>(&characteristics_finder_error_callback_), |
| 207 Return(new NiceMock<MockBluetoothLowEnergyCharacteristicsFinder>))); |
| 208 |
| 209 create_gatt_connection_success_callback_.Run(make_scoped_ptr( |
| 210 new NiceMock<device::MockBluetoothGattConnection>(kBluetoothAddress))); |
| 211 |
| 212 EXPECT_EQ(connection->sub_status(), |
| 213 BluetoothLowEnergyConnection::SubStatus::WAITING_CHARACTERISTICS); |
| 214 EXPECT_EQ(connection->status(), Connection::IN_PROGRESS); |
| 215 } |
| 216 |
| 217 // Transitions |connection| from WAITING_CHARACTERISTICS to |
| 218 // WAITING_NOTIFY_SESSION state. |
| 219 void CharacteristicsFound(MockBluetoothLowEnergyConnection* connection) { |
| 220 EXPECT_CALL(*from_peripheral_char_, StartNotifySession(_, _)) |
| 221 .WillOnce(DoAll(SaveArg<0>(¬ify_session_success_callback_), |
| 222 SaveArg<1>(¬ify_session_error_callback_))); |
| 223 EXPECT_FALSE(characteristics_finder_error_callback_.is_null()); |
| 224 ASSERT_FALSE(characteristics_finder_success_callback_.is_null()); |
| 225 |
| 226 characteristics_finder_success_callback_.Run( |
| 227 {service_uuid_, kServiceID}, |
| 228 {to_peripheral_char_uuid_, kToPeripheralCharID}, |
| 229 {from_peripheral_char_uuid_, kFromPeripheralCharID}); |
| 230 |
| 231 EXPECT_EQ(connection->sub_status(), |
| 232 BluetoothLowEnergyConnection::SubStatus::WAITING_NOTIFY_SESSION); |
| 233 EXPECT_EQ(connection->status(), Connection::IN_PROGRESS); |
| 234 } |
| 235 |
| 236 // Transitions |connection| from WAITING_NOTIFY_SESSION to |
| 237 // WAITING_RESPONSE_SIGNAL state. |
| 238 void NotifySessionStarted(MockBluetoothLowEnergyConnection* connection) { |
| 239 EXPECT_CALL(*to_peripheral_char_, WriteRemoteCharacteristic(_, _, _)) |
| 240 .WillOnce( |
| 241 DoAll(SaveArg<0>(&last_value_written_on_to_peripheral_char_), |
| 242 SaveArg<1>(&write_remote_characteristic_success_callback_), |
| 243 SaveArg<2>(&write_remote_characteristic_error_callback_))); |
| 244 EXPECT_FALSE(notify_session_error_callback_.is_null()); |
| 245 ASSERT_FALSE(notify_session_success_callback_.is_null()); |
| 246 |
| 247 // Store an alias for the notify session passed |connection|. |
| 248 scoped_ptr<device::MockBluetoothGattNotifySession> notify_session( |
| 249 new NiceMock<device::MockBluetoothGattNotifySession>( |
| 250 kToPeripheralCharID)); |
| 251 notify_session_alias_ = notify_session.get(); |
| 252 notify_session_success_callback_.Run(notify_session.Pass()); |
| 253 |
| 254 EXPECT_EQ(connection->sub_status(), |
| 255 BluetoothLowEnergyConnection::SubStatus::WAITING_RESPONSE_SIGNAL); |
| 256 EXPECT_EQ(connection->status(), Connection::IN_PROGRESS); |
| 257 } |
| 258 |
| 259 // Transitions |connection| from WAITING_RESPONSE_SIGNAL to CONNECTED state. |
| 260 void ResponseSignalReceived(MockBluetoothLowEnergyConnection* connection) { |
| 261 // Written value contains only the |
| 262 // BluetoothLowEneryConnection::ControlSignal::kInviteToConnectSignal. |
| 263 const std::vector<uint8> kInviteToConnectSignal = ToByteVector(static_cast< |
| 264 uint32>( |
| 265 BluetoothLowEnergyConnection::ControlSignal::kInviteToConnectSignal)); |
| 266 EXPECT_EQ(last_value_written_on_to_peripheral_char_, |
| 267 kInviteToConnectSignal); |
| 268 |
| 269 EXPECT_CALL(*connection, OnDidSendMessage(_, _)).Times(0); |
| 270 EXPECT_FALSE(write_remote_characteristic_error_callback_.is_null()); |
| 271 ASSERT_FALSE(write_remote_characteristic_success_callback_.is_null()); |
| 272 write_remote_characteristic_success_callback_.Run(); |
| 273 |
| 274 // Received the |
| 275 // BluetoothLowEneryConnection::ControlSignal::kInvitationResponseSignal. |
| 276 const std::vector<uint8> kInvitationResponseSignal = ToByteVector( |
| 277 static_cast<uint32>(BluetoothLowEnergyConnection::ControlSignal:: |
| 278 kInvitationResponseSignal)); |
| 279 connection->GattCharacteristicValueChanged( |
| 280 adapter_.get(), from_peripheral_char_.get(), kInvitationResponseSignal); |
| 281 |
| 282 EXPECT_EQ(connection->sub_status(), |
| 283 BluetoothLowEnergyConnection::SubStatus::CONNECTED); |
| 284 EXPECT_EQ(connection->status(), Connection::CONNECTED); |
| 285 } |
| 286 |
| 287 // Transitions |connection| to a DISCONNECTED state regardless of its initial |
| 288 // state. |
| 289 void Disconnect(MockBluetoothLowEnergyConnection* connection) { |
| 290 // A notify session was previously set. |
| 291 if (notify_session_alias_) |
| 292 EXPECT_CALL(*notify_session_alias_, Stop(_)); |
| 293 |
| 294 connection->Disconnect(); |
| 295 |
| 296 EXPECT_EQ(connection->sub_status(), |
| 297 BluetoothLowEnergyConnection::SubStatus::DISCONNECTED); |
| 298 EXPECT_EQ(connection->status(), Connection::DISCONNECTED); |
| 299 } |
| 300 |
| 301 std::vector<uint8> ToByteVector(uint32 value) { |
| 302 std::vector<uint8> bytes(4, 0); |
| 303 bytes[0] = static_cast<uint8>(value); |
| 304 bytes[1] = static_cast<uint8>(value >> 8); |
| 305 bytes[2] = static_cast<uint8>(value >> 16); |
| 306 bytes[3] = static_cast<uint8>(value >> 24); |
| 307 return bytes; |
| 308 } |
| 309 |
| 310 protected: |
| 311 scoped_refptr<device::MockBluetoothAdapter> adapter_; |
| 312 RemoteDevice remote_device_; |
| 313 device::BluetoothUUID service_uuid_; |
| 314 device::BluetoothUUID to_peripheral_char_uuid_; |
| 315 device::BluetoothUUID from_peripheral_char_uuid_; |
| 316 scoped_ptr<device::MockBluetoothGattConnection> gatt_connection_; |
| 317 device::MockBluetoothGattConnection* gatt_connection_alias_; |
| 318 scoped_ptr<device::MockBluetoothDevice> device_; |
| 319 scoped_ptr<device::MockBluetoothGattService> service_; |
| 320 scoped_ptr<device::MockBluetoothGattCharacteristic> to_peripheral_char_; |
| 321 scoped_ptr<device::MockBluetoothGattCharacteristic> from_peripheral_char_; |
| 322 std::vector<uint8> last_value_written_on_to_peripheral_char_; |
| 323 device::MockBluetoothGattNotifySession* notify_session_alias_; |
| 324 |
| 325 // Callbacks |
| 326 device::BluetoothDevice::GattConnectionCallback |
| 327 create_gatt_connection_success_callback_; |
| 328 device::BluetoothDevice::ConnectErrorCallback |
| 329 create_gatt_connection_error_callback_; |
| 330 |
| 331 BluetoothLowEnergyCharacteristicsFinder::SuccessCallback |
| 332 characteristics_finder_success_callback_; |
| 333 BluetoothLowEnergyCharacteristicsFinder::ErrorCallback |
| 334 characteristics_finder_error_callback_; |
| 335 |
| 336 device::BluetoothGattCharacteristic::NotifySessionCallback |
| 337 notify_session_success_callback_; |
| 338 device::BluetoothGattCharacteristic::ErrorCallback |
| 339 notify_session_error_callback_; |
| 340 |
| 341 base::Closure write_remote_characteristic_success_callback_; |
| 342 device::BluetoothGattCharacteristic::ErrorCallback |
| 343 write_remote_characteristic_error_callback_; |
| 344 }; |
| 345 |
| 346 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, |
| 347 CreateAndDestroyWithouthConnectCallDoesntCrash) { |
| 348 BluetoothLowEnergyConnection connection( |
| 349 remote_device_, adapter_, service_uuid_, to_peripheral_char_uuid_, |
| 350 from_peripheral_char_uuid_, gatt_connection_.Pass(), kMaxNumberOfTries); |
| 351 } |
| 352 |
| 353 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, |
| 354 Disconect_WithoutConnectDoesntCrash) { |
| 355 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection()); |
| 356 Disconnect(connection.get()); |
| 357 } |
| 358 |
| 359 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, |
| 360 Connect_Success_WithGattConnection) { |
| 361 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection()); |
| 362 ConnectWithExistingGattConnection(connection.get()); |
| 363 CharacteristicsFound(connection.get()); |
| 364 NotifySessionStarted(connection.get()); |
| 365 ResponseSignalReceived(connection.get()); |
| 366 } |
| 367 |
| 368 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, |
| 369 Connect_Success_WithoutGattConnection) { |
| 370 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection()); |
| 371 ConnectWithoutExistingGattConnection(connection.get()); |
| 372 CharacteristicsFound(connection.get()); |
| 373 NotifySessionStarted(connection.get()); |
| 374 ResponseSignalReceived(connection.get()); |
| 375 } |
| 376 |
| 377 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, |
| 378 Connect_Success_Disconnect) { |
| 379 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection()); |
| 380 ConnectWithExistingGattConnection(connection.get()); |
| 381 CharacteristicsFound(connection.get()); |
| 382 NotifySessionStarted(connection.get()); |
| 383 ResponseSignalReceived(connection.get()); |
| 384 Disconnect(connection.get()); |
| 385 } |
| 386 |
| 387 TEST_F( |
| 388 ProximityAuthBluetoothLowEnergyConnectionTest, |
| 389 Connect_Incomplete_Disconnect_FromWaitingCharacteristicsStateWithoutExisting
GattConnection) { |
| 390 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection()); |
| 391 ConnectWithoutExistingGattConnection(connection.get()); |
| 392 Disconnect(connection.get()); |
| 393 } |
| 394 |
| 395 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, |
| 396 Connect_Incomplete_Disconnect_FromWaitingCharacteristicsState) { |
| 397 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection()); |
| 398 ConnectWithExistingGattConnection(connection.get()); |
| 399 Disconnect(connection.get()); |
| 400 } |
| 401 |
| 402 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, |
| 403 Connect_Incomplete_Disconnect_FromWaitingNotifySessionState) { |
| 404 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection()); |
| 405 ConnectWithExistingGattConnection(connection.get()); |
| 406 CharacteristicsFound(connection.get()); |
| 407 Disconnect(connection.get()); |
| 408 } |
| 409 |
| 410 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, |
| 411 Connect_Incomplete_Disconnect_FromWaitingResponseSignalState) { |
| 412 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection()); |
| 413 ConnectWithExistingGattConnection(connection.get()); |
| 414 CharacteristicsFound(connection.get()); |
| 415 NotifySessionStarted(connection.get()); |
| 416 Disconnect(connection.get()); |
| 417 } |
| 418 |
| 419 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, |
| 420 Connect_Fails_CharacteristicsNotFound) { |
| 421 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection()); |
| 422 ConnectWithExistingGattConnection(connection.get()); |
| 423 |
| 424 EXPECT_CALL(*from_peripheral_char_, StartNotifySession(_, _)).Times(0); |
| 425 EXPECT_FALSE(characteristics_finder_success_callback_.is_null()); |
| 426 ASSERT_FALSE(characteristics_finder_error_callback_.is_null()); |
| 427 |
| 428 characteristics_finder_error_callback_.Run( |
| 429 {to_peripheral_char_uuid_, kToPeripheralCharID}, |
| 430 {from_peripheral_char_uuid_, kFromPeripheralCharID}); |
| 431 |
| 432 EXPECT_EQ(connection->sub_status(), |
| 433 BluetoothLowEnergyConnection::SubStatus::DISCONNECTED); |
| 434 EXPECT_EQ(connection->status(), Connection::DISCONNECTED); |
| 435 } |
| 436 |
| 437 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, |
| 438 Connect_Fails_NotifySessionError) { |
| 439 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection()); |
| 440 ConnectWithExistingGattConnection(connection.get()); |
| 441 CharacteristicsFound(connection.get()); |
| 442 |
| 443 EXPECT_CALL(*to_peripheral_char_, WriteRemoteCharacteristic(_, _, _)) |
| 444 .Times(0); |
| 445 EXPECT_FALSE(notify_session_success_callback_.is_null()); |
| 446 ASSERT_FALSE(notify_session_error_callback_.is_null()); |
| 447 |
| 448 notify_session_error_callback_.Run( |
| 449 device::BluetoothGattService::GATT_ERROR_UNKNOWN); |
| 450 |
| 451 EXPECT_EQ(connection->sub_status(), |
| 452 BluetoothLowEnergyConnection::SubStatus::DISCONNECTED); |
| 453 EXPECT_EQ(connection->status(), Connection::DISCONNECTED); |
| 454 } |
| 455 |
| 456 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, |
| 457 Connect_Fails_ErrorSendingInviteToConnectSignal) { |
| 458 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection()); |
| 459 ConnectWithExistingGattConnection(connection.get()); |
| 460 CharacteristicsFound(connection.get()); |
| 461 NotifySessionStarted(connection.get()); |
| 462 |
| 463 // |connection| will call WriteRemoteCharacteristics(_,_) to try to send the |
| 464 // message |kMaxNumberOfTries| times. There is alredy one EXPECTA_CALL for |
| 465 // WriteRemoteCharacteristic(_,_,_) in NotifySessionStated, that's why we use |
| 466 // |kMaxNumberOfTries-1| in the EXPECT_CALL statement. |
| 467 EXPECT_CALL(*connection, OnDidSendMessage(_, _)).Times(0); |
| 468 EXPECT_CALL(*to_peripheral_char_, WriteRemoteCharacteristic(_, _, _)) |
| 469 .Times(kMaxNumberOfTries - 1) |
| 470 .WillRepeatedly( |
| 471 DoAll(SaveArg<0>(&last_value_written_on_to_peripheral_char_), |
| 472 SaveArg<1>(&write_remote_characteristic_success_callback_), |
| 473 SaveArg<2>(&write_remote_characteristic_error_callback_))); |
| 474 |
| 475 for (int i = 0; i < kMaxNumberOfTries; i++) { |
| 476 const std::vector<uint8> kInviteToConnectSignal = ToByteVector(static_cast< |
| 477 uint32>( |
| 478 BluetoothLowEnergyConnection::ControlSignal::kInviteToConnectSignal)); |
| 479 EXPECT_EQ(last_value_written_on_to_peripheral_char_, |
| 480 kInviteToConnectSignal); |
| 481 ASSERT_FALSE(write_remote_characteristic_error_callback_.is_null()); |
| 482 EXPECT_FALSE(write_remote_characteristic_success_callback_.is_null()); |
| 483 write_remote_characteristic_error_callback_.Run( |
| 484 device::BluetoothGattService::GATT_ERROR_UNKNOWN); |
| 485 } |
| 486 |
| 487 EXPECT_EQ(connection->sub_status(), |
| 488 BluetoothLowEnergyConnection::SubStatus::DISCONNECTED); |
| 489 EXPECT_EQ(connection->status(), Connection::DISCONNECTED); |
| 490 } |
| 491 |
| 492 TEST_F(ProximityAuthBluetoothLowEnergyConnectionTest, |
| 493 Connect_Fails_CharacteristicsNotFound_WithoutExistingGattConnection) { |
| 494 scoped_ptr<MockBluetoothLowEnergyConnection> connection(CreateConnection()); |
| 495 ConnectWithoutExistingGattConnection(connection.get()); |
| 496 |
| 497 EXPECT_CALL(*from_peripheral_char_, StartNotifySession(_, _)).Times(0); |
| 498 EXPECT_FALSE(characteristics_finder_success_callback_.is_null()); |
| 499 ASSERT_FALSE(characteristics_finder_error_callback_.is_null()); |
| 500 |
| 501 characteristics_finder_error_callback_.Run( |
| 502 {to_peripheral_char_uuid_, kToPeripheralCharID}, |
| 503 {from_peripheral_char_uuid_, kFromPeripheralCharID}); |
| 504 |
| 505 EXPECT_EQ(connection->sub_status(), |
| 506 BluetoothLowEnergyConnection::SubStatus::DISCONNECTED); |
| 507 EXPECT_EQ(connection->status(), Connection::DISCONNECTED); |
| 508 } |
| 509 |
| 510 } // namespace proximity_auth |
OLD | NEW |