• 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 android.content.Context;
20 import android.content.pm.PackageManager;
21 import android.media.AudioAttributes;
22 import android.media.AudioManager;
23 import android.media.audiopolicy.AudioProductStrategy;
24 import android.media.audiopolicy.AudioVolumeGroup;
25 import android.test.ActivityInstrumentationTestCase2;
26 
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 
31 public class AudioVolumesTestBase extends ActivityInstrumentationTestCase2<AudioPolicyTest> {
32     public AudioManager mAudioManager;
33     Context mContext;
34     private Map<Integer, Integer> mOriginalStreamVolumes = new HashMap<>();
35     private Map<Integer, Integer> mOriginalVolumeGroupVolumes = new HashMap<>();
36 
37     // Default matches the invalid (empty) attributes from native.
38     // The difference is the input source default which is not aligned between native and java
39     public static final AudioAttributes sDefaultAttributes =
40             AudioProductStrategy.getDefaultAttributes();
41 
42     public static final AudioAttributes sInvalidAttributes = new AudioAttributes.Builder().build();
43 
AudioVolumesTestBase()44     public AudioVolumesTestBase() {
45         super("com.android.audiopolicytest", AudioPolicyTest.class);
46     }
47 
48     /**
49      * <p>Note: must be called with shell permission (MODIFY_AUDIO_ROUTING)
50      */
storeAllVolumes()51     private void storeAllVolumes() {
52         List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups();
53         for (final AudioVolumeGroup avg : audioVolumeGroups) {
54             if (avg.getAudioAttributes().isEmpty()) {
55                 // some volume group may not supports volume control per attributes
56                 // like rerouting/patch since these groups are internal to audio policy manager
57                 continue;
58             }
59             AudioAttributes avgAttributes = sDefaultAttributes;
60             for (final AudioAttributes aa : avg.getAudioAttributes()) {
61                 if (!aa.equals(AudioProductStrategy.getDefaultAttributes())) {
62                     avgAttributes = aa;
63                     break;
64                 }
65             }
66             if (avgAttributes.equals(sDefaultAttributes)) {
67                 // This shall not happen, however, not purpose of this base class.
68                 // so bailing out.
69                 continue;
70             }
71             mOriginalVolumeGroupVolumes.put(
72                     avg.getId(), mAudioManager.getVolumeIndexForAttributes(avgAttributes));
73         }
74     }
75 
76     /**
77      * <p>Note: must be called with shell permission (MODIFY_AUDIO_ROUTING)
78      */
restoreAllVolumes()79     private void restoreAllVolumes() {
80         List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups();
81         for (Map.Entry<Integer, Integer> e : mOriginalVolumeGroupVolumes.entrySet()) {
82             for (final AudioVolumeGroup avg : audioVolumeGroups) {
83                 if (avg.getId() == e.getKey()) {
84                     assertTrue(!avg.getAudioAttributes().isEmpty());
85                     AudioAttributes avgAttributes = sDefaultAttributes;
86                     for (final AudioAttributes aa : avg.getAudioAttributes()) {
87                         if (!aa.equals(AudioProductStrategy.getDefaultAttributes())) {
88                             avgAttributes = aa;
89                             break;
90                         }
91                     }
92                     assertTrue(!avgAttributes.equals(sDefaultAttributes));
93                     mAudioManager.setVolumeIndexForAttributes(
94                             avgAttributes, e.getValue(), AudioManager.FLAG_ALLOW_RINGER_MODES);
95                 }
96             }
97         }
98     }
99 
100     @Override
setUp()101     protected void setUp() throws Exception {
102         super.setUp();
103 
104         mContext = getActivity();
105         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
106 
107         assertEquals(PackageManager.PERMISSION_GRANTED,
108                 mContext.checkSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING));
109 
110         // Store the original volumes that that they can be recovered in tearDown().
111         mOriginalStreamVolumes.clear();
112         for (int streamType : AudioManager.getPublicStreamTypes()) {
113             mOriginalStreamVolumes.put(streamType, mAudioManager.getStreamVolume(streamType));
114         }
115         // Store the original volume per attributes so that they can be recovered in tearDown()
116         mOriginalVolumeGroupVolumes.clear();
117         storeAllVolumes();
118     }
119 
120     @Override
tearDown()121     protected void tearDown() throws Exception {
122         super.tearDown();
123 
124         // Recover the volume and the ringer mode that the test may have overwritten.
125         for (Map.Entry<Integer, Integer> e : mOriginalStreamVolumes.entrySet()) {
126             mAudioManager.setStreamVolume(e.getKey(), e.getValue(),
127                                           AudioManager.FLAG_ALLOW_RINGER_MODES);
128         }
129 
130         // Recover the original volume per attributes
131         restoreAllVolumes();
132     }
133 
resetVolumeIndex(int indexMin, int indexMax)134     public static int resetVolumeIndex(int indexMin, int indexMax) {
135         return (indexMax + indexMin) / 2;
136     }
137 
incrementVolumeIndex(int index, int indexMin, int indexMax)138     public static int incrementVolumeIndex(int index, int indexMin, int indexMax) {
139         return (index + 1 > indexMax) ? resetVolumeIndex(indexMin, indexMax) : ++index;
140     }
141 }
142