| OLD | NEW |
| (Empty) |
| 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 #ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_BLUEZ_H_ | |
| 6 #define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_BLUEZ_H_ | |
| 7 | |
| 8 #include <stdint.h> | |
| 9 | |
| 10 #include <map> | |
| 11 #include <memory> | |
| 12 #include <queue> | |
| 13 #include <string> | |
| 14 #include <tuple> | |
| 15 #include <utility> | |
| 16 #include <vector> | |
| 17 | |
| 18 #include "base/macros.h" | |
| 19 #include "base/memory/weak_ptr.h" | |
| 20 #include "dbus/object_path.h" | |
| 21 #include "device/bluetooth/bluetooth_adapter.h" | |
| 22 #include "device/bluetooth/bluetooth_audio_sink.h" | |
| 23 #include "device/bluetooth/bluetooth_device.h" | |
| 24 #include "device/bluetooth/bluetooth_discovery_session.h" | |
| 25 #include "device/bluetooth/bluetooth_export.h" | |
| 26 #include "device/bluetooth/dbus/bluetooth_adapter_client.h" | |
| 27 #include "device/bluetooth/dbus/bluetooth_agent_service_provider.h" | |
| 28 #include "device/bluetooth/dbus/bluetooth_device_client.h" | |
| 29 #include "device/bluetooth/dbus/bluetooth_input_client.h" | |
| 30 #include "device/bluetooth/dbus/bluetooth_profile_manager_client.h" | |
| 31 #include "device/bluetooth/dbus/bluetooth_profile_service_provider.h" | |
| 32 | |
| 33 namespace base { | |
| 34 class SequencedTaskRunner; | |
| 35 } // namespace base | |
| 36 | |
| 37 namespace device { | |
| 38 class BluetoothSocketThread; | |
| 39 class BluetoothTestBlueZ; | |
| 40 } // namespace device | |
| 41 | |
| 42 namespace bluez { | |
| 43 | |
| 44 class BluetoothBlueZTest; | |
| 45 class BluetoothAdapterProfileBlueZ; | |
| 46 class BluetoothDeviceBlueZ; | |
| 47 class BluetoothPairingBlueZ; | |
| 48 | |
| 49 // The BluetoothAdapterBlueZ class implements BluetoothAdapter for platforms | |
| 50 // that use BlueZ. | |
| 51 // | |
| 52 // All methods are called from the dbus origin / UI thread and are generally | |
| 53 // not assumed to be thread-safe. | |
| 54 // | |
| 55 // This class interacts with sockets using the BluetoothSocketThread to ensure | |
| 56 // single-threaded calls, and posts tasks to the UI thread. | |
| 57 // | |
| 58 // Methods tolerate a shutdown scenario where BluetoothAdapterBlueZ::Shutdown | |
| 59 // causes IsPresent to return false just before the dbus system is shutdown but | |
| 60 // while references to the BluetoothAdapterBlueZ object still exists. | |
| 61 // | |
| 62 // When adding methods to this class verify shutdown behavior in | |
| 63 // BluetoothBlueZTest, Shutdown. | |
| 64 class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterBlueZ | |
| 65 : public device::BluetoothAdapter, | |
| 66 public bluez::BluetoothAdapterClient::Observer, | |
| 67 public bluez::BluetoothDeviceClient::Observer, | |
| 68 public bluez::BluetoothInputClient::Observer, | |
| 69 public bluez::BluetoothAgentServiceProvider::Delegate { | |
| 70 public: | |
| 71 typedef base::Callback<void(const std::string& error_message)> | |
| 72 ErrorCompletionCallback; | |
| 73 typedef base::Callback<void(BluetoothAdapterProfileBlueZ* profile)> | |
| 74 ProfileRegisteredCallback; | |
| 75 | |
| 76 // Calls |init_callback| after a BluetoothAdapter is fully initialized. | |
| 77 static base::WeakPtr<BluetoothAdapter> CreateAdapter( | |
| 78 const InitCallback& init_callback); | |
| 79 | |
| 80 // BluetoothAdapter: | |
| 81 void Shutdown() override; | |
| 82 UUIDList GetUUIDs() const override; | |
| 83 std::string GetAddress() const override; | |
| 84 std::string GetName() const override; | |
| 85 void SetName(const std::string& name, | |
| 86 const base::Closure& callback, | |
| 87 const ErrorCallback& error_callback) override; | |
| 88 bool IsInitialized() const override; | |
| 89 bool IsPresent() const override; | |
| 90 bool IsPowered() const override; | |
| 91 void SetPowered(bool powered, | |
| 92 const base::Closure& callback, | |
| 93 const ErrorCallback& error_callback) override; | |
| 94 bool IsDiscoverable() const override; | |
| 95 void SetDiscoverable(bool discoverable, | |
| 96 const base::Closure& callback, | |
| 97 const ErrorCallback& error_callback) override; | |
| 98 bool IsDiscovering() const override; | |
| 99 void CreateRfcommService( | |
| 100 const device::BluetoothUUID& uuid, | |
| 101 const ServiceOptions& options, | |
| 102 const CreateServiceCallback& callback, | |
| 103 const CreateServiceErrorCallback& error_callback) override; | |
| 104 void CreateL2capService( | |
| 105 const device::BluetoothUUID& uuid, | |
| 106 const ServiceOptions& options, | |
| 107 const CreateServiceCallback& callback, | |
| 108 const CreateServiceErrorCallback& error_callback) override; | |
| 109 void RegisterAudioSink( | |
| 110 const device::BluetoothAudioSink::Options& options, | |
| 111 const device::BluetoothAdapter::AcquiredCallback& callback, | |
| 112 const device::BluetoothAudioSink::ErrorCallback& error_callback) override; | |
| 113 | |
| 114 void RegisterAdvertisement( | |
| 115 std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement_data, | |
| 116 const CreateAdvertisementCallback& callback, | |
| 117 const CreateAdvertisementErrorCallback& error_callback) override; | |
| 118 | |
| 119 // Locates the device object by object path (the devices map and | |
| 120 // BluetoothDevice methods are by address). | |
| 121 BluetoothDeviceBlueZ* GetDeviceWithPath(const dbus::ObjectPath& object_path); | |
| 122 | |
| 123 // Announces to observers a change in device state that is not reflected by | |
| 124 // its D-Bus properties. |device| is owned by the caller and cannot be NULL. | |
| 125 void NotifyDeviceChanged(BluetoothDeviceBlueZ* device); | |
| 126 | |
| 127 // Announce to observers a device address change. | |
| 128 void NotifyDeviceAddressChanged(BluetoothDeviceBlueZ* device, | |
| 129 const std::string& old_address); | |
| 130 | |
| 131 // Returns the object path of the adapter. | |
| 132 const dbus::ObjectPath& object_path() const { return object_path_; } | |
| 133 | |
| 134 // Request a profile on the adapter for a custom service with a | |
| 135 // specific UUID for the device at |device_path| to be sent to |delegate|. | |
| 136 // If |device_path| is the empty string, incoming connections will be | |
| 137 // assigned to |delegate|. When the profile is | |
| 138 // successfully registered, |success_callback| will be called with a pointer | |
| 139 // to the profile which is managed by BluetoothAdapterBlueZ. On failure, | |
| 140 // |error_callback| will be called. | |
| 141 void UseProfile(const device::BluetoothUUID& uuid, | |
| 142 const dbus::ObjectPath& device_path, | |
| 143 const bluez::BluetoothProfileManagerClient::Options& options, | |
| 144 bluez::BluetoothProfileServiceProvider::Delegate* delegate, | |
| 145 const ProfileRegisteredCallback& success_callback, | |
| 146 const ErrorCompletionCallback& error_callback); | |
| 147 | |
| 148 // Release use of a profile by a device. | |
| 149 void ReleaseProfile(const dbus::ObjectPath& device_path, | |
| 150 BluetoothAdapterProfileBlueZ* profile); | |
| 151 | |
| 152 protected: | |
| 153 // BluetoothAdapter: | |
| 154 void RemovePairingDelegateInternal( | |
| 155 device::BluetoothDevice::PairingDelegate* pairing_delegate) override; | |
| 156 | |
| 157 private: | |
| 158 friend class BluetoothBlueZTest; | |
| 159 friend class BluetoothBlueZTest_Shutdown_Test; | |
| 160 friend class BluetoothBlueZTest_Shutdown_OnStartDiscovery_Test; | |
| 161 friend class BluetoothBlueZTest_Shutdown_OnStartDiscoveryError_Test; | |
| 162 friend class BluetoothBlueZTest_Shutdown_OnStopDiscovery_Test; | |
| 163 friend class BluetoothBlueZTest_Shutdown_OnStopDiscoveryError_Test; | |
| 164 friend class device::BluetoothTestBlueZ; | |
| 165 | |
| 166 // typedef for callback parameters that are passed to AddDiscoverySession | |
| 167 // and RemoveDiscoverySession. This is used to queue incoming requests while | |
| 168 // a call to BlueZ is pending. | |
| 169 typedef std::tuple<device::BluetoothDiscoveryFilter*, | |
| 170 base::Closure, | |
| 171 DiscoverySessionErrorCallback> DiscoveryParamTuple; | |
| 172 typedef std::queue<DiscoveryParamTuple> DiscoveryCallbackQueue; | |
| 173 | |
| 174 // Callback pair for the profile registration queue. | |
| 175 typedef std::pair<base::Closure, ErrorCompletionCallback> | |
| 176 RegisterProfileCompletionPair; | |
| 177 | |
| 178 explicit BluetoothAdapterBlueZ(const InitCallback& init_callback); | |
| 179 ~BluetoothAdapterBlueZ() override; | |
| 180 | |
| 181 // Init will get asynchronouly called once we know if Object Manager is | |
| 182 // supported. | |
| 183 void Init(); | |
| 184 | |
| 185 // bluez::BluetoothAdapterClient::Observer override. | |
| 186 void AdapterAdded(const dbus::ObjectPath& object_path) override; | |
| 187 void AdapterRemoved(const dbus::ObjectPath& object_path) override; | |
| 188 void AdapterPropertyChanged(const dbus::ObjectPath& object_path, | |
| 189 const std::string& property_name) override; | |
| 190 | |
| 191 // bluez::BluetoothDeviceClient::Observer override. | |
| 192 void DeviceAdded(const dbus::ObjectPath& object_path) override; | |
| 193 void DeviceRemoved(const dbus::ObjectPath& object_path) override; | |
| 194 void DevicePropertyChanged(const dbus::ObjectPath& object_path, | |
| 195 const std::string& property_name) override; | |
| 196 | |
| 197 // bluez::BluetoothInputClient::Observer override. | |
| 198 void InputPropertyChanged(const dbus::ObjectPath& object_path, | |
| 199 const std::string& property_name) override; | |
| 200 | |
| 201 // bluez::BluetoothAgentServiceProvider::Delegate override. | |
| 202 void Released() override; | |
| 203 void RequestPinCode(const dbus::ObjectPath& device_path, | |
| 204 const PinCodeCallback& callback) override; | |
| 205 void DisplayPinCode(const dbus::ObjectPath& device_path, | |
| 206 const std::string& pincode) override; | |
| 207 void RequestPasskey(const dbus::ObjectPath& device_path, | |
| 208 const PasskeyCallback& callback) override; | |
| 209 void DisplayPasskey(const dbus::ObjectPath& device_path, | |
| 210 uint32_t passkey, | |
| 211 uint16_t entered) override; | |
| 212 void RequestConfirmation(const dbus::ObjectPath& device_path, | |
| 213 uint32_t passkey, | |
| 214 const ConfirmationCallback& callback) override; | |
| 215 void RequestAuthorization(const dbus::ObjectPath& device_path, | |
| 216 const ConfirmationCallback& callback) override; | |
| 217 void AuthorizeService(const dbus::ObjectPath& device_path, | |
| 218 const std::string& uuid, | |
| 219 const ConfirmationCallback& callback) override; | |
| 220 void Cancel() override; | |
| 221 | |
| 222 // Called by dbus:: on completion of the D-Bus method call to register the | |
| 223 // pairing agent. | |
| 224 void OnRegisterAgent(); | |
| 225 void OnRegisterAgentError(const std::string& error_name, | |
| 226 const std::string& error_message); | |
| 227 | |
| 228 // Called by dbus:: on completion of the D-Bus method call to request that | |
| 229 // the pairing agent be made the default. | |
| 230 void OnRequestDefaultAgent(); | |
| 231 void OnRequestDefaultAgentError(const std::string& error_name, | |
| 232 const std::string& error_message); | |
| 233 | |
| 234 // Called by BluetoothAudioSinkBlueZ on completion of registering an audio | |
| 235 // sink. | |
| 236 void OnRegisterAudioSink( | |
| 237 const device::BluetoothAdapter::AcquiredCallback& callback, | |
| 238 const device::BluetoothAudioSink::ErrorCallback& error_callback, | |
| 239 scoped_refptr<device::BluetoothAudioSink> audio_sink); | |
| 240 | |
| 241 // Internal method to obtain a BluetoothPairingBlueZ object for the device | |
| 242 // with path |object_path|. Returns the existing pairing object if the device | |
| 243 // already has one (usually an outgoing connection in progress) or a new | |
| 244 // pairing object with the default pairing delegate if not. If no default | |
| 245 // pairing object exists, NULL will be returned. | |
| 246 BluetoothPairingBlueZ* GetPairing(const dbus::ObjectPath& object_path); | |
| 247 | |
| 248 // Set the tracked adapter to the one in |object_path|, this object will | |
| 249 // subsequently operate on that adapter until it is removed. | |
| 250 void SetAdapter(const dbus::ObjectPath& object_path); | |
| 251 | |
| 252 #if defined(OS_CHROMEOS) | |
| 253 // Set the adapter name to one chosen from the system information. | |
| 254 void SetStandardChromeOSAdapterName(); | |
| 255 #endif | |
| 256 | |
| 257 // Remove the currently tracked adapter. IsPresent() will return false after | |
| 258 // this is called. | |
| 259 void RemoveAdapter(); | |
| 260 | |
| 261 // Announce to observers a change in the adapter state. | |
| 262 void PoweredChanged(bool powered); | |
| 263 void DiscoverableChanged(bool discoverable); | |
| 264 void DiscoveringChanged(bool discovering); | |
| 265 void PresentChanged(bool present); | |
| 266 | |
| 267 // Called by dbus:: on completion of the discoverable property change. | |
| 268 void OnSetDiscoverable(const base::Closure& callback, | |
| 269 const ErrorCallback& error_callback, | |
| 270 bool success); | |
| 271 | |
| 272 // Called by dbus:: on completion of an adapter property change. | |
| 273 void OnPropertyChangeCompleted(const base::Closure& callback, | |
| 274 const ErrorCallback& error_callback, | |
| 275 bool success); | |
| 276 | |
| 277 // BluetoothAdapter: | |
| 278 void AddDiscoverySession( | |
| 279 device::BluetoothDiscoveryFilter* discovery_filter, | |
| 280 const base::Closure& callback, | |
| 281 const DiscoverySessionErrorCallback& error_callback) override; | |
| 282 void RemoveDiscoverySession( | |
| 283 device::BluetoothDiscoveryFilter* discovery_filter, | |
| 284 const base::Closure& callback, | |
| 285 const DiscoverySessionErrorCallback& error_callback) override; | |
| 286 void SetDiscoveryFilter( | |
| 287 std::unique_ptr<device::BluetoothDiscoveryFilter> discovery_filter, | |
| 288 const base::Closure& callback, | |
| 289 const DiscoverySessionErrorCallback& error_callback) override; | |
| 290 | |
| 291 // Called by dbus:: on completion of the D-Bus method call to start discovery. | |
| 292 void OnStartDiscovery(const base::Closure& callback, | |
| 293 const DiscoverySessionErrorCallback& error_callback); | |
| 294 void OnStartDiscoveryError( | |
| 295 const base::Closure& callback, | |
| 296 const DiscoverySessionErrorCallback& error_callback, | |
| 297 const std::string& error_name, | |
| 298 const std::string& error_message); | |
| 299 | |
| 300 // Called by dbus:: on completion of the D-Bus method call to stop discovery. | |
| 301 void OnStopDiscovery(const base::Closure& callback); | |
| 302 void OnStopDiscoveryError(const DiscoverySessionErrorCallback& error_callback, | |
| 303 const std::string& error_name, | |
| 304 const std::string& error_message); | |
| 305 | |
| 306 void OnPreSetDiscoveryFilter( | |
| 307 const base::Closure& callback, | |
| 308 const DiscoverySessionErrorCallback& error_callback); | |
| 309 void OnPreSetDiscoveryFilterError( | |
| 310 const base::Closure& callback, | |
| 311 const DiscoverySessionErrorCallback& error_callback, | |
| 312 device::UMABluetoothDiscoverySessionOutcome outcome); | |
| 313 void OnSetDiscoveryFilter( | |
| 314 const base::Closure& callback, | |
| 315 const DiscoverySessionErrorCallback& error_callback); | |
| 316 void OnSetDiscoveryFilterError( | |
| 317 const base::Closure& callback, | |
| 318 const DiscoverySessionErrorCallback& error_callback, | |
| 319 const std::string& error_name, | |
| 320 const std::string& error_message); | |
| 321 | |
| 322 // Called by dbus:: on completion of the D-Bus method to register a profile. | |
| 323 void OnRegisterProfile(const device::BluetoothUUID& uuid, | |
| 324 std::unique_ptr<BluetoothAdapterProfileBlueZ> profile); | |
| 325 | |
| 326 void SetProfileDelegate( | |
| 327 const device::BluetoothUUID& uuid, | |
| 328 const dbus::ObjectPath& device_path, | |
| 329 bluez::BluetoothProfileServiceProvider::Delegate* delegate, | |
| 330 const ProfileRegisteredCallback& success_callback, | |
| 331 const ErrorCompletionCallback& error_callback); | |
| 332 void OnRegisterProfileError(const device::BluetoothUUID& uuid, | |
| 333 const std::string& error_name, | |
| 334 const std::string& error_message); | |
| 335 | |
| 336 // Called by BluetoothAdapterProfileBlueZ when no users of a profile | |
| 337 // remain. | |
| 338 void RemoveProfile(const device::BluetoothUUID& uuid); | |
| 339 | |
| 340 // Processes the queued discovery requests. For each DiscoveryParamTuple in | |
| 341 // the queue, this method will try to add a new discovery session. This method | |
| 342 // is called whenever a pending D-Bus call to start or stop discovery has | |
| 343 // ended (with either success or failure). | |
| 344 void ProcessQueuedDiscoveryRequests(); | |
| 345 | |
| 346 InitCallback init_callback_; | |
| 347 | |
| 348 bool initialized_; | |
| 349 | |
| 350 // Set in |Shutdown()|, makes IsPresent()| return false. | |
| 351 bool dbus_is_shutdown_; | |
| 352 | |
| 353 // Number of discovery sessions that have been added. | |
| 354 int num_discovery_sessions_; | |
| 355 | |
| 356 // True, if there is a pending request to start or stop discovery. | |
| 357 bool discovery_request_pending_; | |
| 358 | |
| 359 // List of queued requests to add new discovery sessions. While there is a | |
| 360 // pending request to BlueZ to start or stop discovery, many requests from | |
| 361 // within Chrome to start or stop discovery sessions may occur. We only | |
| 362 // queue requests to add new sessions to be processed later. All requests to | |
| 363 // remove a session while a call is pending immediately return failure. Note | |
| 364 // that since BlueZ keeps its own reference count of applications that have | |
| 365 // requested discovery, dropping our count to 0 won't necessarily result in | |
| 366 // the controller actually stopping discovery if, for example, an application | |
| 367 // other than Chrome, such as bt_console, was also used to start discovery. | |
| 368 DiscoveryCallbackQueue discovery_request_queue_; | |
| 369 | |
| 370 // Object path of the adapter we track. | |
| 371 dbus::ObjectPath object_path_; | |
| 372 | |
| 373 // Instance of the D-Bus agent object used for pairing, initialized with | |
| 374 // our own class as its delegate. | |
| 375 std::unique_ptr<bluez::BluetoothAgentServiceProvider> agent_; | |
| 376 | |
| 377 // UI thread task runner and socket thread object used to create sockets. | |
| 378 scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; | |
| 379 scoped_refptr<device::BluetoothSocketThread> socket_thread_; | |
| 380 | |
| 381 // The profiles we have registered with the bluetooth daemon. | |
| 382 std::map<device::BluetoothUUID, BluetoothAdapterProfileBlueZ*> profiles_; | |
| 383 | |
| 384 // Queue of delegates waiting for a profile to register. | |
| 385 std::map<device::BluetoothUUID, std::vector<RegisterProfileCompletionPair>*> | |
| 386 profile_queues_; | |
| 387 | |
| 388 std::unique_ptr<device::BluetoothDiscoveryFilter> current_filter_; | |
| 389 | |
| 390 // Note: This should remain the last member so it'll be destroyed and | |
| 391 // invalidate its weak pointers before any other members are destroyed. | |
| 392 base::WeakPtrFactory<BluetoothAdapterBlueZ> weak_ptr_factory_; | |
| 393 | |
| 394 DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterBlueZ); | |
| 395 }; | |
| 396 | |
| 397 } // namespace bluez | |
| 398 | |
| 399 #endif // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_BLUEZ_H_ | |
| OLD | NEW |