summaryrefslogtreecommitdiffstats
path: root/chromium/device/nfc/nfc_peer_chromeos.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/device/nfc/nfc_peer_chromeos.cc')
-rw-r--r--chromium/device/nfc/nfc_peer_chromeos.cc194
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