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