1 /*
2  * Copyright (C) 2019 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 <common/all-versions/VersionUtils.h>
20 
21 #include "PolicyConfig.h"
22 
23 // clang-format off
24 #include PATH(android/hardware/audio/FILE_VERSION/types.h)
25 #include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
26 // clang-format on
27 
28 using ::android::hardware::audio::common::utils::EnumBitfield;
29 using ::android::hardware::audio::common::utils::mkEnumBitfield;
30 
31 // Forward declaration for functions that are substituted
32 // in generator unit tests.
33 const PolicyConfig& getCachedPolicyConfig();
34 
35 //////////////////////////////////////////////////////////////////////////////
36 //////////////// Required and recommended audio format support ///////////////
37 // From:
38 // https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
39 // From:
40 // https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback
41 /////////// TODO: move to the beginning of the file for easier update ////////
42 //////////////////////////////////////////////////////////////////////////////
43 
44 struct ConfigHelper {
45     // for retro compatibility only test the primary device IN_BUILTIN_MIC
46     // FIXME: in the next audio HAL version, test all available devices
primaryHasMicConfigHelper47     static bool primaryHasMic() {
48         auto& policyConfig = getCachedPolicyConfig();
49         if (policyConfig.getStatus() != android::OK || policyConfig.getPrimaryModule() == nullptr) {
50             return true;  // Could not get the information, run all tests
51         }
52         auto getMic = [](auto& devs) {
53             return devs.getDevice(AUDIO_DEVICE_IN_BUILTIN_MIC, {}, AUDIO_FORMAT_DEFAULT);
54         };
55         auto primaryMic = getMic(policyConfig.getPrimaryModule()->getDeclaredDevices());
56         auto availableMic = getMic(policyConfig.getInputDevices());
57 
58         return primaryMic != nullptr && primaryMic->equals(availableMic);
59     }
60 
61     // Cache result ?
getRequiredSupportPlaybackAudioConfigConfigHelper62     static const std::vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
63         return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
64                                   {8000, 11025, 16000, 22050, 32000, 44100},
65                                   {AudioFormat::PCM_16_BIT});
66     }
67 
getRecommendedSupportPlaybackAudioConfigConfigHelper68     static const std::vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
69         return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
70                                   {24000, 48000}, {AudioFormat::PCM_16_BIT});
71     }
72 
getRequiredSupportCaptureAudioConfigConfigHelper73     static const std::vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
74         if (!primaryHasMic()) return {};
75         return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100},
76                                   {AudioFormat::PCM_16_BIT});
77     }
getRecommendedSupportCaptureAudioConfigConfigHelper78     static const std::vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
79         if (!primaryHasMic()) return {};
80         return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
81                                   {AudioFormat::PCM_16_BIT});
82     }
83 
combineAudioConfigConfigHelper84     static std::vector<AudioConfig> combineAudioConfig(
85             std::vector<audio_channel_mask_t> channelMasks, std::vector<uint32_t> sampleRates,
86             audio_format_t format) {
87         std::vector<AudioConfig> configs;
88         configs.reserve(channelMasks.size() * sampleRates.size());
89         for (auto channelMask : channelMasks) {
90             for (auto sampleRate : sampleRates) {
91                 AudioConfig config{};
92                 // leave offloadInfo to 0
93                 config.channelMask = EnumBitfield<AudioChannelMask>(channelMask);
94                 config.sampleRateHz = sampleRate;
95                 config.format = AudioFormat(format);
96                 configs.push_back(config);
97             }
98         }
99         return configs;
100     }
101 
combineAudioConfigConfigHelper102     static std::vector<AudioConfig> combineAudioConfig(std::vector<AudioChannelMask> channelMasks,
103                                                        std::vector<uint32_t> sampleRates,
104                                                        std::vector<AudioFormat> formats) {
105         std::vector<AudioConfig> configs;
106         configs.reserve(channelMasks.size() * sampleRates.size() * formats.size());
107         for (auto channelMask : channelMasks) {
108             for (auto sampleRate : sampleRates) {
109                 for (auto format : formats) {
110                     AudioConfig config{};
111                     // leave offloadInfo to 0
112                     config.channelMask = mkEnumBitfield(channelMask);
113                     config.sampleRateHz = sampleRate;
114                     config.format = format;
115                     // FIXME: leave frameCount to 0 ?
116                     configs.push_back(config);
117                 }
118             }
119         }
120         return configs;
121     }
122 };
123