// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/bind_helpers.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_current.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "dbus/object_path.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/bluetooth_common.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_discovery_session.h"
#include "device/bluetooth/bluez/bluetooth_adapter_bluez.h"
#include "device/bluetooth/bluez/bluetooth_device_bluez.h"
#include "device/bluetooth/bluez/bluetooth_pairing_bluez.h"
#include "device/bluetooth/dbus/bluez_dbus_manager.h"
#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_input_client.h"
#include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
#include "device/bluetooth/test/test_pairing_delegate.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

using device::BluetoothAdapter;
using device::BluetoothAdapterFactory;
using device::BluetoothDevice;
using device::BluetoothDeviceType;
using device::BluetoothDiscoveryFilter;
using device::BluetoothDiscoverySession;
using device::BluetoothUUID;
using device::TestBluetoothAdapterObserver;
using device::TestPairingDelegate;

namespace bluez {

namespace {

// Callback for BluetoothDevice::GetConnectionInfo() that simply saves the
// connection info to the bound argument.
void SaveConnectionInfo(BluetoothDevice::ConnectionInfo* out,
                        const BluetoothDevice::ConnectionInfo& conn_info) {
  *out = conn_info;
}

// Find |address| in |devices|, if found returns the index otherwise returns -1.
int GetDeviceIndexByAddress(const BluetoothAdapter::DeviceList& devices,
                            const char* address) {
  int idx = -1;
  for (auto* device : devices) {
    ++idx;
    if (device->GetAddress().compare(address) == 0)
      return idx;
  }
  return -1;
}

class FakeBluetoothProfileServiceProviderDelegate
    : public bluez::BluetoothProfileServiceProvider::Delegate {
 public:
  FakeBluetoothProfileServiceProviderDelegate() = default;

  // bluez::BluetoothProfileServiceProvider::Delegate:
  void Released() override {}

  void NewConnection(
      const dbus::ObjectPath&,
      base::ScopedFD,
      const bluez::BluetoothProfileServiceProvider::Delegate::Options&,
      const ConfirmationCallback&) override {}

  void RequestDisconnection(const dbus::ObjectPath&,
                            const ConfirmationCallback&) override {}

  void Cancel() override {}
};

}  // namespace


class BluetoothBlueZTest : public testing::Test {
 public:
  static const char kGapUuid[];
  static const char kGattUuid[];
  static const char kPnpUuid[];
  static const char kHeadsetUuid[];

  void SetUp() override {
    std::unique_ptr<bluez::BluezDBusManagerSetter> dbus_setter =
        bluez::BluezDBusManager::GetSetterForTesting();
    // We need to initialize BluezDBusManager early to prevent
    // Bluetooth*::Create() methods from picking the real instead of fake
    // implementations.
    fake_bluetooth_adapter_client_ = new bluez::FakeBluetoothAdapterClient;
    dbus_setter->SetBluetoothAdapterClient(
        std::unique_ptr<bluez::BluetoothAdapterClient>(
            fake_bluetooth_adapter_client_));

    fake_bluetooth_device_client_ = new bluez::FakeBluetoothDeviceClient;
    // Use the original fake behavior for these tests.
    fake_bluetooth_device_client_->set_delay_start_discovery(true);
    dbus_setter->SetBluetoothDeviceClient(
        std::unique_ptr<bluez::BluetoothDeviceClient>(
            fake_bluetooth_device_client_));
    dbus_setter->SetBluetoothInputClient(
        std::unique_ptr<bluez::BluetoothInputClient>(
            new bluez::FakeBluetoothInputClient));
    dbus_setter->SetBluetoothAgentManagerClient(
        std::unique_ptr<bluez::BluetoothAgentManagerClient>(
            new bluez::FakeBluetoothAgentManagerClient));
    dbus_setter->SetBluetoothGattServiceClient(
        std::unique_ptr<bluez::BluetoothGattServiceClient>(
            new bluez::FakeBluetoothGattServiceClient));

    fake_bluetooth_adapter_client_->SetSimulationIntervalMs(10);

    callback_count_ = 0;
    error_callback_count_ = 0;
    last_connect_error_ = BluetoothDevice::ERROR_UNKNOWN;
    last_client_error_ = "";
  }

  void TearDown() override {
    for (const auto& session : discovery_sessions_) {
      if (!session->IsActive())
        continue;
      callback_count_ = 0;
      session->Stop(GetCallback(), GetErrorCallback());
      base::RunLoop().Run();
      ASSERT_EQ(1, callback_count_);
    }
    discovery_sessions_.clear();
    adapter_ = nullptr;
    bluez::BluezDBusManager::Shutdown();
  }

  // Generic callbacks
  void Callback() {
    ++callback_count_;
    QuitMessageLoop();
  }

  base::Closure GetCallback() {
    return base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this));
  }

  void AdapterCallback() { QuitMessageLoop(); }

  void DiscoverySessionCallback(
      std::unique_ptr<BluetoothDiscoverySession> discovery_session) {
    ++callback_count_;
    discovery_sessions_.push_back(std::move(discovery_session));
    QuitMessageLoop();
  }

  void ProfileRegisteredCallback(BluetoothAdapterProfileBlueZ* profile) {
    adapter_profile_ = profile;
    ++callback_count_;
    QuitMessageLoop();
  }

  void ErrorCallback() {
    ++error_callback_count_;
    QuitMessageLoop();
  }

  void DiscoveryErrorCallback(device::UMABluetoothDiscoverySessionOutcome) {
    ErrorCallback();
  }

  base::Closure GetErrorCallback() {
    return base::Bind(&BluetoothBlueZTest::ErrorCallback,
                      base::Unretained(this));
  }

  base::Callback<void(device::UMABluetoothDiscoverySessionOutcome)>
  GetDiscoveryErrorCallback() {
    return base::Bind(&BluetoothBlueZTest::DiscoveryErrorCallback,
                      base::Unretained(this));
  }

  void DBusErrorCallback(const std::string& error_name,
                         const std::string& error_message) {
    ++error_callback_count_;
    last_client_error_ = error_name;
    QuitMessageLoop();
  }

  void ConnectErrorCallback(BluetoothDevice::ConnectErrorCode error) {
    ++error_callback_count_;
    last_connect_error_ = error;
  }

  void ErrorCompletionCallback(const std::string& error_message) {
    ++error_callback_count_;
    QuitMessageLoop();
  }

  // Call to fill the adapter_ member with a BluetoothAdapter instance.
  void GetAdapter() {
    adapter_ = new BluetoothAdapterBlueZ(base::Bind(
        &BluetoothBlueZTest::AdapterCallback, base::Unretained(this)));
    base::RunLoop().Run();
    ASSERT_TRUE(adapter_.get() != nullptr);
    ASSERT_TRUE(adapter_->IsInitialized());
  }

  // Run a discovery phase until the named device is detected, or if the named
  // device is not created, the discovery process ends without finding it.
  //
  // The correct behavior of discovery is tested by the "Discovery" test case
  // without using this function.
  void DiscoverDevice(const std::string& address) {
    ASSERT_TRUE(adapter_.get() != nullptr);
    ASSERT_TRUE(base::MessageLoopCurrent::IsSet());
    fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

    TestBluetoothAdapterObserver observer(adapter_);

    adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
    adapter_->StartDiscoverySession(
        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                   base::Unretained(this)),
        GetErrorCallback());
    base::RunLoop().Run();
    ASSERT_EQ(2, callback_count_);
    ASSERT_EQ(0, error_callback_count_);
    ASSERT_EQ((size_t)1, discovery_sessions_.size());
    ASSERT_TRUE(discovery_sessions_[0]->IsActive());
    callback_count_ = 0;

    ASSERT_TRUE(adapter_->IsPowered());
    ASSERT_TRUE(adapter_->IsDiscovering());

    while (!observer.device_removed_count() &&
           observer.last_device_address() != address)
      base::RunLoop().Run();

    discovery_sessions_[0]->Stop(GetCallback(), GetErrorCallback());
    base::RunLoop().Run();
    ASSERT_EQ(1, callback_count_);
    ASSERT_EQ(0, error_callback_count_);
    callback_count_ = 0;

    ASSERT_FALSE(adapter_->IsDiscovering());
  }

  // Run a discovery phase so we have devices that can be paired with.
  void DiscoverDevices() {
    // Pass an invalid address for the device so that the discovery process
    // completes with all devices.
    DiscoverDevice("does not exist");
  }

 protected:
  base::MessageLoop message_loop_;
  bluez::FakeBluetoothAdapterClient* fake_bluetooth_adapter_client_;
  bluez::FakeBluetoothDeviceClient* fake_bluetooth_device_client_;
  scoped_refptr<BluetoothAdapter> adapter_;

  int callback_count_;
  int error_callback_count_;
  enum BluetoothDevice::ConnectErrorCode last_connect_error_;
  std::string last_client_error_;
  std::vector<std::unique_ptr<BluetoothDiscoverySession>> discovery_sessions_;
  BluetoothAdapterProfileBlueZ* adapter_profile_;

 private:
  // Some tests use a message loop since background processing is simulated;
  // break out of those loops.
  void QuitMessageLoop() {
    if (base::RunLoop::IsRunningOnCurrentThread())
      base::RunLoop::QuitCurrentWhenIdleDeprecated();
  }
};
const char BluetoothBlueZTest::kGapUuid[] =
    "00001800-0000-1000-8000-00805f9b34fb";
const char BluetoothBlueZTest::kGattUuid[] =
    "00001801-0000-1000-8000-00805f9b34fb";
const char BluetoothBlueZTest::kPnpUuid[] =
    "00001200-0000-1000-8000-00805f9b34fb";
const char BluetoothBlueZTest::kHeadsetUuid[] =
    "00001112-0000-1000-8000-00805f9b34fb";

TEST_F(BluetoothBlueZTest, AlreadyPresent) {
  GetAdapter();

  // This verifies that the class gets the list of adapters when created;
  // and initializes with an existing adapter if there is one.
  EXPECT_TRUE(adapter_->IsPresent());
  EXPECT_FALSE(adapter_->IsPowered());
  EXPECT_EQ(bluez::FakeBluetoothAdapterClient::kAdapterAddress,
            adapter_->GetAddress());
  EXPECT_FALSE(adapter_->IsDiscovering());

  // There should be 2 devices
  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
  EXPECT_EQ(2U, devices.size());

  // |devices| are not ordered, verify it contains the 2 device addresses.
  EXPECT_NE(
      -1, GetDeviceIndexByAddress(
              devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress));
  EXPECT_NE(
      -1,
      GetDeviceIndexByAddress(
          devices,
          bluez::FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress));
}

TEST_F(BluetoothBlueZTest, BecomePresent) {
  fake_bluetooth_adapter_client_->SetVisible(false);
  GetAdapter();
  ASSERT_FALSE(adapter_->IsPresent());

  // Install an observer; expect the AdapterPresentChanged to be called
  // with true, and IsPresent() to return true.
  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_adapter_client_->SetVisible(true);

  EXPECT_EQ(1, observer.present_changed_count());
  EXPECT_TRUE(observer.last_present());

  EXPECT_TRUE(adapter_->IsPresent());

  // We should have had a device announced.
  EXPECT_EQ(2, observer.device_added_count());
  EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress,
            observer.last_device_address());

  // Other callbacks shouldn't be called if the values are false.
  EXPECT_EQ(0, observer.powered_changed_count());
  EXPECT_EQ(0, observer.discovering_changed_count());
  EXPECT_FALSE(adapter_->IsPowered());
  EXPECT_FALSE(adapter_->IsDiscovering());
}

TEST_F(BluetoothBlueZTest, BecomeNotPresent) {
  GetAdapter();
  ASSERT_TRUE(adapter_->IsPresent());

  // Install an observer; expect the AdapterPresentChanged to be called
  // with false, and IsPresent() to return false.
  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_adapter_client_->SetVisible(false);

  EXPECT_EQ(1, observer.present_changed_count());
  EXPECT_FALSE(observer.last_present());

  EXPECT_FALSE(adapter_->IsPresent());

  // We should have had 2 devices removed.
  EXPECT_EQ(2, observer.device_removed_count());
  // 2 possibilities for the last device here.
  std::string address = observer.last_device_address();
  EXPECT_TRUE(address.compare(bluez::FakeBluetoothDeviceClient::
                                  kPairedUnconnectableDeviceAddress) == 0 ||
              address.compare(
                  bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress) == 0);

  // DiscoveringChanged() should be triggered regardless of the current value
  // of Discovering property.
  EXPECT_EQ(1, observer.discovering_changed_count());

  // Other callbacks shouldn't be called since the values are false.
  EXPECT_EQ(0, observer.powered_changed_count());
  EXPECT_FALSE(adapter_->IsPowered());
  EXPECT_FALSE(adapter_->IsDiscovering());
}

TEST_F(BluetoothBlueZTest, SecondAdapter) {
  GetAdapter();
  ASSERT_TRUE(adapter_->IsPresent());

  // Install an observer, then add a second adapter. Nothing should change,
  // we ignore the second adapter.
  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_adapter_client_->SetSecondVisible(true);

  EXPECT_EQ(0, observer.present_changed_count());

  EXPECT_TRUE(adapter_->IsPresent());
  EXPECT_EQ(bluez::FakeBluetoothAdapterClient::kAdapterAddress,
            adapter_->GetAddress());

  // Try removing the first adapter, we should now act as if the adapter
  // is no longer present rather than fall back to the second.
  fake_bluetooth_adapter_client_->SetVisible(false);

  EXPECT_EQ(1, observer.present_changed_count());
  EXPECT_FALSE(observer.last_present());

  EXPECT_FALSE(adapter_->IsPresent());

  // We should have had 2 devices removed.
  EXPECT_EQ(2, observer.device_removed_count());
  // As BluetoothAdapter devices removal does not keep the order of adding them,
  // 2 possibilities for the last device here.
  std::string address = observer.last_device_address();
  EXPECT_TRUE(address.compare(bluez::FakeBluetoothDeviceClient::
                                  kPairedUnconnectableDeviceAddress) == 0 ||
              address.compare(
                  bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress) == 0);

  // DiscoveringChanged() should be triggered regardless of the current value
  // of Discovering property.
  EXPECT_EQ(1, observer.discovering_changed_count());

  // Other callbacks shouldn't be called since the values are false.
  EXPECT_EQ(0, observer.powered_changed_count());
  EXPECT_FALSE(adapter_->IsPowered());
  EXPECT_FALSE(adapter_->IsDiscovering());

  observer.Reset();

  // Removing the second adapter shouldn't set anything either.
  fake_bluetooth_adapter_client_->SetSecondVisible(false);

  EXPECT_EQ(0, observer.device_removed_count());
  EXPECT_EQ(0, observer.powered_changed_count());
  EXPECT_EQ(0, observer.discovering_changed_count());
}

TEST_F(BluetoothBlueZTest, BecomePowered) {
  GetAdapter();
  ASSERT_FALSE(adapter_->IsPowered());

  // Install an observer; expect the AdapterPoweredChanged to be called
  // with true, and IsPowered() to return true.
  TestBluetoothAdapterObserver observer(adapter_);

  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  EXPECT_EQ(1, observer.powered_changed_count());
  EXPECT_TRUE(observer.last_powered());

  EXPECT_TRUE(adapter_->IsPowered());
}

