// Copyright (c) 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 "chromeos/dbus/fake_bluetooth_device_client.h"

#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <algorithm>
#include <map>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/threading/worker_pool.h"
#include "base/time/time.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
#include "chromeos/dbus/fake_bluetooth_agent_service_provider.h"
#include "chromeos/dbus/fake_bluetooth_input_client.h"
#include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
#include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
#include "dbus/file_descriptor.h"
#include "dbus/object_path.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace {

// Default interval between simulated events.
const int kSimulationIntervalMs = 750;


void SimulatedProfileSocket(int fd) {
  // Simulate a server-side socket of a profile; read data from the socket,
  // write it back, and then close.
  char buf[1024];
  ssize_t len;
  ssize_t count;

  len = read(fd, buf, sizeof buf);
  if (len < 0) {
    close(fd);
    return;
  }

  count = len;
  len = write(fd, buf, count);
  if (len < 0) {
    close(fd);
    return;
  }

  close(fd);
}

}  // namespace

namespace chromeos {

const char FakeBluetoothDeviceClient::kPairedDevicePath[] =
    "/fake/hci0/dev0";
const char FakeBluetoothDeviceClient::kPairedDeviceAddress[] =
    "00:11:22:33:44:55";
const char FakeBluetoothDeviceClient::kPairedDeviceName[] =
    "Fake Device";
const uint32 FakeBluetoothDeviceClient::kPairedDeviceClass = 0x000104;

const char FakeBluetoothDeviceClient::kAppleMousePath[] =
    "/fake/hci0/dev1";
const char FakeBluetoothDeviceClient::kAppleMouseAddress[] =
    "28:CF:DA:00:00:00";
const char FakeBluetoothDeviceClient::kAppleMouseName[] =
    "Apple Magic Mouse";
const uint32 FakeBluetoothDeviceClient::kAppleMouseClass = 0x002580;

const char FakeBluetoothDeviceClient::kAppleKeyboardPath[] =
    "/fake/hci0/dev2";
const char FakeBluetoothDeviceClient::kAppleKeyboardAddress[] =
    "28:37:37:00:00:00";
const char FakeBluetoothDeviceClient::kAppleKeyboardName[] =
    "Apple Wireless Keyboard";
const uint32 FakeBluetoothDeviceClient::kAppleKeyboardClass = 0x002540;

const char FakeBluetoothDeviceClient::kVanishingDevicePath[] =
    "/fake/hci0/dev3";
const char FakeBluetoothDeviceClient::kVanishingDeviceAddress[] =
    "01:02:03:04:05:06";
const char FakeBluetoothDeviceClient::kVanishingDeviceName[] =
    "Vanishing Device";
const uint32 FakeBluetoothDeviceClient::kVanishingDeviceClass = 0x000104;

const char FakeBluetoothDeviceClient::kMicrosoftMousePath[] =
    "/fake/hci0/dev4";
const char FakeBluetoothDeviceClient::kMicrosoftMouseAddress[] =
    "7C:ED:8D:00:00:00";
const char FakeBluetoothDeviceClient::kMicrosoftMouseName[] =
    "Microsoft Mouse";
const uint32 FakeBluetoothDeviceClient::kMicrosoftMouseClass = 0x002580;

const char FakeBluetoothDeviceClient::kMotorolaKeyboardPath[] =
    "/fake/hci0/dev5";
const char FakeBluetoothDeviceClient::kMotorolaKeyboardAddress[] =
    "00:0F:F6:00:00:00";
const char FakeBluetoothDeviceClient::kMotorolaKeyboardName[] =
    "Motorola Keyboard";
const uint32 FakeBluetoothDeviceClient::kMotorolaKeyboardClass = 0x002540;

const char FakeBluetoothDeviceClient::kSonyHeadphonesPath[] =
    "/fake/hci0/dev6";
const char FakeBluetoothDeviceClient::kSonyHeadphonesAddress[] =
    "00:24:BE:00:00:00";
const char FakeBluetoothDeviceClient::kSonyHeadphonesName[] =
    "Sony BT-00";
const uint32 FakeBluetoothDeviceClient::kSonyHeadphonesClass = 0x240408;

const char FakeBluetoothDeviceClient::kPhonePath[] =
    "/fake/hci0/dev7";
const char FakeBluetoothDeviceClient::kPhoneAddress[] =
    "20:7D:74:00:00:00";
const char FakeBluetoothDeviceClient::kPhoneName[] =
    "Phone";
const uint32 FakeBluetoothDeviceClient::kPhoneClass = 0x7a020c;

const char FakeBluetoothDeviceClient::kWeirdDevicePath[] =
    "/fake/hci0/dev8";
const char FakeBluetoothDeviceClient::kWeirdDeviceAddress[] =
    "20:7D:74:00:00:01";
const char FakeBluetoothDeviceClient::kWeirdDeviceName[] =
    "Weird Device";
const uint32 FakeBluetoothDeviceClient::kWeirdDeviceClass = 0x7a020c;

const char FakeBluetoothDeviceClient::kUnconnectableDevicePath[] =
    "/fake/hci0/dev9";
const char FakeBluetoothDeviceClient::kUnconnectableDeviceAddress[] =
    "20:7D:74:00:00:02";
const char FakeBluetoothDeviceClient::kUnconnectableDeviceName[] =
    "Unconnectable Device";
const uint32 FakeBluetoothDeviceClient::kUnconnectableDeviceClass = 0x7a020c;

const char FakeBluetoothDeviceClient::kUnpairableDevicePath[] =
    "/fake/hci0/devA";
const char FakeBluetoothDeviceClient::kUnpairableDeviceAddress[] =
    "20:7D:74:00:00:03";
const char FakeBluetoothDeviceClient::kUnpairableDeviceName[] =
    "Unpairable Device";
const uint32 FakeBluetoothDeviceClient::kUnpairableDeviceClass = 0x002540;

FakeBluetoothDeviceClient::Properties::Properties(
    const PropertyChangedCallback& callback)
    : BluetoothDeviceClient::Properties(
          NULL,
          bluetooth_device::kBluetoothDeviceInterface,
          callback) {
}

FakeBluetoothDeviceClient::Properties::~Properties() {
}

void FakeBluetoothDeviceClient::Properties::Get(
    dbus::PropertyBase* property,
    dbus::PropertySet::GetCallback callback) {
  VLOG(1) << "Get " << property->name();
  callback.Run(false);
}

void FakeBluetoothDeviceClient::Properties::GetAll() {
  VLOG(1) << "GetAll";
}

void FakeBluetoothDeviceClient::Properties::Set(
    dbus::PropertyBase *property,
    dbus::PropertySet::SetCallback callback) {
  VLOG(1) << "Set " << property->name();
  if (property->name() == trusted.name()) {
    callback.Run(true);
    property->ReplaceValueWithSetValue();
  } else {
    callback.Run(false);
  }
}

FakeBluetoothDeviceClient::FakeBluetoothDeviceClient()
    : simulation_interval_ms_(kSimulationIntervalMs),
      discovery_simulation_step_(0),
      pairing_cancelled_(false) {
  Properties* properties = new Properties(base::Bind(
      &FakeBluetoothDeviceClient::OnPropertyChanged,
      base::Unretained(this),
      dbus::ObjectPath(kPairedDevicePath)));
  properties->address.ReplaceValue(kPairedDeviceAddress);
  properties->bluetooth_class.ReplaceValue(kPairedDeviceClass);
  properties->name.ReplaceValue("Fake Device (Name)");
  properties->alias.ReplaceValue(kPairedDeviceName);
  properties->paired.ReplaceValue(true);
  properties->trusted.ReplaceValue(true);
  properties->adapter.ReplaceValue(
      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));

