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.
5 #include "chromeos/dbus/fake_nfc_adapter_client.h"
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"
17 using nfc_client_helpers::ObjectPathVector
;
19 const char FakeNfcAdapterClient::kAdapterPath0
[] = "/fake/nfc0";
20 const char FakeNfcAdapterClient::kAdapterPath1
[] = "/fake/nfc1";
22 FakeNfcAdapterClient::Properties::Properties(
23 const PropertyChangedCallback
& callback
)
24 : NfcAdapterClient::Properties(NULL
, callback
) {
27 FakeNfcAdapterClient::Properties::~Properties() {
30 void FakeNfcAdapterClient::Properties::Get(
31 dbus::PropertyBase
* property
,
32 dbus::PropertySet::GetCallback callback
) {
33 VLOG(1) << "Get " << property
->name();
37 void FakeNfcAdapterClient::Properties::GetAll() {
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()) {
50 // Cannot set the power if currently polling.
51 if (polling
.value()) {
52 LOG(ERROR
) << "Cannot set power while polling.";
57 // Cannot set power if there is a device or a tag that is currently
59 if (!devices
.value().empty() || !tags
.value().empty()) {
60 LOG(ERROR
) << "Cannot set power while the device is paired.";
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 scoped_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.";
77 property
->ReplaceValueWithSetValue();
81 FakeNfcAdapterClient::FakeNfcAdapterClient()
83 second_present_(false),
84 start_pairing_on_poll_(true),
85 device_pairing_(false) {
86 VLOG(1) << "Creating FakeNfcAdapterClient";
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
);
95 properties_
.reset(new Properties(base::Bind(
96 &FakeNfcAdapterClient::OnPropertyChanged
,
97 base::Unretained(this),
98 dbus::ObjectPath(kAdapterPath0
))));
99 properties_
->protocols
.ReplaceValue(protocols
);
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
);
108 FakeNfcAdapterClient::~FakeNfcAdapterClient() {
111 void FakeNfcAdapterClient::Init(dbus::Bus
* bus
) {
114 void FakeNfcAdapterClient::AddObserver(Observer
* observer
) {
115 observers_
.AddObserver(observer
);
118 void FakeNfcAdapterClient::RemoveObserver(Observer
* observer
) {
119 observers_
.RemoveObserver(observer
);
122 std::vector
<dbus::ObjectPath
> FakeNfcAdapterClient::GetAdapters() {
123 std::vector
<dbus::ObjectPath
> object_paths
;
125 object_paths
.push_back(dbus::ObjectPath(kAdapterPath0
));
127 object_paths
.push_back(dbus::ObjectPath(kAdapterPath1
));
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();
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
, "");
150 if (!properties_
->powered
.value()) {
151 error_callback
.Run(nfc_error::kFailed
, "Adapter not powered.");
154 if (properties_
->polling
.value()) {
155 error_callback
.Run(nfc_error::kFailed
, "Already polling.");
158 if (!properties_
->devices
.value().empty() ||
159 !properties_
->tags
.value().empty()) {
160 error_callback
.Run(nfc_error::kFailed
, "Adapter busy.");
163 properties_
->polling
.ReplaceValue(true);
164 properties_
->mode
.ReplaceValue(mode
);
167 if (!start_pairing_on_poll_
)
170 if (device_pairing_
) {
171 FakeNfcDeviceClient
* device_client
=
172 static_cast<FakeNfcDeviceClient
*>(
173 DBusThreadManager::Get()->GetNfcDeviceClient());
174 device_client
->BeginPairingSimulation(3000, 2000);
176 FakeNfcTagClient
* tag_client
=
177 static_cast<FakeNfcTagClient
*>(
178 DBusThreadManager::Get()->GetNfcTagClient());
179 tag_client
->BeginPairingSimulation(2000);
181 device_pairing_
= !device_pairing_
;
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
, "");
193 if (!properties_
->polling
.value()) {
194 error_callback
.Run("org.neard.Error.Failed", "Not polling.");
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);
209 void FakeNfcAdapterClient::SetAdapterPresent(bool present
) {
210 if (present
== present_
)
214 FOR_EACH_OBSERVER(NfcAdapterClient::Observer
, observers_
,
215 AdapterAdded(dbus::ObjectPath(kAdapterPath0
)));
217 FOR_EACH_OBSERVER(NfcAdapterClient::Observer
, observers_
,
218 AdapterRemoved(dbus::ObjectPath(kAdapterPath0
)));
222 void FakeNfcAdapterClient::SetSecondAdapterPresent(bool present
) {
223 if (present
== second_present_
)
225 second_present_
= present
;
227 FOR_EACH_OBSERVER(NfcAdapterClient::Observer
, observers_
,
228 AdapterAdded(dbus::ObjectPath(kAdapterPath1
)));
230 FOR_EACH_OBSERVER(NfcAdapterClient::Observer
, observers_
,
231 AdapterRemoved(dbus::ObjectPath(kAdapterPath1
)));
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.";
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.";
249 // Mark as not polling.
250 properties_
->polling
.ReplaceValue(false);
252 ObjectPathVector new_devices
= devices
;
253 new_devices
.push_back(device_path
);
254 properties_
->devices
.ReplaceValue(new_devices
);
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.";
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.";
271 // Mark as not polling.
272 properties_
->polling
.ReplaceValue(false);
274 ObjectPathVector new_tags
= tags
;
275 new_tags
.push_back(tag_path
);
276 properties_
->tags
.ReplaceValue(new_tags
);
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
);
290 DCHECK(!properties_
->polling
.value());
291 properties_
->polling
.ReplaceValue(true);
295 LOG(WARNING
) << "Device path not in list of devices.";
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
);
308 DCHECK(!properties_
->polling
.value());
309 properties_
->polling
.ReplaceValue(true);
313 LOG(WARNING
) << "Tag path not in list of tags.";
316 void FakeNfcAdapterClient::EnablePairingOnPoll(bool enabled
) {
317 start_pairing_on_poll_
= enabled
;
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
));
327 } // namespace chromeos