TEST_F(BluetoothBlueZTest, BecomeNotPowered) {
  GetAdapter();
  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  ASSERT_TRUE(adapter_->IsPowered());

  // Install an observer; expect the AdapterPoweredChanged to be called
  // with false, and IsPowered() to return false.
  TestBluetoothAdapterObserver observer(adapter_);

  adapter_->SetPowered(false, GetCallback(), GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  EXPECT_EQ(1, observer.powered_changed_count());
  EXPECT_FALSE(observer.last_powered());

  EXPECT_FALSE(adapter_->IsPowered());
}

TEST_F(BluetoothBlueZTest, SetPoweredWhenNotPresent) {
  GetAdapter();
  ASSERT_TRUE(adapter_->IsPresent());

  // Install an observer; expect the AdapterPresentChanged to be called
  // with false, and IsPresent() to return false.
  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_adapter_client_->SetVisible(false);

  EXPECT_EQ(1, observer.present_changed_count());
  EXPECT_FALSE(observer.last_present());

  EXPECT_FALSE(adapter_->IsPresent());
  EXPECT_FALSE(adapter_->IsPowered());

  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);

  EXPECT_EQ(0, observer.powered_changed_count());
  EXPECT_FALSE(observer.last_powered());

  EXPECT_FALSE(adapter_->IsPowered());
}

TEST_F(BluetoothBlueZTest, ChangeAdapterName) {
  GetAdapter();

  const std::string new_name(".__.");

  adapter_->SetName(new_name, GetCallback(), GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  EXPECT_EQ(new_name, adapter_->GetName());
}

TEST_F(BluetoothBlueZTest, ChangeAdapterNameWhenNotPresent) {
  GetAdapter();
  ASSERT_TRUE(adapter_->IsPresent());

  // Install an observer; expect the AdapterPresentChanged to be called
  // with false, and IsPresent() to return false.
  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_adapter_client_->SetVisible(false);

  EXPECT_EQ(1, observer.present_changed_count());
  EXPECT_FALSE(observer.last_present());

  EXPECT_FALSE(adapter_->IsPresent());
  EXPECT_FALSE(adapter_->IsPowered());

  adapter_->SetName("^o^", GetCallback(), GetErrorCallback());
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);

  EXPECT_EQ("", adapter_->GetName());
}

TEST_F(BluetoothBlueZTest, GetUUIDs) {
  std::vector<std::string> adapterUuids;
  GetAdapter();

  adapterUuids.push_back(kGapUuid);
  adapterUuids.push_back(kGattUuid);
  adapterUuids.push_back(kPnpUuid);
  adapterUuids.push_back(kHeadsetUuid);

  fake_bluetooth_adapter_client_->SetUUIDs(adapterUuids);

  BluetoothAdapter::UUIDList uuids = adapter_->GetUUIDs();

  ASSERT_EQ(4U, uuids.size());
  // Check that the UUIDs match those from above - in order, GAP, GATT, PnP, and
  // headset.
  EXPECT_EQ(uuids[0], BluetoothUUID("1800"));
  EXPECT_EQ(uuids[1], BluetoothUUID("1801"));
  EXPECT_EQ(uuids[2], BluetoothUUID("1200"));
  EXPECT_EQ(uuids[3], BluetoothUUID("1112"));
}

TEST_F(BluetoothBlueZTest, BecomeDiscoverable) {
  GetAdapter();
  ASSERT_FALSE(adapter_->IsDiscoverable());

  // Install an observer; expect the AdapterDiscoverableChanged to be called
  // with true, and IsDiscoverable() to return true.
  TestBluetoothAdapterObserver observer(adapter_);

  adapter_->SetDiscoverable(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  EXPECT_EQ(1, observer.discoverable_changed_count());

  EXPECT_TRUE(adapter_->IsDiscoverable());
}

TEST_F(BluetoothBlueZTest, BecomeNotDiscoverable) {
  GetAdapter();
  adapter_->SetDiscoverable(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  ASSERT_TRUE(adapter_->IsDiscoverable());

  // Install an observer; expect the AdapterDiscoverableChanged to be called
  // with false, and IsDiscoverable() to return false.
  TestBluetoothAdapterObserver observer(adapter_);

  adapter_->SetDiscoverable(false, GetCallback(), GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  EXPECT_EQ(1, observer.discoverable_changed_count());

  EXPECT_FALSE(adapter_->IsDiscoverable());
}

TEST_F(BluetoothBlueZTest, SetDiscoverableWhenNotPresent) {
  GetAdapter();
  ASSERT_TRUE(adapter_->IsPresent());
  ASSERT_FALSE(adapter_->IsDiscoverable());

  // Install an observer; expect the AdapterDiscoverableChanged to be called
  // with true, and IsDiscoverable() to return true.
  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_adapter_client_->SetVisible(false);

  EXPECT_EQ(1, observer.present_changed_count());
  EXPECT_FALSE(observer.last_present());

  EXPECT_FALSE(adapter_->IsPresent());
  EXPECT_FALSE(adapter_->IsDiscoverable());

  adapter_->SetDiscoverable(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);

  EXPECT_EQ(0, observer.discoverable_changed_count());

  EXPECT_FALSE(adapter_->IsDiscoverable());
}

TEST_F(BluetoothBlueZTest, StopDiscovery) {
  GetAdapter();

  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  base::RunLoop().Run();
  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  ASSERT_TRUE(discovery_sessions_[0]->IsActive());

  // Install an observer; aside from the callback, expect the
  // AdapterDiscoveringChanged method to be called and no longer to be
  // discovering,
  TestBluetoothAdapterObserver observer(adapter_);

  discovery_sessions_[0]->Stop(GetCallback(), GetErrorCallback());
  base::RunLoop().Run();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_FALSE(observer.last_discovering());

  EXPECT_FALSE(adapter_->IsDiscovering());
  discovery_sessions_.clear();
  callback_count_ = 0;

  // Test that the Stop callbacks get called even if the
  // BluetoothDiscoverySession objects gets deleted
  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  base::RunLoop().Run();
  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;
  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  ASSERT_TRUE(discovery_sessions_[0]->IsActive());

  discovery_sessions_[0]->Stop(GetCallback(), GetErrorCallback());
  discovery_sessions_.clear();

  base::RunLoop().Run();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
}

TEST_F(BluetoothBlueZTest, StopDiscoveryInProgress) {
  GetAdapter();

  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());

  callback_count_ = 0;
  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  base::RunLoop().Run();
  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;
  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  ASSERT_TRUE(discovery_sessions_[0]->IsActive());

  // First call to Stop() should succeed.
  discovery_sessions_[0]->Stop(GetCallback(), GetErrorCallback());
  // Second call to Stop() while the first is in progress should fail.
  discovery_sessions_[0]->Stop(GetCallback(), GetErrorCallback());

  base::RunLoop().Run();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  discovery_sessions_.clear();
  callback_count_ = 0;
  error_callback_count_ = 0;
}

TEST_F(BluetoothBlueZTest, Discovery) {
  // Test a simulated discovery session.
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
  GetAdapter();

  TestBluetoothAdapterObserver observer(adapter_);

  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  base::RunLoop().Run();
  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  ASSERT_TRUE(discovery_sessions_[0]->IsActive());

  // First two devices to appear.
  base::RunLoop().Run();

  EXPECT_EQ(2, observer.device_added_count());
  EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress,
            observer.last_device_address());

  // Next we should get another two devices...
  base::RunLoop().Run();
  EXPECT_EQ(4, observer.device_added_count());

  // Okay, let's run forward until a device is actually removed...
  while (!observer.device_removed_count())
    base::RunLoop().Run();

  EXPECT_EQ(1, observer.device_removed_count());
  EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kVanishingDeviceAddress,
            observer.last_device_address());
}

TEST_F(BluetoothBlueZTest, PoweredAndDiscovering) {
  GetAdapter();
  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  base::RunLoop().Run();
  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  ASSERT_TRUE(discovery_sessions_[0]->IsActive());

  // Stop the timers that the simulation uses
  fake_bluetooth_device_client_->EndDiscoverySimulation(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath));

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_TRUE(adapter_->IsDiscovering());

  fake_bluetooth_adapter_client_->SetVisible(false);
  ASSERT_FALSE(adapter_->IsPresent());
  ASSERT_FALSE(discovery_sessions_[0]->IsActive());

  // Install an observer; expect the AdapterPresentChanged,
  // AdapterPoweredChanged and AdapterDiscoveringChanged methods to be called
  // with true, and IsPresent(), IsPowered() and IsDiscovering() to all
  // return true.
  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_adapter_client_->SetVisible(true);

  EXPECT_EQ(1, observer.present_changed_count());
  EXPECT_TRUE(observer.last_present());
  EXPECT_TRUE(adapter_->IsPresent());

  EXPECT_EQ(1, observer.powered_changed_count());
  EXPECT_TRUE(observer.last_powered());
  EXPECT_TRUE(adapter_->IsPowered());

  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());

  observer.Reset();

  // Now mark the adapter not present again. Expect the methods to be called
  // again, to reset the properties back to false
  fake_bluetooth_adapter_client_->SetVisible(false);

  EXPECT_EQ(1, observer.present_changed_count());
  EXPECT_FALSE(observer.last_present());
  EXPECT_FALSE(adapter_->IsPresent());

  EXPECT_EQ(1, observer.powered_changed_count());
  EXPECT_FALSE(observer.last_powered());
  EXPECT_FALSE(adapter_->IsPowered());

  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());
}

// This unit test asserts that the basic reference counting logic works
// correctly for discovery requests done via the BluetoothAdapter.
TEST_F(BluetoothBlueZTest, MultipleDiscoverySessions) {
  GetAdapter();
  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(adapter_->IsPowered());
  callback_count_ = 0;

  TestBluetoothAdapterObserver observer(adapter_);

  EXPECT_EQ(0, observer.discovering_changed_count());
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());

  // Request device discovery 3 times.
  for (int i = 0; i < 3; i++) {
    adapter_->StartDiscoverySession(
        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                   base::Unretained(this)),
        GetErrorCallback());
  }
  // Run only once, as there should have been one D-Bus call.
  base::RunLoop().Run();

  // The observer should have received the discovering changed event exactly
  // once, the success callback should have been called 3 times and the adapter
  // should be discovering.
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_EQ(3, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)3, discovery_sessions_.size());

  // Request to stop discovery twice.
  for (int i = 0; i < 2; i++) {
    discovery_sessions_[i]->Stop(GetCallback(), GetErrorCallback());
  }

  // The observer should have received no additional discovering changed events,
  // the success callback should have been called 2 times and the adapter should
  // still be discovering.
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_EQ(5, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
  EXPECT_FALSE(discovery_sessions_[1]->IsActive());
  EXPECT_TRUE(discovery_sessions_[2]->IsActive());

  // Request device discovery 3 times.
  for (int i = 0; i < 3; i++) {
    adapter_->StartDiscoverySession(
        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                   base::Unretained(this)),
        GetErrorCallback());
  }

  // The observer should have received no additional discovering changed events,
  // the success callback should have been called 3 times and the adapter should
  // still be discovering.
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_EQ(8, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)6, discovery_sessions_.size());

  // Request to stop discovery 4 times.
  for (int i = 2; i < 6; i++) {
    discovery_sessions_[i]->Stop(GetCallback(), GetErrorCallback());
  }
  // Run only once, as there should have been one D-Bus call.
  base::RunLoop().Run();

  // The observer should have received the discovering changed event exactly
  // once, the success callback should have been called 4 times and the adapter
  // should no longer be discovering.
  EXPECT_EQ(2, observer.discovering_changed_count());
  EXPECT_EQ(12, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());

  // All discovery sessions should be inactive.
  for (int i = 0; i < 6; i++)
    EXPECT_FALSE(discovery_sessions_[i]->IsActive());

  // Request to stop discovery on of the inactive sessions.
  discovery_sessions_[0]->Stop(GetCallback(), GetErrorCallback());

  // The call should have failed.
  EXPECT_EQ(2, observer.discovering_changed_count());
  EXPECT_EQ(12, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());
}

// This unit test asserts that the reference counting logic works correctly in
// the cases when the adapter gets reset and D-Bus calls are made outside of
// the BluetoothAdapter.
TEST_F(BluetoothBlueZTest, UnexpectedChangesDuringMultipleDiscoverySessions) {
  GetAdapter();
  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(adapter_->IsPowered());
  callback_count_ = 0;

  TestBluetoothAdapterObserver observer(adapter_);

  EXPECT_EQ(0, observer.discovering_changed_count());
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());

  // Request device discovery 3 times.
  for (int i = 0; i < 3; i++) {
    adapter_->StartDiscoverySession(
        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                   base::Unretained(this)),
        GetErrorCallback());
  }
  // Run only once, as there should have been one D-Bus call.
  base::RunLoop().Run();

  // The observer should have received the discovering changed event exactly
  // once, the success callback should have been called 3 times and the adapter
  // should be discovering.
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_EQ(3, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)3, discovery_sessions_.size());

  for (int i = 0; i < 3; i++)
    EXPECT_TRUE(discovery_sessions_[i]->IsActive());

  // Stop the timers that the simulation uses
  fake_bluetooth_device_client_->EndDiscoverySimulation(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath));

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_TRUE(adapter_->IsDiscovering());

  // Stop device discovery behind the adapter. The adapter and the observer
  // should be notified of the change and the reference count should be reset.
  // Even though bluez::FakeBluetoothAdapterClient does its own reference
  // counting and
  // we called 3 BluetoothAdapter::StartDiscoverySession 3 times, the
  // bluez::FakeBluetoothAdapterClient's count should be only 1 and a single
  // call to
  // bluez::FakeBluetoothAdapterClient::StopDiscovery should work.
  fake_bluetooth_adapter_client_->StopDiscovery(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                base::Unretained(this)));
  base::RunLoop().Run();
  EXPECT_EQ(2, observer.discovering_changed_count());
  EXPECT_EQ(4, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());

  // All discovery session instances should have been updated.
  for (int i = 0; i < 3; i++)
    EXPECT_FALSE(discovery_sessions_[i]->IsActive());
  discovery_sessions_.clear();

  // It should be possible to successfully start discovery.
  for (int i = 0; i < 2; i++) {
    adapter_->StartDiscoverySession(
        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                   base::Unretained(this)),
        GetErrorCallback());
  }
  // Run only once, as there should have been one D-Bus call.
  base::RunLoop().Run();
  EXPECT_EQ(3, observer.discovering_changed_count());
  EXPECT_EQ(6, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)2, discovery_sessions_.size());

  for (int i = 0; i < 2; i++)
    EXPECT_TRUE(discovery_sessions_[i]->IsActive());

  fake_bluetooth_device_client_->EndDiscoverySimulation(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath));

  // Make the adapter disappear and appear. This will make it come back as
  // discovering. When this happens, the reference count should become and
  // remain 0 as no new request was made through the BluetoothAdapter.
  fake_bluetooth_adapter_client_->SetVisible(false);
  ASSERT_FALSE(adapter_->IsPresent());
  EXPECT_EQ(4, observer.discovering_changed_count());
  EXPECT_EQ(6, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());

  for (int i = 0; i < 2; i++)
    EXPECT_FALSE(discovery_sessions_[i]->IsActive());
  discovery_sessions_.clear();

  fake_bluetooth_adapter_client_->SetVisible(true);
  ASSERT_TRUE(adapter_->IsPresent());
  EXPECT_EQ(5, observer.discovering_changed_count());
  EXPECT_EQ(6, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());

  // Start and stop discovery. At this point, bluez::FakeBluetoothAdapterClient
  // has
  // a reference count that is equal to 1. Pretend that this was done by an
  // application other than us. Starting and stopping discovery will succeed
  // but it won't cause the discovery state to change.
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  // Run the loop, as there should have been a D-Bus call.
  base::RunLoop().Run();
  EXPECT_EQ(5, observer.discovering_changed_count());
  EXPECT_EQ(7, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  EXPECT_TRUE(discovery_sessions_[0]->IsActive());

  discovery_sessions_[0]->Stop(GetCallback(), GetErrorCallback());
  // Run the loop, as there should have been a D-Bus call.
  base::RunLoop().Run();
  EXPECT_EQ(5, observer.discovering_changed_count());
  EXPECT_EQ(8, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
  discovery_sessions_.clear();

  // Start discovery again.
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  // Run the loop, as there should have been a D-Bus call.
  base::RunLoop().Run();
  EXPECT_EQ(5, observer.discovering_changed_count());
  EXPECT_EQ(9, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  EXPECT_TRUE(discovery_sessions_[0]->IsActive());

  // Stop discovery via D-Bus. The fake client's reference count will drop but
  // the discovery state won't change since our BluetoothAdapter also just
  // requested it via D-Bus.
  fake_bluetooth_adapter_client_->StopDiscovery(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                base::Unretained(this)));
  base::RunLoop().Run();
  EXPECT_EQ(5, observer.discovering_changed_count());
  EXPECT_EQ(10, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());

  // Now end the discovery session. This should change the adapter's discovery
  // state.
  discovery_sessions_[0]->Stop(GetCallback(), GetErrorCallback());
  base::RunLoop().Run();
  EXPECT_EQ(6, observer.discovering_changed_count());
  EXPECT_EQ(11, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());
  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
}

TEST_F(BluetoothBlueZTest, InvalidatedDiscoverySessions) {
  GetAdapter();
  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(adapter_->IsPowered());
  callback_count_ = 0;

  TestBluetoothAdapterObserver observer(adapter_);

  EXPECT_EQ(0, observer.discovering_changed_count());
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());

  // Request device discovery 3 times.
  for (int i = 0; i < 3; i++) {
    adapter_->StartDiscoverySession(
        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                   base::Unretained(this)),
        GetErrorCallback());
  }
  // Run only once, as there should have been one D-Bus call.
  base::RunLoop().Run();

  // The observer should have received the discovering changed event exactly
  // once, the success callback should have been called 3 times and the adapter
  // should be discovering.
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_EQ(3, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)3, discovery_sessions_.size());

  for (int i = 0; i < 3; i++)
    EXPECT_TRUE(discovery_sessions_[i]->IsActive());

  // Stop the timers that the simulation uses
  fake_bluetooth_device_client_->EndDiscoverySimulation(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath));

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_TRUE(adapter_->IsDiscovering());

  // Delete all but one discovery session.
  discovery_sessions_.pop_back();
  discovery_sessions_.pop_back();
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  EXPECT_TRUE(discovery_sessions_[0]->IsActive());
  EXPECT_TRUE(adapter_->IsDiscovering());

  // Stop device discovery behind the adapter. The one active discovery session
  // should become inactive, but more importantly, we shouldn't run into any
  // memory errors as the sessions that we explicitly deleted should get
  // cleaned up.
  fake_bluetooth_adapter_client_->StopDiscovery(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                base::Unretained(this)));
  base::RunLoop().Run();
  EXPECT_EQ(2, observer.discovering_changed_count());
  EXPECT_EQ(4, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());
  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
}

