1 /* 2 * Copyright (C) 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 package com.android.car.audio; 18 19 import static android.media.AudioFormat.CHANNEL_OUT_MONO; 20 import static android.media.AudioFormat.CHANNEL_OUT_QUAD; 21 import static android.media.AudioFormat.CHANNEL_OUT_STEREO; 22 import static android.media.AudioFormat.ENCODING_PCM_16BIT; 23 24 import static com.google.common.truth.Truth.assertThat; 25 26 import static org.junit.Assert.assertThrows; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.when; 29 30 import android.media.AudioDeviceInfo; 31 import android.media.AudioDevicePort; 32 import android.media.AudioGain; 33 34 import androidx.test.ext.junit.runners.AndroidJUnit4; 35 36 import org.junit.Test; 37 import org.junit.runner.RunWith; 38 39 @RunWith(AndroidJUnit4.class) 40 public class CarAudioDeviceInfoTest { 41 42 private static final String TEST_ADDRESS = "test address"; 43 private static final int MIN_GAIN = 0; 44 private static final int MAX_GAIN = 100; 45 private static final int DEFAULT_GAIN = 50; 46 private static final int STEP_SIZE = 2; 47 48 @Test constructor_requiresNonNullGain()49 public void constructor_requiresNonNullGain() { 50 AudioDeviceInfo audioDeviceInfo = mock(AudioDeviceInfo.class); 51 when(audioDeviceInfo.getPort()).thenReturn(null); 52 53 assertThrows(NullPointerException.class, () -> new CarAudioDeviceInfo(audioDeviceInfo)); 54 } 55 56 @Test constructor_requiresJointModeGain()57 public void constructor_requiresJointModeGain() { 58 AudioGain gainWithChannelMode = new GainBuilder().setMode(AudioGain.MODE_CHANNELS).build(); 59 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo( 60 new AudioGain[]{gainWithChannelMode}); 61 62 assertThrows(NullPointerException.class, () -> new CarAudioDeviceInfo(audioDeviceInfo)); 63 } 64 65 @Test constructor_requiresMaxGainLargerThanMin()66 public void constructor_requiresMaxGainLargerThanMin() { 67 AudioGain gainWithChannelMode = new GainBuilder().setMaxValue(10).setMinValue(20).build(); 68 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo( 69 new AudioGain[]{gainWithChannelMode}); 70 71 assertThrows(IllegalArgumentException.class, () -> new CarAudioDeviceInfo(audioDeviceInfo)); 72 } 73 74 @Test constructor_requiresDefaultGainLargerThanMin()75 public void constructor_requiresDefaultGainLargerThanMin() { 76 AudioGain gainWithChannelMode = new GainBuilder().setDefaultValue(10).setMinValue( 77 20).build(); 78 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo( 79 new AudioGain[]{gainWithChannelMode}); 80 81 assertThrows(IllegalArgumentException.class, () -> new CarAudioDeviceInfo(audioDeviceInfo)); 82 } 83 84 @Test constructor_requiresDefaultGainSmallerThanMax()85 public void constructor_requiresDefaultGainSmallerThanMax() { 86 AudioGain gainWithChannelMode = new GainBuilder().setDefaultValue(15).setMaxValue( 87 10).build(); 88 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo( 89 new AudioGain[]{gainWithChannelMode}); 90 91 assertThrows(IllegalArgumentException.class, () -> new CarAudioDeviceInfo(audioDeviceInfo)); 92 } 93 94 @Test constructor_requiresGainStepSizeFactorOfRange()95 public void constructor_requiresGainStepSizeFactorOfRange() { 96 AudioGain gainWithChannelMode = new GainBuilder().setStepSize(7).build(); 97 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo( 98 new AudioGain[]{gainWithChannelMode}); 99 100 assertThrows(IllegalArgumentException.class, () -> new CarAudioDeviceInfo(audioDeviceInfo)); 101 } 102 103 @Test constructor_requiresGainStepSizeFactorOfRangeToDefault()104 public void constructor_requiresGainStepSizeFactorOfRangeToDefault() { 105 AudioGain gainWithChannelMode = new GainBuilder().setStepSize(7).setMaxValue(98).build(); 106 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo( 107 new AudioGain[]{gainWithChannelMode}); 108 109 assertThrows(IllegalArgumentException.class, () -> new CarAudioDeviceInfo(audioDeviceInfo)); 110 } 111 112 @Test getSampleRate_withMultipleSampleRates_returnsMax()113 public void getSampleRate_withMultipleSampleRates_returnsMax() { 114 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 115 int[] sampleRates = new int[]{48000, 96000, 16000, 8000}; 116 when(audioDeviceInfo.getSampleRates()).thenReturn(sampleRates); 117 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 118 119 int sampleRate = info.getSampleRate(); 120 121 assertThat(sampleRate).isEqualTo(96000); 122 } 123 124 @Test getSampleRate_withNullSampleRate_returnsDefault()125 public void getSampleRate_withNullSampleRate_returnsDefault() { 126 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 127 when(audioDeviceInfo.getSampleRates()).thenReturn(null); 128 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 129 130 int sampleRate = info.getSampleRate(); 131 132 assertThat(sampleRate).isEqualTo(CarAudioDeviceInfo.DEFAULT_SAMPLE_RATE); 133 } 134 135 @Test getAudioDevicePort_returnsValueFromDeviceInfo()136 public void getAudioDevicePort_returnsValueFromDeviceInfo() { 137 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 138 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 139 140 assertThat(info.getAudioDevicePort()).isEqualTo(audioDeviceInfo.getPort()); 141 } 142 143 @Test getAddress_returnsValueFromDeviceInfo()144 public void getAddress_returnsValueFromDeviceInfo() { 145 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 146 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 147 148 assertThat(info.getAddress()).isEqualTo(TEST_ADDRESS); 149 } 150 151 @Test getMaxGain_returnsValueFromDeviceInfo()152 public void getMaxGain_returnsValueFromDeviceInfo() { 153 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 154 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 155 156 assertThat(info.getMaxGain()).isEqualTo(MAX_GAIN); 157 } 158 159 @Test getMinGain_returnsValueFromDeviceInfo()160 public void getMinGain_returnsValueFromDeviceInfo() { 161 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 162 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 163 164 assertThat(info.getMinGain()).isEqualTo(MIN_GAIN); 165 } 166 167 @Test getDefaultGain_returnsValueFromDeviceInfo()168 public void getDefaultGain_returnsValueFromDeviceInfo() { 169 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 170 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 171 172 assertThat(info.getDefaultGain()).isEqualTo(DEFAULT_GAIN); 173 } 174 175 @Test getStepValue_returnsValueFromDeviceInfo()176 public void getStepValue_returnsValueFromDeviceInfo() { 177 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 178 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 179 180 assertThat(info.getStepValue()).isEqualTo(STEP_SIZE); 181 } 182 183 @Test getChannelCount_withNoChannelMasks_returnsOne()184 public void getChannelCount_withNoChannelMasks_returnsOne() { 185 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 186 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 187 188 int channelCount = info.getChannelCount(); 189 190 assertThat(channelCount).isEqualTo(1); 191 } 192 193 @Test getChannelCount_withMultipleChannels_returnsHighestCount()194 public void getChannelCount_withMultipleChannels_returnsHighestCount() { 195 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 196 when(audioDeviceInfo.getChannelMasks()).thenReturn(new int[]{CHANNEL_OUT_STEREO, 197 CHANNEL_OUT_QUAD, CHANNEL_OUT_MONO}); 198 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 199 200 int channelCount = info.getChannelCount(); 201 202 assertThat(channelCount).isEqualTo(4); 203 } 204 205 @Test getAudioDeviceInfo_returnsConstructorParameter()206 public void getAudioDeviceInfo_returnsConstructorParameter() { 207 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 208 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 209 210 assertThat(info.getAudioDeviceInfo()).isEqualTo(audioDeviceInfo); 211 } 212 213 @Test getEncodingFormat_returnsPCM16()214 public void getEncodingFormat_returnsPCM16() { 215 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 216 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 217 218 assertThat(info.getEncodingFormat()).isEqualTo(ENCODING_PCM_16BIT); 219 } 220 221 @Test getAudioGain_returnsGainFromDeviceInfo()222 public void getAudioGain_returnsGainFromDeviceInfo() { 223 AudioDeviceInfo audioDeviceInfo = getMockAudioDeviceInfo(); 224 CarAudioDeviceInfo info = new CarAudioDeviceInfo(audioDeviceInfo); 225 AudioGain expectedGain = audioDeviceInfo.getPort().gains()[0]; 226 227 assertThat(info.getAudioGain()).isEqualTo(expectedGain); 228 } 229 getMockAudioDeviceInfo()230 private AudioDeviceInfo getMockAudioDeviceInfo() { 231 AudioGain mockGain = new GainBuilder().build(); 232 return getMockAudioDeviceInfo(new AudioGain[]{mockGain}); 233 } 234 getMockAudioDeviceInfo(AudioGain[] gains)235 private AudioDeviceInfo getMockAudioDeviceInfo(AudioGain[] gains) { 236 AudioDeviceInfo mockInfo = mock(AudioDeviceInfo.class); 237 AudioDevicePort mockPort = mock(AudioDevicePort.class); 238 when(mockInfo.getPort()).thenReturn(mockPort); 239 when(mockPort.gains()).thenReturn(gains); 240 when(mockInfo.getAddress()).thenReturn(TEST_ADDRESS); 241 return mockInfo; 242 } 243 244 private static class GainBuilder { 245 int mMode = AudioGain.MODE_JOINT; 246 int mMaxValue = MAX_GAIN; 247 int mMinValue = MIN_GAIN; 248 int mDefaultValue = DEFAULT_GAIN; 249 int mStepSize = STEP_SIZE; 250 setMode(int mode)251 GainBuilder setMode(int mode) { 252 mMode = mode; 253 return this; 254 } 255 setMaxValue(int maxValue)256 GainBuilder setMaxValue(int maxValue) { 257 mMaxValue = maxValue; 258 return this; 259 } 260 setMinValue(int minValue)261 GainBuilder setMinValue(int minValue) { 262 mMinValue = minValue; 263 return this; 264 } 265 setDefaultValue(int defaultValue)266 GainBuilder setDefaultValue(int defaultValue) { 267 mDefaultValue = defaultValue; 268 return this; 269 } 270 setStepSize(int stepSize)271 GainBuilder setStepSize(int stepSize) { 272 mStepSize = stepSize; 273 return this; 274 } 275 build()276 AudioGain build() { 277 AudioGain mockGain = mock(AudioGain.class); 278 when(mockGain.mode()).thenReturn(mMode); 279 when(mockGain.maxValue()).thenReturn(mMaxValue); 280 when(mockGain.minValue()).thenReturn(mMinValue); 281 when(mockGain.defaultValue()).thenReturn(mDefaultValue); 282 when(mockGain.stepValue()).thenReturn(mStepSize); 283 return mockGain; 284 } 285 } 286 } 287