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 |