TEST_F(BluetoothBlueZTest, QueuedDiscoveryRequests) {
  GetAdapter();

  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(adapter_->IsPowered());
  callback_count_ = 0;

  TestBluetoothAdapterObserver observer(adapter_);

  EXPECT_EQ(0, observer.discovering_changed_count());
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());

  // Request to start discovery. The call should be pending.
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  EXPECT_EQ(0, callback_count_);

  fake_bluetooth_device_client_->EndDiscoverySimulation(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath));

  // The underlying adapter has started discovery, but our call hasn't returned
  // yet.
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  EXPECT_TRUE(discovery_sessions_.empty());

  // Request to start discovery twice. These should get queued and there should
  // be no change in state.
  for (int i = 0; i < 2; i++) {
    adapter_->StartDiscoverySession(
        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                   base::Unretained(this)),
        GetErrorCallback());
  }
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  EXPECT_TRUE(discovery_sessions_.empty());

  // Process the pending call. The queued calls should execute and the discovery
  // session reference count should increase.
  base::RunLoop().Run();
  EXPECT_EQ(3, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)3, discovery_sessions_.size());

  // Verify the reference count by removing sessions 3 times. The last request
  // should remain pending.
  for (int i = 0; i < 3; i++) {
    discovery_sessions_[i]->Stop(GetCallback(), GetErrorCallback());
  }
  EXPECT_EQ(5, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(2, observer.discovering_changed_count());
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());
  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
  EXPECT_FALSE(discovery_sessions_[1]->IsActive());
  EXPECT_TRUE(discovery_sessions_[2]->IsActive());

  // Request to stop the session whose call is pending should fail.
  discovery_sessions_[2]->Stop(GetCallback(), GetErrorCallback());
  EXPECT_EQ(5, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(2, observer.discovering_changed_count());
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());
  EXPECT_TRUE(discovery_sessions_[2]->IsActive());

  // Request to start should get queued.
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  EXPECT_EQ(5, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(2, observer.discovering_changed_count());
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)3, discovery_sessions_.size());

  // Run the pending request.
  base::RunLoop().Run();
  EXPECT_EQ(6, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(3, observer.discovering_changed_count());
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)3, discovery_sessions_.size());
  EXPECT_FALSE(discovery_sessions_[2]->IsActive());

  // The queued request to start discovery should have been issued but is still
  // pending. Run the loop and verify.
  base::RunLoop().Run();
  EXPECT_EQ(7, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(3, observer.discovering_changed_count());
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)4, discovery_sessions_.size());
  EXPECT_TRUE(discovery_sessions_[3]->IsActive());
}

TEST_F(BluetoothBlueZTest, StartDiscoverySession) {
  GetAdapter();

  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(adapter_->IsPowered());
  callback_count_ = 0;

  TestBluetoothAdapterObserver observer(adapter_);

  EXPECT_EQ(0, observer.discovering_changed_count());
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());
  EXPECT_TRUE(discovery_sessions_.empty());

  // Request a new discovery session.
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  base::RunLoop().Run();
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  EXPECT_TRUE(discovery_sessions_[0]->IsActive());

  // Start another session. A new one should be returned in the callback, which
  // in turn will destroy the previous session. Adapter should still be
  // discovering and the reference count should be 1.
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  base::RunLoop().Run();
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)2, discovery_sessions_.size());
  EXPECT_TRUE(discovery_sessions_[0]->IsActive());

  // Request a new session.
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  base::RunLoop().Run();
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_EQ(3, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)3, discovery_sessions_.size());
  EXPECT_TRUE(discovery_sessions_[1]->IsActive());
  EXPECT_NE(discovery_sessions_[0], discovery_sessions_[1]);

  // Stop the previous discovery session. The session should end but discovery
  // should continue.
  discovery_sessions_[0]->Stop(GetCallback(), GetErrorCallback());
  base::RunLoop().Run();
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_EQ(4, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(observer.last_discovering());
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)3, discovery_sessions_.size());
  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
  EXPECT_TRUE(discovery_sessions_[1]->IsActive());

  // Delete the current active session. Discovery should eventually stop.
  discovery_sessions_.clear();
  while (observer.last_discovering())
    base::RunLoop().RunUntilIdle();

  EXPECT_EQ(2, observer.discovering_changed_count());
  EXPECT_EQ(4, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_FALSE(observer.last_discovering());
  EXPECT_FALSE(adapter_->IsDiscovering());
}

