• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.media.audio.cts;
18 
19 import android.content.pm.PackageManager;
20 import android.media.AudioManager;
21 import android.os.SystemClock;
22 import android.platform.test.annotations.AppModeFull;
23 import android.util.Log;
24 
25 import androidx.test.filters.SdkSuppress;
26 
27 import com.android.compatibility.common.util.CtsAndroidTestCase;
28 import com.android.internal.annotations.GuardedBy;
29 
30 import java.util.concurrent.Executors;
31 
32 
33 
34 @SdkSuppress(minSdkVersion = 31, codeName = "S")
35 public class AudioModeListenerTest extends CtsAndroidTestCase {
36     private final static String TAG = "AudioModeListenerTest";
37 
38     private AudioManager mAudioManager;
39 
40     @Override
setUp()41     protected void setUp() throws Exception {
42         super.setUp();
43         mAudioManager = getInstrumentation().getContext().getSystemService(AudioManager.class);
44     }
45 
46     static class MyOnModeChangedListener implements AudioManager.OnModeChangedListener {
47 
48         private final Object mCbLock = new Object();
49         @GuardedBy("mCbLock")
50         private boolean mCalled;
51         @GuardedBy("mCbLock")
52         private int mMode;
53 
54         private static final int LISTENER_WAIT_TIMEOUT_MS = 3000;
reset()55         void reset() {
56             synchronized (mCbLock) {
57                 mCalled = false;
58                 mMode = -1977; // magic value that doesn't match any mode
59             }
60         }
61 
wasCalled()62         boolean wasCalled() {
63             synchronized (mCbLock) {
64                 return mCalled;
65             }
66         }
67 
waitForModeUpdate()68         int waitForModeUpdate() {
69             synchronized (mCbLock) {
70                 long endTimeMillis = SystemClock.uptimeMillis() + LISTENER_WAIT_TIMEOUT_MS;
71                 long waiTimeMillis = endTimeMillis - SystemClock.uptimeMillis();
72                 while (!mCalled && waiTimeMillis > 0) {
73                     try {
74                         mCbLock.wait(waiTimeMillis);
75                     } catch (InterruptedException e) {
76                     }
77                     waiTimeMillis = endTimeMillis - SystemClock.uptimeMillis();
78                 }
79                 return mMode;
80             }
81         }
82 
getMode()83         int getMode() {
84             synchronized (mCbLock) {
85                 return mMode;
86             }
87         }
88 
MyOnModeChangedListener()89         MyOnModeChangedListener() {
90             reset();
91         }
92 
93         @Override
onModeChanged(int mode)94         public void onModeChanged(int mode) {
95             synchronized (mCbLock) {
96                 mCalled = true;
97                 mMode = mode;
98                 mCbLock.notifyAll();
99             }
100         }
101     }
102 
103     @AppModeFull(reason = "Instant apps don't have MODIFY_AUDIO_SETTINGS")
testModeListener()104     public void testModeListener() throws Exception {
105         if (!isValidPlatform("testModeListener")) return;
106 
107         MyOnModeChangedListener listener = new MyOnModeChangedListener();
108 
109         try {
110             mAudioManager.addOnModeChangedListener(null, listener);
111             fail("addOnModeChangedListener should fail with null executor");
112         } catch (Exception e) {
113         }
114 
115         try {
116             mAudioManager.addOnModeChangedListener(
117                     Executors.newSingleThreadExecutor(), null);
118             fail("addOnModeChangedListener should fail with null listener");
119         } catch (Exception e) {
120         }
121 
122         try {
123             mAudioManager.removeOnModeChangedListener(null);
124             fail("removeOnModeChangedListener should fail with null listener");
125         } catch (Exception e) {
126         }
127 
128         try {
129             mAudioManager.addOnModeChangedListener(
130                 Executors.newSingleThreadExecutor(), listener);
131         } catch (Exception e) {
132             fail("addOnModeChangedListener failed with exception: " + e);
133         }
134 
135         try {
136             mAudioManager.addOnModeChangedListener(
137                 Executors.newSingleThreadExecutor(), listener);
138             fail("addOnCommunicationDeviceChangedListener succeeded for same listener");
139         } catch (Exception e) {
140         }
141 
142         int originalMode = mAudioManager.getMode();
143         int testMode = (originalMode == AudioManager.MODE_NORMAL)
144                 ? AudioManager.MODE_RINGTONE : AudioManager.MODE_NORMAL;
145 
146         mAudioManager.setMode(testMode);
147         int dispatchedMode = listener.waitForModeUpdate();
148         assertTrue("listener wasn't called", listener.wasCalled());
149         assertEquals("Mode not updated correctly", testMode, dispatchedMode);
150 
151         listener.reset();
152 
153         if (originalMode == AudioManager.MODE_NORMAL) {
154             mAudioManager.setMode(originalMode);
155 
156             dispatchedMode = listener.waitForModeUpdate();
157             assertTrue("listener wasn't called for mode restore", listener.wasCalled());
158             assertEquals("Mode not updated correctly for mode restore",
159                     originalMode, dispatchedMode);
160         }
161 
162         try {
163             mAudioManager.removeOnModeChangedListener(listener);
164         } catch (Exception e) {
165             fail("removeOnModeChangedListener failed with exception: " + e);
166         }
167     }
168 
isValidPlatform(String testName)169     private boolean isValidPlatform(String testName) {
170         PackageManager pm = getInstrumentation().getContext().getPackageManager();
171         if (!pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)
172                 ||  pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)
173                 || !pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
174             Log.i(TAG,"Skipping test " + testName
175                     + " : device has no audio output or is a TV or does not support telephony");
176             return false;
177         }
178         return true;
179     }
180 }
181