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 "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"
18 using nfc_client_helpers::ObjectPathVector
;
20 const char FakeNfcAdapterClient::kAdapterPath0
[] = "/fake/nfc0";
21 const char FakeNfcAdapterClient::kAdapterPath1
[] = "/fake/nfc1";
23 FakeNfcAdapterClient::Properties::Properties(
24 const PropertyChangedCallback
& callback
)
25 : NfcAdapterClient::Properties(NULL
, callback
) {
28 FakeNfcAdapterClient::Properties::~Properties() {
31 void FakeNfcAdapterClient::Properties::Get(
32 dbus::PropertyBase
* property
,
33 dbus::PropertySet::GetCallback callback
) {
34 VLOG(1) << "Get " << property
->name();
38 void FakeNfcAdapterClient::Properties::GetAll() {
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()) {
51 // Cannot set the power if currently polling.
52 if (polling
.value()) {
53 LOG(ERROR
) << "Cannot set power while polling.";
58 // Cannot set power if there is a device or a tag that is currently
60 if (!devices
.value().empty() || !tags
.value().empty()) {
61 LOG(ERROR
) << "Cannot set power while the device is paired.";
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.";
78 property
->ReplaceValueWithSetValue();
82 FakeNfcAdapterClient::FakeNfcAdapterClient()
84 second_present_(false),
85 start_pairing_on_poll_(true),
86 device_pairing_(false) {
87 VLOG(1) << "Creating FakeNfcAdapterClient";
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
);
96 properties_
.reset(new Properties(base::Bind(
97 &FakeNfcAdapterClient::OnPropertyChanged
,
98 base::Unretained(this),
99 dbus::ObjectPath(kAdapterPath0
))));
100 properties_
->protocols
.ReplaceValue(protocols
);
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
);
109 FakeNfcAdapterClient::~FakeNfcAdapterClient() {
112 void FakeNfcAdapterClient::Init(dbus::Bus
* bus
) {
115 void FakeNfcAdapterClient::AddObserver(Observer
* observer
) {
116 observers_
.AddObserver(observer
);
119 void FakeNfcAdapterClient::RemoveObserver(Observer
* observer
) {
120 observers_
.RemoveObserver(observer
);
123 std::vector
<dbus::ObjectPath
> FakeNfcAdapterClient::GetAdapters() {
124 std::vector
<dbus::ObjectPath
> object_paths
;
126 object_paths
.push_back(dbus::ObjectPath(kAdapterPath0
));
128 object_paths
.push_back(dbus::ObjectPath(kAdapterPath1
));
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();
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
, "");
151 if (!properties_
->powered
.value()) {
152 error_callback
.Run(nfc_error::kFailed
, "Adapter not powered.");
155 if (properties_
->polling
.value()) {
156 error_callback
.Run(nfc_error::kFailed
, "Already polling.");
159 if (!properties_
->devices
.value().empty() ||
160 !properties_
->tags
.value().empty()) {
161 error_callback
.Run(nfc_error::kFailed
, "Adapter busy.");
164 properties_
->polling
.ReplaceValue(true);
165 properties_
->mode
.ReplaceValue(mode
);
168 if (!start_pairing_on_poll_
)
171 if (device_pairing_
) {
172 FakeNfcDeviceClient
* device_client
=
173 static_cast<FakeNfcDeviceClient
*>(
174 DBusThreadManager::Get()->GetNfcDeviceClient());
175 device_client
->BeginPairingSimulation(3000, 2000);
177 FakeNfcTagClient
* tag_client
=
178 static_cast<FakeNfcTagClient
*>(
179 DBusThreadManager::Get()->GetNfcTagClient());
180 tag_client
->BeginPairingSimulation(2000);
182 device_pairing_
= !device_pairing_
;
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
, "");
194 if (!properties_
->polling
.value()) {
195 error_callback
.Run("org.neard.Error.Failed", "Not polling.");
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);
210 void FakeNfcAdapterClient::SetAdapterPresent(bool present
) {
211 if (present
== present_
)
215 FOR_EACH_OBSERVER(NfcAdapterClient::Observer
, observers_
,
216 AdapterAdded(dbus::ObjectPath(kAdapterPath0
)));
218 FOR_EACH_OBSERVER(NfcAdapterClient::Observer
, observers_
,
219 AdapterRemoved(dbus::ObjectPath(kAdapterPath0
)));
223 void FakeNfcAdapterClient::SetSecondAdapterPresent(bool present
) {
224 if (present
== second_present_
)
226 second_present_
= present
;
228 FOR_EACH_OBSERVER(NfcAdapterClient::Observer
, observers_
,
229 AdapterAdded(dbus::ObjectPath(kAdapterPath1
)));
231 FOR_EACH_OBSERVER(NfcAdapterClient::Observer
, observers_
,
232 AdapterRemoved(dbus::ObjectPath(kAdapterPath1
)));
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.";
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.";
250 // Mark as not polling.
251 properties_
->polling
.ReplaceValue(false);
253 ObjectPathVector new_devices
= devices
;
254 new_devices
.push_back(device_path
);
255 properties_
->devices
.ReplaceValue(new_devices
);
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.";
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.";
272 // Mark as not polling.
273 properties_
->polling
.ReplaceValue(false);
275 ObjectPathVector new_tags
= tags
;
276 new_tags
.push_back(tag_path
);
277 properties_
->tags
.ReplaceValue(new_tags
);
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
);
291 DCHECK(!properties_
->polling
.value());
292 properties_
->polling
.ReplaceValue(true);
296 LOG(WARNING
) << "Device path not in list of devices.";
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
);
309 DCHECK(!properties_
->polling
.value());
310 properties_
->polling
.ReplaceValue(true);
314 LOG(WARNING
) << "Tag path not in list of tags.";
317 void FakeNfcAdapterClient::EnablePairingOnPoll(bool enabled
) {
318 start_pairing_on_poll_
= enabled
;
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
));
328 } // namespace chromeos