TEST_F(BluetoothBlueZTest, SetDiscoveryFilterBeforeStartDiscovery) {
  // Test a simulated discovery session.
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
  GetAdapter();

  TestBluetoothAdapterObserver observer(adapter_);

  BluetoothDiscoveryFilter* df =
      new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
  df->SetRSSI(-60);
  df->AddUUID(BluetoothUUID("1000"));
  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(df);

  adapter_->SetPowered(
      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
  adapter_->StartDiscoverySessionWithFilter(
      std::move(discovery_filter),
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
  base::RunLoop().Run();
  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  ASSERT_TRUE(discovery_sessions_[0]->IsActive());
  ASSERT_TRUE(df->Equals(*discovery_sessions_[0]->GetDiscoveryFilter()));

  auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_NE(nullptr, filter);
  EXPECT_EQ("le", *filter->transport);
  EXPECT_EQ(-60, *filter->rssi);
  EXPECT_EQ(nullptr, filter->pathloss.get());
  std::vector<std::string> uuids = *filter->uuids;
  EXPECT_TRUE(base::ContainsValue(uuids, "1000"));

  discovery_sessions_[0]->Stop(
      base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_FALSE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  ASSERT_FALSE(discovery_sessions_[0]->IsActive());
  ASSERT_EQ(discovery_sessions_[0]->GetDiscoveryFilter(),
            (BluetoothDiscoveryFilter*)nullptr);

  filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_EQ(nullptr, filter);
}

TEST_F(BluetoothBlueZTest, SetDiscoveryFilterBeforeStartDiscoveryFail) {
  // Test a simulated discovery session.
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
  GetAdapter();

  TestBluetoothAdapterObserver observer(adapter_);

  BluetoothDiscoveryFilter* df =
      new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
  df->SetRSSI(-60);
  df->AddUUID(BluetoothUUID("1000"));
  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(df);

  adapter_->SetPowered(
      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
  EXPECT_EQ(1, callback_count_);
  callback_count_ = 0;

  fake_bluetooth_adapter_client_->MakeSetDiscoveryFilterFail();

  adapter_->StartDiscoverySessionWithFilter(
      std::move(discovery_filter),
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  base::RunLoop().Run();

  EXPECT_EQ(1, error_callback_count_);
  error_callback_count_ = 0;

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_FALSE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)0, discovery_sessions_.size());

  auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_EQ(nullptr, filter);
}

// This test queues two requests to StartDiscovery with pre set filter. This
// should result in SetDiscoveryFilter, then StartDiscovery, and SetDiscovery
// DBus calls
TEST_F(BluetoothBlueZTest, QueuedSetDiscoveryFilterBeforeStartDiscovery) {
  // Test a simulated discovery session.
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
  GetAdapter();

  TestBluetoothAdapterObserver observer(adapter_);

  BluetoothDiscoveryFilter* df =
      new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
  df->SetRSSI(-60);
  df->AddUUID(BluetoothUUID("1000"));
  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(df);

  BluetoothDiscoveryFilter* df2 =
      new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_CLASSIC);
  df2->SetRSSI(-65);
  df2->AddUUID(BluetoothUUID("1002"));
  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter2(df2);

  adapter_->SetPowered(
      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  // Queue two requests to start discovery session with filter.
  adapter_->StartDiscoverySessionWithFilter(
      std::move(discovery_filter),
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  adapter_->StartDiscoverySessionWithFilter(
      std::move(discovery_filter2),
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  // Run requests, on DBus level there should be call SetDiscoveryFilter, then
  // StartDiscovery, then SetDiscoveryFilter again.
  base::RunLoop().Run();
  base::RunLoop().Run();

  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)2, discovery_sessions_.size());
  ASSERT_TRUE(discovery_sessions_[0]->IsActive());
  ASSERT_TRUE(df->Equals(*discovery_sessions_[0]->GetDiscoveryFilter()));
  ASSERT_TRUE(discovery_sessions_[1]->IsActive());
  ASSERT_TRUE(df2->Equals(*discovery_sessions_[1]->GetDiscoveryFilter()));

  auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_NE(nullptr, filter);
  EXPECT_EQ("auto", *filter->transport);
  EXPECT_EQ(-65, *filter->rssi);
  EXPECT_EQ(nullptr, filter->pathloss.get());
  auto uuids = *filter->uuids;
  EXPECT_TRUE(base::ContainsValue(uuids, "1000"));
  EXPECT_TRUE(base::ContainsValue(uuids, "1002"));

  discovery_sessions_[0]->Stop(
      base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  discovery_sessions_[1]->Stop(
      base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  base::RunLoop().Run();

  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_FALSE(adapter_->IsDiscovering());
  ASSERT_FALSE(discovery_sessions_[0]->IsActive());
  ASSERT_EQ(discovery_sessions_[0]->GetDiscoveryFilter(),
            (BluetoothDiscoveryFilter*)nullptr);
  ASSERT_FALSE(discovery_sessions_[1]->IsActive());
  ASSERT_EQ(discovery_sessions_[1]->GetDiscoveryFilter(),
            (BluetoothDiscoveryFilter*)nullptr);

  filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_EQ(nullptr, filter);
}

// Call StartFilteredDiscovery twice (2nd time while 1st call is still pending).
// Make the first SetDiscoveryFilter fail and the second one succeed. It should
// end up with one active discovery session.
TEST_F(BluetoothBlueZTest, QueuedSetDiscoveryFilterBeforeStartDiscoveryFail) {
  // Test a simulated discovery session.
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
  GetAdapter();

  TestBluetoothAdapterObserver observer(adapter_);

  BluetoothDiscoveryFilter* df =
      new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
  df->SetRSSI(-60);
  df->AddUUID(BluetoothUUID("1000"));
  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(df);

  BluetoothDiscoveryFilter* df2 =
      new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_CLASSIC);
  df2->SetRSSI(-65);
  df2->AddUUID(BluetoothUUID("1002"));
  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter2(df2);

  adapter_->SetPowered(
      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  fake_bluetooth_adapter_client_->MakeSetDiscoveryFilterFail();

  // Queue two requests to start discovery session with filter.
  adapter_->StartDiscoverySessionWithFilter(
      std::move(discovery_filter),
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  adapter_->StartDiscoverySessionWithFilter(
      std::move(discovery_filter2),
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  base::RunLoop().Run();

  // First request to SetDiscoveryFilter should fail, resulting in no session
  // being created.
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  error_callback_count_ = 0;

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_FALSE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)0, discovery_sessions_.size());

  base::RunLoop().Run();

  // Second request should succeed
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  ASSERT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  ASSERT_TRUE(discovery_sessions_[0]->IsActive());
  ASSERT_TRUE(df2->Equals(*discovery_sessions_[0]->GetDiscoveryFilter()));

  auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_NE(nullptr, filter);
  EXPECT_EQ("bredr", *filter->transport);
  EXPECT_EQ(-65, *filter->rssi);
  EXPECT_EQ(nullptr, filter->pathloss.get());
  auto uuids = *filter->uuids;
  EXPECT_TRUE(base::ContainsValue(uuids, "1002"));

  discovery_sessions_[0]->Stop(
      base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_FALSE(adapter_->IsDiscovering());
  ASSERT_FALSE(discovery_sessions_[0]->IsActive());
  ASSERT_EQ(discovery_sessions_[0]->GetDiscoveryFilter(),
            (BluetoothDiscoveryFilter*)nullptr);

  filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_EQ(nullptr, filter);
}

TEST_F(BluetoothBlueZTest, SetDiscoveryFilterAfterStartDiscovery) {
  // Test a simulated discovery session.
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
  GetAdapter();

  TestBluetoothAdapterObserver observer(adapter_);

  adapter_->SetPowered(
      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
  base::RunLoop().Run();
  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  ASSERT_TRUE(discovery_sessions_[0]->IsActive());
  EXPECT_EQ(1, observer.discovering_changed_count());
  observer.Reset();

  auto null_instance = std::unique_ptr<BluetoothDiscoveryFilter>();
  null_instance.reset();
  ASSERT_EQ(discovery_sessions_[0]->GetDiscoveryFilter(), null_instance.get());

  auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_EQ(nullptr, filter);

  BluetoothDiscoveryFilter* df =
      new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
  df->SetRSSI(-60);
  df->AddUUID(BluetoothUUID("1000"));
  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(df);

  discovery_sessions_[0]->SetDiscoveryFilter(
      std::move(discovery_filter),
      base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  base::RunLoop().Run();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  ASSERT_TRUE(df->Equals(*discovery_sessions_[0]->GetDiscoveryFilter()));

  filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_NE(nullptr, filter);
  EXPECT_EQ("le", *filter->transport);
  EXPECT_EQ(-60, *filter->rssi);
  EXPECT_EQ(nullptr, filter->pathloss.get());
  std::vector<std::string> uuids = *filter->uuids;
  EXPECT_TRUE(base::ContainsValue(uuids, "1000"));

  discovery_sessions_[0]->Stop(
      base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  ASSERT_TRUE(adapter_->IsPowered());
  ASSERT_FALSE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  ASSERT_FALSE(discovery_sessions_[0]->IsActive());
  ASSERT_EQ(discovery_sessions_[0]->GetDiscoveryFilter(),
            (BluetoothDiscoveryFilter*)nullptr);

  filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_EQ(nullptr, filter);
}

// This unit test asserts that the basic reference counting, and filter merging
// works correctly for discovery requests done via the BluetoothAdapter.
TEST_F(BluetoothBlueZTest, SetDiscoveryFilterBeforeStartDiscoveryMultiple) {
  GetAdapter();
  adapter_->SetPowered(
      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(adapter_->IsPowered());
  callback_count_ = 0;

  TestBluetoothAdapterObserver observer(adapter_);

  // Request device discovery with pre-set filter 3 times.
  for (int i = 0; i < 3; i++) {
    std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter;
    if (i == 0) {
      BluetoothDiscoveryFilter* df =
          new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
      df->SetRSSI(-85);
      df->AddUUID(BluetoothUUID("1000"));
      discovery_filter.reset(df);
    } else if (i == 1) {
      BluetoothDiscoveryFilter* df =
          new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
      df->SetRSSI(-60);
      df->AddUUID(BluetoothUUID("1020"));
      df->AddUUID(BluetoothUUID("1001"));
      discovery_filter.reset(df);
    } else if (i == 2) {
      BluetoothDiscoveryFilter* df =
          new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
      df->SetRSSI(-65);
      df->AddUUID(BluetoothUUID("1020"));
      df->AddUUID(BluetoothUUID("1003"));
      discovery_filter.reset(df);
    }

    adapter_->StartDiscoverySessionWithFilter(
        std::move(discovery_filter),
        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                   base::Unretained(this)),
        base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

    base::RunLoop().Run();

    if (i == 0) {
      EXPECT_EQ(1, observer.discovering_changed_count());
      observer.Reset();

      auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
      EXPECT_EQ("le", *filter->transport);
      EXPECT_EQ(-85, *filter->rssi);
      EXPECT_EQ(nullptr, filter->pathloss.get());
      std::vector<std::string> uuids = *filter->uuids;
      EXPECT_TRUE(base::ContainsValue(uuids, "1000"));
    } else if (i == 1) {
      auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
      EXPECT_EQ("le", *filter->transport);
      EXPECT_EQ(-85, *filter->rssi);
      EXPECT_EQ(nullptr, filter->pathloss.get());
      std::vector<std::string> uuids = *filter->uuids;
      EXPECT_TRUE(base::ContainsValue(uuids, "1000"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1001"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1020"));
    } else if (i == 2) {
      auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
      EXPECT_EQ("le", *filter->transport);
      EXPECT_EQ(-85, *filter->rssi);
      EXPECT_EQ(nullptr, filter->pathloss.get());
      std::vector<std::string> uuids = *filter->uuids;
      EXPECT_TRUE(base::ContainsValue(uuids, "1000"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1001"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1003"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1020"));
    }
  }

  // the success callback should have been called 3 times and the adapter should
  // be discovering.
  EXPECT_EQ(3, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)3, discovery_sessions_.size());

  callback_count_ = 0;
  // Request to stop discovery twice.
  for (int i = 0; i < 2; i++) {
    discovery_sessions_[i]->Stop(
        base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
        base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));
    base::RunLoop().Run();

    if (i == 0) {
      auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
      EXPECT_EQ("le", *filter->transport);
      EXPECT_EQ(-65, *filter->rssi);
      EXPECT_EQ(nullptr, filter->pathloss.get());
      std::vector<std::string> uuids = *filter->uuids;
      EXPECT_EQ(3UL, uuids.size());
      EXPECT_FALSE(base::ContainsValue(uuids, "1000"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1001"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1003"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1020"));
    } else if (i == 1) {
      auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
      EXPECT_EQ("le", *filter->transport);
      EXPECT_EQ(-65, *filter->rssi);
      EXPECT_EQ(nullptr, filter->pathloss.get());
      std::vector<std::string> uuids = *filter->uuids;
      EXPECT_EQ(2UL, uuids.size());
      EXPECT_FALSE(base::ContainsValue(uuids, "1000"));
      EXPECT_FALSE(base::ContainsValue(uuids, "1001"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1003"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1020"));
    } else if (i == 2) {
      auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
      EXPECT_EQ("le", *filter->transport);
      EXPECT_EQ(-65, *filter->rssi);
      EXPECT_EQ(nullptr, filter->pathloss.get());
      std::vector<std::string> uuids = *filter->uuids;
      EXPECT_EQ(0UL, uuids.size());
    }
  }

  // The success callback should have been called 2 times and the adapter should
  // still be discovering.
  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(adapter_->IsDiscovering());
  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
  EXPECT_FALSE(discovery_sessions_[1]->IsActive());
  EXPECT_TRUE(discovery_sessions_[2]->IsActive());

  callback_count_ = 0;

  // Request device discovery 3 times.
  for (int i = 0; i < 3; i++) {
    std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter;

    if (i == 0) {
      BluetoothDiscoveryFilter* df =
          new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
      df->SetRSSI(-85);
      df->AddUUID(BluetoothUUID("1000"));
      discovery_filter.reset(df);
    } else if (i == 1) {
      BluetoothDiscoveryFilter* df =
          new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
      df->SetRSSI(-60);
      df->AddUUID(BluetoothUUID("1020"));
      df->AddUUID(BluetoothUUID("1001"));
      discovery_filter.reset(df);
    } else if (i == 2) {
      BluetoothDiscoveryFilter* df =
          new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
      df->SetRSSI(-65);
      df->AddUUID(BluetoothUUID("1020"));
      df->AddUUID(BluetoothUUID("1003"));
      discovery_filter.reset(df);
    }

    adapter_->StartDiscoverySessionWithFilter(
        std::move(discovery_filter),
        base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                   base::Unretained(this)),
        base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

    // each result in 1 requests.
    base::RunLoop().Run();

    if (i == 0) {
      auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
      EXPECT_EQ("le", *filter->transport);
      EXPECT_EQ(-85, *filter->rssi);
      EXPECT_EQ(nullptr, filter->pathloss.get());
      std::vector<std::string> uuids = *filter->uuids;
      EXPECT_TRUE(base::ContainsValue(uuids, "1000"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1003"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1020"));
    } else if (i == 1 || i == 2) {
      auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
      EXPECT_EQ("le", *filter->transport);
      EXPECT_EQ(-85, *filter->rssi);
      EXPECT_EQ(nullptr, filter->pathloss.get());
      std::vector<std::string> uuids = *filter->uuids;
      EXPECT_TRUE(base::ContainsValue(uuids, "1000"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1001"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1003"));
      EXPECT_TRUE(base::ContainsValue(uuids, "1020"));
    }
  }

  // The success callback should have been called 3 times and the adapter should
  // still be discovering.
  EXPECT_EQ(3, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(adapter_->IsDiscovering());
  ASSERT_EQ((size_t)6, discovery_sessions_.size());

  callback_count_ = 0;
  // Request to stop discovery 4 times.
  for (int i = 2; i < 6; i++) {
    discovery_sessions_[i]->Stop(
        base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
        base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

    // filter no  2 is same as filter no 5, so removing it shouldn't cause any
    // filter update
    if (i != 2 && i != 5)
      base::RunLoop().Run();
  }
  // Run only once, as there should have been one D-Bus call.
  base::RunLoop().Run();

  // The success callback should have been called 4 times and the adapter should
  // no longer be discovering.
  EXPECT_EQ(4, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_FALSE(adapter_->IsDiscovering());
  EXPECT_EQ(1, observer.discovering_changed_count());

  // All discovery sessions should be inactive.
  for (int i = 0; i < 6; i++)
    EXPECT_FALSE(discovery_sessions_[i]->IsActive());

  auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_EQ(nullptr, filter);
}

// This unit test asserts that filter merging logic works correctly for filtered
// discovery requests done via the BluetoothAdapter.
TEST_F(BluetoothBlueZTest, SetDiscoveryFilterMergingTest) {
  GetAdapter();
  adapter_->SetPowered(
      true, base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  BluetoothDiscoveryFilter* df =
      new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
  df->SetRSSI(-15);
  df->AddUUID(BluetoothUUID("1000"));
  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(df);

  adapter_->StartDiscoverySessionWithFilter(
      std::move(discovery_filter),
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  base::RunLoop().Run();

  auto* filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_EQ("le", *filter->transport);
  EXPECT_EQ(-15, *filter->rssi);
  EXPECT_EQ(nullptr, filter->pathloss.get());
  std::vector<std::string> uuids = *filter->uuids;
  EXPECT_TRUE(base::ContainsValue(uuids, "1000"));

  df = new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_LE);
  df->SetRSSI(-60);
  df->AddUUID(BluetoothUUID("1020"));
  df->AddUUID(BluetoothUUID("1001"));
  discovery_filter = std::unique_ptr<BluetoothDiscoveryFilter>(df);

  adapter_->StartDiscoverySessionWithFilter(
      std::move(discovery_filter),
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  base::RunLoop().Run();

  filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_EQ("le", *filter->transport);
  EXPECT_EQ(-60, *filter->rssi);
  EXPECT_EQ(nullptr, filter->pathloss.get());
  uuids = *filter->uuids;
  EXPECT_TRUE(base::ContainsValue(uuids, "1000"));
  EXPECT_TRUE(base::ContainsValue(uuids, "1001"));
  EXPECT_TRUE(base::ContainsValue(uuids, "1020"));

  BluetoothDiscoveryFilter* df3 =
      new BluetoothDiscoveryFilter(device::BLUETOOTH_TRANSPORT_CLASSIC);
  df3->SetRSSI(-65);
  df3->AddUUID(BluetoothUUID("1020"));
  df3->AddUUID(BluetoothUUID("1003"));
  std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter3(df3);

  adapter_->StartDiscoverySessionWithFilter(
      std::move(discovery_filter3),
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  base::RunLoop().Run();

  filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_EQ("auto", *filter->transport);
  EXPECT_EQ(-65, *filter->rssi);
  EXPECT_EQ(nullptr, filter->pathloss.get());
  uuids = *filter->uuids;
  EXPECT_TRUE(base::ContainsValue(uuids, "1000"));
  EXPECT_TRUE(base::ContainsValue(uuids, "1001"));
  EXPECT_TRUE(base::ContainsValue(uuids, "1003"));
  EXPECT_TRUE(base::ContainsValue(uuids, "1020"));

  // start additionally classic scan
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

  base::RunLoop().Run();

  filter = fake_bluetooth_adapter_client_->GetDiscoveryFilter();
  EXPECT_EQ("auto", *filter->transport);
  EXPECT_EQ(nullptr, filter->rssi.get());
  EXPECT_EQ(nullptr, filter->pathloss.get());
  EXPECT_EQ(nullptr, filter->uuids.get());

  // Request to stop discovery 4 times.
  for (int i = 3; i >= 0; i--) {
    discovery_sessions_[i]->Stop(
        base::Bind(&BluetoothBlueZTest::Callback, base::Unretained(this)),
        base::Bind(&BluetoothBlueZTest::ErrorCallback, base::Unretained(this)));

    // Every session stopping would trigger filter update
    base::RunLoop().Run();
  }
}

TEST_F(BluetoothBlueZTest, DeviceProperties) {
  GetAdapter();

  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
  ASSERT_EQ(2U, devices.size());

  int idx = GetDeviceIndexByAddress(
      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_NE(-1, idx);
  ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress,
            devices[idx]->GetAddress());

  // Verify the other device properties.
  EXPECT_EQ(
      base::UTF8ToUTF16(bluez::FakeBluetoothDeviceClient::kPairedDeviceName),
      devices[idx]->GetNameForDisplay());
  EXPECT_EQ(BluetoothDeviceType::COMPUTER, devices[idx]->GetDeviceType());
  EXPECT_TRUE(devices[idx]->IsPaired());
  EXPECT_FALSE(devices[idx]->IsConnected());
  EXPECT_FALSE(devices[idx]->IsConnecting());

  // Non HID devices are always connectable.
  EXPECT_TRUE(devices[idx]->IsConnectable());

  BluetoothDevice::UUIDSet uuids = devices[idx]->GetUUIDs();
  EXPECT_EQ(2U, uuids.size());
  EXPECT_TRUE(base::ContainsKey(uuids, BluetoothUUID("1800")));
  EXPECT_TRUE(base::ContainsKey(uuids, BluetoothUUID("1801")));

  EXPECT_EQ(BluetoothDevice::VENDOR_ID_USB, devices[idx]->GetVendorIDSource());
  EXPECT_EQ(0x05ac, devices[idx]->GetVendorID());
  EXPECT_EQ(0x030d, devices[idx]->GetProductID());
  EXPECT_EQ(0x0306, devices[idx]->GetDeviceID());
}

TEST_F(BluetoothBlueZTest, DeviceClassChanged) {
  // Simulate a change of class of a device, as sometimes occurs
  // during discovery.
  GetAdapter();

  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
  ASSERT_EQ(2U, devices.size());

  int idx = GetDeviceIndexByAddress(
      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_NE(-1, idx);
  ASSERT_EQ(BluetoothDeviceType::COMPUTER, devices[idx]->GetDeviceType());

  // Install an observer; expect the DeviceChanged method to be called when
  // we change the class of the device.
  TestBluetoothAdapterObserver observer(adapter_);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));

  properties->bluetooth_class.ReplaceValue(0x002580);

  EXPECT_EQ(1, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());

  EXPECT_EQ(BluetoothDeviceType::MOUSE, devices[idx]->GetDeviceType());
}

TEST_F(BluetoothBlueZTest, DeviceAppearance) {
  // Simulate a device with appearance.
  GetAdapter();

  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
  ASSERT_EQ(2U, devices.size());

  int idx = GetDeviceIndexByAddress(
      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_NE(-1, idx);
  ASSERT_EQ(BluetoothDeviceType::COMPUTER, devices[idx]->GetDeviceType());

  // Install an observer; expect the DeviceChanged method to be called when
  // we change the appearance of the device.
  TestBluetoothAdapterObserver observer(adapter_);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));

  // Let the device come without bluetooth_class.
  properties->appearance.ReplaceValue(0);  // DeviceChanged method called
  EXPECT_EQ(1, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());

  // Set the device appearance as keyboard (961).
  properties->appearance.ReplaceValue(961);  // DeviceChanged method called
  properties->appearance.set_valid(true);
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());
  EXPECT_EQ(961, devices[idx]->GetAppearance());
  // When discovery is over, the value should be invalidated.
  properties->appearance.set_valid(false);
  // DeviceChanged method called by NotifyPropertyChanged()
  properties->NotifyPropertyChanged(properties->appearance.name());
  EXPECT_EQ(3, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());
  EXPECT_EQ((int)BluetoothDevice::kAppearanceNotPresent,
            devices[idx]->GetAppearance());

  // Change the device appearance to mouse (962).
  properties->appearance.ReplaceValue(962);  // DeviceChanged method called
  properties->appearance.set_valid(true);
  EXPECT_EQ(4, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());
  EXPECT_EQ(962, devices[idx]->GetAppearance());
  // When discovery is over, the value should be invalidated.
  properties->appearance.set_valid(false);
  // DeviceChanged method called by NotifyPropertyChanged()
  properties->NotifyPropertyChanged(properties->appearance.name());
  EXPECT_EQ(5, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());
  EXPECT_EQ((int)BluetoothDevice::kAppearanceNotPresent,
            devices[idx]->GetAppearance());
}

TEST_F(BluetoothBlueZTest, DeviceTypebyAppearanceNotBluetoothClass) {
  // Test device type of a device with appearance but without bluetooth class.
  GetAdapter();

  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
  ASSERT_EQ(2U, devices.size());

  int idx = GetDeviceIndexByAddress(
      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_NE(-1, idx);
  ASSERT_EQ(BluetoothDeviceType::COMPUTER, devices[idx]->GetDeviceType());

  // Install an observer; expect the DeviceChanged method to be called when
  // we change the appearance of the device.
  TestBluetoothAdapterObserver observer(adapter_);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));

  // Let the device come without bluetooth_class.
  properties->bluetooth_class.ReplaceValue(0);  // DeviceChanged method called
  properties->appearance.ReplaceValue(0);       // DeviceChanged method called
  EXPECT_EQ(BluetoothDeviceType::UNKNOWN, devices[idx]->GetDeviceType());
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());

  // Set the device appearance as keyboard.
  properties->appearance.ReplaceValue(961);  // DeviceChanged method called
  properties->appearance.set_valid(true);
  EXPECT_EQ(BluetoothDeviceType::KEYBOARD, devices[idx]->GetDeviceType());
  EXPECT_EQ(3, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());
  // When discovery is over, the value should be invalidated.
  properties->appearance.set_valid(false);
  // DeviceChanged method called by NotifyPropertyChanged()
  properties->NotifyPropertyChanged(properties->appearance.name());
  EXPECT_EQ(4, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());
  EXPECT_EQ(BluetoothDeviceType::UNKNOWN, devices[idx]->GetDeviceType());

  // Change the device appearance to mouse.
  properties->appearance.ReplaceValue(962);  // DeviceChanged method called
  properties->appearance.set_valid(true);
  EXPECT_EQ(BluetoothDeviceType::MOUSE, devices[idx]->GetDeviceType());
  EXPECT_EQ(5, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());
  // When discovery is over, the value should be invalidated.
  properties->appearance.set_valid(false);
  // DeviceChanged method called by NotifyPropertyChanged()
  properties->NotifyPropertyChanged(properties->appearance.name());
  EXPECT_EQ(6, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());
  EXPECT_EQ(BluetoothDeviceType::UNKNOWN, devices[idx]->GetDeviceType());
}

TEST_F(BluetoothBlueZTest, DeviceNameChanged) {
  // Simulate a change of name of a device.
  GetAdapter();

  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
  ASSERT_EQ(2U, devices.size());

  int idx = GetDeviceIndexByAddress(
      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_NE(-1, idx);
  ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress,
            devices[idx]->GetAddress());
  ASSERT_EQ(
      base::UTF8ToUTF16(bluez::FakeBluetoothDeviceClient::kPairedDeviceName),
      devices[idx]->GetNameForDisplay());

  // Install an observer; expect the DeviceChanged method to be called when
  // we change the alias of the device.
  TestBluetoothAdapterObserver observer(adapter_);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));

  const std::string new_name("New Device Name");
  properties->name.ReplaceValue(new_name);

  EXPECT_EQ(1, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());

  EXPECT_EQ(base::UTF8ToUTF16(new_name), devices[idx]->GetNameForDisplay());
}

TEST_F(BluetoothBlueZTest, DeviceAddressChanged) {
  // Simulate a change of address of a device.
  GetAdapter();

  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
  ASSERT_EQ(2U, devices.size());

  int idx = GetDeviceIndexByAddress(
      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_NE(-1, idx);
  ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress,
            devices[idx]->GetAddress());
  ASSERT_EQ(
      base::UTF8ToUTF16(bluez::FakeBluetoothDeviceClient::kPairedDeviceName),
      devices[idx]->GetNameForDisplay());

  // Install an observer; expect the DeviceAddressChanged method to be called
  // when we change the alias of the device.
  TestBluetoothAdapterObserver observer(adapter_);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));

  static const char* kNewAddress = "D9:1F:FC:11:22:33";
  properties->address.ReplaceValue(kNewAddress);

  EXPECT_EQ(1, observer.device_address_changed_count());
  EXPECT_EQ(1, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());

  EXPECT_EQ(std::string(kNewAddress), devices[idx]->GetAddress());
}

#if defined(OS_CHROMEOS) || defined(OS_LINUX)
TEST_F(BluetoothBlueZTest, DevicePairedChanged) {
  // Simulate a change of paired state of a device.
  GetAdapter();

  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
  ASSERT_EQ(2U, devices.size());

  int idx = GetDeviceIndexByAddress(
      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_NE(-1, idx);
  ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress,
            devices[idx]->GetAddress());
  ASSERT_EQ(true, devices[idx]->IsPaired());

  // Install an observer; expect the DevicePairedChanged method to be called
  // when we change the paired state of the device.
  TestBluetoothAdapterObserver observer(adapter_);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));

  properties->paired.ReplaceValue(false);

  EXPECT_EQ(1, observer.device_changed_count());
  EXPECT_EQ(1, observer.device_paired_changed_count());
  EXPECT_FALSE(observer.device_new_paired_status());
  EXPECT_EQ(devices[idx], observer.last_device());

  // Change the paired state back to true to examine the consistent behavior of
  // DevicePairedChanged method.
  properties->paired.ReplaceValue(true);

  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_EQ(2, observer.device_paired_changed_count());
  EXPECT_TRUE(observer.device_new_paired_status());
  EXPECT_EQ(devices[idx], observer.last_device());
}

TEST_F(BluetoothBlueZTest, DeviceMTUChanged) {
  // Simulate a change of MTU of a device.
  GetAdapter();

  fake_bluetooth_device_client_->CreateDevice(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
  BluetoothDevice* device =
      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
  ASSERT_TRUE(device);

  // Install an observer; expect DeviceMTUChanged method to be called with the
  // updated MTU values.
  TestBluetoothAdapterObserver observer(adapter_);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(
          dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
  ASSERT_EQ(0, observer.device_mtu_changed_count());

  properties->mtu.ReplaceValue(258);
  EXPECT_EQ(1, observer.device_mtu_changed_count());
  EXPECT_EQ(258, observer.last_mtu_value());

  properties->mtu.ReplaceValue(128);
  EXPECT_EQ(2, observer.device_mtu_changed_count());
  EXPECT_EQ(128, observer.last_mtu_value());
}
#endif

TEST_F(BluetoothBlueZTest, DeviceUuidsChanged) {
  // Simulate a change of advertised services of a device.
  GetAdapter();

  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
  ASSERT_EQ(2U, devices.size());

  int idx = GetDeviceIndexByAddress(
      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_NE(-1, idx);
  ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress,
            devices[idx]->GetAddress());

  BluetoothDevice::UUIDSet uuids = devices[idx]->GetUUIDs();
  ASSERT_EQ(2U, uuids.size());
  ASSERT_TRUE(base::ContainsKey(uuids, BluetoothUUID("1800")));
  ASSERT_TRUE(base::ContainsKey(uuids, BluetoothUUID("1801")));

  // Install an observer; expect the DeviceChanged method to be called when
  // we change the class of the device.
  TestBluetoothAdapterObserver observer(adapter_);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));

  std::vector<std::string> new_uuids;
  new_uuids.push_back(BluetoothUUID("1800").canonical_value());
  new_uuids.push_back(BluetoothUUID("1801").canonical_value());
  new_uuids.push_back("0000110c-0000-1000-8000-00805f9b34fb");
  new_uuids.push_back("0000110e-0000-1000-8000-00805f9b34fb");
  new_uuids.push_back("0000110a-0000-1000-8000-00805f9b34fb");

  properties->uuids.ReplaceValue(new_uuids);

  EXPECT_EQ(1, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());

  // Fetching the value should give the new one.
  uuids = devices[idx]->GetUUIDs();
  EXPECT_EQ(5U, uuids.size());
  EXPECT_TRUE(base::ContainsKey(uuids, BluetoothUUID("1800")));
  EXPECT_TRUE(base::ContainsKey(uuids, BluetoothUUID("1801")));
  EXPECT_TRUE(base::ContainsKey(uuids, BluetoothUUID("110c")));
  EXPECT_TRUE(base::ContainsKey(uuids, BluetoothUUID("110e")));
  EXPECT_TRUE(base::ContainsKey(uuids, BluetoothUUID("110a")));
}

TEST_F(BluetoothBlueZTest, DeviceInquiryRSSIInvalidated) {
  // Simulate invalidation of inquiry RSSI of a device, as it occurs
  // when discovery is finished.
  GetAdapter();

  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
  ASSERT_EQ(2U, devices.size());

  int idx = GetDeviceIndexByAddress(
      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_NE(-1, idx);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));

  // During discovery, rssi is a valid value (-75)
  properties->rssi.ReplaceValue(-75);
  properties->rssi.set_valid(true);

  ASSERT_EQ(-75, devices[idx]->GetInquiryRSSI().value());

  properties->rssi.ReplaceValue(INT8_MAX + 1);
  ASSERT_EQ(INT8_MAX, devices[idx]->GetInquiryRSSI().value());

  properties->rssi.ReplaceValue(INT8_MIN - 1);
  ASSERT_EQ(INT8_MIN, devices[idx]->GetInquiryRSSI().value());

  // Install an observer; expect the DeviceChanged method to be called when
  // we invalidate the RSSI of the device.
  TestBluetoothAdapterObserver observer(adapter_);

  // When discovery is over, the value should be invalidated.
  properties->rssi.set_valid(false);
  properties->NotifyPropertyChanged(properties->rssi.name());

  EXPECT_EQ(1, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());

  EXPECT_FALSE(devices[idx]->GetInquiryRSSI());
}

TEST_F(BluetoothBlueZTest, DeviceInquiryTxPowerInvalidated) {
  // Simulate invalidation of inquiry TxPower of a device, as it occurs
  // when discovery is finished.
  GetAdapter();

  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
  ASSERT_EQ(2U, devices.size());

  int idx = GetDeviceIndexByAddress(
      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_NE(-1, idx);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));

  // During discovery, tx_power is a valid value (0)
  properties->tx_power.ReplaceValue(0);
  properties->tx_power.set_valid(true);

  ASSERT_EQ(0, devices[idx]->GetInquiryTxPower().value());

  properties->tx_power.ReplaceValue(INT8_MAX + 1);
  ASSERT_EQ(INT8_MAX, devices[idx]->GetInquiryTxPower().value());

  properties->tx_power.ReplaceValue(INT8_MIN - 1);
  ASSERT_EQ(INT8_MIN, devices[idx]->GetInquiryTxPower().value());

  // Install an observer; expect the DeviceChanged method to be called when
  // we invalidate the tx_power of the device.
  TestBluetoothAdapterObserver observer(adapter_);

  // When discovery is over, the value should be invalidated.
  properties->tx_power.set_valid(false);
  properties->NotifyPropertyChanged(properties->tx_power.name());

  EXPECT_EQ(1, observer.device_changed_count());
  EXPECT_EQ(devices[idx], observer.last_device());

  EXPECT_FALSE(devices[idx]->GetInquiryTxPower());
}

TEST_F(BluetoothBlueZTest, ForgetDevice) {
  GetAdapter();

  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
  ASSERT_EQ(2U, devices.size());

  int idx = GetDeviceIndexByAddress(
      devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_NE(-1, idx);
  ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress,
            devices[idx]->GetAddress());

  std::string address = devices[idx]->GetAddress();

  // Install an observer; expect the DeviceRemoved method to be called
  // with the device we remove.
  TestBluetoothAdapterObserver observer(adapter_);

  devices[idx]->Forget(base::DoNothing(), GetErrorCallback());
  EXPECT_EQ(0, error_callback_count_);

  EXPECT_EQ(1, observer.device_removed_count());
  EXPECT_EQ(address, observer.last_device_address());

  // GetDevices shouldn't return the device either.
  devices = adapter_->GetDevices();
  ASSERT_EQ(1U, devices.size());
}

TEST_F(BluetoothBlueZTest, ForgetUnpairedDevice) {
  GetAdapter();
  DiscoverDevices();

  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  // Connect the device so it becomes trusted and remembered.
  device->Connect(nullptr, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  ASSERT_EQ(1, callback_count_);
  ASSERT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  ASSERT_TRUE(device->IsConnected());
  ASSERT_FALSE(device->IsConnecting());

  // Pause discovery to connect without pair.
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kConnectUnpairablePath));
  ASSERT_TRUE(properties->trusted.value());

  // Install an observer; expect the DeviceRemoved method to be called
  // with the device we remove.
  TestBluetoothAdapterObserver observer(adapter_);

  device->Forget(base::DoNothing(), GetErrorCallback());
  EXPECT_EQ(0, error_callback_count_);

  EXPECT_EQ(1, observer.device_removed_count());
  EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress,
            observer.last_device_address());

  // GetDevices shouldn't return the device either.
  device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress);
  EXPECT_FALSE(device != nullptr);
}

TEST_F(BluetoothBlueZTest, ConnectPairedDevice) {
  GetAdapter();

  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_TRUE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  // Connect without a pairing delegate; since the device is already Paired
  // this should succeed and the device should become connected.
  device->Connect(nullptr, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // Two changes for connecting, one for connected and one for for trusted
  // after connecting.
  EXPECT_EQ(4, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());

  // Pause discovery to connect without pair.
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, ConnectUnpairableDevice) {
  GetAdapter();
  DiscoverDevices();

  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  // Connect without a pairing delegate; since the device does not require
  // pairing, this should succeed and the device should become connected.
  device->Connect(nullptr, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // Two changes for connecting, one for connected, one for for trusted after
  // connection, and one for the reconnect mode (IsConnectable).
  EXPECT_EQ(5, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());

  // Pause discovery to connect without pair.
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kConnectUnpairablePath));
  EXPECT_TRUE(properties->trusted.value());

  // Verify is a HID device and is not connectable.
  BluetoothDevice::UUIDSet uuids = device->GetUUIDs();
  EXPECT_EQ(1U, uuids.size());
  EXPECT_TRUE(base::ContainsKey(uuids, BluetoothUUID("1124")));
  EXPECT_FALSE(device->IsConnectable());
}

TEST_F(BluetoothBlueZTest, ConnectConnectedDevice) {
  GetAdapter();

  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_TRUE(device->IsPaired());

  device->Connect(nullptr, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  ASSERT_EQ(1, callback_count_);
  ASSERT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  ASSERT_TRUE(device->IsConnected());

  // Pause discovery to connect without pair.
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());

  // Connect again; since the device is already Connected, this shouldn't do
  // anything to initiate the connection.
  TestBluetoothAdapterObserver observer(adapter_);

  device->Connect(nullptr, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // The observer will be called because Connecting will toggle true and false,
  // and the trusted property will be updated to true.
  EXPECT_EQ(3, observer.device_changed_count());

  EXPECT_TRUE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());

  // Pause discovery to connect without pair.
  EXPECT_EQ(2, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(2, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, ConnectDeviceFails) {
  GetAdapter();
  DiscoverDevices();

  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kLegacyAutopairAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  // Connect without a pairing delegate; since the device requires pairing,
  // this should fail with an error.
  device->Connect(nullptr, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_);

  EXPECT_EQ(2, observer.device_changed_count());

  EXPECT_FALSE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());

  // Pause discovery to connect without pair.
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

// Tests that discovery is unpaused if the device gets removed during a
// connection.
TEST_F(BluetoothBlueZTest, RemoveDeviceDuringConnection) {
  GetAdapter();

  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_TRUE(device != nullptr);

  fake_bluetooth_device_client_->LeaveConnectionsPending();
  device->Connect(nullptr, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));
  // We pause discovery before connecting.
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetUnpauseCount());

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  EXPECT_FALSE(device->IsConnected());
  EXPECT_TRUE(device->IsConnecting());

  // Install an observer; expect the DeviceRemoved method to be called
  // with the device we remove.
  TestBluetoothAdapterObserver observer(adapter_);

  device->Forget(base::DoNothing(), GetErrorCallback());
  EXPECT_EQ(0, error_callback_count_);

  EXPECT_EQ(1, observer.device_removed_count());

  // If the device gets removed, we should still unpause discovery.
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, DisconnectDevice) {
  GetAdapter();

  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_TRUE(device->IsPaired());

  device->Connect(nullptr, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  ASSERT_EQ(1, callback_count_);
  ASSERT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  ASSERT_TRUE(device->IsConnected());
  ASSERT_FALSE(device->IsConnecting());

  // Pause discovery to connect without pair.
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());

  // Disconnect the device, we should see the observer method fire and the
  // device get dropped.
  TestBluetoothAdapterObserver observer(adapter_);

  device->Disconnect(GetCallback(), GetErrorCallback());

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  EXPECT_EQ(1, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_FALSE(device->IsConnected());
}

TEST_F(BluetoothBlueZTest, DisconnectUnconnectedDevice) {
  GetAdapter();

  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_TRUE(device->IsPaired());
  ASSERT_FALSE(device->IsConnected());

  // Disconnect the device, we should see the observer method fire and the
  // device get dropped.
  TestBluetoothAdapterObserver observer(adapter_);

  device->Disconnect(GetCallback(), GetErrorCallback());

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);

  EXPECT_EQ(0, observer.device_changed_count());

  EXPECT_FALSE(device->IsConnected());
}

TEST_F(BluetoothBlueZTest, PairTrustedDevice) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
  GetAdapter();

  fake_bluetooth_device_client_->CreateDevice(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::
                           kConnectedTrustedNotPairedDevicePath));
  BluetoothDevice* device =
      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::
                              kConnectedTrustedNotPairedDeviceAddress);
  ASSERT_TRUE(device != nullptr);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(
          dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::
                               kConnectedTrustedNotPairedDevicePath));
  EXPECT_FALSE(properties->paired.value());
  EXPECT_TRUE(properties->trusted.value());
  ASSERT_FALSE(device->IsPaired());

  // The |kConnectedTrustedNotPairedDevicePath| requests a passkey confirmation.
  // Obs.: This is the flow when CrOS triggers pairing with a iOS device.
  TestBluetoothAdapterObserver observer(adapter_);
  TestPairingDelegate pairing_delegate;
  adapter_->AddPairingDelegate(
      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
  device->Pair(&pairing_delegate, GetCallback(),
               base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                          base::Unretained(this)));
  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
  EXPECT_EQ(123456U, pairing_delegate.last_passkey_);

  // Confirm the passkey.
  device->ConfirmPairing();
  base::RunLoop().Run();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // Make sure the paired property has been set to true.
  properties = fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
      bluez::FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDevicePath));
  EXPECT_TRUE(properties->paired.value());
}

