diff options
author | mcchou <mcchou@chromium.org> | 2015-01-21 20:36:48 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-22 04:37:44 +0000 |
commit | 6ad5832b96d497beb736e521b24f698ee74c592c (patch) | |
tree | 899f4e6392bb4e6175242fd26993f8861f2d1860 /device | |
parent | fd59ae6c44ac0388a0d4929cd056231c78c7f0b4 (diff) | |
download | chromium_src-6ad5832b96d497beb736e521b24f698ee74c592c.zip chromium_src-6ad5832b96d497beb736e521b24f698ee74c592c.tar.gz chromium_src-6ad5832b96d497beb736e521b24f698ee74c592c.tar.bz2 |
device/bluetooth: Add BluetoothAudioSinkChromeOS.
This CL implements Bluetooth Audio Sink API for ChromeOS platform,
where user applications can register/unregister a BT audio sink
via BlueAdapter interface. This API acts as a middle layer hiding
the components of BlueZ/D-Bus.
BUG=441581
Review URL: https://codereview.chromium.org/787743002
Cr-Commit-Position: refs/heads/master@{#312562}
Diffstat (limited to 'device')
-rw-r--r-- | device/bluetooth/BUILD.gn | 2 | ||||
-rw-r--r-- | device/bluetooth/bluetooth.gyp | 2 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_audio_sink_chromeos.cc | 164 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_audio_sink_chromeos.h | 150 |
4 files changed, 318 insertions, 0 deletions
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn index c9c9f6c..d08f74f 100644 --- a/device/bluetooth/BUILD.gn +++ b/device/bluetooth/BUILD.gn @@ -29,6 +29,8 @@ component("bluetooth") { "bluetooth_adapter_win.h", "bluetooth_audio_sink.cc", "bluetooth_audio_sink.h", + "bluetooth_audio_sink_chromeos.cc", + "bluetooth_audio_sink_chromeos.h", "bluetooth_channel_mac.mm", "bluetooth_channel_mac.h", "bluetooth_device.cc", diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp index 3a16228..cec2180 100644 --- a/device/bluetooth/bluetooth.gyp +++ b/device/bluetooth/bluetooth.gyp @@ -34,6 +34,8 @@ 'bluetooth_adapter_win.h', 'bluetooth_audio_sink.cc', 'bluetooth_audio_sink.h', + 'bluetooth_audio_sink_chromeos.cc', + 'bluetooth_audio_sink_chromeos.h', 'bluetooth_channel_mac.mm', 'bluetooth_channel_mac.h', 'bluetooth_device.cc', diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos.cc b/device/bluetooth/bluetooth_audio_sink_chromeos.cc new file mode 100644 index 0000000..840769e --- /dev/null +++ b/device/bluetooth/bluetooth_audio_sink_chromeos.cc @@ -0,0 +1,164 @@ +// 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. + +#include "device/bluetooth/bluetooth_audio_sink_chromeos.h" + +#include <sstream> + +#include "base/logging.h" + +namespace chromeos { + +BluetoothAudioSinkChromeOS::BluetoothAudioSinkChromeOS( + BluetoothAdapterChromeOS* adapter) + : state_(device::BluetoothAudioSink::STATE_INVALID), + present_(false), + powered_(false), + volume_(0), + read_mtu_(0), + write_mtu_(0), + adapter_(adapter), + weak_ptr_factory_(this) { + DCHECK(adapter_); + + present_ = adapter_->IsPresent(); + powered_ = adapter_->IsPowered(); + if (present_ && powered_) + state_ = device::BluetoothAudioSink::STATE_DISCONNECTED; + adapter_->AddObserver(this); +} + +BluetoothAudioSinkChromeOS::~BluetoothAudioSinkChromeOS() { + DCHECK(adapter_); + adapter_->RemoveObserver(this); +} + +void BluetoothAudioSinkChromeOS::AddObserver( + device::BluetoothAudioSink::Observer* observer) { + DCHECK(observer); + observers_.AddObserver(observer); +} + +void BluetoothAudioSinkChromeOS::RemoveObserver( + device::BluetoothAudioSink::Observer* observer) { + DCHECK(observer); + observers_.RemoveObserver(observer); +} + +device::BluetoothAudioSink::State BluetoothAudioSinkChromeOS::GetState() const { + return state_; +} + +uint16_t BluetoothAudioSinkChromeOS::GetVolume() const { + return volume_; +} + +void BluetoothAudioSinkChromeOS::AdapterPresentChanged( + device::BluetoothAdapter* adapter, + bool present) { + // TODO(mcchou): BUG=441581 + // If |persent| is true, change state to |STATE_DISCONNECTED| and call + // StateChanged(). Otherwise, change state to |STATE_INVALID| and call + // StateChanged. +} + +void BluetoothAudioSinkChromeOS::AdapterPoweredChanged( + device::BluetoothAdapter* adapter, + bool powered) { + // TODO(mcchou): BUG=441581 + // If |powered| is true, change state to |STATE_DISCONNECTED| and call + // StateChanged(). Otherwise, change state to |STATE_INVALID| and call + // StateChanged. +} + +void BluetoothAudioSinkChromeOS::MediaRemoved( + const dbus::ObjectPath& object_path) { + // TODO(mcchou): BUG=441581 + // Check if |object_path| equals to |media_path_|. If true, change the state + // of the audio sink, call StateChanged and reset the audio sink. +} + +void BluetoothAudioSinkChromeOS::MediaTransportRemoved( + const dbus::ObjectPath& object_path) { + // TODO(mcchou): BUG=441581 + // Check if |object_path| equals to |transport_path_|. If true, change the + // state of the audio sink, call StateChanged and reset the audio sink. +} + +void BluetoothAudioSinkChromeOS::MediaTransportPropertyChanged( + const dbus::ObjectPath& object_path, + const std::string& property_name) { + // TODO(mcchou): BUG=441581 + // Call StateChanged and VolumeChanged accordingly if there is any change on + // state/volume. +} + +void BluetoothAudioSinkChromeOS::SetConfiguration( + const dbus::ObjectPath& transport_path, + const dbus::MessageReader& properties) { + // TODO(mcchou): BUG=441581 + // Update |transport_path_| and store properties if needed. +} + +void BluetoothAudioSinkChromeOS::SelectConfiguration( + const std::vector<uint8_t>& capabilities, + const SelectConfigurationCallback& callback) { + // TODO(mcchou): BUG=441581 + // Use SelectConfigurationCallback to return the agreed capabilities. +} + +void BluetoothAudioSinkChromeOS::ClearConfiguration( + const dbus::ObjectPath& transport_path) { + // TODO(mcchou): BUG=441581 + // Reset the configuration to the default one and close IOBuffer. +} + +void BluetoothAudioSinkChromeOS::Release() { + // TODO(mcchou): BUG=441581 + // Let the audio sink does the clean-up and do nothing here. +} + +void BluetoothAudioSinkChromeOS::Register( + const device::BluetoothAudioSink::Options& options, + const base::Closure& callback, + const device::BluetoothAudioSink::ErrorCallback& error_callback) { + // TODO(mcchou): BUG=441581 + // Get Media object, initiate an Media Endpoint with options, and return the + // audio sink via callback. Add the audio sink as observer of both Media and + // Media Transport. +} + +void BluetoothAudioSinkChromeOS::Unregister( + const base::Closure& callback, + const device::BluetoothAudioSink::ErrorCallback& error_callback) { + // TODO(mcchou): BUG=441581 + // Clean |observers_| and |transport_path_| and reset |state_| and |volume_|. +} + +void BluetoothAudioSinkChromeOS::StateChanged( + device::BluetoothAudioSink::State state) { + DCHECK_NE(state, state_); + VLOG(1) << "Bluetooth audio sink state changed: " << state; + state_ = state; + FOR_EACH_OBSERVER(device::BluetoothAudioSink::Observer, observers_, + BluetoothAudioSinkStateChanged(this, state_)); +} + +void BluetoothAudioSinkChromeOS::VolumeChanged(uint16_t volume) { + DCHECK_NE(volume, volume_); + VLOG(1) << "Bluetooth audio sink volume changed: " << volume; + volume_ = volume; + FOR_EACH_OBSERVER(device::BluetoothAudioSink::Observer, observers_, + BluetoothAudioSinkVolumeChanged(this, volume_)); +} + +void BluetoothAudioSinkChromeOS::ReadFromFD() { + DCHECK_GE(fd_.value(), 0); + + // TODO(mcchou): BUG=441581 + // Read from file descriptor using watcher and create a buffer to contain the + // data. Notify |Observers_| while there is audio data available. +} + +} // namespace chromeos diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos.h b/device/bluetooth/bluetooth_audio_sink_chromeos.h new file mode 100644 index 0000000..3f9f839 --- /dev/null +++ b/device/bluetooth/bluetooth_audio_sink_chromeos.h @@ -0,0 +1,150 @@ +// 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/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "chromeos/dbus/bluetooth_media_client.h" +#include "chromeos/dbus/bluetooth_media_endpoint_service_provider.h" +#include "chromeos/dbus/bluetooth_media_transport_client.h" +#include "dbus/file_descriptor.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_adapter_chromeos.h" +#include "device/bluetooth/bluetooth_audio_sink.h" +#include "device/bluetooth/bluetooth_export.h" + +namespace chromeos { + +class DEVICE_BLUETOOTH_EXPORT BluetoothAudioSinkChromeOS + : public device::BluetoothAudioSink, + public device::BluetoothAdapter::Observer, + public BluetoothMediaClient::Observer, + public BluetoothMediaTransportClient::Observer, + public BluetoothMediaEndpointServiceProvider::Delegate { + public: + explicit BluetoothAudioSinkChromeOS(BluetoothAdapterChromeOS* adapter); + + // device::BluetoothAudioSink overrides. + void AddObserver(BluetoothAudioSink::Observer* observer) override; + void RemoveObserver(BluetoothAudioSink::Observer* observer) override; + device::BluetoothAudioSink::State GetState() const override; + uint16_t GetVolume() const override; + + // device::BluetoothAdapter::Observer overrides. + void AdapterPresentChanged(device::BluetoothAdapter* adapter, + bool present) override; + void AdapterPoweredChanged(device::BluetoothAdapter* adapter, + bool powered) override; + + // BluetoothMediaClient::Observer overrides. + void MediaRemoved(const dbus::ObjectPath& object_path) override; + + // BluetoothMediaTransportClient::Observer overrides. + void MediaTransportRemoved(const dbus::ObjectPath& object_path) override; + void MediaTransportPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) override; + + // BluetoothMediaEndpointServiceProvider::Delegate overrides. + void SetConfiguration(const dbus::ObjectPath& transport_path, + const dbus::MessageReader& properties) override; + void SelectConfiguration( + const std::vector<uint8_t>& capabilities, + const SelectConfigurationCallback& callback) override; + void ClearConfiguration(const dbus::ObjectPath& transport_path) override; + void Release() 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 + // from BluetoothAdapterChromeOS. + void Register( + const device::BluetoothAudioSink::Options& options, + const base::Closure& callback, + const device::BluetoothAudioSink::ErrorCallback& error_callback); + + // 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; + + private: + ~BluetoothAudioSinkChromeOS() override; + + // 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); + + // Reads from the file descriptor acquired via Media Transport object and + // notify |observer_| while the audio data is available. + void ReadFromFD(); + + // The connection state between the BluetoothAudioSinkChromeOS and the remote + // device. + device::BluetoothAudioSink::State state_; + + // Indicates whether the adapter is present. + bool present_; + + // Indicates whether the adapter is powered. + bool powered_; + + // The volume control by the remote device during the streaming. + 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_; + + // File descriptor acquired via Media Transport object. + dbus::FileDescriptor fd_; + + // 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. + BluetoothAdapterChromeOS* 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<BluetoothMediaEndpointServiceProvider> media_endpoint_; + + // List of observers interested in event notifications from us. Objects in + // |observers_| are expected to outlive a BluetoothAudioSinkChromeOS object. + 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_ |