[Password Generation] Enable new UI
[chromium-blink-merge.git] / chromeos / dbus / nfc_tag_client.cc
blob6c439fa47c082a59889e4114445ca5adf5a1a187
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 "third_party/cros_system_api/dbus/service_constants.h"
16 using chromeos::nfc_client_helpers::DBusObjectMap;
17 using chromeos::nfc_client_helpers::ObjectProxyTree;
19 namespace chromeos {
21 NfcTagClient::Properties::Properties(
22 dbus::ObjectProxy* object_proxy,
23 const PropertyChangedCallback& callback)
24 : NfcPropertySet(object_proxy,
25 nfc_tag::kNfcTagInterface,
26 callback) {
27 RegisterProperty(nfc_tag::kTypeProperty, &type);
28 RegisterProperty(nfc_tag::kProtocolProperty, &protocol);
29 RegisterProperty(nfc_tag::kRecordsProperty, &records);
30 RegisterProperty(nfc_tag::kReadOnlyProperty, &read_only);
33 NfcTagClient::Properties::~Properties() {
36 // The NfcTagClient implementation used in production.
37 class NfcTagClientImpl : public NfcTagClient,
38 public NfcAdapterClient::Observer,
39 public DBusObjectMap::Delegate {
40 public:
41 explicit NfcTagClientImpl(NfcAdapterClient* adapter_client)
42 : bus_(NULL),
43 adapter_client_(adapter_client),
44 weak_ptr_factory_(this) {
45 DCHECK(adapter_client);
48 virtual ~NfcTagClientImpl() {
49 DCHECK(adapter_client_);
50 adapter_client_->RemoveObserver(this);
53 // NfcTagClient override.
54 virtual void AddObserver(NfcTagClient::Observer* observer) OVERRIDE {
55 DCHECK(observer);
56 observers_.AddObserver(observer);
59 // NfcTagClient override.
60 virtual void RemoveObserver(NfcTagClient::Observer* observer) OVERRIDE {
61 DCHECK(observer);
62 observers_.RemoveObserver(observer);
65 // NfcTagClient override.
66 virtual std::vector<dbus::ObjectPath> GetTagsForAdapter(
67 const dbus::ObjectPath& adapter_path) OVERRIDE {
68 DBusObjectMap* object_map =
69 adapters_to_object_maps_.GetObjectMap(adapter_path);
70 if (!object_map)
71 return std::vector<dbus::ObjectPath>();
72 return object_map->GetObjectPaths();
75 // NfcTagClient override.
76 virtual Properties* GetProperties(
77 const dbus::ObjectPath& object_path) OVERRIDE {
78 return static_cast<Properties*>(
79 adapters_to_object_maps_.FindObjectProperties(object_path));
82 // NfcTagClient override.
83 virtual void Write(
84 const dbus::ObjectPath& object_path,
85 const base::DictionaryValue& attributes,
86 const base::Closure& callback,
87 const nfc_client_helpers::ErrorCallback& error_callback) OVERRIDE {
88 dbus::ObjectProxy* object_proxy =
89 adapters_to_object_maps_.FindObjectProxy(object_path);
90 if (!object_proxy) {
91 std::string error_message =
92 base::StringPrintf("NFC tag with object path \"%s\" does not exist.",
93 object_path.value().c_str());
94 LOG(ERROR) << error_message;
95 error_callback.Run(nfc_client_helpers::kUnknownObjectError,
96 error_message);
97 return;
100 // |attributes| should not be empty.
101 if (attributes.empty()) {
102 std::string error_message =
103 "Cannot write data to tag with empty arguments.";
104 LOG(ERROR) << error_message;
105 error_callback.Run(nfc_error::kInvalidArguments, error_message);
106 return;
109 // Create the arguments.
110 dbus::MethodCall method_call(nfc_tag::kNfcTagInterface, nfc_tag::kWrite);
111 dbus::MessageWriter writer(&method_call);
112 dbus::MessageWriter array_writer(NULL);
113 dbus::MessageWriter dict_entry_writer(NULL);
114 writer.OpenArray("{sv}", &array_writer);
115 for (base::DictionaryValue::Iterator iter(attributes);
116 !iter.IsAtEnd(); iter.Advance()) {
117 array_writer.OpenDictEntry(&dict_entry_writer);
118 dict_entry_writer.AppendString(iter.key());
119 nfc_client_helpers::AppendValueDataAsVariant(&dict_entry_writer,
120 iter.value());
121 array_writer.CloseContainer(&dict_entry_writer);
123 writer.CloseContainer(&array_writer);
125 object_proxy->CallMethodWithErrorCallback(
126 &method_call,
127 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
128 base::Bind(&nfc_client_helpers::OnSuccess, callback),
129 base::Bind(&nfc_client_helpers::OnError, error_callback));
132 protected:
133 // DBusClient override.
134 virtual void Init(dbus::Bus* bus) OVERRIDE {
135 VLOG(1) << "Creating NfcTagClientImpl";
136 DCHECK(bus);
137 bus_ = bus;
138 DCHECK(adapter_client_);
139 adapter_client_->AddObserver(this);
142 private:
143 // NfcAdapterClient::Observer override.
144 virtual void AdapterAdded(const dbus::ObjectPath& object_path) OVERRIDE {
145 VLOG(1) << "Adapter added. Creating map for tag proxies belonging to "
146 << "adapter: " << object_path.value();
147 adapters_to_object_maps_.CreateObjectMap(
148 object_path, nfc_tag::kNfcTagServiceName, this, bus_);
151 // NfcAdapterClient::Observer override.
152 virtual void AdapterRemoved(const dbus::ObjectPath& object_path) OVERRIDE {
153 // Neard doesn't send out property changed signals for the tags that
154 // are removed when the adapter they belong to is removed. Clean up the
155 // object proxies for devices that are managed by the removed adapter.
156 // Note: DBusObjectMap guarantees that the Properties structure for the
157 // removed adapter will be valid before this method returns.
158 VLOG(1) << "Adapter removed. Cleaning up tag proxies belonging to "
159 << "adapter: " << object_path.value();
160 adapters_to_object_maps_.RemoveObjectMap(object_path);
163 // NfcAdapterClient::Observer override.
164 virtual void AdapterPropertyChanged(
165 const dbus::ObjectPath& object_path,
166 const std::string& property_name) OVERRIDE {
167 // Update the tag proxies.
168 DCHECK(adapter_client_);
169 NfcAdapterClient::Properties *adapter_properties =
170 adapter_client_->GetProperties(object_path);
171 DCHECK(adapter_properties);
172 if (!adapter_properties) {
173 LOG(ERROR) << "No property structure found for adapter: "
174 << object_path.value();
175 return;
178 // Ignore changes to properties other than "Tags".
179 if (property_name != adapter_properties->tags.name())
180 return;
182 // Update the known tags.
183 VLOG(1) << "NFC tags changed.";
184 const std::vector<dbus::ObjectPath>& received_tags =
185 adapter_properties->tags.value();
186 DBusObjectMap* object_map =
187 adapters_to_object_maps_.GetObjectMap(object_path);
188 DCHECK(object_map);
189 object_map->UpdateObjects(received_tags);
192 // nfc_client_helpers::DBusObjectMap::Delegate override.
193 virtual NfcPropertySet* CreateProperties(
194 dbus::ObjectProxy* object_proxy) OVERRIDE {
195 Properties* properties = new Properties(
196 object_proxy,
197 base::Bind(&NfcTagClientImpl::OnPropertyChanged,
198 weak_ptr_factory_.GetWeakPtr(),
199 object_proxy->object_path()));
200 properties->SetAllPropertiesReceivedCallback(
201 base::Bind(&NfcTagClientImpl::OnPropertiesReceived,
202 weak_ptr_factory_.GetWeakPtr(),
203 object_proxy->object_path()));
204 return properties;
207 // nfc_client_helpers::DBusObjectMap::Delegate override.
208 virtual void ObjectAdded(const dbus::ObjectPath& object_path) OVERRIDE {
209 FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
210 TagAdded(object_path));
213 virtual void ObjectRemoved(const dbus::ObjectPath& object_path) OVERRIDE {
214 FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
215 TagRemoved(object_path));
218 // Called by NfcPropertySet when a property value is changed, either by
219 // result of a signal or response to a GetAll() or Get() call.
220 void OnPropertyChanged(const dbus::ObjectPath& object_path,
221 const std::string& property_name) {
222 VLOG(1) << "Tag property changed; Path: " << object_path.value()
223 << " Property: " << property_name;
224 FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
225 TagPropertyChanged(object_path, property_name));
228 // Called by NfcPropertySet when all properties have been processed as a
229 // result of a call to GetAll.
230 void OnPropertiesReceived(const dbus::ObjectPath& object_path) {
231 VLOG(1) << "All tag properties received; Path: " << object_path.value();
232 FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
233 TagPropertiesReceived(object_path));
236 // We maintain a pointer to the bus to be able to request proxies for
237 // new NFC tags that appear.
238 dbus::Bus* bus_;
240 // List of observers interested in event notifications.
241 ObserverList<NfcTagClient::Observer> observers_;
243 // Mapping from object paths to object proxies and properties structures that
244 // were already created by us. This stucture stores a different DBusObjectMap
245 // for each known NFC adapter object path.
246 ObjectProxyTree adapters_to_object_maps_;
248 // The adapter client that we listen to events notifications from.
249 NfcAdapterClient* adapter_client_;
251 // Weak pointer factory for generating 'this' pointers that might live longer
252 // than we do.
253 // Note: This should remain the last member so it'll be destroyed and
254 // invalidate its weak pointers before any other members are destroyed.
255 base::WeakPtrFactory<NfcTagClientImpl> weak_ptr_factory_;
257 DISALLOW_COPY_AND_ASSIGN(NfcTagClientImpl);
260 NfcTagClient::NfcTagClient() {
263 NfcTagClient::~NfcTagClient() {
266 NfcTagClient* NfcTagClient::Create(NfcAdapterClient* adapter_client) {
267 return new NfcTagClientImpl(adapter_client);
270 } // namespace chromeos