0

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}
This commit is contained in:
mcchou
2015-01-21 20:36:48 -08:00
committed by Commit bot
parent fd59ae6c44
commit 6ad5832b96
4 changed files with 318 additions and 0 deletions

@ -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",

@ -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',

@ -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

@ -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_