Home | History | Annotate | Download | only in nfc
      1 // Copyright 2014 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 "device/nfc/nfc_tag_chromeos.h"
      6 
      7 #include "chromeos/dbus/dbus_thread_manager.h"
      8 #include "device/nfc/nfc_tag_technology_chromeos.h"
      9 #include "third_party/cros_system_api/dbus/service_constants.h"
     10 
     11 using device::NfcTag;
     12 using device::NfcTagTechnology;
     13 using device::NfcNdefTagTechnology;
     14 
     15 namespace chromeos {
     16 
     17 namespace {
     18 
     19 // Converts an NFC tag type value returned by neard to a NfcTag::TagType enum
     20 // value.
     21 NfcTag::TagType DBusTypePropertyToTagType(const std::string& type) {
     22   if (type == nfc_tag::kTagType1)
     23     return NfcTag::kTagType1;
     24   if (type == nfc_tag::kTagType2)
     25     return NfcTag::kTagType2;
     26   if (type == nfc_tag::kTagType3)
     27     return NfcTag::kTagType3;
     28   if (type == nfc_tag::kTagType4)
     29     return NfcTag::kTagType4;
     30   return NfcTag::kTagTypeUnknown;
     31 }
     32 
     33 // Converts an NFC tag protocol value returned by neard to a NfcTag::Protocol
     34 // enum value.
     35 NfcTag::Protocol DBusProtocolPropertyToTagProtocol(
     36     const std::string& protocol) {
     37   if (protocol == nfc_common::kProtocolFelica)
     38     return NfcTag::kProtocolFelica;
     39   if (protocol == nfc_common::kProtocolIsoDep)
     40     return NfcTag::kProtocolIsoDep;
     41   if (protocol == nfc_common::kProtocolJewel)
     42     return NfcTag::kProtocolJewel;
     43   if (protocol == nfc_common::kProtocolMifare)
     44     return NfcTag::kProtocolMifare;
     45   if (protocol == nfc_common::kProtocolNfcDep)
     46     return NfcTag::kProtocolNfcDep;
     47   return NfcTag::kProtocolUnknown;
     48 }
     49 
     50 }  // namespace
     51 
     52 NfcTagChromeOS::NfcTagChromeOS(const dbus::ObjectPath& object_path)
     53     : object_path_(object_path),
     54       is_ready_(false),
     55       ndef_technology_(new NfcNdefTagTechnologyChromeOS(this)) {
     56   DBusThreadManager::Get()->GetNfcTagClient()->AddObserver(this);
     57 }
     58 
     59 NfcTagChromeOS::~NfcTagChromeOS() {
     60   DBusThreadManager::Get()->GetNfcTagClient()->RemoveObserver(this);
     61 }
     62 
     63 void NfcTagChromeOS::AddObserver(NfcTag::Observer* observer) {
     64   observers_.AddObserver(observer);
     65 }
     66 
     67 void NfcTagChromeOS::RemoveObserver(NfcTag::Observer* observer) {
     68   observers_.RemoveObserver(observer);
     69 }
     70 
     71 std::string NfcTagChromeOS::GetIdentifier() const {
     72   return object_path_.value();
     73 }
     74 
     75 NfcTag::TagType NfcTagChromeOS::GetType() const {
     76   DCHECK(object_path_.IsValid());
     77   return DBusTypePropertyToTagType(
     78       DBusThreadManager::Get()->GetNfcTagClient()->
     79           GetProperties(object_path_)->type.value());
     80 }
     81 
     82 bool NfcTagChromeOS::IsReadOnly() const {
     83   DCHECK(object_path_.IsValid());
     84   return DBusThreadManager::Get()->GetNfcTagClient()->
     85       GetProperties(object_path_)->read_only.value();
     86 }
     87 
     88 NfcTag::Protocol NfcTagChromeOS::GetSupportedProtocol() const {
     89   DCHECK(object_path_.IsValid());
     90   return DBusProtocolPropertyToTagProtocol(
     91       DBusThreadManager::Get()->GetNfcTagClient()->
     92           GetProperties(object_path_)->protocol.value());
     93 }
     94 
     95 NfcTagTechnology::TechnologyTypeMask
     96 NfcTagChromeOS::GetSupportedTechnologies() const {
     97   // Determine supported technologies based on the tag's protocol and
     98   // type.
     99   NfcTag::TagType type = GetType();
    100   NfcTag::Protocol protocol = GetSupportedProtocol();
    101   if (type == NfcTag::kTagTypeUnknown || protocol == kProtocolUnknown) {
    102     VLOG(1) << "Tag type and protocol unknown.";
    103     return 0;
    104   }
    105 
    106   NfcTagTechnology::TechnologyTypeMask technologies = 0;
    107   technologies |= NfcTagTechnology::kTechnologyTypeNdef;
    108   if (type == NfcTag::kTagType3) {
    109     DCHECK(protocol == NfcTag::kProtocolFelica);
    110     return technologies | NfcTagTechnology::kTechnologyTypeNfcF;
    111   }
    112 
    113   if (protocol == NfcTag::kProtocolIsoDep) {
    114     DCHECK(type == NfcTag::kTagType4);
    115     technologies |= NfcTagTechnology::kTechnologyTypeIsoDep;
    116     // TODO(armansito): Neard doesn't provide enough information to determine
    117     // if the underlying wave-form is type A or type B. For now, report
    118     // neither.
    119     return technologies;
    120   }
    121 
    122   return technologies | NfcTagTechnology::kTechnologyTypeNfcA;
    123 }
    124 
    125 bool NfcTagChromeOS::IsReady() const {
    126   return is_ready_;
    127 }
    128 
    129 NfcNdefTagTechnology* NfcTagChromeOS::GetNdefTagTechnology() {
    130   return ndef_technology_.get();
    131 }
    132 
    133 void NfcTagChromeOS::TagPropertyChanged(const dbus::ObjectPath& object_path,
    134                                         const std::string& property_name) {
    135   if (object_path != object_path_)
    136     return;
    137 
    138   NfcTagClient::Properties* properties =
    139     DBusThreadManager::Get()->GetNfcTagClient()->GetProperties(object_path_);
    140   DCHECK(properties);
    141 
    142   if (property_name == properties->type.name()) {
    143     FOR_EACH_OBSERVER(NfcTag::Observer, observers_,
    144                       TagTypeChanged(this, GetType()));
    145   } else if (property_name == properties->read_only.name()) {
    146     FOR_EACH_OBSERVER(NfcTag::Observer, observers_,
    147                       TagWritePermissionChanged(this, IsReadOnly()));
    148   } else if (property_name == properties->protocol.name()) {
    149     FOR_EACH_OBSERVER(
    150         NfcTag::Observer, observers_,
    151         TagSupportedProtocolChanged(this, GetSupportedProtocol()));
    152   }
    153 }
    154 
    155 void NfcTagChromeOS::TagPropertiesReceived(
    156     const dbus::ObjectPath& object_path) {
    157   if (is_ready_ || object_path != object_path_)
    158     return;
    159 
    160   is_ready_ = true;
    161   FOR_EACH_OBSERVER(NfcTag::Observer, observers_, TagReady(this));
    162 }
    163 
    164 }  // namespace chromeos
    165