/* * 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 com.android.mediaframeworktest.MediaNames; import android.content.res.AssetFileDescriptor; import android.media.audiofx.AudioEffect; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioTrack; import android.media.AudioRecord; import android.media.audiofx.EnvironmentalReverb; import android.media.audiofx.Equalizer; import android.media.MediaPlayer; import android.media.MediaRecorder; import android.os.Looper; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.Suppress; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; import java.nio.ByteOrder; import java.nio.ByteBuffer; import java.util.UUID; /** * Junit / Instrumentation test case for the media AudioTrack api */ public class MediaAudioEffectTest extends ActivityInstrumentationTestCase2 { private String TAG = "MediaAudioEffectTest"; private AudioEffect mEffect = null; private boolean mHasControl = false; private boolean mIsEnabled = false; private int mParameterChanged = -1; private MediaPlayer mMediaPlayer = null; private boolean mInitialized = false; private Looper mLooper = null; private int mError = 0; private final Object lock = new Object(); private final static int SAMPLING_RATE = 44100; public MediaAudioEffectTest() { super("com.android.mediaframeworktest", MediaFrameworkTest.class); } @Override protected void setUp() throws Exception { super.setUp(); } @Override protected void tearDown() throws Exception { super.tearDown(); } private static void assumeTrue(String message, boolean cond) { assertTrue("(assume)"+message, cond); } private void log(String testName, String message) { Log.v(TAG, "["+testName+"] "+message); } private void loge(String testName, String message) { Log.e(TAG, "["+testName+"] "+message); } //----------------------------------------------------------------- // AUDIOEFFECT TESTS: //---------------------------------- //----------------------------------------------------------------- // 0 - static methods //---------------------------------- //Test case 0.0: test queryEffects() and available effects @LargeTest public void test0_0QueryEffects() throws Exception { AudioEffect.Descriptor[] desc = AudioEffect.queryEffects(); assertTrue("test0_0QueryEffects: number of effects < 4: "+desc.length, (desc.length >= 4)); boolean hasEQ = false; boolean hasBassBoost = false; boolean hasVirtualizer = false; boolean hasEnvReverb = false; for (int i = 0; i < desc.length; i++) { if (desc[i].type.equals(AudioEffect.EFFECT_TYPE_EQUALIZER)) { hasEQ = true; } if (desc[i].type.equals(AudioEffect.EFFECT_TYPE_BASS_BOOST)) { hasBassBoost = true; } else if (desc[i].type.equals(AudioEffect.EFFECT_TYPE_VIRTUALIZER)) { hasVirtualizer = true; } else if (desc[i].type.equals(AudioEffect.EFFECT_TYPE_ENV_REVERB)) { hasEnvReverb = true; } } assertTrue("test0_0QueryEffects: equalizer not found", hasEQ); assertTrue("test0_0QueryEffects: bass boost not found", hasBassBoost); assertTrue("test0_0QueryEffects: virtualizer not found", hasVirtualizer); assertTrue("test0_0QueryEffects: environmental reverb not found", hasEnvReverb); } //----------------------------------------------------------------- // 1 - constructor //---------------------------------- private AudioRecord getAudioRecord() { AudioRecord ar = null; try { ar = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, SAMPLING_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, AudioRecord.getMinBufferSize(SAMPLING_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT) * 10); assertNotNull("Could not create AudioRecord", ar); assertEquals("AudioRecord not initialized", AudioRecord.STATE_INITIALIZED, ar.getState()); } catch (IllegalArgumentException e) { fail("AudioRecord invalid parameter"); } return ar; } //Test case 1.0: test constructor from effect type and get effect ID @LargeTest public void test1_0ConstructorFromType() throws Exception { boolean result = true; String msg = "test1_0ConstructorFromType()"; AudioEffect.Descriptor[] desc = AudioEffect.queryEffects(); assertTrue(msg+": no effects found", (desc.length != 0)); try { int sessionId; AudioRecord ar = null; if (AudioEffect.EFFECT_PRE_PROCESSING.equals(desc[0].connectMode)) { ar = getAudioRecord(); sessionId = ar.getAudioSessionId(); } else { sessionId = 0; } AudioEffect effect = new AudioEffect(desc[0].type, AudioEffect.EFFECT_TYPE_NULL, 0, sessionId); assertNotNull(msg + ": could not create AudioEffect", effect); try { assertTrue(msg +": invalid effect ID", (effect.getId() != 0)); } catch (IllegalStateException e) { msg = msg.concat(": AudioEffect not initialized"); result = false; } finally { effect.release(); if (ar != null) { ar.release(); } } } catch (IllegalArgumentException e) { msg = msg.concat(": Effect not found: "+desc[0].name); result = false; } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); result = false; } assertTrue(msg, result); } //Test case 1.1: test constructor from effect uuid @LargeTest public void test1_1ConstructorFromUuid() throws Exception { boolean result = true; String msg = "test1_1ConstructorFromUuid()"; AudioEffect.Descriptor[] desc = AudioEffect.queryEffects(); assertTrue(msg+"no effects found", (desc.length != 0)); try { int sessionId; AudioRecord ar = null; if (AudioEffect.EFFECT_PRE_PROCESSING.equals(desc[0].connectMode)) { ar = getAudioRecord(); sessionId = ar.getAudioSessionId(); } else { sessionId = 0; } AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_NULL, desc[0].uuid, 0, sessionId); assertNotNull(msg + ": could not create AudioEffect", effect); effect.release(); if (ar != null) { ar.release(); } } catch (IllegalArgumentException e) { msg = msg.concat(": Effect not found: "+desc[0].name); result = false; } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); result = false; } assertTrue(msg, result); } //Test case 1.2: test constructor failure from unknown type @LargeTest public void test1_2ConstructorUnknownType() throws Exception { boolean result = false; String msg = "test1_2ConstructorUnknownType()"; try { AudioEffect effect = new AudioEffect(UUID.randomUUID(), AudioEffect.EFFECT_TYPE_NULL, 0, 0); msg = msg.concat(": could create random AudioEffect"); if (effect != null) { effect.release(); } } catch (IllegalArgumentException e) { result = true; } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); } assertTrue(msg, result); } //Test case 1.3: test getEnabled() failure when called on released effect @LargeTest public void test1_3GetEnabledAfterRelease() throws Exception { boolean result = false; String msg = "test1_3GetEnabledAfterRelease()"; try { AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); effect.release(); try { effect.getEnabled(); } catch (IllegalStateException e) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Equalizer not found"); } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); } assertTrue(msg, result); } //Test case 1.4: test contructor on mediaPlayer audio session @LargeTest public void test1_4InsertOnMediaPlayer() throws Exception { boolean result = false; String msg = "test1_4InsertOnMediaPlayer()"; try { MediaPlayer mp = new MediaPlayer(); mp.setDataSource(MediaNames.SHORTMP3); AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, mp.getAudioSessionId()); assertNotNull(msg + ": could not create AudioEffect", effect); try { loge(msg, ": effect.setEnabled"); effect.setEnabled(true); } catch (IllegalStateException e) { msg = msg.concat(": AudioEffect not initialized"); } result = true; effect.release(); mp.release(); } catch (IllegalArgumentException e) { msg = msg.concat(": Equalizer not found"); loge(msg, ": Equalizer not found"); } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); loge(msg, ": Effect library not loaded"); } catch (Exception e){ loge(msg, "Could not create media player:" + e); } assertTrue(msg, result); } //Test case 1.5: test auxiliary effect attachement on MediaPlayer @LargeTest public void test1_5AuxiliaryOnMediaPlayer() throws Exception { boolean result = false; String msg = "test1_5AuxiliaryOnMediaPlayer()"; try { MediaPlayer mp = new MediaPlayer(); mp.setDataSource(MediaNames.SHORTMP3); AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); mp.attachAuxEffect(effect.getId()); mp.setAuxEffectSendLevel(1.0f); result = true; effect.release(); mp.release(); } catch (IllegalArgumentException e) { msg = msg.concat(": Equalizer not found"); loge(msg, ": Equalizer not found"); } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); loge(msg, ": Effect library not loaded"); } catch (Exception e){ loge(msg, "Could not create media player:" + e); } assertTrue(msg, result); } //Test case 1.6: test auxiliary effect attachement failure before setDatasource @LargeTest public void test1_6AuxiliaryOnMediaPlayerFailure() throws Exception { boolean result = false; String msg = "test1_6AuxiliaryOnMediaPlayerFailure()"; try { createMediaPlayerLooper(); synchronized(lock) { try { lock.wait(1000); } catch(Exception e) { Log.e(TAG, "Looper creation: wait was interrupted."); } } assertTrue(mInitialized); // mMediaPlayer has been initialized? mError = 0; AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); synchronized(lock) { try { mMediaPlayer.attachAuxEffect(effect.getId()); lock.wait(1000); } catch(Exception e) { Log.e(TAG, "Attach effect: wait was interrupted."); } } assertTrue(msg + ": no error on attachAuxEffect", mError != 0); result = true; effect.release(); terminateMediaPlayerLooper(); } catch (IllegalArgumentException e) { msg = msg.concat(": Equalizer not found"); loge(msg, ": Equalizer not found"); } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); loge(msg, ": Effect library not loaded"); } catch (Exception e){ loge(msg, "Could not create media player:" + e); } assertTrue(msg, result); } //Test case 1.7: test auxiliary effect attachement on AudioTrack @LargeTest public void test1_7AuxiliaryOnAudioTrack() throws Exception { boolean result = false; String msg = "test1_7AuxiliaryOnAudioTrack()"; try { AudioTrack track = new AudioTrack( AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT), AudioTrack.MODE_STREAM); assertNotNull(msg + ": could not create AudioTrack", track); AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, AudioEffect.EFFECT_TYPE_NULL, 0, 0); track.attachAuxEffect(effect.getId()); track.setAuxEffectSendLevel(1.0f); result = true; effect.release(); track.release(); } catch (IllegalArgumentException e) { msg = msg.concat(": Equalizer not found"); loge(msg, ": Equalizer not found"); } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); loge(msg, ": Effect library not loaded"); } assertTrue(msg, result); } //----------------------------------------------------------------- // 2 - enable/ disable //---------------------------------- //Test case 2.0: test setEnabled() and getEnabled() in valid state @LargeTest public void test2_0SetEnabledGetEnabled() throws Exception { boolean result = false; String msg = "test2_0SetEnabledGetEnabled()"; try { AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); try { effect.setEnabled(true); assertTrue(msg + ": invalid state from getEnabled", effect.getEnabled()); effect.setEnabled(false); assertFalse(msg + ": invalid state to getEnabled", effect.getEnabled()); result = true; } catch (IllegalStateException e) { msg = msg.concat(": setEnabled() in wrong state"); } finally { effect.release(); } } catch (IllegalArgumentException e) { msg = msg.concat(": Equalizer not found"); loge(msg, ": Equalizer not found"); } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); loge(msg, ": Effect library not loaded"); } assertTrue(msg, result); } //Test case 2.1: test setEnabled() throws exception after release @LargeTest public void test2_1SetEnabledAfterRelease() throws Exception { boolean result = false; String msg = "test2_1SetEnabledAfterRelease()"; try { AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); effect.release(); try { effect.setEnabled(true); } catch (IllegalStateException e) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Equalizer not found"); loge(msg, ": Equalizer not found"); } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); loge(msg, ": Effect library not loaded"); } assertTrue(msg, result); } //----------------------------------------------------------------- // 3 - set parameters //---------------------------------- //Test case 3.0: test setParameter(byte[], byte[]) @LargeTest public void test3_0SetParameterByteArrayByteArray() throws Exception { boolean result = false; String msg = "test3_0SetParameterByteArrayByteArray()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); byte[] param = intToByteArray(Equalizer.PARAM_CURRENT_PRESET); byte[] value = shortToByteArray((short)0); if (effect.setParameter(param, value) == AudioEffect.SUCCESS) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": setParameter() rejected"); loge(msg, "setParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("setParameter() called in wrong state"); loge(msg, "setParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 3.1: test setParameter(int, int) @LargeTest public void test3_1SetParameterIntInt() throws Exception { boolean result = false; String msg = "test3_1SetParameterIntInt()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); if (effect.setParameter(EnvironmentalReverb.PARAM_DECAY_TIME, 0) == AudioEffect.SUCCESS) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": setParameter() rejected"); loge(msg, "setParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("setParameter() called in wrong state"); loge(msg, "setParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 3.2: test setParameter(int, short) @LargeTest public void test3_2SetParameterIntShort() throws Exception { boolean result = false; String msg = "test3_2SetParameterIntShort()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); if (effect.setParameter(Equalizer.PARAM_CURRENT_PRESET, (short)0) == AudioEffect.SUCCESS) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": setParameter() rejected"); loge(msg, "setParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("setParameter() called in wrong state"); loge(msg, "setParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 3.3: test setParameter(int, byte[]) @LargeTest public void test3_3SetParameterIntByteArray() throws Exception { boolean result = false; String msg = "test3_3SetParameterIntByteArray()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); byte[] value = shortToByteArray((short)0); if (effect.setParameter(Equalizer.PARAM_CURRENT_PRESET, value) == AudioEffect.SUCCESS) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": setParameter() rejected"); loge(msg, "setParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("setParameter() called in wrong state"); loge(msg, "setParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 3.4: test setParameter(int[], int[]) @LargeTest public void test3_4SetParameterIntArrayIntArray() throws Exception { boolean result = false; String msg = "test3_4SetParameterIntArrayIntArray()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); int[] param = new int[1]; int[] value = new int[1]; param[0] = EnvironmentalReverb.PARAM_DECAY_TIME; value[0] = 0; if (effect.setParameter(param, value) == AudioEffect.SUCCESS) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": setParameter() rejected"); loge(msg, "setParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("setParameter() called in wrong state"); loge(msg, "setParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 3.5: test setParameter(int[], short[]) @LargeTest public void test3_5SetParameterIntArrayShortArray() throws Exception { boolean result = false; String msg = "test3_5SetParameterIntArrayShortArray()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); int[] param = new int[1]; short[] value = new short[1]; param[0] = Equalizer.PARAM_CURRENT_PRESET; value[0] = (short)0; if (effect.setParameter(param, value) == AudioEffect.SUCCESS) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": setParameter() rejected"); loge(msg, "setParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("setParameter() called in wrong state"); loge(msg, "setParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 3.6: test setParameter(int[], byte[]) @LargeTest public void test3_6SetParameterIntArrayByteArray() throws Exception { boolean result = false; String msg = "test3_6SetParameterIntArrayByteArray()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); int[] param = new int[1]; byte[] value = shortToByteArray((short)0); param[0] = Equalizer.PARAM_CURRENT_PRESET; if (effect.setParameter(param, value) == AudioEffect.SUCCESS) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": setParameter() rejected"); loge(msg, "setParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("setParameter() called in wrong state"); loge(msg, "setParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 3.7: test setParameter() throws exception after release() @LargeTest public void test3_7SetParameterAfterRelease() throws Exception { boolean result = false; String msg = "test3_7SetParameterAfterRelease()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); effect.release(); effect.setParameter(Equalizer.PARAM_CURRENT_PRESET, (short)0); } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": setParameter() rejected"); loge(msg, "setParameter() rejected"); } catch (IllegalStateException e) { result = true; } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //----------------------------------------------------------------- // 4 - get parameters //---------------------------------- //Test case 4.0: test getParameter(byte[], byte[]) @LargeTest public void test4_0GetParameterByteArrayByteArray() throws Exception { boolean result = false; String msg = "test4_0GetParameterByteArrayByteArray()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); byte[] param = intToByteArray(Equalizer.PARAM_CURRENT_PRESET); byte[] value = new byte[2]; if (!AudioEffect.isError(effect.getParameter(param, value))) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": getParameter() rejected"); loge(msg, "getParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("getParameter() called in wrong state"); loge(msg, "getParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 4.1: test getParameter(int, int[]) @LargeTest public void test4_1GetParameterIntIntArray() throws Exception { boolean result = false; String msg = "test4_1GetParameterIntIntArray()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); int[] value = new int[1]; if (!AudioEffect.isError( effect.getParameter(EnvironmentalReverb.PARAM_DECAY_TIME, value))) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": getParameter() rejected"); loge(msg, "getParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("getParameter() called in wrong state"); loge(msg, "getParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 4.2: test getParameter(int, short[]) @LargeTest public void test4_2GetParameterIntShortArray() throws Exception { boolean result = false; String msg = "test4_2GetParameterIntShortArray()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); short[] value = new short[1]; if (!AudioEffect.isError(effect.getParameter(Equalizer.PARAM_CURRENT_PRESET, value))) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": getParameter() rejected"); loge(msg, "getParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("getParameter() called in wrong state"); loge(msg, "getParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 4.3: test getParameter(int, byte[]) @LargeTest public void test4_3GetParameterIntByteArray() throws Exception { boolean result = false; String msg = "test4_3GetParameterIntByteArray()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); byte[] value = new byte[2]; if (!AudioEffect.isError(effect.getParameter(Equalizer.PARAM_CURRENT_PRESET, value))) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": getParameter() rejected"); loge(msg, "getParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("getParameter() called in wrong state"); loge(msg, "getParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 4.4: test getParameter(int[], int[]) @LargeTest public void test4_4GetParameterIntArrayIntArray() throws Exception { boolean result = false; String msg = "test4_4GetParameterIntArrayIntArray()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); int[] param = new int[1]; int[] value = new int[1]; param[0] = EnvironmentalReverb.PARAM_DECAY_TIME; if (!AudioEffect.isError(effect.getParameter(param, value))) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": getParameter() rejected"); loge(msg, "getParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("getParameter() called in wrong state"); loge(msg, "getParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 4.5: test getParameter(int[], short[]) @LargeTest public void test4_5GetParameterIntArrayShortArray() throws Exception { boolean result = false; String msg = "test4_5GetParameterIntArrayShortArray()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); int[] param = new int[1]; short[] value = new short[1]; param[0] = Equalizer.PARAM_CURRENT_PRESET; if (!AudioEffect.isError(effect.getParameter(param, value))) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": getParameter() rejected"); loge(msg, "getParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("getParameter() called in wrong state"); loge(msg, "getParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 4.6: test getParameter(int[], byte[]) @LargeTest public void test4_6GetParameterIntArrayByteArray() throws Exception { boolean result = false; String msg = "test4_6GetParameterIntArrayByteArray()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); int[] param = new int[1]; byte[] value = new byte[2]; param[0] = Equalizer.PARAM_CURRENT_PRESET; if (!AudioEffect.isError(effect.getParameter(param, value))) { result = true; } } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": getParameter() rejected"); loge(msg, "getParameter() rejected"); } catch (IllegalStateException e) { msg = msg.concat("getParameter() called in wrong state"); loge(msg, "getParameter() called in wrong state"); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //Test case 4.7: test getParameter() throws exception after release() @LargeTest public void test4_7GetParameterAfterRelease() throws Exception { boolean result = false; String msg = "test4_7GetParameterAfterRelease()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); effect.release(); short[] value = new short[1]; effect.getParameter(Equalizer.PARAM_CURRENT_PRESET, value); } catch (IllegalArgumentException e) { msg = msg.concat(": Bad parameter value"); loge(msg, "Bad parameter value"); } catch (UnsupportedOperationException e) { msg = msg.concat(": getParameter() rejected"); loge(msg, "getParameter() rejected"); } catch (IllegalStateException e) { result = true; } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //----------------------------------------------------------------- // 5 priority and listeners //---------------------------------- //Test case 5.0: test control passed to higher priority client @LargeTest public void test5_0setEnabledLowerPriority() throws Exception { boolean result = false; String msg = "test5_0setEnabledLowerPriority()"; AudioEffect effect1 = null; AudioEffect effect2 = null; try { effect1 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 1, 0); assertNotNull(msg + ": could not create AudioEffect", effect1); assertNotNull(msg + ": could not create AudioEffect", effect2); assertTrue(msg + ": Effect2 does not have control", effect2.hasControl()); assertFalse(msg + ": Effect1 has control", effect1.hasControl()); assertTrue(msg + ": Effect1 can enable", effect1.setEnabled(true) == AudioEffect.ERROR_INVALID_OPERATION); assertFalse(msg + ": Effect1 has enabled", effect2.getEnabled()); result = true; } catch (IllegalArgumentException e) { msg = msg.concat(": Effect not found"); result = false; } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); result = false; } finally { if (effect1 != null) { effect1.release(); } if (effect2 != null) { effect2.release(); } } assertTrue(msg, result); } //Test case 5.1: test control passed to higher priority client @LargeTest public void test5_1setParameterLowerPriority() throws Exception { boolean result = false; String msg = "test5_1setParameterLowerPriority()"; AudioEffect effect1 = null; AudioEffect effect2 = null; try { effect1 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 1, 0); assertNotNull(msg + ": could not create AudioEffect", effect1); assertNotNull(msg + ": could not create AudioEffect", effect2); int status = effect2.setParameter(Equalizer.PARAM_CURRENT_PRESET, (short)0); assertEquals(msg + ": Effect2 setParameter failed", AudioEffect.SUCCESS, status); status = effect1.setParameter(Equalizer.PARAM_CURRENT_PRESET, (short)1); assertEquals(msg + ": Effect1 setParameter did not fail", AudioEffect.ERROR_INVALID_OPERATION, status); short[] value = new short[1]; status = effect2.getParameter(Equalizer.PARAM_CURRENT_PRESET, value); assertFalse(msg + ": Effect2 getParameter failed", AudioEffect.isError(status)); assertEquals(msg + ": Effect1 changed parameter", (short)0, value[0]); result = true; } catch (IllegalArgumentException e) { msg = msg.concat(": Effect not found"); result = false; } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); result = false; } finally { if (effect1 != null) { effect1.release(); } if (effect2 != null) { effect2.release(); } } assertTrue(msg, result); } //Test case 5.2: test control status listener @LargeTest public void test5_2ControlStatusListener() throws Exception { boolean result = false; String msg = "test5_2ControlStatusListener()"; mEffect = null; AudioEffect effect2 = null; try { mHasControl = true; createListenerLooper(true, false, false); synchronized(lock) { try { lock.wait(1000); } catch(Exception e) { Log.e(TAG, "Looper creation: wait was interrupted."); } } assertTrue(mInitialized); synchronized(lock) { try { effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 1, 0); assertNotNull(msg + ": could not create AudioEffect", effect2); lock.wait(1000); } catch(Exception e) { Log.e(TAG, "Create second effect: wait was interrupted."); } } assertFalse(msg + ": effect control not lost by effect1", mHasControl); result = true; } catch (IllegalArgumentException e) { msg = msg.concat(": Equalizer not found"); loge(msg, ": Equalizer not found"); } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); loge(msg, ": Effect library not loaded"); } catch (Exception e){ loge(msg, "Could not create media player:" + e); } finally { terminateListenerLooper(); if (effect2 != null) { effect2.release(); } } assertTrue(msg, result); } //Test case 5.3: test enable status listener @LargeTest public void test5_3EnableStatusListener() throws Exception { boolean result = false; String msg = "test5_3EnableStatusListener()"; mEffect = null; AudioEffect effect2 = null; try { createListenerLooper(false, true, false); synchronized(lock) { try { lock.wait(1000); } catch(Exception e) { Log.e(TAG, "Looper creation: wait was interrupted."); } } assertTrue(mInitialized); mEffect.setEnabled(true); mIsEnabled = true; effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 1, 0); assertNotNull(msg + ": could not create AudioEffect", effect2); assertTrue(msg + ": effect not enabled", effect2.getEnabled()); synchronized(lock) { try { effect2.setEnabled(false); lock.wait(1000); } catch(Exception e) { Log.e(TAG, "Create second effect: wait was interrupted."); } } assertFalse(msg + ": enable status not updated", mIsEnabled); result = true; } catch (IllegalArgumentException e) { msg = msg.concat(": Equalizer not found"); loge(msg, ": Equalizer not found"); } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); loge(msg, ": Effect library not loaded"); } catch (Exception e){ loge(msg, "Could not create media player:" + e); } finally { terminateListenerLooper(); if (effect2 != null) { effect2.release(); } } assertTrue(msg, result); } //Test case 5.4: test parameter changed listener @LargeTest public void test5_4ParameterChangedListener() throws Exception { boolean result = false; String msg = "test5_4ParameterChangedListener()"; mEffect = null; AudioEffect effect2 = null; try { createListenerLooper(false, false, true); synchronized(lock) { try { lock.wait(1000); } catch(Exception e) { Log.e(TAG, "Looper creation: wait was interrupted."); } } assertTrue(mInitialized); effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 1, 0); assertNotNull(msg + ": could not create AudioEffect", effect2); synchronized(lock) { try { mParameterChanged = -1; effect2.setParameter(Equalizer.PARAM_CURRENT_PRESET, (short)0); lock.wait(1000); } catch(Exception e) { Log.e(TAG, "Create second effect: wait was interrupted."); } } assertEquals(msg + ": parameter change not received", Equalizer.PARAM_CURRENT_PRESET, mParameterChanged); result = true; } catch (IllegalArgumentException e) { msg = msg.concat(": Equalizer not found"); loge(msg, ": Equalizer not found"); } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); loge(msg, ": Effect library not loaded"); } catch (Exception e){ loge(msg, "Could not create media player:" + e); } finally { terminateListenerLooper(); if (effect2 != null) { effect2.release(); } } assertTrue(msg, result); } //----------------------------------------------------------------- // 6 command method //---------------------------------- //Test case 6.0: test command method @LargeTest public void test6_0Command() throws Exception { boolean result = false; String msg = "test6_0Command()"; AudioEffect effect = null; try { effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull(msg + ": could not create AudioEffect", effect); try { byte[] cmd = new byte[0]; byte[] reply = new byte[4]; int status = effect.command(3, cmd, reply); assertFalse(msg + ": command failed", AudioEffect.isError(status)); assertTrue(msg + ": effect not enabled", effect.getEnabled()); result = true; } catch (IllegalStateException e) { msg = msg.concat(": command in illegal state"); } } catch (IllegalArgumentException e) { msg = msg.concat(": Equalizer not found"); loge(msg, ": Equalizer not found"); } catch (UnsupportedOperationException e) { msg = msg.concat(": Effect library not loaded"); loge(msg, ": Effect library not loaded"); } catch (Exception e){ loge(msg, "Could not create media player:" + e); } finally { if (effect != null) { effect.release(); } } assertTrue(msg, result); } //----------------------------------------------------------------- // private methods //---------------------------------- /* * Initializes the message looper so that the MediaPlayer object can * receive the callback messages. */ private void createMediaPlayerLooper() { new Thread() { @Override public void run() { // Set up a looper to be used by mMediaPlayer. Looper.prepare(); // Save the looper so that we can terminate this thread // after we are done with it. mLooper = Looper.myLooper(); mMediaPlayer = new MediaPlayer(); mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { public boolean onError(MediaPlayer player, int what, int extra) { synchronized(lock) { mError = what; lock.notify(); } return true; } }); mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer player) { synchronized(lock) { lock.notify(); } } }); synchronized(lock) { mInitialized = true; lock.notify(); } Looper.loop(); // Blocks forever until Looper.quit() is called. } }.start(); } /* * Terminates the message looper thread. */ private void terminateMediaPlayerLooper() { if (mLooper != null) { mLooper.quit(); mLooper = null; } if (mMediaPlayer != null) { mMediaPlayer.release(); } } /* * Initializes the message looper fro effect listener */ class ListenerThread extends Thread { boolean mControl; boolean mEnable; boolean mParameter; public ListenerThread(boolean control, boolean enable, boolean parameter) { super(); mControl = control; mEnable = enable; mParameter = parameter; } } private void createListenerLooper(boolean control, boolean enable, boolean parameter) { new ListenerThread(control, enable, parameter) { @Override public void run() { // Set up a looper to be used by mEffect. Looper.prepare(); // Save the looper so that we can terminate this thread // after we are done with it. mLooper = Looper.myLooper(); mEffect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, AudioEffect.EFFECT_TYPE_NULL, 0, 0); assertNotNull("could not create AudioEffect", mEffect); if (mControl) { mEffect.setControlStatusListener(new AudioEffect.OnControlStatusChangeListener() { public void onControlStatusChange(AudioEffect effect, boolean controlGranted) { synchronized(lock) { if (effect == mEffect) { mHasControl = controlGranted; lock.notify(); } } } }); } if (mEnable) { mEffect.setEnableStatusListener(new AudioEffect.OnEnableStatusChangeListener() { public void onEnableStatusChange(AudioEffect effect, boolean enabled) { synchronized(lock) { if (effect == mEffect) { mIsEnabled = enabled; lock.notify(); } } } }); } if (mParameter) { mEffect.setParameterListener(new AudioEffect.OnParameterChangeListener() { public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) { synchronized(lock) { if (effect == mEffect) { mParameterChanged = byteArrayToInt(param); lock.notify(); } } } }); } synchronized(lock) { mInitialized = true; lock.notify(); } Looper.loop(); // Blocks forever until Looper.quit() is called. } }.start(); } /* * Terminates the listener looper thread. */ private void terminateListenerLooper() { if (mEffect != null) { mEffect.release(); mEffect = null; } if (mLooper != null) { mLooper.quit(); mLooper = null; } } protected int byteArrayToInt(byte[] valueBuf) { return byteArrayToInt(valueBuf, 0); } protected int byteArrayToInt(byte[] valueBuf, int offset) { ByteBuffer converter = ByteBuffer.wrap(valueBuf); converter.order(ByteOrder.nativeOrder()); return converter.getInt(offset); } protected byte[] intToByteArray(int value) { ByteBuffer converter = ByteBuffer.allocate(4); converter.order(ByteOrder.nativeOrder()); converter.putInt(value); return converter.array(); } protected short byteArrayToShort(byte[] valueBuf) { return byteArrayToShort(valueBuf, 0); } protected short byteArrayToShort(byte[] valueBuf, int offset) { ByteBuffer converter = ByteBuffer.wrap(valueBuf); converter.order(ByteOrder.nativeOrder()); return converter.getShort(offset); } protected byte[] shortToByteArray(short value) { ByteBuffer converter = ByteBuffer.allocate(2); converter.order(ByteOrder.nativeOrder()); short sValue = (short) value; converter.putShort(sValue); return converter.array(); } }