diff options
Diffstat (limited to 'device/bluetooth/bluetooth_audio_sink_chromeos.h')
-rw-r--r-- | device/bluetooth/bluetooth_audio_sink_chromeos.h | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos.h b/device/bluetooth/bluetooth_audio_sink_chromeos.h new file mode 100644 index 0000000..750b31d --- /dev/null +++ b/device/bluetooth/bluetooth_audio_sink_chromeos.h @@ -0,0 +1,222 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_BLUETOOTH_BLUETOOTH_AUDIO_SINK_CHROMEOS_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_AUDIO_SINK_CHROMEOS_H_ + +#include <stdint.h> +#include <string> +#include <vector> + +#include "base/files/file.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/observer_list.h" +#include "dbus/file_descriptor.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_audio_sink.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_media_client.h" +#include "device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h" +#include "device/bluetooth/dbus/bluetooth_media_transport_client.h" + +namespace chromeos { + +class BluetoothAudioSinkChromeOSTest; + +class DEVICE_BLUETOOTH_EXPORT BluetoothAudioSinkChromeOS + : public device::BluetoothAudioSink, + public device::BluetoothAdapter::Observer, + public bluez::BluetoothMediaClient::Observer, + public bluez::BluetoothMediaTransportClient::Observer, + public bluez::BluetoothMediaEndpointServiceProvider::Delegate, + public base::MessageLoopForIO::Watcher { + public: + explicit BluetoothAudioSinkChromeOS( + scoped_refptr<device::BluetoothAdapter> adapter); + + // device::BluetoothAudioSink overrides. + // Unregisters a BluetoothAudioSink. |callback| should handle + // the clean-up after the audio sink is deleted successfully, otherwise + // |error_callback| will be called. + void Unregister( + const base::Closure& callback, + const device::BluetoothAudioSink::ErrorCallback& error_callback) override; + void AddObserver(BluetoothAudioSink::Observer* observer) override; + void RemoveObserver(BluetoothAudioSink::Observer* observer) override; + device::BluetoothAudioSink::State GetState() const override; + uint16_t GetVolume() const override; + + // Registers a BluetoothAudioSink. User applications can use |options| to + // configure the audio sink. |callback| will be executed if the audio sink is + // successfully registered, otherwise |error_callback| will be called. Called + // by BluetoothAdapterChromeOS. + void Register( + const device::BluetoothAudioSink::Options& options, + const base::Closure& callback, + const device::BluetoothAudioSink::ErrorCallback& error_callback); + + // Returns a pointer to the media endpoint object. This function should be + // used for testing purpose only. + bluez::BluetoothMediaEndpointServiceProvider* GetEndpointServiceProvider(); + + private: + ~BluetoothAudioSinkChromeOS() override; + + // device::BluetoothAdapter::Observer overrides. + void AdapterPresentChanged(device::BluetoothAdapter* adapter, + bool present) override; + void AdapterPoweredChanged(device::BluetoothAdapter* adapter, + bool powered) override; + + // bluez::BluetoothMediaClient::Observer overrides. + void MediaRemoved(const dbus::ObjectPath& object_path) override; + + // bluez::BluetoothMediaTransportClient::Observer overrides. + void MediaTransportRemoved(const dbus::ObjectPath& object_path) override; + void MediaTransportPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) override; + + // bluez::BluetoothMediaEndpointServiceProvider::Delegate overrides. + void SetConfiguration(const dbus::ObjectPath& transport_path, + const TransportProperties& properties) override; + void SelectConfiguration( + const std::vector<uint8_t>& capabilities, + const SelectConfigurationCallback& callback) override; + void ClearConfiguration(const dbus::ObjectPath& transport_path) override; + void Released() override; + + // base::MessageLoopForIO::Watcher overrides. + void OnFileCanReadWithoutBlocking(int fd) override; + void OnFileCanWriteWithoutBlocking(int fd) override; + + // Acquires file descriptor via current transport object when the state change + // is triggered by MediaTransportPropertyChanged. + void AcquireFD(); + + // Watches if there is any available data from |fd_|. + void WatchFD(); + + // Stops watching |fd_| and resets |fd_|. + void StopWatchingFD(); + + // Reads from the file descriptor acquired via Media Transport object and + // notify |observer_| while the audio data is available. + void ReadFromFile(); + + // Called when the state property of BluetoothMediaTransport has been updated. + void StateChanged(device::BluetoothAudioSink::State state); + + // Called when the volume property of BluetoothMediaTransport has been + // updated. + void VolumeChanged(uint16_t volume); + + // Called when the registration of Media Endpoint has succeeded. + void OnRegisterSucceeded(const base::Closure& callback); + + // Called when the registration of Media Endpoint failed. + void OnRegisterFailed( + const device::BluetoothAudioSink::ErrorCallback& error_callback, + const std::string& error_name, + const std::string& error_message); + + // Called when the unregistration of Media Endpoint has succeeded. The + // clean-up of media, media transport and media endpoint will be handled here. + void OnUnregisterSucceeded(const base::Closure& callback); + + // Called when the unregistration of Media Endpoint failed. + void OnUnregisterFailed( + const device::BluetoothAudioSink::ErrorCallback& error_callback, + const std::string& error_name, + const std::string& error_message); + + // Called when the file descriptor, read MTU and write MTU are retrieved + // successfully using |transport_path_|. + void OnAcquireSucceeded(dbus::FileDescriptor* fd, + const uint16_t read_mtu, + const uint16_t write_mtu); + + // Called when acquiring the file descriptor, read MTU and write MTU failed. + void OnAcquireFailed(const std::string& error_name, + const std::string& error_message); + + // Called when the file descriptor is released successfully. + void OnReleaseFDSucceeded(); + + // Called when it failed to release file descriptor. + void OnReleaseFDFailed(const std::string& error_name, + const std::string& error_message); + + // Helper functions to clean up media, media transport and media endpoint. + // Called when the |state_| changes to either STATE_INVALID or + // STATE_DISCONNECTED. + void ResetMedia(); + void ResetTransport(); + void ResetEndpoint(); + + // The connection state between the BluetoothAudioSinkChromeOS and the remote + // device. + device::BluetoothAudioSink::State state_; + + // The volume control by the remote device during the streaming. The valid + // range of volume is 0-127, and 128 is used to represent invalid volume. + uint16_t volume_; + + // Read MTU of the file descriptor acquired via Media Transport object. + uint16_t read_mtu_; + + // Write MTU of the file descriptor acquired via Media Transport object. + uint16_t write_mtu_; + + // Flag for logging the read failure in ReadFromFD. + bool read_has_failed_; + + // The file which takes ownership of the file descriptor acquired via Media + // Transport object. + scoped_ptr<base::File> file_; + + // To avoid reallocation of memory, data will be updated only when |read_mtu_| + // changes. + scoped_ptr<char[]> data_; + + // File descriptor watcher for the file descriptor acquired via Media + // Transport object. + base::MessageLoopForIO::FileDescriptorWatcher fd_read_watcher_; + + // Object path of the media object being used. + dbus::ObjectPath media_path_; + + // Object path of the transport object being used. + dbus::ObjectPath transport_path_; + + // Object path of the media endpoint object being used. + dbus::ObjectPath endpoint_path_; + + // BT adapter which the audio sink binds to. |adapter_| should outlive + // a BluetoothAudioSinkChromeOS object. + scoped_refptr<device::BluetoothAdapter> adapter_; + + // Options used to initiate Media Endpoint and select configuration for the + // transport. + device::BluetoothAudioSink::Options options_; + + // Media Endpoint object owned by the audio sink object. + scoped_ptr<bluez::BluetoothMediaEndpointServiceProvider> media_endpoint_; + + // List of observers interested in event notifications from us. Objects in + // |observers_| are expected to outlive a BluetoothAudioSinkChromeOS object. + base::ObserverList<BluetoothAudioSink::Observer> observers_; + + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothAudioSinkChromeOS> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothAudioSinkChromeOS); +}; + +} // namespace chromeos + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_AUDIO_SINK_CHROMEOS_H_ |