1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package com.android.mediaframeworktest.functional.audio; 18 19import com.android.mediaframeworktest.MediaFrameworkTest; 20import android.content.Context; 21import android.media.AudioManager; 22import android.media.MediaPlayer; 23import android.media.AudioManager.OnAudioFocusChangeListener; 24import android.os.Looper; 25import android.test.ActivityInstrumentationTestCase2; 26import android.test.suitebuilder.annotation.MediumTest; 27import android.test.suitebuilder.annotation.LargeTest; 28import android.util.Log; 29 30/** 31 * Junit / Instrumentation test case for the media AudioManager api 32 */ 33 34public class MediaAudioManagerTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> { 35 36 private final static String TAG = "MediaAudioManagerTest"; 37 // the AudioManager used throughout the test 38 private AudioManager mAudioManager; 39 // keep track of looper for AudioManager so we can terminate it 40 private Looper mAudioManagerLooper; 41 private final Object mLooperLock = new Object(); 42 private final static int WAIT_FOR_LOOPER_TO_INITIALIZE_MS = 60000; // 60s 43 private int[] ringtoneMode = {AudioManager.RINGER_MODE_NORMAL, 44 AudioManager.RINGER_MODE_SILENT, AudioManager.RINGER_MODE_VIBRATE}; 45 private boolean mUseFixedVolume; 46 47 public MediaAudioManagerTest() { 48 super("com.android.mediaframeworktest", MediaFrameworkTest.class); 49 } 50 51 private void initializeAudioManagerWithLooper() { 52 new Thread() { 53 @Override 54 public void run() { 55 Looper.prepare(); 56 mAudioManagerLooper = Looper.myLooper(); 57 mAudioManager = (AudioManager)getActivity().getSystemService(Context.AUDIO_SERVICE); 58 synchronized (mLooperLock) { 59 mLooperLock.notify(); 60 } 61 Looper.loop(); 62 } 63 }.start(); 64 } 65 66 @Override 67 protected void setUp() throws Exception { 68 super.setUp(); 69 70 mUseFixedVolume = getActivity().getResources().getBoolean( 71 com.android.internal.R.bool.config_useFixedVolume); 72 73 synchronized(mLooperLock) { 74 initializeAudioManagerWithLooper(); 75 try { 76 mLooperLock.wait(WAIT_FOR_LOOPER_TO_INITIALIZE_MS); 77 } catch (Exception e) { 78 assertTrue("initializeAudioManagerWithLooper() failed to complete in time", false); 79 } 80 } 81 } 82 83 @Override 84 protected void tearDown() throws Exception { 85 super.tearDown(); 86 synchronized(mLooperLock) { 87 if (mAudioManagerLooper != null) { 88 mAudioManagerLooper.quit(); 89 } 90 } 91 } 92 93 //----------------------------------------------------------------- 94 // Ringer Mode 95 //---------------------------------- 96 97 public boolean validateSetRingTone(int i) { 98 int getRingtone = mAudioManager.getRingerMode(); 99 100 if (mUseFixedVolume) { 101 return (getRingtone == AudioManager.RINGER_MODE_NORMAL); 102 } else { 103 return (getRingtone == i); 104 } 105 } 106 107 // Test case 1: Simple test case to validate the set ringtone mode 108 @MediumTest 109 public void testSetRingtoneMode() throws Exception { 110 boolean result = false; 111 112 for (int i = 0; i < ringtoneMode.length; i++) { 113 mAudioManager.setRingerMode(ringtoneMode[i]); 114 result = validateSetRingTone(ringtoneMode[i]); 115 assertTrue("SetRingtoneMode : " + ringtoneMode[i], result); 116 } 117 } 118 119 //----------------------------------------------------------------- 120 // AudioFocus 121 //---------------------------------- 122 123 private static AudioFocusListener mAudioFocusListener; 124 private final static int INVALID_FOCUS = -80; // initialized to magic invalid focus change type 125 private final static int WAIT_FOR_AUDIOFOCUS_LOSS_MS = 10; 126 127 private static class AudioFocusListener implements OnAudioFocusChangeListener { 128 public int mLastFocusChange = INVALID_FOCUS; 129 public int mFocusChangeCounter = 0; 130 public AudioFocusListener() { 131 } 132 public void onAudioFocusChange(int focusChange) { 133 mLastFocusChange = focusChange; 134 mFocusChangeCounter++; 135 } 136 } 137 138 /** 139 * Fails the test if expectedFocusLossMode != mAudioFocusListener.mLastFocusChange 140 */ 141 private void verifyAudioFocusLoss(int focusGainMode, int expectedFocusLossMode) 142 throws Exception { 143 // request AudioFocus so we can test that mAudioFocusListener loses it when another 144 // request comes in 145 int result = mAudioManager.requestAudioFocus(mAudioFocusListener, 146 AudioManager.STREAM_MUSIC, 147 AudioManager.AUDIOFOCUS_GAIN); 148 assertTrue("requestAudioFocus returned " + result, 149 result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED); 150 // cause mAudioFocusListener to lose AudioFocus 151 result = mAudioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC, 152 focusGainMode); 153 assertTrue("requestAudioFocus returned " + result, 154 result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED); 155 // the audio focus request is async, so wait a bit to verify it had the expected effect 156 java.lang.Thread.sleep(WAIT_FOR_AUDIOFOCUS_LOSS_MS); 157 // test successful if the expected focus loss was recorded 158 assertEquals("listener lost focus", 159 mAudioFocusListener.mLastFocusChange, expectedFocusLossMode); 160 } 161 162 private void setupAudioFocusListener() { 163 mAudioFocusListener = new AudioFocusListener(); 164 mAudioManager.registerAudioFocusListener(mAudioFocusListener); 165 } 166 167 private void cleanupAudioFocusListener() { 168 // clean up 169 mAudioManager.abandonAudioFocus(mAudioFocusListener); 170 mAudioManager.unregisterAudioFocusListener(mAudioFocusListener); 171 } 172 173 //---------------------------------- 174 175 //Test case 1: test audio focus listener loses audio focus: 176 // AUDIOFOCUS_GAIN causes AUDIOFOCUS_LOSS 177 @MediumTest 178 public void testAudioFocusLoss() throws Exception { 179 setupAudioFocusListener(); 180 181 verifyAudioFocusLoss(AudioManager.AUDIOFOCUS_GAIN, AudioManager.AUDIOFOCUS_LOSS); 182 183 cleanupAudioFocusListener(); 184 } 185 186 //Test case 2: test audio focus listener loses audio focus: 187 // AUDIOFOCUS_GAIN_TRANSIENT causes AUDIOFOCUS_LOSS_TRANSIENT 188 @MediumTest 189 public void testAudioFocusLossTransient() throws Exception { 190 setupAudioFocusListener(); 191 192 verifyAudioFocusLoss(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, 193 AudioManager.AUDIOFOCUS_LOSS_TRANSIENT); 194 195 cleanupAudioFocusListener(); 196 } 197 198 //Test case 3: test audio focus listener loses audio focus: 199 // AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK causes AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK 200 @MediumTest 201 public void testAudioFocusLossTransientDuck() throws Exception { 202 setupAudioFocusListener(); 203 204 verifyAudioFocusLoss(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 205 AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK); 206 207 cleanupAudioFocusListener(); 208 } 209 210 //Test case 4: test audio focus registering and use over 3000 iterations 211 @LargeTest 212 public void testAudioFocusStressListenerRequestAbandon() throws Exception { 213 final int ITERATIONS = 3000; 214 // here we only test the life cycle of a focus listener, and make sure we don't crash 215 // when doing it many times without waiting 216 for (int i = 0 ; i < ITERATIONS ; i++) { 217 setupAudioFocusListener(); 218 int result = mAudioManager.requestAudioFocus(mAudioFocusListener, 219 AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); 220 assertTrue("audio focus request was not granted", 221 result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED); 222 cleanupAudioFocusListener(); 223 } 224 assertTrue("testAudioFocusListenerLifeCycle : tested" + ITERATIONS +" iterations", true); 225 } 226 227 //Test case 5: test audio focus use without listener 228 @LargeTest 229 public void testAudioFocusStressNoListenerRequestAbandon() throws Exception { 230 final int ITERATIONS = 1000; 231 // make sure we have a listener in the stack 232 setupAudioFocusListener(); 233 mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, 234 AudioManager.AUDIOFOCUS_GAIN); 235 // keep making the current owner lose and gain audio focus repeatedly 236 for (int i = 0 ; i < ITERATIONS ; i++) { 237 mAudioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC, 238 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); 239 mAudioManager.abandonAudioFocus(null); 240 // the audio focus request is async, so wait a bit to verify it had the expected effect 241 java.lang.Thread.sleep(WAIT_FOR_AUDIOFOCUS_LOSS_MS); 242 } 243 // verify there were 2 audio focus changes per iteration (one loss + one gain) 244 assertTrue("testAudioFocusListenerLifeCycle : observed " + 245 mAudioFocusListener.mFocusChangeCounter + " AudioFocus changes", 246 mAudioFocusListener.mFocusChangeCounter == ITERATIONS * 2); 247 mAudioManager.abandonAudioFocus(mAudioFocusListener); 248 mAudioManager.unregisterAudioFocusListener(mAudioFocusListener); 249 } 250 } 251