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:
@ -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',
|
||||
|
164
device/bluetooth/bluetooth_audio_sink_chromeos.cc
Normal file
164
device/bluetooth/bluetooth_audio_sink_chromeos.cc
Normal file
@ -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
|
150
device/bluetooth/bluetooth_audio_sink_chromeos.h
Normal file
150
device/bluetooth/bluetooth_audio_sink_chromeos.h
Normal file
@ -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_
|
Reference in New Issue
Block a user