  std::vector<std::string> uuids;
  uuids.push_back("00001800-0000-1000-8000-00805f9b34fb");
  uuids.push_back("00001801-0000-1000-8000-00805f9b34fb");
  properties->uuids.ReplaceValue(uuids);

  properties->modalias.ReplaceValue("usb:v05ACp030Dd0306");

  properties_map_[dbus::ObjectPath(kPairedDevicePath)] = properties;
  device_list_.push_back(dbus::ObjectPath(kPairedDevicePath));
}

FakeBluetoothDeviceClient::~FakeBluetoothDeviceClient() {
  // Clean up Properties structures
  STLDeleteValues(&properties_map_);
}

void FakeBluetoothDeviceClient::Init(dbus::Bus* bus) {
}

void FakeBluetoothDeviceClient::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void FakeBluetoothDeviceClient::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

std::vector<dbus::ObjectPath> FakeBluetoothDeviceClient::GetDevicesForAdapter(
    const dbus::ObjectPath& adapter_path) {
  if (adapter_path ==
      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath))
    return device_list_;
  else
    return std::vector<dbus::ObjectPath>();
}

FakeBluetoothDeviceClient::Properties*
FakeBluetoothDeviceClient::GetProperties(const dbus::ObjectPath& object_path) {
  PropertiesMap::iterator iter = properties_map_.find(object_path);
  if (iter != properties_map_.end())
    return iter->second;
  return NULL;
}

