1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chromeos/dbus/nfc_manager_client.h"
6
7#include "base/memory/scoped_ptr.h"
8#include "base/memory/weak_ptr.h"
9#include "base/observer_list.h"
10#include "dbus/bus.h"
11#include "third_party/cros_system_api/dbus/service_constants.h"
12
13namespace chromeos {
14
15NfcManagerClient::Properties::Properties(
16    dbus::ObjectProxy* object_proxy,
17    const PropertyChangedCallback& callback)
18    : NfcPropertySet(object_proxy,
19                     nfc_manager::kNfcManagerInterface,
20                     callback) {
21  RegisterProperty(nfc_manager::kAdaptersProperty, &adapters);
22}
23
24NfcManagerClient::Properties::~Properties() {
25}
26
27
28// The NfcManagerClient implementation used in production.
29class NfcManagerClientImpl : public NfcManagerClient {
30 public:
31  NfcManagerClientImpl()
32      : object_proxy_(NULL),
33        weak_ptr_factory_(this) {
34  }
35
36  virtual ~NfcManagerClientImpl() {
37  }
38
39  // NfcManagerClient override.
40  virtual void AddObserver(Observer* observer) OVERRIDE {
41    DCHECK(observer);
42    observers_.AddObserver(observer);
43  }
44
45  // NfcManagerClient override.
46  virtual void RemoveObserver(Observer* observer) OVERRIDE {
47    DCHECK(observer);
48    observers_.RemoveObserver(observer);
49  }
50
51  // NfcManagerClient override.
52  virtual Properties* GetProperties() OVERRIDE {
53    return properties_.get();
54  }
55
56 protected:
57  // DBusClient override.
58  virtual void Init(dbus::Bus* bus) OVERRIDE {
59    VLOG(1) << "Creating NfcManagerClientImpl";
60
61    // Create the object proxy.
62    object_proxy_ = bus->GetObjectProxy(
63        nfc_manager::kNfcManagerServiceName,
64        dbus::ObjectPath(nfc_manager::kNfcManagerServicePath));
65
66    // Set up the signal handlers.
67    object_proxy_->ConnectToSignal(
68        nfc_manager::kNfcManagerInterface,
69        nfc_manager::kAdapterAddedSignal,
70        base::Bind(&NfcManagerClientImpl::AdapterAddedReceived,
71                   weak_ptr_factory_.GetWeakPtr()),
72        base::Bind(&NfcManagerClientImpl::AdapterAddedConnected,
73                   weak_ptr_factory_.GetWeakPtr()));
74
75    object_proxy_->ConnectToSignal(
76        nfc_manager::kNfcManagerInterface,
77        nfc_manager::kAdapterRemovedSignal,
78        base::Bind(&NfcManagerClientImpl::AdapterRemovedReceived,
79                   weak_ptr_factory_.GetWeakPtr()),
80        base::Bind(&NfcManagerClientImpl::AdapterRemovedConnected,
81                   weak_ptr_factory_.GetWeakPtr()));
82
83    // Create the properties structure.
84    properties_.reset(new Properties(
85        object_proxy_,
86        base::Bind(&NfcManagerClientImpl::OnPropertyChanged,
87                   weak_ptr_factory_.GetWeakPtr())));
88
89    properties_->ConnectSignals();
90    properties_->GetAll();
91  }
92
93 private:
94  // NFC manager signal handlers.
95  void OnPropertyChanged(const std::string& property_name) {
96    VLOG(1) << "NFC Manager property changed: " << property_name;
97    FOR_EACH_OBSERVER(Observer, observers_,
98                      ManagerPropertyChanged(property_name));
99  }
100
101  // Called by dbus:: when an "AdapterAdded" signal is received..
102  void AdapterAddedReceived(dbus::Signal* signal) {
103    DCHECK(signal);
104    dbus::MessageReader reader(signal);
105    dbus::ObjectPath object_path;
106    if (!reader.PopObjectPath(&object_path)) {
107      LOG(WARNING) << "AdapterAdded signal has incorrect parameters: "
108                   << signal->ToString();
109      return;
110    }
111    VLOG(1) << "Adapter added: " << object_path.value();
112    FOR_EACH_OBSERVER(Observer, observers_, AdapterAdded(object_path));
113  }
114
115  // Called by dbus:: when the "AdapterAdded" signal is initially connected.
116  void AdapterAddedConnected(const std::string& interface_name,
117                             const std::string& signal_name,
118                             bool success) {
119    LOG_IF(WARNING, !success) << "Failed to connect to AdapterAdded signal.";
120  }
121
122  // Called by dbus:: when an "AdapterRemoved" signal is received..
123  void AdapterRemovedReceived(dbus::Signal* signal) {
124    DCHECK(signal);
125    dbus::MessageReader reader(signal);
126    dbus::ObjectPath object_path;
127    if (!reader.PopObjectPath(&object_path)) {
128      LOG(WARNING) << "AdapterRemoved signal has incorrect parameters: "
129                   << signal->ToString();
130      return;
131    }
132    VLOG(1) << "Adapter removed: " << object_path.value();
133    FOR_EACH_OBSERVER(Observer, observers_, AdapterRemoved(object_path));
134  }
135
136  // Called by dbus:: when the "AdapterAdded" signal is initially connected.
137  void AdapterRemovedConnected(const std::string& interface_name,
138                               const std::string& signal_name,
139                               bool success) {
140    LOG_IF(WARNING, !success) << "Failed to connect to AdapterRemoved signal.";
141  }
142
143  // D-Bus proxy for neard Manager interface.
144  dbus::ObjectProxy* object_proxy_;
145
146  // Properties for neard Manager interface.
147  scoped_ptr<Properties> properties_;
148
149  // List of observers interested in event notifications.
150  ObserverList<NfcManagerClient::Observer> observers_;
151
152  // Weak pointer factory for generating 'this' pointers that might live longer
153  // than we do.
154  // Note: This should remain the last member so it'll be destroyed and
155  // invalidate its weak pointers before any other members are destroyed.
156  base::WeakPtrFactory<NfcManagerClientImpl> weak_ptr_factory_;
157
158  DISALLOW_COPY_AND_ASSIGN(NfcManagerClientImpl);
159};
160
161NfcManagerClient::NfcManagerClient() {
162}
163
164NfcManagerClient::~NfcManagerClient() {
165}
166
167// static
168NfcManagerClient* NfcManagerClient::Create() {
169  return new NfcManagerClientImpl();
170}
171
172}  // namespace chromeos
173