diff options
Diffstat (limited to 'chromium/device/nfc/nfc_peer_chromeos.cc')
-rw-r--r-- | chromium/device/nfc/nfc_peer_chromeos.cc | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/chromium/device/nfc/nfc_peer_chromeos.cc b/chromium/device/nfc/nfc_peer_chromeos.cc new file mode 100644 index 00000000000..4ef1804b857 --- /dev/null +++ b/chromium/device/nfc/nfc_peer_chromeos.cc @@ -0,0 +1,194 @@ +// Copyright 2013 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_peer_chromeos.h" + +#include <string> +#include <vector> + +#include "base/logging.h" +#include "base/stl_util.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/nfc_device_client.h" +#include "device/nfc/nfc_ndef_record_utils_chromeos.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +using device::NfcNdefMessage; +using device::NfcNdefRecord; + +namespace chromeos { + +namespace { + +typedef std::vector<dbus::ObjectPath> ObjectPathVector; + +} // namespace + +NfcPeerChromeOS::NfcPeerChromeOS(const dbus::ObjectPath& object_path) + : object_path_(object_path), + weak_ptr_factory_(this) { + // Create record objects for all records that were received before. + const ObjectPathVector& records = + DBusThreadManager::Get()->GetNfcRecordClient()-> + GetRecordsForDevice(object_path_); + for (ObjectPathVector::const_iterator iter = records.begin(); + iter != records.end(); ++iter) { + AddRecord(*iter); + } + DBusThreadManager::Get()->GetNfcRecordClient()->AddObserver(this); +} + +NfcPeerChromeOS::~NfcPeerChromeOS() { + DBusThreadManager::Get()->GetNfcRecordClient()->RemoveObserver(this); + STLDeleteValues(&records_); +} + +void NfcPeerChromeOS::AddObserver(device::NfcPeer::Observer* observer) { + DCHECK(observer); + observers_.AddObserver(observer); +} + +void NfcPeerChromeOS::RemoveObserver(device::NfcPeer::Observer* observer) { + DCHECK(observer); + observers_.RemoveObserver(observer); +} + +std::string NfcPeerChromeOS::GetIdentifier() const { + return object_path_.value(); +} + +const NfcNdefMessage& NfcPeerChromeOS::GetNdefMessage() const { + return message_; +} + +void NfcPeerChromeOS::PushNdef(const NfcNdefMessage& message, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (message.records().empty()) { + LOG(ERROR) << "Given NDEF message is empty. Cannot push it."; + error_callback.Run(); + return; + } + // TODO(armansito): neard currently supports pushing only one NDEF record + // to a remote device and won't support multiple records until 0.15. Until + // then, report failure if |message| contains more than one record. + if (message.records().size() > 1) { + LOG(ERROR) << "Currently, pushing only 1 NDEF record is supported."; + error_callback.Run(); + return; + } + const NfcNdefRecord* record = message.records()[0]; + base::DictionaryValue attributes; + if (!nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes( + record, &attributes)) { + LOG(ERROR) << "Failed to extract NDEF record fields for NDEF push."; + error_callback.Run(); + return; + } + DBusThreadManager::Get()->GetNfcDeviceClient()->Push( + object_path_, + attributes, + base::Bind(&NfcPeerChromeOS::OnPushNdef, + weak_ptr_factory_.GetWeakPtr(), + callback), + base::Bind(&NfcPeerChromeOS::OnPushNdefError, + weak_ptr_factory_.GetWeakPtr(), + error_callback)); +} + +void NfcPeerChromeOS::StartHandover(HandoverType handover_type, + const base::Closure& callback, + const ErrorCallback& error_callback) { + // TODO(armansito): Initiating handover with a peer is currently not + // supported. For now, return an error immediately. + LOG(ERROR) << "NFC Handover currently not supported."; + error_callback.Run(); +} + +void NfcPeerChromeOS::RecordAdded(const dbus::ObjectPath& object_path) { + // Don't create the record object yet. Instead, wait until all record + // properties have been received and contruct the object and notify observers + // then. + VLOG(1) << "Record added: " << object_path.value() << ". Waiting until " + << "all properties have been fetched to create record object."; +} + +void NfcPeerChromeOS::RecordRemoved(const dbus::ObjectPath& object_path) { + NdefRecordMap::iterator iter = records_.find(object_path); + if (iter == records_.end()) + return; + VLOG(1) << "Lost remote NDEF record object: " << object_path.value() + << ", removing record."; + NfcNdefRecord* record = iter->second; + message_.RemoveRecord(record); + delete record; + records_.erase(iter); +} + +void NfcPeerChromeOS::RecordPropertiesReceived( + const dbus::ObjectPath& object_path) { + VLOG(1) << "Record properties received for: " << object_path.value(); + + // Check if the found record belongs to this device. + bool record_found = false; + const ObjectPathVector& records = + DBusThreadManager::Get()->GetNfcRecordClient()-> + GetRecordsForDevice(object_path_); + for (ObjectPathVector::const_iterator iter = records.begin(); + iter != records.end(); ++iter) { + if (*iter == object_path) { + record_found = true; + break; + } + } + if (!record_found) { + VLOG(1) << "Record \"" << object_path.value() << "\" doesn't belong to this" + << " device. Ignoring."; + return; + } + + AddRecord(object_path); +} + +void NfcPeerChromeOS::OnPushNdef(const base::Closure& callback) { + callback.Run(); +} + +void NfcPeerChromeOS::OnPushNdefError(const ErrorCallback& error_callback, + const std::string& error_name, + const std::string& error_message) { + LOG(ERROR) << object_path_.value() << ": Failed to Push NDEF message: " + << error_name << ": " << error_message; + error_callback.Run(); +} + +void NfcPeerChromeOS::AddRecord(const dbus::ObjectPath& object_path) { + // Ignore this call if an entry for this record already exists. + if (records_.find(object_path) != records_.end()) { + VLOG(1) << "Record object for remote \"" << object_path.value() + << "\" already exists."; + return; + } + + NfcRecordClient::Properties* record_properties = + DBusThreadManager::Get()->GetNfcRecordClient()-> + GetProperties(object_path); + DCHECK(record_properties); + + NfcNdefRecord* record = new NfcNdefRecord(); + if (!nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord( + record_properties, record)) { + LOG(ERROR) << "Failed to create record object for record with object " + << "path \"" << object_path.value() << "\""; + delete record; + return; + } + + message_.AddRecord(record); + records_[object_path] = record; + FOR_EACH_OBSERVER(NfcPeer::Observer, observers_, + RecordReceived(this, record)); +} + +} // namespace chromeos |