void FakeBluetoothDeviceClient::Connect(
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  VLOG(1) << "Connect: " << object_path.value();
  Properties* properties = GetProperties(object_path);

  if (properties->connected.value() == true) {
    // Already connected.
    callback.Run();
    return;
  }

  if (properties->paired.value() != true &&
      object_path != dbus::ObjectPath(kMicrosoftMousePath)) {
    // Must be paired.
    error_callback.Run(bluetooth_device::kErrorFailed, "Not paired");
    return;
  } else if (properties->paired.value() == true &&
             object_path == dbus::ObjectPath(kUnconnectableDevicePath)) {
    // Must not be paired
    error_callback.Run(bluetooth_device::kErrorFailed,
                       "Connection fails while paired");
    return;
  }

  // The device can be connected.
  properties->connected.ReplaceValue(true);
  callback.Run();

  AddInputDeviceIfNeeded(object_path, properties);
}

void FakeBluetoothDeviceClient::Disconnect(
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  VLOG(1) << "Disconnect: " << object_path.value();
  Properties* properties = GetProperties(object_path);

  if (properties->connected.value() == true) {
    callback.Run();
    properties->connected.ReplaceValue(false);
  } else {
    error_callback.Run("org.bluez.Error.NotConnected", "Not Connected");
  }
}

void FakeBluetoothDeviceClient::ConnectProfile(
    const dbus::ObjectPath& object_path,
    const std::string& uuid,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  VLOG(1) << "ConnectProfile: " << object_path.value() << " " << uuid;

  FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
      static_cast<FakeBluetoothProfileManagerClient*>(
          DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
  FakeBluetoothProfileServiceProvider* profile_service_provider =
      fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid);
  if (profile_service_provider == NULL) {
    error_callback.Run(kNoResponseError, "Missing profile");
    return;
  }

  // Make a socket pair of a compatible type with the type used by Bluetooth;
  // spin up a thread to simulate the server side and wrap the client side in
  // a D-Bus file descriptor object.
  int socket_type = SOCK_STREAM;
  if (uuid == FakeBluetoothProfileManagerClient::kL2capUuid)
    socket_type = SOCK_SEQPACKET;

  int fds[2];
  if (socketpair(AF_UNIX, socket_type, 0, fds) < 0) {
    error_callback.Run(kNoResponseError, "socketpair call failed");
    return;
  }

  int args;
  args = fcntl(fds[1], F_GETFL, NULL);
  if (args < 0) {
    error_callback.Run(kNoResponseError, "failed to get socket flags");
    return;
  }

  args |= O_NONBLOCK;
  if (fcntl(fds[1], F_SETFL, args) < 0) {
    error_callback.Run(kNoResponseError, "failed to set socket non-blocking");
    return;
  }

  base::WorkerPool::GetTaskRunner(false)->PostTask(
      FROM_HERE,
      base::Bind(&SimulatedProfileSocket,
                 fds[0]));

  scoped_ptr<dbus::FileDescriptor> fd(new dbus::FileDescriptor(fds[1]));

  // Post the new connection to the service provider.
  BluetoothProfileServiceProvider::Delegate::Options options;

  profile_service_provider->NewConnection(
      object_path,
      fd.Pass(),
      options,
      base::Bind(&FakeBluetoothDeviceClient::ConnectionCallback,
                 base::Unretained(this),
                 object_path,
                 callback,
                 error_callback));
}

void FakeBluetoothDeviceClient::DisconnectProfile(
    const dbus::ObjectPath& object_path,
    const std::string& uuid,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  VLOG(1) << "DisconnectProfile: " << object_path.value() << " " << uuid;

  FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
      static_cast<FakeBluetoothProfileManagerClient*>(
          DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
  FakeBluetoothProfileServiceProvider* profile_service_provider =
      fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid);
  if (profile_service_provider == NULL) {
    error_callback.Run(kNoResponseError, "Missing profile");
    return;
  }

  profile_service_provider->RequestDisconnection(
      object_path,
      base::Bind(&FakeBluetoothDeviceClient::DisconnectionCallback,
                 base::Unretained(this),
                 object_path,
                 callback,
                 error_callback));
}

