| Index: device/bluetooth/bluetooth_device_unittest.cc
 | 
| diff --git a/device/bluetooth/bluetooth_device_unittest.cc b/device/bluetooth/bluetooth_device_unittest.cc
 | 
| index 4cea1b6fa6e48e13990e2564085aae1aad3bb134..1c4945d274986056e002c0b1a6699e67d31ae8bd 100644
 | 
| --- a/device/bluetooth/bluetooth_device_unittest.cc
 | 
| +++ b/device/bluetooth/bluetooth_device_unittest.cc
 | 
| @@ -125,4 +125,397 @@ TEST_F(BluetoothTest, LowEnergyDeviceNoUUIDs) {
 | 
|  // also require build configuration to generate string resources into a .pak
 | 
|  // file.
 | 
|  
 | 
| +#if defined(OS_ANDROID)
 | 
| +// Basic CreateGattConnection test.
 | 
| +TEST_F(BluetoothTest, CreateGattConnection) {
 | 
| +  InitWithFakeAdapter();
 | 
| +  TestBluetoothAdapterObserver observer(adapter_);
 | 
| +
 | 
| +  // Get a device.
 | 
| +  adapter_->StartDiscoverySession(GetDiscoverySessionCallback(),
 | 
| +                                  GetErrorCallback());
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  DiscoverLowEnergyDevice(3);
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  BluetoothDevice* device = observer.last_device();
 | 
| +
 | 
| +  callback_count_ = error_callback_count_ = 0;
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  CompleteGattConnection(device);
 | 
| +  EXPECT_EQ(1, callback_count_);
 | 
| +  EXPECT_EQ(0, error_callback_count_);
 | 
| +  ASSERT_EQ(1u, gatt_connections_.size());
 | 
| +  EXPECT_TRUE(device->IsGattConnected());
 | 
| +  EXPECT_TRUE(gatt_connections_[0]->IsConnected());
 | 
| +}
 | 
| +#endif  // defined(OS_ANDROID)
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +// Creates BluetoothGattConnection instances and tests that the interface
 | 
| +// functions even when some Disconnect and the BluetoothDevice is destroyed.
 | 
| +TEST_F(BluetoothTest, BluetoothGattConnection) {
 | 
| +  InitWithFakeAdapter();
 | 
| +  TestBluetoothAdapterObserver observer(adapter_);
 | 
| +
 | 
| +  // Get a device.
 | 
| +  adapter_->StartDiscoverySession(GetDiscoverySessionCallback(),
 | 
| +                                  GetErrorCallback());
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  DiscoverLowEnergyDevice(3);
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  BluetoothDevice* device = observer.last_device();
 | 
| +  std::string device_address = device->GetAddress();
 | 
| +
 | 
| +  // CreateGattConnection
 | 
| +  callback_count_ = error_callback_count_ = 0;
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  EXPECT_EQ(1, gatt_connection_attempt_count_);
 | 
| +  CompleteGattConnection(device);
 | 
| +  EXPECT_EQ(1, callback_count_);
 | 
| +  EXPECT_EQ(0, error_callback_count_);
 | 
| +  ASSERT_EQ(1u, gatt_connections_.size());
 | 
| +  EXPECT_TRUE(device->IsGattConnected());
 | 
| +  EXPECT_TRUE(gatt_connections_[0]->IsConnected());
 | 
| +
 | 
| +  // Connect again once already connected.
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  EXPECT_EQ(1, gatt_connection_attempt_count_);
 | 
| +  EXPECT_EQ(3, callback_count_);
 | 
| +  EXPECT_EQ(0, error_callback_count_);
 | 
| +  ASSERT_EQ(3u, gatt_connections_.size());
 | 
| +
 | 
| +  // Test GetDeviceAddress
 | 
| +  EXPECT_EQ(device_address, gatt_connections_[0]->GetDeviceAddress());
 | 
| +
 | 
| +  // Test IsConnected
 | 
| +  EXPECT_TRUE(gatt_connections_[0]->IsConnected());
 | 
| +  EXPECT_TRUE(gatt_connections_[1]->IsConnected());
 | 
| +  EXPECT_TRUE(gatt_connections_[2]->IsConnected());
 | 
| +
 | 
| +  // Disconnect & Delete connection objects. Device stays connected.
 | 
| +  gatt_connections_[0]->Disconnect();  // Disconnect first.
 | 
| +  gatt_connections_.pop_back();        // Delete last.
 | 
| +  EXPECT_FALSE(gatt_connections_[0]->IsConnected());
 | 
| +  EXPECT_TRUE(gatt_connections_[1]->IsConnected());
 | 
| +  EXPECT_TRUE(device->IsGattConnected());
 | 
| +  EXPECT_EQ(0, gatt_disconnection_attempt_count_);
 | 
| +
 | 
| +  // Delete device, connection objects should all be disconnected.
 | 
| +  DeleteDevice(device);
 | 
| +  EXPECT_FALSE(gatt_connections_[0]->IsConnected());
 | 
| +  EXPECT_FALSE(gatt_connections_[1]->IsConnected());
 | 
| +
 | 
| +  // Test GetDeviceAddress after device deleted.
 | 
| +  EXPECT_EQ(device_address, gatt_connections_[0]->GetDeviceAddress());
 | 
| +  EXPECT_EQ(device_address, gatt_connections_[1]->GetDeviceAddress());
 | 
| +}
 | 
| +#endif  // defined(OS_ANDROID)
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +// Calls CreateGattConnection then simulates multiple connections from platform.
 | 
| +TEST_F(BluetoothTest,
 | 
| +       BluetoothGattConnection_ConnectWithMultipleOSConnections) {
 | 
| +  InitWithFakeAdapter();
 | 
| +  TestBluetoothAdapterObserver observer(adapter_);
 | 
| +
 | 
| +  // Get a device.
 | 
| +  adapter_->StartDiscoverySession(GetDiscoverySessionCallback(),
 | 
| +                                  GetErrorCallback());
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  DiscoverLowEnergyDevice(3);
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  BluetoothDevice* device = observer.last_device();
 | 
| +
 | 
| +  // CreateGattConnection, & multiple connections from platform only invoke
 | 
| +  // callbacks once:
 | 
| +  callback_count_ = error_callback_count_ = 0;
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  CompleteGattConnection(device);
 | 
| +  CompleteGattConnection(device);
 | 
| +  EXPECT_EQ(1, gatt_connection_attempt_count_);
 | 
| +  EXPECT_EQ(1, callback_count_);
 | 
| +  EXPECT_EQ(0, error_callback_count_);
 | 
| +  EXPECT_TRUE(gatt_connections_[0]->IsConnected());
 | 
| +
 | 
| +  // Become disconnected:
 | 
| +  CompleteGattDisconnection(device);
 | 
| +  EXPECT_EQ(1, callback_count_);
 | 
| +  EXPECT_EQ(0, error_callback_count_);
 | 
| +  EXPECT_FALSE(gatt_connections_[0]->IsConnected());
 | 
| +}
 | 
| +#endif  // defined(OS_ANDROID)
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +// Calls CreateGattConnection after already connected.
 | 
| +TEST_F(BluetoothTest, BluetoothGattConnection_AlreadyConnected) {
 | 
| +  InitWithFakeAdapter();
 | 
| +  TestBluetoothAdapterObserver observer(adapter_);
 | 
| +
 | 
| +  // Get a device.
 | 
| +  adapter_->StartDiscoverySession(GetDiscoverySessionCallback(),
 | 
| +                                  GetErrorCallback());
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  DiscoverLowEnergyDevice(3);
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  BluetoothDevice* device = observer.last_device();
 | 
| +
 | 
| +  // Be already connected:
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  CompleteGattConnection(device);
 | 
| +  EXPECT_TRUE(gatt_connections_[0]->IsConnected());
 | 
| +
 | 
| +  // Then CreateGattConnection:
 | 
| +  callback_count_ = error_callback_count_ = gatt_connection_attempt_count_ =
 | 
| +      gatt_disconnection_attempt_count_ = 0;
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  EXPECT_EQ(0, gatt_connection_attempt_count_);
 | 
| +  EXPECT_EQ(1, callback_count_);
 | 
| +  EXPECT_EQ(0, error_callback_count_);
 | 
| +  EXPECT_TRUE(gatt_connections_[1]->IsConnected());
 | 
| +}
 | 
| +#endif  // defined(OS_ANDROID)
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +// Creates BluetoothGattConnection after one exists that has disconnected.
 | 
| +TEST_F(BluetoothTest,
 | 
| +       BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected) {
 | 
| +  InitWithFakeAdapter();
 | 
| +  TestBluetoothAdapterObserver observer(adapter_);
 | 
| +
 | 
| +  // Get a device.
 | 
| +  adapter_->StartDiscoverySession(GetDiscoverySessionCallback(),
 | 
| +                                  GetErrorCallback());
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  DiscoverLowEnergyDevice(3);
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  BluetoothDevice* device = observer.last_device();
 | 
| +
 | 
| +  // Create connection:
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  CompleteGattConnection(device);
 | 
| +
 | 
| +  // Disconnect connection:
 | 
| +  gatt_connections_[0]->Disconnect();
 | 
| +  CompleteGattDisconnection(device);
 | 
| +
 | 
| +  // Create 2nd connection:
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  CompleteGattConnection(device);
 | 
| +
 | 
| +  EXPECT_FALSE(gatt_connections_[0]->IsConnected())
 | 
| +      << "The disconnected connection shouldn't become connected when another "
 | 
| +         "connection is created.";
 | 
| +  EXPECT_TRUE(gatt_connections_[1]->IsConnected());
 | 
| +}
 | 
| +#endif  // defined(OS_ANDROID)
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +// Deletes BluetoothGattConnection causing disconnection.
 | 
| +TEST_F(BluetoothTest, BluetoothGattConnection_DisconnectWhenObjectsDestroyed) {
 | 
| +  InitWithFakeAdapter();
 | 
| +  TestBluetoothAdapterObserver observer(adapter_);
 | 
| +
 | 
| +  // Get a device.
 | 
| +  adapter_->StartDiscoverySession(GetDiscoverySessionCallback(),
 | 
| +                                  GetErrorCallback());
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  DiscoverLowEnergyDevice(3);
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  BluetoothDevice* device = observer.last_device();
 | 
| +
 | 
| +  // Create multiple connections and simulate connection complete:
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  CompleteGattConnection(device);
 | 
| +
 | 
| +  // Delete all CreateGattConnection objects, observe disconnection:
 | 
| +  callback_count_ = error_callback_count_ = 0;
 | 
| +  gatt_connections_.clear();
 | 
| +  EXPECT_EQ(1, gatt_disconnection_attempt_count_);
 | 
| +}
 | 
| +#endif  // defined(OS_ANDROID)
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +// Starts process of disconnecting and then calls BluetoothGattConnection.
 | 
| +TEST_F(BluetoothTest, BluetoothGattConnection_DisconnectInProgress) {
 | 
| +  InitWithFakeAdapter();
 | 
| +  TestBluetoothAdapterObserver observer(adapter_);
 | 
| +
 | 
| +  // Get a device.
 | 
| +  adapter_->StartDiscoverySession(GetDiscoverySessionCallback(),
 | 
| +                                  GetErrorCallback());
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  DiscoverLowEnergyDevice(3);
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  BluetoothDevice* device = observer.last_device();
 | 
| +
 | 
| +  // Create multiple connections and simulate connection complete:
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  CompleteGattConnection(device);
 | 
| +
 | 
| +  // Disconnect all CreateGattConnection objects & create a new connection.
 | 
| +  // But, don't yet simulate the device disconnecting:
 | 
| +  callback_count_ = error_callback_count_ = gatt_connection_attempt_count_ =
 | 
| +      gatt_disconnection_attempt_count_ = 0;
 | 
| +  for (BluetoothGattConnection* connection : gatt_connections_)
 | 
| +    connection->Disconnect();
 | 
| +  EXPECT_EQ(1, gatt_disconnection_attempt_count_);
 | 
| +
 | 
| +  // Create a connection.
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  EXPECT_EQ(0, gatt_connection_attempt_count_);  // No connection attempt.
 | 
| +  EXPECT_EQ(1, callback_count_);  // Device is assumed still connected.
 | 
| +  EXPECT_EQ(0, error_callback_count_);
 | 
| +  callback_count_ = error_callback_count_ = 0;
 | 
| +  EXPECT_FALSE(gatt_connections_.front()->IsConnected());
 | 
| +  EXPECT_TRUE(gatt_connections_.back()->IsConnected());
 | 
| +
 | 
| +  // Actually disconnect:
 | 
| +  CompleteGattDisconnection(device);
 | 
| +  EXPECT_EQ(0, callback_count_);
 | 
| +  EXPECT_EQ(0, error_callback_count_);
 | 
| +  for (BluetoothGattConnection* connection : gatt_connections_)
 | 
| +    EXPECT_FALSE(connection->IsConnected());
 | 
| +}
 | 
| +#endif  // defined(OS_ANDROID)
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +// Calls CreateGattConnection but receives notice that the device disconnected
 | 
| +// before it ever connects.
 | 
| +TEST_F(BluetoothTest, BluetoothGattConnection_SimulateDisconnect) {
 | 
| +  InitWithFakeAdapter();
 | 
| +  TestBluetoothAdapterObserver observer(adapter_);
 | 
| +
 | 
| +  // Get a device.
 | 
| +  adapter_->StartDiscoverySession(GetDiscoverySessionCallback(),
 | 
| +                                  GetErrorCallback());
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  DiscoverLowEnergyDevice(3);
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  BluetoothDevice* device = observer.last_device();
 | 
| +
 | 
| +  callback_count_ = error_callback_count_ = 0;
 | 
| +  last_connect_error_code_ = BluetoothDevice::ERROR_UNKNOWN;
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  EXPECT_EQ(1, gatt_connection_attempt_count_);
 | 
| +  CompleteGattDisconnection(device);
 | 
| +  EXPECT_EQ(0, callback_count_);
 | 
| +  EXPECT_EQ(1, error_callback_count_);
 | 
| +  EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_code_);
 | 
| +  for (BluetoothGattConnection* connection : gatt_connections_)
 | 
| +    EXPECT_FALSE(connection->IsConnected());
 | 
| +}
 | 
