• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertTrue;
25 
26 import android.content.Context;
27 import android.content.pm.PackageManager;
28 import android.media.AudioAttributes;
29 import android.media.AudioManager;
30 import android.media.audiopolicy.AudioProductStrategy;
31 import android.media.audiopolicy.AudioVolumeGroup;
32 
33 import androidx.test.core.app.ActivityScenario;
34 
35 import org.junit.After;
36 import org.junit.Before;
37 import org.junit.rules.ExternalResource;
38 
39 import java.util.HashMap;
40 import java.util.List;
41 import java.util.Map;
42 
43 final class AudioVolumesTestRule extends ExternalResource {
44     private AudioManager mAudioManager;
45     private Context mContext;
46     private Map<Integer, Integer> mOriginalStreamVolumes = new HashMap<>();
47     private Map<Integer, Integer> mOriginalVolumeGroupVolumes = new HashMap<>();
48 
49     /**
50      * <p>Note: must be called with shell permission (MODIFY_AUDIO_ROUTING)
51      */
storeAllVolumes()52     private void storeAllVolumes() {
53         List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups();
54         for (final AudioVolumeGroup avg : audioVolumeGroups) {
55             if (avg.getAudioAttributes().isEmpty()) {
56                 // some volume group may not supports volume control per attributes
57                 // like rerouting/patch since these groups are internal to audio policy manager
58                 continue;
59             }
60             AudioAttributes avgAttributes = DEFAULT_ATTRIBUTES;
61             for (final AudioAttributes aa : avg.getAudioAttributes()) {
62                 if (!aa.equals(AudioProductStrategy.getDefaultAttributes())) {
63                     avgAttributes = aa;
64                     break;
65                 }
66             }
67             if (avgAttributes.equals(DEFAULT_ATTRIBUTES)) {
68                 // This shall not happen, however, not purpose of this base class.
69                 // so bailing out.
70                 continue;
71             }
72             mOriginalVolumeGroupVolumes.put(
73                     avg.getId(), mAudioManager.getVolumeIndexForAttributes(avgAttributes));
74         }
75     }
76 
77     /**
78      * <p>Note: must be called with shell permission (MODIFY_AUDIO_ROUTING)
79      */
restoreAllVolumes()80     private void restoreAllVolumes() {
81         List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups();
82         for (Map.Entry<Integer, Integer> e : mOriginalVolumeGroupVolumes.entrySet()) {
83             for (final AudioVolumeGroup avg : audioVolumeGroups) {
84                 if (avg.getId() == e.getKey()) {
85                     assertTrue(!avg.getAudioAttributes().isEmpty());
86                     AudioAttributes avgAttributes = DEFAULT_ATTRIBUTES;
87                     for (final AudioAttributes aa : avg.getAudioAttributes()) {
88                         if (!aa.equals(AudioProductStrategy.getDefaultAttributes())) {
89                             avgAttributes = aa;
90                             break;
91                         }
92                     }
93                     assertTrue(!avgAttributes.equals(DEFAULT_ATTRIBUTES));
94                     mAudioManager.setVolumeIndexForAttributes(
95                             avgAttributes, e.getValue(), AudioManager.FLAG_ALLOW_RINGER_MODES);
96                 }
97             }
98         }
99     }
100 
101     @Before
setUp()102     public void setUp() throws Exception {
103         ActivityScenario.launch(AudioVolumeTestActivity.class);
104 
105         mContext = getApplicationContext();
106         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
107 
108         assertEquals(PackageManager.PERMISSION_GRANTED,
109                 mContext.checkSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING));
110 
111         // Store the original volumes that that they can be recovered in tearDown().
112         mOriginalStreamVolumes.clear();
113         for (int streamType : AudioManager.getPublicStreamTypes()) {
114             mOriginalStreamVolumes.put(streamType, mAudioManager.getStreamVolume(streamType));
115         }
116         // Store the original volume per attributes so that they can be recovered in tearDown()
117         mOriginalVolumeGroupVolumes.clear();
118         storeAllVolumes();
119     }
120 
121     @After
tearDown()122     public void tearDown() throws Exception {
123         // Recover the volume and the ringer mode that the test may have overwritten.
124         for (Map.Entry<Integer, Integer> e : mOriginalStreamVolumes.entrySet()) {
125             mAudioManager.setStreamVolume(e.getKey(), e.getValue(),
126                                           AudioManager.FLAG_ALLOW_RINGER_MODES);
127         }
128 
129         // Recover the original volume per attributes
130         restoreAllVolumes();
131     }
132 
133 
134 }
135