void FakeBluetoothDeviceClient::Pair(
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  VLOG(1) << "Pair: " << object_path.value();
  Properties* properties = GetProperties(object_path);

  if (properties->paired.value() == true) {
    // Already paired.
    callback.Run();
    return;
  }

  pairing_cancelled_ = false;

  FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
      static_cast<FakeBluetoothAgentManagerClient*>(
          DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
  FakeBluetoothAgentServiceProvider* agent_service_provider =
      fake_bluetooth_agent_manager_client->GetAgentServiceProvider();
  if (agent_service_provider == NULL) {
    error_callback.Run(kNoResponseError, "Missing agent");
    return;
  }

  if (object_path == dbus::ObjectPath(kAppleMousePath) ||
      object_path == dbus::ObjectPath(kMicrosoftMousePath) ||
      object_path == dbus::ObjectPath(kUnconnectableDevicePath)) {
    // No need to call anything on the pairing delegate, just wait 3 times
    // the interval before acting as if the other end accepted it.
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
                   base::Unretained(this),
                   object_path, callback, error_callback),
        base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));

  } else if (object_path == dbus::ObjectPath(kAppleKeyboardPath)) {
    // Display a Pincode, and wait 7 times the interval before acting as
    // if the other end accepted it.
    agent_service_provider->DisplayPinCode(object_path, "123456");

    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
                   base::Unretained(this),
                   object_path, callback, error_callback),
        base::TimeDelta::FromMilliseconds(7 * simulation_interval_ms_));

  } else if (object_path == dbus::ObjectPath(kVanishingDevicePath)) {
    // The vanishing device simulates being too far away, and thus times out.
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing,
                   base::Unretained(this),
                   object_path, error_callback),
        base::TimeDelta::FromMilliseconds(4 * simulation_interval_ms_));

  } else if (object_path == dbus::ObjectPath(kMotorolaKeyboardPath)) {
    // Display a passkey, and each interval act as if another key was entered
    // for it.
    agent_service_provider->DisplayPasskey(object_path, 123456, 0);

    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
                   base::Unretained(this),
                   1, object_path, callback, error_callback),
        base::TimeDelta::FromMilliseconds(simulation_interval_ms_));

  } else if (object_path == dbus::ObjectPath(kSonyHeadphonesPath)) {
    // Request a Pincode.
    agent_service_provider->RequestPinCode(
        object_path,
        base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback,
                   base::Unretained(this),
                   object_path,
                   callback,
                   error_callback));

  } else if (object_path == dbus::ObjectPath(kPhonePath)) {
    // Request confirmation of a Passkey.
    agent_service_provider->RequestConfirmation(
        object_path, 123456,
        base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback,
                   base::Unretained(this),
                   object_path,
                   callback,
                   error_callback));

  } else if (object_path == dbus::ObjectPath(kWeirdDevicePath)) {
    // Request a Passkey from the user.
    agent_service_provider->RequestPasskey(
        object_path,
        base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback,
                   base::Unretained(this),
                   object_path,
                   callback,
                   error_callback));

  } else if (object_path == dbus::ObjectPath(kUnpairableDevicePath)) {
    // Fails the pairing with an org.bluez.Error.Failed error.
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing,
                   base::Unretained(this),
                   object_path, error_callback),
        base::TimeDelta::FromMilliseconds(simulation_interval_ms_));

  } else {
    error_callback.Run(kNoResponseError, "No pairing fake");
  }
}

void FakeBluetoothDeviceClient::CancelPairing(
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  VLOG(1) << "CancelPairing: " << object_path.value();
  pairing_cancelled_ = true;
  callback.Run();
}


void FakeBluetoothDeviceClient::BeginDiscoverySimulation(
    const dbus::ObjectPath& adapter_path) {
  VLOG(1) << "starting discovery simulation";

  discovery_simulation_step_ = 1;

  base::MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
                 base::Unretained(this)),
      base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
}

void FakeBluetoothDeviceClient::EndDiscoverySimulation(
    const dbus::ObjectPath& adapter_path) {
  VLOG(1) << "stopping discovery simulation";
  discovery_simulation_step_ = 0;
}

void FakeBluetoothDeviceClient::SetSimulationIntervalMs(int interval_ms) {
  simulation_interval_ms_ = interval_ms;
}

void FakeBluetoothDeviceClient::RemoveDevice(
    const dbus::ObjectPath& adapter_path,
    const dbus::ObjectPath& device_path) {
  std::vector<dbus::ObjectPath>::iterator listiter =
      std::find(device_list_.begin(), device_list_.end(), device_path);
  if (listiter == device_list_.end())
    return;

  PropertiesMap::iterator iter = properties_map_.find(device_path);
  Properties* properties = iter->second;

  VLOG(1) << "removing device: " << properties->alias.value();
  device_list_.erase(listiter);

  // Remove the Input interface if it exists. This should be called before the
  // BluetoothDeviceClient::Observer::DeviceRemoved because it deletes the
  // BluetoothDeviceChromeOS object, including the device_path referenced here.
  FakeBluetoothInputClient* fake_bluetooth_input_client =
      static_cast<FakeBluetoothInputClient*>(
          DBusThreadManager::Get()->GetBluetoothInputClient());
  fake_bluetooth_input_client->RemoveInputDevice(device_path);

  FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
                    DeviceRemoved(device_path));

  delete properties;
  properties_map_.erase(iter);
}

