/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.android.mediaframeworktest.functional.audio;
import com.android.mediaframeworktest.MediaFrameworkTest;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.os.Looper;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
/**
* Junit / Instrumentation test case for the media AudioManager api
*/
public class MediaAudioManagerTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
private final static String TAG = "MediaAudioManagerTest";
// the AudioManager used throughout the test
private AudioManager mAudioManager;
// keep track of looper for AudioManager so we can terminate it
private Looper mAudioManagerLooper;
private final Object mLooperLock = new Object();
private final static int WAIT_FOR_LOOPER_TO_INITIALIZE_MS = 60000; // 60s
private int[] ringtoneMode = {AudioManager.RINGER_MODE_NORMAL,
AudioManager.RINGER_MODE_SILENT, AudioManager.RINGER_MODE_VIBRATE};
private boolean mUseFixedVolume;
public MediaAudioManagerTest() {
super("com.android.mediaframeworktest", MediaFrameworkTest.class);
}
private void initializeAudioManagerWithLooper() {
new Thread() {
@Override
public void run() {
Looper.prepare();
mAudioManagerLooper = Looper.myLooper();
mAudioManager = (AudioManager)getActivity().getSystemService(Context.AUDIO_SERVICE);
synchronized (mLooperLock) {
mLooperLock.notify();
}
Looper.loop();
}
}.start();
}
@Override
protected void setUp() throws Exception {
super.setUp();
mUseFixedVolume = getActivity().getResources().getBoolean(
com.android.internal.R.bool.config_useFixedVolume);
synchronized(mLooperLock) {
initializeAudioManagerWithLooper();
try {
mLooperLock.wait(WAIT_FOR_LOOPER_TO_INITIALIZE_MS);
} catch (Exception e) {
assertTrue("initializeAudioManagerWithLooper() failed to complete in time", false);
}
}
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
synchronized(mLooperLock) {
if (mAudioManagerLooper != null) {
mAudioManagerLooper.quit();
}
}
}
//-----------------------------------------------------------------
// Ringer Mode
//----------------------------------
public boolean validateSetRingTone(int i) {
int getRingtone = mAudioManager.getRingerMode();
if (mUseFixedVolume) {
return (getRingtone == AudioManager.RINGER_MODE_NORMAL);
} else {
return (getRingtone == i);
}
}
// Test case 1: Simple test case to validate the set ringtone mode
@MediumTest
public void testSetRingtoneMode() throws Exception {
boolean result = false;
for (int i = 0; i < ringtoneMode.length; i++) {
mAudioManager.setRingerMode(ringtoneMode[i]);
result = validateSetRingTone(ringtoneMode[i]);
assertTrue("SetRingtoneMode : " + ringtoneMode[i], result);
}
}
//-----------------------------------------------------------------
// AudioFocus
//----------------------------------
private static AudioFocusListener mAudioFocusListener;
private final static int INVALID_FOCUS = -80; // initialized to magic invalid focus change type
private final static int WAIT_FOR_AUDIOFOCUS_LOSS_MS = 10;
private static class AudioFocusListener implements OnAudioFocusChangeListener {
public int mLastFocusChange = INVALID_FOCUS;
public int mFocusChangeCounter = 0;
public AudioFocusListener() {
}
public void onAudioFocusChange(int focusChange) {
mLastFocusChange = focusChange;
mFocusChangeCounter++;
}
}
/**
* Fails the test if expectedFocusLossMode != mAudioFocusListener.mLastFocusChange
*/
private void verifyAudioFocusLoss(int focusGainMode, int expectedFocusLossMode)
throws Exception {
// request AudioFocus so we can test that mAudioFocusListener loses it when another
// request comes in
int result = mAudioManager.requestAudioFocus(mAudioFocusListener,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
assertTrue("requestAudioFocus returned " + result,
result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
// cause mAudioFocusListener to lose AudioFocus
result = mAudioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC,
focusGainMode);
assertTrue("requestAudioFocus returned " + result,
result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
// the audio focus request is async, so wait a bit to verify it had the expected effect
java.lang.Thread.sleep(WAIT_FOR_AUDIOFOCUS_LOSS_MS);
// test successful if the expected focus loss was recorded
assertEquals("listener lost focus",
mAudioFocusListener.mLastFocusChange, expectedFocusLossMode);
}
private void setupAudioFocusListener() {
mAudioFocusListener = new AudioFocusListener();
mAudioManager.registerAudioFocusListener(mAudioFocusListener);
}
private void cleanupAudioFocusListener() {
// clean up
mAudioManager.abandonAudioFocus(mAudioFocusListener);
mAudioManager.unregisterAudioFocusListener(mAudioFocusListener);
}
//----------------------------------
//Test case 1: test audio focus listener loses audio focus:
// AUDIOFOCUS_GAIN causes AUDIOFOCUS_LOSS
@MediumTest
public void testAudioFocusLoss() throws Exception {
setupAudioFocusListener();
verifyAudioFocusLoss(AudioManager.AUDIOFOCUS_GAIN, AudioManager.AUDIOFOCUS_LOSS);
cleanupAudioFocusListener();
}
//Test case 2: test audio focus listener loses audio focus:
// AUDIOFOCUS_GAIN_TRANSIENT causes AUDIOFOCUS_LOSS_TRANSIENT
@MediumTest
public void testAudioFocusLossTransient() throws Exception {
setupAudioFocusListener();
verifyAudioFocusLoss(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT);
cleanupAudioFocusListener();
}
//Test case 3: test audio focus listener loses audio focus:
// AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK causes AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
@MediumTest
public void testAudioFocusLossTransientDuck() throws Exception {
setupAudioFocusListener();
verifyAudioFocusLoss(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK);
cleanupAudioFocusListener();
}
//Test case 4: test audio focus registering and use over 3000 iterations
@LargeTest
public void testAudioFocusStressListenerRequestAbandon() throws Exception {
final int ITERATIONS = 3000;
// here we only test the life cycle of a focus listener, and make sure we don't crash
// when doing it many times without waiting
for (int i = 0 ; i < ITERATIONS ; i++) {
setupAudioFocusListener();
int result = mAudioManager.requestAudioFocus(mAudioFocusListener,
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
assertTrue("audio focus request was not granted",
result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
cleanupAudioFocusListener();
}
assertTrue("testAudioFocusListenerLifeCycle : tested" + ITERATIONS +" iterations", true);
}
//Test case 5: test audio focus use without listener
@LargeTest
public void testAudioFocusStressNoListenerRequestAbandon() throws Exception {
final int ITERATIONS = 1000;
// make sure we have a listener in the stack
setupAudioFocusListener();
mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
// keep making the current owner lose and gain audio focus repeatedly
for (int i = 0 ; i < ITERATIONS ; i++) {
mAudioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
mAudioManager.abandonAudioFocus(null);
// the audio focus request is async, so wait a bit to verify it had the expected effect
java.lang.Thread.sleep(WAIT_FOR_AUDIOFOCUS_LOSS_MS);
}
// verify there were 2 audio focus changes per iteration (one loss + one gain)
assertTrue("testAudioFocusListenerLifeCycle : observed " +
mAudioFocusListener.mFocusChangeCounter + " AudioFocus changes",
mAudioFocusListener.mFocusChangeCounter == ITERATIONS * 2);
mAudioManager.abandonAudioFocus(mAudioFocusListener);
mAudioManager.unregisterAudioFocusListener(mAudioFocusListener);
}
}