blob: e2390fa04fbe135415e75d7a21536d8802ec07a2 [file] [log] [blame]
// 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