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 ~TestObserver() override
{}
61 // NfcAdapter::Observer override.
62 void AdapterPresentChanged(NfcAdapter
* adapter
, bool present
) override
{
63 EXPECT_EQ(adapter_
.get(), adapter
);
64 present_changed_count_
++;
67 // NfcAdapter::Observer override.
68 void AdapterPoweredChanged(NfcAdapter
* adapter
, bool powered
) override
{
69 EXPECT_EQ(adapter_
.get(), adapter
);
70 powered_changed_count_
++;
73 // NfcAdapter::Observer override.
74 void AdapterPollingChanged(NfcAdapter
* adapter
, bool powered
) override
{
75 EXPECT_EQ(adapter_
.get(), adapter
);
76 polling_changed_count_
++;
79 // NfcAdapter::Observer override.
80 void PeerFound(NfcAdapter
* adapter
, NfcPeer
* peer
) override
{
81 EXPECT_EQ(adapter_
.get(), adapter
);
83 peer_identifier_
= peer
->GetIdentifier();
86 // NfcAdapter::Observer override.
87 void PeerLost(NfcAdapter
* adapter
, NfcPeer
* peer
) override
{
88 EXPECT_EQ(adapter_
.get(), adapter
);
89 EXPECT_EQ(peer_identifier_
, peer
->GetIdentifier());
91 peer_identifier_
.clear();
94 // NfcAdapter::Observer override.
95 void TagFound(NfcAdapter
* adapter
, NfcTag
* tag
) override
{
96 EXPECT_EQ(adapter_
.get(), adapter
);
98 tag_identifier_
= tag
->GetIdentifier();
101 // NfcAdapter::Observer override.
102 void TagLost(NfcAdapter
* adapter
, NfcTag
* tag
) override
{
103 EXPECT_EQ(adapter_
.get(), adapter
);
104 EXPECT_EQ(tag_identifier_
, tag
->GetIdentifier());
106 tag_identifier_
.clear();
109 // NfcPeer::Observer override.
110 void RecordReceived(NfcPeer
* peer
, const NfcNdefRecord
* record
) override
{
111 EXPECT_EQ(peer
, adapter_
->GetPeer(peer_identifier_
));
112 EXPECT_EQ(peer_identifier_
, peer
->GetIdentifier());
113 peer_records_received_count_
++;
116 // NfcNdefTagTechnology::Observer override.
117 void RecordReceived(NfcTag
* tag
, const NfcNdefRecord
* record
) override
{
118 EXPECT_EQ(tag
, adapter_
->GetTag(tag_identifier_
));
119 EXPECT_EQ(tag_identifier_
, tag
->GetIdentifier());
120 tag_records_received_count_
++;
123 int present_changed_count_
;
124 int powered_changed_count_
;
125 int polling_changed_count_
;
126 int peer_records_received_count_
;
127 int tag_records_received_count_
;
130 std::string peer_identifier_
;
131 std::string tag_identifier_
;
132 scoped_refptr
<NfcAdapter
> adapter_
;
137 class NfcChromeOSTest
: public testing::Test
{
139 void SetUp() override
{
140 DBusThreadManager::Initialize();
141 fake_nfc_adapter_client_
= static_cast<FakeNfcAdapterClient
*>(
142 DBusThreadManager::Get()->GetNfcAdapterClient());
143 fake_nfc_device_client_
= static_cast<FakeNfcDeviceClient
*>(
144 DBusThreadManager::Get()->GetNfcDeviceClient());
145 fake_nfc_record_client_
= static_cast<FakeNfcRecordClient
*>(
146 DBusThreadManager::Get()->GetNfcRecordClient());
147 fake_nfc_tag_client_
= static_cast<FakeNfcTagClient
*>(
148 DBusThreadManager::Get()->GetNfcTagClient());
150 fake_nfc_adapter_client_
->EnablePairingOnPoll(false);
151 fake_nfc_device_client_
->DisableSimulationTimeout();
152 fake_nfc_tag_client_
->DisableSimulationTimeout();
153 success_callback_count_
= 0;
154 error_callback_count_
= 0;
157 void TearDown() override
{
159 DBusThreadManager::Shutdown();
162 // Assigns a new instance of NfcAdapterChromeOS to |adapter_|.
164 adapter_
= new NfcAdapterChromeOS();
165 ASSERT_TRUE(adapter_
.get() != NULL
);
166 ASSERT_TRUE(adapter_
->IsInitialized());
167 base::RunLoop().RunUntilIdle();
170 // Generic callbacks for success and error.
171 void SuccessCallback() {
172 success_callback_count_
++;
175 void ErrorCallback() {
176 error_callback_count_
++;
179 void ErrorCallbackWithParameters(const std::string
& error_name
,
180 const std::string
& error_message
) {
181 LOG(INFO
) << "Error callback called: " << error_name
<< ", "
183 error_callback_count_
++;
187 // MessageLoop instance, used to simulate asynchronous behavior.
188 base::MessageLoop message_loop_
;
190 // Fields for storing the number of times SuccessCallback and ErrorCallback
192 int success_callback_count_
;
193 int error_callback_count_
;
195 // The NfcAdapter instance under test.
196 scoped_refptr
<NfcAdapter
> adapter_
;
198 // The fake D-Bus client instances used for testing.
199 FakeNfcAdapterClient
* fake_nfc_adapter_client_
;
200 FakeNfcDeviceClient
* fake_nfc_device_client_
;
201 FakeNfcRecordClient
* fake_nfc_record_client_
;
202 FakeNfcTagClient
* fake_nfc_tag_client_
;
205 // Tests that the adapter updates correctly to reflect the current "default"
206 // adapter, when multiple adapters appear and disappear.
207 TEST_F(NfcChromeOSTest
, PresentChanged
) {
209 EXPECT_TRUE(adapter_
->IsPresent());
211 TestObserver
observer(adapter_
);
212 adapter_
->AddObserver(&observer
);
214 // Remove all adapters.
215 fake_nfc_adapter_client_
->SetAdapterPresent(false);
216 EXPECT_EQ(1, observer
.present_changed_count_
);
217 EXPECT_FALSE(adapter_
->IsPresent());
220 fake_nfc_adapter_client_
->SetAdapterPresent(true);
221 fake_nfc_adapter_client_
->SetSecondAdapterPresent(true);
222 EXPECT_EQ(2, observer
.present_changed_count_
);
223 EXPECT_TRUE(adapter_
->IsPresent());
225 // Remove the first adapter. Adapter should update to the second one.
226 fake_nfc_adapter_client_
->SetAdapterPresent(false);
227 EXPECT_EQ(4, observer
.present_changed_count_
);
228 EXPECT_TRUE(adapter_
->IsPresent());
230 fake_nfc_adapter_client_
->SetSecondAdapterPresent(false);
231 EXPECT_EQ(5, observer
.present_changed_count_
);
232 EXPECT_FALSE(adapter_
->IsPresent());
235 // Tests that the adapter correctly reflects the power state.
236 TEST_F(NfcChromeOSTest
, SetPowered
) {
238 TestObserver
observer(adapter_
);
239 adapter_
->AddObserver(&observer
);
241 EXPECT_FALSE(adapter_
->IsPowered());
243 // SetPowered(false), while not powered.
244 adapter_
->SetPowered(
246 base::Bind(&NfcChromeOSTest::SuccessCallback
,
247 base::Unretained(this)),
248 base::Bind(&NfcChromeOSTest::ErrorCallback
,
249 base::Unretained(this)));
250 EXPECT_FALSE(adapter_
->IsPowered());
251 EXPECT_EQ(0, observer
.powered_changed_count_
);
252 EXPECT_EQ(0, success_callback_count_
);
253 EXPECT_EQ(1, error_callback_count_
);
256 adapter_
->SetPowered(
258 base::Bind(&NfcChromeOSTest::SuccessCallback
,
259 base::Unretained(this)),
260 base::Bind(&NfcChromeOSTest::ErrorCallback
,
261 base::Unretained(this)));
262 EXPECT_TRUE(adapter_
->IsPowered());
263 EXPECT_EQ(1, observer
.powered_changed_count_
);
264 EXPECT_EQ(1, success_callback_count_
);
265 EXPECT_EQ(1, error_callback_count_
);
267 // SetPowered(true), while powered.
268 adapter_
->SetPowered(
270 base::Bind(&NfcChromeOSTest::SuccessCallback
,
271 base::Unretained(this)),
272 base::Bind(&NfcChromeOSTest::ErrorCallback
,
273 base::Unretained(this)));
274 EXPECT_TRUE(adapter_
->IsPowered());
275 EXPECT_EQ(1, observer
.powered_changed_count_
);
276 EXPECT_EQ(1, success_callback_count_
);
277 EXPECT_EQ(2, error_callback_count_
);
279 // SetPowered(false).
280 adapter_
->SetPowered(
282 base::Bind(&NfcChromeOSTest::SuccessCallback
,
283 base::Unretained(this)),
284 base::Bind(&NfcChromeOSTest::ErrorCallback
,
285 base::Unretained(this)));
286 EXPECT_FALSE(adapter_
->IsPowered());
287 EXPECT_EQ(2, observer
.powered_changed_count_
);
288 EXPECT_EQ(2, success_callback_count_
);
289 EXPECT_EQ(2, error_callback_count_
);
292 // Tests that the power state updates correctly when the adapter disappears.
293 TEST_F(NfcChromeOSTest
, PresentChangedWhilePowered
) {
295 TestObserver
observer(adapter_
);
296 adapter_
->AddObserver(&observer
);
298 EXPECT_FALSE(adapter_
->IsPowered());
299 EXPECT_TRUE(adapter_
->IsPresent());
301 adapter_
->SetPowered(
303 base::Bind(&NfcChromeOSTest::SuccessCallback
,
304 base::Unretained(this)),
305 base::Bind(&NfcChromeOSTest::ErrorCallback
,
306 base::Unretained(this)));
307 EXPECT_TRUE(adapter_
->IsPowered());
309 fake_nfc_adapter_client_
->SetAdapterPresent(false);
310 EXPECT_EQ(1, observer
.present_changed_count_
);
311 EXPECT_EQ(2, observer
.powered_changed_count_
);
312 EXPECT_FALSE(adapter_
->IsPowered());
313 EXPECT_FALSE(adapter_
->IsPresent());
316 // Tests that peer and record objects are created for all peers and records
317 // that already exist when the adapter is created.
318 TEST_F(NfcChromeOSTest
, PeersInitializedWhenAdapterCreated
) {
319 // Set up the adapter client.
320 NfcAdapterClient::Properties
* properties
=
321 fake_nfc_adapter_client_
->GetProperties(
322 dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0
));
323 properties
->powered
.Set(true, base::Bind(&OnSet
));
325 fake_nfc_adapter_client_
->StartPollLoop(
326 dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0
),
327 nfc_adapter::kModeInitiator
,
328 base::Bind(&NfcChromeOSTest::SuccessCallback
,
329 base::Unretained(this)),
330 base::Bind(&NfcChromeOSTest::ErrorCallbackWithParameters
,
331 base::Unretained(this)));
332 EXPECT_EQ(1, success_callback_count_
);
333 EXPECT_TRUE(properties
->powered
.value());
334 EXPECT_TRUE(properties
->polling
.value());
336 // Start pairing simulation, which will add a fake device and fake records.
337 fake_nfc_device_client_
->BeginPairingSimulation(0, 0);
338 base::RunLoop().RunUntilIdle();
340 // Create the adapter.
342 TestObserver
observer(adapter_
);
343 adapter_
->AddObserver(&observer
);
345 // Observer shouldn't have received any calls, as it got created AFTER the
346 // notifications were sent.
347 EXPECT_EQ(0, observer
.present_changed_count_
);
348 EXPECT_EQ(0, observer
.powered_changed_count_
);
349 EXPECT_EQ(0, observer
.polling_changed_count_
);
350 EXPECT_EQ(0, observer
.peer_count_
);
352 EXPECT_TRUE(adapter_
->IsPresent());
353 EXPECT_TRUE(adapter_
->IsPowered());
354 EXPECT_FALSE(adapter_
->IsPolling());
356 NfcAdapter::PeerList peers
;
357 adapter_
->GetPeers(&peers
);
358 EXPECT_EQ(static_cast<size_t>(1), peers
.size());
360 NfcPeer
* peer
= peers
[0];
361 const NfcNdefMessage
& message
= peer
->GetNdefMessage();
362 EXPECT_EQ(static_cast<size_t>(3), message
.records().size());
365 // Tests that tag and record objects are created for all tags and records that
366 // already exist when the adapter is created.
367 TEST_F(NfcChromeOSTest
, TagsInitializedWhenAdapterCreated
) {
368 const char kTestURI
[] = "fake://path/for/testing";
370 // Set up the adapter client.
371 NfcAdapterClient::Properties
* properties
=
372 fake_nfc_adapter_client_
->GetProperties(
373 dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0
));
374 properties
->powered
.Set(true, base::Bind(&OnSet
));
376 fake_nfc_adapter_client_
->StartPollLoop(
377 dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0
),
378 nfc_adapter::kModeInitiator
,
379 base::Bind(&NfcChromeOSTest::SuccessCallback
,
380 base::Unretained(this)),
381 base::Bind(&NfcChromeOSTest::ErrorCallbackWithParameters
,
382 base::Unretained(this)));
383 EXPECT_EQ(1, success_callback_count_
);
384 EXPECT_TRUE(properties
->powered
.value());
385 EXPECT_TRUE(properties
->polling
.value());
388 fake_nfc_tag_client_
->BeginPairingSimulation(0);
389 base::RunLoop().RunUntilIdle();
391 // Create a fake record.
392 base::DictionaryValue test_record_data
;
393 test_record_data
.SetString(nfc_record::kTypeProperty
, nfc_record::kTypeUri
);
394 test_record_data
.SetString(nfc_record::kUriProperty
, kTestURI
);
395 fake_nfc_tag_client_
->Write(
396 dbus::ObjectPath(FakeNfcTagClient::kTagPath
),
398 base::Bind(&NfcChromeOSTest::SuccessCallback
,
399 base::Unretained(this)),
400 base::Bind(&NfcChromeOSTest::ErrorCallbackWithParameters
,
401 base::Unretained(this)));
402 EXPECT_EQ(2, success_callback_count_
);
404 // Create the adapter.
406 TestObserver
observer(adapter_
);
407 adapter_
->AddObserver(&observer
);
409 // Observer shouldn't have received any calls, as it got created AFTER the
410 // notifications were sent.
411 EXPECT_EQ(0, observer
.present_changed_count_
);
412 EXPECT_EQ(0, observer
.powered_changed_count_
);
413 EXPECT_EQ(0, observer
.polling_changed_count_
);
414 EXPECT_EQ(0, observer
.peer_count_
);
416 EXPECT_TRUE(adapter_
->IsPresent());
417 EXPECT_TRUE(adapter_
->IsPowered());
418 EXPECT_FALSE(adapter_
->IsPolling());
420 NfcAdapter::TagList tags
;
421 adapter_
->GetTags(&tags
);
422 EXPECT_EQ(static_cast<size_t>(1), tags
.size());
424 NfcTag
* tag
= tags
[0];
425 const NfcNdefMessage
& message
= tag
->GetNdefTagTechnology()->GetNdefMessage();
426 EXPECT_EQ(static_cast<size_t>(1), message
.records().size());
428 const NfcNdefRecord
* record
= message
.records()[0];
430 EXPECT_TRUE(record
->data().GetString(NfcNdefRecord::kFieldURI
, &uri
));
431 EXPECT_EQ(kTestURI
, uri
);
434 // Tests that the adapter correctly updates its state when polling is started
436 TEST_F(NfcChromeOSTest
, StartAndStopPolling
) {
438 EXPECT_TRUE(adapter_
->IsPresent());
440 TestObserver
observer(adapter_
);
441 adapter_
->AddObserver(&observer
);
443 // Start polling while not powered. Should fail.
444 EXPECT_FALSE(adapter_
->IsPowered());
445 adapter_
->StartPolling(
446 base::Bind(&NfcChromeOSTest::SuccessCallback
,
447 base::Unretained(this)),
448 base::Bind(&NfcChromeOSTest::ErrorCallback
,
449 base::Unretained(this)));
450 EXPECT_EQ(0, success_callback_count_
);
451 EXPECT_EQ(1, error_callback_count_
);
452 EXPECT_FALSE(adapter_
->IsPolling());
454 // Start polling while powered. Should succeed.
455 adapter_
->SetPowered(
457 base::Bind(&NfcChromeOSTest::SuccessCallback
,
458 base::Unretained(this)),
459 base::Bind(&NfcChromeOSTest::ErrorCallback
,
460 base::Unretained(this)));
461 EXPECT_EQ(1, success_callback_count_
);
462 EXPECT_EQ(1, error_callback_count_
);
463 EXPECT_TRUE(adapter_
->IsPowered());
465 adapter_
->StartPolling(
466 base::Bind(&NfcChromeOSTest::SuccessCallback
,
467 base::Unretained(this)),
468 base::Bind(&NfcChromeOSTest::ErrorCallback
,
469 base::Unretained(this)));
470 EXPECT_EQ(2, success_callback_count_
);
471 EXPECT_EQ(1, error_callback_count_
);
472 EXPECT_TRUE(adapter_
->IsPolling());
474 // Start polling while already polling. Should fail.
475 adapter_
->StartPolling(
476 base::Bind(&NfcChromeOSTest::SuccessCallback
,
477 base::Unretained(this)),
478 base::Bind(&NfcChromeOSTest::ErrorCallback
,
479 base::Unretained(this)));
480 EXPECT_EQ(2, success_callback_count_
);
481 EXPECT_EQ(2, error_callback_count_
);
482 EXPECT_TRUE(adapter_
->IsPolling());
484 // Stop polling. Should succeed.
485 adapter_
->StopPolling(
486 base::Bind(&NfcChromeOSTest::SuccessCallback
,
487 base::Unretained(this)),
488 base::Bind(&NfcChromeOSTest::ErrorCallback
,
489 base::Unretained(this)));
490 EXPECT_EQ(3, success_callback_count_
);
491 EXPECT_EQ(2, error_callback_count_
);
492 EXPECT_FALSE(adapter_
->IsPolling());
494 // Stop polling while not polling. Should fail.
495 adapter_
->StopPolling(
496 base::Bind(&NfcChromeOSTest::SuccessCallback
,
497 base::Unretained(this)),
498 base::Bind(&NfcChromeOSTest::ErrorCallback
,
499 base::Unretained(this)));
500 EXPECT_EQ(3, success_callback_count_
);
501 EXPECT_EQ(3, error_callback_count_
);
502 EXPECT_FALSE(adapter_
->IsPolling());
505 // Tests a simple peer pairing simulation.
506 TEST_F(NfcChromeOSTest
, PeerTest
) {
508 TestObserver
observer(adapter_
);
509 adapter_
->AddObserver(&observer
);
511 adapter_
->SetPowered(
513 base::Bind(&NfcChromeOSTest::SuccessCallback
,
514 base::Unretained(this)),
515 base::Bind(&NfcChromeOSTest::ErrorCallback
,
516 base::Unretained(this)));
517 adapter_
->StartPolling(
518 base::Bind(&NfcChromeOSTest::SuccessCallback
,
519 base::Unretained(this)),
520 base::Bind(&NfcChromeOSTest::ErrorCallback
,
521 base::Unretained(this)));
522 EXPECT_EQ(2, success_callback_count_
);
524 EXPECT_TRUE(adapter_
->IsPowered());
525 EXPECT_TRUE(adapter_
->IsPolling());
526 EXPECT_EQ(0, observer
.peer_count_
);
528 // Add the fake device.
529 fake_nfc_device_client_
->BeginPairingSimulation(0, -1);
530 base::RunLoop().RunUntilIdle();
532 EXPECT_EQ(1, observer
.peer_count_
);
533 EXPECT_EQ(FakeNfcDeviceClient::kDevicePath
, observer
.peer_identifier_
);
535 NfcPeer
* peer
= adapter_
->GetPeer(observer
.peer_identifier_
);
537 peer
->AddObserver(&observer
);
539 // Peer should have no records on it.
540 EXPECT_TRUE(peer
->GetNdefMessage().records().empty());
541 EXPECT_EQ(0, observer
.peer_records_received_count_
);
543 // Make records visible.
544 fake_nfc_record_client_
->SetDeviceRecordsVisible(true);
545 EXPECT_EQ(3, observer
.peer_records_received_count_
);
546 EXPECT_EQ(static_cast<size_t>(3), peer
->GetNdefMessage().records().size());
548 // End the simulation. Peer should get removed.
549 fake_nfc_device_client_
->EndPairingSimulation();
550 EXPECT_EQ(0, observer
.peer_count_
);
551 EXPECT_TRUE(observer
.peer_identifier_
.empty());
553 peer
= adapter_
->GetPeer(observer
.peer_identifier_
);
556 // No record related notifications will be sent when a peer gets removed.
557 EXPECT_EQ(3, observer
.peer_records_received_count_
);
560 // Tests a simple tag pairing simulation.
561 TEST_F(NfcChromeOSTest
, TagTest
) {
562 const char kTestURI
[] = "fake://path/for/testing";
565 TestObserver
observer(adapter_
);
566 adapter_
->AddObserver(&observer
);
568 adapter_
->SetPowered(
570 base::Bind(&NfcChromeOSTest::SuccessCallback
,
571 base::Unretained(this)),
572 base::Bind(&NfcChromeOSTest::ErrorCallback
,
573 base::Unretained(this)));
574 adapter_
->StartPolling(
575 base::Bind(&NfcChromeOSTest::SuccessCallback
,
576 base::Unretained(this)),
577 base::Bind(&NfcChromeOSTest::ErrorCallback
,
578 base::Unretained(this)));
579 EXPECT_EQ(2, success_callback_count_
);
581 EXPECT_TRUE(adapter_
->IsPowered());
582 EXPECT_TRUE(adapter_
->IsPolling());
583 EXPECT_EQ(0, observer
.tag_count_
);
586 fake_nfc_tag_client_
->BeginPairingSimulation(0);
587 base::RunLoop().RunUntilIdle();
589 EXPECT_EQ(1, observer
.tag_count_
);
590 EXPECT_EQ(FakeNfcTagClient::kTagPath
, observer
.tag_identifier_
);
592 NfcTag
* tag
= adapter_
->GetTag(observer
.tag_identifier_
);
594 tag
->AddObserver(&observer
);
595 EXPECT_TRUE(tag
->IsReady());
596 CHECK(tag
->GetNdefTagTechnology());
597 tag
->GetNdefTagTechnology()->AddObserver(&observer
);
599 NfcNdefTagTechnology
* tag_technology
= tag
->GetNdefTagTechnology();
600 EXPECT_TRUE(tag_technology
->IsSupportedByTag());
602 // Tag should have no records on it.
603 EXPECT_TRUE(tag_technology
->GetNdefMessage().records().empty());
604 EXPECT_EQ(0, observer
.tag_records_received_count_
);
606 // Set the tag record visible. By default the record has no content, so no
607 // NfcNdefMessage should be received.
608 fake_nfc_record_client_
->SetTagRecordsVisible(true);
609 EXPECT_TRUE(tag_technology
->GetNdefMessage().records().empty());
610 EXPECT_EQ(0, observer
.tag_records_received_count_
);
611 fake_nfc_record_client_
->SetTagRecordsVisible(false);
613 // Write an NDEF record to the tag.
614 EXPECT_EQ(2, success_callback_count_
); // 2 for SetPowered and StartPolling.
615 EXPECT_EQ(0, error_callback_count_
);
617 base::DictionaryValue record_data
;
618 record_data
.SetString(NfcNdefRecord::kFieldURI
, kTestURI
);
619 NfcNdefRecord written_record
;
620 written_record
.Populate(NfcNdefRecord::kTypeURI
, &record_data
);
621 NfcNdefMessage written_message
;
622 written_message
.AddRecord(&written_record
);
624 tag_technology
->WriteNdef(
626 base::Bind(&NfcChromeOSTest::SuccessCallback
,
627 base::Unretained(this)),
628 base::Bind(&NfcChromeOSTest::ErrorCallback
,
629 base::Unretained(this)));
630 EXPECT_EQ(3, success_callback_count_
);
631 EXPECT_EQ(0, error_callback_count_
);
633 EXPECT_EQ(static_cast<size_t>(1),
634 tag_technology
->GetNdefMessage().records().size());
635 EXPECT_EQ(1, observer
.tag_records_received_count_
);
637 NfcNdefRecord
* received_record
=
638 tag_technology
->GetNdefMessage().records()[0];
639 EXPECT_EQ(NfcNdefRecord::kTypeURI
, received_record
->type());
641 EXPECT_TRUE(received_record
->data().GetString(
642 NfcNdefRecord::kFieldURI
, &uri
));
643 EXPECT_EQ(kTestURI
, uri
);
645 // End the simulation. Tag should get removed.
646 fake_nfc_tag_client_
->EndPairingSimulation();
647 EXPECT_EQ(0, observer
.tag_count_
);
648 EXPECT_TRUE(observer
.tag_identifier_
.empty());
650 tag
= adapter_
->GetTag(observer
.tag_identifier_
);
653 // No record related notifications will be sent when a tag gets removed.
654 EXPECT_EQ(1, observer
.tag_records_received_count_
);
657 // Unit tests for nfc_ndef_record_utils methods.
658 TEST_F(NfcChromeOSTest
, NfcNdefRecordToDBusAttributes
) {
659 const char kText
[] = "text";
660 const char kURI
[] = "test://uri";
661 const char kEncoding
[] = "encoding";
662 const char kLanguageCode
[] = "en";
663 const char kMimeType
[] = "mime-type";
664 const double kSize
= 5;
667 base::DictionaryValue data
;
668 data
.SetString(NfcNdefRecord::kFieldText
, kText
);
669 data
.SetString(NfcNdefRecord::kFieldLanguageCode
, kLanguageCode
);
670 data
.SetString(NfcNdefRecord::kFieldEncoding
, kEncoding
);
672 scoped_ptr
<NfcNdefRecord
> record(new NfcNdefRecord());
673 ASSERT_TRUE(record
->Populate(NfcNdefRecord::kTypeText
, &data
));
675 base::DictionaryValue result
;
676 EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
677 record
.get(), &result
));
679 std::string string_value
;
680 EXPECT_TRUE(result
.GetString(
681 nfc_record::kTypeProperty
, &string_value
));
682 EXPECT_EQ(nfc_record::kTypeText
, string_value
);
683 EXPECT_TRUE(result
.GetString(
684 nfc_record::kRepresentationProperty
, &string_value
));
685 EXPECT_EQ(kText
, string_value
);
686 EXPECT_TRUE(result
.GetString(
687 nfc_record::kLanguageProperty
, &string_value
));
688 EXPECT_EQ(kLanguageCode
, string_value
);
689 EXPECT_TRUE(result
.GetString(
690 nfc_record::kEncodingProperty
, &string_value
));
691 EXPECT_EQ(kEncoding
, string_value
);
695 data
.SetString(NfcNdefRecord::kFieldURI
, kURI
);
696 data
.SetString(NfcNdefRecord::kFieldMimeType
, kMimeType
);
697 data
.SetDouble(NfcNdefRecord::kFieldTargetSize
, kSize
);
699 record
.reset(new NfcNdefRecord());
700 ASSERT_TRUE(record
->Populate(NfcNdefRecord::kTypeURI
, &data
));
703 EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
704 record
.get(), &result
));
706 EXPECT_TRUE(result
.GetString(nfc_record::kTypeProperty
, &string_value
));
707 EXPECT_EQ(nfc_record::kTypeUri
, string_value
);
708 EXPECT_TRUE(result
.GetString(nfc_record::kUriProperty
, &string_value
));
709 EXPECT_EQ(kURI
, string_value
);
710 EXPECT_TRUE(result
.GetString(nfc_record::kMimeTypeProperty
, &string_value
));
711 EXPECT_EQ(kMimeType
, string_value
);
713 EXPECT_TRUE(result
.GetDouble(nfc_record::kSizeProperty
, &double_value
));
714 EXPECT_EQ(kSize
, double_value
);
716 // SmartPoster record.
717 base::DictionaryValue
* title
= new base::DictionaryValue();
718 title
->SetString(NfcNdefRecord::kFieldText
, kText
);
719 title
->SetString(NfcNdefRecord::kFieldLanguageCode
, kLanguageCode
);
720 title
->SetString(NfcNdefRecord::kFieldEncoding
, kEncoding
);
722 base::ListValue
* titles
= new base::ListValue();
723 titles
->Append(title
);
724 data
.Set(NfcNdefRecord::kFieldTitles
, titles
);
726 record
.reset(new NfcNdefRecord());
727 ASSERT_TRUE(record
->Populate(NfcNdefRecord::kTypeSmartPoster
, &data
));
730 EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
731 record
.get(), &result
));
733 EXPECT_TRUE(result
.GetString(
734 nfc_record::kTypeProperty
, &string_value
));
735 EXPECT_EQ(nfc_record::kTypeSmartPoster
, string_value
);
736 EXPECT_TRUE(result
.GetString(
737 nfc_record::kRepresentationProperty
, &string_value
));
738 EXPECT_EQ(kText
, string_value
);
739 EXPECT_TRUE(result
.GetString(
740 nfc_record::kLanguageProperty
, &string_value
));
741 EXPECT_EQ(kLanguageCode
, string_value
);
742 EXPECT_TRUE(result
.GetString(
743 nfc_record::kEncodingProperty
, &string_value
));
744 EXPECT_EQ(kEncoding
, string_value
);
745 EXPECT_TRUE(result
.GetString(nfc_record::kUriProperty
, &string_value
));
746 EXPECT_EQ(kURI
, string_value
);
747 EXPECT_TRUE(result
.GetString(nfc_record::kMimeTypeProperty
, &string_value
));
748 EXPECT_EQ(kMimeType
, string_value
);
749 EXPECT_TRUE(result
.GetDouble(nfc_record::kSizeProperty
, &double_value
));
750 EXPECT_EQ(kSize
, double_value
);
753 TEST_F(NfcChromeOSTest
, RecordPropertiesToNfcNdefRecord
) {
754 const char kText
[] = "text";
755 const char kURI
[] = "test://uri";
756 const char kEncoding
[] = "encoding";
757 const char kLanguageCode
[] = "en";
758 const char kMimeType
[] = "mime-type";
759 const uint32 kSize
= 5;
761 FakeNfcRecordClient::Properties
record_properties(
762 base::Bind(&OnPropertyChangedCallback
));
765 record_properties
.type
.ReplaceValue(nfc_record::kTypeText
);
766 record_properties
.representation
.ReplaceValue(kText
);
767 record_properties
.language
.ReplaceValue(kLanguageCode
);
768 record_properties
.encoding
.ReplaceValue(kEncoding
);
770 scoped_ptr
<NfcNdefRecord
> record(new NfcNdefRecord());
771 EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
772 &record_properties
, record
.get()));
773 EXPECT_TRUE(record
->IsPopulated());
775 std::string string_value
;
776 EXPECT_EQ(NfcNdefRecord::kTypeText
, record
->type());
777 EXPECT_TRUE(record
->data().GetString(
778 NfcNdefRecord::kFieldText
, &string_value
));
779 EXPECT_EQ(kText
, string_value
);
780 EXPECT_TRUE(record
->data().GetString(
781 NfcNdefRecord::kFieldLanguageCode
, &string_value
));
782 EXPECT_EQ(kLanguageCode
, string_value
);
783 EXPECT_TRUE(record
->data().GetString(
784 NfcNdefRecord::kFieldEncoding
, &string_value
));
785 EXPECT_EQ(kEncoding
, string_value
);
788 record_properties
.representation
.ReplaceValue("");
789 record_properties
.language
.ReplaceValue("");
790 record_properties
.encoding
.ReplaceValue("");
792 record_properties
.type
.ReplaceValue(nfc_record::kTypeUri
);
793 record_properties
.uri
.ReplaceValue(kURI
);
794 record_properties
.mime_type
.ReplaceValue(kMimeType
);
795 record_properties
.size
.ReplaceValue(kSize
);
797 record
.reset(new NfcNdefRecord());
798 EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
799 &record_properties
, record
.get()));
800 EXPECT_TRUE(record
->IsPopulated());
802 EXPECT_EQ(NfcNdefRecord::kTypeURI
, record
->type());
803 EXPECT_TRUE(record
->data().GetString(
804 NfcNdefRecord::kFieldURI
, &string_value
));
805 EXPECT_EQ(kURI
, string_value
);
806 EXPECT_TRUE(record
->data().GetString(
807 NfcNdefRecord::kFieldMimeType
, &string_value
));
808 EXPECT_EQ(kMimeType
, string_value
);
810 EXPECT_TRUE(record
->data().GetDouble(
811 NfcNdefRecord::kFieldTargetSize
, &double_value
));
812 EXPECT_EQ(kSize
, double_value
);
814 // Contents not matching type.
815 record_properties
.representation
.ReplaceValue(kText
);
816 record_properties
.language
.ReplaceValue(kLanguageCode
);
817 record_properties
.encoding
.ReplaceValue(kEncoding
);
819 record
.reset(new NfcNdefRecord());
820 EXPECT_FALSE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
821 &record_properties
, record
.get()));
822 EXPECT_FALSE(record
->IsPopulated());
824 // SmartPoster record.
825 record_properties
.type
.ReplaceValue(nfc_record::kTypeSmartPoster
);
826 EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
827 &record_properties
, record
.get()));
828 EXPECT_TRUE(record
->IsPopulated());
830 EXPECT_EQ(NfcNdefRecord::kTypeSmartPoster
, record
->type());
831 EXPECT_TRUE(record
->data().GetString(
832 NfcNdefRecord::kFieldURI
, &string_value
));
833 EXPECT_EQ(kURI
, string_value
);
834 EXPECT_TRUE(record
->data().GetString(
835 NfcNdefRecord::kFieldMimeType
, &string_value
));
836 EXPECT_EQ(kMimeType
, string_value
);
837 EXPECT_TRUE(record
->data().GetDouble(
838 NfcNdefRecord::kFieldTargetSize
, &double_value
));
839 EXPECT_EQ(kSize
, double_value
);
841 const base::ListValue
* titles
= NULL
;
842 EXPECT_TRUE(record
->data().GetList(NfcNdefRecord::kFieldTitles
, &titles
));
843 EXPECT_EQ(static_cast<size_t>(1), titles
->GetSize());
845 const base::DictionaryValue
* title
= NULL
;
846 EXPECT_TRUE(titles
->GetDictionary(0, &title
));
849 EXPECT_TRUE(title
->GetString(NfcNdefRecord::kFieldText
, &string_value
));
850 EXPECT_EQ(kText
, string_value
);
851 EXPECT_TRUE(title
->GetString(
852 NfcNdefRecord::kFieldLanguageCode
, &string_value
));
853 EXPECT_EQ(kLanguageCode
, string_value
);
854 EXPECT_TRUE(title
->GetString(NfcNdefRecord::kFieldEncoding
, &string_value
));
855 EXPECT_EQ(kEncoding
, string_value
);
858 } // namespace chromeos