xref: /aosp_15_r20/hardware/interfaces/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "BTAudioProviderA2dpHW"
18*4d7e907cSAndroid Build Coastguard Worker 
19*4d7e907cSAndroid Build Coastguard Worker #include "A2dpOffloadAudioProvider.h"
20*4d7e907cSAndroid Build Coastguard Worker 
21*4d7e907cSAndroid Build Coastguard Worker #include <BluetoothAudioCodecs.h>
22*4d7e907cSAndroid Build Coastguard Worker #include <BluetoothAudioSessionReport.h>
23*4d7e907cSAndroid Build Coastguard Worker #include <android-base/logging.h>
24*4d7e907cSAndroid Build Coastguard Worker 
25*4d7e907cSAndroid Build Coastguard Worker #include "A2dpOffloadCodecAac.h"
26*4d7e907cSAndroid Build Coastguard Worker #include "A2dpOffloadCodecSbc.h"
27*4d7e907cSAndroid Build Coastguard Worker 
28*4d7e907cSAndroid Build Coastguard Worker namespace aidl {
29*4d7e907cSAndroid Build Coastguard Worker namespace android {
30*4d7e907cSAndroid Build Coastguard Worker namespace hardware {
31*4d7e907cSAndroid Build Coastguard Worker namespace bluetooth {
32*4d7e907cSAndroid Build Coastguard Worker namespace audio {
33*4d7e907cSAndroid Build Coastguard Worker 
A2dpOffloadEncodingAudioProvider(const A2dpOffloadCodecFactory & codec_factory)34*4d7e907cSAndroid Build Coastguard Worker A2dpOffloadEncodingAudioProvider::A2dpOffloadEncodingAudioProvider(
35*4d7e907cSAndroid Build Coastguard Worker     const A2dpOffloadCodecFactory& codec_factory)
36*4d7e907cSAndroid Build Coastguard Worker     : A2dpOffloadAudioProvider(codec_factory) {
37*4d7e907cSAndroid Build Coastguard Worker   session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
38*4d7e907cSAndroid Build Coastguard Worker }
39*4d7e907cSAndroid Build Coastguard Worker 
A2dpOffloadDecodingAudioProvider(const A2dpOffloadCodecFactory & codec_factory)40*4d7e907cSAndroid Build Coastguard Worker A2dpOffloadDecodingAudioProvider::A2dpOffloadDecodingAudioProvider(
41*4d7e907cSAndroid Build Coastguard Worker     const A2dpOffloadCodecFactory& codec_factory)
42*4d7e907cSAndroid Build Coastguard Worker     : A2dpOffloadAudioProvider(codec_factory) {
43*4d7e907cSAndroid Build Coastguard Worker   session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH;
44*4d7e907cSAndroid Build Coastguard Worker }
45*4d7e907cSAndroid Build Coastguard Worker 
A2dpOffloadAudioProvider(const A2dpOffloadCodecFactory & codec_factory)46*4d7e907cSAndroid Build Coastguard Worker A2dpOffloadAudioProvider::A2dpOffloadAudioProvider(
47*4d7e907cSAndroid Build Coastguard Worker     const A2dpOffloadCodecFactory& codec_factory)
48*4d7e907cSAndroid Build Coastguard Worker     : codec_factory_(codec_factory) {}
49*4d7e907cSAndroid Build Coastguard Worker 
isValid(const SessionType & session_type)50*4d7e907cSAndroid Build Coastguard Worker bool A2dpOffloadAudioProvider::isValid(const SessionType& session_type) {
51*4d7e907cSAndroid Build Coastguard Worker   return (session_type == session_type_);
52*4d7e907cSAndroid Build Coastguard Worker }
53*4d7e907cSAndroid Build Coastguard Worker 
startSession(const std::shared_ptr<IBluetoothAudioPort> & host_if,const AudioConfiguration & audio_config,const std::vector<LatencyMode> & latency_modes,DataMQDesc * _aidl_return)54*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus A2dpOffloadAudioProvider::startSession(
55*4d7e907cSAndroid Build Coastguard Worker     const std::shared_ptr<IBluetoothAudioPort>& host_if,
56*4d7e907cSAndroid Build Coastguard Worker     const AudioConfiguration& audio_config,
57*4d7e907cSAndroid Build Coastguard Worker     const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
58*4d7e907cSAndroid Build Coastguard Worker   if (audio_config.getTag() == AudioConfiguration::Tag::a2dp) {
59*4d7e907cSAndroid Build Coastguard Worker     auto a2dp_config = audio_config.get<AudioConfiguration::Tag::a2dp>();
60*4d7e907cSAndroid Build Coastguard Worker     A2dpStatus a2dp_status = A2dpStatus::NOT_SUPPORTED_CODEC_TYPE;
61*4d7e907cSAndroid Build Coastguard Worker 
62*4d7e907cSAndroid Build Coastguard Worker     auto codec = codec_factory_.GetCodec(a2dp_config.codecId);
63*4d7e907cSAndroid Build Coastguard Worker     if (!codec) {
64*4d7e907cSAndroid Build Coastguard Worker       LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
65*4d7e907cSAndroid Build Coastguard Worker                 << " - CodecId=" << a2dp_config.codecId.toString()
66*4d7e907cSAndroid Build Coastguard Worker                 << " is not found";
67*4d7e907cSAndroid Build Coastguard Worker       return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
68*4d7e907cSAndroid Build Coastguard Worker     }
69*4d7e907cSAndroid Build Coastguard Worker 
70*4d7e907cSAndroid Build Coastguard Worker     if (codec->info.id == CodecId(CodecId::A2dp::SBC)) {
71*4d7e907cSAndroid Build Coastguard Worker       SbcParameters sbc_parameters;
72*4d7e907cSAndroid Build Coastguard Worker 
73*4d7e907cSAndroid Build Coastguard Worker       auto codec_sbc =
74*4d7e907cSAndroid Build Coastguard Worker           std::static_pointer_cast<const A2dpOffloadCodecSbc>(codec);
75*4d7e907cSAndroid Build Coastguard Worker       a2dp_status = codec_sbc->ParseConfiguration(a2dp_config.configuration,
76*4d7e907cSAndroid Build Coastguard Worker                                                   &sbc_parameters);
77*4d7e907cSAndroid Build Coastguard Worker 
78*4d7e907cSAndroid Build Coastguard Worker     } else if (codec->info.id == CodecId(CodecId::A2dp::AAC)) {
79*4d7e907cSAndroid Build Coastguard Worker       AacParameters aac_parameters;
80*4d7e907cSAndroid Build Coastguard Worker 
81*4d7e907cSAndroid Build Coastguard Worker       auto codec_aac =
82*4d7e907cSAndroid Build Coastguard Worker           std::static_pointer_cast<const A2dpOffloadCodecAac>(codec);
83*4d7e907cSAndroid Build Coastguard Worker       a2dp_status = codec_aac->ParseConfiguration(a2dp_config.configuration,
84*4d7e907cSAndroid Build Coastguard Worker                                                   &aac_parameters);
85*4d7e907cSAndroid Build Coastguard Worker     }
86*4d7e907cSAndroid Build Coastguard Worker     if (a2dp_status != A2dpStatus::OK) {
87*4d7e907cSAndroid Build Coastguard Worker       LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
88*4d7e907cSAndroid Build Coastguard Worker                    << audio_config.toString();
89*4d7e907cSAndroid Build Coastguard Worker       *_aidl_return = DataMQDesc();
90*4d7e907cSAndroid Build Coastguard Worker       return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
91*4d7e907cSAndroid Build Coastguard Worker     }
92*4d7e907cSAndroid Build Coastguard Worker   } else if (audio_config.getTag() == AudioConfiguration::Tag::a2dpConfig) {
93*4d7e907cSAndroid Build Coastguard Worker     if (!BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
94*4d7e907cSAndroid Build Coastguard Worker             session_type_,
95*4d7e907cSAndroid Build Coastguard Worker             audio_config.get<AudioConfiguration::a2dpConfig>())) {
96*4d7e907cSAndroid Build Coastguard Worker       LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
97*4d7e907cSAndroid Build Coastguard Worker                    << audio_config.toString();
98*4d7e907cSAndroid Build Coastguard Worker       *_aidl_return = DataMQDesc();
99*4d7e907cSAndroid Build Coastguard Worker       return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
100*4d7e907cSAndroid Build Coastguard Worker     }
101*4d7e907cSAndroid Build Coastguard Worker   } else {
102*4d7e907cSAndroid Build Coastguard Worker     LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
103*4d7e907cSAndroid Build Coastguard Worker                  << audio_config.toString();
104*4d7e907cSAndroid Build Coastguard Worker     *_aidl_return = DataMQDesc();
105*4d7e907cSAndroid Build Coastguard Worker     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
106*4d7e907cSAndroid Build Coastguard Worker   }
107*4d7e907cSAndroid Build Coastguard Worker 
108*4d7e907cSAndroid Build Coastguard Worker   return BluetoothAudioProvider::startSession(
109*4d7e907cSAndroid Build Coastguard Worker       host_if, audio_config, latency_modes, _aidl_return);
110*4d7e907cSAndroid Build Coastguard Worker }
111*4d7e907cSAndroid Build Coastguard Worker 
onSessionReady(DataMQDesc * _aidl_return)112*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus A2dpOffloadAudioProvider::onSessionReady(
113*4d7e907cSAndroid Build Coastguard Worker     DataMQDesc* _aidl_return) {
114*4d7e907cSAndroid Build Coastguard Worker   *_aidl_return = DataMQDesc();
115*4d7e907cSAndroid Build Coastguard Worker   BluetoothAudioSessionReport::OnSessionStarted(
116*4d7e907cSAndroid Build Coastguard Worker       session_type_, stack_iface_, nullptr, *audio_config_, latency_modes_);
117*4d7e907cSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
118*4d7e907cSAndroid Build Coastguard Worker }
119*4d7e907cSAndroid Build Coastguard Worker 
parseA2dpConfiguration(const CodecId & codec_id,const std::vector<uint8_t> & configuration,CodecParameters * codec_parameters,A2dpStatus * _aidl_return)120*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus A2dpOffloadAudioProvider::parseA2dpConfiguration(
121*4d7e907cSAndroid Build Coastguard Worker     const CodecId& codec_id, const std::vector<uint8_t>& configuration,
122*4d7e907cSAndroid Build Coastguard Worker     CodecParameters* codec_parameters, A2dpStatus* _aidl_return) {
123*4d7e907cSAndroid Build Coastguard Worker   if (!kEnableA2dpCodecExtensibility) {
124*4d7e907cSAndroid Build Coastguard Worker     // parseA2dpConfiguration must not be implemented if A2dp codec
125*4d7e907cSAndroid Build Coastguard Worker     // extensibility is not supported.
126*4d7e907cSAndroid Build Coastguard Worker     return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION);
127*4d7e907cSAndroid Build Coastguard Worker   }
128*4d7e907cSAndroid Build Coastguard Worker 
129*4d7e907cSAndroid Build Coastguard Worker   auto codec = codec_factory_.GetCodec(codec_id);
130*4d7e907cSAndroid Build Coastguard Worker   if (!codec) {
131*4d7e907cSAndroid Build Coastguard Worker     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
132*4d7e907cSAndroid Build Coastguard Worker               << " - CodecId=" << codec_id.toString() << " is not found";
133*4d7e907cSAndroid Build Coastguard Worker     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
134*4d7e907cSAndroid Build Coastguard Worker   }
135*4d7e907cSAndroid Build Coastguard Worker 
136*4d7e907cSAndroid Build Coastguard Worker   *_aidl_return = codec->ParseConfiguration(configuration, codec_parameters);
137*4d7e907cSAndroid Build Coastguard Worker 
138*4d7e907cSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
139*4d7e907cSAndroid Build Coastguard Worker }
140*4d7e907cSAndroid Build Coastguard Worker 
getA2dpConfiguration(const std::vector<A2dpRemoteCapabilities> & remote_a2dp_capabilities,const A2dpConfigurationHint & hint,std::optional<audio::A2dpConfiguration> * _aidl_return)141*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus A2dpOffloadAudioProvider::getA2dpConfiguration(
142*4d7e907cSAndroid Build Coastguard Worker     const std::vector<A2dpRemoteCapabilities>& remote_a2dp_capabilities,
143*4d7e907cSAndroid Build Coastguard Worker     const A2dpConfigurationHint& hint,
144*4d7e907cSAndroid Build Coastguard Worker     std::optional<audio::A2dpConfiguration>* _aidl_return) {
145*4d7e907cSAndroid Build Coastguard Worker   if (!kEnableA2dpCodecExtensibility) {
146*4d7e907cSAndroid Build Coastguard Worker     // getA2dpConfiguration must not be implemented if A2dp codec
147*4d7e907cSAndroid Build Coastguard Worker     // extensibility is not supported.
148*4d7e907cSAndroid Build Coastguard Worker     return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION);
149*4d7e907cSAndroid Build Coastguard Worker   }
150*4d7e907cSAndroid Build Coastguard Worker 
151*4d7e907cSAndroid Build Coastguard Worker   *_aidl_return = std::nullopt;
152*4d7e907cSAndroid Build Coastguard Worker   A2dpConfiguration avdtp_configuration;
153*4d7e907cSAndroid Build Coastguard Worker 
154*4d7e907cSAndroid Build Coastguard Worker   if (codec_factory_.GetConfiguration(remote_a2dp_capabilities, hint,
155*4d7e907cSAndroid Build Coastguard Worker                                       &avdtp_configuration))
156*4d7e907cSAndroid Build Coastguard Worker     *_aidl_return =
157*4d7e907cSAndroid Build Coastguard Worker         std::make_optional<A2dpConfiguration>(std::move(avdtp_configuration));
158*4d7e907cSAndroid Build Coastguard Worker 
159*4d7e907cSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
160*4d7e907cSAndroid Build Coastguard Worker }
161*4d7e907cSAndroid Build Coastguard Worker 
162*4d7e907cSAndroid Build Coastguard Worker }  // namespace audio
163*4d7e907cSAndroid Build Coastguard Worker }  // namespace bluetooth
164*4d7e907cSAndroid Build Coastguard Worker }  // namespace hardware
165*4d7e907cSAndroid Build Coastguard Worker }  // namespace android
166*4d7e907cSAndroid Build Coastguard Worker }  // namespace aidl
167