Chromium Code Reviews| Index: device/bluetooth/bluetooth_audio_sink_chromeos.cc |
| diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos.cc b/device/bluetooth/bluetooth_audio_sink_chromeos.cc |
| index 840769e8f1d337d79ec3a1927d9d5ea5aacf5e81..59c3d3e08c57ce79db2fede704f04d64e7200d37 100644 |
| --- a/device/bluetooth/bluetooth_audio_sink_chromeos.cc |
| +++ b/device/bluetooth/bluetooth_audio_sink_chromeos.cc |
| @@ -7,6 +7,23 @@ |
| #include <sstream> |
| #include "base/logging.h" |
| +#include "chromeos/dbus/dbus_thread_manager.h" |
| + |
| +namespace { |
| + |
| +// TODO(mcchou): Add the constant to dbus/service_constants.h. |
| +const char kBluetoothAudioSinkServicePath[] = "/org/chromium/AudioSink"; |
| +const char kBluetoothAudioSinkUUID[] = "0000110b-0000-1000-8000-00805f9b34fb"; |
| + |
| +dbus::ObjectPath GenerateEndpointPath() { |
| + static unsigned int sequence_number = 0; |
| + ++sequence_number; |
| + std::stringstream path; |
| + path << kBluetoothAudioSinkServicePath << "/endpoint" << sequence_number; |
| + return dbus::ObjectPath(path.str()); |
| +} |
| + |
| +} // namespace |
| namespace chromeos { |
| @@ -25,7 +42,7 @@ BluetoothAudioSinkChromeOS::BluetoothAudioSinkChromeOS( |
| present_ = adapter_->IsPresent(); |
| powered_ = adapter_->IsPowered(); |
| if (present_ && powered_) |
| - state_ = device::BluetoothAudioSink::STATE_DISCONNECTED; |
| + StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED); |
| adapter_->AddObserver(this); |
| } |
| @@ -57,19 +74,29 @@ uint16_t BluetoothAudioSinkChromeOS::GetVolume() const { |
| 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. |
| + if (present == present_) return; |
|
armansito
2015/01/27 04:38:06
nit: Put return in its own line.
armansito
2015/01/27 04:38:06
This check isn't really necessary, since the adapt
Miao
2015/01/28 02:05:01
Removed.
|
| + VLOG(1) << "Bluetooth audio sink: Bluetooth adapter present changed: " |
| + << present; |
| + present_ = present; |
|
armansito
2015/01/27 04:38:06
I don't think that |present_| and |powered_| are n
Miao
2015/01/28 02:05:01
Removed.
|
| + if (present_ && adapter->IsPowered()) { |
| + StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED); |
| + } else { |
|
armansito
2015/01/27 04:38:06
This means that the state will become INVALID if |
Miao
2015/01/28 02:05:01
Will remove AdapterPoweredChanged and let MediaTra
|
| + StateChanged(device::BluetoothAudioSink::STATE_INVALID); |
| + } |
| } |
| 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. |
| + if (powered == powered_) return; |
|
armansito
2015/01/27 04:38:05
Same as above.
Miao
2015/01/28 02:05:01
Removed.
|
| + VLOG(1) << "Bluetooth audio sink: Bluetooth adapter powered changed: " |
| + << powered; |
| + powered_ = powered; |
| + if (powered_ && adapter->IsPresent()) { |
| + StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED); |
| + } else { |
| + StateChanged(device::BluetoothAudioSink::STATE_INVALID); |
|
armansito
2015/01/27 04:38:05
Same logic as above. Besides this code is essentia
Miao
2015/01/28 02:05:01
Removed.
|
| + } |
| } |
| void BluetoothAudioSinkChromeOS::MediaRemoved( |
| @@ -106,6 +133,8 @@ void BluetoothAudioSinkChromeOS::SelectConfiguration( |
| const SelectConfigurationCallback& callback) { |
| // TODO(mcchou): BUG=441581 |
| // Use SelectConfigurationCallback to return the agreed capabilities. |
| + VLOG(1) << "Bluetooth audio sink: SelectConfiguration called"; |
| + callback.Run(options_.capabilities); |
| } |
| void BluetoothAudioSinkChromeOS::ClearConfiguration( |
| @@ -127,19 +156,86 @@ void BluetoothAudioSinkChromeOS::Register( |
| // 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. |
| + DCHECK(adapter_); |
| + DCHECK_EQ(state_, device::BluetoothAudioSink::STATE_DISCONNECTED); |
| + |
| + // Gets system bus. |
| + dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); |
| + |
| + // Creates a Media Endpoint with newly-generated path. |
| + dbus::ObjectPath endpoint_path_ = GenerateEndpointPath(); |
|
armansito
2015/01/27 04:38:05
This code shouldn't compile, since you're redeclar
Miao
2015/01/28 02:05:01
The compilation will pass, since it will be a loca
|
| + media_endpoint_.reset( |
| + BluetoothMediaEndpointServiceProvider::Create( |
| + system_bus, endpoint_path_, this)); |
| + |
| + DCHECK(media_endpoint_.get()); |
| + |
| + // Creates endpoint properties with |options|. |
| + options_ = options; |
| + chromeos::BluetoothMediaClient::EndpointProperties endpoint_properties; |
| + endpoint_properties.uuid = std::string(kBluetoothAudioSinkUUID); |
| + endpoint_properties.codec = options_.codec; |
| + endpoint_properties.capabilities = options_.capabilities; |
| + |
| + // Gets Media object exported by D-Bus and registers the endpoint. |
| + chromeos::BluetoothMediaClient* media = |
| + DBusThreadManager::Get()->GetBluetoothMediaClient(); |
| + media->AddObserver(this); |
| + media_path_ = adapter_->object_path(); |
| + media->RegisterEndpoint( |
| + media_path_, |
| + endpoint_path_, |
| + endpoint_properties, |
| + base::Bind(&BluetoothAudioSinkChromeOS::OnRegisterSucceeded, |
| + weak_ptr_factory_.GetWeakPtr(), callback), |
| + base::Bind(&BluetoothAudioSinkChromeOS::OnRegisterFailed, |
| + weak_ptr_factory_.GetWeakPtr(), error_callback)); |
| } |
| 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_|. |
| + // Call UnregisterEndpoint on the media object with |media_path_| and clean |
| + // |observers_| and transport_path_ and reset state_ and volume. |
| } |
| void BluetoothAudioSinkChromeOS::StateChanged( |
| device::BluetoothAudioSink::State state) { |
| - DCHECK_NE(state, state_); |
| + if (state == state_) return; |
|
armansito
2015/01/27 04:38:06
nit: return; in its own line.
Miao
2015/01/28 02:05:01
Done.
|
| VLOG(1) << "Bluetooth audio sink state changed: " << state; |
| + switch (state) { |
| + case device::BluetoothAudioSink::STATE_INVALID: { |
| + // TODO(mcchou): BUG=441581 |
| + // Clean media, media transport and media endpoint. |
| + break; |
| + } |
| + case device::BluetoothAudioSink::STATE_DISCONNECTED: { |
| + // TODO(mcchou): BUG=441581 |
| + // Clean media transport. |
| + break; |
| + } |
| + case device::BluetoothAudioSink::STATE_IDLE: { |
| + // TODO(mcchou): BUG=441581 |
| + // Triggered by MediaTransportPropertyChanged. Stop watching on file |
| + // descriptor if there is one. |
| + break; |
| + } |
| + case device::BluetoothAudioSink::STATE_PENDING: { |
| + // TODO(mcchou): BUG=441581 |
| + // Call BluetoothMediaTransportClient::Acquire() to get fd and mtus. |
| + break; |
| + } |
| + case device::BluetoothAudioSink::STATE_ACTIVE: { |
| + // TODO(mcchou): BUG=441581 |
| + // Read from fd and call DataAvailable. |
| + ReadFromFD(); |
| + break; |
| + } |
| + default: { |
|
armansito
2015/01/27 04:38:05
No need for empty scope here.
Miao
2015/01/28 02:05:01
Done.
|
| + } |
| + } |
| + |
| state_ = state; |
| FOR_EACH_OBSERVER(device::BluetoothAudioSink::Observer, observers_, |
| BluetoothAudioSinkStateChanged(this, state_)); |
| @@ -153,6 +249,26 @@ void BluetoothAudioSinkChromeOS::VolumeChanged(uint16_t volume) { |
| BluetoothAudioSinkVolumeChanged(this, volume_)); |
| } |
| +void BluetoothAudioSinkChromeOS::OnRegisterSucceeded( |
| + const base::Closure& callback) { |
| + VLOG(1) << "Bluetooth audio sink registerd"; |
| + |
| + StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED); |
| + callback.Run(); |
| +} |
| + |
| +void BluetoothAudioSinkChromeOS::OnRegisterFailed( |
| + const BluetoothAudioSink::ErrorCallback& error_back, |
| + const std::string& error_name, |
| + const std::string& error_message) { |
| + DCHECK(media_endpoint_.get()); |
| + VLOG(1) << "Bluetooth audio sink: " << error_name << ": " << error_message; |
| + |
| + endpoint_path_ = dbus::ObjectPath(""); |
| + media_endpoint_ = nullptr; |
| + error_back.Run(device::BluetoothAudioSink::ERROR_NOT_REGISTERED); |
| +} |
| + |
| void BluetoothAudioSinkChromeOS::ReadFromFD() { |
| DCHECK_GE(fd_.value(), 0); |