| +#endif  // defined(OS_ANDROID)
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +// Calls CreateGattConnection & DisconnectGatt, then simulates connection.
 | 
| +TEST_F(BluetoothTest, BluetoothGattConnection_DisconnectGatt_SimulateConnect) {
 | 
| +  InitWithFakeAdapter();
 | 
| +  TestBluetoothAdapterObserver observer(adapter_);
 | 
| +
 | 
| +  // Get a device.
 | 
| +  adapter_->StartDiscoverySession(GetDiscoverySessionCallback(),
 | 
| +                                  GetErrorCallback());
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  DiscoverLowEnergyDevice(3);
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  BluetoothDevice* device = observer.last_device();
 | 
| +
 | 
| +  callback_count_ = error_callback_count_ = gatt_connection_attempt_count_ =
 | 
| +      gatt_disconnection_attempt_count_ = 0;
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  device->DisconnectGatt();
 | 
| +  EXPECT_EQ(1, gatt_connection_attempt_count_);
 | 
| +  EXPECT_EQ(1, gatt_disconnection_attempt_count_);
 | 
| +  CompleteGattConnection(device);
 | 
| +  EXPECT_EQ(1, callback_count_);
 | 
| +  EXPECT_EQ(0, error_callback_count_);
 | 
| +  EXPECT_TRUE(gatt_connections_.back()->IsConnected());
 | 
| +  callback_count_ = error_callback_count_ = gatt_connection_attempt_count_ =
 | 
| +      gatt_disconnection_attempt_count_ = 0;
 | 
| +  CompleteGattDisconnection(device);
 | 
| +  EXPECT_EQ(0, callback_count_);
 | 
| +  EXPECT_EQ(0, error_callback_count_);
 | 
| +}
 | 
