• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Properties(const PropertyChangedCallback & callback)23 FakeNfcAdapterClient::Properties::Properties(
24     const PropertyChangedCallback& callback)
25     : NfcAdapterClient::Properties(NULL, callback) {
26 }
27 
~Properties()28 FakeNfcAdapterClient::Properties::~Properties() {
29 }
30 
Get(dbus::PropertyBase * property,dbus::PropertySet::GetCallback callback)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 
GetAll()38 void FakeNfcAdapterClient::Properties::GetAll() {
39   VLOG(1) << "GetAll";
40 }
41 
Set(dbus::PropertyBase * property,dbus::PropertySet::SetCallback callback)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 
FakeNfcAdapterClient()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 
~FakeNfcAdapterClient()109 FakeNfcAdapterClient::~FakeNfcAdapterClient() {
110 }
111 
Init(dbus::Bus * bus)112 void FakeNfcAdapterClient::Init(dbus::Bus* bus) {
113 }
114 
AddObserver(Observer * observer)115 void FakeNfcAdapterClient::AddObserver(Observer* observer) {
116   observers_.AddObserver(observer);
117 }
118 
RemoveObserver(Observer * observer)119 void FakeNfcAdapterClient::RemoveObserver(Observer* observer) {
120   observers_.RemoveObserver(observer);
121 }
122 
GetAdapters()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*
GetProperties(const dbus::ObjectPath & object_path)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 
StartPollLoop(const dbus::ObjectPath & object_path,const std::string & mode,const base::Closure & callback,const nfc_client_helpers::ErrorCallback & error_callback)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 
StopPollLoop(const dbus::ObjectPath & object_path,const base::Closure & callback,const nfc_client_helpers::ErrorCallback & error_callback)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 
SetAdapterPresent(bool present)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 
SetSecondAdapterPresent(bool present)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 
SetDevice(const dbus::ObjectPath & device_path)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 
SetTag(const dbus::ObjectPath & tag_path)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 
UnsetDevice(const dbus::ObjectPath & device_path)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 
UnsetTag(const dbus::ObjectPath & tag_path)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 
EnablePairingOnPoll(bool enabled)317 void FakeNfcAdapterClient::EnablePairingOnPoll(bool enabled) {
318   start_pairing_on_poll_ = enabled;
319 }
320 
OnPropertyChanged(const dbus::ObjectPath & object_path,const std::string & property_name)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