Home | History | Annotate | Download | only in nfc
      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 "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"
     23 
     24 using device::NfcAdapter;
     25 using device::NfcNdefMessage;
     26 using device::NfcNdefRecord;
     27 using device::NfcNdefTagTechnology;
     28 using device::NfcPeer;
     29 using device::NfcTag;
     30 
     31 namespace chromeos {
     32 
     33 namespace {
     34 
     35 // Callback passed to property structures.
     36 void OnPropertyChangedCallback(const std::string& property_name) {
     37 }
     38 
     39 // Callback passed to dbus::PropertyBase::Set.
     40 void OnSet(bool success) {
     41 }
     42 
     43 class TestObserver : public NfcAdapter::Observer,
     44                      public NfcPeer::Observer,
     45                      public NfcTag::Observer,
     46                      public NfcNdefTagTechnology::Observer {
     47  public:
     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),
     54         peer_count_(0),
     55         tag_count_(0),
     56         adapter_(adapter) {
     57   }
     58 
     59   virtual ~TestObserver() {}
     60 
     61   // NfcAdapter::Observer override.
     62   virtual void AdapterPresentChanged(NfcAdapter* adapter,
     63                                      bool present) OVERRIDE {
     64     EXPECT_EQ(adapter_, adapter);
     65     present_changed_count_++;
     66   }
     67 
     68   // NfcAdapter::Observer override.
     69   virtual void AdapterPoweredChanged(NfcAdapter* adapter,
     70                                      bool powered) OVERRIDE {
     71     EXPECT_EQ(adapter_, adapter);
     72     powered_changed_count_++;
     73   }
     74 
     75   // NfcAdapter::Observer override.
     76   virtual void AdapterPollingChanged(NfcAdapter* adapter,
     77                                      bool powered) OVERRIDE {
     78     EXPECT_EQ(adapter_, adapter);
     79     polling_changed_count_++;
     80   }
     81 
     82   // NfcAdapter::Observer override.
     83   virtual void PeerFound(NfcAdapter* adapter, NfcPeer* peer) OVERRIDE {
     84     EXPECT_EQ(adapter_, adapter);
     85     peer_count_++;
     86     peer_identifier_ = peer->GetIdentifier();
     87   }
     88 
     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());
     93     peer_count_--;
     94     peer_identifier_.clear();
     95   }
     96 
     97   // NfcAdapter::Observer override.
     98   virtual void TagFound(NfcAdapter* adapter, NfcTag* tag) OVERRIDE {
     99     EXPECT_EQ(adapter_, adapter);
    100     tag_count_++;
    101     tag_identifier_ = tag->GetIdentifier();
    102   }
    103 
    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());
    108     tag_count_--;
    109     tag_identifier_.clear();
    110   }
    111 
    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_++;
    118   }
    119 
    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_++;
    126   }
    127 
    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_;
    133   int peer_count_;
    134   int tag_count_;
    135   std::string peer_identifier_;
    136   std::string tag_identifier_;
    137   scoped_refptr<NfcAdapter> adapter_;
    138 };
    139 
    140 }  // namespace
    141 
    142 class NfcChromeOSTest : public testing::Test {
    143  public:
    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());
    154 
    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;
    160   }
    161 
    162   virtual void TearDown() {
    163     adapter_ = NULL;
    164     DBusThreadManager::Shutdown();
    165   }
    166 
    167   // Assigns a new instance of NfcAdapterChromeOS to |adapter_|.
    168   void SetAdapter() {
    169     adapter_ = new NfcAdapterChromeOS();
    170     ASSERT_TRUE(adapter_.get() != NULL);
    171     ASSERT_TRUE(adapter_->IsInitialized());
    172     base::RunLoop().RunUntilIdle();
    173   }
    174 
    175   // Generic callbacks for success and error.
    176   void SuccessCallback() {
    177     success_callback_count_++;
    178   }
    179 
    180   void ErrorCallback() {
    181     error_callback_count_++;
    182   }
    183 
    184   void ErrorCallbackWithParameters(const std::string& error_name,
    185                                    const std::string& error_message) {
    186     LOG(INFO) << "Error callback called: " << error_name << ", "
    187               << error_message;
    188     error_callback_count_++;
    189   }
    190 
    191  protected:
    192   // MessageLoop instance, used to simulate asynchronous behavior.
    193   base::MessageLoop message_loop_;
    194 
    195   // Fields for storing the number of times SuccessCallback and ErrorCallback
    196   // have been called.
    197   int success_callback_count_;
    198   int error_callback_count_;
    199 
    200   // The NfcAdapter instance under test.
    201   scoped_refptr<NfcAdapter> adapter_;
    202 
    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_;
    208 };
    209 
    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) {
    213   SetAdapter();
    214   EXPECT_TRUE(adapter_->IsPresent());
    215 
    216   TestObserver observer(adapter_);
    217   adapter_->AddObserver(&observer);
    218 
    219   // Remove all adapters.
    220   fake_nfc_adapter_client_->SetAdapterPresent(false);
    221   EXPECT_EQ(1, observer.present_changed_count_);
    222   EXPECT_FALSE(adapter_->IsPresent());
    223 
    224   // Add two adapters.
    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());
    229 
    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());
    234 
    235   fake_nfc_adapter_client_->SetSecondAdapterPresent(false);
    236   EXPECT_EQ(5, observer.present_changed_count_);
    237   EXPECT_FALSE(adapter_->IsPresent());
    238 }
    239 
    240 // Tests that the adapter correctly reflects the power state.
    241 TEST_F(NfcChromeOSTest, SetPowered) {
    242   SetAdapter();
    243   TestObserver observer(adapter_);
    244   adapter_->AddObserver(&observer);
    245 
    246   EXPECT_FALSE(adapter_->IsPowered());
    247 
    248   // SetPowered(false), while not powered.
    249   adapter_->SetPowered(
    250       false,
    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_);
    259 
    260   // SetPowered(true).
    261   adapter_->SetPowered(
    262       true,
    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_);
    271 
    272   // SetPowered(true), while powered.
    273   adapter_->SetPowered(
    274       true,
    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_);
    283 
    284   // SetPowered(false).
    285   adapter_->SetPowered(
    286       false,
    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_);
    295 }
    296 
    297 // Tests that the power state updates correctly when the adapter disappears.
    298 TEST_F(NfcChromeOSTest, PresentChangedWhilePowered) {
    299   SetAdapter();
    300   TestObserver observer(adapter_);
    301   adapter_->AddObserver(&observer);
    302 
    303   EXPECT_FALSE(adapter_->IsPowered());
    304   EXPECT_TRUE(adapter_->IsPresent());
    305 
    306   adapter_->SetPowered(
    307       true,
    308       base::Bind(&NfcChromeOSTest::SuccessCallback,
    309                  base::Unretained(this)),
    310       base::Bind(&NfcChromeOSTest::ErrorCallback,
    311                  base::Unretained(this)));
    312   EXPECT_TRUE(adapter_->IsPowered());
    313 
    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());
    319 }
    320 
    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));
    329 
    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());
    340 
    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();
    344 
    345   // Create the adapter.
    346   SetAdapter();
    347   TestObserver observer(adapter_);
    348   adapter_->AddObserver(&observer);
    349 
    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_);
    356 
    357   EXPECT_TRUE(adapter_->IsPresent());
    358   EXPECT_TRUE(adapter_->IsPowered());
    359   EXPECT_FALSE(adapter_->IsPolling());
    360 
    361   NfcAdapter::PeerList peers;
    362   adapter_->GetPeers(&peers);
    363   EXPECT_EQ(static_cast<size_t>(1), peers.size());
    364 
    365   NfcPeer* peer = peers[0];
    366   const NfcNdefMessage& message = peer->GetNdefMessage();
    367   EXPECT_EQ(static_cast<size_t>(3), message.records().size());
    368 }
    369 
    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";
    374 
    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));
    380 
    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());
    391 
    392   // Add the fake tag.
    393   fake_nfc_tag_client_->BeginPairingSimulation(0);
    394   base::RunLoop().RunUntilIdle();
    395 
    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),
    402       test_record_data,
    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_);
    408 
    409   // Create the adapter.
    410   SetAdapter();
    411   TestObserver observer(adapter_);
    412   adapter_->AddObserver(&observer);
    413 
    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_);
    420 
    421   EXPECT_TRUE(adapter_->IsPresent());
    422   EXPECT_TRUE(adapter_->IsPowered());
    423   EXPECT_FALSE(adapter_->IsPolling());
    424 
    425   NfcAdapter::TagList tags;
    426   adapter_->GetTags(&tags);
    427   EXPECT_EQ(static_cast<size_t>(1), tags.size());
    428 
    429   NfcTag* tag = tags[0];
    430   const NfcNdefMessage& message = tag->GetNdefTagTechnology()->GetNdefMessage();
    431   EXPECT_EQ(static_cast<size_t>(1), message.records().size());
    432 
    433   const NfcNdefRecord* record = message.records()[0];
    434   std::string uri;
    435   EXPECT_TRUE(record->data().GetString(NfcNdefRecord::kFieldURI, &uri));
    436   EXPECT_EQ(kTestURI, uri);
    437 }
    438 
    439 // Tests that the adapter correctly updates its state when polling is started
    440 // and stopped.
    441 TEST_F(NfcChromeOSTest, StartAndStopPolling) {
    442   SetAdapter();
    443   EXPECT_TRUE(adapter_->IsPresent());
    444 
    445   TestObserver observer(adapter_);
    446   adapter_->AddObserver(&observer);
    447 
    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());
    458 
    459   // Start polling while powered. Should succeed.
    460   adapter_->SetPowered(
    461       true,
    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());
    469 
    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());
    478 
    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());
    488 
    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());
    498 
    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());
    508 }
    509 
    510 // Tests a simple peer pairing simulation.
    511 TEST_F(NfcChromeOSTest, PeerTest) {
    512   SetAdapter();
    513   TestObserver observer(adapter_);
    514   adapter_->AddObserver(&observer);
    515 
    516   adapter_->SetPowered(
    517       true,
    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_);
    528 
    529   EXPECT_TRUE(adapter_->IsPowered());
    530   EXPECT_TRUE(adapter_->IsPolling());
    531   EXPECT_EQ(0, observer.peer_count_);
    532 
    533   // Add the fake device.
    534   fake_nfc_device_client_->BeginPairingSimulation(0, -1);
    535   base::RunLoop().RunUntilIdle();
    536 
    537   EXPECT_EQ(1, observer.peer_count_);
    538   EXPECT_EQ(FakeNfcDeviceClient::kDevicePath, observer.peer_identifier_);
    539 
    540   NfcPeer* peer = adapter_->GetPeer(observer.peer_identifier_);
    541   CHECK(peer);
    542   peer->AddObserver(&observer);
    543 
    544   // Peer should have no records on it.
    545   EXPECT_TRUE(peer->GetNdefMessage().records().empty());
    546   EXPECT_EQ(0, observer.peer_records_received_count_);
    547 
    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());
    552 
    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());
    557 
    558   peer = adapter_->GetPeer(observer.peer_identifier_);
    559   EXPECT_FALSE(peer);
    560 
    561   // No record related notifications will be sent when a peer gets removed.
    562   EXPECT_EQ(3, observer.peer_records_received_count_);
    563 }
    564 
    565 // Tests a simple tag pairing simulation.
    566 TEST_F(NfcChromeOSTest, TagTest) {
    567   const char kTestURI[] = "fake://path/for/testing";
    568 
    569   SetAdapter();
    570   TestObserver observer(adapter_);
    571   adapter_->AddObserver(&observer);
    572 
    573   adapter_->SetPowered(
    574       true,
    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_);
    585 
    586   EXPECT_TRUE(adapter_->IsPowered());
    587   EXPECT_TRUE(adapter_->IsPolling());
    588   EXPECT_EQ(0, observer.tag_count_);
    589 
    590   // Add the fake tag.
    591   fake_nfc_tag_client_->BeginPairingSimulation(0);
    592   base::RunLoop().RunUntilIdle();
    593 
    594   EXPECT_EQ(1, observer.tag_count_);
    595   EXPECT_EQ(FakeNfcTagClient::kTagPath, observer.tag_identifier_);
    596 
    597   NfcTag* tag = adapter_->GetTag(observer.tag_identifier_);
    598   CHECK(tag);
    599   tag->AddObserver(&observer);
    600   EXPECT_TRUE(tag->IsReady());
    601   CHECK(tag->GetNdefTagTechnology());
    602   tag->GetNdefTagTechnology()->AddObserver(&observer);
    603 
    604   NfcNdefTagTechnology* tag_technology = tag->GetNdefTagTechnology();
    605   EXPECT_TRUE(tag_technology->IsSupportedByTag());
    606 
    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_);
    610 
    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);
    617 
    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_);
    621 
    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);
    628 
    629   tag_technology->WriteNdef(
    630       written_message,
    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_);
    637 
    638   EXPECT_EQ(static_cast<size_t>(1),
    639             tag_technology->GetNdefMessage().records().size());
    640   EXPECT_EQ(1, observer.tag_records_received_count_);
    641 
    642   NfcNdefRecord* received_record =
    643       tag_technology->GetNdefMessage().records()[0];
    644   EXPECT_EQ(NfcNdefRecord::kTypeURI, received_record->type());
    645   std::string uri;
    646   EXPECT_TRUE(received_record->data().GetString(
    647       NfcNdefRecord::kFieldURI, &uri));
    648   EXPECT_EQ(kTestURI, uri);
    649 
    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());
    654 
    655   tag = adapter_->GetTag(observer.tag_identifier_);
    656   EXPECT_FALSE(tag);
    657 
    658   // No record related notifications will be sent when a tag gets removed.
    659   EXPECT_EQ(1, observer.tag_records_received_count_);
    660 }
    661 
    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;
    670 
    671   // Text record.
    672   base::DictionaryValue data;
    673   data.SetString(NfcNdefRecord::kFieldText, kText);
    674   data.SetString(NfcNdefRecord::kFieldLanguageCode, kLanguageCode);
    675   data.SetString(NfcNdefRecord::kFieldEncoding, kEncoding);
    676 
    677   scoped_ptr<NfcNdefRecord> record(new NfcNdefRecord());
    678   ASSERT_TRUE(record->Populate(NfcNdefRecord::kTypeText, &data));
    679 
    680   base::DictionaryValue result;
    681   EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
    682       record.get(), &result));
    683 
    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);
    697 
    698   // URI record.
    699   data.Clear();
    700   data.SetString(NfcNdefRecord::kFieldURI, kURI);
    701   data.SetString(NfcNdefRecord::kFieldMimeType, kMimeType);
    702   data.SetDouble(NfcNdefRecord::kFieldTargetSize, kSize);
    703 
    704   record.reset(new NfcNdefRecord());
    705   ASSERT_TRUE(record->Populate(NfcNdefRecord::kTypeURI, &data));
    706 
    707   result.Clear();
    708   EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
    709       record.get(), &result));
    710 
    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);
    717   double double_value;
    718   EXPECT_TRUE(result.GetDouble(nfc_record::kSizeProperty, &double_value));
    719   EXPECT_EQ(kSize, double_value);
    720 
    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);
    726 
    727   base::ListValue* titles = new base::ListValue();
    728   titles->Append(title);
    729   data.Set(NfcNdefRecord::kFieldTitles, titles);
    730 
    731   record.reset(new NfcNdefRecord());
    732   ASSERT_TRUE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
    733 
    734   result.Clear();
    735   EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
    736       record.get(), &result));
    737 
    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);
    756 }
    757 
    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;
    765 
    766   FakeNfcRecordClient::Properties record_properties(
    767       base::Bind(&OnPropertyChangedCallback));
    768 
    769   // Text record.
    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);
    774 
    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());
    779 
    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);
    791 
    792   // URI record.
    793   record_properties.representation.ReplaceValue("");
    794   record_properties.language.ReplaceValue("");
    795   record_properties.encoding.ReplaceValue("");
    796 
    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);
    801 
    802   record.reset(new NfcNdefRecord());
    803   EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
    804       &record_properties, record.get()));
    805   EXPECT_TRUE(record->IsPopulated());
    806 
    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);
    814   double double_value;
    815   EXPECT_TRUE(record->data().GetDouble(
    816       NfcNdefRecord::kFieldTargetSize, &double_value));
    817   EXPECT_EQ(kSize, double_value);
    818 
    819   // Contents not matching type.
    820   record_properties.representation.ReplaceValue(kText);
    821   record_properties.language.ReplaceValue(kLanguageCode);
    822   record_properties.encoding.ReplaceValue(kEncoding);
    823 
    824   record.reset(new NfcNdefRecord());
    825   EXPECT_FALSE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
    826       &record_properties, record.get()));
    827   EXPECT_FALSE(record->IsPopulated());
    828 
    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());
    834 
    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);
    845 
    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());
    849   ASSERT_TRUE(titles);
    850   const base::DictionaryValue* title = NULL;
    851   EXPECT_TRUE(titles->GetDictionary(0, &title));
    852   CHECK(title);
    853 
    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);
    861 }
    862 
    863 }  // namespace chromeos
    864