void FakeBluetoothDeviceClient::OnPropertyChanged(
    const dbus::ObjectPath& object_path,
    const std::string& property_name) {
  FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
                    DevicePropertyChanged(object_path, property_name));
}

void FakeBluetoothDeviceClient::DiscoverySimulationTimer() {
  if (!discovery_simulation_step_)
    return;

  // Timer fires every .75s, the numbers below are arbitrary to give a feel
  // for a discovery process.
  VLOG(1) << "discovery simulation, step " << discovery_simulation_step_;
  if (discovery_simulation_step_ == 2) {
    if (std::find(device_list_.begin(), device_list_.end(),
                  dbus::ObjectPath(kAppleMousePath)) == device_list_.end()) {
      Properties* properties = new Properties(base::Bind(
          &FakeBluetoothDeviceClient::OnPropertyChanged,
          base::Unretained(this),
          dbus::ObjectPath(kAppleMousePath)));
      properties->address.ReplaceValue(kAppleMouseAddress);
      properties->bluetooth_class.ReplaceValue(kAppleMouseClass);
      properties->name.ReplaceValue("Fake Apple Magic Mouse");
      properties->alias.ReplaceValue(kAppleMouseName);
      properties->adapter.ReplaceValue(
          dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));

      std::vector<std::string> uuids;
      uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
      properties->uuids.ReplaceValue(uuids);

      properties_map_[dbus::ObjectPath(kAppleMousePath)] = properties;
      device_list_.push_back(dbus::ObjectPath(kAppleMousePath));
      FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
                        DeviceAdded(dbus::ObjectPath(kAppleMousePath)));
    }

  } else if (discovery_simulation_step_ == 4) {
    if (std::find(device_list_.begin(), device_list_.end(),
                  dbus::ObjectPath(kAppleKeyboardPath)) == device_list_.end()) {
      Properties *properties = new Properties(base::Bind(
          &FakeBluetoothDeviceClient::OnPropertyChanged,
          base::Unretained(this),
          dbus::ObjectPath(kAppleKeyboardPath)));
      properties->address.ReplaceValue(kAppleKeyboardAddress);
      properties->bluetooth_class.ReplaceValue(kAppleKeyboardClass);
      properties->name.ReplaceValue("Fake Apple Wireless Keyboard");
      properties->alias.ReplaceValue(kAppleKeyboardName);
      properties->adapter.ReplaceValue(
          dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));

      std::vector<std::string> uuids;
      uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
      properties->uuids.ReplaceValue(uuids);

      properties_map_[dbus::ObjectPath(kAppleKeyboardPath)] = properties;
      device_list_.push_back(dbus::ObjectPath(kAppleKeyboardPath));
      FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
                        DeviceAdded(dbus::ObjectPath(kAppleKeyboardPath)));
    }

    if (std::find(device_list_.begin(), device_list_.end(),
                  dbus::ObjectPath(kVanishingDevicePath)) ==
        device_list_.end()) {
      Properties* properties = new Properties(base::Bind(
          &FakeBluetoothDeviceClient::OnPropertyChanged,
          base::Unretained(this),
          dbus::ObjectPath(kVanishingDevicePath)));
      properties->address.ReplaceValue(kVanishingDeviceAddress);
      properties->bluetooth_class.ReplaceValue(kVanishingDeviceClass);
      properties->name.ReplaceValue("Fake Vanishing Device");
      properties->alias.ReplaceValue(kVanishingDeviceName);
      properties->adapter.ReplaceValue(
          dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));

      properties_map_[dbus::ObjectPath(kVanishingDevicePath)] = properties;
      device_list_.push_back(dbus::ObjectPath(kVanishingDevicePath));
      FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
                        DeviceAdded(dbus::ObjectPath(kVanishingDevicePath)));
    }

  } else if (discovery_simulation_step_ == 7) {
    if (std::find(device_list_.begin(), device_list_.end(),
                  dbus::ObjectPath(kMicrosoftMousePath)) ==
        device_list_.end()) {
      Properties* properties = new Properties(base::Bind(
          &FakeBluetoothDeviceClient::OnPropertyChanged,
          base::Unretained(this),
          dbus::ObjectPath(kMicrosoftMousePath)));
      properties->address.ReplaceValue(kMicrosoftMouseAddress);
      properties->bluetooth_class.ReplaceValue(kMicrosoftMouseClass);
      properties->name.ReplaceValue("Fake Microsoft Mouse");
      properties->alias.ReplaceValue(kMicrosoftMouseName);
      properties->adapter.ReplaceValue(
          dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));

      std::vector<std::string> uuids;
      uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
      properties->uuids.ReplaceValue(uuids);

      properties_map_[dbus::ObjectPath(kMicrosoftMousePath)] = properties;
      device_list_.push_back(dbus::ObjectPath(kMicrosoftMousePath));
      FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
                        DeviceAdded(dbus::ObjectPath(kMicrosoftMousePath)));
    }

  } else if (discovery_simulation_step_ == 8) {
    if (std::find(device_list_.begin(), device_list_.end(),
                  dbus::ObjectPath(kMotorolaKeyboardPath)) ==
        device_list_.end()) {
      Properties* properties = new Properties(base::Bind(
          &FakeBluetoothDeviceClient::OnPropertyChanged,
          base::Unretained(this),
          dbus::ObjectPath(kMotorolaKeyboardPath)));
      properties->address.ReplaceValue(kMotorolaKeyboardAddress);
      properties->bluetooth_class.ReplaceValue(kMotorolaKeyboardClass);
      properties->name.ReplaceValue("Fake Motorola Keyboard");
      properties->alias.ReplaceValue(kMotorolaKeyboardName);
      properties->adapter.ReplaceValue(
          dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));

      std::vector<std::string> uuids;
      uuids.push_back("00001124-0000-1000-8000-00805f9b34fb");
      properties->uuids.ReplaceValue(uuids);

      properties_map_[dbus::ObjectPath(kMotorolaKeyboardPath)] = properties;
      device_list_.push_back(dbus::ObjectPath(kMotorolaKeyboardPath));
      FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
                        DeviceAdded(dbus::ObjectPath(kMotorolaKeyboardPath)));
    }

    if (std::find(device_list_.begin(), device_list_.end(),
                  dbus::ObjectPath(kSonyHeadphonesPath)) ==
        device_list_.end()) {
      Properties* properties = new Properties(base::Bind(
          &FakeBluetoothDeviceClient::OnPropertyChanged,
          base::Unretained(this),
          dbus::ObjectPath(kSonyHeadphonesPath)));
      properties->address.ReplaceValue(kSonyHeadphonesAddress);
      properties->bluetooth_class.ReplaceValue(kSonyHeadphonesClass);
      properties->name.ReplaceValue("Fake Sony Headphones");
      properties->alias.ReplaceValue(kSonyHeadphonesName);
      properties->adapter.ReplaceValue(
          dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));

      properties_map_[dbus::ObjectPath(kSonyHeadphonesPath)] = properties;
      device_list_.push_back(dbus::ObjectPath(kSonyHeadphonesPath));
      FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
                        DeviceAdded(dbus::ObjectPath(kSonyHeadphonesPath)));
    }

  } else if (discovery_simulation_step_ == 10) {
    if (std::find(device_list_.begin(), device_list_.end(),
                  dbus::ObjectPath(kPhonePath)) == device_list_.end()) {
      Properties* properties = new Properties(base::Bind(
          &FakeBluetoothDeviceClient::OnPropertyChanged,
          base::Unretained(this),
          dbus::ObjectPath(kPhonePath)));
      properties->address.ReplaceValue(kPhoneAddress);
      properties->bluetooth_class.ReplaceValue(kPhoneClass);
      properties->name.ReplaceValue("Fake Phone");
      properties->alias.ReplaceValue(kPhoneName);
      properties->adapter.ReplaceValue(
          dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));

      properties_map_[dbus::ObjectPath(kPhonePath)] = properties;
      device_list_.push_back(dbus::ObjectPath(kPhonePath));
      FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
                        DeviceAdded(dbus::ObjectPath(kPhonePath)));
    }

    if (std::find(device_list_.begin(), device_list_.end(),
                  dbus::ObjectPath(kWeirdDevicePath)) == device_list_.end()) {
      Properties* properties = new Properties(base::Bind(
          &FakeBluetoothDeviceClient::OnPropertyChanged,
          base::Unretained(this),
          dbus::ObjectPath(kWeirdDevicePath)));
      properties->address.ReplaceValue(kWeirdDeviceAddress);
      properties->bluetooth_class.ReplaceValue(kWeirdDeviceClass);
      properties->name.ReplaceValue("Fake Weird Device");
      properties->alias.ReplaceValue(kWeirdDeviceName);
      properties->adapter.ReplaceValue(
          dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));

      properties_map_[dbus::ObjectPath(kWeirdDevicePath)] = properties;
      device_list_.push_back(dbus::ObjectPath(kWeirdDevicePath));
      FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
                        DeviceAdded(dbus::ObjectPath(kWeirdDevicePath)));
    }

    if (std::find(device_list_.begin(), device_list_.end(),
                  dbus::ObjectPath(kUnconnectableDevicePath)) ==
        device_list_.end()) {
      Properties* properties = new Properties(base::Bind(
          &FakeBluetoothDeviceClient::OnPropertyChanged,
          base::Unretained(this),
          dbus::ObjectPath(kUnconnectableDevicePath)));
      properties->address.ReplaceValue(kUnconnectableDeviceAddress);
      properties->bluetooth_class.ReplaceValue(kUnconnectableDeviceClass);
      properties->name.ReplaceValue("Fake Unconnectable Device");
      properties->alias.ReplaceValue(kUnconnectableDeviceName);
      properties->adapter.ReplaceValue(
          dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));

      properties_map_[dbus::ObjectPath(kUnconnectableDevicePath)] = properties;
      device_list_.push_back(dbus::ObjectPath(kUnconnectableDevicePath));
      FOR_EACH_OBSERVER(
          BluetoothDeviceClient::Observer, observers_,
          DeviceAdded(dbus::ObjectPath(kUnconnectableDevicePath)));
    }

    if (std::find(device_list_.begin(), device_list_.end(),
                  dbus::ObjectPath(kUnpairableDevicePath)) ==
        device_list_.end()) {
      Properties* properties = new Properties(base::Bind(
          &FakeBluetoothDeviceClient::OnPropertyChanged,
          base::Unretained(this),
          dbus::ObjectPath(kUnpairableDevicePath)));
      properties->address.ReplaceValue(kUnpairableDeviceAddress);
      properties->bluetooth_class.ReplaceValue(kUnpairableDeviceClass);
      properties->name.ReplaceValue("Fake Unpairable Device");
      properties->alias.ReplaceValue(kUnpairableDeviceName);
      properties->adapter.ReplaceValue(
          dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));

      properties_map_[dbus::ObjectPath(kUnpairableDevicePath)] = properties;
      device_list_.push_back(dbus::ObjectPath(kUnpairableDevicePath));
      FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
                        DeviceAdded(dbus::ObjectPath(kUnpairableDevicePath)));
    }

  } else if (discovery_simulation_step_ == 13) {
    RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
                 dbus::ObjectPath(kVanishingDevicePath));

  } else if (discovery_simulation_step_ == 14) {
    return;

  }

  ++discovery_simulation_step_;
  base::MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer,
                 base::Unretained(this)),
      base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
}


