| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "device/nfc/nfc_tag_chromeos.h" |
| |
| #include "chromeos/dbus/dbus_thread_manager.h" |
| #include "device/nfc/nfc_tag_technology_chromeos.h" |
| #include "third_party/cros_system_api/dbus/service_constants.h" |
| |
| using device::NfcTag; |
| using device::NfcTagTechnology; |
| using device::NfcNdefTagTechnology; |
| |
| namespace chromeos { |
| |
| namespace { |
| |
| // Converts an NFC tag type value returned by neard to a NfcTag::TagType enum |
| // value. |
| NfcTag::TagType DBusTypePropertyToTagType(const std::string& type) { |
| if (type == nfc_tag::kTagType1) |
| return NfcTag::kTagType1; |
| if (type == nfc_tag::kTagType2) |
| return NfcTag::kTagType2; |
| if (type == nfc_tag::kTagType3) |
| return NfcTag::kTagType3; |
| if (type == nfc_tag::kTagType4) |
| return NfcTag::kTagType4; |
| return NfcTag::kTagTypeUnknown; |
| } |
| |
| // Converts an NFC tag protocol value returned by neard to a NfcTag::Protocol |
| // enum value. |
| NfcTag::Protocol DBusProtocolPropertyToTagProtocol( |
| const std::string& protocol) { |
| if (protocol == nfc_common::kProtocolFelica) |
| return NfcTag::kProtocolFelica; |
| if (protocol == nfc_common::kProtocolIsoDep) |
| return NfcTag::kProtocolIsoDep; |
| if (protocol == nfc_common::kProtocolJewel) |
| return NfcTag::kProtocolJewel; |
| if (protocol == nfc_common::kProtocolMifare) |
| return NfcTag::kProtocolMifare; |
| if (protocol == nfc_common::kProtocolNfcDep) |
| return NfcTag::kProtocolNfcDep; |
| return NfcTag::kProtocolUnknown; |
| } |
| |
| } // namespace |
| |
| NfcTagChromeOS::NfcTagChromeOS(const dbus::ObjectPath& object_path) |
| : object_path_(object_path), |
| is_ready_(false), |
| ndef_technology_(new NfcNdefTagTechnologyChromeOS(this)) { |
| DBusThreadManager::Get()->GetNfcTagClient()->AddObserver(this); |
| } |
| |
| NfcTagChromeOS::~NfcTagChromeOS() { |
| DBusThreadManager::Get()->GetNfcTagClient()->RemoveObserver(this); |
| } |
| |
| void NfcTagChromeOS::AddObserver(NfcTag::Observer* observer) { |
| observers_.AddObserver(observer); |
| } |
| |
| void NfcTagChromeOS::RemoveObserver(NfcTag::Observer* observer) { |
| observers_.RemoveObserver(observer); |
| } |
| |
| std::string NfcTagChromeOS::GetIdentifier() const { |
| return object_path_.value(); |
| } |
| |
| NfcTag::TagType NfcTagChromeOS::GetType() const { |
| DCHECK(object_path_.IsValid()); |
| return DBusTypePropertyToTagType( |
| DBusThreadManager::Get()->GetNfcTagClient()-> |
| GetProperties(object_path_)->type.value()); |
| } |
| |
| bool NfcTagChromeOS::IsReadOnly() const { |
| DCHECK(object_path_.IsValid()); |
| return DBusThreadManager::Get()->GetNfcTagClient()-> |
| GetProperties(object_path_)->read_only.value(); |
| } |
| |
| NfcTag::Protocol NfcTagChromeOS::GetSupportedProtocol() const { |
| DCHECK(object_path_.IsValid()); |
| return DBusProtocolPropertyToTagProtocol( |
| DBusThreadManager::Get()->GetNfcTagClient()-> |
| GetProperties(object_path_)->protocol.value()); |
| } |
| |
| NfcTagTechnology::TechnologyTypeMask |
| NfcTagChromeOS::GetSupportedTechnologies() const { |
| // Determine supported technologies based on the tag's protocol and |
| // type. |
| NfcTag::TagType type = GetType(); |
| NfcTag::Protocol protocol = GetSupportedProtocol(); |
| if (type == NfcTag::kTagTypeUnknown || protocol == kProtocolUnknown) { |
| VLOG(1) << "Tag type and protocol unknown."; |
| return 0; |
| } |
| |
| NfcTagTechnology::TechnologyTypeMask technologies = 0; |
| technologies |= NfcTagTechnology::kTechnologyTypeNdef; |
| if (type == NfcTag::kTagType3) { |
| DCHECK(protocol == NfcTag::kProtocolFelica); |
| return technologies | NfcTagTechnology::kTechnologyTypeNfcF; |
| } |
| |
| if (protocol == NfcTag::kProtocolIsoDep) { |
| DCHECK(type == NfcTag::kTagType4); |
| technologies |= NfcTagTechnology::kTechnologyTypeIsoDep; |
| // TODO(armansito): Neard doesn't provide enough information to determine |
| // if the underlying wave-form is type A or type B. For now, report |
| // neither. |
| return technologies; |
| } |
| |
| return technologies | NfcTagTechnology::kTechnologyTypeNfcA; |
| } |
| |
| bool NfcTagChromeOS::IsReady() const { |
| return is_ready_; |
| } |
| |
| NfcNdefTagTechnology* NfcTagChromeOS::GetNdefTagTechnology() { |
| return ndef_technology_.get(); |
| } |
| |
| void NfcTagChromeOS::TagPropertyChanged(const dbus::ObjectPath& object_path, |
| const std::string& property_name) { |
| if (object_path != object_path_) |
| return; |
| |
| NfcTagClient::Properties* properties = |
| DBusThreadManager::Get()->GetNfcTagClient()->GetProperties(object_path_); |
| DCHECK(properties); |
| |
| if (property_name == properties->type.name()) { |
| FOR_EACH_OBSERVER(NfcTag::Observer, observers_, |
| TagTypeChanged(this, GetType())); |
| } else if (property_name == properties->read_only.name()) { |
| FOR_EACH_OBSERVER(NfcTag::Observer, observers_, |
| TagWritePermissionChanged(this, IsReadOnly())); |
| } else if (property_name == properties->protocol.name()) { |
| FOR_EACH_OBSERVER( |
| NfcTag::Observer, observers_, |
| TagSupportedProtocolChanged(this, GetSupportedProtocol())); |
| } |
| } |
| |
| void NfcTagChromeOS::TagPropertiesReceived( |
| const dbus::ObjectPath& object_path) { |
| if (is_ready_ || object_path != object_path_) |
| return; |
| |
| is_ready_ = true; |
| FOR_EACH_OBSERVER(NfcTag::Observer, observers_, TagReady(this)); |
| } |
| |
| } // namespace chromeos |