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 // Code in this file uses 'getCachedPolicyConfig'
18 #ifndef AUDIO_PRIMARY_HIDL_HAL_TEST
19 #error Must be included from AudioPrimaryHidlTest.h
20 #endif
21 
22 //////////////////////////////////////////////////////////////////////////////
23 //////////////// Required and recommended audio format support ///////////////
24 // From:
25 // https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
26 // From:
27 // https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback
28 /////////// TODO: move to the beginning of the file for easier update ////////
29 //////////////////////////////////////////////////////////////////////////////
30 
31 struct ConfigHelper {
32     // for retro compatibility only test the primary device IN_BUILTIN_MIC
33     // FIXME: in the next audio HAL version, test all available devices
primaryHasMicConfigHelper34     static bool primaryHasMic() {
35         auto& policyConfig = getCachedPolicyConfig();
36         if (policyConfig.getStatus() != OK || policyConfig.getPrimaryModule() == nullptr) {
37             return true;  // Could not get the information, run all tests
38         }
39         auto getMic = [](auto& devs) {
40             return devs.getDevice(AUDIO_DEVICE_IN_BUILTIN_MIC, {}, AUDIO_FORMAT_DEFAULT);
41         };
42         auto primaryMic = getMic(policyConfig.getPrimaryModule()->getDeclaredDevices());
43         auto availableMic = getMic(policyConfig.getInputDevices());
44 
45         return primaryMic != nullptr && primaryMic->equals(availableMic);
46     }
47 
48     // Cache result ?
getRequiredSupportPlaybackAudioConfigConfigHelper49     static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
50         return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
51                                   {8000, 11025, 16000, 22050, 32000, 44100},
52                                   {AudioFormat::PCM_16_BIT});
53     }
54 
getRecommendedSupportPlaybackAudioConfigConfigHelper55     static const vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
56         return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
57                                   {24000, 48000}, {AudioFormat::PCM_16_BIT});
58     }
59 
getRequiredSupportCaptureAudioConfigConfigHelper60     static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
61         if (!primaryHasMic()) return {};
62         return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100},
63                                   {AudioFormat::PCM_16_BIT});
64     }
getRecommendedSupportCaptureAudioConfigConfigHelper65     static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
66         if (!primaryHasMic()) return {};
67         return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
68                                   {AudioFormat::PCM_16_BIT});
69     }
70 
combineAudioConfigConfigHelper71     static vector<AudioConfig> combineAudioConfig(vector<audio_channel_mask_t> channelMasks,
72                                                   vector<uint32_t> sampleRates,
73                                                   audio_format_t format) {
74         vector<AudioConfig> configs;
75         configs.reserve(channelMasks.size() * sampleRates.size());
76         for (auto channelMask : channelMasks) {
77             for (auto sampleRate : sampleRates) {
78                 AudioConfig config{};
79                 // leave offloadInfo to 0
80                 config.channelMask = EnumBitfield<AudioChannelMask>(channelMask);
81                 config.sampleRateHz = sampleRate;
82                 config.format = AudioFormat(format);
83                 configs.push_back(config);
84             }
85         }
86         return configs;
87     }
88 
combineAudioConfigConfigHelper89     static vector<AudioConfig> combineAudioConfig(vector<AudioChannelMask> channelMasks,
90                                                   vector<uint32_t> sampleRates,
91                                                   vector<AudioFormat> formats) {
92         vector<AudioConfig> configs;
93         configs.reserve(channelMasks.size() * sampleRates.size() * formats.size());
94         for (auto channelMask : channelMasks) {
95             for (auto sampleRate : sampleRates) {
96                 for (auto format : formats) {
97                     AudioConfig config{};
98                     // leave offloadInfo to 0
99                     config.channelMask = mkEnumBitfield(channelMask);
100                     config.sampleRateHz = sampleRate;
101                     config.format = format;
102                     // FIXME: leave frameCount to 0 ?
103                     configs.push_back(config);
104                 }
105             }
106         }
107         return configs;
108     }
109 };
110