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