TEST_F(BluetoothBlueZTest, PairAlreadyPairedDevice) {
  GetAdapter();

  fake_bluetooth_device_client_->CreateDevice(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  ASSERT_TRUE(device != nullptr);

  // On the DBus level a device can be trusted but not paired.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));
  EXPECT_TRUE(properties->paired.value());
  EXPECT_TRUE(properties->trusted.value());
  ASSERT_TRUE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);
  TestPairingDelegate pairing_delegate;
  adapter_->AddPairingDelegate(
      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
  device->Pair(&pairing_delegate, GetCallback(),
               base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                          base::Unretained(this)));

  // For already paired devices a call to |Pair| should succeed without calling
  // the pairing delegate.
  EXPECT_EQ(0, pairing_delegate.call_count_);
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
}

TEST_F(BluetoothBlueZTest, PairLegacyAutopair) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // The Legacy Autopair device requires no PIN or Passkey to pair because
  // the daemon provides 0000 to the device for us.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kLegacyAutopairAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(0, pairing_delegate.call_count_);
  EXPECT_TRUE(device->IsConnecting());

  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // Two changes for connecting, one change for connected, one for paired,
  // two for trusted (after pairing and connection), and one for the reconnect
  // mode (IsConnectable).
  EXPECT_EQ(7, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());

  // Connect after pair.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());

  EXPECT_TRUE(device->IsPaired());

  // Verify is a HID device and is connectable.
  BluetoothDevice::UUIDSet uuids = device->GetUUIDs();
  EXPECT_EQ(1U, uuids.size());
  EXPECT_TRUE(base::ContainsKey(uuids, BluetoothUUID("1124")));
  EXPECT_TRUE(device->IsConnectable());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kLegacyAutopairPath));
  EXPECT_TRUE(properties->trusted.value());
}

