Home | History | Annotate | Download | only in dbus
      1 // Copyright 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_nfc_adapter_client.h"
      6 
      7 #include "base/logging.h"
      8 #include "chromeos/dbus/dbus_thread_manager.h"
      9 #include "chromeos/dbus/fake_nfc_device_client.h"
     10 #include "chromeos/dbus/fake_nfc_tag_client.h"
     11 #include "chromeos/dbus/nfc_client_helpers.h"
     12 #include "dbus/message.h"
     13 #include "dbus/object_path.h"
     14 #include "third_party/cros_system_api/dbus/service_constants.h"
     15 
     16 namespace chromeos {
     17 
     18 using nfc_client_helpers::ObjectPathVector;
     19 
     20 const char FakeNfcAdapterClient::kAdapterPath0[] = "/fake/nfc0";
     21 const char FakeNfcAdapterClient::kAdapterPath1[] = "/fake/nfc1";
     22 
     23 FakeNfcAdapterClient::Properties::Properties(
     24     const PropertyChangedCallback& callback)
     25     : NfcAdapterClient::Properties(NULL, callback) {
     26 }
     27 
     28 FakeNfcAdapterClient::Properties::~Properties() {
     29 }
     30 
     31 void FakeNfcAdapterClient::Properties::Get(
     32     dbus::PropertyBase* property,
     33     dbus::PropertySet::GetCallback callback) {
     34   VLOG(1) << "Get " << property->name();
     35   callback.Run(false);
     36 }
     37 
     38 void FakeNfcAdapterClient::Properties::GetAll() {
     39   VLOG(1) << "GetAll";
     40 }
     41 
     42 void FakeNfcAdapterClient::Properties::Set(
     43     dbus::PropertyBase* property,
     44     dbus::PropertySet::SetCallback callback) {
     45   VLOG(1) << "Set " << property->name();
     46   if (property->name() != powered.name()) {
     47     callback.Run(false);
     48     return;
     49   }
     50 
     51   // Cannot set the power if currently polling.
     52   if (polling.value()) {
     53     LOG(ERROR) << "Cannot set power while polling.";
     54     callback.Run(false);
     55     return;
     56   }
     57 
     58   // Cannot set power if there is a device or a tag that is currently
     59   // "paired".
     60   if (!devices.value().empty() || !tags.value().empty()) {
     61     LOG(ERROR) << "Cannot set power while the device is paired.";
     62     callback.Run(false);
     63     return;
     64   }
     65 
     66   // Obtain the cached "set value" and send a property changed signal only if
     67   // its value is different from the current value of the property.
     68   scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
     69   dbus::MessageWriter writer(response.get());
     70   property->AppendSetValueToWriter(&writer);
     71   dbus::MessageReader reader(response.get());
     72   bool set_value = false;
     73   if (!reader.PopVariantOfBool(&set_value) || set_value == powered.value()) {
     74     LOG(WARNING) << "Property has not changed.";
     75     callback.Run(false);
     76     return;
     77   }
     78   property->ReplaceValueWithSetValue();
     79   callback.Run(true);
     80 }
     81 
     82 FakeNfcAdapterClient::FakeNfcAdapterClient()
     83     : present_(true),
     84       second_present_(false),
     85       start_pairing_on_poll_(true),
     86       device_pairing_(false) {
     87   VLOG(1) << "Creating FakeNfcAdapterClient";
     88 
     89   std::vector<std::string> protocols;
     90   protocols.push_back(nfc_common::kProtocolFelica);
     91   protocols.push_back(nfc_common::kProtocolMifare);
     92   protocols.push_back(nfc_common::kProtocolJewel);
     93   protocols.push_back(nfc_common::kProtocolIsoDep);
     94   protocols.push_back(nfc_common::kProtocolNfcDep);
     95 
     96   properties_.reset(new Properties(base::Bind(
     97       &FakeNfcAdapterClient::OnPropertyChanged,
     98       base::Unretained(this),
     99       dbus::ObjectPath(kAdapterPath0))));
    100   properties_->protocols.ReplaceValue(protocols);
    101 
    102   second_properties_.reset(new Properties(base::Bind(
    103       &FakeNfcAdapterClient::OnPropertyChanged,
    104       base::Unretained(this),
    105       dbus::ObjectPath(kAdapterPath1))));
    106   second_properties_->protocols.ReplaceValue(protocols);
    107 }
    108 
    109 FakeNfcAdapterClient::~FakeNfcAdapterClient() {
    110 }
    111 
    112 void FakeNfcAdapterClient::Init(dbus::Bus* bus) {
    113 }
    114 
    115 void FakeNfcAdapterClient::AddObserver(Observer* observer) {
    116   observers_.AddObserver(observer);
    117 }
    118 
    119 void FakeNfcAdapterClient::RemoveObserver(Observer* observer) {
    120   observers_.RemoveObserver(observer);
    121 }
    122 
    123 std::vector<dbus::ObjectPath> FakeNfcAdapterClient::GetAdapters() {
    124   std::vector<dbus::ObjectPath> object_paths;
    125   if (present_)
    126     object_paths.push_back(dbus::ObjectPath(kAdapterPath0));
    127   if (second_present_)
    128     object_paths.push_back(dbus::ObjectPath(kAdapterPath1));
    129   return object_paths;
    130 }
    131 
    132 FakeNfcAdapterClient::Properties*
    133 FakeNfcAdapterClient::GetProperties(const dbus::ObjectPath& object_path) {
    134   if (object_path == dbus::ObjectPath(kAdapterPath0))
    135     return properties_.get();
    136   if (object_path == dbus::ObjectPath(kAdapterPath1))
    137     return second_properties_.get();
    138   return NULL;
    139 }
    140 
    141 void FakeNfcAdapterClient::StartPollLoop(
    142     const dbus::ObjectPath& object_path,
    143     const std::string& mode,
    144     const base::Closure& callback,
    145     const nfc_client_helpers::ErrorCallback& error_callback) {
    146   VLOG(1) << "FakeNfcAdapterClient::StartPollLoop";
    147   if (object_path != dbus::ObjectPath(kAdapterPath0)) {
    148     error_callback.Run(nfc_client_helpers::kNoResponseError, "");
    149     return;
    150   }
    151   if (!properties_->powered.value()) {
    152     error_callback.Run(nfc_error::kFailed, "Adapter not powered.");
    153     return;
    154   }
    155   if (properties_->polling.value()) {
    156     error_callback.Run(nfc_error::kFailed, "Already polling.");
    157     return;
    158   }
    159   if (!properties_->devices.value().empty() ||
    160       !properties_->tags.value().empty()) {
    161     error_callback.Run(nfc_error::kFailed, "Adapter busy.");
    162     return;
    163   }
    164   properties_->polling.ReplaceValue(true);
    165   properties_->mode.ReplaceValue(mode);
    166   callback.Run();
    167 
    168   if (!start_pairing_on_poll_)
    169     return;
    170 
    171   if (device_pairing_) {
    172     FakeNfcDeviceClient* device_client =
    173         static_cast<FakeNfcDeviceClient*>(
    174             DBusThreadManager::Get()->GetNfcDeviceClient());
    175     device_client->BeginPairingSimulation(3000, 2000);
    176   } else {
    177     FakeNfcTagClient* tag_client =
    178         static_cast<FakeNfcTagClient*>(
    179             DBusThreadManager::Get()->GetNfcTagClient());
    180     tag_client->BeginPairingSimulation(2000);
    181   }
    182   device_pairing_ = !device_pairing_;
    183 }
    184 
    185 void FakeNfcAdapterClient::StopPollLoop(
    186     const dbus::ObjectPath& object_path,
    187     const base::Closure& callback,
    188     const nfc_client_helpers::ErrorCallback& error_callback) {
    189   VLOG(1) << "FakeNfcAdapterClient::StopPollLoop.";
    190   if (object_path != dbus::ObjectPath(kAdapterPath0)) {
    191     error_callback.Run(nfc_client_helpers::kNoResponseError, "");
    192     return;
    193   }
    194   if (!properties_->polling.value()) {
    195     error_callback.Run("org.neard.Error.Failed", "Not polling.");
    196     return;
    197   }
    198   FakeNfcDeviceClient* device_client =
    199       static_cast<FakeNfcDeviceClient*>(
    200           DBusThreadManager::Get()->GetNfcDeviceClient());
    201   device_client->EndPairingSimulation();
    202   FakeNfcTagClient* tag_client =
    203       static_cast<FakeNfcTagClient*>(
    204           DBusThreadManager::Get()->GetNfcTagClient());
    205   tag_client->EndPairingSimulation();
    206   properties_->polling.ReplaceValue(false);
    207   callback.Run();
    208 }
    209 
    210 void FakeNfcAdapterClient::SetAdapterPresent(bool present) {
    211   if (present == present_)
    212     return;
    213   present_ = present;
    214   if (present_) {
    215     FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
    216                       AdapterAdded(dbus::ObjectPath(kAdapterPath0)));
    217   } else {
    218     FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
    219                       AdapterRemoved(dbus::ObjectPath(kAdapterPath0)));
    220   }
    221 }
    222 
    223 void FakeNfcAdapterClient::SetSecondAdapterPresent(bool present) {
    224   if (present == second_present_)
    225     return;
    226   second_present_ = present;
    227   if (present_) {
    228     FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
    229                       AdapterAdded(dbus::ObjectPath(kAdapterPath1)));
    230   } else {
    231     FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
    232                       AdapterRemoved(dbus::ObjectPath(kAdapterPath1)));
    233   }
    234 }
    235 
    236 void FakeNfcAdapterClient::SetDevice(const dbus::ObjectPath& device_path) {
    237   LOG(INFO) << "Add device path to the fake adapter: " << device_path.value();
    238   if (!properties_->polling.value()) {
    239     LOG(ERROR) << "Adapter not polling, cannot set device.";
    240     return;
    241   }
    242   const ObjectPathVector& devices(properties_->devices.value());
    243   for (ObjectPathVector::const_iterator iter = devices.begin();
    244        iter != devices.end(); ++iter) {
    245     if (*iter == device_path) {
    246       LOG(WARNING) << "Device path already in list of devices.";
    247       return;
    248     }
    249   }
    250   // Mark as not polling.
    251   properties_->polling.ReplaceValue(false);
    252 
    253   ObjectPathVector new_devices = devices;
    254   new_devices.push_back(device_path);
    255   properties_->devices.ReplaceValue(new_devices);
    256 }
    257 
    258 void FakeNfcAdapterClient::SetTag(const dbus::ObjectPath& tag_path) {
    259   LOG(INFO) << "Add tag path to the fake adapter: " << tag_path.value();
    260   if (!properties_->polling.value()) {
    261     LOG(ERROR) << "Adapter not polling, cannot set tag.";
    262     return;
    263   }
    264   const ObjectPathVector& tags(properties_->tags.value());
    265   for (ObjectPathVector::const_iterator iter = tags.begin();
    266        iter != tags.end(); ++iter) {
    267     if (*iter == tag_path) {
    268       LOG(WARNING) << "Tag path already in list of tags.";
    269       return;
    270     }
    271   }
    272   // Mark as not polling.
    273   properties_->polling.ReplaceValue(false);
    274 
    275   ObjectPathVector new_tags = tags;
    276   new_tags.push_back(tag_path);
    277   properties_->tags.ReplaceValue(new_tags);
    278 }
    279 
    280 void FakeNfcAdapterClient::UnsetDevice(const dbus::ObjectPath& device_path) {
    281   LOG(INFO) << "Remove device path from the fake adapter: "
    282             << device_path.value();
    283   ObjectPathVector new_devices = properties_->devices.value();
    284   for (ObjectPathVector::iterator iter = new_devices.begin();
    285        iter != new_devices.end(); ++iter) {
    286     if (*iter == device_path) {
    287       new_devices.erase(iter);
    288       properties_->devices.ReplaceValue(new_devices);
    289 
    290       // Mark as polling.
    291       DCHECK(!properties_->polling.value());
    292       properties_->polling.ReplaceValue(true);
    293       return;
    294     }
    295   }
    296   LOG(WARNING) << "Device path not in list of devices.";
    297 }
    298 
    299 void FakeNfcAdapterClient::UnsetTag(const dbus::ObjectPath& tag_path) {
    300   LOG(INFO) << "Remove tag path from the fake adapter: " << tag_path.value();
    301   ObjectPathVector new_tags = properties_->tags.value();
    302   for (ObjectPathVector::iterator iter = new_tags.begin();
    303        iter != new_tags.end(); ++iter) {
    304     if (*iter == tag_path) {
    305       new_tags.erase(iter);
    306       properties_->tags.ReplaceValue(new_tags);
    307 
    308       // Mark as polling.
    309       DCHECK(!properties_->polling.value());
    310       properties_->polling.ReplaceValue(true);
    311       return;
    312     }
    313   }
    314   LOG(WARNING) << "Tag path not in list of tags.";
    315 }
    316 
    317 void FakeNfcAdapterClient::EnablePairingOnPoll(bool enabled) {
    318   start_pairing_on_poll_ = enabled;
    319 }
    320 
    321 void FakeNfcAdapterClient::OnPropertyChanged(
    322     const dbus::ObjectPath& object_path,
    323     const std::string& property_name) {
    324   FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
    325                     AdapterPropertyChanged(object_path, property_name));
    326 }
    327 
    328 }  // namespace chromeos
    329