// Copyright 2018 The Chromium OS 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 "bluetooth/newblued/newblue_daemon.h"

#include <map>
#include <memory>
#include <string>
#include <utility>

#include <base/memory/ref_counted.h>
#include <base/message_loop/message_loop.h>
#include <base/run_loop.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_exported_object.h>
#include <dbus/mock_object_manager.h>
#include <dbus/mock_object_proxy.h>
#include <dbus/object_manager.h>
#include <gtest/gtest.h>

#include "bluetooth/common/util.h"
#include "bluetooth/newblued/mock_libnewblue.h"

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::SaveArg;

namespace bluetooth {

namespace {

constexpr char kTestSender[] = ":1.1";
constexpr char kTestSender2[] = ":1.2";
constexpr int kTestSerial = 10;
constexpr char kTestDeviceAddress[] = "06:05:04:03:02:01";
constexpr char kTestDeviceObjectPath[] =
    "/org/bluez/hci0/dev_06_05_04_03_02_01";

constexpr uniq_t kTestDiscoveryId = 7;

void SaveResponse(std::unique_ptr<dbus::Response>* saved_response,
                  std::unique_ptr<dbus::Response> response) {
  *saved_response = std::move(response);
}

}  // namespace

class NewblueDaemonTest : public ::testing::Test {
 public:
  using MethodHandlerMap =
      std::map<std::string, dbus::ExportedObject::MethodCallCallback*>;

  void SetUp() override {
    bus_ = new dbus::MockBus(dbus::Bus::Options());
    EXPECT_CALL(*bus_, GetDBusTaskRunner())
        .WillRepeatedly(Return(message_loop_.task_runner().get()));
    EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
    EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
    EXPECT_CALL(*bus_, Connect()).WillRepeatedly(Return(true));
    EXPECT_CALL(*bus_, SetUpAsyncOperations()).WillRepeatedly(Return(true));
    EXPECT_CALL(*bus_, SendWithReplyAndBlock(_, _, _)).Times(AnyNumber());
    EXPECT_CALL(*bus_, AddFilterFunction(_, _)).Times(AnyNumber());
    EXPECT_CALL(*bus_, RemoveFilterFunction(_, _)).Times(AnyNumber());
    EXPECT_CALL(*bus_, AddMatch(_, _)).Times(AnyNumber());
    EXPECT_CALL(*bus_, RemoveMatch(_, _)).Times(AnyNumber());
    auto libnewblue = std::make_unique<MockLibNewblue>();
    libnewblue_ = libnewblue.get();
    auto newblue = std::make_unique<Newblue>(std::move(libnewblue));
    newblue_daemon_ = std::make_unique<NewblueDaemon>(std::move(newblue),
                                                      false /* is_idle_mode */);
    SetupBluezObjectProxy();
    SetupBluezObjectManager();
    // Force MessageLoop to run all pending tasks as an effect of instantiating
    // MockObjectManager. This is needed to avoid memory leak as pending tasks
    // hold pointers.
    base::RunLoop().RunUntilIdle();
  }

 protected:
  dbus::ExportedObject::MethodCallCallback* GetMethodHandler(
      MethodHandlerMap method_handlers, const std::string& method_name) {
    return base::ContainsKey(method_handlers, method_name)
               ? method_handlers[method_name]
               : &dummy_method_handler_;
  }

  // Expects that the standard methods on org.freedesktop.DBus.Properties
  // interface are exported.
  void ExpectPropertiesMethodsExportedAsync(
      scoped_refptr<dbus::MockExportedObject> exported_object) {
    EXPECT_CALL(*exported_object, ExportMethod(dbus::kPropertiesInterface,
                                               dbus::kPropertiesGet, _, _))
        .Times(1);
    EXPECT_CALL(*exported_object, ExportMethod(dbus::kPropertiesInterface,
                                               dbus::kPropertiesSet, _, _))
        .Times(1);
    EXPECT_CALL(*exported_object, ExportMethod(dbus::kPropertiesInterface,
                                               dbus::kPropertiesGetAll, _, _))
        .Times(1);
  }