TEST_F(BluetoothBlueZTest, PairDisplayPinCode) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Requires that we display a randomly generated PIN on the screen.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kDisplayPinCodeAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.display_pincode_count_);
  EXPECT_EQ("123456", pairing_delegate.last_pincode_);
  EXPECT_TRUE(device->IsConnecting());

  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // Two changes for connecting, one change for connected, one for paired,
  // two for trusted (after pairing and connection), and one for the reconnect
  // mode (IsConnectable).
  EXPECT_EQ(7, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());

  // Connect after pair.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());

  EXPECT_TRUE(device->IsPaired());

  // Verify is a HID device and is connectable.
  BluetoothDevice::UUIDSet uuids = device->GetUUIDs();
  EXPECT_EQ(1U, uuids.size());
  EXPECT_TRUE(base::ContainsKey(uuids, BluetoothUUID("1124")));
  EXPECT_TRUE(device->IsConnectable());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kDisplayPinCodePath));
  EXPECT_TRUE(properties->trusted.value());
}

TEST_F(BluetoothBlueZTest, PairDisplayPasskey) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Requires that we display a randomly generated Passkey on the screen,
  // and notifies us as it's typed in.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kDisplayPasskeyAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  // One call for DisplayPasskey() and one for KeysEntered().
  EXPECT_EQ(2, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.display_passkey_count_);
  EXPECT_EQ(123456U, pairing_delegate.last_passkey_);
  EXPECT_EQ(1, pairing_delegate.keys_entered_count_);
  EXPECT_EQ(0U, pairing_delegate.last_entered_);

  EXPECT_TRUE(device->IsConnecting());

  // One call to KeysEntered() for each key, including [enter].
  for (int i = 1; i <= 7; ++i) {
    base::RunLoop().Run();

    EXPECT_EQ(2 + i, pairing_delegate.call_count_);
    EXPECT_EQ(1 + i, pairing_delegate.keys_entered_count_);
    EXPECT_EQ(static_cast<uint32_t>(i), pairing_delegate.last_entered_);
  }

  base::RunLoop().Run();

  // 8 KeysEntered notifications (0 to 7, inclusive) and one aditional call for
  // DisplayPasskey().
  EXPECT_EQ(9, pairing_delegate.call_count_);
  EXPECT_EQ(8, pairing_delegate.keys_entered_count_);
  EXPECT_EQ(7U, pairing_delegate.last_entered_);

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // Two changes for connecting, one change for connected, one for paired,
  // two for trusted (after pairing and connection), and one for the reconnect
  // mode (IsConnectable).
  EXPECT_EQ(7, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());

  // Connect after pair.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());

  EXPECT_TRUE(device->IsPaired());

  // Verify is a HID device.
  BluetoothDevice::UUIDSet uuids = device->GetUUIDs();
  EXPECT_EQ(1U, uuids.size());
  EXPECT_TRUE(base::ContainsKey(uuids, BluetoothUUID("1124")));

  // And usually not connectable.
  EXPECT_FALSE(device->IsConnectable());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kDisplayPasskeyPath));
  EXPECT_TRUE(properties->trusted.value());
}

TEST_F(BluetoothBlueZTest, PairRequestPinCode) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Requires that the user enters a PIN for them.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
  EXPECT_TRUE(device->IsConnecting());

  // Set the PIN.
  device->SetPinCode("1234");
  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // Two changes for connecting, one change for connected, one for paired and
  // two for trusted (after pairing and connection).
  EXPECT_EQ(6, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());

  // Connect after pair.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());

  EXPECT_TRUE(device->IsPaired());

  // Verify is not a HID device.
  BluetoothDevice::UUIDSet uuids = device->GetUUIDs();
  EXPECT_EQ(0U, uuids.size());

  // Non HID devices are always connectable.
  EXPECT_TRUE(device->IsConnectable());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kRequestPinCodePath));
  EXPECT_TRUE(properties->trusted.value());
}

TEST_F(BluetoothBlueZTest, PairConfirmPasskey) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Requests that we confirm a displayed passkey.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
  EXPECT_EQ(123456U, pairing_delegate.last_passkey_);
  EXPECT_TRUE(device->IsConnecting());

  // Confirm the passkey.
  device->ConfirmPairing();
  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // Two changes for connecting, one change for connected, one for paired and
  // two for trusted (after pairing and connection).
  EXPECT_EQ(6, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());

  // Connect after pair.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());

  EXPECT_TRUE(device->IsPaired());

  // Non HID devices are always connectable.
  EXPECT_TRUE(device->IsConnectable());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath));
  EXPECT_TRUE(properties->trusted.value());
}

TEST_F(BluetoothBlueZTest, PairRequestPasskey) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Requires that the user enters a Passkey, this would be some kind of
  // device that has a display, but doesn't use "just works" - maybe a car?
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
  EXPECT_TRUE(device->IsConnecting());

  // Set the Passkey.
  device->SetPasskey(1234);
  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // Two changes for connecting, one change for connected, one for paired and
  // two for trusted (after pairing and connection).
  EXPECT_EQ(6, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());

  // Connect after pair.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());

  EXPECT_TRUE(device->IsPaired());

  // Non HID devices are always connectable.
  EXPECT_TRUE(device->IsConnectable());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath));
  EXPECT_TRUE(properties->trusted.value());
}

TEST_F(BluetoothBlueZTest, PairJustWorks) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Uses just-works pairing, since this is an outgoing pairing, no delegate
  // interaction is required.
  BluetoothDevice* device =
      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kJustWorksAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(0, pairing_delegate.call_count_);

  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // Two changes for connecting, one change for connected, one for paired and
  // two for trusted (after pairing and connection).
  EXPECT_EQ(6, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());

  // Connect after pair.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());

  EXPECT_TRUE(device->IsPaired());

  // Non HID devices are always connectable.
  EXPECT_TRUE(device->IsConnectable());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(
          dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath));
  EXPECT_TRUE(properties->trusted.value());
}

TEST_F(BluetoothBlueZTest, PairUnpairableDeviceFails) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevice(bluez::FakeBluetoothDeviceClient::kUnconnectableDeviceAddress);

  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kUnpairableDeviceAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(0, pairing_delegate.call_count_);
  EXPECT_TRUE(device->IsConnecting());

  // Run the loop to get the error..
  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);

  EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_);

  EXPECT_FALSE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());
  EXPECT_FALSE(device->IsPaired());

  // No connection.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, PairingFails) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevice(bluez::FakeBluetoothDeviceClient::kVanishingDeviceAddress);

  // The vanishing device times out during pairing
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kVanishingDeviceAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(0, pairing_delegate.call_count_);
  EXPECT_TRUE(device->IsConnecting());

  // Run the loop to get the error..
  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);

  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_TIMEOUT, last_connect_error_);

  EXPECT_FALSE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());
  EXPECT_FALSE(device->IsPaired());

  // No connection.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, PairingFailsAtConnection) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Everything seems to go according to plan with the unconnectable device;
  // it pairs, but then you can't make connections to it after.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kUnconnectableDeviceAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(0, pairing_delegate.call_count_);
  EXPECT_TRUE(device->IsConnecting());

  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_);

  // Two changes for connecting, one for paired and one for trusted after
  // pairing. The device should not be connected.
  EXPECT_EQ(4, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_FALSE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());

  // Connect after pair.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());

  EXPECT_TRUE(device->IsPaired());

  // Make sure the trusted property has been set to true still (since pairing
  // worked).
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kUnconnectableDevicePath));
  EXPECT_TRUE(properties->trusted.value());
}

TEST_F(BluetoothBlueZTest, PairingRejectedAtPinCode) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Reject the pairing after we receive a request for the PIN code.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
  EXPECT_TRUE(device->IsConnecting());

  // Reject the pairing.
  device->RejectPairing();
  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_);

  // Should be no changes except connecting going true and false.
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_FALSE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());
  EXPECT_FALSE(device->IsPaired());

  // No connection.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, PairingCancelledAtPinCode) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Cancel the pairing after we receive a request for the PIN code.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
  EXPECT_TRUE(device->IsConnecting());

  // Cancel the pairing.
  device->CancelPairing();
  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_);

  // Should be no changes except connecting going true and false.
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_FALSE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());
  EXPECT_FALSE(device->IsPaired());

  // No connection.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, PairingRejectedAtPasskey) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Reject the pairing after we receive a request for the passkey.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
  EXPECT_TRUE(device->IsConnecting());

  // Reject the pairing.
  device->RejectPairing();
  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_);

  // Should be no changes except connecting going true and false.
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_FALSE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());
  EXPECT_FALSE(device->IsPaired());

  // No connection.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, PairingCancelledAtPasskey) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Cancel the pairing after we receive a request for the passkey.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
  EXPECT_TRUE(device->IsConnecting());

  // Cancel the pairing.
  device->CancelPairing();
  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_);

  // Should be no changes except connecting going true and false.
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_FALSE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());
  EXPECT_FALSE(device->IsPaired());

  // No connection.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, PairingRejectedAtConfirmation) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Reject the pairing after we receive a request for passkey confirmation.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
  EXPECT_TRUE(device->IsConnecting());

  // Reject the pairing.
  device->RejectPairing();
  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_);

  // Should be no changes except connecting going true and false.
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_FALSE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());
  EXPECT_FALSE(device->IsPaired());

  // No connection.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, PairingCancelledAtConfirmation) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Cancel the pairing after we receive a request for the passkey.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
  EXPECT_TRUE(device->IsConnecting());

  // Cancel the pairing.
  device->CancelPairing();
  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_);

  // Should be no changes except connecting going true and false.
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_FALSE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());
  EXPECT_FALSE(device->IsPaired());

  // No connection.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, PairingCancelledInFlight) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();
  DiscoverDevices();

  // Cancel the pairing while we're waiting for the remote host.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kLegacyAutopairAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  TestPairingDelegate pairing_delegate;
  device->Connect(&pairing_delegate, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));

  EXPECT_EQ(0, pairing_delegate.call_count_);
  EXPECT_TRUE(device->IsConnecting());

  // Cancel the pairing.
  device->CancelPairing();
  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_);

  // Should be no changes except connecting going true and false.
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_FALSE(device->IsConnected());
  EXPECT_FALSE(device->IsConnecting());
  EXPECT_FALSE(device->IsPaired());

  // No connection.
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(0, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, IncomingPairRequestPinCode) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();

  TestPairingDelegate pairing_delegate;
  adapter_->AddPairingDelegate(
      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);

  // Requires that we provide a PIN code.
  fake_bluetooth_device_client_->CreateDevice(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath));
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_device_client_->SimulatePairing(
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath),
      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                      base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.request_pincode_count_);

  // Set the PIN.
  device->SetPinCode("1234");
  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // One change for paired, and one for trusted.
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsPaired());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kRequestPinCodePath));
  ASSERT_TRUE(properties->trusted.value());

  // No pairing context should remain on the device.
  BluetoothDeviceBlueZ* device_bluez =
      static_cast<BluetoothDeviceBlueZ*>(device);
  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
}

TEST_F(BluetoothBlueZTest, IncomingPairConfirmPasskey) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();

  TestPairingDelegate pairing_delegate;
  adapter_->AddPairingDelegate(
      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);

  // Requests that we confirm a displayed passkey.
  fake_bluetooth_device_client_->CreateDevice(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath));
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_device_client_->SimulatePairing(
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath),
      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                      base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
  EXPECT_EQ(123456U, pairing_delegate.last_passkey_);

  // Confirm the passkey.
  device->ConfirmPairing();
  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // One change for paired, and one for trusted.
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsPaired());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath));
  ASSERT_TRUE(properties->trusted.value());

  // No pairing context should remain on the device.
  BluetoothDeviceBlueZ* device_bluez =
      static_cast<BluetoothDeviceBlueZ*>(device);
  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
}