| +#endif  // defined(OS_ANDROID)
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +// Calls CreateGattConnection & DisconnectGatt, then simulates disconnection.
 | 
| +TEST_F(BluetoothTest,
 | 
| +       BluetoothGattConnection_DisconnectGatt_SimulateDisconnect) {
 | 
| +  InitWithFakeAdapter();
 | 
| +  TestBluetoothAdapterObserver observer(adapter_);
 | 
| +
 | 
| +  // Get a device.
 | 
| +  adapter_->StartDiscoverySession(GetDiscoverySessionCallback(),
 | 
| +                                  GetErrorCallback());
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  DiscoverLowEnergyDevice(3);
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  BluetoothDevice* device = observer.last_device();
 | 
| +
 | 
| +  callback_count_ = error_callback_count_ = gatt_connection_attempt_count_ =
 | 
| +      gatt_disconnection_attempt_count_ = 0;
 | 
| +  last_connect_error_code_ = BluetoothDevice::ERROR_UNKNOWN;
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  device->DisconnectGatt();
 | 
| +  EXPECT_EQ(1, gatt_connection_attempt_count_);
 | 
| +  EXPECT_EQ(1, gatt_disconnection_attempt_count_);
 | 
| +  CompleteGattDisconnection(device);
 | 
| +  EXPECT_EQ(0, callback_count_);
 | 
| +  EXPECT_EQ(1, error_callback_count_);
 | 
| +  EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_code_);
 | 
