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