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 <stddef.h> | |
6 #include <stdint.h> | |
7 | |
8 #include <memory> | |
9 | |
10 #include "base/callback.h" | |
11 #include "base/message_loop/message_loop.h" | |
12 #include "base/run_loop.h" | |
13 #include "base/values.h" | |
14 #include "chromeos/dbus/dbus_thread_manager.h" | |
15 #include "chromeos/dbus/fake_nfc_adapter_client.h" | |
16 #include "chromeos/dbus/fake_nfc_device_client.h" | |
17 #include "chromeos/dbus/fake_nfc_record_client.h" | |
18 #include "chromeos/dbus/fake_nfc_tag_client.h" | |
19 #include "device/nfc/nfc_adapter_chromeos.h" | |
20 #include "device/nfc/nfc_ndef_record.h" | |
21 #include "device/nfc/nfc_ndef_record_utils_chromeos.h" | |
22 #include "device/nfc/nfc_peer.h" | |
23 #include "device/nfc/nfc_tag.h" | |
24 #include "device/nfc/nfc_tag_technology.h" | |
25 #include "testing/gtest/include/gtest/gtest.h" | |
26 #include "third_party/cros_system_api/dbus/service_constants.h" | |
27 | |
28 using device::NfcAdapter; | |
29 using device::NfcNdefMessage; | |
30 using device::NfcNdefRecord; | |
31 using device::NfcNdefTagTechnology; | |
32 using device::NfcPeer; | |
33 using device::NfcTag; | |
34 | |
35 namespace chromeos { | |
36 | |
37 namespace { | |
38 | |
39 // Callback passed to property structures. | |
40 void OnPropertyChangedCallback(const std::string& property_name) { | |
41 } | |
42 | |
43 // Callback passed to dbus::PropertyBase::Set. | |
44 void OnSet(bool success) { | |
45 } | |
46 | |
47 class TestObserver : public NfcAdapter::Observer, | |
48 public NfcPeer::Observer, | |
49 public NfcTag::Observer, | |
50 public NfcNdefTagTechnology::Observer { | |
51 public: | |
52 TestObserver(scoped_refptr<NfcAdapter> adapter) | |
53 : present_changed_count_(0), | |
54 powered_changed_count_(0), | |
55 polling_changed_count_(0), | |
56 peer_records_received_count_(0), | |
57 tag_records_received_count_(0), | |
58 peer_count_(0), | |
59 tag_count_(0), | |
60 adapter_(adapter) { | |
61 } | |
62 | |
63 ~TestObserver() override {} | |
64 | |
65 // NfcAdapter::Observer override. | |
66 void AdapterPresentChanged(NfcAdapter* adapter, bool present) override { | |
67 EXPECT_EQ(adapter_.get(), adapter); | |
68 present_changed_count_++; | |
69 } | |
70 | |
71 // NfcAdapter::Observer override. | |
72 void AdapterPoweredChanged(NfcAdapter* adapter, bool powered) override { | |
73 EXPECT_EQ(adapter_.get(), adapter); | |
74 powered_changed_count_++; | |
75 } | |
76 | |
77 // NfcAdapter::Observer override. | |
78 void AdapterPollingChanged(NfcAdapter* adapter, bool powered) override { | |
79 EXPECT_EQ(adapter_.get(), adapter); | |
80 polling_changed_count_++; | |
81 } | |
82 | |
83 // NfcAdapter::Observer override. | |
84 void PeerFound(NfcAdapter* adapter, NfcPeer* peer) override { | |
85 EXPECT_EQ(adapter_.get(), adapter); | |
86 peer_count_++; | |
87 peer_identifier_ = peer->GetIdentifier(); | |
88 } | |
89 | |
90 // NfcAdapter::Observer override. | |
91 void PeerLost(NfcAdapter* adapter, NfcPeer* peer) override { | |
92 EXPECT_EQ(adapter_.get(), adapter); | |
93 EXPECT_EQ(peer_identifier_, peer->GetIdentifier()); | |
94 peer_count_--; | |
95 peer_identifier_.clear(); | |
96 } | |
97 | |
98 // NfcAdapter::Observer override. | |
99 void TagFound(NfcAdapter* adapter, NfcTag* tag) override { | |
100 EXPECT_EQ(adapter_.get(), adapter); | |
101 tag_count_++; | |
102 tag_identifier_ = tag->GetIdentifier(); | |
103 } | |
104 | |
105 // NfcAdapter::Observer override. | |
106 void TagLost(NfcAdapter* adapter, NfcTag* tag) override { | |
107 EXPECT_EQ(adapter_.get(), adapter); | |
108 EXPECT_EQ(tag_identifier_, tag->GetIdentifier()); | |
109 tag_count_--; | |
110 tag_identifier_.clear(); | |
111 } | |
112 | |
113 // NfcPeer::Observer override. | |
114 void RecordReceived(NfcPeer* peer, const NfcNdefRecord* record) override { | |
115 EXPECT_EQ(peer, adapter_->GetPeer(peer_identifier_)); | |
116 EXPECT_EQ(peer_identifier_, peer->GetIdentifier()); | |
117 peer_records_received_count_++; | |
118 } | |
119 | |
120 // NfcNdefTagTechnology::Observer override. | |
121 void RecordReceived(NfcTag* tag, const NfcNdefRecord* record) override { | |
122 EXPECT_EQ(tag, adapter_->GetTag(tag_identifier_)); | |
123 EXPECT_EQ(tag_identifier_, tag->GetIdentifier()); | |
124 tag_records_received_count_++; | |
125 } | |
126 | |
127 int present_changed_count_; | |
128 int powered_changed_count_; | |
129 int polling_changed_count_; | |
130 int peer_records_received_count_; | |
131 int tag_records_received_count_; | |
132 int peer_count_; | |
133 int tag_count_; | |
134 std::string peer_identifier_; | |
135 std::string tag_identifier_; | |
136 scoped_refptr<NfcAdapter> adapter_; | |
137 }; | |
138 | |
139 } // namespace | |
140 | |
141 class NfcChromeOSTest : public testing::Test { | |
142 public: | |
143 void SetUp() override { | |
144 DBusThreadManager::Initialize(); | |
145 fake_nfc_adapter_client_ = static_cast<FakeNfcAdapterClient*>( | |
146 DBusThreadManager::Get()->GetNfcAdapterClient()); | |
147 fake_nfc_device_client_ = static_cast<FakeNfcDeviceClient*>( | |
148 DBusThreadManager::Get()->GetNfcDeviceClient()); | |
149 fake_nfc_record_client_ = static_cast<FakeNfcRecordClient*>( | |
150 DBusThreadManager::Get()->GetNfcRecordClient()); | |
151 fake_nfc_tag_client_ = static_cast<FakeNfcTagClient*>( | |
152 DBusThreadManager::Get()->GetNfcTagClient()); | |
153 | |
154 fake_nfc_adapter_client_->EnablePairingOnPoll(false); | |
155 fake_nfc_device_client_->DisableSimulationTimeout(); | |
156 fake_nfc_tag_client_->DisableSimulationTimeout(); | |
157 success_callback_count_ = 0; | |
158 error_callback_count_ = 0; | |
159 } | |
160 | |
161 void TearDown() override { | |
162 adapter_ = NULL; | |
163 DBusThreadManager::Shutdown(); | |
164 } | |
165 | |
166 // Assigns a new instance of NfcAdapterChromeOS to |adapter_|. | |
167 void SetAdapter() { | |
168 adapter_ = new NfcAdapterChromeOS(); | |
169 ASSERT_TRUE(adapter_.get() != NULL); | |
170 ASSERT_TRUE(adapter_->IsInitialized()); | |
171 base::RunLoop().RunUntilIdle(); | |
172 } | |
173 | |
174 // Generic callbacks for success and error. | |
175 void SuccessCallback() { | |
176 success_callback_count_++; | |
177 } | |
178 | |
179 void ErrorCallback() { | |
180 error_callback_count_++; | |
181 } | |
182 | |
183 void ErrorCallbackWithParameters(const std::string& error_name, | |
184 const std::string& error_message) { | |
185 LOG(INFO) << "Error callback called: " << error_name << ", " | |
186 << error_message; | |
187 error_callback_count_++; | |
188 } | |
189 | |
190 protected: | |
191 // MessageLoop instance, used to simulate asynchronous behavior. | |
192 base::MessageLoop message_loop_; | |
193 | |
194 // Fields for storing the number of times SuccessCallback and ErrorCallback | |
195 // have been called. | |
196 int success_callback_count_; | |
197 int error_callback_count_; | |
198 | |
199 // The NfcAdapter instance under test. | |
200 scoped_refptr<NfcAdapter> adapter_; | |
201 | |
202 // The fake D-Bus client instances used for testing. | |
203 FakeNfcAdapterClient* fake_nfc_adapter_client_; | |
204 FakeNfcDeviceClient* fake_nfc_device_client_; | |
205 FakeNfcRecordClient* fake_nfc_record_client_; | |
206 FakeNfcTagClient* fake_nfc_tag_client_; | |
207 }; | |
208 | |
209 // Tests that the adapter updates correctly to reflect the current "default" | |
210 // adapter, when multiple adapters appear and disappear. | |
211 TEST_F(NfcChromeOSTest, PresentChanged) { | |
212 SetAdapter(); | |
213 EXPECT_TRUE(adapter_->IsPresent()); | |
214 | |
215 TestObserver observer(adapter_); | |
216 adapter_->AddObserver(&observer); | |
217 | |
218 // Remove all adapters. | |
219 fake_nfc_adapter_client_->SetAdapterPresent(false); | |
220 EXPECT_EQ(1, observer.present_changed_count_); | |
221 EXPECT_FALSE(adapter_->IsPresent()); | |
222 | |
223 // Add two adapters. | |
224 fake_nfc_adapter_client_->SetAdapterPresent(true); | |
225 fake_nfc_adapter_client_->SetSecondAdapterPresent(true); | |
226 EXPECT_EQ(2, observer.present_changed_count_); | |
227 EXPECT_TRUE(adapter_->IsPresent()); | |
228 | |
229 // Remove the first adapter. Adapter should update to the second one. | |
230 fake_nfc_adapter_client_->SetAdapterPresent(false); | |
231 EXPECT_EQ(4, observer.present_changed_count_); | |
232 EXPECT_TRUE(adapter_->IsPresent()); | |
233 | |
234 fake_nfc_adapter_client_->SetSecondAdapterPresent(false); | |
235 EXPECT_EQ(5, observer.present_changed_count_); | |
236 EXPECT_FALSE(adapter_->IsPresent()); | |
237 } | |
238 | |
239 // Tests that the adapter correctly reflects the power state. | |
240 TEST_F(NfcChromeOSTest, SetPowered) { | |
241 SetAdapter(); | |
242 TestObserver observer(adapter_); | |
243 adapter_->AddObserver(&observer); | |
244 | |
245 EXPECT_FALSE(adapter_->IsPowered()); | |
246 | |
247 // SetPowered(false), while not powered. | |
248 adapter_->SetPowered( | |
249 false, | |
250 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
251 base::Unretained(this)), | |
252 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
253 base::Unretained(this))); | |
254 EXPECT_FALSE(adapter_->IsPowered()); | |
255 EXPECT_EQ(0, observer.powered_changed_count_); | |
256 EXPECT_EQ(0, success_callback_count_); | |
257 EXPECT_EQ(1, error_callback_count_); | |
258 | |
259 // SetPowered(true). | |
260 adapter_->SetPowered( | |
261 true, | |
262 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
263 base::Unretained(this)), | |
264 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
265 base::Unretained(this))); | |
266 EXPECT_TRUE(adapter_->IsPowered()); | |
267 EXPECT_EQ(1, observer.powered_changed_count_); | |
268 EXPECT_EQ(1, success_callback_count_); | |
269 EXPECT_EQ(1, error_callback_count_); | |
270 | |
271 // SetPowered(true), while powered. | |
272 adapter_->SetPowered( | |
273 true, | |
274 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
275 base::Unretained(this)), | |
276 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
277 base::Unretained(this))); | |
278 EXPECT_TRUE(adapter_->IsPowered()); | |
279 EXPECT_EQ(1, observer.powered_changed_count_); | |
280 EXPECT_EQ(1, success_callback_count_); | |
281 EXPECT_EQ(2, error_callback_count_); | |
282 | |
283 // SetPowered(false). | |
284 adapter_->SetPowered( | |
285 false, | |
286 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
287 base::Unretained(this)), | |
288 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
289 base::Unretained(this))); | |
290 EXPECT_FALSE(adapter_->IsPowered()); | |
291 EXPECT_EQ(2, observer.powered_changed_count_); | |
292 EXPECT_EQ(2, success_callback_count_); | |
293 EXPECT_EQ(2, error_callback_count_); | |
294 } | |
295 | |
296 // Tests that the power state updates correctly when the adapter disappears. | |
297 TEST_F(NfcChromeOSTest, PresentChangedWhilePowered) { | |
298 SetAdapter(); | |
299 TestObserver observer(adapter_); | |
300 adapter_->AddObserver(&observer); | |
301 | |
302 EXPECT_FALSE(adapter_->IsPowered()); | |
303 EXPECT_TRUE(adapter_->IsPresent()); | |
304 | |
305 adapter_->SetPowered( | |
306 true, | |
307 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
308 base::Unretained(this)), | |
309 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
310 base::Unretained(this))); | |
311 EXPECT_TRUE(adapter_->IsPowered()); | |
312 | |
313 fake_nfc_adapter_client_->SetAdapterPresent(false); | |
314 EXPECT_EQ(1, observer.present_changed_count_); | |
315 EXPECT_EQ(2, observer.powered_changed_count_); | |
316 EXPECT_FALSE(adapter_->IsPowered()); | |
317 EXPECT_FALSE(adapter_->IsPresent()); | |
318 } | |
319 | |
320 // Tests that peer and record objects are created for all peers and records | |
321 // that already exist when the adapter is created. | |
322 TEST_F(NfcChromeOSTest, PeersInitializedWhenAdapterCreated) { | |
323 // Set up the adapter client. | |
324 NfcAdapterClient::Properties* properties = | |
325 fake_nfc_adapter_client_->GetProperties( | |
326 dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0)); | |
327 properties->powered.Set(true, base::Bind(&OnSet)); | |
328 | |
329 fake_nfc_adapter_client_->StartPollLoop( | |
330 dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0), | |
331 nfc_adapter::kModeInitiator, | |
332 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
333 base::Unretained(this)), | |
334 base::Bind(&NfcChromeOSTest::ErrorCallbackWithParameters, | |
335 base::Unretained(this))); | |
336 EXPECT_EQ(1, success_callback_count_); | |
337 EXPECT_TRUE(properties->powered.value()); | |
338 EXPECT_TRUE(properties->polling.value()); | |
339 | |
340 // Start pairing simulation, which will add a fake device and fake records. | |
341 fake_nfc_device_client_->BeginPairingSimulation(0, 0); | |
342 base::RunLoop().RunUntilIdle(); | |
343 | |
344 // Create the adapter. | |
345 SetAdapter(); | |
346 TestObserver observer(adapter_); | |
347 adapter_->AddObserver(&observer); | |
348 | |
349 // Observer shouldn't have received any calls, as it got created AFTER the | |
350 // notifications were sent. | |
351 EXPECT_EQ(0, observer.present_changed_count_); | |
352 EXPECT_EQ(0, observer.powered_changed_count_); | |
353 EXPECT_EQ(0, observer.polling_changed_count_); | |
354 EXPECT_EQ(0, observer.peer_count_); | |
355 | |
356 EXPECT_TRUE(adapter_->IsPresent()); | |
357 EXPECT_TRUE(adapter_->IsPowered()); | |
358 EXPECT_FALSE(adapter_->IsPolling()); | |
359 | |
360 NfcAdapter::PeerList peers; | |
361 adapter_->GetPeers(&peers); | |
362 EXPECT_EQ(static_cast<size_t>(1), peers.size()); | |
363 | |
364 NfcPeer* peer = peers[0]; | |
365 const NfcNdefMessage& message = peer->GetNdefMessage(); | |
366 EXPECT_EQ(static_cast<size_t>(3), message.records().size()); | |
367 } | |
368 | |
369 // Tests that tag and record objects are created for all tags and records that | |
370 // already exist when the adapter is created. | |
371 TEST_F(NfcChromeOSTest, TagsInitializedWhenAdapterCreated) { | |
372 const char kTestURI[] = "fake://path/for/testing"; | |
373 | |
374 // Set up the adapter client. | |
375 NfcAdapterClient::Properties* properties = | |
376 fake_nfc_adapter_client_->GetProperties( | |
377 dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0)); | |
378 properties->powered.Set(true, base::Bind(&OnSet)); | |
379 | |
380 fake_nfc_adapter_client_->StartPollLoop( | |
381 dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0), | |
382 nfc_adapter::kModeInitiator, | |
383 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
384 base::Unretained(this)), | |
385 base::Bind(&NfcChromeOSTest::ErrorCallbackWithParameters, | |
386 base::Unretained(this))); | |
387 EXPECT_EQ(1, success_callback_count_); | |
388 EXPECT_TRUE(properties->powered.value()); | |
389 EXPECT_TRUE(properties->polling.value()); | |
390 | |
391 // Add the fake tag. | |
392 fake_nfc_tag_client_->BeginPairingSimulation(0); | |
393 base::RunLoop().RunUntilIdle(); | |
394 | |
395 // Create a fake record. | |
396 base::DictionaryValue test_record_data; | |
397 test_record_data.SetString(nfc_record::kTypeProperty, nfc_record::kTypeUri); | |
398 test_record_data.SetString(nfc_record::kUriProperty, kTestURI); | |
399 fake_nfc_tag_client_->Write( | |
400 dbus::ObjectPath(FakeNfcTagClient::kTagPath), | |
401 test_record_data, | |
402 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
403 base::Unretained(this)), | |
404 base::Bind(&NfcChromeOSTest::ErrorCallbackWithParameters, | |
405 base::Unretained(this))); | |
406 EXPECT_EQ(2, success_callback_count_); | |
407 | |
408 // Create the adapter. | |
409 SetAdapter(); | |
410 TestObserver observer(adapter_); | |
411 adapter_->AddObserver(&observer); | |
412 | |
413 // Observer shouldn't have received any calls, as it got created AFTER the | |
414 // notifications were sent. | |
415 EXPECT_EQ(0, observer.present_changed_count_); | |
416 EXPECT_EQ(0, observer.powered_changed_count_); | |
417 EXPECT_EQ(0, observer.polling_changed_count_); | |
418 EXPECT_EQ(0, observer.peer_count_); | |
419 | |
420 EXPECT_TRUE(adapter_->IsPresent()); | |
421 EXPECT_TRUE(adapter_->IsPowered()); | |
422 EXPECT_FALSE(adapter_->IsPolling()); | |
423 | |
424 NfcAdapter::TagList tags; | |
425 adapter_->GetTags(&tags); | |
426 EXPECT_EQ(static_cast<size_t>(1), tags.size()); | |
427 | |
428 NfcTag* tag = tags[0]; | |
429 const NfcNdefMessage& message = tag->GetNdefTagTechnology()->GetNdefMessage(); | |
430 EXPECT_EQ(static_cast<size_t>(1), message.records().size()); | |
431 | |
432 const NfcNdefRecord* record = message.records()[0]; | |
433 std::string uri; | |
434 EXPECT_TRUE(record->data().GetString(NfcNdefRecord::kFieldURI, &uri)); | |
435 EXPECT_EQ(kTestURI, uri); | |
436 } | |
437 | |
438 // Tests that the adapter correctly updates its state when polling is started | |
439 // and stopped. | |
440 TEST_F(NfcChromeOSTest, StartAndStopPolling) { | |
441 SetAdapter(); | |
442 EXPECT_TRUE(adapter_->IsPresent()); | |
443 | |
444 TestObserver observer(adapter_); | |
445 adapter_->AddObserver(&observer); | |
446 | |
447 // Start polling while not powered. Should fail. | |
448 EXPECT_FALSE(adapter_->IsPowered()); | |
449 adapter_->StartPolling( | |
450 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
451 base::Unretained(this)), | |
452 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
453 base::Unretained(this))); | |
454 EXPECT_EQ(0, success_callback_count_); | |
455 EXPECT_EQ(1, error_callback_count_); | |
456 EXPECT_FALSE(adapter_->IsPolling()); | |
457 | |
458 // Start polling while powered. Should succeed. | |
459 adapter_->SetPowered( | |
460 true, | |
461 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
462 base::Unretained(this)), | |
463 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
464 base::Unretained(this))); | |
465 EXPECT_EQ(1, success_callback_count_); | |
466 EXPECT_EQ(1, error_callback_count_); | |
467 EXPECT_TRUE(adapter_->IsPowered()); | |
468 | |
469 adapter_->StartPolling( | |
470 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
471 base::Unretained(this)), | |
472 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
473 base::Unretained(this))); | |
474 EXPECT_EQ(2, success_callback_count_); | |
475 EXPECT_EQ(1, error_callback_count_); | |
476 EXPECT_TRUE(adapter_->IsPolling()); | |
477 | |
478 // Start polling while already polling. Should fail. | |
479 adapter_->StartPolling( | |
480 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
481 base::Unretained(this)), | |
482 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
483 base::Unretained(this))); | |
484 EXPECT_EQ(2, success_callback_count_); | |
485 EXPECT_EQ(2, error_callback_count_); | |
486 EXPECT_TRUE(adapter_->IsPolling()); | |
487 | |
488 // Stop polling. Should succeed. | |
489 adapter_->StopPolling( | |
490 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
491 base::Unretained(this)), | |
492 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
493 base::Unretained(this))); | |
494 EXPECT_EQ(3, success_callback_count_); | |
495 EXPECT_EQ(2, error_callback_count_); | |
496 EXPECT_FALSE(adapter_->IsPolling()); | |
497 | |
498 // Stop polling while not polling. Should fail. | |
499 adapter_->StopPolling( | |
500 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
501 base::Unretained(this)), | |
502 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
503 base::Unretained(this))); | |
504 EXPECT_EQ(3, success_callback_count_); | |
505 EXPECT_EQ(3, error_callback_count_); | |
506 EXPECT_FALSE(adapter_->IsPolling()); | |
507 } | |
508 | |
509 // Tests a simple peer pairing simulation. | |
510 TEST_F(NfcChromeOSTest, PeerTest) { | |
511 SetAdapter(); | |
512 TestObserver observer(adapter_); | |
513 adapter_->AddObserver(&observer); | |
514 | |
515 adapter_->SetPowered( | |
516 true, | |
517 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
518 base::Unretained(this)), | |
519 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
520 base::Unretained(this))); | |
521 adapter_->StartPolling( | |
522 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
523 base::Unretained(this)), | |
524 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
525 base::Unretained(this))); | |
526 EXPECT_EQ(2, success_callback_count_); | |
527 | |
528 EXPECT_TRUE(adapter_->IsPowered()); | |
529 EXPECT_TRUE(adapter_->IsPolling()); | |
530 EXPECT_EQ(0, observer.peer_count_); | |
531 | |
532 // Add the fake device. | |
533 fake_nfc_device_client_->BeginPairingSimulation(0, -1); | |
534 base::RunLoop().RunUntilIdle(); | |
535 | |
536 EXPECT_EQ(1, observer.peer_count_); | |
537 EXPECT_EQ(FakeNfcDeviceClient::kDevicePath, observer.peer_identifier_); | |
538 | |
539 NfcPeer* peer = adapter_->GetPeer(observer.peer_identifier_); | |
540 CHECK(peer); | |
541 peer->AddObserver(&observer); | |
542 | |
543 // Peer should have no records on it. | |
544 EXPECT_TRUE(peer->GetNdefMessage().records().empty()); | |
545 EXPECT_EQ(0, observer.peer_records_received_count_); | |
546 | |
547 // Make records visible. | |
548 fake_nfc_record_client_->SetDeviceRecordsVisible(true); | |
549 EXPECT_EQ(3, observer.peer_records_received_count_); | |
550 EXPECT_EQ(static_cast<size_t>(3), peer->GetNdefMessage().records().size()); | |
551 | |
552 // End the simulation. Peer should get removed. | |
553 fake_nfc_device_client_->EndPairingSimulation(); | |
554 EXPECT_EQ(0, observer.peer_count_); | |
555 EXPECT_TRUE(observer.peer_identifier_.empty()); | |
556 | |
557 peer = adapter_->GetPeer(observer.peer_identifier_); | |
558 EXPECT_FALSE(peer); | |
559 | |
560 // No record related notifications will be sent when a peer gets removed. | |
561 EXPECT_EQ(3, observer.peer_records_received_count_); | |
562 } | |
563 | |
564 // Tests a simple tag pairing simulation. | |
565 TEST_F(NfcChromeOSTest, TagTest) { | |
566 const char kTestURI[] = "fake://path/for/testing"; | |
567 | |
568 SetAdapter(); | |
569 TestObserver observer(adapter_); | |
570 adapter_->AddObserver(&observer); | |
571 | |
572 adapter_->SetPowered( | |
573 true, | |
574 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
575 base::Unretained(this)), | |
576 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
577 base::Unretained(this))); | |
578 adapter_->StartPolling( | |
579 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
580 base::Unretained(this)), | |
581 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
582 base::Unretained(this))); | |
583 EXPECT_EQ(2, success_callback_count_); | |
584 | |
585 EXPECT_TRUE(adapter_->IsPowered()); | |
586 EXPECT_TRUE(adapter_->IsPolling()); | |
587 EXPECT_EQ(0, observer.tag_count_); | |
588 | |
589 // Add the fake tag. | |
590 fake_nfc_tag_client_->BeginPairingSimulation(0); | |
591 base::RunLoop().RunUntilIdle(); | |
592 | |
593 EXPECT_EQ(1, observer.tag_count_); | |
594 EXPECT_EQ(FakeNfcTagClient::kTagPath, observer.tag_identifier_); | |
595 | |
596 NfcTag* tag = adapter_->GetTag(observer.tag_identifier_); | |
597 CHECK(tag); | |
598 tag->AddObserver(&observer); | |
599 EXPECT_TRUE(tag->IsReady()); | |
600 CHECK(tag->GetNdefTagTechnology()); | |
601 tag->GetNdefTagTechnology()->AddObserver(&observer); | |
602 | |
603 NfcNdefTagTechnology* tag_technology = tag->GetNdefTagTechnology(); | |
604 EXPECT_TRUE(tag_technology->IsSupportedByTag()); | |
605 | |
606 // Tag should have no records on it. | |
607 EXPECT_TRUE(tag_technology->GetNdefMessage().records().empty()); | |
608 EXPECT_EQ(0, observer.tag_records_received_count_); | |
609 | |
610 // Set the tag record visible. By default the record has no content, so no | |
611 // NfcNdefMessage should be received. | |
612 fake_nfc_record_client_->SetTagRecordsVisible(true); | |
613 EXPECT_TRUE(tag_technology->GetNdefMessage().records().empty()); | |
614 EXPECT_EQ(0, observer.tag_records_received_count_); | |
615 fake_nfc_record_client_->SetTagRecordsVisible(false); | |
616 | |
617 // Write an NDEF record to the tag. | |
618 EXPECT_EQ(2, success_callback_count_); // 2 for SetPowered and StartPolling. | |
619 EXPECT_EQ(0, error_callback_count_); | |
620 | |
621 base::DictionaryValue record_data; | |
622 record_data.SetString(NfcNdefRecord::kFieldURI, kTestURI); | |
623 NfcNdefRecord written_record; | |
624 written_record.Populate(NfcNdefRecord::kTypeURI, &record_data); | |
625 NfcNdefMessage written_message; | |
626 written_message.AddRecord(&written_record); | |
627 | |
628 tag_technology->WriteNdef( | |
629 written_message, | |
630 base::Bind(&NfcChromeOSTest::SuccessCallback, | |
631 base::Unretained(this)), | |
632 base::Bind(&NfcChromeOSTest::ErrorCallback, | |
633 base::Unretained(this))); | |
634 EXPECT_EQ(3, success_callback_count_); | |
635 EXPECT_EQ(0, error_callback_count_); | |
636 | |
637 EXPECT_EQ(static_cast<size_t>(1), | |
638 tag_technology->GetNdefMessage().records().size()); | |
639 EXPECT_EQ(1, observer.tag_records_received_count_); | |
640 | |
641 NfcNdefRecord* received_record = | |
642 tag_technology->GetNdefMessage().records()[0]; | |
643 EXPECT_EQ(NfcNdefRecord::kTypeURI, received_record->type()); | |
644 std::string uri; | |
645 EXPECT_TRUE(received_record->data().GetString( | |
646 NfcNdefRecord::kFieldURI, &uri)); | |
647 EXPECT_EQ(kTestURI, uri); | |
648 | |
649 // End the simulation. Tag should get removed. | |
650 fake_nfc_tag_client_->EndPairingSimulation(); | |
651 EXPECT_EQ(0, observer.tag_count_); | |
652 EXPECT_TRUE(observer.tag_identifier_.empty()); | |
653 | |
654 tag = adapter_->GetTag(observer.tag_identifier_); | |
655 EXPECT_FALSE(tag); | |
656 | |
657 // No record related notifications will be sent when a tag gets removed. | |
658 EXPECT_EQ(1, observer.tag_records_received_count_); | |
659 } | |
660 | |
661 // Unit tests for nfc_ndef_record_utils methods. | |
662 TEST_F(NfcChromeOSTest, NfcNdefRecordToDBusAttributes) { | |
663 const char kText[] = "text"; | |
664 const char kURI[] = "test://uri"; | |
665 const char kEncoding[] = "encoding"; | |
666 const char kLanguageCode[] = "en"; | |
667 const char kMimeType[] = "mime-type"; | |
668 const double kSize = 5; | |
669 | |
670 // Text record. | |
671 base::DictionaryValue data; | |
672 data.SetString(NfcNdefRecord::kFieldText, kText); | |
673 data.SetString(NfcNdefRecord::kFieldLanguageCode, kLanguageCode); | |
674 data.SetString(NfcNdefRecord::kFieldEncoding, kEncoding); | |
675 | |
676 std::unique_ptr<NfcNdefRecord> record(new NfcNdefRecord()); | |
677 ASSERT_TRUE(record->Populate(NfcNdefRecord::kTypeText, &data)); | |
678 | |
679 base::DictionaryValue result; | |
680 EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes( | |
681 record.get(), &result)); | |
682 | |
683 std::string string_value; | |
684 EXPECT_TRUE(result.GetString( | |
685 nfc_record::kTypeProperty, &string_value)); | |
686 EXPECT_EQ(nfc_record::kTypeText, string_value); | |
687 EXPECT_TRUE(result.GetString( | |
688 nfc_record::kRepresentationProperty, &string_value)); | |
689 EXPECT_EQ(kText, string_value); | |
690 EXPECT_TRUE(result.GetString( | |
691 nfc_record::kLanguageProperty, &string_value)); | |
692 EXPECT_EQ(kLanguageCode, string_value); | |
693 EXPECT_TRUE(result.GetString( | |
694 nfc_record::kEncodingProperty, &string_value)); | |
695 EXPECT_EQ(kEncoding, string_value); | |
696 | |
697 // URI record. | |
698 data.Clear(); | |
699 data.SetString(NfcNdefRecord::kFieldURI, kURI); | |
700 data.SetString(NfcNdefRecord::kFieldMimeType, kMimeType); | |
701 data.SetDouble(NfcNdefRecord::kFieldTargetSize, kSize); | |
702 | |
703 record.reset(new NfcNdefRecord()); | |
704 ASSERT_TRUE(record->Populate(NfcNdefRecord::kTypeURI, &data)); | |
705 | |
706 result.Clear(); | |
707 EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes( | |
708 record.get(), &result)); | |
709 | |
710 EXPECT_TRUE(result.GetString(nfc_record::kTypeProperty, &string_value)); | |
711 EXPECT_EQ(nfc_record::kTypeUri, string_value); | |
712 EXPECT_TRUE(result.GetString(nfc_record::kUriProperty, &string_value)); | |
713 EXPECT_EQ(kURI, string_value); | |
714 EXPECT_TRUE(result.GetString(nfc_record::kMimeTypeProperty, &string_value)); | |
715 EXPECT_EQ(kMimeType, string_value); | |
716 double double_value; | |
717 EXPECT_TRUE(result.GetDouble(nfc_record::kSizeProperty, &double_value)); | |
718 EXPECT_EQ(kSize, double_value); | |
719 | |
720 // SmartPoster record. | |
721 base::DictionaryValue* title = new base::DictionaryValue(); | |
722 title->SetString(NfcNdefRecord::kFieldText, kText); | |
723 title->SetString(NfcNdefRecord::kFieldLanguageCode, kLanguageCode); | |
724 title->SetString(NfcNdefRecord::kFieldEncoding, kEncoding); | |
725 | |
726 base::ListValue* titles = new base::ListValue(); | |
727 titles->Append(title); | |
728 data.Set(NfcNdefRecord::kFieldTitles, titles); | |
729 | |
730 record.reset(new NfcNdefRecord()); | |
731 ASSERT_TRUE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data)); | |
732 | |
733 result.Clear(); | |
734 EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes( | |
735 record.get(), &result)); | |
736 | |
737 EXPECT_TRUE(result.GetString( | |
738 nfc_record::kTypeProperty, &string_value)); | |
739 EXPECT_EQ(nfc_record::kTypeSmartPoster, string_value); | |
740 EXPECT_TRUE(result.GetString( | |
741 nfc_record::kRepresentationProperty, &string_value)); | |
742 EXPECT_EQ(kText, string_value); | |
743 EXPECT_TRUE(result.GetString( | |
744 nfc_record::kLanguageProperty, &string_value)); | |
745 EXPECT_EQ(kLanguageCode, string_value); | |
746 EXPECT_TRUE(result.GetString( | |
747 nfc_record::kEncodingProperty, &string_value)); | |
748 EXPECT_EQ(kEncoding, string_value); | |
749 EXPECT_TRUE(result.GetString(nfc_record::kUriProperty, &string_value)); | |
750 EXPECT_EQ(kURI, string_value); | |
751 EXPECT_TRUE(result.GetString(nfc_record::kMimeTypeProperty, &string_value)); | |
752 EXPECT_EQ(kMimeType, string_value); | |
753 EXPECT_TRUE(result.GetDouble(nfc_record::kSizeProperty, &double_value)); | |
754 EXPECT_EQ(kSize, double_value); | |
755 } | |
756 | |
757 TEST_F(NfcChromeOSTest, RecordPropertiesToNfcNdefRecord) { | |
758 const char kText[] = "text"; | |
759 const char kURI[] = "test://uri"; | |
760 const char kEncoding[] = "encoding"; | |
761 const char kLanguageCode[] = "en"; | |
762 const char kMimeType[] = "mime-type"; | |
763 const uint32_t kSize = 5; | |
764 | |
765 FakeNfcRecordClient::Properties record_properties( | |
766 base::Bind(&OnPropertyChangedCallback)); | |
767 | |
768 // Text record. | |
769 record_properties.type.ReplaceValue(nfc_record::kTypeText); | |
770 record_properties.representation.ReplaceValue(kText); | |
771 record_properties.language.ReplaceValue(kLanguageCode); | |
772 record_properties.encoding.ReplaceValue(kEncoding); | |
773 | |
774 std::unique_ptr<NfcNdefRecord> record(new NfcNdefRecord()); | |
775 EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord( | |
776 &record_properties, record.get())); | |
777 EXPECT_TRUE(record->IsPopulated()); | |
778 | |
779 std::string string_value; | |
780 EXPECT_EQ(NfcNdefRecord::kTypeText, record->type()); | |
781 EXPECT_TRUE(record->data().GetString( | |
782 NfcNdefRecord::kFieldText, &string_value)); | |
783 EXPECT_EQ(kText, string_value); | |
784 EXPECT_TRUE(record->data().GetString( | |
785 NfcNdefRecord::kFieldLanguageCode, &string_value)); | |
786 EXPECT_EQ(kLanguageCode, string_value); | |
787 EXPECT_TRUE(record->data().GetString( | |
788 NfcNdefRecord::kFieldEncoding, &string_value)); | |
789 EXPECT_EQ(kEncoding, string_value); | |
790 | |
791 // URI record. | |
792 record_properties.representation.ReplaceValue(""); | |
793 record_properties.language.ReplaceValue(""); | |
794 record_properties.encoding.ReplaceValue(""); | |
795 | |
796 record_properties.type.ReplaceValue(nfc_record::kTypeUri); | |
797 record_properties.uri.ReplaceValue(kURI); | |
798 record_properties.mime_type.ReplaceValue(kMimeType); | |
799 record_properties.size.ReplaceValue(kSize); | |
800 | |
801 record.reset(new NfcNdefRecord()); | |
802 EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord( | |
803 &record_properties, record.get())); | |
804 EXPECT_TRUE(record->IsPopulated()); | |
805 | |
806 EXPECT_EQ(NfcNdefRecord::kTypeURI, record->type()); | |
807 EXPECT_TRUE(record->data().GetString( | |
808 NfcNdefRecord::kFieldURI, &string_value)); | |
809 EXPECT_EQ(kURI, string_value); | |
810 EXPECT_TRUE(record->data().GetString( | |
811 NfcNdefRecord::kFieldMimeType, &string_value)); | |
812 EXPECT_EQ(kMimeType, string_value); | |
813 double double_value; | |
814 EXPECT_TRUE(record->data().GetDouble( | |
815 NfcNdefRecord::kFieldTargetSize, &double_value)); | |
816 EXPECT_EQ(kSize, double_value); | |
817 | |
818 // Contents not matching type. | |
819 record_properties.representation.ReplaceValue(kText); | |
820 record_properties.language.ReplaceValue(kLanguageCode); | |
821 record_properties.encoding.ReplaceValue(kEncoding); | |
822 | |
823 record.reset(new NfcNdefRecord()); | |
824 EXPECT_FALSE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord( | |
825 &record_properties, record.get())); | |
826 EXPECT_FALSE(record->IsPopulated()); | |
827 | |
828 // SmartPoster record. | |
829 record_properties.type.ReplaceValue(nfc_record::kTypeSmartPoster); | |
830 EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord( | |
831 &record_properties, record.get())); | |
832 EXPECT_TRUE(record->IsPopulated()); | |
833 | |
834 EXPECT_EQ(NfcNdefRecord::kTypeSmartPoster, record->type()); | |
835 EXPECT_TRUE(record->data().GetString( | |
836 NfcNdefRecord::kFieldURI, &string_value)); | |
837 EXPECT_EQ(kURI, string_value); | |
838 EXPECT_TRUE(record->data().GetString( | |
839 NfcNdefRecord::kFieldMimeType, &string_value)); | |
840 EXPECT_EQ(kMimeType, string_value); | |
841 EXPECT_TRUE(record->data().GetDouble( | |
842 NfcNdefRecord::kFieldTargetSize, &double_value)); | |
843 EXPECT_EQ(kSize, double_value); | |
844 | |
845 const base::ListValue* titles = NULL; | |
846 EXPECT_TRUE(record->data().GetList(NfcNdefRecord::kFieldTitles, &titles)); | |
847 EXPECT_EQ(static_cast<size_t>(1), titles->GetSize()); | |
848 ASSERT_TRUE(titles); | |
849 const base::DictionaryValue* title = NULL; | |
850 EXPECT_TRUE(titles->GetDictionary(0, &title)); | |
851 CHECK(title); | |
852 | |
853 EXPECT_TRUE(title->GetString(NfcNdefRecord::kFieldText, &string_value)); | |
854 EXPECT_EQ(kText, string_value); | |
855 EXPECT_TRUE(title->GetString( | |
856 NfcNdefRecord::kFieldLanguageCode, &string_value)); | |
857 EXPECT_EQ(kLanguageCode, string_value); | |
858 EXPECT_TRUE(title->GetString(NfcNdefRecord::kFieldEncoding, &string_value)); | |
859 EXPECT_EQ(kEncoding, string_value); | |
860 } | |
861 | |
862 } // namespace chromeos | |
OLD | NEW |