| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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_peer_chromeos.h" | |
| 6 | |
| 7 #include <string> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/logging.h" | |
| 11 #include "base/stl_util.h" | |
| 12 #include "chromeos/dbus/dbus_thread_manager.h" | |
| 13 #include "chromeos/dbus/nfc_device_client.h" | |
| 14 #include "device/nfc/nfc_ndef_record_utils_chromeos.h" | |
| 15 #include "third_party/cros_system_api/dbus/service_constants.h" | |
| 16 | |
| 17 using device::NfcNdefMessage; | |
| 18 using device::NfcNdefRecord; | |
| 19 | |
| 20 namespace chromeos { | |
| 21 | |
| 22 namespace { | |
| 23 | |
| 24 typedef std::vector<dbus::ObjectPath> ObjectPathVector; | |
| 25 | |
| 26 } // namespace | |
| 27 | |
| 28 NfcPeerChromeOS::NfcPeerChromeOS(const dbus::ObjectPath& object_path) | |
| 29 : object_path_(object_path), | |
| 30 weak_ptr_factory_(this) { | |
| 31 // Create record objects for all records that were received before. | |
| 32 const ObjectPathVector& records = | |
| 33 DBusThreadManager::Get()->GetNfcRecordClient()-> | |
| 34 GetRecordsForDevice(object_path_); | |
| 35 for (ObjectPathVector::const_iterator iter = records.begin(); | |
| 36 iter != records.end(); ++iter) { | |
| 37 AddRecord(*iter); | |
| 38 } | |
| 39 DBusThreadManager::Get()->GetNfcRecordClient()->AddObserver(this); | |
| 40 } | |
| 41 | |
| 42 NfcPeerChromeOS::~NfcPeerChromeOS() { | |
| 43 DBusThreadManager::Get()->GetNfcRecordClient()->RemoveObserver(this); | |
| 44 base::STLDeleteValues(&records_); | |
| 45 } | |
| 46 | |
| 47 void NfcPeerChromeOS::AddObserver(device::NfcPeer::Observer* observer) { | |
| 48 DCHECK(observer); | |
| 49 observers_.AddObserver(observer); | |
| 50 } | |
| 51 | |
| 52 void NfcPeerChromeOS::RemoveObserver(device::NfcPeer::Observer* observer) { | |
| 53 DCHECK(observer); | |
| 54 observers_.RemoveObserver(observer); | |
| 55 } | |
| 56 | |
| 57 std::string NfcPeerChromeOS::GetIdentifier() const { | |
| 58 return object_path_.value(); | |
| 59 } | |
| 60 | |
| 61 const NfcNdefMessage& NfcPeerChromeOS::GetNdefMessage() const { | |
| 62 return message_; | |
| 63 } | |
| 64 | |
| 65 void NfcPeerChromeOS::PushNdef(const NfcNdefMessage& message, | |
| 66 const base::Closure& callback, | |
| 67 const ErrorCallback& error_callback) { | |
| 68 if (message.records().empty()) { | |
| 69 LOG(ERROR) << "Given NDEF message is empty. Cannot push it."; | |
| 70 error_callback.Run(); | |
| 71 return; | |
| 72 } | |
| 73 // TODO(armansito): neard currently supports pushing only one NDEF record | |
| 74 // to a remote device and won't support multiple records until 0.15. Until | |
| 75 // then, report failure if |message| contains more than one record. | |
| 76 if (message.records().size() > 1) { | |
| 77 LOG(ERROR) << "Currently, pushing only 1 NDEF record is supported."; | |
| 78 error_callback.Run(); | |
| 79 return; | |
| 80 } | |
| 81 const NfcNdefRecord* record = message.records()[0]; | |
| 82 base::DictionaryValue attributes; | |
| 83 if (!nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes( | |
| 84 record, &attributes)) { | |
| 85 LOG(ERROR) << "Failed to extract NDEF record fields for NDEF push."; | |
| 86 error_callback.Run(); | |
| 87 return; | |
| 88 } | |
| 89 DBusThreadManager::Get()->GetNfcDeviceClient()->Push( | |
| 90 object_path_, | |
| 91 attributes, | |
| 92 base::Bind(&NfcPeerChromeOS::OnPushNdef, | |
| 93 weak_ptr_factory_.GetWeakPtr(), | |
| 94 callback), | |
| 95 base::Bind(&NfcPeerChromeOS::OnPushNdefError, | |
| 96 weak_ptr_factory_.GetWeakPtr(), | |
| 97 error_callback)); | |
| 98 } | |
| 99 | |
| 100 void NfcPeerChromeOS::StartHandover(HandoverType handover_type, | |
| 101 const base::Closure& callback, | |
| 102 const ErrorCallback& error_callback) { | |
| 103 // TODO(armansito): Initiating handover with a peer is currently not | |
| 104 // supported. For now, return an error immediately. | |
| 105 LOG(ERROR) << "NFC Handover currently not supported."; | |
| 106 error_callback.Run(); | |
| 107 } | |
| 108 | |
| 109 void NfcPeerChromeOS::RecordAdded(const dbus::ObjectPath& object_path) { | |
| 110 // Don't create the record object yet. Instead, wait until all record | |
| 111 // properties have been received and contruct the object and notify observers | |
| 112 // then. | |
| 113 VLOG(1) << "Record added: " << object_path.value() << ". Waiting until " | |
| 114 << "all properties have been fetched to create record object."; | |
| 115 } | |
| 116 | |
| 117 void NfcPeerChromeOS::RecordRemoved(const dbus::ObjectPath& object_path) { | |
| 118 NdefRecordMap::iterator iter = records_.find(object_path); | |
| 119 if (iter == records_.end()) | |
| 120 return; | |
| 121 VLOG(1) << "Lost remote NDEF record object: " << object_path.value() | |
| 122 << ", removing record."; | |
| 123 NfcNdefRecord* record = iter->second; | |
| 124 message_.RemoveRecord(record); | |
| 125 delete record; | |
| 126 records_.erase(iter); | |
| 127 } | |
| 128 | |
| 129 void NfcPeerChromeOS::RecordPropertiesReceived( | |
| 130 const dbus::ObjectPath& object_path) { | |
| 131 VLOG(1) << "Record properties received for: " << object_path.value(); | |
| 132 | |
| 133 // Check if the found record belongs to this device. | |
| 134 bool record_found = false; | |
| 135 const ObjectPathVector& records = | |
| 136 DBusThreadManager::Get()->GetNfcRecordClient()-> | |
| 137 GetRecordsForDevice(object_path_); | |
| 138 for (ObjectPathVector::const_iterator iter = records.begin(); | |
| 139 iter != records.end(); ++iter) { | |
| 140 if (*iter == object_path) { | |
| 141 record_found = true; | |
| 142 break; | |
| 143 } | |
| 144 } | |
| 145 if (!record_found) { | |
| 146 VLOG(1) << "Record \"" << object_path.value() << "\" doesn't belong to this" | |
| 147 << " device. Ignoring."; | |
| 148 return; | |
| 149 } | |
| 150 | |
| 151 AddRecord(object_path); | |
| 152 } | |
| 153 | |
| 154 void NfcPeerChromeOS::OnPushNdef(const base::Closure& callback) { | |
| 155 callback.Run(); | |
| 156 } | |
| 157 | |
| 158 void NfcPeerChromeOS::OnPushNdefError(const ErrorCallback& error_callback, | |
| 159 const std::string& error_name, | |
| 160 const std::string& error_message) { | |
| 161 LOG(ERROR) << object_path_.value() << ": Failed to Push NDEF message: " | |
| 162 << error_name << ": " << error_message; | |
| 163 error_callback.Run(); | |
| 164 } | |
| 165 | |
| 166 void NfcPeerChromeOS::AddRecord(const dbus::ObjectPath& object_path) { | |
| 167 // Ignore this call if an entry for this record already exists. | |
| 168 if (records_.find(object_path) != records_.end()) { | |
| 169 VLOG(1) << "Record object for remote \"" << object_path.value() | |
| 170 << "\" already exists."; | |
| 171 return; | |
| 172 } | |
| 173 | |
| 174 NfcRecordClient::Properties* record_properties = | |
| 175 DBusThreadManager::Get()->GetNfcRecordClient()-> | |
| 176 GetProperties(object_path); | |
| 177 DCHECK(record_properties); | |
| 178 | |
| 179 NfcNdefRecord* record = new NfcNdefRecord(); | |
| 180 if (!nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord( | |
| 181 record_properties, record)) { | |
| 182 LOG(ERROR) << "Failed to create record object for record with object " | |
| 183 << "path \"" << object_path.value() << "\""; | |
| 184 delete record; | |
| 185 return; | |
| 186 } | |
| 187 | |
| 188 message_.AddRecord(record); | |
| 189 records_[object_path] = record; | |
| 190 FOR_EACH_OBSERVER(NfcPeer::Observer, observers_, | |
| 191 RecordReceived(this, record)); | |
| 192 } | |
| 193 | |
| 194 } // namespace chromeos | |
| OLD | NEW |