// // Copyright 2017 Google, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "service/a2dp_sink.h" #include #include #include "service/logging_helpers.h" using bluetooth::hal::BluetoothAvInterface; namespace bluetooth { // static const int A2dpSink::kSingletonInstanceId = 0; A2dpSink::A2dpSink(const Uuid& uuid) : app_identifier_(uuid) { hal::BluetoothAvInterface::Get()->AddA2dpSinkObserver(this); } A2dpSink::~A2dpSink() { hal::BluetoothAvInterface::Get()->RemoveA2dpSinkObserver(this); } const Uuid& A2dpSink::GetAppIdentifier() const { return app_identifier_; } int A2dpSink::GetInstanceId() const { return kSingletonInstanceId; } void A2dpSink::SetDelegate(Delegate* delegate) { std::lock_guard lock(delegate_mutex_); delegate_ = delegate; } bool A2dpSink::Enable() { std::lock_guard lock(mutex_); return hal::BluetoothAvInterface::Get()->A2dpSinkEnable(); } void A2dpSink::Disable() { std::lock_guard lock(mutex_); hal::BluetoothAvInterface::Get()->A2dpSinkDisable(); } bool A2dpSink::Connect(const std::string& device_address) { std::lock_guard lock(mutex_); RawAddress addr; if (!RawAddress::FromString(device_address, addr)) { LOG(ERROR) << "Invalid device address given: " << device_address; return false; } bt_status_t status = hal::BluetoothAvInterface::Get()->GetA2dpSinkHALInterface()->connect( addr); if (status != BT_STATUS_SUCCESS) { LOG(ERROR) << "Failed to connect"; return false; } return true; } bool A2dpSink::Disconnect(const std::string& device_address) { std::lock_guard lock(mutex_); RawAddress addr; if (!RawAddress::FromString(device_address, addr)) { LOG(ERROR) << "Invalid device address given: " << device_address; return false; } bt_status_t status = hal::BluetoothAvInterface::Get()->GetA2dpSinkHALInterface()->disconnect( addr); if (status != BT_STATUS_SUCCESS) { LOG(ERROR) << "Failed to disconnect"; return false; } return true; } void A2dpSink::SetAudioFocusState(int focus_state) { std::lock_guard lock(mutex_); hal::BluetoothAvInterface::Get() ->GetA2dpSinkHALInterface() ->set_audio_focus_state(focus_state); } void A2dpSink::SetAudioTrackGain(float gain) { std::lock_guard lock(mutex_); hal::BluetoothAvInterface::Get() ->GetA2dpSinkHALInterface() ->set_audio_track_gain(gain); } void A2dpSink::ConnectionStateCallback(BluetoothAvInterface* iface, const RawAddress& bd_addr, btav_connection_state_t state) { std::string device_address = BtAddrString(&bd_addr); std::lock_guard lock(delegate_mutex_); if (delegate_) delegate_->OnConnectionState(device_address, static_cast(state)); } void A2dpSink::AudioStateCallback(BluetoothAvInterface* iface, const RawAddress& bd_addr, btav_audio_state_t state) { std::string device_address = BtAddrString(&bd_addr); std::lock_guard lock(delegate_mutex_); if (delegate_) delegate_->OnAudioState(device_address, static_cast(state)); } void A2dpSink::AudioConfigCallback(BluetoothAvInterface* iface, const RawAddress& bd_addr, uint32_t sample_rate, uint8_t channel_count) { std::string device_address = BtAddrString(&bd_addr); std::lock_guard lock(delegate_mutex_); if (delegate_) delegate_->OnAudioConfig(device_address, sample_rate, channel_count); } // A2dpSinkFactory implementation // ======================================================== A2dpSinkFactory::A2dpSinkFactory() = default; A2dpSinkFactory::~A2dpSinkFactory() = default; bool A2dpSinkFactory::RegisterInstance(const Uuid& uuid, const RegisterCallback& callback) { VLOG(1) << __func__ << " - Uuid: " << uuid.ToString(); auto a2dp_sink = base::WrapUnique(new A2dpSink(uuid)); callback(BLE_STATUS_SUCCESS, uuid, std::move(a2dp_sink)); return true; } } // namespace bluetooth