Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chromeos / dbus / nfc_record_client.cc
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_record_client.h"
6
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"
14
15 using chromeos::nfc_client_helpers::DBusObjectMap;
16 using chromeos::nfc_client_helpers::ObjectProxyTree;
17
18 namespace chromeos {
19
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);
34 }
35
36 NfcRecordClient::Properties::~Properties() {
37 }
38
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);
53   }
54
55   virtual ~NfcRecordClientImpl() {
56     DCHECK(device_client_);
57     DCHECK(tag_client_);
58     device_client_->RemoveObserver(this);
59     tag_client_->RemoveObserver(this);
60   }
61
62   // NfcRecordClient override.
63   virtual void AddObserver(NfcRecordClient::Observer* observer) override {
64     DCHECK(observer);
65     observers_.AddObserver(observer);
66   }
67
68   // NfcRecordClient override.
69   virtual void RemoveObserver(NfcRecordClient::Observer* observer) override {
70     DCHECK(observer);
71     observers_.RemoveObserver(observer);
72   }
73
74   virtual 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();
81   }
82
83   virtual std::vector<dbus::ObjectPath> GetRecordsForTag(
84       const dbus::ObjectPath& tag_path) override {
85     return GetRecordsForDevice(tag_path);
86   }
87
88   // NfcRecordClient override.
89   virtual Properties* GetProperties(
90       const dbus::ObjectPath& object_path) override {
91     return static_cast<Properties*>(
92         devices_and_tags_to_object_maps_.FindObjectProperties(object_path));
93   }
94
95  protected:
96   // DBusClient override.
97   virtual void Init(dbus::Bus* bus) override {
98     VLOG(1) << "Creating NfcRecordClient impl";
99     DCHECK(bus);
100     bus_ = bus;
101     DCHECK(device_client_);
102     DCHECK(tag_client_);
103     device_client_->AddObserver(this);
104     tag_client_->AddObserver(this);
105   }
106
107  private:
108   // NfcDeviceClient::Observer override.
109   virtual void DeviceAdded(const dbus::ObjectPath& object_path) override {
110     VLOG(1) << "Device added. Creating map for record proxies belonging to "
111             << "device: " << object_path.value();
112     devices_and_tags_to_object_maps_.CreateObjectMap(
113         object_path, nfc_record::kNfcRecordServiceName, this, bus_);
114   }
115
116   // NfcDeviceClient::Observer override.
117   virtual void DeviceRemoved(const dbus::ObjectPath& object_path) override {
118     // Neard doesn't send out property changed signals for the records that
119     // are removed when the device they belong to is removed. Clean up the
120     // object proxies for records that belong to the removed device.
121     // Note: DBusObjectMap guarantees that the Properties structure for the
122     // removed adapter will be valid before this method returns.
123     VLOG(1) << "Device removed. Cleaning up record proxies belonging to "
124             << "device: " << object_path.value();
125     devices_and_tags_to_object_maps_.RemoveObjectMap(object_path);
126   }
127
128   // NfcDeviceClient::Observer override.
129   virtual void DevicePropertyChanged(
130       const dbus::ObjectPath& object_path,
131       const std::string& property_name) override {
132     // Update the record proxies using records from the device.
133     DCHECK(device_client_);
134     NfcDeviceClient::Properties* device_properties =
135         device_client_->GetProperties(object_path);
136
137     // Ignore changes to properties other than "Records".
138     if (property_name != device_properties->records.name())
139       return;
140
141     // Update known records.
142     VLOG(1) << "NFC records changed.";
143     const std::vector<dbus::ObjectPath>& received_records =
144         device_properties->records.value();
145     DBusObjectMap* object_map =
146         devices_and_tags_to_object_maps_.GetObjectMap(object_path);
147     DCHECK(object_map);
148     object_map->UpdateObjects(received_records);
149   }
150
151   // NfcTagClient::Observer override.
152   virtual void TagAdded(const dbus::ObjectPath& object_path) override {
153     VLOG(1) << "Tag added. Creating map for record proxies belonging to "
154             << "tag: " << object_path.value();
155     devices_and_tags_to_object_maps_.CreateObjectMap(
156         object_path, nfc_record::kNfcRecordServiceName, this, bus_);
157   }
158
159   // NfcTagClient::Observer override.
160   virtual void TagRemoved(const dbus::ObjectPath& object_path) override {
161     // Neard doesn't send out property changed signals for the records that
162     // are removed when the tag they belong to is removed. Clean up the
163     // object proxies for records that belong to the removed tag.
164     // Note: DBusObjectMap guarantees that the Properties structure for the
165     // removed adapter will be valid before this method returns.
166     VLOG(1) << "Tag removed. Cleaning up record proxies belonging to "
167             << "tag: " << object_path.value();
168     devices_and_tags_to_object_maps_.RemoveObjectMap(object_path);
169   }
170
171   // NfcTagClient::Observer override.
172   virtual void TagPropertyChanged(const dbus::ObjectPath& object_path,
173                                   const std::string& property_name) override {
174     // Update the record proxies using records from the tag.
175     DCHECK(device_client_);
176     NfcTagClient::Properties* tag_properties =
177         tag_client_->GetProperties(object_path);
178
179     // Ignore changes to properties other than "Records".
180     if (property_name != tag_properties->records.name())
181       return;
182
183     // Update known records.
184     VLOG(1) << "NFC records changed.";
185     const std::vector<dbus::ObjectPath>& received_records =
186         tag_properties->records.value();
187     DBusObjectMap* object_map =
188         devices_and_tags_to_object_maps_.GetObjectMap(object_path);
189     DCHECK(object_map);
190     object_map->UpdateObjects(received_records);
191
192     // When rewriting the record to a tag, neard fires a property changed
193     // signal for the tags "Records" property, without creating a new object
194     // path. Sync the properties of all records here, in case Update objects
195     // doesn't do it.
196     VLOG(1) << "Fetch properties for all records.";
197     object_map->RefreshAllProperties();
198   }
199
200   // nfc_client_helpers::DBusObjectMap::Delegate override.
201   virtual NfcPropertySet* CreateProperties(
202       dbus::ObjectProxy* object_proxy) override {
203     Properties* properties = new Properties(
204         object_proxy,
205         base::Bind(&NfcRecordClientImpl::OnPropertyChanged,
206                    weak_ptr_factory_.GetWeakPtr(),
207                    object_proxy->object_path()));
208     properties->SetAllPropertiesReceivedCallback(
209         base::Bind(&NfcRecordClientImpl::OnPropertiesReceived,
210                    weak_ptr_factory_.GetWeakPtr(),
211                    object_proxy->object_path()));
212     return properties;
213   }
214
215   // nfc_client_helpers::DBusObjectMap::Delegate override.
216   virtual void ObjectAdded(const dbus::ObjectPath& object_path) override {
217     FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
218                       RecordAdded(object_path));
219   }
220
221   // nfc_client_helpers::DBusObjectMap::Delegate override.
222   virtual void ObjectRemoved(const dbus::ObjectPath& object_path) override {
223     FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
224                       RecordRemoved(object_path));
225   }
226
227   // Called by NfcPropertySet when a property value is changed, either by
228   // result of a signal or response to a GetAll() or Get() call.
229   void OnPropertyChanged(const dbus::ObjectPath& object_path,
230                          const std::string& property_name) {
231     VLOG(1) << "Record property changed; Path: " << object_path.value()
232             << " Property: " << property_name;
233     FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
234                       RecordPropertyChanged(object_path, property_name));
235   }
236
237   // Called by NfcPropertySet when all properties have been processed as a
238   // result of a call to GetAll.
239   void OnPropertiesReceived(const dbus::ObjectPath& object_path) {
240     VLOG(1) << "All record properties received; Path: " << object_path.value();
241     FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
242                       RecordPropertiesReceived(object_path));
243   }
244
245   // We maintain a pointer to the bus to be able to request proxies for
246   // new NFC records that appear.
247   dbus::Bus* bus_;
248
249   // List of observers interested in event notifications.
250   ObserverList<NfcRecordClient::Observer> observers_;
251
252   // Mapping from object paths to object proxies and properties structures that
253   // were already created by us. Record objects belong to either Tag or Device
254   // objects. This structure stores a different DBusObjectMap for each known
255   // device and tag.
256   ObjectProxyTree devices_and_tags_to_object_maps_;
257
258   // The device and tag clients that we listen to events notifications from.
259   NfcDeviceClient* device_client_;
260   NfcTagClient* tag_client_;
261   // Weak pointer factory for generating 'this' pointers that might live longer
262   // than we do.
263   // Note: This should remain the last member so it'll be destroyed and
264   // invalidate its weak pointers before any other members are destroyed.
265   base::WeakPtrFactory<NfcRecordClientImpl> weak_ptr_factory_;
266
267   DISALLOW_COPY_AND_ASSIGN(NfcRecordClientImpl);
268 };
269
270 NfcRecordClient::NfcRecordClient() {
271 }
272
273 NfcRecordClient::~NfcRecordClient() {
274 }
275
276 NfcRecordClient* NfcRecordClient::Create(NfcDeviceClient* device_client,
277                                          NfcTagClient* tag_client) {
278   return new NfcRecordClientImpl(device_client, tag_client);
279 }
280
281 }  // namespace chromeos