  // Expects that the standard methods on org.freedesktop.DBus.Properties
  // interface are exported.
  void ExpectPropertiesMethodsExported(
      scoped_refptr<dbus::MockExportedObject> exported_object) {
    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(dbus::kPropertiesInterface,
                                     dbus::kPropertiesGet, _))
        .WillOnce(Return(true));
    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(dbus::kPropertiesInterface,
                                     dbus::kPropertiesSet, _))
        .WillOnce(Return(true));
    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(dbus::kPropertiesInterface,
                                     dbus::kPropertiesGetAll, _))
        .WillOnce(Return(true));
  }

  // Expects that the methods on org.bluez.Device1 interface are exported.
  void ExpectDeviceMethodsExported(
      scoped_refptr<dbus::MockExportedObject> exported_object) {
    EXPECT_CALL(
        *exported_object,
        ExportMethodAndBlock(bluetooth_device::kBluetoothDeviceInterface,
                             bluetooth_device::kPair, _))
        .WillOnce(Return(true));
    EXPECT_CALL(
        *exported_object,
        ExportMethodAndBlock(bluetooth_device::kBluetoothDeviceInterface,
                             bluetooth_device::kCancelPairing, _))
        .WillOnce(Return(true));
    EXPECT_CALL(
        *exported_object,
        ExportMethodAndBlock(bluetooth_device::kBluetoothDeviceInterface,
                             bluetooth_device::kConnect, _))
        .WillOnce(Return(true));
  }

  // Expects that the methods on org.bluez.Device1 interface are unexported.
  void ExpectDeviceMethodsUnexported(
      scoped_refptr<dbus::MockExportedObject> exported_object) {
    EXPECT_CALL(
        *exported_object,
        UnexportMethodAndBlock(bluetooth_device::kBluetoothDeviceInterface,
                               bluetooth_device::kPair))
        .WillOnce(Return(true));
    EXPECT_CALL(
        *exported_object,
        UnexportMethodAndBlock(bluetooth_device::kBluetoothDeviceInterface,
                               bluetooth_device::kCancelPairing))
        .WillOnce(Return(true));
    EXPECT_CALL(
        *exported_object,
        UnexportMethodAndBlock(bluetooth_device::kBluetoothDeviceInterface,
                               bluetooth_device::kConnect))
        .WillOnce(Return(true));
  }

  // Expects that the methods on org.bluez.AdvertisingManager1 interface are
  // exported.
  void ExpectAdvertisingManagerMethodsExported(
      scoped_refptr<dbus::MockExportedObject> exported_object) {
    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(
                    bluetooth_advertising_manager::
                        kBluetoothAdvertisingManagerInterface,
                    bluetooth_advertising_manager::kRegisterAdvertisement, _))
        .WillOnce(Return(true));
    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(
                    bluetooth_advertising_manager::
                        kBluetoothAdvertisingManagerInterface,
                    bluetooth_advertising_manager::kUnregisterAdvertisement, _))
        .WillOnce(Return(true));
  }

  // Expects that the methods on org.bluez.AgentManager1 interface are
  // exported.
  void ExpectAgentManagerMethodsExported(
      scoped_refptr<dbus::MockExportedObject> exported_object) {
    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(
                    bluetooth_agent_manager::kBluetoothAgentManagerInterface,
                    bluetooth_agent_manager::kRegisterAgent, _))
        .WillOnce(Return(true));
    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(
                    bluetooth_agent_manager::kBluetoothAgentManagerInterface,
                    bluetooth_agent_manager::kUnregisterAgent, _))
        .WillOnce(Return(true));
    EXPECT_CALL(*exported_object,
                ExportMethodAndBlock(
                    bluetooth_agent_manager::kBluetoothAgentManagerInterface,
                    bluetooth_agent_manager::kRequestDefaultAgent, _))
        .WillOnce(Return(true));
  }

  scoped_refptr<dbus::MockExportedObject> AddOrGetMockExportedObject(
      const dbus::ObjectPath& object_path) {
    if (base::ContainsKey(mock_exported_objects_, object_path))
      return mock_exported_objects_[object_path];

    scoped_refptr<dbus::MockExportedObject> exported_object =
        new dbus::MockExportedObject(bus_.get(), object_path);
    mock_exported_objects_[object_path] = exported_object;
    return exported_object;
  }

  void RemoveMockExportedObject(const dbus::ObjectPath& object_path) {
    if (base::ContainsKey(mock_exported_objects_, object_path))
      mock_exported_objects_.erase(object_path);
  }

  void ExpectDeviceObjectExported(const dbus::ObjectPath& device_object_path) {
    scoped_refptr<dbus::MockExportedObject> exported_dev_object =
        AddOrGetMockExportedObject(device_object_path);
    ExpectDeviceMethodsExported(exported_dev_object);
    ExpectPropertiesMethodsExported(exported_dev_object);
    EXPECT_CALL(*bus_, GetExportedObject(device_object_path))
        .WillOnce(Return(exported_dev_object.get()));
    EXPECT_CALL(*exported_dev_object, SendSignal(_)).Times(AnyNumber());
  }

  void ExpectDeviceObjectUnexported(
      const dbus::ObjectPath& device_object_path) {
    scoped_refptr<dbus::MockExportedObject> exported_dev_object =
        AddOrGetMockExportedObject(device_object_path);
    ExpectDeviceMethodsUnexported(exported_dev_object);
    EXPECT_CALL(*exported_dev_object, Unregister()).Times(1);
  }

  scoped_refptr<dbus::MockExportedObject> SetupExportedRootObject() {
    dbus::ObjectPath root_path(
        newblue_object_manager::kNewblueObjectManagerServicePath);
    scoped_refptr<dbus::MockExportedObject> exported_root_object =
        new dbus::MockExportedObject(bus_.get(), root_path);
    EXPECT_CALL(*bus_, GetExportedObject(root_path))
        .WillRepeatedly(Return(exported_root_object.get()));
    EXPECT_CALL(*exported_root_object, SendSignal(_)).Times(AnyNumber());
    return exported_root_object;
  }

  scoped_refptr<dbus::MockExportedObject> SetupExportedAgentManagerObject() {
    dbus::ObjectPath agent_manager_path(
        bluetooth_agent_manager::kBluetoothAgentManagerServicePath);
    scoped_refptr<dbus::MockExportedObject> exported_agent_manager_object =
        new dbus::MockExportedObject(bus_.get(), agent_manager_path);
    EXPECT_CALL(*bus_, GetExportedObject(agent_manager_path))
        .WillRepeatedly(Return(exported_agent_manager_object.get()));
    return exported_agent_manager_object;
  }

  scoped_refptr<dbus::MockExportedObject> SetupExportedAdapterObject() {
    dbus::ObjectPath adapter_object_path(kAdapterObjectPath);
    scoped_refptr<dbus::MockExportedObject> exported_adapter_object =
        new dbus::MockExportedObject(bus_.get(), adapter_object_path);
    EXPECT_CALL(*bus_, GetExportedObject(adapter_object_path))
        .WillRepeatedly(Return(exported_adapter_object.get()));
    return exported_adapter_object;
  }

  void SetupBluezObjectProxy() {
    dbus::ObjectPath object_path(
        bluez_object_manager::kBluezObjectManagerServicePath);
    bluez_object_proxy_ = new dbus::MockObjectProxy(
        bus_.get(), bluez_object_manager::kBluezObjectManagerServiceName,
        object_path);
    EXPECT_CALL(*bus_, GetObjectProxy(
                           bluez_object_manager::kBluezObjectManagerServiceName,
                           object_path))
        .WillRepeatedly(Return(bluez_object_proxy_.get()));
    EXPECT_CALL(*bluez_object_proxy_, SetNameOwnerChangedCallback(_))
        .Times(AnyNumber());
    EXPECT_CALL(*bluez_object_proxy_, ConnectToSignal(_, _, _, _))
        .Times(AnyNumber());
  }

  void SetupBluezObjectManager() {
    dbus::ObjectPath object_path(
        bluez_object_manager::kBluezObjectManagerServicePath);
    bluez_object_manager_ = new dbus::MockObjectManager(
        bus_.get(), bluez_object_manager::kBluezObjectManagerServiceName,
        object_path);
    EXPECT_CALL(*bus_, GetObjectManager(
                           bluez_object_manager::kBluezObjectManagerServiceName,
                           object_path))
        .WillRepeatedly(Return(bluez_object_manager_.get()));
  }

  struct smKnownDevNode* CreateSmKnownDeviceNode(const std::string& address,
                                                 bool is_random_address,
                                                 bool is_paired,
                                                 std::string name) {
    struct smKnownDevNode* node =
        (struct smKnownDevNode*)calloc(1, sizeof(struct smKnownDevNode));
    ConvertToBtAddr(is_random_address, address, &node->addr);
    node->isPaired = is_paired;
    node->name = strdup(name.c_str());
    return node;
  }

  struct smKnownDevNode* StubGetKnownDevices() {
    struct smKnownDevNode* node1 = CreateSmKnownDeviceNode(
        "01:AA:BB:CC:DD:EE", /* is_random_address */ true,
        /* is_paired */ true, "Test Device 1");
    struct smKnownDevNode* node2 = CreateSmKnownDeviceNode(
        "02:AA:BB:CC:DD:EE", /* is_random_address */ true,
        /* is_paired */ false, "Test Device 2");
    struct smKnownDevNode* node3 = CreateSmKnownDeviceNode(
        "03:AA:BB:CC:DD:EE", /* is_random_address */ false,
        /* is_paired */ true, "Test Device 3");
    node1->next = node2;
    node2->next = node3;
    node3->next = nullptr;
    return node1;
  }

  void ExpectTestInit(
      scoped_refptr<dbus::MockExportedObject> exported_root_object) {
    EXPECT_CALL(*bus_,
                RequestOwnershipAndBlock(
                    newblue_object_manager::kNewblueObjectManagerServiceName,
                    dbus::Bus::REQUIRE_PRIMARY))
        .WillOnce(Return(true));

    // Standard methods on org.freedesktop.DBus.ObjectManager interface should
    // be exported.
    EXPECT_CALL(*exported_root_object,
                ExportMethod(dbus::kObjectManagerInterface,
                             dbus::kObjectManagerGetManagedObjects, _, _))
        .Times(1);
    // Standard methods on org.freedesktop.DBus.Properties interface should be
    // exported.
    ExpectPropertiesMethodsExportedAsync(exported_root_object);
  }

  void TestInit() {
    exported_root_object_ = SetupExportedRootObject();
    exported_agent_manager_object_ = SetupExportedAgentManagerObject();
    exported_adapter_object_ = SetupExportedAdapterObject();
    ExpectPropertiesMethodsExported(exported_adapter_object_);
    ExpectAdvertisingManagerMethodsExported(exported_adapter_object_);
    ExpectPropertiesMethodsExported(exported_agent_manager_object_);
    ExpectAgentManagerMethodsExported(exported_agent_manager_object_);

    ExpectTestInit(exported_root_object_);

    EXPECT_CALL(*libnewblue_, HciUp(_, _, _)).WillOnce(Return(true));
    EXPECT_TRUE(newblue_daemon_->Init(
        bus_, nullptr /* no need to access the delegator */));
  }

  void TestDeinit() {
    EXPECT_CALL(*exported_root_object_, Unregister()).Times(1);
    EXPECT_CALL(*exported_adapter_object_, Unregister()).Times(1);
    EXPECT_CALL(*exported_agent_manager_object_, Unregister()).Times(1);
    // Expect that all the exported objects are unregistered.
    for (const auto it : mock_exported_objects_) {
      scoped_refptr<dbus::MockExportedObject> mock_exported_object = it.second;
      EXPECT_CALL(*mock_exported_object, Unregister()).Times(1);
    }
    // Shutdown now to make sure ExportedObjectManagerWrapper is destructed
    // first before the mocked objects.
    newblue_daemon_->Shutdown();
  }

  void TestAdapterBringUp(
      scoped_refptr<dbus::MockExportedObject> exported_adapter_object,
      MethodHandlerMap adapter_method_handlers) {
    // org.bluez.Adapter1 methods
    EXPECT_CALL(
        *exported_adapter_object,
        ExportMethodAndBlock(bluetooth_adapter::kBluetoothAdapterInterface,
                             bluetooth_adapter::kStartDiscovery, _))
        .WillOnce(DoAll(
            SaveArg<2>(GetMethodHandler(adapter_method_handlers,
                                        bluetooth_adapter::kStartDiscovery)),
            Return(true)));

    EXPECT_CALL(
        *exported_adapter_object,
        ExportMethodAndBlock(bluetooth_adapter::kBluetoothAdapterInterface,
                             bluetooth_adapter::kStopDiscovery, _))
        .WillOnce(DoAll(
            SaveArg<2>(GetMethodHandler(adapter_method_handlers,
                                        bluetooth_adapter::kStopDiscovery)),
            Return(true)));

    EXPECT_CALL(
        *exported_adapter_object,
        ExportMethodAndBlock(bluetooth_adapter::kBluetoothAdapterInterface,
                             bluetooth_adapter::kRemoveDevice, _))
        .WillOnce(DoAll(
            SaveArg<2>(GetMethodHandler(adapter_method_handlers,
                                        bluetooth_adapter::kRemoveDevice)),
            Return(true)));

    EXPECT_CALL(*libnewblue_, HciIsUp()).WillOnce(Return(true));
    EXPECT_CALL(*libnewblue_, L2cInit()).WillOnce(Return(0));
    EXPECT_CALL(*libnewblue_, AttInit()).WillOnce(Return(true));
    EXPECT_CALL(*libnewblue_, GattProfileInit()).WillOnce(Return(true));
    EXPECT_CALL(*libnewblue_, GattBuiltinInit()).WillOnce(Return(true));
    EXPECT_CALL(*libnewblue_, SmInit()).WillOnce(Return(true));
    EXPECT_CALL(*libnewblue_, SmRegisterPasskeyDisplayObserver(_, _))
        .WillOnce(Return(true));
    EXPECT_CALL(*libnewblue_, SmRegisterPairStateObserver(_, _))
        .WillOnce(Return(true));

    // At initialization, newblued should export the saved paired devices.
    ExpectDeviceObjectExported(
        dbus::ObjectPath("/org/bluez/hci0/dev_01_AA_BB_CC_DD_EE"));
    ExpectDeviceObjectExported(
        dbus::ObjectPath("/org/bluez/hci0/dev_03_AA_BB_CC_DD_EE"));
    struct smKnownDevNode* known_devices = StubGetKnownDevices();
    EXPECT_CALL(*libnewblue_, SmGetKnownDevices())
        .WillOnce(Return(known_devices));
    EXPECT_CALL(*libnewblue_, SmKnownDevicesFree(known_devices))
        .WillOnce(Invoke(&smKnownDevicesFree));

    // Listens to BlueZ's Adapter1 interface for monitoring StackSyncQuitting.
    EXPECT_CALL(
        *bluez_object_manager_,
        RegisterInterface(bluetooth_adapter::kBluetoothAdapterInterface, _))
        .Times(1);

    newblue_daemon_->OnHciReadyForUp();
  }

  void ConstructRemoveDeviceMethodCall(
      dbus::MethodCall* remove_device_method_call,
      const std::string device_object_path) {
    remove_device_method_call->SetPath(dbus::ObjectPath(kAdapterObjectPath));
    remove_device_method_call->SetSender(kTestSender);
    remove_device_method_call->SetSerial(kTestSerial);
    dbus::MessageWriter writer(remove_device_method_call);
    writer.AppendObjectPath(dbus::ObjectPath(device_object_path));
  }

  base::MessageLoop message_loop_;
  scoped_refptr<dbus::MockBus> bus_;
  scoped_refptr<dbus::MockObjectProxy> bluez_object_proxy_;
  scoped_refptr<dbus::MockObjectManager> bluez_object_manager_;
  // Declare MockExportedObject's before newblue_daemon_ to make sure the
  // MockExportedObject-s are destroyed after newblue_daemon_.
  std::map<dbus::ObjectPath, scoped_refptr<dbus::MockExportedObject>>
      mock_exported_objects_;
  scoped_refptr<dbus::MockExportedObject> exported_root_object_;
  scoped_refptr<dbus::MockExportedObject> exported_adapter_object_;
  scoped_refptr<dbus::MockExportedObject> exported_agent_manager_object_;
  std::unique_ptr<NewblueDaemon> newblue_daemon_;
  MockLibNewblue* libnewblue_;
  dbus::ExportedObject::MethodCallCallback dummy_method_handler_;
};