TEST_F(BluetoothBlueZTest, IncomingPairRequestPasskey) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();

  TestPairingDelegate pairing_delegate;
  adapter_->AddPairingDelegate(
      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);

  // Requests that we provide a Passkey.
  fake_bluetooth_device_client_->CreateDevice(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath));
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_device_client_->SimulatePairing(
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath),
      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                      base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);

  // Set the Passkey.
  device->SetPasskey(1234);
  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // One change for paired, and one for trusted.
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsPaired());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath));
  ASSERT_TRUE(properties->trusted.value());

  // No pairing context should remain on the device.
  BluetoothDeviceBlueZ* device_bluez =
      static_cast<BluetoothDeviceBlueZ*>(device);
  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
}

TEST_F(BluetoothBlueZTest, IncomingPairJustWorks) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();

  TestPairingDelegate pairing_delegate;
  adapter_->AddPairingDelegate(
      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);

  // Uses just-works pairing so, sinec this an incoming pairing, require
  // authorization from the user.
  fake_bluetooth_device_client_->CreateDevice(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath));
  BluetoothDevice* device =
      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kJustWorksAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_device_client_->SimulatePairing(
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath), true,
      GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.authorize_pairing_count_);

  // Confirm the pairing.
  device->ConfirmPairing();
  base::RunLoop().Run();

  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // One change for paired, and one for trusted.
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_TRUE(device->IsPaired());

  // Make sure the trusted property has been set to true.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(
          dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath));
  ASSERT_TRUE(properties->trusted.value());

  // No pairing context should remain on the device.
  BluetoothDeviceBlueZ* device_bluez =
      static_cast<BluetoothDeviceBlueZ*>(device);
  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
}

TEST_F(BluetoothBlueZTest, IncomingPairRequestPinCodeWithoutDelegate) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();

  // Requires that we provide a PIN Code, without a pairing delegate,
  // that will be rejected.
  fake_bluetooth_device_client_->CreateDevice(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath));
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_device_client_->SimulatePairing(
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath),
      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                      base::Unretained(this)));

  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(bluetooth_device::kErrorAuthenticationRejected, last_client_error_);

  // No changes should be observer.
  EXPECT_EQ(0, observer.device_changed_count());

  EXPECT_FALSE(device->IsPaired());

  // No pairing context should remain on the device.
  BluetoothDeviceBlueZ* device_bluez =
      static_cast<BluetoothDeviceBlueZ*>(device);
  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
}

TEST_F(BluetoothBlueZTest, IncomingPairConfirmPasskeyWithoutDelegate) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();

  // Requests that we confirm a displayed passkey, without a pairing delegate,
  // that will be rejected.
  fake_bluetooth_device_client_->CreateDevice(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath));
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_device_client_->SimulatePairing(
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath),
      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                      base::Unretained(this)));

  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(bluetooth_device::kErrorAuthenticationRejected, last_client_error_);

  // No changes should be observer.
  EXPECT_EQ(0, observer.device_changed_count());

  EXPECT_FALSE(device->IsPaired());

  // No pairing context should remain on the device.
  BluetoothDeviceBlueZ* device_bluez =
      static_cast<BluetoothDeviceBlueZ*>(device);
  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
}

TEST_F(BluetoothBlueZTest, IncomingPairRequestPasskeyWithoutDelegate) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();

  // Requests that we provide a displayed passkey, without a pairing delegate,
  // that will be rejected.
  fake_bluetooth_device_client_->CreateDevice(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath));
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_device_client_->SimulatePairing(
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath),
      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                      base::Unretained(this)));

  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(bluetooth_device::kErrorAuthenticationRejected, last_client_error_);

  // No changes should be observer.
  EXPECT_EQ(0, observer.device_changed_count());

  EXPECT_FALSE(device->IsPaired());

  // No pairing context should remain on the device.
  BluetoothDeviceBlueZ* device_bluez =
      static_cast<BluetoothDeviceBlueZ*>(device);
  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
}

TEST_F(BluetoothBlueZTest, IncomingPairJustWorksWithoutDelegate) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();

  // Uses just-works pairing and thus requires authorization for incoming
  // pairings, without a pairing delegate, that will be rejected.
  fake_bluetooth_device_client_->CreateDevice(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath));
  BluetoothDevice* device =
      adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kJustWorksAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_device_client_->SimulatePairing(
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath), true,
      GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                base::Unretained(this)));

  base::RunLoop().Run();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(bluetooth_device::kErrorAuthenticationRejected, last_client_error_);

  // No changes should be observer.
  EXPECT_EQ(0, observer.device_changed_count());

  EXPECT_FALSE(device->IsPaired());

  // No pairing context should remain on the device.
  BluetoothDeviceBlueZ* device_bluez =
      static_cast<BluetoothDeviceBlueZ*>(device);
  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);
}

TEST_F(BluetoothBlueZTest, RemovePairingDelegateDuringPairing) {
  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);

  GetAdapter();

  TestPairingDelegate pairing_delegate;
  adapter_->AddPairingDelegate(
      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);

  // Requests that we provide a Passkey.
  fake_bluetooth_device_client_->CreateDevice(
      dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath));
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress);
  ASSERT_TRUE(device != nullptr);
  ASSERT_FALSE(device->IsPaired());

  TestBluetoothAdapterObserver observer(adapter_);

  fake_bluetooth_device_client_->SimulatePairing(
      dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath),
      true, GetCallback(), base::Bind(&BluetoothBlueZTest::DBusErrorCallback,
                                      base::Unretained(this)));

  EXPECT_EQ(1, pairing_delegate.call_count_);
  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);

  // A pairing context should now be set on the device.
  BluetoothDeviceBlueZ* device_bluez =
      static_cast<BluetoothDeviceBlueZ*>(device);
  ASSERT_TRUE(device_bluez->GetPairing() != nullptr);

  // Removing the pairing delegate should remove that pairing context.
  adapter_->RemovePairingDelegate(&pairing_delegate);

  EXPECT_TRUE(device_bluez->GetPairing() == nullptr);

  // Set the Passkey, this should now have no effect since the pairing has
  // been, in-effect, cancelled
  device->SetPasskey(1234);

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(0, observer.device_changed_count());

  EXPECT_FALSE(device->IsPaired());
}

TEST_F(BluetoothBlueZTest, DeviceId) {
  GetAdapter();

  // Use the built-in paired device for this test, grab its Properties
  // structure so we can adjust the underlying modalias property.
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));

  ASSERT_TRUE(device != nullptr);
  ASSERT_TRUE(properties != nullptr);

  // Valid USB IF-assigned identifier.
  ASSERT_EQ("usb:v05ACp030Dd0306", properties->modalias.value());

  EXPECT_EQ(BluetoothDevice::VENDOR_ID_USB, device->GetVendorIDSource());
  EXPECT_EQ(0x05ac, device->GetVendorID());
  EXPECT_EQ(0x030d, device->GetProductID());
  EXPECT_EQ(0x0306, device->GetDeviceID());

  // Valid Bluetooth SIG-assigned identifier.
  properties->modalias.ReplaceValue("bluetooth:v00E0p2400d0400");

  EXPECT_EQ(BluetoothDevice::VENDOR_ID_BLUETOOTH, device->GetVendorIDSource());
  EXPECT_EQ(0x00e0, device->GetVendorID());
  EXPECT_EQ(0x2400, device->GetProductID());
  EXPECT_EQ(0x0400, device->GetDeviceID());

  // Invalid USB IF-assigned identifier.
  properties->modalias.ReplaceValue("usb:x00E0p2400d0400");

  EXPECT_EQ(BluetoothDevice::VENDOR_ID_UNKNOWN, device->GetVendorIDSource());
  EXPECT_EQ(0, device->GetVendorID());
  EXPECT_EQ(0, device->GetProductID());
  EXPECT_EQ(0, device->GetDeviceID());

  // Invalid Bluetooth SIG-assigned identifier.
  properties->modalias.ReplaceValue("bluetooth:x00E0p2400d0400");

  EXPECT_EQ(BluetoothDevice::VENDOR_ID_UNKNOWN, device->GetVendorIDSource());
  EXPECT_EQ(0, device->GetVendorID());
  EXPECT_EQ(0, device->GetProductID());
  EXPECT_EQ(0, device->GetDeviceID());

  // Unknown vendor specification identifier.
  properties->modalias.ReplaceValue("chrome:v00E0p2400d0400");

  EXPECT_EQ(BluetoothDevice::VENDOR_ID_UNKNOWN, device->GetVendorIDSource());
  EXPECT_EQ(0, device->GetVendorID());
  EXPECT_EQ(0, device->GetProductID());
  EXPECT_EQ(0, device->GetDeviceID());
}

TEST_F(BluetoothBlueZTest, GetConnectionInfoForDisconnectedDevice) {
  GetAdapter();
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);

  // Calling GetConnectionInfo for an unconnected device should return a result
  // in which all fields are filled with BluetoothDevice::kUnknownPower.
  BluetoothDevice::ConnectionInfo conn_info(0, 0, 0);
  device->GetConnectionInfo(base::Bind(&SaveConnectionInfo, &conn_info));
  int unknown_power = BluetoothDevice::kUnknownPower;
  EXPECT_NE(0, unknown_power);
  EXPECT_EQ(unknown_power, conn_info.rssi);
  EXPECT_EQ(unknown_power, conn_info.transmit_power);
  EXPECT_EQ(unknown_power, conn_info.max_transmit_power);
}

TEST_F(BluetoothBlueZTest, GetConnectionInfoForConnectedDevice) {
  GetAdapter();
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);

  device->Connect(nullptr, GetCallback(),
                  base::Bind(&BluetoothBlueZTest::ConnectErrorCallback,
                             base::Unretained(this)));
  EXPECT_TRUE(device->IsConnected());

  // Calling GetConnectionInfo for a connected device should return valid
  // results.
  fake_bluetooth_device_client_->UpdateConnectionInfo(-10, 3, 4);
  BluetoothDevice::ConnectionInfo conn_info;
  device->GetConnectionInfo(base::Bind(&SaveConnectionInfo, &conn_info));
  EXPECT_EQ(-10, conn_info.rssi);
  EXPECT_EQ(3, conn_info.transmit_power);
  EXPECT_EQ(4, conn_info.max_transmit_power);

  // Pause discovery to connect without pair.
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetPauseCount());
  EXPECT_EQ(1, fake_bluetooth_adapter_client_->GetUnpauseCount());
}

TEST_F(BluetoothBlueZTest, GetDiscoverableTimeout) {
  constexpr uint32_t kShortDiscoverableTimeout = 30;
  constexpr uint32_t kLongDiscoverableTimeout = 240;
  GetAdapter();
  BluetoothAdapterBlueZ* adapter_bluez =
      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());

  fake_bluetooth_adapter_client_->SetDiscoverableTimeout(
      kShortDiscoverableTimeout);
  EXPECT_EQ(kShortDiscoverableTimeout, adapter_bluez->GetDiscoverableTimeout());

  fake_bluetooth_adapter_client_->SetDiscoverableTimeout(
      kLongDiscoverableTimeout);
  EXPECT_EQ(kLongDiscoverableTimeout, adapter_bluez->GetDiscoverableTimeout());
}

