blob: 1c43d3abf12b466841dfc24d86c1f3adedb09958 [file] [log] [blame]
// 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_BLUEZ_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_AUDIO_SINK_BLUEZ_H_
#include <stdint.h>
#include <string>
#include <vector>
#include "base/files/file.h"
#include "base/macros.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 bluez {
class BluetoothAudioSinkBlueZTest;
class DEVICE_BLUETOOTH_EXPORT BluetoothAudioSinkBlueZ
: 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 BluetoothAudioSinkBlueZ(
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 BluetoothAdapterBlueZ.
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:
~BluetoothAudioSinkBlueZ() 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 BluetoothAudioSinkBlueZ 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 BluetoothAudioSinkBlueZ 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 BluetoothAudioSinkBlueZ 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<BluetoothAudioSinkBlueZ> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BluetoothAudioSinkBlueZ);
};
} // namespace bluez
#endif // DEVICE_BLUETOOTH_BLUETOOTH_AUDIO_SINK_BLUEZ_H_