10f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
20f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
30f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// found in the LICENSE file.
40f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
50f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chromeos/dbus/nfc_tag_client.h"
60f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
70f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/bind.h"
80f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/memory/weak_ptr.h"
90f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/observer_list.h"
100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/strings/stringprintf.h"
110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chromeos/dbus/nfc_adapter_client.h"
120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "dbus/bus.h"
130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "dbus/message.h"
140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)using chromeos::nfc_client_helpers::DBusObjectMap;
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using chromeos::nfc_client_helpers::ObjectProxyTree;
180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace chromeos {
200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)NfcTagClient::Properties::Properties(
220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    dbus::ObjectProxy* object_proxy,
230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const PropertyChangedCallback& callback)
240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    : NfcPropertySet(object_proxy,
250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                     nfc_tag::kNfcTagInterface,
260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                     callback) {
270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RegisterProperty(nfc_tag::kTypeProperty, &type);
280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RegisterProperty(nfc_tag::kProtocolProperty, &protocol);
290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RegisterProperty(nfc_tag::kRecordsProperty, &records);
300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RegisterProperty(nfc_tag::kReadOnlyProperty, &read_only);
310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)NfcTagClient::Properties::~Properties() {
340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// The NfcTagClient implementation used in production.
370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class NfcTagClientImpl : public NfcTagClient,
380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         public NfcAdapterClient::Observer,
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         public DBusObjectMap::Delegate {
400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  explicit NfcTagClientImpl(NfcAdapterClient* adapter_client)
420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      : bus_(NULL),
430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        adapter_client_(adapter_client),
440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        weak_ptr_factory_(this) {
450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DCHECK(adapter_client);
460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual ~NfcTagClientImpl() {
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(adapter_client_);
500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    adapter_client_->RemoveObserver(this);
510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // NfcTagClient override.
540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void AddObserver(NfcTagClient::Observer* observer) OVERRIDE {
550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DCHECK(observer);
560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    observers_.AddObserver(observer);
570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // NfcTagClient override.
600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void RemoveObserver(NfcTagClient::Observer* observer) OVERRIDE {
610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DCHECK(observer);
620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    observers_.RemoveObserver(observer);
630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // NfcTagClient override.
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual Properties* GetProperties(
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const dbus::ObjectPath& object_path) OVERRIDE {
680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return static_cast<Properties*>(
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        adapters_to_object_maps_.FindObjectProperties(object_path));
700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // NfcTagClient override.
730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void Write(
740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      const dbus::ObjectPath& object_path,
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::DictionaryValue& attributes,
760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      const base::Closure& callback,
770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      const nfc_client_helpers::ErrorCallback& error_callback) OVERRIDE {
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    dbus::ObjectProxy* object_proxy =
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        adapters_to_object_maps_.FindObjectProxy(object_path);
800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!object_proxy) {
810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      std::string error_message =
820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          base::StringPrintf("NFC tag with object path \"%s\" does not exist.",
830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                             object_path.value().c_str());
840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      LOG(ERROR) << error_message;
850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      error_callback.Run(nfc_client_helpers::kUnknownObjectError,
860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         error_message);
870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return;
880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // |attributes| should not be empty.
910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (attributes.empty()) {
920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      std::string error_message =
930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          "Cannot write data to tag with empty arguments.";
940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      LOG(ERROR) << error_message;
950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      error_callback.Run(nfc_error::kInvalidArguments, error_message);
960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return;
970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // Create the arguments.
1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    dbus::MethodCall method_call(nfc_tag::kNfcTagInterface, nfc_tag::kWrite);
1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    dbus::MessageWriter array_writer(NULL);
1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    dbus::MessageWriter dict_entry_writer(NULL);
1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    writer.OpenArray("{sv}", &array_writer);
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    for (DictionaryValue::Iterator iter(attributes);
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)         !iter.IsAtEnd(); iter.Advance()) {
1070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      array_writer.OpenDictEntry(&dict_entry_writer);
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      dict_entry_writer.AppendString(iter.key());
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      nfc_client_helpers::AppendValueDataAsVariant(&dict_entry_writer,
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                   iter.value());
1110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      array_writer.CloseContainer(&dict_entry_writer);
1120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
1130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    writer.CloseContainer(&array_writer);
1140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    object_proxy->CallMethodWithErrorCallback(
1160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        &method_call,
1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        base::Bind(&nfc_client_helpers::OnSuccess, callback),
1190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        base::Bind(&nfc_client_helpers::OnError, error_callback));
1200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) protected:
1230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // DBusClient override.
1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void Init(dbus::Bus* bus) OVERRIDE {
1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    VLOG(1) << "Creating NfcTagClientImpl";
1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DCHECK(bus);
1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    bus_ = bus;
1280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DCHECK(adapter_client_);
1290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    adapter_client_->AddObserver(this);
1300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // NfcAdapterClient::Observer override.
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void AdapterAdded(const dbus::ObjectPath& object_path) OVERRIDE {
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    VLOG(1) << "Adapter added. Creating map for tag proxies belonging to "
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            << "adapter: " << object_path.value();
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    adapters_to_object_maps_.CreateObjectMap(
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        object_path, nfc_tag::kNfcTagServiceName, this, bus_);
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // NfcAdapterClient::Observer override.
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void AdapterRemoved(const dbus::ObjectPath& object_path) OVERRIDE {
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Neard doesn't send out property changed signals for the tags that
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // are removed when the adapter they belong to is removed. Clean up the
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // object proxies for devices that are managed by the removed adapter.
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Note: DBusObjectMap guarantees that the Properties structure for the
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // removed adapter will be valid before this method returns.
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    VLOG(1) << "Adapter removed. Cleaning up tag proxies belonging to "
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            << "adapter: " << object_path.value();
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    adapters_to_object_maps_.RemoveObjectMap(object_path);
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // NfcAdapterClient::Observer override.
1540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void AdapterPropertyChanged(
1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      const dbus::ObjectPath& object_path,
1560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      const std::string& property_name) OVERRIDE {
1570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // Update the tag proxies.
1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    DCHECK(adapter_client_);
1590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    NfcAdapterClient::Properties *adapter_properties =
1600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        adapter_client_->GetProperties(object_path);
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(adapter_properties);
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!adapter_properties) {
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      LOG(ERROR) << "No property structure found for adapter: "
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 << object_path.value();
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // Ignore changes to properties other than "Tags".
1690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (property_name != adapter_properties->tags.name())
1700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return;
1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // Update the known tags.
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    VLOG(1) << "NFC tags changed.";
1740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const std::vector<dbus::ObjectPath>& received_tags =
1750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        adapter_properties->tags.value();
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DBusObjectMap* object_map =
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        adapters_to_object_maps_.GetObjectMap(object_path);
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(object_map);
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    object_map->UpdateObjects(received_tags);
1800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // nfc_client_helpers::DBusObjectMap::Delegate override.
1830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual NfcPropertySet* CreateProperties(
1840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      dbus::ObjectProxy* object_proxy) OVERRIDE {
1850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return new Properties(
1860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        object_proxy,
1870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        base::Bind(&NfcTagClientImpl::OnPropertyChanged,
1880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                   object_proxy->object_path()));
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // nfc_client_helpers::DBusObjectMap::Delegate override.
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void ObjectAdded(const dbus::ObjectPath& object_path) OVERRIDE {
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      TagAdded(object_path));
1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void ObjectRemoved(const dbus::ObjectPath& object_path) OVERRIDE {
1990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      TagRemoved(object_path));
2010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Called by NfcPropertySet when a property value is changed, either by
2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // result of a signal or response to a GetAll() or Get() call.
2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void OnPropertyChanged(const dbus::ObjectPath& object_path,
2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         const std::string& property_name) {
2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    VLOG(1) << "Tag property changed; Path: " << object_path.value()
2080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)            << " Property: " << property_name;
2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
2100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                      TagPropertyChanged(object_path, property_name));
2110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // We maintain a pointer to the bus to be able to request proxies for
2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // new NFC tags that appear.
2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  dbus::Bus* bus_;
2160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // List of observers interested in event notifications.
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ObserverList<NfcTagClient::Observer> observers_;
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Mapping from object paths to object proxies and properties structures that
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // were already created by us. This stucture stores a different DBusObjectMap
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // for each known NFC adapter object path.
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ObjectProxyTree adapters_to_object_maps_;
2240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The adapter client that we listen to events notifications from.
2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  NfcAdapterClient* adapter_client_;
2270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Weak pointer factory for generating 'this' pointers that might live longer
2290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // than we do.
2300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Note: This should remain the last member so it'll be destroyed and
2310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // invalidate its weak pointers before any other members are destroyed.
2320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::WeakPtrFactory<NfcTagClientImpl> weak_ptr_factory_;
2330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NfcTagClientImpl);
2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)NfcTagClient::NfcTagClient() {
2380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)NfcTagClient::~NfcTagClient() {
2410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)NfcTagClient* NfcTagClient::Create(NfcAdapterClient* adapter_client) {
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return new NfcTagClientImpl(adapter_client);
2450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace chromeos
248