void FakeBluetoothDeviceClient::CompleteSimulatedPairing(
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  VLOG(1) << "CompleteSimulatedPairing: " << object_path.value();
  if (pairing_cancelled_) {
    pairing_cancelled_ = false;

    error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled,
                       "Cancaled");
  } else {
    Properties* properties = GetProperties(object_path);

    properties->paired.ReplaceValue(true);
    callback.Run();

    AddInputDeviceIfNeeded(object_path, properties);
  }
}

void FakeBluetoothDeviceClient::TimeoutSimulatedPairing(
    const dbus::ObjectPath& object_path,
    const ErrorCallback& error_callback) {
  VLOG(1) << "TimeoutSimulatedPairing: " << object_path.value();

  error_callback.Run(bluetooth_device::kErrorAuthenticationTimeout,
                     "Timed out");
}

void FakeBluetoothDeviceClient::CancelSimulatedPairing(
    const dbus::ObjectPath& object_path,
    const ErrorCallback& error_callback) {
  VLOG(1) << "CancelSimulatedPairing: " << object_path.value();

  error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled,
                     "Canceled");
}

void FakeBluetoothDeviceClient::RejectSimulatedPairing(
    const dbus::ObjectPath& object_path,
    const ErrorCallback& error_callback) {
  VLOG(1) << "RejectSimulatedPairing: " << object_path.value();

  error_callback.Run(bluetooth_device::kErrorAuthenticationRejected,
                     "Rejected");
}

