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