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/bluetooth_adapter_client.h" 6 7 #include "base/bind.h" 8 #include "base/logging.h" 9 #include "chromeos/dbus/fake_bluetooth_adapter_client.h" 10 #include "dbus/bus.h" 11 #include "dbus/message.h" 12 #include "dbus/object_manager.h" 13 #include "dbus/object_path.h" 14 #include "dbus/object_proxy.h" 15 #include "third_party/cros_system_api/dbus/service_constants.h" 16 17 namespace chromeos { 18 19 const char BluetoothAdapterClient::kNoResponseError[] = 20 "org.chromium.Error.NoResponse"; 21 const char BluetoothAdapterClient::kUnknownAdapterError[] = 22 "org.chromium.Error.UnknownAdapter"; 23 24 BluetoothAdapterClient::Properties::Properties( 25 dbus::ObjectProxy* object_proxy, 26 const std::string& interface_name, 27 const PropertyChangedCallback& callback) 28 : dbus::PropertySet(object_proxy, interface_name, callback) { 29 RegisterProperty(bluetooth_adapter::kAddressProperty, &address); 30 RegisterProperty(bluetooth_adapter::kNameProperty, &name); 31 RegisterProperty(bluetooth_adapter::kAliasProperty, &alias); 32 RegisterProperty(bluetooth_adapter::kClassProperty, &bluetooth_class); 33 RegisterProperty(bluetooth_adapter::kPoweredProperty, &powered); 34 RegisterProperty(bluetooth_adapter::kDiscoverableProperty, &discoverable); 35 RegisterProperty(bluetooth_adapter::kPairableProperty, &pairable); 36 RegisterProperty(bluetooth_adapter::kPairableTimeoutProperty, 37 &pairable_timeout); 38 RegisterProperty(bluetooth_adapter::kDiscoverableTimeoutProperty, 39 &discoverable_timeout); 40 RegisterProperty(bluetooth_adapter::kDiscoveringProperty, &discovering); 41 RegisterProperty(bluetooth_adapter::kUUIDsProperty, &uuids); 42 RegisterProperty(bluetooth_adapter::kModaliasProperty, &modalias); 43 } 44 45 BluetoothAdapterClient::Properties::~Properties() { 46 } 47 48 49 // The BluetoothAdapterClient implementation used in production. 50 class BluetoothAdapterClientImpl 51 : public BluetoothAdapterClient, 52 public dbus::ObjectManager::Interface { 53 public: 54 explicit BluetoothAdapterClientImpl(dbus::Bus* bus) 55 : bus_(bus), 56 weak_ptr_factory_(this) { 57 object_manager_ = bus_->GetObjectManager( 58 bluetooth_object_manager::kBluetoothObjectManagerServiceName, 59 dbus::ObjectPath( 60 bluetooth_object_manager::kBluetoothObjectManagerServicePath)); 61 object_manager_->RegisterInterface( 62 bluetooth_adapter::kBluetoothAdapterInterface, this); 63 } 64 65 virtual ~BluetoothAdapterClientImpl() { 66 object_manager_->UnregisterInterface( 67 bluetooth_adapter::kBluetoothAdapterInterface); 68 } 69 70 // BluetoothAdapterClient override. 71 virtual void AddObserver(BluetoothAdapterClient::Observer* observer) 72 OVERRIDE { 73 DCHECK(observer); 74 observers_.AddObserver(observer); 75 } 76 77 // BluetoothAdapterClient override. 78 virtual void RemoveObserver(BluetoothAdapterClient::Observer* observer) 79 OVERRIDE { 80 DCHECK(observer); 81 observers_.RemoveObserver(observer); 82 } 83 84 // Returns the list of adapter object paths known to the system. 85 virtual std::vector<dbus::ObjectPath> GetAdapters() OVERRIDE { 86 return object_manager_->GetObjectsWithInterface( 87 bluetooth_adapter::kBluetoothAdapterInterface); 88 } 89 90 // dbus::ObjectManager::Interface override. 91 virtual dbus::PropertySet* CreateProperties( 92 dbus::ObjectProxy* object_proxy, 93 const dbus::ObjectPath& object_path, 94 const std::string& interface_name) OVERRIDE { 95 Properties* properties = new Properties( 96 object_proxy, 97 interface_name, 98 base::Bind(&BluetoothAdapterClientImpl::OnPropertyChanged, 99 weak_ptr_factory_.GetWeakPtr(), 100 object_path)); 101 return static_cast<dbus::PropertySet*>(properties); 102 } 103 104 // BluetoothAdapterClient override. 105 virtual Properties* GetProperties(const dbus::ObjectPath& object_path) 106 OVERRIDE { 107 return static_cast<Properties*>( 108 object_manager_->GetProperties( 109 object_path, 110 bluetooth_adapter::kBluetoothAdapterInterface)); 111 } 112 113 // BluetoothAdapterClient override. 114 virtual void StartDiscovery(const dbus::ObjectPath& object_path, 115 const base::Closure& callback, 116 const ErrorCallback& error_callback) OVERRIDE { 117 dbus::MethodCall method_call( 118 bluetooth_adapter::kBluetoothAdapterInterface, 119 bluetooth_adapter::kStartDiscovery); 120 121 dbus::ObjectProxy* object_proxy = 122 object_manager_->GetObjectProxy(object_path); 123 if (!object_proxy) { 124 error_callback.Run(kUnknownAdapterError, ""); 125 return; 126 } 127 128 object_proxy->CallMethodWithErrorCallback( 129 &method_call, 130 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 131 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, 132 weak_ptr_factory_.GetWeakPtr(), callback), 133 base::Bind(&BluetoothAdapterClientImpl::OnError, 134 weak_ptr_factory_.GetWeakPtr(), error_callback)); 135 } 136 137 // BluetoothAdapterClient override. 138 virtual void StopDiscovery(const dbus::ObjectPath& object_path, 139 const base::Closure& callback, 140 const ErrorCallback& error_callback) OVERRIDE { 141 dbus::MethodCall method_call( 142 bluetooth_adapter::kBluetoothAdapterInterface, 143 bluetooth_adapter::kStopDiscovery); 144 145 dbus::ObjectProxy* object_proxy = 146 object_manager_->GetObjectProxy(object_path); 147 if (!object_proxy) { 148 error_callback.Run(kUnknownAdapterError, ""); 149 return; 150 } 151 152 object_proxy->CallMethodWithErrorCallback( 153 &method_call, 154 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 155 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, 156 weak_ptr_factory_.GetWeakPtr(), callback), 157 base::Bind(&BluetoothAdapterClientImpl::OnError, 158 weak_ptr_factory_.GetWeakPtr(), error_callback)); 159 } 160 161 // BluetoothAdapterClient override. 162 virtual void RemoveDevice(const dbus::ObjectPath& object_path, 163 const dbus::ObjectPath& device_path, 164 const base::Closure& callback, 165 const ErrorCallback& error_callback) OVERRIDE { 166 dbus::MethodCall method_call( 167 bluetooth_adapter::kBluetoothAdapterInterface, 168 bluetooth_adapter::kRemoveDevice); 169 170 dbus::MessageWriter writer(&method_call); 171 writer.AppendObjectPath(device_path); 172 173 dbus::ObjectProxy* object_proxy = 174 object_manager_->GetObjectProxy(object_path); 175 if (!object_proxy) { 176 error_callback.Run(kUnknownAdapterError, ""); 177 return; 178 } 179 180 object_proxy->CallMethodWithErrorCallback( 181 &method_call, 182 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 183 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, 184 weak_ptr_factory_.GetWeakPtr(), callback), 185 base::Bind(&BluetoothAdapterClientImpl::OnError, 186 weak_ptr_factory_.GetWeakPtr(), error_callback)); 187 } 188 189 private: 190 // Called by dbus::ObjectManager when an object with the adapter interface 191 // is created. Informs observers. 192 virtual void ObjectAdded(const dbus::ObjectPath& object_path, 193 const std::string& interface_name) OVERRIDE { 194 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, 195 AdapterAdded(object_path)); 196 } 197 198 // Called by dbus::ObjectManager when an object with the adapter interface 199 // is removed. Informs observers. 200 virtual void ObjectRemoved(const dbus::ObjectPath& object_path, 201 const std::string& interface_name) OVERRIDE { 202 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, 203 AdapterRemoved(object_path)); 204 } 205 206 // Called by dbus::PropertySet when a property value is changed, 207 // either by result of a signal or response to a GetAll() or Get() 208 // call. Informs observers. 209 void OnPropertyChanged(const dbus::ObjectPath& object_path, 210 const std::string& property_name) { 211 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, 212 AdapterPropertyChanged(object_path, property_name)); 213 } 214 215 // Called when a response for successful method call is received. 216 void OnSuccess(const base::Closure& callback, 217 dbus::Response* response) { 218 DCHECK(response); 219 callback.Run(); 220 } 221 222 // Called when a response for a failed method call is received. 223 void OnError(const ErrorCallback& error_callback, 224 dbus::ErrorResponse* response) { 225 // Error response has optional error message argument. 226 std::string error_name; 227 std::string error_message; 228 if (response) { 229 dbus::MessageReader reader(response); 230 error_name = response->GetErrorName(); 231 reader.PopString(&error_message); 232 } else { 233 error_name = kNoResponseError; 234 error_message = ""; 235 } 236 error_callback.Run(error_name, error_message); 237 } 238 239 dbus::Bus* bus_; 240 dbus::ObjectManager* object_manager_; 241 242 // List of observers interested in event notifications from us. 243 ObserverList<BluetoothAdapterClient::Observer> observers_; 244 245 // Weak pointer factory for generating 'this' pointers that might live longer 246 // than we do. 247 // Note: This should remain the last member so it'll be destroyed and 248 // invalidate its weak pointers before any other members are destroyed. 249 base::WeakPtrFactory<BluetoothAdapterClientImpl> 250 weak_ptr_factory_; 251 252 DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClientImpl); 253 }; 254 255 BluetoothAdapterClient::BluetoothAdapterClient() { 256 } 257 258 BluetoothAdapterClient::~BluetoothAdapterClient() { 259 } 260 261 BluetoothAdapterClient* BluetoothAdapterClient::Create( 262 DBusClientImplementationType type, 263 dbus::Bus* bus) { 264 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) 265 return new BluetoothAdapterClientImpl(bus); 266 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); 267 return new FakeBluetoothAdapterClient(); 268 } 269 270 } // namespace chromeos 271