TEST_F(NewblueDaemonTest, InitFailed) {
  scoped_refptr<dbus::MockExportedObject> exported_root_object =
      SetupExportedRootObject();
  scoped_refptr<dbus::MockExportedObject> exported_agent_manager_object =
      SetupExportedAgentManagerObject();
  scoped_refptr<dbus::MockExportedObject> exported_adapter_object =
      SetupExportedAdapterObject();
  ExpectPropertiesMethodsExported(exported_adapter_object);
  ExpectAdvertisingManagerMethodsExported(exported_adapter_object);
  ExpectPropertiesMethodsExported(exported_agent_manager_object);
  ExpectAgentManagerMethodsExported(exported_agent_manager_object);

  ExpectTestInit(exported_root_object);

  EXPECT_CALL(*libnewblue_, HciUp(_, _, _)).WillOnce(Return(false));
  EXPECT_FALSE(newblue_daemon_->Init(
      bus_, nullptr /* no need to access the delegator */));

  // Shutdown now to make sure ExportedObjectManagerWrapper is destructed first
  // before the mocked objects.
  newblue_daemon_->Shutdown();
}

TEST_F(NewblueDaemonTest, InitSuccessAndBringUp) {
  TestInit();

  MethodHandlerMap adapter_method_handlers;
  TestAdapterBringUp(exported_adapter_object_, adapter_method_handlers);

  TestDeinit();
}