| +  for (BluetoothGattConnection* connection : gatt_connections_)
 | 
| +    EXPECT_FALSE(connection->IsConnected());
 | 
| +}
 | 
| +#endif  // defined(OS_ANDROID)
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +// Calls CreateGattConnection, but simulate errors connecting. Also, verifies
 | 
| +// multiple errors should only invoke callbacks once.
 | 
| +TEST_F(BluetoothTest, BluetoothGattConnection_ErrorAfterConnection) {
 | 
| +  InitWithFakeAdapter();
 | 
| +  TestBluetoothAdapterObserver observer(adapter_);
 | 
| +
 | 
| +  // Get a device.
 | 
| +  adapter_->StartDiscoverySession(GetDiscoverySessionCallback(),
 | 
| +                                  GetErrorCallback());
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  DiscoverLowEnergyDevice(3);
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +  BluetoothDevice* device = observer.last_device();
 | 
| +
 | 
| +  callback_count_ = error_callback_count_ = 0;
 | 
| +  device->CreateGattConnection(GetGattConnectionCallback(),
 | 
| +                               GetConnectErrorCallback());
 | 
| +  EXPECT_EQ(1, gatt_connection_attempt_count_);
 | 
| +  FailGattConnection(device, BluetoothDevice::ERROR_AUTH_FAILED);
 | 
| +  FailGattConnection(device, BluetoothDevice::ERROR_FAILED);
 | 
| +  EXPECT_EQ(0, callback_count_);
 | 
| +  EXPECT_EQ(1, error_callback_count_);
 | 
| +  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_FAILED, last_connect_error_code_);
 | 
| +  for (BluetoothGattConnection* connection : gatt_connections_)
 | 
| +    EXPECT_FALSE(connection->IsConnected());
 | 
| +}
 | 
| +#endif  // defined(OS_ANDROID)
 | 
| +
 | 
|  }  // namespace device
 | 
| 
 |