Home | History | Annotate | Download | only in dbus
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/time/time.h"
     11 #include "chromeos/dbus/dbus_thread_manager.h"
     12 #include "chromeos/dbus/fake_bluetooth_device_client.h"
     13 #include "dbus/object_path.h"
     14 #include "third_party/cros_system_api/dbus/service_constants.h"
     15 
     16 namespace chromeos {
     17 
     18 namespace {
     19 
     20 // Default interval for delayed tasks.
     21 const int kSimulationIntervalMs = 750;
     22 
     23 }  // namespace
     24 
     25 const char FakeBluetoothAdapterClient::kAdapterPath[] =
     26     "/fake/hci0";
     27 const char FakeBluetoothAdapterClient::kAdapterName[] =
     28     "Fake Adapter";
     29 const char FakeBluetoothAdapterClient::kAdapterAddress[] =
     30     "01:1A:2B:1A:2B:03";
     31 
     32 const char FakeBluetoothAdapterClient::kSecondAdapterPath[] =
     33     "/fake/hci1";
     34 const char FakeBluetoothAdapterClient::kSecondAdapterName[] =
     35     "Second Fake Adapter";
     36 const char FakeBluetoothAdapterClient::kSecondAdapterAddress[] =
     37     "00:DE:51:10:01:00";
     38 
     39 FakeBluetoothAdapterClient::Properties::Properties(
     40     const PropertyChangedCallback& callback)
     41     : BluetoothAdapterClient::Properties(
     42         NULL,
     43         bluetooth_adapter::kBluetoothAdapterInterface,
     44         callback) {
     45 }
     46 
     47 FakeBluetoothAdapterClient::Properties::~Properties() {
     48 }
     49 
     50 void FakeBluetoothAdapterClient::Properties::Get(
     51     dbus::PropertyBase* property,
     52     dbus::PropertySet::GetCallback callback) {
     53   VLOG(1) << "Get " << property->name();
     54   callback.Run(false);
     55 }
     56 
     57 void FakeBluetoothAdapterClient::Properties::GetAll() {
     58   VLOG(1) << "GetAll";
     59 }
     60 
     61 void FakeBluetoothAdapterClient::Properties::Set(
     62     dbus::PropertyBase *property,
     63     dbus::PropertySet::SetCallback callback) {
     64   VLOG(1) << "Set " << property->name();
     65   if (property->name() == powered.name() ||
     66       property->name() == alias.name() ||
     67       property->name() == discoverable.name() ||
     68       property->name() == discoverable_timeout.name()) {
     69     callback.Run(true);
     70     property->ReplaceValueWithSetValue();
     71   } else {
     72     callback.Run(false);
     73   }
     74 }
     75 
     76 FakeBluetoothAdapterClient::FakeBluetoothAdapterClient()
     77     : visible_(true),
     78       second_visible_(false),
     79       discovering_count_(0),
     80       simulation_interval_ms_(kSimulationIntervalMs) {
     81   properties_.reset(new Properties(base::Bind(
     82       &FakeBluetoothAdapterClient::OnPropertyChanged, base::Unretained(this))));
     83 
     84   properties_->address.ReplaceValue(kAdapterAddress);
     85   properties_->name.ReplaceValue("Fake Adapter (Name)");
     86   properties_->alias.ReplaceValue(kAdapterName);
     87   properties_->pairable.ReplaceValue(true);
     88 
     89   second_properties_.reset(new Properties(base::Bind(
     90       &FakeBluetoothAdapterClient::OnPropertyChanged, base::Unretained(this))));
     91 
     92   second_properties_->address.ReplaceValue(kSecondAdapterAddress);
     93   second_properties_->name.ReplaceValue("Second Fake Adapter (Name)");
     94   second_properties_->alias.ReplaceValue(kSecondAdapterName);
     95   second_properties_->pairable.ReplaceValue(true);
     96 }
     97 
     98 FakeBluetoothAdapterClient::~FakeBluetoothAdapterClient() {
     99 }
    100 
    101 void FakeBluetoothAdapterClient::Init(dbus::Bus* bus) {
    102 }
    103 
    104 void FakeBluetoothAdapterClient::AddObserver(Observer* observer) {
    105   observers_.AddObserver(observer);
    106 }
    107 
    108 void FakeBluetoothAdapterClient::RemoveObserver(Observer* observer) {
    109   observers_.RemoveObserver(observer);
    110 }
    111 
    112 std::vector<dbus::ObjectPath> FakeBluetoothAdapterClient::GetAdapters() {
    113   std::vector<dbus::ObjectPath> object_paths;
    114   if (visible_)
    115     object_paths.push_back(dbus::ObjectPath(kAdapterPath));
    116   if (second_visible_)
    117     object_paths.push_back(dbus::ObjectPath(kSecondAdapterPath));
    118   return object_paths;
    119 }
    120 
    121 FakeBluetoothAdapterClient::Properties*
    122 FakeBluetoothAdapterClient::GetProperties(const dbus::ObjectPath& object_path) {
    123   if (object_path == dbus::ObjectPath(kAdapterPath))
    124     return properties_.get();
    125   else if (object_path == dbus::ObjectPath(kSecondAdapterPath))
    126     return second_properties_.get();
    127   else
    128     return NULL;
    129 }
    130 
    131 void FakeBluetoothAdapterClient::StartDiscovery(
    132     const dbus::ObjectPath& object_path,
    133     const base::Closure& callback,
    134     const ErrorCallback& error_callback) {
    135   if (object_path != dbus::ObjectPath(kAdapterPath)) {
    136     PostDelayedTask(base::Bind(error_callback, kNoResponseError, ""));
    137     return;
    138   }
    139 
    140   ++discovering_count_;
    141   VLOG(1) << "StartDiscovery: " << object_path.value() << ", "
    142           << "count is now " << discovering_count_;
    143   PostDelayedTask(callback);
    144 
    145   if (discovering_count_ == 1) {
    146     properties_->discovering.ReplaceValue(true);
    147 
    148     FakeBluetoothDeviceClient* device_client =
    149         static_cast<FakeBluetoothDeviceClient*>(
    150             DBusThreadManager::Get()->GetBluetoothDeviceClient());
    151     device_client->BeginDiscoverySimulation(dbus::ObjectPath(kAdapterPath));
    152   }
    153 }
    154 
    155 void FakeBluetoothAdapterClient::StopDiscovery(
    156     const dbus::ObjectPath& object_path,
    157     const base::Closure& callback,
    158     const ErrorCallback& error_callback) {
    159   if (object_path != dbus::ObjectPath(kAdapterPath)) {
    160     PostDelayedTask(base::Bind(error_callback, kNoResponseError, ""));
    161     return;
    162   }
    163 
    164   if (!discovering_count_) {
    165     LOG(WARNING) << "StopDiscovery called when not discovering";
    166     PostDelayedTask(base::Bind(error_callback, kNoResponseError, ""));
    167     return;
    168   }
    169 
    170   --discovering_count_;
    171   VLOG(1) << "StopDiscovery: " << object_path.value() << ", "
    172           << "count is now " << discovering_count_;
    173   PostDelayedTask(callback);
    174 
    175   if (discovering_count_ == 0) {
    176     FakeBluetoothDeviceClient* device_client =
    177         static_cast<FakeBluetoothDeviceClient*>(
    178             DBusThreadManager::Get()->GetBluetoothDeviceClient());
    179     device_client->EndDiscoverySimulation(dbus::ObjectPath(kAdapterPath));
    180 
    181     if (simulation_interval_ms_ > 100) {
    182       device_client->BeginIncomingPairingSimulation(
    183           dbus::ObjectPath(kAdapterPath));
    184     }
    185 
    186     properties_->discovering.ReplaceValue(false);
    187   }
    188 }
    189 
    190 void FakeBluetoothAdapterClient::RemoveDevice(
    191     const dbus::ObjectPath& object_path,
    192     const dbus::ObjectPath& device_path,
    193     const base::Closure& callback,
    194     const ErrorCallback& error_callback) {
    195   if (object_path != dbus::ObjectPath(kAdapterPath)) {
    196     error_callback.Run(kNoResponseError, "");
    197     return;
    198   }
    199 
    200   VLOG(1) << "RemoveDevice: " << object_path.value()
    201           << " " << device_path.value();
    202   callback.Run();
    203 
    204   FakeBluetoothDeviceClient* device_client =
    205       static_cast<FakeBluetoothDeviceClient*>(
    206           DBusThreadManager::Get()->GetBluetoothDeviceClient());
    207   device_client->RemoveDevice(dbus::ObjectPath(kAdapterPath), device_path);
    208 }
    209 
    210 void FakeBluetoothAdapterClient::SetSimulationIntervalMs(int interval_ms) {
    211   simulation_interval_ms_ = interval_ms;
    212 }
    213 
    214 void FakeBluetoothAdapterClient::SetVisible(
    215     bool visible) {
    216   if (visible && !visible_) {
    217     // Adapter becoming visible
    218     visible_ = visible;
    219 
    220     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
    221                       AdapterAdded(dbus::ObjectPath(kAdapterPath)));
    222 
    223   } else if (visible_ && !visible) {
    224     // Adapter becoming invisible
    225     visible_ = visible;
    226 
    227     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
    228                       AdapterRemoved(dbus::ObjectPath(kAdapterPath)));
    229   }
    230 }
    231 
    232 void FakeBluetoothAdapterClient::SetSecondVisible(
    233     bool visible) {
    234   if (visible && !second_visible_) {
    235     // Second adapter becoming visible
    236     second_visible_ = visible;
    237 
    238     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
    239                       AdapterAdded(dbus::ObjectPath(kSecondAdapterPath)));
    240 
    241   } else if (second_visible_ && !visible) {
    242     // Second adapter becoming invisible
    243     second_visible_ = visible;
    244 
    245     FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
    246                       AdapterRemoved(dbus::ObjectPath(kSecondAdapterPath)));
    247   }
    248 }
    249 
    250 void FakeBluetoothAdapterClient::OnPropertyChanged(
    251     const std::string& property_name) {
    252   if (property_name == properties_->powered.name() &&
    253       !properties_->powered.value()) {
    254     VLOG(1) << "Adapter powered off";
    255 
    256     if (discovering_count_) {
    257       discovering_count_ = 0;
    258       properties_->discovering.ReplaceValue(false);
    259     }
    260   }
    261 
    262   FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
    263                     AdapterPropertyChanged(dbus::ObjectPath(kAdapterPath),
    264                                            property_name));
    265 }
    266 
    267 void FakeBluetoothAdapterClient::PostDelayedTask(
    268     const base::Closure& callback) {
    269   base::MessageLoop::current()->PostDelayedTask(
    270       FROM_HERE, callback,
    271       base::TimeDelta::FromMilliseconds(simulation_interval_ms_));
    272 }
    273 
    274 }  // namespace chromeos
    275