void FakeBluetoothDeviceClient::FailSimulatedPairing(
    const dbus::ObjectPath& object_path,
    const ErrorCallback& error_callback) {
  VLOG(1) << "FailSimulatedPairing: " << object_path.value();

  error_callback.Run(bluetooth_device::kErrorFailed, "Failed");
}

void FakeBluetoothDeviceClient::AddInputDeviceIfNeeded(
    const dbus::ObjectPath& object_path,
    Properties* properties) {
  // If the paired device is a HID device based on it's bluetooth class,
  // simulate the Input interface.
  FakeBluetoothInputClient* fake_bluetooth_input_client =
      static_cast<FakeBluetoothInputClient*>(
          DBusThreadManager::Get()->GetBluetoothInputClient());

  if ((properties->bluetooth_class.value() & 0x001f03) == 0x000500)
    fake_bluetooth_input_client->AddInputDevice(object_path);
}

void FakeBluetoothDeviceClient::PinCodeCallback(
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback,
    BluetoothAgentServiceProvider::Delegate::Status status,
    const std::string& pincode) {
  VLOG(1) << "PinCodeCallback: " << object_path.value();

  if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
                   base::Unretained(this),
                   object_path, callback, error_callback),
        base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));

  } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
                   base::Unretained(this),
                   object_path, error_callback),
        base::TimeDelta::FromMilliseconds(simulation_interval_ms_));

  } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
                   base::Unretained(this),
                   object_path, error_callback),
        base::TimeDelta::FromMilliseconds(simulation_interval_ms_));

  }
}

