blob: 8d03faec0497dc65f72a37329e858e171fd6a8a3 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* 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.
*/
#define LOG_TAG "BTAudioProviderStub"
#include "BluetoothAudioProvider.h"
#include <BluetoothAudioSessionReport.h>
#include <android-base/logging.h>
#include "A2dpOffloadCodecFactory.h"
namespace aidl {
namespace android {
namespace hardware {
namespace bluetooth {
namespace audio {
struct BluetoothAudioProviderContext {
SessionType session_type;
};
static void binderUnlinkedCallbackAidl(void* cookie) {
LOG(INFO) << __func__;
BluetoothAudioProviderContext* ctx =
static_cast<BluetoothAudioProviderContext*>(cookie);
delete ctx;
}
static void binderDiedCallbackAidl(void* cookie) {
LOG(INFO) << __func__;
BluetoothAudioProviderContext* ctx =
static_cast<BluetoothAudioProviderContext*>(cookie);
CHECK_NE(ctx, nullptr);
BluetoothAudioSessionReport::OnSessionEnded(ctx->session_type);
}
BluetoothAudioProvider::BluetoothAudioProvider() {
death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient(
AIBinder_DeathRecipient_new(binderDiedCallbackAidl));
AIBinder_DeathRecipient_setOnUnlinked(death_recipient_.get(),
binderUnlinkedCallbackAidl);
}
ndk::ScopedAStatus BluetoothAudioProvider::startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
const std::vector<LatencyMode>& latencyModes,
DataMQDesc* _aidl_return) {
if (host_if == nullptr) {
*_aidl_return = DataMQDesc();
LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
<< " Illegal argument";
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
latency_modes_ = latencyModes;
audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
stack_iface_ = host_if;
BluetoothAudioProviderContext* cookie =
new BluetoothAudioProviderContext{session_type_};
AIBinder_linkToDeath(stack_iface_->asBinder().get(), death_recipient_.get(),
cookie);
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
onSessionReady(_aidl_return);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus BluetoothAudioProvider::endSession() {
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
if (stack_iface_ != nullptr) {
BluetoothAudioSessionReport::OnSessionEnded(session_type_);
AIBinder_unlinkToDeath(stack_iface_->asBinder().get(),
death_recipient_.get(), this);
} else {
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
<< " has NO session";
}
stack_iface_ = nullptr;
audio_config_ = nullptr;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus BluetoothAudioProvider::streamStarted(
BluetoothAudioStatus status) {
if (stack_iface_ != nullptr) {
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
<< ", status=" << toString(status);
BluetoothAudioSessionReport::ReportControlStatus(session_type_, true,
status);
} else {
LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
<< ", status=" << toString(status) << " has NO session";
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus BluetoothAudioProvider::streamSuspended(
BluetoothAudioStatus status) {
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
<< ", status=" << toString(status);
if (stack_iface_ != nullptr) {
BluetoothAudioSessionReport::ReportControlStatus(session_type_, false,
status);
} else {
LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
<< ", status=" << toString(status) << " has NO session";
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus BluetoothAudioProvider::updateAudioConfiguration(
const AudioConfiguration& audio_config) {
if (stack_iface_ == nullptr || audio_config_ == nullptr) {
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
<< " has NO session";
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
if (audio_config.getTag() != audio_config_->getTag()) {
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
<< " audio config type is not match";
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
BluetoothAudioSessionReport::ReportAudioConfigChanged(session_type_,
*audio_config_);
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
<< " | audio_config=" << audio_config.toString();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus BluetoothAudioProvider::setLowLatencyModeAllowed(
bool allowed) {
if (stack_iface_ == nullptr) {
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
<< " has NO session";
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
LOG(INFO) << __func__ << " - allowed " << allowed;
BluetoothAudioSessionReport::ReportLowLatencyModeAllowedChanged(
session_type_, allowed);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus BluetoothAudioProvider::parseA2dpConfiguration(
[[maybe_unused]] const CodecId& codec_id,
[[maybe_unused]] const std::vector<uint8_t>& configuration,
[[maybe_unused]] CodecParameters* codec_parameters,
[[maybe_unused]] A2dpStatus* _aidl_return) {
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
<< " is illegal";
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
ndk::ScopedAStatus BluetoothAudioProvider::getA2dpConfiguration(
[[maybe_unused]] const std::vector<A2dpRemoteCapabilities>&
remote_a2dp_capabilities,
[[maybe_unused]] const A2dpConfigurationHint& hint,
[[maybe_unused]] std::optional<audio::A2dpConfiguration>* _aidl_return) {
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
<< " is illegal";
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
ndk::ScopedAStatus BluetoothAudioProvider::setCodecPriority(
const ::aidl::android::hardware::bluetooth::audio::CodecId& in_codecId,
int32_t in_priority) {
/* TODO: Implement */
(void)in_codecId;
(void)in_priority;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
};
ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseConfiguration(
const std::optional<std::vector<std::optional<
::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
LeAudioDeviceCapabilities>>>& in_remoteSinkAudioCapabilities,
const std::optional<std::vector<std::optional<
::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
LeAudioDeviceCapabilities>>>& in_remoteSourceAudioCapabilities,
const std::vector<
::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
LeAudioConfigurationRequirement>& in_requirements,
std::vector<::aidl::android::hardware::bluetooth::audio::
IBluetoothAudioProvider::LeAudioAseConfigurationSetting>*
_aidl_return) {
/* TODO: Implement */
(void)in_remoteSinkAudioCapabilities;
(void)in_remoteSourceAudioCapabilities;
(void)in_requirements;
(void)_aidl_return;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
};
ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseQosConfiguration(
const ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
LeAudioAseQosConfigurationRequirement& in_qosRequirement,
::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
LeAudioAseQosConfigurationPair* _aidl_return) {
/* TODO: Implement */
(void)in_qosRequirement;
(void)_aidl_return;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
};
ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseDatapathConfiguration(
const std::optional<::aidl::android::hardware::bluetooth::audio::
IBluetoothAudioProvider::StreamConfig>&
in_sinkConfig,
const std::optional<::aidl::android::hardware::bluetooth::audio::
IBluetoothAudioProvider::StreamConfig>&
in_sourceConfig,
::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
LeAudioDataPathConfigurationPair* _aidl_return) {
/* TODO: Implement */
(void)in_sinkConfig;
(void)in_sourceConfig;
(void)_aidl_return;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
ndk::ScopedAStatus BluetoothAudioProvider::onSinkAseMetadataChanged(
::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
AseState in_state,
int32_t cigId, int32_t cisId,
const std::optional<std::vector<std::optional<
::aidl::android::hardware::bluetooth::audio::MetadataLtv>>>&
in_metadata) {
/* TODO: Implement */
(void)in_state;
(void)cigId;
(void)cisId;
(void)in_metadata;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
};
ndk::ScopedAStatus BluetoothAudioProvider::onSourceAseMetadataChanged(
::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
AseState in_state,
int32_t cigId, int32_t cisId,
const std::optional<std::vector<std::optional<
::aidl::android::hardware::bluetooth::audio::MetadataLtv>>>&
in_metadata) {
/* TODO: Implement */
(void)in_state;
(void)cigId;
(void)cisId;
(void)in_metadata;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
};
ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioBroadcastConfiguration(
const std::optional<std::vector<std::optional<
::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
LeAudioDeviceCapabilities>>>& in_remoteSinkAudioCapabilities,
const ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
LeAudioBroadcastConfigurationRequirement& in_requirement,
::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
LeAudioBroadcastConfigurationSetting* _aidl_return) {
/* TODO: Implement */
(void)in_remoteSinkAudioCapabilities;
(void)in_requirement;
(void)_aidl_return;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
};
ndk::ScopedAStatus
BluetoothAudioProvider::getLeAudioBroadcastDatapathConfiguration(
const ::aidl::android::hardware::bluetooth::audio::AudioContext& in_context,
const std::vector<::aidl::android::hardware::bluetooth::audio::
LeAudioBroadcastConfiguration::BroadcastStreamMap>&
in_streamMap,
::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
LeAudioDataPathConfiguration* _aidl_return) {
/* TODO: Implement */
(void)in_context;
(void)in_streamMap;
(void)_aidl_return;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
} // namespace audio
} // namespace bluetooth
} // namespace hardware
} // namespace android
} // namespace aidl