summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authorarmansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-08 07:18:54 +0000
committerarmansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-08 07:18:54 +0000
commit42716047fd8604517a73070401470fada6971b23 (patch)
treef17388c8038fb91984dc2c727ae58649862f96de /device
parent6fe561067c842ec9d884f1b3356b4218af9a0dfa (diff)
downloadchromium_src-42716047fd8604517a73070401470fada6971b23.zip
chromium_src-42716047fd8604517a73070401470fada6971b23.tar.gz
chromium_src-42716047fd8604517a73070401470fada6971b23.tar.bz2
nfc: Implement NfcAdapterChromeOS.
Added the basic implementation of NfcAdapterChromeOS, with no tag/peer logic. BUG=316471 TEST=device_unittests Review URL: https://codereview.chromium.org/100393011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@239388 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'device')
-rw-r--r--device/device_tests.gyp1
-rw-r--r--device/nfc/nfc.gyp2
-rw-r--r--device/nfc/nfc_adapter.cc2
-rw-r--r--device/nfc/nfc_adapter_chromeos.cc304
-rw-r--r--device/nfc/nfc_adapter_chromeos.h117
-rw-r--r--device/nfc/nfc_adapter_factory.cc38
-rw-r--r--device/nfc/nfc_chromeos_unittest.cc202
7 files changed, 660 insertions, 6 deletions
diff --git a/device/device_tests.gyp b/device/device_tests.gyp
index 00bd47b..e0564b5 100644
--- a/device/device_tests.gyp
+++ b/device/device_tests.gyp
@@ -30,6 +30,7 @@
'bluetooth/bluetooth_service_record_win_unittest.cc',
'bluetooth/bluetooth_task_manager_win_unittest.cc',
'bluetooth/bluetooth_utils_unittest.cc',
+ 'nfc/nfc_chromeos_unittest.cc',
'nfc/nfc_ndef_record_unittest.cc',
'usb/usb_ids_unittest.cc',
],
diff --git a/device/nfc/nfc.gyp b/device/nfc/nfc.gyp
index eafa31d..d5e519b 100644
--- a/device/nfc/nfc.gyp
+++ b/device/nfc/nfc.gyp
@@ -16,6 +16,8 @@
'sources': [
'nfc_adapter.cc',
'nfc_adapter.h',
+ 'nfc_adapter_chromeos.cc',
+ 'nfc_adapter_chromeos.h',
'nfc_adapter_factory.cc',
'nfc_adapter_factory.h',
'nfc_ndef_record.cc',
diff --git a/device/nfc/nfc_adapter.cc b/device/nfc/nfc_adapter.cc
index dd790b2..1bef83d3 100644
--- a/device/nfc/nfc_adapter.cc
+++ b/device/nfc/nfc_adapter.cc
@@ -4,8 +4,6 @@
#include "device/nfc/nfc_adapter.h"
-#include "base/lazy_instance.h"
-#include "base/memory/weak_ptr.h"
#include "base/stl_util.h"
#include "device/nfc/nfc_peer.h"
#include "device/nfc/nfc_tag.h"
diff --git a/device/nfc/nfc_adapter_chromeos.cc b/device/nfc/nfc_adapter_chromeos.cc
new file mode 100644
index 0000000..071b080
--- /dev/null
+++ b/device/nfc/nfc_adapter_chromeos.cc
@@ -0,0 +1,304 @@
+// 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_adapter_chromeos.h"
+
+#include <vector>
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "device/nfc/nfc_peer.h"
+#include "device/nfc/nfc_tag.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace chromeos {
+
+NfcAdapterChromeOS::NfcAdapterChromeOS()
+ : weak_ptr_factory_(this) {
+ DBusThreadManager::Get()->GetNfcAdapterClient()->AddObserver(this);
+ DBusThreadManager::Get()->GetNfcDeviceClient()->AddObserver(this);
+ DBusThreadManager::Get()->GetNfcTagClient()->AddObserver(this);
+
+ const std::vector<dbus::ObjectPath>& object_paths =
+ DBusThreadManager::Get()->GetNfcAdapterClient()->GetAdapters();
+ if (!object_paths.empty()) {
+ VLOG(1) << object_paths.size() << " NFC adapter(s) available.";
+ SetAdapter(object_paths[0]);
+ }
+}
+
+NfcAdapterChromeOS::~NfcAdapterChromeOS() {
+ DBusThreadManager::Get()->GetNfcAdapterClient()->RemoveObserver(this);
+ DBusThreadManager::Get()->GetNfcDeviceClient()->RemoveObserver(this);
+ DBusThreadManager::Get()->GetNfcTagClient()->RemoveObserver(this);
+}
+
+void NfcAdapterChromeOS::AddObserver(NfcAdapter::Observer* observer) {
+ DCHECK(observer);
+ observers_.AddObserver(observer);
+}
+
+void NfcAdapterChromeOS::RemoveObserver(NfcAdapter::Observer* observer) {
+ DCHECK(observer);
+ observers_.RemoveObserver(observer);
+}
+
+bool NfcAdapterChromeOS::IsPresent() const {
+ return !object_path_.value().empty();
+}
+
+bool NfcAdapterChromeOS::IsPowered() const {
+ if (!IsPresent())
+ return false;
+ return DBusThreadManager::Get()->GetNfcAdapterClient()->
+ GetProperties(object_path_)->powered.value();
+}
+
+bool NfcAdapterChromeOS::IsPolling() const {
+ if (!IsPresent())
+ return false;
+ return DBusThreadManager::Get()->GetNfcAdapterClient()->
+ GetProperties(object_path_)->polling.value();
+}
+
+bool NfcAdapterChromeOS::IsInitialized() const {
+ return true;
+}
+
+void NfcAdapterChromeOS::SetPowered(bool powered,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ if (!IsPresent()) {
+ LOG(WARNING) << "Adapter not present. Cannot power up the antenna.";
+ error_callback.Run();
+ return;
+ }
+ DBusThreadManager::Get()->GetNfcAdapterClient()->
+ GetProperties(object_path_)->powered.Set(
+ powered,
+ base::Bind(&NfcAdapterChromeOS::OnSetPowered,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback,
+ error_callback));
+}
+
+void NfcAdapterChromeOS::StartPolling(const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ // Always poll in "Initiator" mode.
+ DBusThreadManager::Get()->GetNfcAdapterClient()->
+ StartPollLoop(object_path_,
+ nfc_adapter::kModeInitiator,
+ base::Bind(&NfcAdapterChromeOS::OnStartPolling,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback),
+ base::Bind(&NfcAdapterChromeOS::OnStartPollingError,
+ weak_ptr_factory_.GetWeakPtr(),
+ error_callback));
+}
+
+void NfcAdapterChromeOS::StopPolling(const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ DBusThreadManager::Get()->GetNfcAdapterClient()->
+ StopPollLoop(object_path_,
+ base::Bind(&NfcAdapterChromeOS::OnStopPolling,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback),
+ base::Bind(&NfcAdapterChromeOS::OnStopPollingError,
+ weak_ptr_factory_.GetWeakPtr(),
+ error_callback));
+}
+
+void NfcAdapterChromeOS::AdapterAdded(const dbus::ObjectPath& object_path) {
+ // Set the adapter to the newly added adapter only if no adapter is present.
+ if (!IsPresent())
+ SetAdapter(object_path);
+}
+
+void NfcAdapterChromeOS::AdapterRemoved(const dbus::ObjectPath& object_path) {
+ if (object_path != object_path_)
+ return;
+
+ // The current adapter was removed, so mark us as not present and clean up
+ // peers and tags.
+ RemoveAdapter();
+
+ // There may still be other adapters present on the system. Set the next
+ // available adapter as the current one.
+ const std::vector<dbus::ObjectPath>& object_paths =
+ DBusThreadManager::Get()->GetNfcAdapterClient()->GetAdapters();
+ for (std::vector<dbus::ObjectPath>::const_iterator iter =
+ object_paths.begin();
+ iter != object_paths.end(); ++iter) {
+ // The removed object will still be available until the call to
+ // AdapterRemoved returns. Make sure that we are not re-adding the
+ // removed adapter.
+ if (*iter == object_path)
+ continue;
+ SetAdapter(*iter);
+ }
+}
+
+void NfcAdapterChromeOS::AdapterPropertyChanged(
+ const dbus::ObjectPath& object_path,
+ const std::string& property_name) {
+ if (object_path != object_path_)
+ return;
+ NfcAdapterClient::Properties* properties =
+ DBusThreadManager::Get()->GetNfcAdapterClient()->
+ GetProperties(object_path_);
+ if (property_name == properties->powered.name())
+ PoweredChanged(properties->powered.value());
+ else if (property_name == properties->polling.name())
+ PollingChanged(properties->polling.value());
+}
+
+void NfcAdapterChromeOS::DeviceAdded(const dbus::ObjectPath& object_path) {
+ VLOG(1) << "NFC device found: " << object_path.value();
+ // TODO(armansito): Implement device logic.
+}
+
+void NfcAdapterChromeOS::DeviceRemoved(const dbus::ObjectPath& object_path) {
+ VLOG(1) << "NFC device lost: " << object_path.value();
+ // TODO(armansito): Implement device logic.
+}
+
+void NfcAdapterChromeOS::DevicePropertyChanged(
+ const dbus::ObjectPath& object_path,
+ const std::string& property_name) {
+ // TODO(armansito): Implement device logic.
+}
+
+void NfcAdapterChromeOS::TagAdded(const dbus::ObjectPath& object_path) {
+ VLOG(1) << "NFC tag found: " << object_path.value();
+ // TODO(armansito): Implement tag logic.
+}
+
+void NfcAdapterChromeOS::TagRemoved(const dbus::ObjectPath& object_path) {
+ VLOG(1) << "NFC tag found: " << object_path.value();
+ // TODO(armansito): Implement tag logic.
+}
+
+void NfcAdapterChromeOS::TagPropertyChanged(
+ const dbus::ObjectPath& object_path,
+ const std::string& property_name) {
+ // TODO(armansito): Implement tag logic.
+}
+
+void NfcAdapterChromeOS::SetAdapter(const dbus::ObjectPath& object_path) {
+ DCHECK(!IsPresent());
+ object_path_ = object_path;
+ VLOG(1) << "Using NFC adapter: " << object_path.value();
+
+ NfcAdapterClient::Properties* properties =
+ DBusThreadManager::Get()->GetNfcAdapterClient()->
+ GetProperties(object_path_);
+ PresentChanged(true);
+ if (properties->powered.value())
+ PoweredChanged(true);
+ if (properties->polling.value())
+ PollingChanged(true);
+
+ // TODO(armansito): Create device::NfcPeer and device::NfcTag instances for
+ // all peers and tags that exist, once they have been implemented for
+ // ChromeOS.
+}
+
+void NfcAdapterChromeOS::RemoveAdapter() {
+ DCHECK(IsPresent());
+ VLOG(1) << "NFC adapter removed: " << object_path_.value();
+
+ NfcAdapterClient::Properties* properties =
+ DBusThreadManager::Get()->GetNfcAdapterClient()->
+ GetProperties(object_path_);
+ if (properties->powered.value())
+ PoweredChanged(false);
+ if (properties->polling.value())
+ PollingChanged(false);
+
+ // Copy the tags and peers here and clear the original containers so that
+ // GetPeers and GetTags return no values during the *Removed observer calls.
+ PeersMap peers = peers_;
+ TagsMap tags = tags_;
+ peers_.clear();
+ tags_.clear();
+
+ for (PeersMap::iterator iter = peers_.begin();
+ iter != peers_.end(); ++iter) {
+ FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
+ PeerLost(this, iter->second));
+ delete iter->second;
+ }
+ for (TagsMap::iterator iter = tags_.begin();
+ iter != tags_.end(); ++iter) {
+ FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
+ TagLost(this, iter->second));
+ delete iter->second;
+ }
+
+ object_path_ = dbus::ObjectPath("");
+ PresentChanged(false);
+}
+
+void NfcAdapterChromeOS::PoweredChanged(bool powered) {
+ FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
+ AdapterPoweredChanged(this, powered));
+}
+
+void NfcAdapterChromeOS::PollingChanged(bool polling) {
+ FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
+ AdapterPollingChanged(this, polling));
+}
+
+void NfcAdapterChromeOS::PresentChanged(bool present) {
+ FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
+ AdapterPresentChanged(this, present));
+}
+
+void NfcAdapterChromeOS::OnSetPowered(const base::Closure& callback,
+ const ErrorCallback& error_callback,
+ bool success) {
+ VLOG(1) << "NfcAdapterChromeOS::OnSetPowered result: " << success;
+ if (success) {
+ // TODO(armansito): There is a bug in neard 0.13 that causes it not to emit
+ // a signal when the "Powered" property changes. Sync the properties here,
+ // but remove it in neard 0.14.
+ if (IsPresent()) {
+ DBusThreadManager::Get()->GetNfcAdapterClient()->
+ GetProperties(object_path_)->GetAll();
+ }
+ callback.Run();
+ } else {
+ LOG(WARNING) << "Failed to power up the NFC antenna radio.";
+ error_callback.Run();
+ }
+}
+
+void NfcAdapterChromeOS::OnStartPolling(const base::Closure& callback) {
+ callback.Run();
+}
+
+void NfcAdapterChromeOS::OnStartPollingError(
+ const ErrorCallback& error_callback,
+ const std::string& error_name,
+ const std::string& error_message) {
+ LOG(WARNING) << object_path_.value() << ": Failed to start polling: "
+ << error_name << ": " << error_message;
+ error_callback.Run();
+}
+
+void NfcAdapterChromeOS::OnStopPolling(const base::Closure& callback) {
+ callback.Run();
+}
+
+void NfcAdapterChromeOS::OnStopPollingError(
+ const ErrorCallback& error_callback,
+ const std::string& error_name,
+ const std::string& error_message) {
+ LOG(WARNING) << object_path_.value() << ": Failed to stop polling: "
+ << error_name << ": " << error_message;
+ error_callback.Run();
+}
+
+} // namespace chromeos
diff --git a/device/nfc/nfc_adapter_chromeos.h b/device/nfc/nfc_adapter_chromeos.h
new file mode 100644
index 0000000..d70a98d
--- /dev/null
+++ b/device/nfc/nfc_adapter_chromeos.h
@@ -0,0 +1,117 @@
+// 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 DEVICE_NFC_NFC_ADAPTER_CHROMEOS_H_
+#define DEVICE_NFC_NFC_ADAPTER_CHROMEOS_H_
+
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "chromeos/dbus/nfc_adapter_client.h"
+#include "chromeos/dbus/nfc_device_client.h"
+#include "chromeos/dbus/nfc_tag_client.h"
+#include "dbus/object_path.h"
+#include "device/nfc/nfc_adapter.h"
+
+namespace device {
+
+class NfcAdapterFactory;
+
+} // namespace device
+
+namespace chromeos {
+
+// The NfcAdapterChromeOS class implements NfcAdapter for the Chrome OS
+// platform.
+class NfcAdapterChromeOS : public device::NfcAdapter,
+ public chromeos::NfcAdapterClient::Observer,
+ public chromeos::NfcDeviceClient::Observer,
+ public chromeos::NfcTagClient::Observer {
+ public:
+ // NfcAdapter overrides.
+ virtual void AddObserver(NfcAdapter::Observer* observer) OVERRIDE;
+ virtual void RemoveObserver(NfcAdapter::Observer* observer) OVERRIDE;
+ virtual bool IsPresent() const OVERRIDE;
+ virtual bool IsPowered() const OVERRIDE;
+ virtual bool IsPolling() const OVERRIDE;
+ virtual bool IsInitialized() const OVERRIDE;
+ virtual void SetPowered(bool powered,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) OVERRIDE;
+ virtual void StartPolling(const base::Closure& callback,
+ const ErrorCallback& error_callback) OVERRIDE;
+ virtual void StopPolling(const base::Closure& callback,
+ const ErrorCallback& error_callback) OVERRIDE;
+
+ private:
+ friend class device::NfcAdapterFactory;
+ friend class NfcChromeOSTest;
+
+ NfcAdapterChromeOS();
+ virtual ~NfcAdapterChromeOS();
+
+ // NfcAdapterClient::Observer overrides.
+ virtual void AdapterAdded(const dbus::ObjectPath& object_path) OVERRIDE;
+ virtual void AdapterRemoved(const dbus::ObjectPath& object_path) OVERRIDE;
+ virtual void AdapterPropertyChanged(
+ const dbus::ObjectPath& object_path,
+ const std::string& property_name) OVERRIDE;
+
+ // NfcDeviceClient::Observer overrides.
+ virtual void DeviceAdded(const dbus::ObjectPath& object_path) OVERRIDE;
+ virtual void DeviceRemoved(const dbus::ObjectPath& object_path) OVERRIDE;
+ virtual void DevicePropertyChanged(const dbus::ObjectPath& object_path,
+ const std::string& property_name) OVERRIDE;
+
+ // NfcTagClient::Observer overrides.
+ virtual void TagAdded(const dbus::ObjectPath& object_path) OVERRIDE;
+ virtual void TagRemoved(const dbus::ObjectPath& object_path) OVERRIDE;
+ virtual void TagPropertyChanged(const dbus::ObjectPath& object_path,
+ const std::string& property_name) OVERRIDE;
+
+ // Set the tracked adapter to the one in |object_path|, this object will
+ // subsequently operate on that adapter until it is removed.
+ void SetAdapter(const dbus::ObjectPath& object_path);
+
+ // Remove the currently tracked adapter. IsPresent() will return false after
+ // this is called.
+ void RemoveAdapter();
+
+ // Announce to observers a change in the adapter state.
+ void PoweredChanged(bool powered);
+ void PollingChanged(bool polling);
+ void PresentChanged(bool present);
+
+ // Called by dbus:: on completion of the powered property change.
+ void OnSetPowered(const base::Closure& callback,
+ const ErrorCallback& error_callback,
+ bool success);
+
+ // Called by dbus:: on completion of the D-Bus method call to start polling.
+ void OnStartPolling(const base::Closure& callback);
+ void OnStartPollingError(const ErrorCallback& error_callback,
+ const std::string& error_name,
+ const std::string& error_message);
+
+ // Called by dbus:: on completion of the D-Bus method call to stop polling.
+ void OnStopPolling(const base::Closure& callback);
+ void OnStopPollingError(const ErrorCallback& error_callback,
+ const std::string& error_name,
+ const std::string& error_message);
+
+ // Object path of the adapter that we are currently tracking.
+ dbus::ObjectPath object_path_;
+
+ // List of observers interested in event notifications from us.
+ ObserverList<device::NfcAdapter::Observer> observers_;
+
+ // 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<NfcAdapterChromeOS> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(NfcAdapterChromeOS);
+};
+
+} // namespace chromeos
+
+#endif // DEVICE_NFC_NFC_ADAPTER_CHROMEOS_H_
diff --git a/device/nfc/nfc_adapter_factory.cc b/device/nfc/nfc_adapter_factory.cc
index c05c933..1ba533a 100644
--- a/device/nfc/nfc_adapter_factory.cc
+++ b/device/nfc/nfc_adapter_factory.cc
@@ -5,20 +5,50 @@
#include "device/nfc/nfc_adapter_factory.h"
#include "base/lazy_instance.h"
+#include "base/logging.h"
#include "base/memory/weak_ptr.h"
+#if defined(OS_CHROMEOS)
+#include "device/nfc/nfc_adapter_chromeos.h"
+#endif
+
namespace device {
+namespace {
+
+// Shared default adapter instance, we don't want to keep this class around
+// if nobody is using it so use a WeakPtr and create the object when needed;
+// since Google C++ Style (and clang's static analyzer) forbids us having
+// exit-time destructors we use a leaky lazy instance for it.
+base::LazyInstance<base::WeakPtr<device::NfcAdapter> >::Leaky
+ default_adapter = LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
// static
bool NfcAdapterFactory::IsNfcAvailable() {
- // TODO(armansito): Return true on supported platforms here.
+#if defined(OS_CHROMEOS)
+ return true;
+#else
return false;
+#endif
}
// static
-void NfcAdapterFactory::GetAdapter(const AdapterCallback& /* callback */) {
- // TODO(armansito): Create platform-specific implementation instances here.
- // No platform currently supports NFC, so we never invoke the callback.
+void NfcAdapterFactory::GetAdapter(const AdapterCallback& callback) {
+ if (!IsNfcAvailable()) {
+ LOG(WARNING) << "NFC is not available on the current platform.";
+ return;
+ }
+ if (!default_adapter.Get().get()) {
+#if defined(OS_CHROMEOS)
+ chromeos::NfcAdapterChromeOS* new_adapter =
+ new chromeos::NfcAdapterChromeOS();
+ default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr();
+#endif
+ }
+ if (default_adapter.Get()->IsInitialized())
+ callback.Run(scoped_refptr<NfcAdapter>(default_adapter.Get().get()));
}
} // namespace device
diff --git a/device/nfc/nfc_chromeos_unittest.cc b/device/nfc/nfc_chromeos_unittest.cc
new file mode 100644
index 0000000..dd94beb
--- /dev/null
+++ b/device/nfc/nfc_chromeos_unittest.cc
@@ -0,0 +1,202 @@
+// 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 "base/message_loop/message_loop.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/fake_nfc_adapter_client.h"
+#include "device/nfc/nfc_adapter_chromeos.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using device::NfcAdapter;
+
+namespace chromeos {
+
+namespace {
+
+class TestObserver : public NfcAdapter::Observer {
+ public:
+ TestObserver(scoped_refptr<NfcAdapter> adapter)
+ : present_changed_count_(0),
+ powered_changed_count_(0),
+ adapter_(adapter) {
+ }
+
+ virtual ~TestObserver() {}
+
+ // NfcAdapter::Observer override.
+ virtual void AdapterPresentChanged(NfcAdapter* adapter,
+ bool present) OVERRIDE {
+ EXPECT_EQ(adapter_, adapter);
+ present_changed_count_++;
+ }
+
+ // NfcAdapter::Observer override.
+ virtual void AdapterPoweredChanged(NfcAdapter* adapter,
+ bool powered) OVERRIDE {
+ EXPECT_EQ(adapter_, adapter);
+ powered_changed_count_++;
+ }
+
+ int present_changed_count_;
+ int powered_changed_count_;
+ scoped_refptr<NfcAdapter> adapter_;
+};
+
+} // namespace
+
+class NfcChromeOSTest : public testing::Test {
+ public:
+ virtual void SetUp() {
+ DBusThreadManager::InitializeWithStub();
+ fake_nfc_adapter_client_ = static_cast<FakeNfcAdapterClient*>(
+ DBusThreadManager::Get()->GetNfcAdapterClient());
+ SetAdapter();
+ message_loop_.RunUntilIdle();
+
+ success_callback_count_ = 0;
+ error_callback_count_ = 0;
+ }
+
+ virtual void TearDown() {
+ adapter_ = NULL;
+ DBusThreadManager::Shutdown();
+ }
+
+ // Assigns a new instance of NfcAdapterChromeOS to |adapter_|.
+ void SetAdapter() {
+ adapter_ = new NfcAdapterChromeOS();
+ ASSERT_TRUE(adapter_.get() != NULL);
+ ASSERT_TRUE(adapter_->IsInitialized());
+ }
+
+ // Generic callbacks for success and error.
+ void SuccessCallback() {
+ success_callback_count_++;
+ }
+
+ void ErrorCallback() {
+ error_callback_count_++;
+ }
+
+ protected:
+ // Fields for storing the number of times SuccessCallback and ErrorCallback
+ // have been called.
+ int success_callback_count_;
+ int error_callback_count_;
+
+ // A message loop to emulate asynchronous behavior.
+ base::MessageLoop message_loop_;
+
+ // The NfcAdapter instance under test.
+ scoped_refptr<NfcAdapter> adapter_;
+
+ // The fake D-Bus client instances used for testing.
+ FakeNfcAdapterClient* fake_nfc_adapter_client_;
+};
+
+TEST_F(NfcChromeOSTest, PresentChanged) {
+ EXPECT_TRUE(adapter_->IsPresent());
+
+ TestObserver observer(adapter_);
+ adapter_->AddObserver(&observer);
+
+ // Remove all adapters.
+ fake_nfc_adapter_client_->SetAdapterPresent(false);
+ EXPECT_EQ(1, observer.present_changed_count_);
+ EXPECT_FALSE(adapter_->IsPresent());
+
+ // Add two adapters.
+ fake_nfc_adapter_client_->SetAdapterPresent(true);
+ fake_nfc_adapter_client_->SetSecondAdapterPresent(true);
+ EXPECT_EQ(2, observer.present_changed_count_);
+ EXPECT_TRUE(adapter_->IsPresent());
+
+ // Remove the first adapter. Adapter should update to the second one.
+ fake_nfc_adapter_client_->SetAdapterPresent(false);
+ EXPECT_EQ(4, observer.present_changed_count_);
+ EXPECT_TRUE(adapter_->IsPresent());
+
+ fake_nfc_adapter_client_->SetSecondAdapterPresent(false);
+ EXPECT_EQ(5, observer.present_changed_count_);
+ EXPECT_FALSE(adapter_->IsPresent());
+}
+
+TEST_F(NfcChromeOSTest, SetPowered) {
+ TestObserver observer(adapter_);
+ adapter_->AddObserver(&observer);
+
+ EXPECT_FALSE(adapter_->IsPowered());
+
+ // SetPowered(false), while not powered.
+ adapter_->SetPowered(
+ false,
+ base::Bind(&NfcChromeOSTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcChromeOSTest::ErrorCallback,
+ base::Unretained(this)));
+ EXPECT_FALSE(adapter_->IsPowered());
+ EXPECT_EQ(0, observer.powered_changed_count_);
+ EXPECT_EQ(0, success_callback_count_);
+ EXPECT_EQ(1, error_callback_count_);
+
+ // SetPowered(true).
+ adapter_->SetPowered(
+ true,
+ base::Bind(&NfcChromeOSTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcChromeOSTest::ErrorCallback,
+ base::Unretained(this)));
+ EXPECT_TRUE(adapter_->IsPowered());
+ EXPECT_EQ(1, observer.powered_changed_count_);
+ EXPECT_EQ(1, success_callback_count_);
+ EXPECT_EQ(1, error_callback_count_);
+
+ // SetPowered(true), while powered.
+ adapter_->SetPowered(
+ true,
+ base::Bind(&NfcChromeOSTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcChromeOSTest::ErrorCallback,
+ base::Unretained(this)));
+ EXPECT_TRUE(adapter_->IsPowered());
+ EXPECT_EQ(1, observer.powered_changed_count_);
+ EXPECT_EQ(1, success_callback_count_);
+ EXPECT_EQ(2, error_callback_count_);
+
+ // SetPowered(false).
+ adapter_->SetPowered(
+ false,
+ base::Bind(&NfcChromeOSTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcChromeOSTest::ErrorCallback,
+ base::Unretained(this)));
+ EXPECT_FALSE(adapter_->IsPowered());
+ EXPECT_EQ(2, observer.powered_changed_count_);
+ EXPECT_EQ(2, success_callback_count_);
+ EXPECT_EQ(2, error_callback_count_);
+}
+
+TEST_F(NfcChromeOSTest, PresentChangedWhilePowered) {
+ TestObserver observer(adapter_);
+ adapter_->AddObserver(&observer);
+
+ EXPECT_FALSE(adapter_->IsPowered());
+ EXPECT_TRUE(adapter_->IsPresent());
+
+ adapter_->SetPowered(
+ true,
+ base::Bind(&NfcChromeOSTest::SuccessCallback,
+ base::Unretained(this)),
+ base::Bind(&NfcChromeOSTest::ErrorCallback,
+ base::Unretained(this)));
+ EXPECT_TRUE(adapter_->IsPowered());
+
+ fake_nfc_adapter_client_->SetAdapterPresent(false);
+ EXPECT_EQ(1, observer.present_changed_count_);
+ EXPECT_EQ(2, observer.powered_changed_count_);
+ EXPECT_FALSE(adapter_->IsPowered());
+ EXPECT_FALSE(adapter_->IsPresent());
+}
+
+} // namespace chromeos