1 /*
2  * Copyright 2023 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 #pragma once
18 
19 #include <unordered_map>
20 #include <vector>
21 
22 #include "audio_aidl_interfaces.h"
23 #include "include/hardware/bt_av.h"
24 
25 namespace bluetooth::audio::aidl::a2dp {
26 
27 using ::aidl::android::hardware::bluetooth::audio::CodecId;
28 using ::aidl::android::hardware::bluetooth::audio::CodecInfo;
29 
30 /***
31  * Record the provider info returned by the HAL implementer.
32  ***/
33 class ProviderInfo {
34  public:
35   /***
36    * Reads the provider information from the HAL.
37    * May return nullptr if the HAL does not implement
38    * getProviderInfo, or if the feature flag for codec
39    * extensibility is disabled.
40    ***/
41   static std::unique_ptr<ProviderInfo> GetProviderInfo(
42       bool supports_a2dp_hw_offload_v2);
43 
44   ProviderInfo(std::vector<CodecInfo> source_codecs,
45                std::vector<CodecInfo> sink_codecs);
46   ~ProviderInfo() = default;
47 
48   /***
49    * Returns the codec with the selected index if supported
50    * by the provider.
51    ***/
52   std::optional<CodecInfo const*> GetCodec(
53       btav_a2dp_codec_index_t codec_index) const;
54 
55   /***
56    * Find the source codec index by codec capabilities.
57    ***/
58   std::optional<btav_a2dp_codec_index_t> SourceCodecIndex(
59       CodecId const& codec_id) const;
60   std::optional<btav_a2dp_codec_index_t> SourceCodecIndex(
61       uint32_t vendor_id, uint16_t codec_id) const;
62   std::optional<btav_a2dp_codec_index_t> SourceCodecIndex(
63       uint8_t const* codec_info) const;
64 
65   /***
66    * Find the sink codec index by codec capabilities.
67    ***/
68   std::optional<btav_a2dp_codec_index_t> SinkCodecIndex(
69       CodecId const& codec_id) const;
70   std::optional<btav_a2dp_codec_index_t> SinkCodecIndex(
71       uint32_t vendor_id, uint16_t codec_id) const;
72   std::optional<btav_a2dp_codec_index_t> SinkCodecIndex(
73       uint8_t const* codec_info) const;
74 
75   /***
76    * Return the name of the codec with the assigned
77    * input index.
78    ***/
79   std::optional<const char*> CodecIndexStr(
80       btav_a2dp_codec_index_t codec_index) const;
81 
82   /***
83    * Return true if the codec is supported by the
84    * provider.
85    ***/
86   bool SupportsCodec(btav_a2dp_codec_index_t codec_index) const;
87 
88   /***
89    * Helper to convert CodecId and byte[] configuration to
90    * the Media Codec Capabilities format.
91    * Returns true if the capabilities were successfully converted.
92    ***/
93   static bool BuildCodecCapabilities(CodecId const& codec_id,
94                                      std::vector<uint8_t> const& capabilities,
95                                      uint8_t* codec_info);
96 
97   /***
98    * Return the A2DP capabilities for the selected codec.
99    * Returns true if the codec is supported, false otherwise.
100    ***/
101   bool CodecCapabilities(btav_a2dp_codec_index_t codec_index,
102                          uint64_t* codec_id, uint8_t* codec_info,
103                          btav_a2dp_codec_config_t* codec_config) const;
104 
105   const std::vector<CodecInfo> source_codecs;
106   const std::vector<CodecInfo> sink_codecs;
107 
108  private:
109   std::unordered_map<btav_a2dp_codec_index_t, CodecInfo const*>
110       assigned_codec_indexes;
111 };
112 
113 }  // namespace bluetooth::audio::aidl::a2dp
114