summaryrefslogtreecommitdiffstats
path: root/chromeos
diff options
context:
space:
mode:
authorarmansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-31 07:56:14 +0000
committerarmansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-31 07:56:14 +0000
commitf8005694519d625602c9473483fa276540506960 (patch)
tree3039d2eaca4157db7c7eae59d7e3154fe45fb7d6 /chromeos
parent9fe90e7b2796df70a786964cf450750a5437b97c (diff)
downloadchromium_src-f8005694519d625602c9473483fa276540506960.zip
chromium_src-f8005694519d625602c9473483fa276540506960.tar.gz
chromium_src-f8005694519d625602c9473483fa276540506960.tar.bz2
nfc: Add D-Bus clients for NFC Tag and Device interfaces.
Added D-Bus client code for the NFC Tag and Device interfaces. BUG=304979 TEST=1. chromeos_unittests 2. Manually test using an external USB adapter that Tag and Device property changes are reflected in the logs. Review URL: https://codereview.chromium.org/48713006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@232042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos')
-rw-r--r--chromeos/chromeos.gyp8
-rw-r--r--chromeos/dbus/dbus_thread_manager.cc25
-rw-r--r--chromeos/dbus/dbus_thread_manager.h4
-rw-r--r--chromeos/dbus/fake_dbus_thread_manager.cc12
-rw-r--r--chromeos/dbus/fake_dbus_thread_manager.h14
-rw-r--r--chromeos/dbus/fake_nfc_adapter_client.cc9
-rw-r--r--chromeos/dbus/fake_nfc_adapter_client.h7
-rw-r--r--chromeos/dbus/fake_nfc_device_client.cc71
-rw-r--r--chromeos/dbus/fake_nfc_device_client.h54
-rw-r--r--chromeos/dbus/fake_nfc_tag_client.cc71
-rw-r--r--chromeos/dbus/fake_nfc_tag_client.h54
-rw-r--r--chromeos/dbus/mock_dbus_thread_manager.cc8
-rw-r--r--chromeos/dbus/mock_dbus_thread_manager.h12
-rw-r--r--chromeos/dbus/nfc_adapter_client.cc4
-rw-r--r--chromeos/dbus/nfc_client_helpers.cc2
-rw-r--r--chromeos/dbus/nfc_client_helpers.h9
-rw-r--r--chromeos/dbus/nfc_client_unittest.cc445
-rw-r--r--chromeos/dbus/nfc_device_client.cc248
-rw-r--r--chromeos/dbus/nfc_device_client.h119
-rw-r--r--chromeos/dbus/nfc_tag_client.cc250
-rw-r--r--chromeos/dbus/nfc_tag_client.h130
21 files changed, 1501 insertions, 55 deletions
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp
index debcaa6..e0e53e6 100644
--- a/chromeos/chromeos.gyp
+++ b/chromeos/chromeos.gyp
@@ -115,8 +115,12 @@
'dbus/fake_gsm_sms_client.h',
'dbus/fake_nfc_adapter_client.cc',
'dbus/fake_nfc_adapter_client.h',
+ 'dbus/fake_nfc_device_client.cc',
+ 'dbus/fake_nfc_device_client.h',
'dbus/fake_nfc_manager_client.cc',
'dbus/fake_nfc_manager_client.h',
+ 'dbus/fake_nfc_tag_client.cc',
+ 'dbus/fake_nfc_tag_client.h',
'dbus/fake_image_burner_client.cc',
'dbus/fake_image_burner_client.h',
'dbus/fake_shill_device_client.cc',
@@ -137,10 +141,14 @@
'dbus/nfc_adapter_client.h',
'dbus/nfc_client_helpers.cc',
'dbus/nfc_client_helpers.h',
+ 'dbus/nfc_device_client.cc',
+ 'dbus/nfc_device_client.h',
'dbus/nfc_manager_client.cc',
'dbus/nfc_manager_client.h',
'dbus/nfc_property_set.cc',
'dbus/nfc_property_set.h',
+ 'dbus/nfc_tag_client.cc',
+ 'dbus/nfc_tag_client.h',
'dbus/shill_client_helper.cc',
'dbus/shill_client_helper.h',
'dbus/shill_device_client.cc',
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc
index b98e07c..164b503 100644
--- a/chromeos/dbus/dbus_thread_manager.cc
+++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -30,7 +30,9 @@
#include "chromeos/dbus/introspectable_client.h"
#include "chromeos/dbus/modem_messaging_client.h"
#include "chromeos/dbus/nfc_adapter_client.h"
+#include "chromeos/dbus/nfc_device_client.h"
#include "chromeos/dbus/nfc_manager_client.h"
+#include "chromeos/dbus/nfc_tag_client.h"
#include "chromeos/dbus/permission_broker_client.h"
#include "chromeos/dbus/power_manager_client.h"
#include "chromeos/dbus/power_policy_controller.h"
@@ -103,8 +105,11 @@ class DBusThreadManagerImpl : public DBusThreadManager {
InitClient(image_burner_client_.get());
InitClient(introspectable_client_.get());
InitClient(modem_messaging_client_.get());
+ // Initialize the NFC clients in the correct order.
InitClient(nfc_manager_client_.get());
InitClient(nfc_adapter_client_.get());
+ InitClient(nfc_device_client_.get());
+ InitClient(nfc_tag_client_.get());
InitClient(permission_broker_client_.get());
InitClient(power_manager_client_.get());
InitClient(session_manager_client_.get());
@@ -269,10 +274,18 @@ class DBusThreadManagerImpl : public DBusThreadManager {
return nfc_adapter_client_.get();
}
+ virtual NfcDeviceClient* GetNfcDeviceClient() OVERRIDE {
+ return nfc_device_client_.get();
+ }
+
virtual NfcManagerClient* GetNfcManagerClient() OVERRIDE {
return nfc_manager_client_.get();
}
+ virtual NfcTagClient* GetNfcTagClient() OVERRIDE {
+ return nfc_tag_client_.get();
+ }
+
virtual PermissionBrokerClient* GetPermissionBrokerClient() OVERRIDE {
return permission_broker_client_.get();
}
@@ -366,9 +379,14 @@ class DBusThreadManagerImpl : public DBusThreadManager {
image_burner_client_.reset(ImageBurnerClient::Create(client_type));
introspectable_client_.reset(IntrospectableClient::Create(client_type));
modem_messaging_client_.reset(ModemMessagingClient::Create(client_type));
+ // Create the NFC clients in the correct order based on their dependencies.
nfc_manager_client_.reset(NfcManagerClient::Create(client_type));
nfc_adapter_client_.reset(
NfcAdapterClient::Create(client_type, nfc_manager_client_.get()));
+ nfc_device_client_.reset(
+ NfcDeviceClient::Create(client_type, nfc_adapter_client_.get()));
+ nfc_tag_client_.reset(
+ NfcTagClient::Create(client_type, nfc_adapter_client_.get()));
permission_broker_client_.reset(
PermissionBrokerClient::Create(client_type));
power_manager_client_.reset(
@@ -404,11 +422,12 @@ class DBusThreadManagerImpl : public DBusThreadManager {
scoped_ptr<ImageBurnerClient> image_burner_client_;
scoped_ptr<IntrospectableClient> introspectable_client_;
scoped_ptr<ModemMessagingClient> modem_messaging_client_;
- // NfcAdapterClient depends on NfcManagerClient. We declare NfcManagerClient
- // first, so that it won't be deallocated before NfcAdapterClient is done
- // cleaning up.
+ // The declaration order for NFC client objects is important. See
+ // DBusThreadManager::CreateDefaultClients for the dependencies.
scoped_ptr<NfcManagerClient> nfc_manager_client_;
scoped_ptr<NfcAdapterClient> nfc_adapter_client_;
+ scoped_ptr<NfcDeviceClient> nfc_device_client_;
+ scoped_ptr<NfcTagClient> nfc_tag_client_;
scoped_ptr<PermissionBrokerClient> permission_broker_client_;
scoped_ptr<SystemClockClient> system_clock_client_;
scoped_ptr<PowerManagerClient> power_manager_client_;
diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h
index d0d6c3c..f0ef8b1 100644
--- a/chromeos/dbus/dbus_thread_manager.h
+++ b/chromeos/dbus/dbus_thread_manager.h
@@ -43,7 +43,9 @@ class ImageBurnerClient;
class IntrospectableClient;
class ModemMessagingClient;
class NfcAdapterClient;
+class NfcDeviceClient;
class NfcManagerClient;
+class NfcTagClient;
class PermissionBrokerClient;
class PowerManagerClient;
class PowerPolicyController;
@@ -137,7 +139,9 @@ class CHROMEOS_EXPORT DBusThreadManager {
virtual IntrospectableClient* GetIntrospectableClient() = 0;
virtual ModemMessagingClient* GetModemMessagingClient() = 0;
virtual NfcAdapterClient* GetNfcAdapterClient() = 0;
+ virtual NfcDeviceClient* GetNfcDeviceClient() = 0;
virtual NfcManagerClient* GetNfcManagerClient() = 0;
+ virtual NfcTagClient* GetNfcTagClient() = 0;
virtual PermissionBrokerClient* GetPermissionBrokerClient() = 0;
virtual PowerManagerClient* GetPowerManagerClient() = 0;
virtual PowerPolicyController* GetPowerPolicyController() = 0;
diff --git a/chromeos/dbus/fake_dbus_thread_manager.cc b/chromeos/dbus/fake_dbus_thread_manager.cc
index e8f7bbb..9d7834a 100644
--- a/chromeos/dbus/fake_dbus_thread_manager.cc
+++ b/chromeos/dbus/fake_dbus_thread_manager.cc
@@ -15,7 +15,9 @@
#include "chromeos/dbus/fake_gsm_sms_client.h"
#include "chromeos/dbus/fake_image_burner_client.h"
#include "chromeos/dbus/fake_nfc_adapter_client.h"
+#include "chromeos/dbus/fake_nfc_device_client.h"
#include "chromeos/dbus/fake_nfc_manager_client.h"
+#include "chromeos/dbus/fake_nfc_tag_client.h"
#include "chromeos/dbus/fake_power_manager_client.h"
#include "chromeos/dbus/fake_session_manager_client.h"
#include "chromeos/dbus/fake_shill_device_client.h"
@@ -41,7 +43,9 @@ FakeDBusThreadManager::FakeDBusThreadManager()
fake_gsm_sms_client_(new FakeGsmSMSClient),
fake_image_burner_client_(new FakeImageBurnerClient),
fake_nfc_adapter_client_(new FakeNfcAdapterClient()),
+ fake_nfc_device_client_(new FakeNfcDeviceClient()),
fake_nfc_manager_client_(new FakeNfcManagerClient()),
+ fake_nfc_tag_client_(new FakeNfcTagClient()),
fake_session_manager_client_(new FakeSessionManagerClient),
fake_shill_device_client_(new FakeShillDeviceClient),
fake_shill_manager_client_(new FakeShillManagerClient),
@@ -182,10 +186,18 @@ NfcAdapterClient* FakeDBusThreadManager::GetNfcAdapterClient() {
return fake_nfc_adapter_client_.get();
}
+NfcDeviceClient* FakeDBusThreadManager::GetNfcDeviceClient() {
+ return fake_nfc_device_client_.get();
+}
+
NfcManagerClient* FakeDBusThreadManager::GetNfcManagerClient() {
return fake_nfc_manager_client_.get();
}
+NfcTagClient* FakeDBusThreadManager::GetNfcTagClient() {
+ return fake_nfc_tag_client_.get();
+}
+
PermissionBrokerClient*
FakeDBusThreadManager::GetPermissionBrokerClient() {
NOTIMPLEMENTED();
diff --git a/chromeos/dbus/fake_dbus_thread_manager.h b/chromeos/dbus/fake_dbus_thread_manager.h
index 495d2d1..c6fb556 100644
--- a/chromeos/dbus/fake_dbus_thread_manager.h
+++ b/chromeos/dbus/fake_dbus_thread_manager.h
@@ -28,7 +28,9 @@ class FakeCrosDisksClient;
class FakeCryptohomeClient;
class FakeGsmSMSClient;
class FakeNfcAdapterClient;
+class FakeNfcDeviceClient;
class FakeNfcManagerClient;
+class FakeNfcTagClient;
class FakePowerManagerClient;
class FakeImageBurnerClient;
class FakeSessionManagerClient;
@@ -75,7 +77,9 @@ class FakeDBusThreadManager : public DBusThreadManager {
virtual IntrospectableClient* GetIntrospectableClient() OVERRIDE;
virtual ModemMessagingClient* GetModemMessagingClient() OVERRIDE;
virtual NfcAdapterClient* GetNfcAdapterClient() OVERRIDE;
+ virtual NfcDeviceClient* GetNfcDeviceClient() OVERRIDE;
virtual NfcManagerClient* GetNfcManagerClient() OVERRIDE;
+ virtual NfcTagClient* GetNfcTagClient() OVERRIDE;
virtual PermissionBrokerClient* GetPermissionBrokerClient() OVERRIDE;
virtual PowerManagerClient* GetPowerManagerClient() OVERRIDE;
virtual PowerPolicyController* GetPowerPolicyController() OVERRIDE;
@@ -130,10 +134,18 @@ class FakeDBusThreadManager : public DBusThreadManager {
return fake_nfc_adapter_client_.get();
}
+ FakeNfcDeviceClient* fake_nfc_device_client() {
+ return fake_nfc_device_client_.get();
+ }
+
FakeNfcManagerClient* fake_nfc_manager_client() {
return fake_nfc_manager_client_.get();
}
+ FakeNfcTagClient* fake_nfc_tag_client() {
+ return fake_nfc_tag_client_.get();
+ }
+
FakeSessionManagerClient* fake_session_manager_client() {
return fake_session_manager_client_.get();
}
@@ -192,7 +204,9 @@ class FakeDBusThreadManager : public DBusThreadManager {
scoped_ptr<FakeGsmSMSClient> fake_gsm_sms_client_;
scoped_ptr<FakeImageBurnerClient> fake_image_burner_client_;
scoped_ptr<FakeNfcAdapterClient> fake_nfc_adapter_client_;
+ scoped_ptr<FakeNfcDeviceClient> fake_nfc_device_client_;
scoped_ptr<FakeNfcManagerClient> fake_nfc_manager_client_;
+ scoped_ptr<FakeNfcTagClient> fake_nfc_tag_client_;
scoped_ptr<FakeSessionManagerClient> fake_session_manager_client_;
scoped_ptr<FakeShillDeviceClient> fake_shill_device_client_;
scoped_ptr<FakeShillManagerClient> fake_shill_manager_client_;
diff --git a/chromeos/dbus/fake_nfc_adapter_client.cc b/chromeos/dbus/fake_nfc_adapter_client.cc
index 6ace808..f9b1688 100644
--- a/chromeos/dbus/fake_nfc_adapter_client.cc
+++ b/chromeos/dbus/fake_nfc_adapter_client.cc
@@ -65,19 +65,14 @@ void FakeNfcAdapterClient::StartPollLoop(
const std::string& mode,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) {
- VLOG(1) << "Starting fake NFC Adapter poll loop.";
- VLOG(1) << "Nothing happened.";
+ VLOG(1) << "FakeNfcAdapterClient::StartPollLoop called. Nothing happened.";
}
void FakeNfcAdapterClient::StopPollLoop(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) {
- VLOG(1) << "Stopping fake NFC Adapter poll loop.";
-}
-
-void FakeNfcAdapterClient::OnPropertyChanged(const std::string& property_name) {
- VLOG(1) << "Fake NFC property changed: " << property_name;
+ VLOG(1) << "FakeNfcAdapterClient::StopPollLoop called. Nothing happened.";
}
} // namespace chromeos
diff --git a/chromeos/dbus/fake_nfc_adapter_client.h b/chromeos/dbus/fake_nfc_adapter_client.h
index 97cab97..7c23fc3 100644
--- a/chromeos/dbus/fake_nfc_adapter_client.h
+++ b/chromeos/dbus/fake_nfc_adapter_client.h
@@ -37,8 +37,8 @@ class CHROMEOS_EXPORT FakeNfcAdapterClient : public NfcAdapterClient {
virtual void Init(dbus::Bus* bus) OVERRIDE;
virtual void AddObserver(Observer* observer) OVERRIDE;
virtual void RemoveObserver(Observer* observer) OVERRIDE;
- virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
- OVERRIDE;
+ virtual Properties* GetProperties(
+ const dbus::ObjectPath& object_path) OVERRIDE;
virtual void StartPollLoop(
const dbus::ObjectPath& object_path,
const std::string& mode,
@@ -50,9 +50,6 @@ class CHROMEOS_EXPORT FakeNfcAdapterClient : public NfcAdapterClient {
const nfc_client_helpers::ErrorCallback& error_callback) OVERRIDE;
private:
- // Property callback passed when we create Properties* structures.
- void OnPropertyChanged(const std::string& property_name);
-
DISALLOW_COPY_AND_ASSIGN(FakeNfcAdapterClient);
};
diff --git a/chromeos/dbus/fake_nfc_device_client.cc b/chromeos/dbus/fake_nfc_device_client.cc
new file mode 100644
index 0000000..6150cd9
--- /dev/null
+++ b/chromeos/dbus/fake_nfc_device_client.cc
@@ -0,0 +1,71 @@
+// 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 "chromeos/dbus/fake_nfc_device_client.h"
+
+#include "base/logging.h"
+#include "dbus/object_path.h"
+
+// TODO(armansito): For now, this class doesn't do anything. Implement fake
+// behavior in conjunction with unit tests while implementing the src/device
+// layer.
+
+namespace chromeos {
+
+FakeNfcDeviceClient::Properties::Properties(
+ const PropertyChangedCallback& callback)
+ : NfcDeviceClient::Properties(NULL, callback) {
+}
+
+FakeNfcDeviceClient::Properties::~Properties() {
+}
+
+void FakeNfcDeviceClient::Properties::Get(
+ dbus::PropertyBase* property,
+ dbus::PropertySet::GetCallback callback) {
+ VLOG(1) << "Get " << property->name();
+ callback.Run(false);
+}
+
+void FakeNfcDeviceClient::Properties::GetAll() {
+ VLOG(1) << "GetAll";
+}
+
+void FakeNfcDeviceClient::Properties::Set(
+ dbus::PropertyBase* property,
+ dbus::PropertySet::SetCallback callback) {
+ VLOG(1) << "Set " << property->name();
+ callback.Run(false);
+}
+
+FakeNfcDeviceClient::FakeNfcDeviceClient() {
+ VLOG(1) << "Creating FakeNfcDeviceClient";
+}
+
+FakeNfcDeviceClient::~FakeNfcDeviceClient() {
+}
+
+void FakeNfcDeviceClient::Init(dbus::Bus* bus) {
+}
+
+void FakeNfcDeviceClient::AddObserver(Observer* observer) {
+}
+
+void FakeNfcDeviceClient::RemoveObserver(Observer* observer) {
+}
+
+FakeNfcDeviceClient::Properties*
+FakeNfcDeviceClient::GetProperties(const dbus::ObjectPath& object_path) {
+ return NULL;
+}
+
+void FakeNfcDeviceClient::Push(
+ const dbus::ObjectPath& object_path,
+ const std::map<std::string, std::string>& attributes,
+ const base::Closure& callback,
+ const nfc_client_helpers::ErrorCallback& error_callback) {
+ VLOG(1) << "FakeNfcDeviceClient::Write called. Nothing happened.";
+}
+
+} // namespace chromeos
diff --git a/chromeos/dbus/fake_nfc_device_client.h b/chromeos/dbus/fake_nfc_device_client.h
new file mode 100644
index 0000000..19806c4
--- /dev/null
+++ b/chromeos/dbus/fake_nfc_device_client.h
@@ -0,0 +1,54 @@
+// 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.
+
+#ifndef CHROMEOS_DBUS_FAKE_NFC_DEVICE_CLIENT_H_
+#define CHROMEOS_DBUS_FAKE_NFC_DEVICE_CLIENT_H_
+
+#include "chromeos/chromeos_export.h"
+#include "chromeos/dbus/nfc_client_helpers.h"
+#include "chromeos/dbus/nfc_device_client.h"
+
+namespace chromeos {
+
+// FakeNfcDeviceClient simulates the behavior of the NFC device objects
+// and is used both in test cases in place of a mock and on the Linux desktop.
+// TODO(armansito): For now, this doesn't do anything. Implement fake
+// behavior in conjunction with unit tests while implementing the src/device
+// layer.
+class CHROMEOS_EXPORT FakeNfcDeviceClient : public NfcDeviceClient {
+ public:
+ struct Properties : public NfcDeviceClient::Properties {
+ explicit Properties(const PropertyChangedCallback& callback);
+ virtual ~Properties();
+
+ // dbus::PropertySet overrides.
+ virtual void Get(dbus::PropertyBase* property,
+ dbus::PropertySet::GetCallback callback) OVERRIDE;
+ virtual void GetAll() OVERRIDE;
+ virtual void Set(dbus::PropertyBase* property,
+ dbus::PropertySet::SetCallback callback) OVERRIDE;
+ };
+
+ FakeNfcDeviceClient();
+ virtual ~FakeNfcDeviceClient();
+
+ // NfcDeviceClient overrides.
+ virtual void Init(dbus::Bus* bus) OVERRIDE;
+ virtual void AddObserver(Observer* observer) OVERRIDE;
+ virtual void RemoveObserver(Observer* observer) OVERRIDE;
+ virtual Properties* GetProperties(
+ const dbus::ObjectPath& object_path) OVERRIDE;
+ virtual void Push(
+ const dbus::ObjectPath& object_path,
+ const std::map<std::string, std::string>& attributes,
+ const base::Closure& callback,
+ const nfc_client_helpers::ErrorCallback& error_callback) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FakeNfcDeviceClient);
+};
+
+} // namespace chromeos
+
+#endif // CHROMEOS_DBUS_FAKE_NFC_DEVICE_CLIENT_H_
diff --git a/chromeos/dbus/fake_nfc_tag_client.cc b/chromeos/dbus/fake_nfc_tag_client.cc
new file mode 100644
index 0000000..a146de1
--- /dev/null
+++ b/chromeos/dbus/fake_nfc_tag_client.cc
@@ -0,0 +1,71 @@
+// 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 "chromeos/dbus/fake_nfc_tag_client.h"
+
+#include "base/logging.h"
+#include "dbus/object_path.h"
+
+// TODO(armansito): For now, this class doesn't do anything. Implement fake
+// behavior in conjunction with unit tests while implementing the src/device
+// layer.
+
+namespace chromeos {
+
+FakeNfcTagClient::Properties::Properties(
+ const PropertyChangedCallback& callback)
+ : NfcTagClient::Properties(NULL, callback) {
+}
+
+FakeNfcTagClient::Properties::~Properties() {
+}
+
+void FakeNfcTagClient::Properties::Get(
+ dbus::PropertyBase* property,
+ dbus::PropertySet::GetCallback callback) {
+ VLOG(1) << "Get " << property->name();
+ callback.Run(false);
+}
+
+void FakeNfcTagClient::Properties::GetAll() {
+ VLOG(1) << "GetAll";
+}
+
+void FakeNfcTagClient::Properties::Set(
+ dbus::PropertyBase* property,
+ dbus::PropertySet::SetCallback callback) {
+ VLOG(1) << "Set " << property->name();
+ callback.Run(false);
+}
+
+FakeNfcTagClient::FakeNfcTagClient() {
+ VLOG(1) << "Creating FakeNfcTagClient";
+}
+
+FakeNfcTagClient::~FakeNfcTagClient() {
+}
+
+void FakeNfcTagClient::Init(dbus::Bus* bus) {
+}
+
+void FakeNfcTagClient::AddObserver(Observer* observer) {
+}
+
+void FakeNfcTagClient::RemoveObserver(Observer* observer) {
+}
+
+FakeNfcTagClient::Properties*
+FakeNfcTagClient::GetProperties(const dbus::ObjectPath& object_path) {
+ return NULL;
+}
+
+void FakeNfcTagClient::Write(
+ const dbus::ObjectPath& object_path,
+ const std::map<std::string, std::string>& attributes,
+ const base::Closure& callback,
+ const nfc_client_helpers::ErrorCallback& error_callback) {
+ VLOG(1) << "FakeNfcTagClient::Write called. Nothing happened.";
+}
+
+} // namespace chromeos
diff --git a/chromeos/dbus/fake_nfc_tag_client.h b/chromeos/dbus/fake_nfc_tag_client.h
new file mode 100644
index 0000000..21bf4ff
--- /dev/null
+++ b/chromeos/dbus/fake_nfc_tag_client.h
@@ -0,0 +1,54 @@
+// 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.
+
+#ifndef CHROMEOS_DBUS_FAKE_NFC_TAG_CLIENT_H_
+#define CHROMEOS_DBUS_FAKE_NFC_TAG_CLIENT_H_
+
+#include "chromeos/chromeos_export.h"
+#include "chromeos/dbus/nfc_client_helpers.h"
+#include "chromeos/dbus/nfc_tag_client.h"
+
+namespace chromeos {
+
+// FakeNfcTagClient simulates the behavior of the NFC tag objects
+// and is used both in test cases in place of a mock and on the Linux desktop.
+// TODO(armansito): For now, this doesn't do anything. Implement fake
+// behavior in conjunction with unit tests while implementing the src/device
+// layer.
+class CHROMEOS_EXPORT FakeNfcTagClient : public NfcTagClient {
+ public:
+ struct Properties : public NfcTagClient::Properties {
+ explicit Properties(const PropertyChangedCallback& callback);
+ virtual ~Properties();
+
+ // dbus::PropertySet overrides.
+ virtual void Get(dbus::PropertyBase* property,
+ dbus::PropertySet::GetCallback callback) OVERRIDE;
+ virtual void GetAll() OVERRIDE;
+ virtual void Set(dbus::PropertyBase* property,
+ dbus::PropertySet::SetCallback callback) OVERRIDE;
+ };
+
+ FakeNfcTagClient();
+ virtual ~FakeNfcTagClient();
+
+ // NfcTagClient overrides.
+ virtual void Init(dbus::Bus* bus) OVERRIDE;
+ virtual void AddObserver(Observer* observer) OVERRIDE;
+ virtual void RemoveObserver(Observer* observer) OVERRIDE;
+ virtual Properties* GetProperties(
+ const dbus::ObjectPath& object_path) OVERRIDE;
+ virtual void Write(
+ const dbus::ObjectPath& object_path,
+ const std::map<std::string, std::string>& attributes,
+ const base::Closure& callback,
+ const nfc_client_helpers::ErrorCallback& error_callback) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FakeNfcTagClient);
+};
+
+} // namespace chromeos
+
+#endif // CHROMEOS_DBUS_FAKE_NFC_TAG_CLIENT_H_
diff --git a/chromeos/dbus/mock_dbus_thread_manager.cc b/chromeos/dbus/mock_dbus_thread_manager.cc
index 95901b15..f9dc873 100644
--- a/chromeos/dbus/mock_dbus_thread_manager.cc
+++ b/chromeos/dbus/mock_dbus_thread_manager.cc
@@ -13,7 +13,9 @@
#include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
#include "chromeos/dbus/fake_gsm_sms_client.h"
#include "chromeos/dbus/fake_nfc_adapter_client.h"
+#include "chromeos/dbus/fake_nfc_device_client.h"
#include "chromeos/dbus/fake_nfc_manager_client.h"
+#include "chromeos/dbus/fake_nfc_tag_client.h"
#include "chromeos/dbus/fake_shill_device_client.h"
#include "chromeos/dbus/fake_shill_ipconfig_client.h"
#include "chromeos/dbus/ibus/mock_ibus_client.h"
@@ -60,7 +62,9 @@ MockDBusThreadManager::MockDBusThreadManager()
new FakeBluetoothProfileManagerClient),
fake_gsm_sms_client_(new FakeGsmSMSClient),
fake_nfc_adapter_client_(new FakeNfcAdapterClient()),
+ fake_nfc_device_client_(new FakeNfcDeviceClient()),
fake_nfc_manager_client_(new FakeNfcManagerClient()),
+ fake_nfc_tag_client_(new FakeNfcTagClient()),
fake_shill_device_client_(new FakeShillDeviceClient),
fake_shill_ipconfig_client_(new FakeShillIPConfigClient),
mock_cryptohome_client_(new MockCryptohomeClient),
@@ -82,8 +86,12 @@ MockDBusThreadManager::MockDBusThreadManager()
.WillRepeatedly(Return(fake_bluetooth_profile_manager_client()));
EXPECT_CALL(*this, GetNfcAdapterClient())
.WillRepeatedly(Return(fake_nfc_adapter_client()));
+ EXPECT_CALL(*this, GetNfcDeviceClient())
+ .WillRepeatedly(Return(fake_nfc_device_client()));
EXPECT_CALL(*this, GetNfcManagerClient())
.WillRepeatedly(Return(fake_nfc_manager_client()));
+ EXPECT_CALL(*this, GetNfcTagClient())
+ .WillRepeatedly(Return(fake_nfc_tag_client()));
EXPECT_CALL(*this, GetShillDeviceClient())
.WillRepeatedly(Return(fake_shill_device_client()));
EXPECT_CALL(*this, GetShillIPConfigClient())
diff --git a/chromeos/dbus/mock_dbus_thread_manager.h b/chromeos/dbus/mock_dbus_thread_manager.h
index 5fe6675..12838ad 100644
--- a/chromeos/dbus/mock_dbus_thread_manager.h
+++ b/chromeos/dbus/mock_dbus_thread_manager.h
@@ -27,7 +27,9 @@ class FakeBluetoothInputClient;
class FakeBluetoothProfileManagerClient;
class FakeGsmSMSClient;
class FakeNfcAdapterClient;
+class FakeNfcDeviceClient;
class FakeNfcManagerClient;
+class FakeNfcTagClient;
class FakeShillDeviceClient;
class FakeShillIPConfigClient;
class MockCryptohomeClient;
@@ -74,7 +76,9 @@ class MockDBusThreadManager : public DBusThreadManager {
MOCK_METHOD0(GetIntrospectableClient, IntrospectableClient*(void));
MOCK_METHOD0(GetModemMessagingClient, ModemMessagingClient*(void));
MOCK_METHOD0(GetNfcAdapterClient, NfcAdapterClient*(void));
+ MOCK_METHOD0(GetNfcDeviceClient, NfcDeviceClient*(void));
MOCK_METHOD0(GetNfcManagerClient, NfcManagerClient*(void));
+ MOCK_METHOD0(GetNfcTagClient, NfcTagClient*(void));
MOCK_METHOD0(GetPermissionBrokerClient, PermissionBrokerClient*(void));
MOCK_METHOD0(GetPowerManagerClient, PowerManagerClient*(void));
MOCK_METHOD0(GetPowerPolicyController, PowerPolicyController*(void));
@@ -110,9 +114,15 @@ class MockDBusThreadManager : public DBusThreadManager {
FakeNfcAdapterClient* fake_nfc_adapter_client() {
return fake_nfc_adapter_client_.get();
}
+ FakeNfcDeviceClient* fake_nfc_device_client() {
+ return fake_nfc_device_client_.get();
+ }
FakeNfcManagerClient* fake_nfc_manager_client() {
return fake_nfc_manager_client_.get();
}
+ FakeNfcTagClient* fake_nfc_tag_client() {
+ return fake_nfc_tag_client_.get();
+ }
FakeShillDeviceClient* fake_shill_device_client() {
return fake_shill_device_client_.get();
}
@@ -149,7 +159,9 @@ class MockDBusThreadManager : public DBusThreadManager {
fake_bluetooth_profile_manager_client_;
scoped_ptr<FakeGsmSMSClient> fake_gsm_sms_client_;
scoped_ptr<FakeNfcAdapterClient> fake_nfc_adapter_client_;
+ scoped_ptr<FakeNfcDeviceClient> fake_nfc_device_client_;
scoped_ptr<FakeNfcManagerClient> fake_nfc_manager_client_;
+ scoped_ptr<FakeNfcTagClient> fake_nfc_tag_client_;
scoped_ptr<FakeShillDeviceClient> fake_shill_device_client_;
scoped_ptr<FakeShillIPConfigClient> fake_shill_ipconfig_client_;
scoped_ptr<MockCryptohomeClient> mock_cryptohome_client_;
diff --git a/chromeos/dbus/nfc_adapter_client.cc b/chromeos/dbus/nfc_adapter_client.cc
index 0557dd8..040db2a 100644
--- a/chromeos/dbus/nfc_adapter_client.cc
+++ b/chromeos/dbus/nfc_adapter_client.cc
@@ -162,8 +162,8 @@ class NfcAdapterClientImpl
}
// NfcManagerClient::Observer override.
- virtual void ManagerPropertyChanged(const std::string& property_name)
- OVERRIDE {
+ virtual void ManagerPropertyChanged(
+ const std::string& property_name) OVERRIDE {
NfcManagerClient::Properties* manager_properties =
manager_client_->GetProperties();
if (!initial_adapters_received_ &&
diff --git a/chromeos/dbus/nfc_client_helpers.cc b/chromeos/dbus/nfc_client_helpers.cc
index 12ae6c0..51889e81 100644
--- a/chromeos/dbus/nfc_client_helpers.cc
+++ b/chromeos/dbus/nfc_client_helpers.cc
@@ -75,7 +75,7 @@ bool DBusObjectMap::AddObject(const dbus::ObjectPath& object_path) {
properties->ConnectSignals();
properties->GetAll();
VLOG(1) << "Created proxy for object with Path: " << object_path.value()
- << " Service: " << service_name_;
+ << ", Service: " << service_name_;
ObjectPropertyPair object = std::make_pair(object_proxy, properties);
object_map_[object_path] = object;
return true;
diff --git a/chromeos/dbus/nfc_client_helpers.h b/chromeos/dbus/nfc_client_helpers.h
index d910369..ed344db 100644
--- a/chromeos/dbus/nfc_client_helpers.h
+++ b/chromeos/dbus/nfc_client_helpers.h
@@ -64,6 +64,9 @@ class CHROMEOS_EXPORT DBusObjectMap {
dbus::ObjectProxy* object_proxy) = 0;
};
+ typedef std::pair<dbus::ObjectProxy*, NfcPropertySet*> ObjectPropertyPair;
+ typedef std::map<dbus::ObjectPath, ObjectPropertyPair> ObjectMap;
+
// Constructor takes in the D-Bus service name the proxies belong to and
// the delegate which will be used to construct properties structures.
// |service_name| must be a valid D-Bus service name, and |delegate| cannot
@@ -91,10 +94,10 @@ class CHROMEOS_EXPORT DBusObjectMap {
// remote object with object path |object_path|.
void RemoveObject(const dbus::ObjectPath& object_path);
- private:
- typedef std::pair<dbus::ObjectProxy*, NfcPropertySet*> ObjectPropertyPair;
- typedef std::map<dbus::ObjectPath, ObjectPropertyPair> ObjectMap;
+ // Returns the underlying map.
+ const ObjectMap& object_map() const { return object_map_; }
+ private:
// Returns an instance of ObjectPropertyPair by looking up |object_path| in
// |object_map_|. If no entry is found, returns an instance that contains
// NULL pointers.
diff --git a/chromeos/dbus/nfc_client_unittest.cc b/chromeos/dbus/nfc_client_unittest.cc
index f62fc42..7327d9e 100644
--- a/chromeos/dbus/nfc_client_unittest.cc
+++ b/chromeos/dbus/nfc_client_unittest.cc
@@ -6,7 +6,9 @@
#include "base/message_loop/message_loop.h"
#include "chromeos/dbus/nfc_adapter_client.h"
#include "chromeos/dbus/nfc_client_helpers.h"
+#include "chromeos/dbus/nfc_device_client.h"
#include "chromeos/dbus/nfc_manager_client.h"
+#include "chromeos/dbus/nfc_tag_client.h"
#include "dbus/mock_bus.h"
#include "dbus/mock_object_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -29,6 +31,10 @@ const char kTestServiceName[] = "test.service.name";
const char kTestManagerPath[] = "/test/nfc/manager";
const char kTestAdapterPath0[] = "/test/nfc/adapter0";
const char kTestAdapterPath1[] = "/test/nfc/adapter1";
+const char kTestDevicePath0[] = "/test/nfc/device0";
+const char kTestDevicePath1[] = "/test/nfc/device1";
+const char kTestTagPath0[] = "/test/nfc/tag0";
+const char kTestTagPath1[] = "/test/nfc/tag1";
class MockNfcManagerObserver : public NfcManagerClient::Observer {
public:
@@ -45,6 +51,26 @@ class MockNfcAdapterObserver : public NfcAdapterClient::Observer {
const std::string&));
};
+class MockNfcDeviceObserver : public NfcDeviceClient::Observer {
+ public:
+ MOCK_METHOD2(DeviceFound, void(const dbus::ObjectPath&,
+ const dbus::ObjectPath&));
+ MOCK_METHOD2(DeviceLost, void(const dbus::ObjectPath&,
+ const dbus::ObjectPath&));
+ MOCK_METHOD2(DevicePropertyChanged, void(const dbus::ObjectPath&,
+ const std::string&));
+};
+
+class MockNfcTagObserver : public NfcTagClient::Observer {
+ public:
+ MOCK_METHOD2(TagFound, void(const dbus::ObjectPath&,
+ const dbus::ObjectPath&));
+ MOCK_METHOD2(TagLost, void(const dbus::ObjectPath&,
+ const dbus::ObjectPath&));
+ MOCK_METHOD2(TagPropertyChanged, void(const dbus::ObjectPath&,
+ const std::string&));
+};
+
} // namespace
class NfcClientTest : public testing::Test {
@@ -71,6 +97,22 @@ class NfcClientTest : public testing::Test {
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestAdapterPath1));
+ mock_device0_proxy_ = new dbus::MockObjectProxy(
+ mock_bus_.get(),
+ kTestServiceName,
+ dbus::ObjectPath(kTestDevicePath0));
+ mock_device1_proxy_ = new dbus::MockObjectProxy(
+ mock_bus_.get(),
+ kTestServiceName,
+ dbus::ObjectPath(kTestDevicePath1));
+ mock_tag0_proxy_ = new dbus::MockObjectProxy(
+ mock_bus_.get(),
+ kTestServiceName,
+ dbus::ObjectPath(kTestTagPath0));
+ mock_tag1_proxy_ = new dbus::MockObjectProxy(
+ mock_bus_.get(),
+ kTestServiceName,
+ dbus::ObjectPath(kTestTagPath1));
// Set expectations that use NfcClientTest::OnConnectToSignal when the
// client connect signals on the mock proxies.
@@ -95,6 +137,22 @@ class NfcClientTest : public testing::Test {
GetObjectProxy(nfc_adapter::kNfcAdapterServiceName,
dbus::ObjectPath(kTestAdapterPath1)))
.WillRepeatedly(Return(mock_adapter1_proxy_.get()));
+ EXPECT_CALL(*mock_bus_.get(),
+ GetObjectProxy(nfc_device::kNfcDeviceServiceName,
+ dbus::ObjectPath(kTestDevicePath0)))
+ .WillRepeatedly(Return(mock_device0_proxy_.get()));
+ EXPECT_CALL(*mock_bus_.get(),
+ GetObjectProxy(nfc_device::kNfcDeviceServiceName,
+ dbus::ObjectPath(kTestDevicePath1)))
+ .WillRepeatedly(Return(mock_device1_proxy_.get()));
+ EXPECT_CALL(*mock_bus_.get(),
+ GetObjectProxy(nfc_tag::kNfcTagServiceName,
+ dbus::ObjectPath(kTestTagPath0)))
+ .WillRepeatedly(Return(mock_tag0_proxy_.get()));
+ EXPECT_CALL(*mock_bus_.get(),
+ GetObjectProxy(nfc_tag::kNfcTagServiceName,
+ dbus::ObjectPath(kTestTagPath1)))
+ .WillRepeatedly(Return(mock_tag1_proxy_.get()));
// ShutdownAndBlock will be called in TearDown.
EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return());
@@ -105,21 +163,35 @@ class NfcClientTest : public testing::Test {
adapter_client_.reset(
NfcAdapterClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION,
manager_client_.get()));
+ device_client_.reset(
+ NfcDeviceClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION,
+ adapter_client_.get()));
+ tag_client_.reset(
+ NfcTagClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION,
+ adapter_client_.get()));
manager_client_->Init(mock_bus_.get());
adapter_client_->Init(mock_bus_.get());
+ device_client_->Init(mock_bus_.get());
+ tag_client_->Init(mock_bus_.get());
manager_client_->AddObserver(&mock_manager_observer_);
adapter_client_->AddObserver(&mock_adapter_observer_);
+ device_client_->AddObserver(&mock_device_observer_);
+ tag_client_->AddObserver(&mock_tag_observer_);
message_loop_.RunUntilIdle();
}
virtual void TearDown() OVERRIDE {
+ tag_client_->RemoveObserver(&mock_tag_observer_);
+ device_client_->RemoveObserver(&mock_device_observer_);
adapter_client_->RemoveObserver(&mock_adapter_observer_);
manager_client_->RemoveObserver(&mock_manager_observer_);
mock_bus_->ShutdownAndBlock();
}
- void SendManagerAdapterAddedSignal(const dbus::ObjectPath& object_path) {
+ void SimulateAdapterAdded(const dbus::ObjectPath& object_path) {
+ EXPECT_CALL(mock_manager_observer_, AdapterAdded(object_path));
+ EXPECT_CALL(mock_adapter_observer_, AdapterAdded(object_path));
dbus::Signal signal(nfc_manager::kNfcManagerInterface,
nfc_manager::kAdapterAddedSignal);
dbus::MessageWriter writer(&signal);
@@ -128,13 +200,64 @@ class NfcClientTest : public testing::Test {
manager_adapter_added_signal_callback_.Run(&signal);
}
- void SendManagerAdapterRemovedSignal(const dbus::ObjectPath& object_path) {
+ void SimulateAdapterRemoved(const dbus::ObjectPath& object_path) {
+ EXPECT_CALL(mock_manager_observer_, AdapterRemoved(object_path));
+ EXPECT_CALL(mock_adapter_observer_, AdapterRemoved(object_path));
dbus::Signal signal(nfc_manager::kNfcManagerInterface,
nfc_manager::kAdapterRemovedSignal);
dbus::MessageWriter writer(&signal);
writer.AppendObjectPath(object_path);
ASSERT_FALSE(manager_adapter_removed_signal_callback_.is_null());
manager_adapter_removed_signal_callback_.Run(&signal);
+ Mock::VerifyAndClearExpectations(&mock_manager_observer_);
+ Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
+ }
+
+ void SimulateTagsChanged(const std::vector<dbus::ObjectPath>& tag_paths,
+ const dbus::ObjectPath& adapter_path) {
+ NfcAdapterClient::Properties* properties =
+ adapter_client_->GetProperties(adapter_path);
+ ASSERT_TRUE(properties);
+ EXPECT_CALL(mock_adapter_observer_,
+ AdapterPropertyChanged(adapter_path,
+ nfc_adapter::kTagsProperty));
+ SendArrayPropertyChangedSignal(
+ properties,
+ nfc_adapter::kNfcAdapterInterface,
+ nfc_adapter::kTagsProperty,
+ tag_paths);
+ Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
+ }
+
+ void SimulateDevicesChanged(const std::vector<dbus::ObjectPath>& device_paths,
+ const dbus::ObjectPath& adapter_path) {
+ NfcAdapterClient::Properties* properties =
+ adapter_client_->GetProperties(adapter_path);
+ ASSERT_TRUE(properties);
+ EXPECT_CALL(mock_adapter_observer_,
+ AdapterPropertyChanged(adapter_path,
+ nfc_adapter::kDevicesProperty));
+ SendArrayPropertyChangedSignal(
+ properties,
+ nfc_adapter::kNfcAdapterInterface,
+ nfc_adapter::kDevicesProperty,
+ device_paths);
+ Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
+ }
+
+ void SendArrayPropertyChangedSignal(
+ dbus::PropertySet* properties,
+ const std::string& interface,
+ const std::string& property_name,
+ std::vector<dbus::ObjectPath> object_paths) {
+ dbus::Signal signal(interface, nfc_common::kPropertyChangedSignal);
+ dbus::MessageWriter writer(&signal);
+ writer.AppendString(property_name);
+ dbus::MessageWriter variant_writer(NULL);
+ writer.OpenVariant("ao", &variant_writer);
+ variant_writer.AppendArrayOfObjectPaths(object_paths);
+ writer.CloseContainer(&variant_writer);
+ properties->ChangedReceived(&signal);
}
MOCK_METHOD0(SuccessCallback, void(void));
@@ -142,6 +265,14 @@ class NfcClientTest : public testing::Test {
const std::string& error_message));
protected:
+ // The mock object proxies.
+ scoped_refptr<dbus::MockObjectProxy> mock_manager_proxy_;
+ scoped_refptr<dbus::MockObjectProxy> mock_adapter0_proxy_;
+ scoped_refptr<dbus::MockObjectProxy> mock_adapter1_proxy_;
+ scoped_refptr<dbus::MockObjectProxy> mock_device0_proxy_;
+ scoped_refptr<dbus::MockObjectProxy> mock_device1_proxy_;
+ scoped_refptr<dbus::MockObjectProxy> mock_tag0_proxy_;
+ scoped_refptr<dbus::MockObjectProxy> mock_tag1_proxy_;
// The mock bus.
scoped_refptr<dbus::MockBus> mock_bus_;
// A message loop to emulate asynchronous behavior.
@@ -151,13 +282,13 @@ class NfcClientTest : public testing::Test {
// The D-Bus client objects under test.
scoped_ptr<NfcManagerClient> manager_client_;
scoped_ptr<NfcAdapterClient> adapter_client_;
+ scoped_ptr<NfcDeviceClient> device_client_;
+ scoped_ptr<NfcTagClient> tag_client_;
// Mock observers.
MockNfcManagerObserver mock_manager_observer_;
MockNfcAdapterObserver mock_adapter_observer_;
- // The mock object proxies.
- scoped_refptr<dbus::MockObjectProxy> mock_manager_proxy_;
- scoped_refptr<dbus::MockObjectProxy> mock_adapter0_proxy_;
- scoped_refptr<dbus::MockObjectProxy> mock_adapter1_proxy_;
+ MockNfcDeviceObserver mock_device_observer_;
+ MockNfcTagObserver mock_tag_observer_;
// The signal callbacks used to simulate asychronous signals.
dbus::ObjectProxy::SignalCallback manager_adapter_added_signal_callback_;
dbus::ObjectProxy::SignalCallback manager_adapter_removed_signal_callback_;
@@ -197,12 +328,7 @@ TEST_F(NfcClientTest, AdaptersAddedAndRemoved) {
Mock::VerifyAndClearExpectations(this);
// Add adapter 0.
- EXPECT_CALL(mock_manager_observer_,
- AdapterAdded(dbus::ObjectPath(kTestAdapterPath0)));
- EXPECT_CALL(mock_adapter_observer_,
- AdapterAdded(dbus::ObjectPath(kTestAdapterPath0)));
- SendManagerAdapterAddedSignal(dbus::ObjectPath(kTestAdapterPath0));
- Mock::VerifyAndClearExpectations(this);
+ SimulateAdapterAdded(dbus::ObjectPath(kTestAdapterPath0));
// Invoking methods should succeed on adapter 0 but fail on adapter 1.
EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
@@ -211,24 +337,21 @@ TEST_F(NfcClientTest, AdaptersAddedAndRemoved) {
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
- Mock::VerifyAndClearExpectations(this);
-
+ Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_);
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath1),
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_);
// Add adapter 1.
- EXPECT_CALL(mock_manager_observer_,
- AdapterAdded(dbus::ObjectPath(kTestAdapterPath1)));
- EXPECT_CALL(mock_adapter_observer_,
- AdapterAdded(dbus::ObjectPath(kTestAdapterPath1)));
- SendManagerAdapterAddedSignal(dbus::ObjectPath(kTestAdapterPath1));
- Mock::VerifyAndClearExpectations(this);
+ SimulateAdapterAdded(dbus::ObjectPath(kTestAdapterPath1));
// Invoking methods should succeed on both adapters.
EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
@@ -243,19 +366,17 @@ TEST_F(NfcClientTest, AdaptersAddedAndRemoved) {
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
- Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_);
+ Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_);
// Remove adapter 0.
- EXPECT_CALL(mock_manager_observer_,
- AdapterRemoved(dbus::ObjectPath(kTestAdapterPath0)));
- EXPECT_CALL(mock_adapter_observer_,
- AdapterRemoved(dbus::ObjectPath(kTestAdapterPath0)));
- SendManagerAdapterRemovedSignal(dbus::ObjectPath(kTestAdapterPath0));
- Mock::VerifyAndClearExpectations(this);
+ SimulateAdapterRemoved(dbus::ObjectPath(kTestAdapterPath0));
// Invoking methods should succeed on adapter 1 but fail on adapter 0.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath0),
nfc_adapter::kModeInitiator,
@@ -269,20 +390,20 @@ TEST_F(NfcClientTest, AdaptersAddedAndRemoved) {
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
- Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_);
+ Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_);
// Remove adapter 1.
- EXPECT_CALL(mock_manager_observer_,
- AdapterRemoved(dbus::ObjectPath(kTestAdapterPath1)));
- EXPECT_CALL(mock_adapter_observer_,
- AdapterRemoved(dbus::ObjectPath(kTestAdapterPath1)));
- SendManagerAdapterRemovedSignal(dbus::ObjectPath(kTestAdapterPath1));
- Mock::VerifyAndClearExpectations(this);
+ SimulateAdapterRemoved(dbus::ObjectPath(kTestAdapterPath1));
// Invoking methods should fail on both adapters.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _))
.Times(2);
+ EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);;
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath0),
nfc_adapter::kModeInitiator,
@@ -295,4 +416,260 @@ TEST_F(NfcClientTest, AdaptersAddedAndRemoved) {
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
}
+// Tests that when tags are added and removed through an adapter, all
+// observers are notified and the proxies are created and removed
+// accordingly.
+TEST_F(NfcClientTest, TagsAddedAndRemoved) {
+ // Invoking methods on tags that haven't been added should fail.
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ NfcTagClient::RecordAttributes write_data;
+ write_data[nfc_record::kTypeProperty] = nfc_record::kTypeText;
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(this);
+
+ // Add adapter 0.
+ SimulateAdapterAdded(dbus::ObjectPath(kTestAdapterPath0));
+
+ // Add tag 0.
+ std::vector<dbus::ObjectPath> tag_paths;
+ tag_paths.push_back(dbus::ObjectPath(kTestTagPath0));
+ EXPECT_CALL(mock_tag_observer_,
+ TagFound(dbus::ObjectPath(kTestTagPath0),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_tag_observer_);
+
+ // Invoking methods should succeed on tag 0 but fail on tag 1.
+ EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(&mock_tag0_proxy_);
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_tag1_proxy_);
+
+ // Add tag 1.
+ tag_paths.push_back(dbus::ObjectPath(kTestTagPath1));
+ EXPECT_CALL(mock_tag_observer_,
+ TagFound(dbus::ObjectPath(kTestTagPath1),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_tag_observer_);
+
+ // Invoking methods should succeed on both tags.
+ EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(&mock_tag0_proxy_);
+ Mock::VerifyAndClearExpectations(&mock_tag1_proxy_);
+
+ // Remove tag 0.
+ tag_paths.erase(tag_paths.begin());
+ EXPECT_CALL(mock_tag_observer_,
+ TagLost(dbus::ObjectPath(kTestTagPath0),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_tag_observer_);
+
+ // Invoking methods should succeed on tag 1 but fail on tag 0.
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_tag0_proxy_);
+ EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(&mock_tag1_proxy_);
+
+ // Remove tag 1.
+ tag_paths.clear();
+ EXPECT_CALL(mock_tag_observer_,
+ TagLost(dbus::ObjectPath(kTestTagPath1),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_tag_observer_);
+
+ // Invoking methods should fail on both tags.
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _))
+ .Times(2);
+ EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+}
+
+// Tests that when devices are added and removed through an adapter, all
+// observers are notified and the proxies are created and removed
+// accordingly.
+TEST_F(NfcClientTest, DevicesAddedAndRemoved) {
+ // Invoking methods on devices that haven't been added should fail.
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ NfcDeviceClient::RecordAttributes write_data;
+ write_data[nfc_record::kTypeProperty] = nfc_record::kTypeText;
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(this);
+
+ // Add adapter 0.
+ SimulateAdapterAdded(dbus::ObjectPath(kTestAdapterPath0));
+
+ // Add device 0.
+ std::vector<dbus::ObjectPath> device_paths;
+ device_paths.push_back(dbus::ObjectPath(kTestDevicePath0));
+ EXPECT_CALL(mock_device_observer_,
+ DeviceFound(dbus::ObjectPath(kTestDevicePath0),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_device_observer_);
+
+ // Invoking methods should succeed on device 0 but fail on device 1.
+ EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(&mock_device0_proxy_);
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_device1_proxy_);
+
+ // Add device 1.
+ device_paths.push_back(dbus::ObjectPath(kTestDevicePath1));
+ EXPECT_CALL(mock_device_observer_,
+ DeviceFound(dbus::ObjectPath(kTestDevicePath1),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_device_observer_);
+
+ // Invoking methods should succeed on both devices.
+ EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(&mock_device0_proxy_);
+ Mock::VerifyAndClearExpectations(&mock_device1_proxy_);
+
+ // Remove device 0.
+ device_paths.erase(device_paths.begin());
+ EXPECT_CALL(mock_device_observer_,
+ DeviceLost(dbus::ObjectPath(kTestDevicePath0),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_device_observer_);
+
+ // Invoking methods should succeed on device 1 but fail on device 0.
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
+ EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(this);
+ Mock::VerifyAndClearExpectations(&mock_device0_proxy_);
+ EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ Mock::VerifyAndClearExpectations(&mock_device1_proxy_);
+
+ // Remove device 1.
+ device_paths.clear();
+ EXPECT_CALL(mock_device_observer_,
+ DeviceLost(dbus::ObjectPath(kTestDevicePath1),
+ dbus::ObjectPath(kTestAdapterPath0)));
+ SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0));
+ Mock::VerifyAndClearExpectations(&mock_device_observer_);
+
+ // Invoking methods should fail on both devices.
+ EXPECT_CALL(*this,
+ ErrorCallback(nfc_client_helpers::kUnknownObjectError, _))
+ .Times(2);
+ EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
+ .Times(0);
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+ device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data,
+ base::Bind(&NfcClientTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcClientTest::ErrorCallback,
+ base::Unretained(this)));
+}
+
} // namespace chromeos
diff --git a/chromeos/dbus/nfc_device_client.cc b/chromeos/dbus/nfc_device_client.cc
new file mode 100644
index 0000000..83076d2
--- /dev/null
+++ b/chromeos/dbus/nfc_device_client.cc
@@ -0,0 +1,248 @@
+// 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 "chromeos/dbus/nfc_device_client.h"
+
+#include <set>
+
+#include "base/bind.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
+#include "chromeos/dbus/fake_nfc_device_client.h"
+#include "chromeos/dbus/nfc_adapter_client.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+using chromeos::nfc_client_helpers::DBusObjectMap;
+
+namespace chromeos {
+
+namespace {
+
+typedef std::vector<dbus::ObjectPath> ObjectPathVector;
+
+} // namespace
+
+NfcDeviceClient::Properties::Properties(
+ dbus::ObjectProxy* object_proxy,
+ const PropertyChangedCallback& callback)
+ : NfcPropertySet(object_proxy,
+ nfc_device::kNfcDeviceInterface,
+ callback) {
+ RegisterProperty(nfc_device::kRecordsProperty, &records);
+}
+
+NfcDeviceClient::Properties::~Properties() {
+}
+
+// The NfcDeviceClient implementation used in production.
+class NfcDeviceClientImpl : public NfcDeviceClient,
+ public NfcAdapterClient::Observer,
+ public DBusObjectMap::Delegate {
+ public:
+ explicit NfcDeviceClientImpl(NfcAdapterClient* adapter_client)
+ : bus_(NULL),
+ adapter_client_(adapter_client),
+ weak_ptr_factory_(this) {
+ DCHECK(adapter_client);
+ }
+
+ virtual ~NfcDeviceClientImpl() {
+ adapter_client_->RemoveObserver(this);
+ }
+
+ // NfcDeviceClient override.
+ virtual void AddObserver(NfcDeviceClient::Observer* observer) OVERRIDE {
+ DCHECK(observer);
+ observers_.AddObserver(observer);
+ }
+
+ // NfcDeviceClient override.
+ virtual void RemoveObserver(NfcDeviceClient::Observer* observer) OVERRIDE {
+ DCHECK(observer);
+ observers_.RemoveObserver(observer);
+ }
+
+ // NfcDeviceClient override.
+ virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
+ OVERRIDE {
+ return static_cast<Properties*>(
+ object_map_->GetObjectProperties(object_path));
+ }
+
+ // NfcDeviceClient override.
+ virtual void Push(
+ const dbus::ObjectPath& object_path,
+ const RecordAttributes& attributes,
+ const base::Closure& callback,
+ const nfc_client_helpers::ErrorCallback& error_callback) OVERRIDE {
+ dbus::ObjectProxy* object_proxy = object_map_->GetObjectProxy(object_path);
+ if (!object_proxy) {
+ std::string error_message =
+ base::StringPrintf(
+ "NFC device with object path \"%s\" does not exist.",
+ object_path.value().c_str());
+ LOG(ERROR) << error_message;
+ error_callback.Run(nfc_client_helpers::kUnknownObjectError,
+ error_message);
+ return;
+ }
+
+ // |attributes| should not be empty.
+ if (attributes.empty()) {
+ std::string error_message =
+ "Cannot push data to device with empty arguments.";
+ LOG(ERROR) << error_message;
+ error_callback.Run(nfc_error::kInvalidArguments, error_message);
+ return;
+ }
+
+ // Create the arguments.
+ dbus::MethodCall method_call(nfc_device::kNfcDeviceInterface,
+ nfc_device::kPush);
+ dbus::MessageWriter writer(&method_call);
+ dbus::MessageWriter array_writer(NULL);
+ dbus::MessageWriter dict_entry_writer(NULL);
+ writer.OpenArray("{sv}", &array_writer);
+ for (RecordAttributes::const_iterator iter = attributes.begin();
+ iter != attributes.end(); ++iter) {
+ array_writer.OpenDictEntry(&dict_entry_writer);
+ dict_entry_writer.AppendString(iter->first);
+ dict_entry_writer.AppendVariantOfString(iter->second);
+ array_writer.CloseContainer(&dict_entry_writer);
+ }
+ writer.CloseContainer(&array_writer);
+
+ object_proxy->CallMethodWithErrorCallback(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&nfc_client_helpers::OnSuccess, callback),
+ base::Bind(&nfc_client_helpers::OnError, error_callback));
+ }
+
+ protected:
+ // DBusClient override.
+ virtual void Init(dbus::Bus* bus) OVERRIDE {
+ VLOG(1) << "Creating NfcDeviceClientImpl";
+ DCHECK(bus);
+ bus_ = bus;
+ object_map_.reset(new DBusObjectMap(
+ nfc_device::kNfcDeviceServiceName, this, bus));
+ DCHECK(adapter_client_);
+ adapter_client_->AddObserver(this);
+ }
+
+ // NfcAdapterClient::Observer override.
+ virtual void AdapterPropertyChanged(
+ const dbus::ObjectPath& object_path,
+ const std::string& property_name) OVERRIDE {
+ DCHECK(adapter_client_);
+ NfcAdapterClient::Properties *adapter_properties =
+ adapter_client_->GetProperties(object_path);
+
+ // Ignore changes to properties other than "Devices".
+ if (property_name != adapter_properties->devices.name())
+ return;
+
+ VLOG(1) << "NFC devices changed.";
+
+ // Add all the new devices.
+ const ObjectPathVector& received_devices =
+ adapter_properties->devices.value();
+ for (ObjectPathVector::const_iterator iter = received_devices.begin();
+ iter != received_devices.end(); ++iter) {
+ const dbus::ObjectPath &device_path = *iter;
+ if (object_map_->AddObject(device_path)) {
+ VLOG(1) << "Found NFC device: " << device_path.value();
+ FOR_EACH_OBSERVER(NfcDeviceClient::Observer, observers_,
+ DeviceFound(device_path, object_path));
+ }
+ }
+
+ // Remove all devices that were lost.
+ const DBusObjectMap::ObjectMap& known_devices =
+ object_map_->object_map();
+ std::set<dbus::ObjectPath> devices_set(received_devices.begin(),
+ received_devices.end());
+ DBusObjectMap::ObjectMap::const_iterator iter = known_devices.begin();
+ while (iter != known_devices.end()) {
+ // Make a copy here, as the iterator will be invalidated by
+ // DBusObjectMap::RemoveObject below, but |device_path| is needed to
+ // notify observers right after. We want to make sure that we notify
+ // the observers AFTER we remove the object, so that method calls
+ // to the removed object paths in observer implementations fail
+ // gracefully.
+ dbus::ObjectPath device_path = iter->first;
+ ++iter;
+ if (!ContainsKey(devices_set, device_path)) {
+ VLOG(1) << "Lost NFC device: " << device_path.value();
+ object_map_->RemoveObject(device_path);
+ FOR_EACH_OBSERVER(NfcDeviceClient::Observer, observers_,
+ DeviceLost(device_path, object_path));
+ }
+ }
+ }
+
+ // nfc_client_helpers::DBusObjectMap::Delegate override.
+ virtual NfcPropertySet* CreateProperties(
+ dbus::ObjectProxy* object_proxy) OVERRIDE {
+ return new Properties(
+ object_proxy,
+ base::Bind(&NfcDeviceClientImpl::OnPropertyChanged,
+ weak_ptr_factory_.GetWeakPtr(),
+ object_proxy->object_path()));
+ }
+
+ // Called by NfcPropertySet when a property value is changed, either by
+ // result of a signal or response to a GetAll() or Get() call.
+ void OnPropertyChanged(const dbus::ObjectPath& object_path,
+ const std::string& property_name) {
+ VLOG(1) << "Device property changed; Path: " << object_path.value()
+ << " Property: " << property_name;
+ FOR_EACH_OBSERVER(NfcDeviceClient::Observer, observers_,
+ DevicePropertyChanged(object_path, property_name));
+ }
+
+ private:
+ // We maintain a pointer to the bus to be able to request proxies for
+ // new NFC devices that appear.
+ dbus::Bus* bus_;
+
+ // Mapping from object paths to object proxies and properties structures that
+ // were already created by us.
+ scoped_ptr<DBusObjectMap> object_map_;
+
+ // The manager client that we listen to events notifications from.
+ NfcAdapterClient* adapter_client_;
+
+ // List of observers interested in event notifications.
+ ObserverList<NfcDeviceClient::Observer> observers_;
+
+ // Weak pointer factory for generating 'this' pointers that might live longer
+ // than we do.
+ // Note: This should remain the last member so it'll be destroyed and
+ // invalidate its weak pointers before any other members are destroyed.
+ base::WeakPtrFactory<NfcDeviceClientImpl> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(NfcDeviceClientImpl);
+};
+
+NfcDeviceClient::NfcDeviceClient() {
+}
+
+NfcDeviceClient::~NfcDeviceClient() {
+}
+
+NfcDeviceClient* NfcDeviceClient::Create(DBusClientImplementationType type,
+ NfcAdapterClient* adapter_client) {
+ if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
+ return new NfcDeviceClientImpl(adapter_client);
+ DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
+ return new FakeNfcDeviceClient();
+}
+
+} // namespace chromeos
diff --git a/chromeos/dbus/nfc_device_client.h b/chromeos/dbus/nfc_device_client.h
new file mode 100644
index 0000000..bbabf7e
--- /dev/null
+++ b/chromeos/dbus/nfc_device_client.h
@@ -0,0 +1,119 @@
+// 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.
+
+#ifndef CHROMEOS_DBUS_NFC_DEVICE_CLIENT_H_
+#define CHROMEOS_DBUS_NFC_DEVICE_CLIENT_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "chromeos/chromeos_export.h"
+#include "chromeos/dbus/dbus_client.h"
+#include "chromeos/dbus/dbus_client_implementation_type.h"
+#include "chromeos/dbus/nfc_client_helpers.h"
+#include "chromeos/dbus/nfc_property_set.h"
+#include "dbus/object_path.h"
+#include "dbus/object_proxy.h"
+#include "dbus/property.h"
+
+namespace chromeos {
+
+class NfcAdapterClient;
+
+// NfcDeviceClient is used to communicate with objects representing remote NFC
+// adapters that can be communicated with.
+class CHROMEOS_EXPORT NfcDeviceClient : public DBusClient {
+ public:
+ // Structure of properties associated with an NFC device.
+ struct Properties : public NfcPropertySet {
+ // List of object paths for NDEF records associated with the NFC device.
+ dbus::Property<std::vector<dbus::ObjectPath> > records;
+
+ Properties(dbus::ObjectProxy* object_proxy,
+ const PropertyChangedCallback& callback);
+ virtual ~Properties();
+ };
+
+ // Interface for observing changes from a remote NFC device.
+ class Observer {
+ public:
+ virtual ~Observer() {}
+
+ // Called when a remote NFC device with the object |object_path| is added
+ // to the set of known devices associated with the adapter with object path
+ // |adapter_path|.
+ virtual void DeviceFound(const dbus::ObjectPath& object_path,
+ const dbus::ObjectPath& adapter_path) {}
+
+ // Called when a remote NFC device with the object path |object_path| is
+ // removed from the set of known devices associated with the adapter with
+ // object path |adapter_path|.
+ virtual void DeviceLost(const dbus::ObjectPath& object_path,
+ const dbus::ObjectPath& adapter_path) {}
+
+ // Called when the device property with the name |property_name| on device
+ // with object path |object_path| has acquired a new value.
+ virtual void DevicePropertyChanged(const dbus::ObjectPath& object_path,
+ const std::string& property_name) {}
+ };
+
+ // TODO(armansito): Move this typedef to the NFC Record client, once
+ // implemented.
+ typedef std::map<std::string, std::string> RecordAttributes;
+
+ virtual ~NfcDeviceClient();
+
+ // Adds and removes observers for events on all remote NFC devices. Check the
+ // |object_path| parameter of observer methods to determine which device is
+ // issuing the event.
+ virtual void AddObserver(Observer* observer) = 0;
+ virtual void RemoveObserver(Observer* observer) = 0;
+
+ // Obtain the properties for the NFC device with object path |object_path|;
+ // any values should be copied if needed.
+ virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0;
+
+ // Creates an NDEF record for the NFC device with object path |object_path|
+ // using the parameters in |attributes|. |attributes| is a dictionary,
+ // containing the NFC Record properties which will be assigned to the
+ // resulting record object and pushed to the device. The properties are
+ // defined by the NFC Record interface (see namespace "nfc_record" in
+ // third_party/cros_system_api/dbus/service_constants.h and
+ // NfcRecordClient::Properties). |attributes| should at least contain a
+ // "Type" plus any other properties associated with that type. For example:
+ //
+ // {
+ // "Type": "Text",
+ // "Encoding": "UTF-8",
+ // "Language": "en",
+ // "Representation": "Chrome OS rulez!"
+ // },
+ // {
+ // "Type": "URI",
+ // "URI": "http://www.chromium.org"
+ // },
+ // etc.
+ virtual void Push(
+ const dbus::ObjectPath& object_path,
+ const RecordAttributes& attributes,
+ const base::Closure& callback,
+ const nfc_client_helpers::ErrorCallback& error_callback) = 0;
+
+ // Creates the instance.
+ static NfcDeviceClient* Create(DBusClientImplementationType type,
+ NfcAdapterClient* adapter_client);
+
+ protected:
+ friend class NfcClientTest;
+
+ NfcDeviceClient();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NfcDeviceClient);
+};
+
+} // namespace chromeos
+
+#endif // CHROMEOS_DBUS_NFC_DEVICE_CLIENT_H_
diff --git a/chromeos/dbus/nfc_tag_client.cc b/chromeos/dbus/nfc_tag_client.cc
new file mode 100644
index 0000000..37f3c0a
--- /dev/null
+++ b/chromeos/dbus/nfc_tag_client.cc
@@ -0,0 +1,250 @@
+// 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 "chromeos/dbus/nfc_tag_client.h"
+
+#include <set>
+
+#include "base/bind.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
+#include "chromeos/dbus/fake_nfc_tag_client.h"
+#include "chromeos/dbus/nfc_adapter_client.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+using chromeos::nfc_client_helpers::DBusObjectMap;
+
+namespace chromeos {
+
+namespace {
+
+typedef std::vector<dbus::ObjectPath> ObjectPathVector;
+
+} // namespace
+
+NfcTagClient::Properties::Properties(
+ dbus::ObjectProxy* object_proxy,
+ const PropertyChangedCallback& callback)
+ : NfcPropertySet(object_proxy,
+ nfc_tag::kNfcTagInterface,
+ callback) {
+ RegisterProperty(nfc_tag::kTypeProperty, &type);
+ RegisterProperty(nfc_tag::kProtocolProperty, &protocol);
+ RegisterProperty(nfc_tag::kRecordsProperty, &records);
+ RegisterProperty(nfc_tag::kReadOnlyProperty, &read_only);
+}
+
+NfcTagClient::Properties::~Properties() {
+}
+
+// The NfcTagClient implementation used in production.
+class NfcTagClientImpl : public NfcTagClient,
+ public NfcAdapterClient::Observer,
+ public nfc_client_helpers::DBusObjectMap::Delegate {
+ public:
+ explicit NfcTagClientImpl(NfcAdapterClient* adapter_client)
+ : bus_(NULL),
+ adapter_client_(adapter_client),
+ weak_ptr_factory_(this) {
+ DCHECK(adapter_client);
+ }
+
+ virtual ~NfcTagClientImpl() {
+ adapter_client_->RemoveObserver(this);
+ }
+
+ // NfcTagClient override.
+ virtual void AddObserver(NfcTagClient::Observer* observer) OVERRIDE {
+ DCHECK(observer);
+ observers_.AddObserver(observer);
+ }
+
+ // NfcTagClient override.
+ virtual void RemoveObserver(NfcTagClient::Observer* observer) OVERRIDE {
+ DCHECK(observer);
+ observers_.RemoveObserver(observer);
+ }
+
+ // NfcTagClient override.
+ virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
+ OVERRIDE {
+ return static_cast<Properties*>(
+ object_map_->GetObjectProperties(object_path));
+ }
+
+ // NfcTagClient override.
+ virtual void Write(
+ const dbus::ObjectPath& object_path,
+ const RecordAttributes& attributes,
+ const base::Closure& callback,
+ const nfc_client_helpers::ErrorCallback& error_callback) OVERRIDE {
+ dbus::ObjectProxy* object_proxy = object_map_->GetObjectProxy(object_path);
+ if (!object_proxy) {
+ std::string error_message =
+ base::StringPrintf("NFC tag with object path \"%s\" does not exist.",
+ object_path.value().c_str());
+ LOG(ERROR) << error_message;
+ error_callback.Run(nfc_client_helpers::kUnknownObjectError,
+ error_message);
+ return;
+ }
+
+ // |attributes| should not be empty.
+ if (attributes.empty()) {
+ std::string error_message =
+ "Cannot write data to tag with empty arguments.";
+ LOG(ERROR) << error_message;
+ error_callback.Run(nfc_error::kInvalidArguments, error_message);
+ return;
+ }
+
+ // Create the arguments.
+ dbus::MethodCall method_call(nfc_tag::kNfcTagInterface, nfc_tag::kWrite);
+ dbus::MessageWriter writer(&method_call);
+ dbus::MessageWriter array_writer(NULL);
+ dbus::MessageWriter dict_entry_writer(NULL);
+ writer.OpenArray("{sv}", &array_writer);
+ for (RecordAttributes::const_iterator iter = attributes.begin();
+ iter != attributes.end(); ++iter) {
+ array_writer.OpenDictEntry(&dict_entry_writer);
+ dict_entry_writer.AppendString(iter->first);
+ dict_entry_writer.AppendVariantOfString(iter->second);
+ array_writer.CloseContainer(&dict_entry_writer);
+ }
+ writer.CloseContainer(&array_writer);
+
+ object_proxy->CallMethodWithErrorCallback(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&nfc_client_helpers::OnSuccess, callback),
+ base::Bind(&nfc_client_helpers::OnError, error_callback));
+ }
+
+ protected:
+ // DBusClient override.
+ virtual void Init(dbus::Bus* bus) OVERRIDE {
+ VLOG(1) << "Creating NfcTagClientImpl";
+ DCHECK(bus);
+ bus_ = bus;
+ object_map_.reset(new nfc_client_helpers::DBusObjectMap(
+ nfc_tag::kNfcTagServiceName, this, bus));
+ DCHECK(adapter_client_);
+ adapter_client_->AddObserver(this);
+ }
+
+ private:
+ // NfcAdapterClient::Observer override.
+ virtual void AdapterPropertyChanged(
+ const dbus::ObjectPath& object_path,
+ const std::string& property_name) OVERRIDE {
+ // Update the tag proxies.
+ DCHECK(adapter_client_);
+ NfcAdapterClient::Properties *adapter_properties =
+ adapter_client_->GetProperties(object_path);
+
+ // Ignore changes to properties other than "Tags".
+ if (property_name != adapter_properties->tags.name())
+ return;
+
+ VLOG(1) << "NFC tags changed.";
+
+ // Add all the new tags.
+ const ObjectPathVector& received_tags =
+ adapter_properties->tags.value();
+ for (ObjectPathVector::const_iterator iter = received_tags.begin();
+ iter != received_tags.end(); ++iter) {
+ const dbus::ObjectPath &tag_path = *iter;
+ if (object_map_->AddObject(tag_path)) {
+ VLOG(1) << "Found NFC tag: " << tag_path.value();
+ FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
+ TagFound(tag_path, object_path));
+ }
+ }
+
+ // Remove all tags that were lost.
+ const DBusObjectMap::ObjectMap& known_tags =
+ object_map_->object_map();
+ std::set<dbus::ObjectPath> tags_set(received_tags.begin(),
+ received_tags.end());
+ DBusObjectMap::ObjectMap::const_iterator iter = known_tags.begin();
+ while (iter != known_tags.end()) {
+ // Make a copy here, as the iterator will be invalidated by
+ // DBusObjectMap::RemoveObject below, but |device_path| is needed to
+ // notify observers right after. We want to make sure that we notify
+ // the observers AFTER we remove the object, so that method calls
+ // to the removed object paths in observer implementations fail
+ // gracefully.
+ dbus::ObjectPath tag_path = iter->first;
+ ++iter;
+ if (!ContainsKey(tags_set, tag_path)) {
+ VLOG(1) << "Lost NFC tag: " << tag_path.value();
+ object_map_->RemoveObject(tag_path);
+ FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
+ TagLost(tag_path, object_path));
+ }
+ }
+ }
+
+ // nfc_client_helpers::DBusObjectMap::Delegate override.
+ virtual NfcPropertySet* CreateProperties(
+ dbus::ObjectProxy* object_proxy) OVERRIDE {
+ return new Properties(
+ object_proxy,
+ base::Bind(&NfcTagClientImpl::OnPropertyChanged,
+ weak_ptr_factory_.GetWeakPtr(),
+ object_proxy->object_path()));
+ }
+
+ // Called by NfcPropertySet when a property value is changed, either by
+ // result of a signal or response to a GetAll() or Get() call.
+ void OnPropertyChanged(const dbus::ObjectPath& object_path,
+ const std::string& property_name) {
+ VLOG(1) << "Tag property changed; Path: " << object_path.value()
+ << " Property: " << property_name;
+ FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
+ TagPropertyChanged(object_path, property_name));
+ }
+
+ // We maintain a pointer to the bus to be able to request proxies for
+ // new NFC tags that appear.
+ dbus::Bus* bus_;
+
+ // Mapping from object paths to object proxies and properties structures that
+ // were already created by us.
+ scoped_ptr<nfc_client_helpers::DBusObjectMap> object_map_;
+
+ // The manager client that we listen to events notifications from.
+ NfcAdapterClient* adapter_client_;
+
+ // List of observers interested in event notifications.
+ ObserverList<NfcTagClient::Observer> observers_;
+
+ // Weak pointer factory for generating 'this' pointers that might live longer
+ // than we do.
+ // Note: This should remain the last member so it'll be destroyed and
+ // invalidate its weak pointers before any other members are destroyed.
+ base::WeakPtrFactory<NfcTagClientImpl> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(NfcTagClientImpl);
+};
+
+NfcTagClient::NfcTagClient() {
+}
+
+NfcTagClient::~NfcTagClient() {
+}
+
+NfcTagClient* NfcTagClient::Create(DBusClientImplementationType type,
+ NfcAdapterClient* adapter_client) {
+ if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
+ return new NfcTagClientImpl(adapter_client);
+ DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
+ return new FakeNfcTagClient();
+}
+
+} // namespace chromeos
diff --git a/chromeos/dbus/nfc_tag_client.h b/chromeos/dbus/nfc_tag_client.h
new file mode 100644
index 0000000..5d7e1e0
--- /dev/null
+++ b/chromeos/dbus/nfc_tag_client.h
@@ -0,0 +1,130 @@
+// 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.
+
+#ifndef CHROMEOS_DBUS_NFC_TAG_CLIENT_H_
+#define CHROMEOS_DBUS_NFC_TAG_CLIENT_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "chromeos/chromeos_export.h"
+#include "chromeos/dbus/dbus_client.h"
+#include "chromeos/dbus/dbus_client_implementation_type.h"
+#include "chromeos/dbus/nfc_client_helpers.h"
+#include "chromeos/dbus/nfc_property_set.h"
+#include "dbus/object_path.h"
+#include "dbus/object_proxy.h"
+#include "dbus/property.h"
+
+namespace chromeos {
+
+class NfcAdapterClient;
+
+// NfcTagClient is used to communicate with objects representing remote NFC
+// tags.
+class CHROMEOS_EXPORT NfcTagClient : public DBusClient {
+ public:
+ // Structure of properties associated with an NFC tag.
+ struct Properties : public NfcPropertySet {
+ // The NFC tag type. Possible values are "Type 1", "Type 2", "Type 3",
+ // and "Type 4".
+ dbus::Property<std::string> type;
+
+ // The NFC tag radio protocol. Possible values are "Felica", "MIFARE",
+ // "Jewel", "ISO-DEP", and "NFC-DEP".
+ dbus::Property<std::string> protocol;
+
+ // List of object paths for NDEF Records associated with the NFC tag.
+ dbus::Property<std::vector<dbus::ObjectPath> > records;
+
+ // The current status of the tag's read mode.
+ dbus::Property<bool> read_only;
+
+ Properties(dbus::ObjectProxy* object_proxy,
+ const PropertyChangedCallback& callback);
+ virtual ~Properties();
+ };
+
+ // Interface for observing changes from a remote NFC tag.
+ class Observer {
+ public:
+ virtual ~Observer() {}
+
+ // Called when a remote NFC tag with the object path |object_path| is added
+ // to the set of known tags associated with the adapter with object path
+ // |adapter_path|.
+ virtual void TagFound(const dbus::ObjectPath& object_path,
+ const dbus::ObjectPath& adapter_path) {}
+
+ // Called when a remote NFC tag with the object path |object_path| is
+ // removed from the set of known tags associated with the adapter with the
+ // object path |adapter_path|.
+ virtual void TagLost(const dbus::ObjectPath& object_path,
+ const dbus::ObjectPath& adapter_path) {}
+
+ // Called when the tag property with the name |property_name| on tag with
+ // object path |object_path| has acquired a new value.
+ virtual void TagPropertyChanged(const dbus::ObjectPath& object_path,
+ const std::string& property_name) {}
+ };
+
+ // TODO(armansito): Move this typedef to the NFC Record client, once
+ // implemented.
+ typedef std::map<std::string, std::string> RecordAttributes;
+
+ virtual ~NfcTagClient();
+
+ // Adds and removes observers for events on all remote NFC tags. Check the
+ // |object_path| parameter of observer methods to determine which tag is
+ // issuing the event.
+ virtual void AddObserver(Observer* observer) = 0;
+ virtual void RemoveObserver(Observer* observer) = 0;
+
+ // Obtain the properties for the NFC tag with object path |object_path|; any
+ // values should be copied if needed.
+ virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0;
+
+ // Creates an NDEF record for the NFC tag with object path |object_path|
+ // using the parameters in |attributes|. |attributes| is a dictionary,
+ // containing the NFC Record properties which will be assigned to the
+ // resulting record object and written to the tag. The properties are defined
+ // by the NFC Record interface (see namespace "nfc_record" in
+ // third_party/cros_system_api/dbus/service_constants.h and
+ // NfcRecordClient::Properties). |attributes| should at least contain a
+ // "Type" plus any other properties associated with that type. For example:
+ //
+ // {
+ // "Type": "Text",
+ // "Encoding": "UTF-8",
+ // "Language": "en",
+ // "Representation": "Chrome OS rulez!"
+ // },
+ // {
+ // "Type": "URI",
+ // "URI": "http://www.chromium.org"
+ // },
+ // etc.
+ virtual void Write(
+ const dbus::ObjectPath& object_path,
+ const RecordAttributes& attributes,
+ const base::Closure& callback,
+ const nfc_client_helpers::ErrorCallback& error_callback) = 0;
+
+ // Creates the instance.
+ static NfcTagClient* Create(DBusClientImplementationType type,
+ NfcAdapterClient* adapter_client);
+
+ protected:
+ friend class NfcClientTest;
+
+ NfcTagClient();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NfcTagClient);
+};
+
+} // namespace chromeos
+
+#endif // CHROMEOS_DBUS_NFC_TAG_CLIENT_H_