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