• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
DBusTypePropertyToTagType(const std::string & type)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.
DBusProtocolPropertyToTagProtocol(const std::string & protocol)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 
NfcTagChromeOS(const dbus::ObjectPath & object_path)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 
~NfcTagChromeOS()59 NfcTagChromeOS::~NfcTagChromeOS() {
60   DBusThreadManager::Get()->GetNfcTagClient()->RemoveObserver(this);
61 }
62 
AddObserver(NfcTag::Observer * observer)63 void NfcTagChromeOS::AddObserver(NfcTag::Observer* observer) {
64   observers_.AddObserver(observer);
65 }
66 
RemoveObserver(NfcTag::Observer * observer)67 void NfcTagChromeOS::RemoveObserver(NfcTag::Observer* observer) {
68   observers_.RemoveObserver(observer);
69 }
70 
GetIdentifier() const71 std::string NfcTagChromeOS::GetIdentifier() const {
72   return object_path_.value();
73 }
74 
GetType() const75 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 
IsReadOnly() const82 bool NfcTagChromeOS::IsReadOnly() const {
83   DCHECK(object_path_.IsValid());
84   return DBusThreadManager::Get()->GetNfcTagClient()->
85       GetProperties(object_path_)->read_only.value();
86 }
87 
GetSupportedProtocol() const88 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
GetSupportedTechnologies() const96 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 
IsReady() const125 bool NfcTagChromeOS::IsReady() const {
126   return is_ready_;
127 }
128 
GetNdefTagTechnology()129 NfcNdefTagTechnology* NfcTagChromeOS::GetNdefTagTechnology() {
130   return ndef_technology_.get();
131 }
132 
TagPropertyChanged(const dbus::ObjectPath & object_path,const std::string & property_name)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 
TagPropertiesReceived(const dbus::ObjectPath & object_path)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