void FakeBluetoothDeviceClient::PasskeyCallback(
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback,
    BluetoothAgentServiceProvider::Delegate::Status status,
    uint32 passkey) {
  VLOG(1) << "PasskeyCallback: " << object_path.value();

  if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
                   base::Unretained(this),
                   object_path, callback, error_callback),
        base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));

  } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
                   base::Unretained(this),
                   object_path, error_callback),
        base::TimeDelta::FromMilliseconds(simulation_interval_ms_));

  } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
                   base::Unretained(this),
                   object_path, error_callback),
        base::TimeDelta::FromMilliseconds(simulation_interval_ms_));

  }
}

void FakeBluetoothDeviceClient::ConfirmationCallback(
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback,
    BluetoothAgentServiceProvider::Delegate::Status status) {
  VLOG(1) << "ConfirmationCallback: " << object_path.value();

  if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
                   base::Unretained(this),
                   object_path, callback, error_callback),
        base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_));

  } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing,
                   base::Unretained(this),
                   object_path, error_callback),
        base::TimeDelta::FromMilliseconds(simulation_interval_ms_));

  } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing,
                   base::Unretained(this),
                   object_path, error_callback),
        base::TimeDelta::FromMilliseconds(simulation_interval_ms_));

  }
}

void FakeBluetoothDeviceClient::SimulateKeypress(
    uint16 entered,
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  VLOG(1) << "SimulateKeypress " << entered << ": " << object_path.value();

  FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client =
      static_cast<FakeBluetoothAgentManagerClient*>(
          DBusThreadManager::Get()->GetBluetoothAgentManagerClient());
  FakeBluetoothAgentServiceProvider* agent_service_provider =
      fake_bluetooth_agent_manager_client->GetAgentServiceProvider();

  // The agent service provider object could have been destroyed after the
  // pairing is canceled.
  if (!agent_service_provider)
    return;

  agent_service_provider->DisplayPasskey(object_path, 123456, entered);

  if (entered < 7) {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress,
                   base::Unretained(this),
                   entered + 1, object_path, callback, error_callback),
        base::TimeDelta::FromMilliseconds(simulation_interval_ms_));

  } else {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing,
                   base::Unretained(this),
                   object_path, callback, error_callback),
        base::TimeDelta::FromMilliseconds(simulation_interval_ms_));

  }
}

void FakeBluetoothDeviceClient::ConnectionCallback(
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback,
    BluetoothProfileServiceProvider::Delegate::Status status) {
  VLOG(1) << "ConnectionCallback: " << object_path.value();

  if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) {
    callback.Run();
  } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) {
    // TODO(keybuk): tear down this side of the connection
    error_callback.Run(bluetooth_device::kErrorFailed, "Canceled");
  } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) {
    // TODO(keybuk): tear down this side of the connection
    error_callback.Run(bluetooth_device::kErrorFailed, "Rejected");
  }
}

void FakeBluetoothDeviceClient::DisconnectionCallback(
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback,
    BluetoothProfileServiceProvider::Delegate::Status status) {
  VLOG(1) << "DisconnectionCallback: " << object_path.value();

  if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) {
    // TODO(keybuk): tear down this side of the connection
    callback.Run();
  } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) {
    error_callback.Run(bluetooth_device::kErrorFailed, "Canceled");
  } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) {
    error_callback.Run(bluetooth_device::kErrorFailed, "Rejected");
  }
}

}  // namespace chromeos