TEST_F(NewblueDaemonTest, DiscoveryAPI) {
  TestInit();

  dbus::ExportedObject::MethodCallCallback start_discovery_handler;
  dbus::ExportedObject::MethodCallCallback stop_discovery_handler;
  dbus::ExportedObject::MethodCallCallback remove_device_handler;
  MethodHandlerMap adapter_method_handlers;
  adapter_method_handlers[bluetooth_adapter::kStartDiscovery] =
      &start_discovery_handler;
  adapter_method_handlers[bluetooth_adapter::kStopDiscovery] =
      &stop_discovery_handler;
  adapter_method_handlers[bluetooth_adapter::kRemoveDevice] =
      &remove_device_handler;
  TestAdapterBringUp(exported_adapter_object_, adapter_method_handlers);

  ASSERT_FALSE(start_discovery_handler.is_null());
  ASSERT_FALSE(stop_discovery_handler.is_null());
  ASSERT_FALSE(remove_device_handler.is_null());

  // StartDiscovery by the first client, it should return D-Bus success and
  // should trigger NewBlue StartDiscovery.
  dbus::MethodCall start_discovery_method_call(
      bluetooth_adapter::kBluetoothAdapterInterface,
      bluetooth_adapter::kStartDiscovery);
  start_discovery_method_call.SetPath(dbus::ObjectPath(kAdapterObjectPath));
  start_discovery_method_call.SetSender(kTestSender);
  start_discovery_method_call.SetSerial(kTestSerial);
  std::unique_ptr<dbus::Response> start_discovery_response;
  Newblue::DeviceDiscoveredCallback on_device_discovered;
  hciDeviceDiscoveredLeCbk inquiry_response_callback;
  void* inquiry_response_callback_data;
  EXPECT_CALL(*libnewblue_, HciDiscoverLeStart(_, _, /* active */ true,
                                               /* use_random_addr */ false))
      .WillOnce(DoAll(SaveArg<0>(&inquiry_response_callback),
                      SaveArg<1>(&inquiry_response_callback_data),
                      Return(kTestDiscoveryId)));
  start_discovery_handler.Run(
      &start_discovery_method_call,
      base::Bind(&SaveResponse, &start_discovery_response));
  EXPECT_EQ("", start_discovery_response->GetErrorName());
  ASSERT_NE(nullptr, inquiry_response_callback);
  ASSERT_NE(nullptr, inquiry_response_callback_data);
  // StartDiscovery again by the same client, it should return D-Bus error and
  // should not affect NewBlue discovery state.
  EXPECT_CALL(*libnewblue_, HciDiscoverLeStart(_, _, _, _)).Times(0);
  start_discovery_handler.Run(
      &start_discovery_method_call,
      base::Bind(&SaveResponse, &start_discovery_response));
  EXPECT_EQ(bluetooth_adapter::kErrorInProgress,
            start_discovery_response->GetErrorName());
  // StartDiscovery by a different client, it should return D-Bus success and
  // should not affect NewBlue discovery state since it has already been
  // started.
  start_discovery_method_call.SetSender(kTestSender2);
  EXPECT_CALL(*libnewblue_, HciDiscoverLeStart(_, _, _, _)).Times(0);
  start_discovery_handler.Run(
      &start_discovery_method_call,
      base::Bind(&SaveResponse, &start_discovery_response));
  EXPECT_EQ("", start_discovery_response->GetErrorName());

  // Device discovered.
  ExpectDeviceObjectExported(dbus::ObjectPath(kTestDeviceObjectPath));
  struct bt_addr address;
  ConvertToBtAddr(false, kTestDeviceAddress, &address);
  inquiry_response_callback(inquiry_response_callback_data, &address,
                            /* rssi */ -101, HCI_ADV_TYPE_SCAN_RSP,
                            /* eir */ {},
                            /* eir_len*/ 0);
  // Trigger the queued inquiry_response_callback task.
  base::RunLoop().RunUntilIdle();

  // RemoveDevice failed (unknown device address).
  dbus::MethodCall remove_device_method_call(
      bluetooth_adapter::kBluetoothAdapterInterface,
      bluetooth_adapter::kRemoveDevice);
  ConstructRemoveDeviceMethodCall(&remove_device_method_call,
                                  "/org/bluez/hci0/dev_11_11_11_11_11_11");
  std::unique_ptr<dbus::Response> remove_device_response;
  remove_device_handler.Run(&remove_device_method_call,
                            base::Bind(&SaveResponse, &remove_device_response));
  EXPECT_EQ(bluetooth_adapter::kErrorFailed,
            remove_device_response->GetErrorName());
  // RemoveDevice successful.
  dbus::MethodCall remove_device_method_call2(
      bluetooth_adapter::kBluetoothAdapterInterface,
      bluetooth_adapter::kRemoveDevice);
  ConstructRemoveDeviceMethodCall(&remove_device_method_call2,
                                  kTestDeviceObjectPath);
  ExpectDeviceObjectUnexported(dbus::ObjectPath(kTestDeviceObjectPath));
  std::unique_ptr<dbus::Response> remove_device_response2;
  remove_device_handler.Run(
      &remove_device_method_call2,
      base::Bind(&SaveResponse, &remove_device_response2));
  EXPECT_EQ("", remove_device_response2->GetErrorName());
  RemoveMockExportedObject(dbus::ObjectPath(kTestDeviceObjectPath));

  // StopDiscovery by the first client, it should return D-Bus success and
  // should not affect NewBlue discovery state since there is still another
  // client having discovery session.
  dbus::MethodCall stop_discovery_method_call(
      bluetooth_adapter::kBluetoothAdapterInterface,
      bluetooth_adapter::kStopDiscovery);
  stop_discovery_method_call.SetPath(dbus::ObjectPath(kAdapterObjectPath));
  stop_discovery_method_call.SetSender(kTestSender);
  stop_discovery_method_call.SetSerial(kTestSerial);
  std::unique_ptr<dbus::Response> stop_discovery_response;
  EXPECT_CALL(*libnewblue_, HciDiscoverLeStop(_)).Times(0);
  stop_discovery_handler.Run(
      &stop_discovery_method_call,
      base::Bind(&SaveResponse, &stop_discovery_response));
  EXPECT_EQ("", stop_discovery_response->GetErrorName());
  // StopDiscovery again by the same client, it should return D-Bus error, and
  // should not affect the NewBlue discovery state.
  EXPECT_CALL(*libnewblue_, HciDiscoverLeStop(_)).Times(0);
  stop_discovery_handler.Run(
      &stop_discovery_method_call,
      base::Bind(&SaveResponse, &stop_discovery_response));
  EXPECT_EQ(bluetooth_adapter::kErrorFailed,
            stop_discovery_response->GetErrorName());
  // StopDiscovery by the other client, it should return D-Bus success, and
  // should trigger NewBlue's StopDiscovery since there is no more client having
  // a discovery session.
  stop_discovery_method_call.SetSender(kTestSender2);
  EXPECT_CALL(*libnewblue_, HciDiscoverLeStop(kTestDiscoveryId))
      .WillOnce(Return(true));
  stop_discovery_handler.Run(
      &stop_discovery_method_call,
      base::Bind(&SaveResponse, &stop_discovery_response));
  EXPECT_EQ("", stop_discovery_response->GetErrorName());

  TestDeinit();
}

TEST_F(NewblueDaemonTest, IdleMode) {
  EXPECT_CALL(*bus_,
              RequestOwnershipAndBlock(
                  newblue_object_manager::kNewblueObjectManagerServiceName,
                  dbus::Bus::REQUIRE_PRIMARY))
      .WillOnce(Return(true));

  auto libnewblue = std::make_unique<MockLibNewblue>();
  libnewblue_ = libnewblue.get();
  auto newblue = std::make_unique<Newblue>(std::move(libnewblue));
  newblue_daemon_ = std::make_unique<NewblueDaemon>(std::move(newblue),
                                                    true /* is_idle_mode */);

  // In idle mode, the daemon shouldn't try to bring up the LE stack.
  EXPECT_CALL(*libnewblue_, HciUp(_, _, _)).Times(0);
  EXPECT_TRUE(newblue_daemon_->Init(
      bus_, nullptr /* no need to access the delegator */));

  // Shutdown now to make sure ExportedObjectManagerWrapper is destructed first
  // before the mocked objects.
  newblue_daemon_->Shutdown();
}

}  // namespace bluetooth
