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