Add a comment to the Browser Blacklist List
[chromium-blink-merge.git] / chromeos / dbus / nfc_tag_client.cc
blobeae3ef9077823c7b3351b701f2d3fb53e31a3af6
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.
5 #include "chromeos/dbus/nfc_tag_client.h"
7 #include "base/bind.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/observer_list.h"
10 #include "base/strings/stringprintf.h"
11 #include "chromeos/dbus/nfc_adapter_client.h"
12 #include "dbus/bus.h"
13 #include "dbus/message.h"
14 #include "dbus/values_util.h"
15 #include "third_party/cros_system_api/dbus/service_constants.h"
17 using chromeos::nfc_client_helpers::DBusObjectMap;
18 using chromeos::nfc_client_helpers::ObjectProxyTree;
20 namespace chromeos {
22 NfcTagClient::Properties::Properties(
23 dbus::ObjectProxy* object_proxy,
24 const PropertyChangedCallback& callback)
25 : NfcPropertySet(object_proxy,
26 nfc_tag::kNfcTagInterface,
27 callback) {
28 RegisterProperty(nfc_tag::kTypeProperty, &type);
29 RegisterProperty(nfc_tag::kProtocolProperty, &protocol);
30 RegisterProperty(nfc_tag::kRecordsProperty, &records);
31 RegisterProperty(nfc_tag::kReadOnlyProperty, &read_only);
34 NfcTagClient::Properties::~Properties() {
37 // The NfcTagClient implementation used in production.
38 class NfcTagClientImpl : public NfcTagClient,
39 public NfcAdapterClient::Observer,
40 public DBusObjectMap::Delegate {
41 public:
42 explicit NfcTagClientImpl(NfcAdapterClient* adapter_client)
43 : bus_(NULL),
44 adapter_client_(adapter_client),
45 weak_ptr_factory_(this) {
46 DCHECK(adapter_client);
49 virtual ~NfcTagClientImpl() {
50 DCHECK(adapter_client_);
51 adapter_client_->RemoveObserver(this);
54 // NfcTagClient override.
55 virtual void AddObserver(NfcTagClient::Observer* observer) OVERRIDE {
56 DCHECK(observer);
57 observers_.AddObserver(observer);
60 // NfcTagClient override.
61 virtual void RemoveObserver(NfcTagClient::Observer* observer) OVERRIDE {
62 DCHECK(observer);
63 observers_.RemoveObserver(observer);
66 // NfcTagClient override.
67 virtual std::vector<dbus::ObjectPath> GetTagsForAdapter(
68 const dbus::ObjectPath& adapter_path) OVERRIDE {
69 DBusObjectMap* object_map =
70 adapters_to_object_maps_.GetObjectMap(adapter_path);
71 if (!object_map)
72 return std::vector<dbus::ObjectPath>();
73 return object_map->GetObjectPaths();
76 // NfcTagClient override.
77 virtual Properties* GetProperties(
78 const dbus::ObjectPath& object_path) OVERRIDE {
79 return static_cast<Properties*>(
80 adapters_to_object_maps_.FindObjectProperties(object_path));
83 // NfcTagClient override.
84 virtual void Write(
85 const dbus::ObjectPath& object_path,
86 const base::DictionaryValue& attributes,
87 const base::Closure& callback,
88 const nfc_client_helpers::ErrorCallback& error_callback) OVERRIDE {
89 dbus::ObjectProxy* object_proxy =
90 adapters_to_object_maps_.FindObjectProxy(object_path);
91 if (!object_proxy) {
92 std::string error_message =
93 base::StringPrintf("NFC tag with object path \"%s\" does not exist.",
94 object_path.value().c_str());
95 LOG(ERROR) << error_message;
96 error_callback.Run(nfc_client_helpers::kUnknownObjectError,
97 error_message);
98 return;
101 // |attributes| should not be empty.
102 if (attributes.empty()) {
103 std::string error_message =
104 "Cannot write data to tag with empty arguments.";
105 LOG(ERROR) << error_message;
106 error_callback.Run(nfc_error::kInvalidArguments, error_message);
107 return;
110 // Create the arguments.
111 dbus::MethodCall method_call(nfc_tag::kNfcTagInterface, nfc_tag::kWrite);
112 dbus::MessageWriter writer(&method_call);
113 dbus::AppendValueData(&writer, attributes);
115 object_proxy->CallMethodWithErrorCallback(
116 &method_call,
117 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
118 base::Bind(&nfc_client_helpers::OnSuccess, callback),
119 base::Bind(&nfc_client_helpers::OnError, error_callback));
122 protected:
123 // DBusClient override.
124 virtual void Init(dbus::Bus* bus) OVERRIDE {
125 VLOG(1) << "Creating NfcTagClientImpl";
126 DCHECK(bus);
127 bus_ = bus;
128 DCHECK(adapter_client_);
129 adapter_client_->AddObserver(this);
132 private:
133 // NfcAdapterClient::Observer override.
134 virtual void AdapterAdded(const dbus::ObjectPath& object_path) OVERRIDE {
135 VLOG(1) << "Adapter added. Creating map for tag proxies belonging to "
136 << "adapter: " << object_path.value();
137 adapters_to_object_maps_.CreateObjectMap(
138 object_path, nfc_tag::kNfcTagServiceName, this, bus_);
141 // NfcAdapterClient::Observer override.
142 virtual void AdapterRemoved(const dbus::ObjectPath& object_path) OVERRIDE {
143 // Neard doesn't send out property changed signals for the tags that
144 // are removed when the adapter they belong to is removed. Clean up the
145 // object proxies for devices that are managed by the removed adapter.
146 // Note: DBusObjectMap guarantees that the Properties structure for the
147 // removed adapter will be valid before this method returns.
148 VLOG(1) << "Adapter removed. Cleaning up tag proxies belonging to "
149 << "adapter: " << object_path.value();
150 adapters_to_object_maps_.RemoveObjectMap(object_path);
153 // NfcAdapterClient::Observer override.
154 virtual void AdapterPropertyChanged(
155 const dbus::ObjectPath& object_path,
156 const std::string& property_name) OVERRIDE {
157 // Update the tag proxies.
158 DCHECK(adapter_client_);
159 NfcAdapterClient::Properties *adapter_properties =
160 adapter_client_->GetProperties(object_path);
161 DCHECK(adapter_properties);
162 if (!adapter_properties) {
163 LOG(ERROR) << "No property structure found for adapter: "
164 << object_path.value();
165 return;
168 // Ignore changes to properties other than "Tags".
169 if (property_name != adapter_properties->tags.name())
170 return;
172 // Update the known tags.
173 VLOG(1) << "NFC tags changed.";
174 const std::vector<dbus::ObjectPath>& received_tags =
175 adapter_properties->tags.value();
176 DBusObjectMap* object_map =
177 adapters_to_object_maps_.GetObjectMap(object_path);
178 DCHECK(object_map);
179 object_map->UpdateObjects(received_tags);
182 // nfc_client_helpers::DBusObjectMap::Delegate override.
183 virtual NfcPropertySet* CreateProperties(
184 dbus::ObjectProxy* object_proxy) OVERRIDE {
185 Properties* properties = new Properties(
186 object_proxy,
187 base::Bind(&NfcTagClientImpl::OnPropertyChanged,
188 weak_ptr_factory_.GetWeakPtr(),
189 object_proxy->object_path()));
190 properties->SetAllPropertiesReceivedCallback(
191 base::Bind(&NfcTagClientImpl::OnPropertiesReceived,
192 weak_ptr_factory_.GetWeakPtr(),
193 object_proxy->object_path()));
194 return properties;
197 // nfc_client_helpers::DBusObjectMap::Delegate override.
198 virtual void ObjectAdded(const dbus::ObjectPath& object_path) OVERRIDE {
199 FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
200 TagAdded(object_path));
203 virtual void ObjectRemoved(const dbus::ObjectPath& object_path) OVERRIDE {
204 FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
205 TagRemoved(object_path));
208 // Called by NfcPropertySet when a property value is changed, either by
209 // result of a signal or response to a GetAll() or Get() call.
210 void OnPropertyChanged(const dbus::ObjectPath& object_path,
211 const std::string& property_name) {
212 VLOG(1) << "Tag property changed; Path: " << object_path.value()
213 << " Property: " << property_name;
214 FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
215 TagPropertyChanged(object_path, property_name));
218 // Called by NfcPropertySet when all properties have been processed as a
219 // result of a call to GetAll.
220 void OnPropertiesReceived(const dbus::ObjectPath& object_path) {
221 VLOG(1) << "All tag properties received; Path: " << object_path.value();
222 FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
223 TagPropertiesReceived(object_path));
226 // We maintain a pointer to the bus to be able to request proxies for
227 // new NFC tags that appear.
228 dbus::Bus* bus_;
230 // List of observers interested in event notifications.
231 ObserverList<NfcTagClient::Observer> observers_;
233 // Mapping from object paths to object proxies and properties structures that
234 // were already created by us. This stucture stores a different DBusObjectMap
235 // for each known NFC adapter object path.
236 ObjectProxyTree adapters_to_object_maps_;
238 // The adapter client that we listen to events notifications from.
239 NfcAdapterClient* adapter_client_;
241 // Weak pointer factory for generating 'this' pointers that might live longer
242 // than we do.
243 // Note: This should remain the last member so it'll be destroyed and
244 // invalidate its weak pointers before any other members are destroyed.
245 base::WeakPtrFactory<NfcTagClientImpl> weak_ptr_factory_;
247 DISALLOW_COPY_AND_ASSIGN(NfcTagClientImpl);
250 NfcTagClient::NfcTagClient() {
253 NfcTagClient::~NfcTagClient() {
256 NfcTagClient* NfcTagClient::Create(NfcAdapterClient* adapter_client) {
257 return new NfcTagClientImpl(adapter_client);
260 } // namespace chromeos