summaryrefslogtreecommitdiffstats
path: root/device/bluetooth/bluetooth_audio_sink_chromeos.h
diff options
context:
space:
mode:
Diffstat (limited to 'device/bluetooth/bluetooth_audio_sink_chromeos.h')
-rw-r--r--device/bluetooth/bluetooth_audio_sink_chromeos.h222
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_