nfc_adapter_client.cc revision f2477e01787aa58f445919b809d89e252beef54f
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_adapter_client.h" 6 7#include <map> 8#include <utility> 9 10#include "base/bind.h" 11#include "base/memory/scoped_ptr.h" 12#include "base/observer_list.h" 13#include "base/strings/stringprintf.h" 14#include "chromeos/dbus/fake_nfc_adapter_client.h" 15#include "chromeos/dbus/nfc_manager_client.h" 16#include "dbus/bus.h" 17#include "dbus/message.h" 18#include "third_party/cros_system_api/dbus/service_constants.h" 19 20namespace chromeos { 21 22NfcAdapterClient::Properties::Properties( 23 dbus::ObjectProxy* object_proxy, 24 const PropertyChangedCallback& callback) 25 : NfcPropertySet(object_proxy, 26 nfc_adapter::kNfcAdapterInterface, 27 callback) { 28 RegisterProperty(nfc_adapter::kModeProperty, &mode); 29 RegisterProperty(nfc_adapter::kPoweredProperty, &powered); 30 RegisterProperty(nfc_adapter::kPollingProperty, &polling); 31 RegisterProperty(nfc_adapter::kProtocolsProperty, &protocols); 32 RegisterProperty(nfc_adapter::kTagsProperty, &tags); 33 RegisterProperty(nfc_adapter::kDevicesProperty, &devices); 34} 35 36NfcAdapterClient::Properties::~Properties() { 37} 38 39// The NfcAdapterClient implementation used in production. 40class NfcAdapterClientImpl 41 : public NfcAdapterClient, 42 public NfcManagerClient::Observer, 43 public nfc_client_helpers::DBusObjectMap::Delegate { 44 public: 45 explicit NfcAdapterClientImpl(NfcManagerClient* manager_client) 46 : bus_(NULL), 47 manager_client_(manager_client), 48 weak_ptr_factory_(this) { 49 DCHECK(manager_client); 50 } 51 52 virtual ~NfcAdapterClientImpl() { 53 manager_client_->RemoveObserver(this); 54 } 55 56 // NfcAdapterClient override. 57 virtual void AddObserver(NfcAdapterClient::Observer* observer) OVERRIDE { 58 DCHECK(observer); 59 observers_.AddObserver(observer); 60 } 61 62 // NfcAdapterClient override. 63 virtual void RemoveObserver(NfcAdapterClient::Observer* observer) OVERRIDE { 64 DCHECK(observer); 65 observers_.RemoveObserver(observer); 66 } 67 68 // NfcAdapterClient override. 69 virtual Properties* GetProperties(const dbus::ObjectPath& object_path) 70 OVERRIDE { 71 return static_cast<Properties*>( 72 object_map_->GetObjectProperties(object_path)); 73 } 74 75 // NfcAdapterClient override. 76 virtual void StartPollLoop( 77 const dbus::ObjectPath& object_path, 78 const std::string& mode, 79 const base::Closure& callback, 80 const nfc_client_helpers::ErrorCallback& error_callback) OVERRIDE { 81 dbus::ObjectProxy* object_proxy = object_map_->GetObjectProxy(object_path); 82 if (!object_proxy) { 83 std::string error_message = 84 base::StringPrintf("NFC adapter with object path \"%s\" does not " 85 "exist.", object_path.value().c_str()); 86 LOG(ERROR) << error_message; 87 error_callback.Run(nfc_client_helpers::kUnknownObjectError, 88 error_message); 89 return; 90 } 91 dbus::MethodCall method_call(nfc_adapter::kNfcAdapterInterface, 92 nfc_adapter::kStartPollLoop); 93 dbus::MessageWriter writer(&method_call); 94 writer.AppendString(mode); 95 object_proxy->CallMethodWithErrorCallback( 96 &method_call, 97 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 98 base::Bind(&nfc_client_helpers::OnSuccess, callback), 99 base::Bind(&nfc_client_helpers::OnError, error_callback)); 100 } 101 102 // NfcAdapterClient override. 103 virtual void StopPollLoop( 104 const dbus::ObjectPath& object_path, 105 const base::Closure& callback, 106 const nfc_client_helpers::ErrorCallback& error_callback) OVERRIDE { 107 dbus::ObjectProxy* object_proxy = object_map_->GetObjectProxy(object_path); 108 if (!object_proxy) { 109 std::string error_message = 110 base::StringPrintf("NFC adapter with object path \"%s\" does not " 111 "exist.", object_path.value().c_str()); 112 LOG(ERROR) << error_message; 113 error_callback.Run(nfc_client_helpers::kUnknownObjectError, 114 error_message); 115 return; 116 } 117 dbus::MethodCall method_call(nfc_adapter::kNfcAdapterInterface, 118 nfc_adapter::kStopPollLoop); 119 object_proxy->CallMethodWithErrorCallback( 120 &method_call, 121 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 122 base::Bind(&nfc_client_helpers::OnSuccess, callback), 123 base::Bind(&nfc_client_helpers::OnError, error_callback)); 124 } 125 126 protected: 127 // DBusClient override. 128 virtual void Init(dbus::Bus* bus) OVERRIDE { 129 VLOG(1) << "Creating NfcAdapterClientImpl"; 130 DCHECK(bus); 131 bus_ = bus; 132 object_map_.reset(new nfc_client_helpers::DBusObjectMap( 133 nfc_adapter::kNfcAdapterServiceName, this, bus)); 134 DCHECK(manager_client_); 135 manager_client_->AddObserver(this); 136 } 137 138 private: 139 // NfcManagerClient::Observer override. 140 virtual void ManagerPropertyChanged( 141 const std::string& property_name) OVERRIDE { 142 // Update the adapter proxies. 143 DCHECK(manager_client_); 144 NfcManagerClient::Properties* manager_properties = 145 manager_client_->GetProperties(); 146 147 // Ignore changes to properties other than "Adapters". 148 if (property_name != manager_properties->adapters.name()) 149 return; 150 151 // Update the known adapters. 152 VLOG(1) << "NFC adapters changed."; 153 const std::vector<dbus::ObjectPath>& received_adapters = 154 manager_properties->adapters.value(); 155 object_map_->UpdateObjects(received_adapters); 156 } 157 158 // nfc_client_helpers::DBusObjectMap::Delegate override. 159 virtual NfcPropertySet* CreateProperties( 160 dbus::ObjectProxy* object_proxy) OVERRIDE { 161 return new Properties( 162 object_proxy, 163 base::Bind(&NfcAdapterClientImpl::OnPropertyChanged, 164 weak_ptr_factory_.GetWeakPtr(), 165 object_proxy->object_path())); 166 } 167 168 // nfc_client_helpers::DBusObjectMap::Delegate override. 169 virtual void ObjectAdded(const dbus::ObjectPath& object_path) OVERRIDE { 170 FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_, 171 AdapterAdded(object_path)); 172 } 173 174 virtual void ObjectRemoved(const dbus::ObjectPath& object_path) OVERRIDE { 175 FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_, 176 AdapterRemoved(object_path)); 177 } 178 179 // Called by NfcPropertySet when a property value is changed, either by 180 // result of a signal or response to a GetAll() or Get() call. 181 void OnPropertyChanged(const dbus::ObjectPath& object_path, 182 const std::string& property_name) { 183 VLOG(1) << "Adapter property changed; Path: " << object_path.value() 184 << " Property: " << property_name; 185 FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_, 186 AdapterPropertyChanged(object_path, property_name)); 187 } 188 189 // We maintain a pointer to the bus to be able to request proxies for 190 // new NFC adapters that appear. 191 dbus::Bus* bus_; 192 193 // List of observers interested in event notifications. 194 ObserverList<NfcAdapterClient::Observer> observers_; 195 196 // Mapping from object paths to object proxies and properties structures that 197 // were already created by us. 198 scoped_ptr<nfc_client_helpers::DBusObjectMap> object_map_; 199 200 // The manager client that we listen to events notifications from. 201 NfcManagerClient* manager_client_; 202 203 // Weak pointer factory for generating 'this' pointers that might live longer 204 // than we do. 205 // Note: This should remain the last member so it'll be destroyed and 206 // invalidate its weak pointers before any other members are destroyed. 207 base::WeakPtrFactory<NfcAdapterClientImpl> weak_ptr_factory_; 208 209 DISALLOW_COPY_AND_ASSIGN(NfcAdapterClientImpl); 210}; 211 212NfcAdapterClient::NfcAdapterClient() { 213} 214 215NfcAdapterClient::~NfcAdapterClient() { 216} 217 218NfcAdapterClient* NfcAdapterClient::Create(DBusClientImplementationType type, 219 NfcManagerClient* manager_client) { 220 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) 221 return new NfcAdapterClientImpl(manager_client); 222 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); 223 return new FakeNfcAdapterClient(); 224} 225 226} // namespace chromeos 227