普通文本  |  165行  |  5.19 KB

// 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