1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "device/nfc/nfc_adapter_chromeos.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <vector>
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/callback.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/logging.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "device/nfc/nfc_peer_chromeos.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "device/nfc/nfc_tag_chromeos.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace chromeos {
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)typedef std::vector<dbus::ObjectPath> ObjectPathVector;
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)NfcAdapterChromeOS::NfcAdapterChromeOS()
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : weak_ptr_factory_(this) {
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DBusThreadManager::Get()->GetNfcAdapterClient()->AddObserver(this);
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DBusThreadManager::Get()->GetNfcDeviceClient()->AddObserver(this);
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DBusThreadManager::Get()->GetNfcTagClient()->AddObserver(this);
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const ObjectPathVector& object_paths =
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      DBusThreadManager::Get()->GetNfcAdapterClient()->GetAdapters();
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!object_paths.empty()) {
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    VLOG(1) << object_paths.size() << " NFC adapter(s) available.";
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SetAdapter(object_paths[0]);
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)NfcAdapterChromeOS::~NfcAdapterChromeOS() {
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DBusThreadManager::Get()->GetNfcAdapterClient()->RemoveObserver(this);
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DBusThreadManager::Get()->GetNfcDeviceClient()->RemoveObserver(this);
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DBusThreadManager::Get()->GetNfcTagClient()->RemoveObserver(this);
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::AddObserver(NfcAdapter::Observer* observer) {
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(observer);
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  observers_.AddObserver(observer);
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::RemoveObserver(NfcAdapter::Observer* observer) {
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(observer);
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  observers_.RemoveObserver(observer);
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool NfcAdapterChromeOS::IsPresent() const {
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return !object_path_.value().empty();
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool NfcAdapterChromeOS::IsPowered() const {
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!IsPresent())
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return DBusThreadManager::Get()->GetNfcAdapterClient()->
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetProperties(object_path_)->powered.value();
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool NfcAdapterChromeOS::IsPolling() const {
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!IsPresent())
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return DBusThreadManager::Get()->GetNfcAdapterClient()->
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetProperties(object_path_)->polling.value();
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool NfcAdapterChromeOS::IsInitialized() const {
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return true;
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::SetPowered(bool powered,
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    const base::Closure& callback,
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    const ErrorCallback& error_callback) {
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!IsPresent()) {
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LOG(WARNING) << "Adapter not present. Cannot power up the antenna.";
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    error_callback.Run();
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DBusThreadManager::Get()->GetNfcAdapterClient()->
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetProperties(object_path_)->powered.Set(
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          powered,
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          base::Bind(&NfcAdapterChromeOS::OnSetPowered,
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     weak_ptr_factory_.GetWeakPtr(),
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     callback,
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     error_callback));
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::StartPolling(const base::Closure& callback,
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                      const ErrorCallback& error_callback) {
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Always poll in "Initiator" mode.
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DBusThreadManager::Get()->GetNfcAdapterClient()->
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      StartPollLoop(object_path_,
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    nfc_adapter::kModeInitiator,
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    base::Bind(&NfcAdapterChromeOS::OnStartPolling,
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               weak_ptr_factory_.GetWeakPtr(),
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               callback),
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    base::Bind(&NfcAdapterChromeOS::OnStartPollingError,
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               weak_ptr_factory_.GetWeakPtr(),
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               error_callback));
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::StopPolling(const base::Closure& callback,
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                     const ErrorCallback& error_callback) {
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DBusThreadManager::Get()->GetNfcAdapterClient()->
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      StopPollLoop(object_path_,
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   base::Bind(&NfcAdapterChromeOS::OnStopPolling,
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                              weak_ptr_factory_.GetWeakPtr(),
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                              callback),
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   base::Bind(&NfcAdapterChromeOS::OnStopPollingError,
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                              weak_ptr_factory_.GetWeakPtr(),
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                              error_callback));
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::AdapterAdded(const dbus::ObjectPath& object_path) {
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Set the adapter to the newly added adapter only if no adapter is present.
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!IsPresent())
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SetAdapter(object_path);
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::AdapterRemoved(const dbus::ObjectPath& object_path) {
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (object_path != object_path_)
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The current adapter was removed, so mark us as not present and clean up
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // peers and tags.
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RemoveAdapter();
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // There may still be other adapters present on the system. Set the next
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // available adapter as the current one.
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const ObjectPathVector& object_paths =
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      DBusThreadManager::Get()->GetNfcAdapterClient()->GetAdapters();
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (ObjectPathVector::const_iterator iter =
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          object_paths.begin();
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       iter != object_paths.end(); ++iter) {
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // The removed object will still be available until the call to
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // AdapterRemoved returns. Make sure that we are not re-adding the
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // removed adapter.
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (*iter == object_path)
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      continue;
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SetAdapter(*iter);
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::AdapterPropertyChanged(
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const dbus::ObjectPath& object_path,
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::string& property_name) {
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (object_path != object_path_)
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NfcAdapterClient::Properties* properties =
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      DBusThreadManager::Get()->GetNfcAdapterClient()->
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          GetProperties(object_path_);
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (property_name == properties->powered.name())
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PoweredChanged(properties->powered.value());
159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  else if (property_name == properties->polling.name())
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PollingChanged(properties->polling.value());
161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::DeviceAdded(const dbus::ObjectPath& object_path) {
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!IsPresent())
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (GetPeer(object_path.value()))
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VLOG(1) << "NFC device found: " << object_path.value();
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check to see if the device belongs to this adapter.
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const ObjectPathVector& devices =
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DBusThreadManager::Get()->GetNfcDeviceClient()->
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          GetDevicesForAdapter(object_path_);
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool device_found = false;
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (ObjectPathVector::const_iterator iter = devices.begin();
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       iter != devices.end(); ++iter) {
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (*iter == object_path) {
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      device_found = true;
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!device_found) {
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    VLOG(1) << "Found peer device does not belong to the current adapter.";
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create the peer object.
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NfcPeerChromeOS* peer_chromeos = new NfcPeerChromeOS(object_path);
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetPeer(object_path.value(), peer_chromeos);
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    PeerFound(this, peer_chromeos));
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::DeviceRemoved(const dbus::ObjectPath& object_path) {
197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VLOG(1) << "NFC device lost: " << object_path.value();
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  device::NfcPeer* peer = RemovePeer(object_path.value());
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!peer) {
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    VLOG(1) << "Removed peer device does not belong to the current adapter.";
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_, PeerLost(this, peer));
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete peer;
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::TagAdded(const dbus::ObjectPath& object_path) {
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!IsPresent())
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (GetTag(object_path.value()))
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VLOG(1) << "NFC tag found: " << object_path.value();
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check to see if the tag belongs to this adapter.
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::vector<dbus::ObjectPath>& tags =
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DBusThreadManager::Get()->GetNfcTagClient()->
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          GetTagsForAdapter(object_path_);
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool tag_found = false;
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (std::vector<dbus::ObjectPath>::const_iterator iter = tags.begin();
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       iter != tags.end(); ++iter) {
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (*iter == object_path) {
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      tag_found = true;
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!tag_found) {
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    VLOG(1) << "Found tag does not belong to the current adapter.";
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create the tag object.
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NfcTagChromeOS* tag_chromeos = new NfcTagChromeOS(object_path);
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetTag(object_path.value(), tag_chromeos);
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    TagFound(this, tag_chromeos));
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NfcAdapterChromeOS::TagRemoved(const dbus::ObjectPath& object_path) {
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  VLOG(1) << "NFC tag lost : " << object_path.value();
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  device::NfcTag* tag = RemoveTag(object_path.value());
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!tag) {
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    VLOG(1) << "Removed tag does not belong to the current adapter.";
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_, TagLost(this, tag));
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete tag;
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::SetAdapter(const dbus::ObjectPath& object_path) {
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(!IsPresent());
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  object_path_ = object_path;
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VLOG(1) << "Using NFC adapter: " << object_path.value();
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NfcAdapterClient::Properties* properties =
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      DBusThreadManager::Get()->GetNfcAdapterClient()->
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          GetProperties(object_path_);
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PresentChanged(true);
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (properties->powered.value())
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PoweredChanged(true);
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (properties->polling.value())
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PollingChanged(true);
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create peer objects for peers that were added before the adapter was set.
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const ObjectPathVector& devices =
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DBusThreadManager::Get()->GetNfcDeviceClient()->
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          GetDevicesForAdapter(object_path_);
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (ObjectPathVector::const_iterator iter = devices.begin();
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       iter != devices.end(); ++iter) {
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const dbus::ObjectPath& object_path = *iter;
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (GetPeer(object_path.value()))
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      continue;
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NfcPeerChromeOS* peer_chromeos = new NfcPeerChromeOS(object_path);
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetPeer(object_path.value(), peer_chromeos);
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      PeerFound(this, peer_chromeos));
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create tag objects for tags that were added before the adapter was set.
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::vector<dbus::ObjectPath>& tags =
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DBusThreadManager::Get()->GetNfcTagClient()->
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          GetTagsForAdapter(object_path_);
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (std::vector<dbus::ObjectPath>::const_iterator iter = tags.begin();
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       iter != tags.end(); ++iter) {
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const dbus::ObjectPath& object_path = *iter;
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (GetTag(object_path.value()))
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      continue;
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NfcTagChromeOS* tag_chromeos = new NfcTagChromeOS(object_path);
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetTag(object_path.value(), tag_chromeos);
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      TagFound(this, tag_chromeos));
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::RemoveAdapter() {
297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsPresent());
298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VLOG(1) << "NFC adapter removed: " << object_path_.value();
299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NfcAdapterClient::Properties* properties =
301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      DBusThreadManager::Get()->GetNfcAdapterClient()->
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          GetProperties(object_path_);
303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (properties->powered.value())
304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PoweredChanged(false);
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (properties->polling.value())
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PollingChanged(false);
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Copy the tags and peers here and clear the original containers so that
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // GetPeers and GetTags return no values during the *Removed observer calls.
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PeerList peers;
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TagList tags;
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetPeers(&peers);
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetTags(&tags);
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ClearPeers();
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ClearTags();
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (PeerList::iterator iter = peers.begin();
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       iter != peers.end(); ++iter) {
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    device::NfcPeer* peer = *iter;
320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      PeerLost(this, peer));
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delete peer;
323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (TagList::iterator iter = tags.begin();
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       iter != tags.end(); ++iter) {
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    device::NfcTag* tag = *iter;
327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      TagLost(this, tag));
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delete tag;
330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  object_path_ = dbus::ObjectPath("");
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PresentChanged(false);
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::PoweredChanged(bool powered) {
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    AdapterPoweredChanged(this, powered));
339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::PollingChanged(bool polling) {
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    AdapterPollingChanged(this, polling));
344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::PresentChanged(bool present) {
347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    AdapterPresentChanged(this, present));
349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::OnSetPowered(const base::Closure& callback,
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                      const ErrorCallback& error_callback,
353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                      bool success) {
354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VLOG(1) << "NfcAdapterChromeOS::OnSetPowered result: " << success;
355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (success) {
356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // TODO(armansito): There is a bug in neard 0.13 that causes it not to emit
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // a signal when the "Powered" property changes. Sync the properties here,
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // but remove it in neard 0.14.
359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (IsPresent()) {
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      DBusThreadManager::Get()->GetNfcAdapterClient()->
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          GetProperties(object_path_)->GetAll();
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback.Run();
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else {
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LOG(ERROR) << "Failed to power up the NFC antenna radio.";
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    error_callback.Run();
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::OnStartPolling(const base::Closure& callback) {
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback.Run();
372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::OnStartPollingError(
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const ErrorCallback& error_callback,
376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::string& error_name,
377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::string& error_message) {
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LOG(ERROR) << object_path_.value() << ": Failed to start polling: "
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             << error_name << ": " << error_message;
380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  error_callback.Run();
381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::OnStopPolling(const base::Closure& callback) {
384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback.Run();
385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NfcAdapterChromeOS::OnStopPollingError(
388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const ErrorCallback& error_callback,
389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::string& error_name,
390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::string& error_message) {
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LOG(ERROR) << object_path_.value() << ": Failed to stop polling: "
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             << error_name << ": " << error_message;
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  error_callback.Run();
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace chromeos
397