1 /* 2 * Copyright (C) 2020 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.audiopolicytest; 18 19 import static androidx.test.core.app.ApplicationProvider.getApplicationContext; 20 21 import static com.android.audiopolicytest.AudioVolumeTestUtil.DEFAULT_ATTRIBUTES; 22 import static com.android.audiopolicytest.AudioVolumeTestUtil.incrementVolumeIndex; 23 24 import static org.junit.Assert.assertEquals; 25 import static org.junit.Assert.assertThrows; 26 import static org.junit.Assert.assertTrue; 27 28 import android.media.AudioAttributes; 29 import android.media.AudioManager; 30 import android.media.audiopolicy.AudioVolumeGroup; 31 import android.media.audiopolicy.AudioVolumeGroupChangeHandler; 32 import android.platform.test.annotations.Presubmit; 33 34 import androidx.test.ext.junit.runners.AndroidJUnit4; 35 36 import org.junit.Before; 37 import org.junit.Rule; 38 import org.junit.Test; 39 import org.junit.runner.RunWith; 40 41 import java.util.ArrayList; 42 import java.util.List; 43 44 @Presubmit 45 @RunWith(AndroidJUnit4.class) 46 public class AudioVolumeGroupChangeHandlerTest { 47 private static final String TAG = "AudioVolumeGroupChangeHandlerTest"; 48 49 @Rule 50 public final AudioVolumesTestRule rule = new AudioVolumesTestRule(); 51 52 private AudioManager mAudioManager; 53 54 @Before setUp()55 public void setUp() { 56 mAudioManager = getApplicationContext().getSystemService(AudioManager.class); 57 } 58 59 @Test testRegisterInvalidCallback()60 public void testRegisterInvalidCallback() { 61 final AudioVolumeGroupChangeHandler audioAudioVolumeGroupChangedHandler = 62 new AudioVolumeGroupChangeHandler(); 63 64 audioAudioVolumeGroupChangedHandler.init(); 65 66 assertThrows(NullPointerException.class, () -> { 67 AudioManager.VolumeGroupCallback nullCb = null; 68 audioAudioVolumeGroupChangedHandler.registerListener(nullCb); 69 }); 70 } 71 72 @Test testUnregisterInvalidCallback()73 public void testUnregisterInvalidCallback() { 74 final AudioVolumeGroupChangeHandler audioAudioVolumeGroupChangedHandler = 75 new AudioVolumeGroupChangeHandler(); 76 77 audioAudioVolumeGroupChangedHandler.init(); 78 79 final AudioVolumeGroupCallbackHelper cb = new AudioVolumeGroupCallbackHelper(); 80 audioAudioVolumeGroupChangedHandler.registerListener(cb); 81 82 assertThrows(NullPointerException.class, () -> { 83 AudioManager.VolumeGroupCallback nullCb = null; 84 audioAudioVolumeGroupChangedHandler.unregisterListener(nullCb); 85 }); 86 audioAudioVolumeGroupChangedHandler.unregisterListener(cb); 87 } 88 89 @Test testRegisterUnregisterCallback()90 public void testRegisterUnregisterCallback() { 91 final AudioVolumeGroupChangeHandler audioAudioVolumeGroupChangedHandler = 92 new AudioVolumeGroupChangeHandler(); 93 94 audioAudioVolumeGroupChangedHandler.init(); 95 final AudioVolumeGroupCallbackHelper validCb = new AudioVolumeGroupCallbackHelper(); 96 97 // Should not assert, otherwise test will fail 98 audioAudioVolumeGroupChangedHandler.registerListener(validCb); 99 100 // Should not assert, otherwise test will fail 101 audioAudioVolumeGroupChangedHandler.unregisterListener(validCb); 102 } 103 104 @Test testCallbackReceived()105 public void testCallbackReceived() { 106 final AudioVolumeGroupChangeHandler audioAudioVolumeGroupChangedHandler = 107 new AudioVolumeGroupChangeHandler(); 108 109 audioAudioVolumeGroupChangedHandler.init(); 110 111 final AudioVolumeGroupCallbackHelper validCb = new AudioVolumeGroupCallbackHelper(); 112 audioAudioVolumeGroupChangedHandler.registerListener(validCb); 113 114 List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups(); 115 assertTrue(audioVolumeGroups.size() > 0); 116 117 try { 118 for (final AudioVolumeGroup audioVolumeGroup : audioVolumeGroups) { 119 int volumeGroupId = audioVolumeGroup.getId(); 120 121 List<AudioAttributes> avgAttributes = audioVolumeGroup.getAudioAttributes(); 122 // Set the volume per attributes (if valid) and wait the callback 123 if (avgAttributes.size() == 0 || avgAttributes.get(0).equals(DEFAULT_ATTRIBUTES)) { 124 // Some volume groups may not have valid attributes, used for internal 125 // volume management like patch/rerouting 126 // so bailing out strategy retrieval from attributes 127 continue; 128 } 129 final AudioAttributes aa = avgAttributes.get(0); 130 131 int index = mAudioManager.getVolumeIndexForAttributes(aa); 132 int indexMax = mAudioManager.getMaxVolumeIndexForAttributes(aa); 133 int indexMin = mAudioManager.getMinVolumeIndexForAttributes(aa); 134 135 final int indexForAa = incrementVolumeIndex(index, indexMin, indexMax); 136 137 // Set the receiver to filter only the current group callback 138 validCb.setExpectedVolumeGroup(volumeGroupId); 139 mAudioManager.setVolumeIndexForAttributes(aa, indexForAa, 0/*flags*/); 140 assertTrue(validCb.waitForExpectedVolumeGroupChanged( 141 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 142 143 final int readIndex = mAudioManager.getVolumeIndexForAttributes(aa); 144 assertEquals(readIndex, indexForAa); 145 } 146 } finally { 147 audioAudioVolumeGroupChangedHandler.unregisterListener(validCb); 148 } 149 } 150 151 @Test testMultipleCallbackReceived()152 public void testMultipleCallbackReceived() { 153 154 final AudioVolumeGroupChangeHandler audioAudioVolumeGroupChangedHandler = 155 new AudioVolumeGroupChangeHandler(); 156 157 audioAudioVolumeGroupChangedHandler.init(); 158 159 final int callbackCount = 10; 160 final List<AudioVolumeGroupCallbackHelper> validCbs = 161 new ArrayList<AudioVolumeGroupCallbackHelper>(); 162 for (int i = 0; i < callbackCount; i++) { 163 validCbs.add(new AudioVolumeGroupCallbackHelper()); 164 } 165 for (final AudioVolumeGroupCallbackHelper cb : validCbs) { 166 audioAudioVolumeGroupChangedHandler.registerListener(cb); 167 } 168 169 List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups(); 170 assertTrue(audioVolumeGroups.size() > 0); 171 172 try { 173 for (final AudioVolumeGroup audioVolumeGroup : audioVolumeGroups) { 174 int volumeGroupId = audioVolumeGroup.getId(); 175 176 List<AudioAttributes> avgAttributes = audioVolumeGroup.getAudioAttributes(); 177 // Set the volume per attributes (if valid) and wait the callback 178 if (avgAttributes.size() == 0 || avgAttributes.get(0).equals(DEFAULT_ATTRIBUTES)) { 179 // Some volume groups may not have valid attributes, used for internal 180 // volume management like patch/rerouting 181 // so bailing out strategy retrieval from attributes 182 continue; 183 } 184 AudioAttributes aa = avgAttributes.get(0); 185 186 int index = mAudioManager.getVolumeIndexForAttributes(aa); 187 int indexMax = mAudioManager.getMaxVolumeIndexForAttributes(aa); 188 int indexMin = mAudioManager.getMinVolumeIndexForAttributes(aa); 189 190 final int indexForAa = incrementVolumeIndex(index, indexMin, indexMax); 191 192 // Set the receiver to filter only the current group callback 193 for (final AudioVolumeGroupCallbackHelper cb : validCbs) { 194 cb.setExpectedVolumeGroup(volumeGroupId); 195 } 196 mAudioManager.setVolumeIndexForAttributes(aa, indexForAa, 0/*flags*/); 197 198 for (final AudioVolumeGroupCallbackHelper cb : validCbs) { 199 assertTrue(cb.waitForExpectedVolumeGroupChanged( 200 AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); 201 } 202 int readIndex = mAudioManager.getVolumeIndexForAttributes(aa); 203 assertEquals(readIndex, indexForAa); 204 } 205 } finally { 206 for (final AudioVolumeGroupCallbackHelper cb : validCbs) { 207 audioAudioVolumeGroupChangedHandler.unregisterListener(cb); 208 } 209 } 210 } 211 } 212