You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
4.7 KiB
155 lines
4.7 KiB
//
|
|
// 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 <base/logging.h>
|
|
#include <base/memory/ptr_util.h>
|
|
|
|
#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<std::mutex> lock(delegate_mutex_);
|
|
delegate_ = delegate;
|
|
}
|
|
|
|
bool A2dpSink::Enable() {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
return hal::BluetoothAvInterface::Get()->A2dpSinkEnable();
|
|
}
|
|
|
|
void A2dpSink::Disable() {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
hal::BluetoothAvInterface::Get()->A2dpSinkDisable();
|
|
}
|
|
|
|
bool A2dpSink::Connect(const std::string& device_address) {
|
|
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> lock(mutex_);
|
|
hal::BluetoothAvInterface::Get()
|
|
->GetA2dpSinkHALInterface()
|
|
->set_audio_focus_state(focus_state);
|
|
}
|
|
|
|
void A2dpSink::SetAudioTrackGain(float gain) {
|
|
std::lock_guard<std::mutex> 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<std::mutex> lock(delegate_mutex_);
|
|
|
|
if (delegate_)
|
|
delegate_->OnConnectionState(device_address, static_cast<int>(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<std::mutex> lock(delegate_mutex_);
|
|
|
|
if (delegate_)
|
|
delegate_->OnAudioState(device_address, static_cast<int>(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<std::mutex> 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
|