1 /*
2 * Copyright 2024 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 #include <bluetooth/log.h>
18 #include <gtest/gtest.h>
19
20 #include <cstdint>
21 #include <string>
22
23 #include "hardware/bt_av.h"
24 #include "stack/include/a2dp_codec_api.h"
25 #include "stack/include/a2dp_constants.h"
26 #include "stack/include/a2dp_vendor_aptx_constants.h"
27 #include "stack/include/a2dp_vendor_aptx_hd_constants.h"
28 #include "stack/include/a2dp_vendor_ldac_constants.h"
29 #include "stack/include/a2dp_vendor_opus_constants.h"
30 #include "stack/include/avdt_api.h"
31
32 namespace {
33 static constexpr uint8_t kCodecCapabilitiesWithTruncatedMediaCodecType[] = {0x0};
34 static constexpr uint8_t kCodecCapabilitiesWithTruncatedVendorCodecId[] = {0x5, 0x0, 0xff,
35 0x1, 0x2, 0x3};
36 static constexpr uint8_t kCodecCapabilitiesWithInvalidMediaCodecType[] = {0x2, 0x0, 0xaa};
37 static constexpr uint8_t kCodecCapabilitiesWithInvalidVendorCodecId[] = {0x8, 0x0, 0xff, 0x1, 0x2,
38 0x3, 0x4, 0x5, 0x6};
39
40 static constexpr uint8_t kSbcCodecCapabilities[] = {
41 6, // Length (A2DP_SBC_INFO_LEN)
42 0, // Media Type: AVDT_MEDIA_TYPE_AUDIO
43 0, // Media Codec Type: A2DP_MEDIA_CT_SBC
44 0x20 | 0x01, // Sample Frequency: A2DP_SBC_IE_SAMP_FREQ_44 |
45 // Channel Mode: A2DP_SBC_IE_CH_MD_JOINT
46 0x10 | 0x04 | 0x01, // Block Length: A2DP_SBC_IE_BLOCKS_16 |
47 // Subbands: A2DP_SBC_IE_SUBBAND_8 |
48 // Allocation Method: A2DP_SBC_IE_ALLOC_MD_L
49 2, // MinimumBitpool Value: A2DP_SBC_IE_MIN_BITPOOL
50 53, // Maximum Bitpool Value: A2DP_SBC_MAX_BITPOOL
51 7, // Fake
52 8, // Fake
53 9 // Fake
54 };
55
56 static constexpr uint8_t kAacCodecCapabilities[] = {
57 8, // Length (A2DP_AAC_INFO_LEN)
58 0, // Media Type: AVDT_MEDIA_TYPE_AUDIO
59 2, // Media Codec Type: A2DP_MEDIA_CT_AAC
60 0x80, // Object Type: A2DP_AAC_OBJECT_TYPE_MPEG2_LC
61 0x01, // Sampling Frequency: A2DP_AAC_SAMPLING_FREQ_44100
62 0x04, // Channels: A2DP_AAC_CHANNEL_MODE_STEREO
63 0x00 | 0x4, // Variable Bit Rate:
64 // A2DP_AAC_VARIABLE_BIT_RATE_DISABLED
65 // Bit Rate: 320000 = 0x4e200
66 0xe2, // Bit Rate: 320000 = 0x4e200
67 0x00, // Bit Rate: 320000 = 0x4e200
68 7, // Unused
69 8, // Unused
70 9 // Unused
71 };
72
73 static constexpr uint8_t kAptxCodecCapabilities[] = {
74 A2DP_APTX_CODEC_LEN,
75 AVDT_MEDIA_TYPE_AUDIO,
76 A2DP_MEDIA_CT_NON_A2DP,
77 0x4F, // A2DP_APTX_VENDOR_ID
78 0x00, // A2DP_APTX_VENDOR_ID
79 0x00, // A2DP_APTX_VENDOR_ID
80 0x00, // A2DP_APTX_VENDOR_ID
81 0x01, // A2DP_APTX_CODEC_ID
82 0x00, // A2DP_APTX_CODEC_ID,
83 A2DP_APTX_SAMPLERATE_44100 | A2DP_APTX_CHANNELS_STEREO,
84 };
85
86 static constexpr uint8_t kAptxHdCodecCapabilities[] = {
87 A2DP_APTX_HD_CODEC_LEN,
88 AVDT_MEDIA_TYPE_AUDIO,
89 A2DP_MEDIA_CT_NON_A2DP,
90 0xD7, // A2DP_APTX_HD_VENDOR_ID
91 0x00, // A2DP_APTX_HD_VENDOR_ID
92 0x00, // A2DP_APTX_HD_VENDOR_ID
93 0x00, // A2DP_APTX_HD_VENDOR_ID
94 0x24, // A2DP_APTX_HD_CODEC_ID
95 0x00, // A2DP_APTX_HD_CODEC_ID,
96 A2DP_APTX_HD_SAMPLERATE_44100 | A2DP_APTX_HD_CHANNELS_STEREO,
97 A2DP_APTX_HD_ACL_SPRINT_RESERVED0,
98 A2DP_APTX_HD_ACL_SPRINT_RESERVED1,
99 A2DP_APTX_HD_ACL_SPRINT_RESERVED2,
100 A2DP_APTX_HD_ACL_SPRINT_RESERVED3,
101 };
102
103 static constexpr uint8_t kLdacCodecCapabilities[] = {
104 A2DP_LDAC_CODEC_LEN,
105 AVDT_MEDIA_TYPE_AUDIO,
106 A2DP_MEDIA_CT_NON_A2DP,
107 0x2D, // A2DP_LDAC_VENDOR_ID
108 0x01, // A2DP_LDAC_VENDOR_ID
109 0x00, // A2DP_LDAC_VENDOR_ID
110 0x00, // A2DP_LDAC_VENDOR_ID
111 0xAA, // A2DP_LDAC_CODEC_ID
112 0x00, // A2DP_LDAC_CODEC_ID,
113 A2DP_LDAC_SAMPLING_FREQ_44100,
114 A2DP_LDAC_CHANNEL_MODE_STEREO,
115 };
116
117 static constexpr uint8_t kOpusCodecCapabilities[] = {
118 A2DP_OPUS_CODEC_LEN, // Length
119 AVDT_MEDIA_TYPE_AUDIO << 4, // Media Type
120 A2DP_MEDIA_CT_NON_A2DP, // Media Codec Type Vendor
121 (A2DP_OPUS_VENDOR_ID & 0x000000FF),
122 (A2DP_OPUS_VENDOR_ID & 0x0000FF00) >> 8,
123 (A2DP_OPUS_VENDOR_ID & 0x00FF0000) >> 16,
124 (A2DP_OPUS_VENDOR_ID & 0xFF000000) >> 24,
125 (A2DP_OPUS_CODEC_ID & 0x00FF),
126 (A2DP_OPUS_CODEC_ID & 0xFF00) >> 8,
127 A2DP_OPUS_CHANNEL_MODE_STEREO | A2DP_OPUS_20MS_FRAMESIZE | A2DP_OPUS_SAMPLING_FREQ_48000,
128 };
129 } // namespace
130
131 namespace bluetooth::a2dp {
132
133 class MediaCodecCapabilitiesTest : public ::testing::Test {};
134
135 // Test the correctness of the method `bluetooth::a2dp::ParseCodecId`.
TEST_F(MediaCodecCapabilitiesTest,ParseCodecId)136 TEST_F(MediaCodecCapabilitiesTest, ParseCodecId) {
137 ASSERT_EQ(ParseCodecId(kCodecCapabilitiesWithTruncatedMediaCodecType), std::nullopt);
138 ASSERT_EQ(ParseCodecId(kCodecCapabilitiesWithTruncatedVendorCodecId), std::nullopt);
139 ASSERT_EQ(ParseCodecId(kCodecCapabilitiesWithInvalidMediaCodecType), std::nullopt);
140 ASSERT_EQ(ParseCodecId(kCodecCapabilitiesWithInvalidVendorCodecId), std::nullopt);
141
142 ASSERT_EQ(ParseCodecId(kSbcCodecCapabilities), CodecId::SBC);
143 ASSERT_EQ(ParseCodecId(kAacCodecCapabilities), CodecId::AAC);
144 ASSERT_EQ(ParseCodecId(kAptxCodecCapabilities), CodecId::APTX);
145 ASSERT_EQ(ParseCodecId(kAptxHdCodecCapabilities), CodecId::APTX_HD);
146 ASSERT_EQ(ParseCodecId(kLdacCodecCapabilities), CodecId::LDAC);
147 ASSERT_EQ(ParseCodecId(kOpusCodecCapabilities), CodecId::OPUS);
148 }
149
150 // Test provided to validate the Media Codec Capabilities, the legacy APIs `A2DP_xxx`
151 // are considered the source of truth here.
TEST_F(MediaCodecCapabilitiesTest,A2DP_SourceCodecIndex)152 TEST_F(MediaCodecCapabilitiesTest, A2DP_SourceCodecIndex) {
153 ASSERT_EQ(A2DP_SourceCodecIndex(kSbcCodecCapabilities), BTAV_A2DP_CODEC_INDEX_SOURCE_SBC);
154 ASSERT_EQ(A2DP_SourceCodecIndex(kAacCodecCapabilities), BTAV_A2DP_CODEC_INDEX_SOURCE_AAC);
155 ASSERT_EQ(A2DP_SourceCodecIndex(kAptxCodecCapabilities), BTAV_A2DP_CODEC_INDEX_SOURCE_APTX);
156 ASSERT_EQ(A2DP_SourceCodecIndex(kAptxHdCodecCapabilities), BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD);
157 ASSERT_EQ(A2DP_SourceCodecIndex(kLdacCodecCapabilities), BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC);
158 ASSERT_EQ(A2DP_SourceCodecIndex(kOpusCodecCapabilities), BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS);
159 }
160
161 } // namespace bluetooth::a2dp
162