blob: e3da26757dac4b1627ee9ef99f17b0623223c449 [file] [log] [blame]
Alice Kuo84e87672021-10-28 12:53:38 +08001/*
2 * Copyright 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "BTAudioProviderLeAudioOffload"
18
19#include "LeAudioOffloadAudioProvider.h"
20
21#include <android-base/logging.h>
22
Jakub Pawlowski8d87eb72021-12-06 15:22:03 +010023#include "AudioPort_2_0_to_2_2_Wrapper.h"
Alice Kuo84e87672021-10-28 12:53:38 +080024#include "BluetoothAudioSessionReport_2_2.h"
25#include "BluetoothAudioSupportedCodecsDB_2_1.h"
26#include "BluetoothAudioSupportedCodecsDB_2_2.h"
27
28namespace android {
29namespace hardware {
30namespace bluetooth {
31namespace audio {
32namespace V2_2 {
33namespace implementation {
34
35using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_2;
36using ::android::hardware::Void;
37using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
38using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
39using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
40
41using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
42
43LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider()
44 : LeAudioOffloadAudioProvider() {
45 session_type_ =
46 V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
47}
48
49LeAudioOffloadInputAudioProvider::LeAudioOffloadInputAudioProvider()
50 : LeAudioOffloadAudioProvider() {
51 session_type_ =
52 V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH;
53}
54
55LeAudioOffloadAudioProvider::LeAudioOffloadAudioProvider()
56 : BluetoothAudioProvider() {}
57
58bool LeAudioOffloadAudioProvider::isValid(
59 const V2_0::SessionType& sessionType) {
60 LOG(ERROR) << __func__
61 << ", invalid session type for Offloaded Le Audio provider: "
62 << toString(sessionType);
63
64 return false;
65}
66
67bool LeAudioOffloadAudioProvider::isValid(
68 const V2_1::SessionType& sessionType) {
69 return (sessionType == session_type_);
70}
71
72Return<void> LeAudioOffloadAudioProvider::startSession_2_1(
73 const sp<V2_0::IBluetoothAudioPort>& hostIf,
74 const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
75 if (audioConfig.getDiscriminator() !=
76 V2_1::AudioConfiguration::hidl_discriminator::leAudioCodecConfig) {
77 LOG(WARNING) << __func__
78 << " - Invalid Audio Configuration=" << toString(audioConfig);
79 _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
80 DataMQ::Descriptor());
81 return Void();
82 }
83
84 AudioConfiguration audioConfig_2_2;
85 audioConfig_2_2.leAudioConfig().mode = LeAudioMode::UNKNOWN;
86 audioConfig_2_2.leAudioConfig().config.unicastConfig() = {
87 .streamMap = {{
88 .streamHandle = 0xFFFF,
89 .audioChannelAllocation =
90 audioConfig.leAudioCodecConfig().audioChannelAllocation,
91 }},
92 .peerDelay = 0,
93 .lc3Config = audioConfig.leAudioCodecConfig().lc3Config};
94
Jakub Pawlowski8d87eb72021-12-06 15:22:03 +010095 sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
96 new AudioPort_2_0_to_2_2_Wrapper(hostIf);
97 return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
Alice Kuo84e87672021-10-28 12:53:38 +080098}
99
100Return<void> LeAudioOffloadAudioProvider::startSession_2_2(
Jakub Pawlowski8d87eb72021-12-06 15:22:03 +0100101 const sp<V2_2::IBluetoothAudioPort>& hostIf,
Alice Kuo84e87672021-10-28 12:53:38 +0800102 const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
103 /**
104 * Initialize the audio platform if audioConfiguration is supported.
105 * Save the IBluetoothAudioPort interface, so that it can be used
106 * later to send stream control commands to the HAL client, based on
107 * interaction with Audio framework.
108 */
109 if (audioConfig.getDiscriminator() !=
110 AudioConfiguration::hidl_discriminator::leAudioConfig) {
111 LOG(WARNING) << __func__
112 << " - Invalid Audio Configuration=" << toString(audioConfig);
113 _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
114 DataMQ::Descriptor());
115 return Void();
116 }
117
118 if (!android::bluetooth::audio::IsOffloadLeAudioConfigurationValid(
119 session_type_, audioConfig.leAudioConfig())) {
120 LOG(WARNING) << __func__ << " - Unsupported LC3 Offloaded Configuration="
121 << toString(audioConfig.leAudioConfig());
122 _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
123 DataMQ::Descriptor());
124 return Void();
125 }
126
127 return BluetoothAudioProvider::startSession_2_2(hostIf, audioConfig,
128 _hidl_cb);
129}
130
131Return<void> LeAudioOffloadAudioProvider::onSessionReady(
132 startSession_cb _hidl_cb) {
133 BluetoothAudioSessionReport_2_2::OnSessionStarted(session_type_, stack_iface_,
134 nullptr, audio_config_);
135 _hidl_cb(BluetoothAudioStatus::SUCCESS, DataMQ::Descriptor());
136 return Void();
137}
138
139} // namespace implementation
140} // namespace V2_2
141} // namespace audio
142} // namespace bluetooth
143} // namespace hardware
144} // namespace android