// Verifies Shutdown shuts down the adapter as expected.
TEST_F(BluetoothBlueZTest, Shutdown) {
  // Set up adapter. Set powered & discoverable, start discovery.
  GetAdapter();
  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  adapter_->SetDiscoverable(true, GetCallback(), GetErrorCallback());
  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  base::RunLoop().Run();
  ASSERT_EQ(3, callback_count_);
  ASSERT_EQ(0, error_callback_count_);
  callback_count_ = 0;

  TestPairingDelegate pairing_delegate;
  adapter_->AddPairingDelegate(
      &pairing_delegate, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);

  // Validate running adapter state.
  EXPECT_NE("", adapter_->GetAddress());
  EXPECT_NE("", adapter_->GetName());
  EXPECT_TRUE(adapter_->IsInitialized());
  EXPECT_TRUE(adapter_->IsPresent());
  EXPECT_TRUE(adapter_->IsPowered());
  EXPECT_TRUE(adapter_->IsDiscoverable());
  EXPECT_TRUE(adapter_->IsDiscovering());
  EXPECT_EQ(2U, adapter_->GetDevices().size());
  EXPECT_NE(nullptr,
            adapter_->GetDevice(
                bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress));
  EXPECT_NE(dbus::ObjectPath(""),
            static_cast<BluetoothAdapterBlueZ*>(adapter_.get())->object_path());

  // Shutdown
  adapter_->Shutdown();

  // Validate post shutdown state by calling all BluetoothAdapterBlueZ
  // members, in declaration order:

  adapter_->Shutdown();
  // DeleteOnCorrectThread omitted as we don't want to delete in this test.
  {
    TestBluetoothAdapterObserver observer(adapter_);  // Calls AddObserver
  }  // ~TestBluetoothAdapterObserver calls RemoveObserver.
  EXPECT_EQ("", adapter_->GetAddress());
  EXPECT_EQ("", adapter_->GetName());

  adapter_->SetName("", GetCallback(), GetErrorCallback());
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_--) << "SetName error";

  EXPECT_TRUE(adapter_->IsInitialized());
  EXPECT_FALSE(adapter_->IsPresent());
  EXPECT_FALSE(adapter_->IsPowered());

  adapter_->SetPowered(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_--) << "SetPowered error";

  EXPECT_FALSE(adapter_->IsDiscoverable());

  adapter_->SetDiscoverable(true, GetCallback(), GetErrorCallback());
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_--) << "SetDiscoverable error";

  EXPECT_FALSE(adapter_->IsDiscovering());
  // CreateRfcommService will DCHECK after Shutdown().
  // CreateL2capService will DCHECK after Shutdown().

  BluetoothAdapterBlueZ* adapter_bluez =
      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());
  EXPECT_EQ(nullptr, adapter_bluez->GetDeviceWithPath(dbus::ObjectPath("")));

  // Notify methods presume objects exist that are owned by the adapter and
  // destroyed in Shutdown(). Mocks are not attempted here that won't exist,
  // as verified below by EXPECT_EQ(0U, adapter_->GetDevices().size());
  // NotifyDeviceChanged
  // NotifyGattServiceAdded
  // NotifyGattServiceRemoved
  // NotifyGattServiceChanged
  // NotifyGattDiscoveryComplete
  // NotifyGattCharacteristicAdded
  // NotifyGattCharacteristicRemoved
  // NotifyGattDescriptorAdded
  // NotifyGattDescriptorRemoved
  // NotifyGattCharacteristicValueChanged
  // NotifyGattDescriptorValueChanged

  EXPECT_EQ(dbus::ObjectPath(""), adapter_bluez->object_path());

  adapter_profile_ = nullptr;

  FakeBluetoothProfileServiceProviderDelegate profile_delegate;
  adapter_bluez->UseProfile(
      BluetoothUUID(), dbus::ObjectPath(""),
      bluez::BluetoothProfileManagerClient::Options(), &profile_delegate,
      base::Bind(&BluetoothBlueZTest::ProfileRegisteredCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCompletionCallback,
                 base::Unretained(this)));

  EXPECT_FALSE(adapter_profile_) << "UseProfile error";
  EXPECT_EQ(0, callback_count_) << "UseProfile error";
  EXPECT_EQ(1, error_callback_count_--) << "UseProfile error";

  // Protected and private methods:

  adapter_bluez->RemovePairingDelegateInternal(&pairing_delegate);
  // AdapterAdded() invalid post Shutdown because it calls SetAdapter.
  adapter_bluez->AdapterRemoved(dbus::ObjectPath("x"));
  adapter_bluez->AdapterPropertyChanged(dbus::ObjectPath("x"), "");
  adapter_bluez->DeviceAdded(dbus::ObjectPath(""));
  adapter_bluez->DeviceRemoved(dbus::ObjectPath(""));
  adapter_bluez->DevicePropertyChanged(dbus::ObjectPath(""), "");
  adapter_bluez->InputPropertyChanged(dbus::ObjectPath(""), "");
  // bluez::BluetoothAgentServiceProvider::Delegate omitted, dbus will be
  // shutdown,
  //   with the exception of Released.
  adapter_bluez->Released();

  adapter_bluez->OnRegisterAgent();
  adapter_bluez->OnRegisterAgentError("", "");
  adapter_bluez->OnRequestDefaultAgent();
  adapter_bluez->OnRequestDefaultAgentError("", "");

  // GetPairing will DCHECK after Shutdown().
  // SetAdapter will DCHECK after Shutdown().
  // SetDefaultAdapterName will DCHECK after Shutdown().
  // RemoveAdapter will DCHECK after Shutdown().
  adapter_bluez->NotifyAdapterPoweredChanged(false);
  adapter_bluez->DiscoverableChanged(false);
  adapter_bluez->DiscoveringChanged(false);
  adapter_bluez->PresentChanged(false);

  adapter_bluez->OnSetDiscoverable(GetCallback(), GetErrorCallback(), true);
  EXPECT_EQ(0, callback_count_) << "OnSetDiscoverable error";
  EXPECT_EQ(1, error_callback_count_--) << "OnSetDiscoverable error";

  adapter_bluez->OnPropertyChangeCompleted(GetCallback(), GetErrorCallback(),
                                           true);
  EXPECT_EQ(0, callback_count_) << "OnPropertyChangeCompleted error";
  EXPECT_EQ(1, error_callback_count_--) << "OnPropertyChangeCompleted error";

  adapter_bluez->AddDiscoverySession(nullptr, GetCallback(),
                                     GetDiscoveryErrorCallback());
  EXPECT_EQ(0, callback_count_) << "AddDiscoverySession error";
  EXPECT_EQ(1, error_callback_count_--) << "AddDiscoverySession error";

  adapter_bluez->RemoveDiscoverySession(nullptr, GetCallback(),
                                        GetDiscoveryErrorCallback());
  EXPECT_EQ(0, callback_count_) << "RemoveDiscoverySession error";
  EXPECT_EQ(1, error_callback_count_--) << "RemoveDiscoverySession error";

  // OnStartDiscovery tested in Shutdown_OnStartDiscovery
  // OnStartDiscoveryError tested in Shutdown_OnStartDiscoveryError
  // OnStopDiscovery tested in Shutdown_OnStopDiscovery
  // OnStopDiscoveryError tested in Shutdown_OnStopDiscoveryError

  adapter_profile_ = nullptr;

  // OnRegisterProfile SetProfileDelegate, OnRegisterProfileError, require
  // UseProfile to be set first, do so again here just before calling them.
  adapter_bluez->UseProfile(
      BluetoothUUID(), dbus::ObjectPath(""),
      bluez::BluetoothProfileManagerClient::Options(), &profile_delegate,
      base::Bind(&BluetoothBlueZTest::ProfileRegisteredCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCompletionCallback,
                 base::Unretained(this)));

  EXPECT_FALSE(adapter_profile_) << "UseProfile error";
  EXPECT_EQ(0, callback_count_) << "UseProfile error";
  EXPECT_EQ(1, error_callback_count_--) << "UseProfile error";

  adapter_bluez->SetProfileDelegate(
      BluetoothUUID(), dbus::ObjectPath(""), &profile_delegate,
      base::Bind(&BluetoothBlueZTest::ProfileRegisteredCallback,
                 base::Unretained(this)),
      base::Bind(&BluetoothBlueZTest::ErrorCompletionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(0, callback_count_) << "SetProfileDelegate error";
  EXPECT_EQ(1, error_callback_count_--) << "SetProfileDelegate error";

  adapter_bluez->OnRegisterProfileError(BluetoothUUID(), "", "");
  EXPECT_EQ(0, callback_count_) << "OnRegisterProfileError error";
  EXPECT_EQ(0, error_callback_count_) << "OnRegisterProfileError error";

  adapter_bluez->ProcessQueuedDiscoveryRequests();

  // From BluetoothAdapater:

  adapter_->StartDiscoverySession(
      base::Bind(&BluetoothBlueZTest::DiscoverySessionCallback,
                 base::Unretained(this)),
      GetErrorCallback());
  EXPECT_EQ(0, callback_count_) << "StartDiscoverySession error";
  EXPECT_EQ(1, error_callback_count_--) << "StartDiscoverySession error";

  EXPECT_EQ(0U, adapter_->GetDevices().size());
  EXPECT_EQ(nullptr,
            adapter_->GetDevice(
                bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress));
  TestPairingDelegate pairing_delegate2;
  adapter_->AddPairingDelegate(
      &pairing_delegate2, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
  adapter_->RemovePairingDelegate(&pairing_delegate2);
}

// Verifies post-Shutdown of discovery sessions and OnStartDiscovery.
TEST_F(BluetoothBlueZTest, Shutdown_OnStartDiscovery) {
  const int kNumberOfDiscoverySessions = 10;
  GetAdapter();
  BluetoothAdapterBlueZ* adapter_bluez =
      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());

  for (int i = 0; i < kNumberOfDiscoverySessions; i++) {
    adapter_bluez->AddDiscoverySession(nullptr, GetCallback(),
                                       GetDiscoveryErrorCallback());
  }
  adapter_->Shutdown();
  adapter_bluez->OnStartDiscovery(GetCallback(), GetDiscoveryErrorCallback());

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(kNumberOfDiscoverySessions, error_callback_count_);
}

// Verifies post-Shutdown of discovery sessions and OnStartDiscoveryError.
TEST_F(BluetoothBlueZTest, Shutdown_OnStartDiscoveryError) {
  const int kNumberOfDiscoverySessions = 10;
  GetAdapter();
  BluetoothAdapterBlueZ* adapter_bluez =
      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());

  for (int i = 0; i < kNumberOfDiscoverySessions; i++) {
    adapter_bluez->AddDiscoverySession(nullptr, GetCallback(),
                                       GetDiscoveryErrorCallback());
  }
  adapter_->Shutdown();
  adapter_bluez->OnStartDiscoveryError(GetCallback(),
                                       GetDiscoveryErrorCallback(), "", "");

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(kNumberOfDiscoverySessions, error_callback_count_);
}

// Verifies post-Shutdown of discovery sessions and OnStartDiscovery.
TEST_F(BluetoothBlueZTest, Shutdown_OnStopDiscovery) {
  const int kNumberOfDiscoverySessions = 10;
  GetAdapter();
  BluetoothAdapterBlueZ* adapter_bluez =
      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());

  // In order to queue up discovery sessions before an OnStopDiscovery call
  // RemoveDiscoverySession must be called, so Add, Start, and Remove:
  adapter_bluez->AddDiscoverySession(nullptr, GetCallback(),
                                     GetDiscoveryErrorCallback());
  adapter_bluez->OnStartDiscovery(GetCallback(), GetDiscoveryErrorCallback());
  adapter_bluez->RemoveDiscoverySession(nullptr, GetCallback(),
                                        GetDiscoveryErrorCallback());
  callback_count_ = 0;
  error_callback_count_ = 0;
  // Can now queue discovery sessions while waiting for OnStopDiscovery.
  for (int i = 0; i < kNumberOfDiscoverySessions; i++) {
    adapter_bluez->AddDiscoverySession(nullptr, GetCallback(),
                                       GetDiscoveryErrorCallback());
  }
  adapter_->Shutdown();
  adapter_bluez->OnStopDiscovery(GetCallback());

  // 1 successful stopped discovery from RemoveDiscoverySession, and
  // kNumberOfDiscoverySessions errors from AddDiscoverySession/OnStopDiscovery.
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(kNumberOfDiscoverySessions, error_callback_count_);
}

// Verifies post-Shutdown of discovery sessions and OnStopDiscoveryError.
TEST_F(BluetoothBlueZTest, Shutdown_OnStopDiscoveryError) {
  const int kNumberOfDiscoverySessions = 10;
  GetAdapter();
  BluetoothAdapterBlueZ* adapter_bluez =
      static_cast<BluetoothAdapterBlueZ*>(adapter_.get());

  // In order to queue up discovery sessions before an OnStopDiscoveryError call
  // RemoveDiscoverySession must be called, so Add, Start, and Remove:
  adapter_bluez->AddDiscoverySession(nullptr, GetCallback(),
                                     GetDiscoveryErrorCallback());
  adapter_bluez->OnStartDiscovery(GetCallback(), GetDiscoveryErrorCallback());
  adapter_bluez->RemoveDiscoverySession(nullptr, GetCallback(),
                                        GetDiscoveryErrorCallback());
  callback_count_ = 0;
  error_callback_count_ = 0;
  // Can now queue discovery sessions while waiting for OnStopDiscoveryError.
  for (int i = 0; i < kNumberOfDiscoverySessions; i++) {
    adapter_bluez->AddDiscoverySession(nullptr, GetCallback(),
                                       GetDiscoveryErrorCallback());
  }
  adapter_->Shutdown();
  adapter_bluez->OnStopDiscoveryError(GetDiscoveryErrorCallback(), "", "");

  // 1 error reported to RemoveDiscoverySession because of OnStopDiscoveryError,
  // and kNumberOfDiscoverySessions errors queued with AddDiscoverySession.
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1 + kNumberOfDiscoverySessions, error_callback_count_);
}

TEST_F(BluetoothBlueZTest, ManufacturerDataChanged) {
  const BluetoothDevice::ManufacturerId kManufacturerId1 = 0x1234;
  const BluetoothDevice::ManufacturerId kManufacturerId2 = 0x2345;
  const BluetoothDevice::ManufacturerId kManufacturerId3 = 0x3456;

  // Simulate a change of manufacturer data of a device.
  GetAdapter();

  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);

  // Install an observer; expect the DeviceChanged method to be called
  // when we change the service data.
  TestBluetoothAdapterObserver observer(adapter_);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));

  properties->manufacturer_data.set_valid(true);

  // Check that ManufacturerDataChanged is correctly invoke.
  properties->manufacturer_data.ReplaceValue({{kManufacturerId1, {1, 2, 3}}});
  EXPECT_EQ(1, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());
  EXPECT_EQ(
      BluetoothDevice::ManufacturerDataMap({{kManufacturerId1, {1, 2, 3}}}),
      device->GetManufacturerData());
  EXPECT_EQ(BluetoothDevice::ManufacturerIDSet({kManufacturerId1}),
            device->GetManufacturerDataIDs());
  EXPECT_EQ(std::vector<uint8_t>({1, 2, 3}),
            *(device->GetManufacturerDataForID(kManufacturerId1)));

  // Check that we can update service data with same uuid / add more uuid.
  properties->manufacturer_data.ReplaceValue(
      {{kManufacturerId1, {3, 2, 1}}, {kManufacturerId2, {1}}});
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_EQ(BluetoothDevice::ManufacturerDataMap(
                {{kManufacturerId1, {3, 2, 1}}, {kManufacturerId2, {1}}}),
            device->GetManufacturerData());
  EXPECT_EQ(
      BluetoothDevice::ManufacturerIDSet({kManufacturerId1, kManufacturerId2}),
      device->GetManufacturerDataIDs());
  EXPECT_EQ(std::vector<uint8_t>({3, 2, 1}),
            *(device->GetManufacturerDataForID(kManufacturerId1)));
  EXPECT_EQ(std::vector<uint8_t>({1}),
            *(device->GetManufacturerDataForID(kManufacturerId2)));

  // Check that we can remove uuid / change uuid with same data.
  properties->manufacturer_data.ReplaceValue({{kManufacturerId3, {3, 2, 1}}});
  EXPECT_EQ(3, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());

  EXPECT_EQ(
      BluetoothDevice::ManufacturerDataMap({{kManufacturerId3, {3, 2, 1}}}),
      device->GetManufacturerData());
  EXPECT_EQ(BluetoothDevice::ManufacturerIDSet({kManufacturerId3}),
            device->GetManufacturerDataIDs());
  EXPECT_EQ(std::vector<uint8_t>({3, 2, 1}),
            *(device->GetManufacturerDataForID(kManufacturerId3)));
  EXPECT_EQ(nullptr, device->GetManufacturerDataForID(kManufacturerId1));
  EXPECT_EQ(nullptr, device->GetManufacturerDataForID(kManufacturerId2));
}

TEST_F(BluetoothBlueZTest, AdvertisingDataFlagsChanged) {
  // Simulate a change of advertising data flags of a device.
  GetAdapter();

  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);

  // Install an observer; expect the DeviceChanged method to be called
  // when we change the service data.
  TestBluetoothAdapterObserver observer(adapter_);

  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kPairedDevicePath));

  properties->advertising_data_flags.set_valid(true);

  // Check that AdvertisingDataFlagsChanged is correctly invoke.
  properties->advertising_data_flags.ReplaceValue(std::vector<uint8_t>({0x12}));
  EXPECT_EQ(1, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());
  EXPECT_TRUE(device->GetAdvertisingDataFlags().has_value());
  EXPECT_EQ(0x12u, device->GetAdvertisingDataFlags().value());

  // Check that we can update advertising data flags.
  properties->advertising_data_flags.ReplaceValue(std::vector<uint8_t>({0x23}));
  EXPECT_EQ(2, observer.device_changed_count());
  EXPECT_EQ(device, observer.last_device());
  EXPECT_TRUE(device->GetAdvertisingDataFlags().has_value());
  EXPECT_EQ(0x23u, device->GetAdvertisingDataFlags().value());
}

TEST_F(BluetoothBlueZTest, SetConnectionLatency) {
  GetAdapter();
  DiscoverDevices();

  // SetConnectionLatency is supported on LE devices.
  bluez::FakeBluetoothDeviceClient::Properties* properties =
      fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath(
          bluez::FakeBluetoothDeviceClient::kConnectUnpairablePath));
  properties->type.ReplaceValue(BluetoothDeviceClient::kTypeLe);
  BluetoothDevice* device = adapter_->GetDevice(
      bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress);
  ASSERT_TRUE(device);

  device->SetConnectionLatency(
      BluetoothDevice::ConnectionLatency::CONNECTION_LATENCY_LOW, GetCallback(),
      GetErrorCallback());
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  device->SetConnectionLatency(
      BluetoothDevice::ConnectionLatency::CONNECTION_LATENCY_HIGH,
      GetCallback(), GetErrorCallback());
  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // Dual mode devices should be supported as well.
  properties->type.ReplaceValue(BluetoothDeviceClient::kTypeDual);
  device->SetConnectionLatency(
      BluetoothDevice::ConnectionLatency::CONNECTION_LATENCY_MEDIUM,
      GetCallback(), GetErrorCallback());
  EXPECT_EQ(3, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  // This API is not supported for BR/EDR devices.
  properties->type.ReplaceValue(BluetoothDeviceClient::kTypeBredr);
  device->SetConnectionLatency(
      BluetoothDevice::ConnectionLatency::CONNECTION_LATENCY_MEDIUM,
      GetCallback(), GetErrorCallback());
  EXPECT_EQ(3, callback_count_);
  EXPECT_EQ(1, error_callback_count_);

  // Return an error if the type is not valid.
  properties->type.set_valid(false);
  device->SetConnectionLatency(
      BluetoothDevice::ConnectionLatency::CONNECTION_LATENCY_MEDIUM,
      GetCallback(), GetErrorCallback());
  EXPECT_EQ(3, callback_count_);
  EXPECT_EQ(2, error_callback_count_);
}

}  // namespace bluez
