Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chromeos / dbus / nfc_record_client.cc
blobf462d698084039d87d4067e0e42b7774985feb1c
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_record_client.h"
7 #include "base/bind.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/observer_list.h"
10 #include "chromeos/dbus/nfc_device_client.h"
11 #include "chromeos/dbus/nfc_tag_client.h"
12 #include "dbus/bus.h"
13 #include "third_party/cros_system_api/dbus/service_constants.h"
15 using chromeos::nfc_client_helpers::DBusObjectMap;
16 using chromeos::nfc_client_helpers::ObjectProxyTree;
18 namespace chromeos {
20 NfcRecordClient::Properties::Properties(
21 dbus::ObjectProxy* object_proxy,
22 const PropertyChangedCallback& callback)
23 : NfcPropertySet(object_proxy,
24 nfc_record::kNfcRecordInterface,
25 callback) {
26 RegisterProperty(nfc_record::kTypeProperty, &type);
27 RegisterProperty(nfc_record::kLanguageProperty, &language);
28 RegisterProperty(nfc_record::kEncodingProperty, &encoding);
29 RegisterProperty(nfc_record::kRepresentationProperty, &representation);
30 RegisterProperty(nfc_record::kUriProperty, &uri);
31 RegisterProperty(nfc_record::kMimeTypeProperty, &mime_type);
32 RegisterProperty(nfc_record::kSizeProperty, &size);
33 RegisterProperty(nfc_record::kActionProperty, &action);
36 NfcRecordClient::Properties::~Properties() {
39 // The NfcRecordClient implementation used in production.
40 class NfcRecordClientImpl : public NfcRecordClient,
41 public NfcDeviceClient::Observer,
42 public NfcTagClient::Observer,
43 public DBusObjectMap::Delegate {
44 public:
45 explicit NfcRecordClientImpl(NfcDeviceClient* device_client,
46 NfcTagClient* tag_client)
47 : bus_(NULL),
48 device_client_(device_client),
49 tag_client_(tag_client),
50 weak_ptr_factory_(this) {
51 DCHECK(device_client);
52 DCHECK(tag_client);
55 ~NfcRecordClientImpl() override {
56 DCHECK(device_client_);
57 DCHECK(tag_client_);
58 device_client_->RemoveObserver(this);
59 tag_client_->RemoveObserver(this);
62 // NfcRecordClient override.
63 void AddObserver(NfcRecordClient::Observer* observer) override {
64 DCHECK(observer);
65 observers_.AddObserver(observer);
68 // NfcRecordClient override.
69 void RemoveObserver(NfcRecordClient::Observer* observer) override {
70 DCHECK(observer);
71 observers_.RemoveObserver(observer);
74 std::vector<dbus::ObjectPath> GetRecordsForDevice(
75 const dbus::ObjectPath& device_path) override {
76 DBusObjectMap* object_map =
77 devices_and_tags_to_object_maps_.GetObjectMap(device_path);
78 if (!object_map)
79 return std::vector<dbus::ObjectPath>();
80 return object_map->GetObjectPaths();
83 std::vector<dbus::ObjectPath> GetRecordsForTag(
84 const dbus::ObjectPath& tag_path) override {
85 return GetRecordsForDevice(tag_path);
88 // NfcRecordClient override.
89 Properties* GetProperties(const dbus::ObjectPath& object_path) override {
90 return static_cast<Properties*>(
91 devices_and_tags_to_object_maps_.FindObjectProperties(object_path));
94 protected:
95 // DBusClient override.
96 void Init(dbus::Bus* bus) override {
97 VLOG(1) << "Creating NfcRecordClient impl";
98 DCHECK(bus);
99 bus_ = bus;
100 DCHECK(device_client_);
101 DCHECK(tag_client_);
102 device_client_->AddObserver(this);
103 tag_client_->AddObserver(this);
106 private:
107 // NfcDeviceClient::Observer override.
108 void DeviceAdded(const dbus::ObjectPath& object_path) override {
109 VLOG(1) << "Device added. Creating map for record proxies belonging to "
110 << "device: " << object_path.value();
111 devices_and_tags_to_object_maps_.CreateObjectMap(
112 object_path, nfc_record::kNfcRecordServiceName, this, bus_);
115 // NfcDeviceClient::Observer override.
116 void DeviceRemoved(const dbus::ObjectPath& object_path) override {
117 // Neard doesn't send out property changed signals for the records that
118 // are removed when the device they belong to is removed. Clean up the
119 // object proxies for records that belong to the removed device.
120 // Note: DBusObjectMap guarantees that the Properties structure for the
121 // removed adapter will be valid before this method returns.
122 VLOG(1) << "Device removed. Cleaning up record proxies belonging to "
123 << "device: " << object_path.value();
124 devices_and_tags_to_object_maps_.RemoveObjectMap(object_path);
127 // NfcDeviceClient::Observer override.
128 void DevicePropertyChanged(const dbus::ObjectPath& object_path,
129 const std::string& property_name) override {
130 // Update the record proxies using records from the device.
131 DCHECK(device_client_);
132 NfcDeviceClient::Properties* device_properties =
133 device_client_->GetProperties(object_path);
135 // Ignore changes to properties other than "Records".
136 if (property_name != device_properties->records.name())
137 return;
139 // Update known records.
140 VLOG(1) << "NFC records changed.";
141 const std::vector<dbus::ObjectPath>& received_records =
142 device_properties->records.value();
143 DBusObjectMap* object_map =
144 devices_and_tags_to_object_maps_.GetObjectMap(object_path);
145 DCHECK(object_map);
146 object_map->UpdateObjects(received_records);
149 // NfcTagClient::Observer override.
150 void TagAdded(const dbus::ObjectPath& object_path) override {
151 VLOG(1) << "Tag added. Creating map for record proxies belonging to "
152 << "tag: " << object_path.value();
153 devices_and_tags_to_object_maps_.CreateObjectMap(
154 object_path, nfc_record::kNfcRecordServiceName, this, bus_);
157 // NfcTagClient::Observer override.
158 void TagRemoved(const dbus::ObjectPath& object_path) override {
159 // Neard doesn't send out property changed signals for the records that
160 // are removed when the tag they belong to is removed. Clean up the
161 // object proxies for records that belong to the removed tag.
162 // Note: DBusObjectMap guarantees that the Properties structure for the
163 // removed adapter will be valid before this method returns.
164 VLOG(1) << "Tag removed. Cleaning up record proxies belonging to "
165 << "tag: " << object_path.value();
166 devices_and_tags_to_object_maps_.RemoveObjectMap(object_path);
169 // NfcTagClient::Observer override.
170 void TagPropertyChanged(const dbus::ObjectPath& object_path,
171 const std::string& property_name) override {
172 // Update the record proxies using records from the tag.
173 DCHECK(device_client_);
174 NfcTagClient::Properties* tag_properties =
175 tag_client_->GetProperties(object_path);
177 // Ignore changes to properties other than "Records".
178 if (property_name != tag_properties->records.name())
179 return;
181 // Update known records.
182 VLOG(1) << "NFC records changed.";
183 const std::vector<dbus::ObjectPath>& received_records =
184 tag_properties->records.value();
185 DBusObjectMap* object_map =
186 devices_and_tags_to_object_maps_.GetObjectMap(object_path);
187 DCHECK(object_map);
188 object_map->UpdateObjects(received_records);
190 // When rewriting the record to a tag, neard fires a property changed
191 // signal for the tags "Records" property, without creating a new object
192 // path. Sync the properties of all records here, in case Update objects
193 // doesn't do it.
194 VLOG(1) << "Fetch properties for all records.";
195 object_map->RefreshAllProperties();
198 // nfc_client_helpers::DBusObjectMap::Delegate override.
199 NfcPropertySet* CreateProperties(dbus::ObjectProxy* object_proxy) override {
200 Properties* properties = new Properties(
201 object_proxy,
202 base::Bind(&NfcRecordClientImpl::OnPropertyChanged,
203 weak_ptr_factory_.GetWeakPtr(),
204 object_proxy->object_path()));
205 properties->SetAllPropertiesReceivedCallback(
206 base::Bind(&NfcRecordClientImpl::OnPropertiesReceived,
207 weak_ptr_factory_.GetWeakPtr(),
208 object_proxy->object_path()));
209 return properties;
212 // nfc_client_helpers::DBusObjectMap::Delegate override.
213 void ObjectAdded(const dbus::ObjectPath& object_path) override {
214 FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
215 RecordAdded(object_path));
218 // nfc_client_helpers::DBusObjectMap::Delegate override.
219 void ObjectRemoved(const dbus::ObjectPath& object_path) override {
220 FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
221 RecordRemoved(object_path));
224 // Called by NfcPropertySet when a property value is changed, either by
225 // result of a signal or response to a GetAll() or Get() call.
226 void OnPropertyChanged(const dbus::ObjectPath& object_path,
227 const std::string& property_name) {
228 VLOG(1) << "Record property changed; Path: " << object_path.value()
229 << " Property: " << property_name;
230 FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
231 RecordPropertyChanged(object_path, property_name));
234 // Called by NfcPropertySet when all properties have been processed as a
235 // result of a call to GetAll.
236 void OnPropertiesReceived(const dbus::ObjectPath& object_path) {
237 VLOG(1) << "All record properties received; Path: " << object_path.value();
238 FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
239 RecordPropertiesReceived(object_path));
242 // We maintain a pointer to the bus to be able to request proxies for
243 // new NFC records that appear.
244 dbus::Bus* bus_;
246 // List of observers interested in event notifications.
247 base::ObserverList<NfcRecordClient::Observer> observers_;
249 // Mapping from object paths to object proxies and properties structures that
250 // were already created by us. Record objects belong to either Tag or Device
251 // objects. This structure stores a different DBusObjectMap for each known
252 // device and tag.
253 ObjectProxyTree devices_and_tags_to_object_maps_;
255 // The device and tag clients that we listen to events notifications from.
256 NfcDeviceClient* device_client_;
257 NfcTagClient* tag_client_;
258 // Weak pointer factory for generating 'this' pointers that might live longer
259 // than we do.
260 // Note: This should remain the last member so it'll be destroyed and
261 // invalidate its weak pointers before any other members are destroyed.
262 base::WeakPtrFactory<NfcRecordClientImpl> weak_ptr_factory_;
264 DISALLOW_COPY_AND_ASSIGN(NfcRecordClientImpl);
267 NfcRecordClient::NfcRecordClient() {
270 NfcRecordClient::~NfcRecordClient() {
273 NfcRecordClient* NfcRecordClient::Create(NfcDeviceClient* device_client,
274 NfcTagClient* tag_client) {
275 return new NfcRecordClientImpl(device_client, tag_client);
278 } // namespace chromeos