summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authormcchou <mcchou@chromium.org>2015-01-21 20:36:48 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-22 04:37:44 +0000
commit6ad5832b96d497beb736e521b24f698ee74c592c (patch)
tree899f4e6392bb4e6175242fd26993f8861f2d1860 /device
parentfd59ae6c44ac0388a0d4929cd056231c78c7f0b4 (diff)
downloadchromium_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.gn2
-rw-r--r--device/bluetooth/bluetooth.gyp2
-rw-r--r--device/bluetooth/bluetooth_audio_sink_chromeos.cc164
-rw-r--r--device/bluetooth/bluetooth_audio_sink_chromeos.h150
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_