Merge "Added tests for audio effects." into gingerbread
diff --git a/tests/tests/media/src/android/media/cts/AudioEffectTest.java b/tests/tests/media/src/android/media/cts/AudioEffectTest.java
new file mode 100644
index 0000000..3d458c4
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioEffectTest.java
@@ -0,0 +1,1379 @@
+/*
+ * 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 android.media.cts;
+
+import com.android.cts.stub.R;
+
+import android.content.res.AssetFileDescriptor;
+import android.media.AudioEffect;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.media.PresetReverb;
+import android.media.EnvironmentalReverb;
+import android.media.Equalizer;
+import android.media.MediaPlayer;
+
+import android.os.Looper;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+import java.util.UUID;
+
+@TestTargetClass(AudioEffect.class)
+public class AudioEffectTest extends AndroidTestCase {
+
+ private String TAG = "AudioEffectTest";
+ private final static int MIN_NUMBER_EFFECTS = 5;
+ // allow +/- 5% tolerance between set and get delays
+ private final static float DELAY_TOLERANCE = 1.05f;
+ // allow +/- 5% tolerance between set and get ratios
+ private final static float RATIO_TOLERANCE = 1.05f;
+
+ private AudioEffect mEffect = null;
+ private AudioEffect mEffect2 = null;
+ private int mSession = -1;
+ private boolean mHasControl = false;
+ private boolean mIsEnabled = false;
+ private int mChangedParameter = -1;
+ private boolean mInitialized = false;
+ private Looper mLooper = null;
+ private MediaPlayer mMediaPlayer = null;
+ private int mError = 0;
+
+ private final Object mLock = new Object();
+
+
+ //-----------------------------------------------------------------
+ // AUDIOEFFECT TESTS:
+ //----------------------------------
+
+ //-----------------------------------------------------------------
+ // 0 - static methods
+ //----------------------------------
+
+ //Test case 0.0: test queryEffects() and platfrom at least provides Equalizer, Bass Boost,
+ // Virtualizer, Environmental reverb and Preset reverb effects
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "queryEffects",
+ args = {}
+ )
+ })
+ public void test0_0QueryEffects() throws Exception {
+
+ AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();
+
+ assertTrue("test0_0QueryEffects: number of effects < MIN_NUMBER_EFFECTS: "+desc.length,
+ (desc.length >= MIN_NUMBER_EFFECTS));
+
+ boolean hasEQ = false;
+ boolean hasBassBoost = false;
+ boolean hasVirtualizer = false;
+ boolean hasEnvReverb = false;
+ boolean hasPresetReverb = false;
+
+ for (int i = 0; i < desc.length; i++) {
+ if (desc[i].mType.equals(AudioEffect.EFFECT_TYPE_EQUALIZER)) {
+ hasEQ = true;
+ } else if (desc[i].mType.equals(AudioEffect.EFFECT_TYPE_BASS_BOOST)) {
+ hasBassBoost = true;
+ } else if (desc[i].mType.equals(AudioEffect.EFFECT_TYPE_VIRTUALIZER)) {
+ hasVirtualizer = true;
+ } else if (desc[i].mType.equals(AudioEffect.EFFECT_TYPE_ENV_REVERB)) {
+ hasEnvReverb = true;
+ } else if (desc[i].mType.equals(AudioEffect.EFFECT_TYPE_PRESET_REVERB)) {
+ hasPresetReverb = 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);
+ assertTrue("test0_0QueryEffects: preset reverb not found", hasPresetReverb);
+ }
+
+ //-----------------------------------------------------------------
+ // 1 - constructor
+ //----------------------------------
+
+ //Test case 1.0: test constructor from effect type and get effect ID
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "AudioEffect",
+ args = {UUID.class, UUID.class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getId",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ )
+ })
+ public void test1_0ConstructorFromType() throws Exception {
+ AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();
+ assertTrue("no effects found", (desc.length != 0));
+ for (int i = 0; i < desc.length; i++) {
+ try {
+ AudioEffect effect = new AudioEffect(desc[i].mType,
+ AudioEffect.EFFECT_TYPE_NULL,
+ 0,
+ 0);
+ assertNotNull("could not create AudioEffect", effect);
+ try {
+ assertTrue("invalid effect ID", (effect.getId() != 0));
+ } catch (IllegalStateException e) {
+ fail("AudioEffect not initialized");
+ } finally {
+ effect.release();
+ }
+ } catch (IllegalArgumentException e) {
+ fail("Effect not found: "+desc[i].mName);
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ }
+ }
+ }
+
+ //Test case 1.1: test constructor from effect uuid
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "AudioEffect",
+ args = {UUID.class, UUID.class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getId",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ )
+ })
+ public void test1_1ConstructorFromUuid() throws Exception {
+ AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();
+ assertTrue("no effects found", (desc.length != 0));
+ for (int i = 0; i < desc.length; i++) {
+ try {
+ AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_NULL,
+ desc[i].mUuid,
+ 0,
+ 0);
+ assertNotNull("could not create AudioEffect", effect);
+ try {
+ assertTrue("invalid effect ID", (effect.getId() != 0));
+ } catch (IllegalStateException e) {
+ fail("AudioEffect not initialized");
+ } finally {
+ effect.release();
+ }
+ } catch (IllegalArgumentException e) {
+ fail("Effect not found: "+desc[i].mName);
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ }
+ }
+ }
+
+ //Test case 1.2: test constructor failure from unknown type
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "AudioEffect",
+ args = {UUID.class, UUID.class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ )
+ })
+ public void test1_2ConstructorUnknownType() throws Exception {
+
+ try {
+ AudioEffect effect = new AudioEffect(UUID.randomUUID(),
+ AudioEffect.EFFECT_TYPE_NULL,
+ 0,
+ 0);
+ fail("could create random AudioEffect");
+ if (effect != null) {
+ effect.release();
+ }
+ } catch (IllegalArgumentException e) {
+
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ }
+ }
+
+ //Test case 1.3: test getEnabled() failure when called on released effect
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "AudioEffect",
+ args = {UUID.class, UUID.class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEnabled",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ )
+ })
+ public void test1_3GetEnabledAfterRelease() throws Exception {
+
+ try {
+ AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
+ AudioEffect.EFFECT_TYPE_NULL,
+ 0,
+ 0);
+ assertNotNull("could not create AudioEffect", effect);
+ effect.release();
+ try {
+ effect.getEnabled();
+ fail("getEnabled() processed after release()");
+ } catch (IllegalStateException e) {
+
+ }
+ } catch (IllegalArgumentException e) {
+ fail("AudioEffect not found");
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ }
+ }
+
+ //Test case 1.4: test contructor on mediaPlayer audio session
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "MediaPlayer.getAudioSessionId",
+ args = {}
+ )
+ })
+ public void test1_4InsertOnMediaPlayer() throws Exception {
+ MediaPlayer mp = new MediaPlayer();
+ assertNotNull("could not create mediaplayer", mp);
+ AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(R.raw.testmp3);
+ mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+ afd.close();
+ getEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, mp.getAudioSessionId());
+ try {
+ mEffect.setEnabled(true);
+
+ } catch (IllegalStateException e) {
+ fail("AudioEffect not initialized");
+ } finally {
+ mp.release();
+ releaseEffect();
+ }
+ }
+
+ //Test case 1.5: test auxiliary effect attachement on MediaPlayer
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getId",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "MediaPlayer.attachAuxEffect",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "MediaPlayer.setAuxEffectSendLevel",
+ args = {}
+ )
+ })
+ public void test1_5AuxiliaryOnMediaPlayer() throws Exception {
+ createMediaPlayerLooper();
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ fail("Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized); // mMediaPlayer has been initialized?
+ mError = 0;
+
+ AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(R.raw.testmp3);
+ mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+ afd.close();
+ getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0);
+ try {
+ synchronized(mLock) {
+ try {
+ mMediaPlayer.attachAuxEffect(mEffect.getId());
+ mMediaPlayer.setAuxEffectSendLevel(1.0f);
+ mLock.wait(200);
+ } catch(Exception e) {
+ fail("Attach effect: wait was interrupted.");
+ }
+ }
+ assertTrue("error on attachAuxEffect", mError == 0);
+
+ } catch (IllegalStateException e) {
+ fail("attach aux effect failed");
+ } finally {
+ terminateMediaPlayerLooper();
+ releaseEffect();
+ }
+ }
+
+ //Test case 1.6: test auxiliary effect attachement failure before setDatasource
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getId",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "MediaPlayer.attachAuxEffect",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "MediaPlayer.setAuxEffectSendLevel",
+ args = {}
+ )
+ })
+ public void test1_6AuxiliaryOnMediaPlayerFailure() throws Exception {
+ createMediaPlayerLooper();
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ fail("Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized); // mMediaPlayer has been initialized?
+ mError = 0;
+
+ getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0);
+ try {
+ synchronized(mLock) {
+ try {
+ mMediaPlayer.attachAuxEffect(mEffect.getId());
+ mLock.wait(1000);
+ } catch(Exception e) {
+ fail("Attach effect: wait was interrupted.");
+ }
+ }
+ assertTrue("no error on attachAuxEffect", mError != 0);
+
+ } catch (IllegalStateException e) {
+ fail("attach aux effect failed");
+ } finally {
+ terminateMediaPlayerLooper();
+ releaseEffect();
+ }
+ }
+
+
+ //Test case 1.7: test auxiliary effect attachement on AudioTrack
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getId",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "AudioTrack.attachAuxEffect",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "AudioTrack.setAuxEffectSendLevel",
+ args = {}
+ )
+ })
+ public void test1_7AuxiliaryOnAudioTrack() throws Exception {
+ AudioTrack track = null;
+ getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0);
+ try {
+ 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("could not create AudioTrack", track);
+
+ int status = track.attachAuxEffect(mEffect.getId());
+ if (status != AudioTrack.SUCCESS) {
+ fail("could not attach aux effect");
+ }
+ status = track.setAuxEffectSendLevel(1.0f);
+ if (status != AudioTrack.SUCCESS) {
+ fail("could not set send level");
+ }
+ } catch (IllegalStateException e) {
+ fail("could not attach aux effect");
+ } catch (IllegalArgumentException e) {
+ fail("could not create AudioTrack");
+ } finally {
+ if (track != null) {
+ track.release();
+ }
+ releaseEffect();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 2 - enable/ disable
+ //----------------------------------
+
+
+ //Test case 2.0: test setEnabled() and getEnabled() in valid state
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEnabled",
+ args = {}
+ )
+ })
+ public void test2_0SetEnabledGetEnabled() throws Exception {
+
+ try {
+ AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
+ AudioEffect.EFFECT_TYPE_NULL,
+ 0,
+ 0);
+ assertNotNull("could not create AudioEffect", effect);
+ try {
+ effect.setEnabled(true);
+ assertTrue("invalid state from getEnabled", effect.getEnabled());
+ effect.setEnabled(false);
+ assertFalse("invalid state to getEnabled", effect.getEnabled());
+
+ } catch (IllegalStateException e) {
+ fail("setEnabled() in wrong state");
+ } finally {
+ effect.release();
+ }
+ } catch (IllegalArgumentException e) {
+ fail("AudioEffect not found");
+
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ }
+ }
+
+ //Test case 2.1: test setEnabled() throws exception after release
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEnabled",
+ args = {}
+ )
+ })
+ public void test2_1SetEnabledAfterRelease() throws Exception {
+
+ try {
+ AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
+ AudioEffect.EFFECT_TYPE_NULL,
+ 0,
+ 0);
+ assertNotNull("could not create AudioEffect", effect);
+ effect.release();
+ try {
+ effect.setEnabled(true);
+ fail("setEnabled() processed after release");
+ } catch (IllegalStateException e) {
+ // test passed
+ }
+ } catch (IllegalArgumentException e) {
+ fail("AudioEffect not found");
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 3 - set/get parameters
+ //----------------------------------
+
+ //Test case 3.0: test setParameter(byte[], byte[]) / getParameter(byte[], byte[])
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameter",
+ args = {byte[].class, byte[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getParameter",
+ args = {byte[].class, byte[].class}
+ )
+ })
+ public void test3_0SetParameterByteArrayByteArray() throws Exception {
+ getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0);
+ try {
+ byte[] param = mEffect.intToByteArray(PresetReverb.PARAM_PRESET);
+ byte[] value = new byte[2];
+ int status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+ short preset = PresetReverb.PRESET_SMALLROOM;
+ if (mEffect.byteArrayToShort(value) == preset) {
+ preset = PresetReverb.PRESET_MEDIUMROOM;
+ }
+ value = mEffect.shortToByteArray(preset);
+ status = mEffect.setParameter(param, value);
+ assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
+ status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+ assertEquals("get/set Parameter failed", preset,
+ mEffect.byteArrayToShort(value));
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("setParameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("setParameter() called in wrong state");
+ } finally {
+ releaseEffect();
+ }
+ }
+
+ //Test case 3.1: test setParameter(int, int) / getParameter(int, int[])
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameter",
+ args = {int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getParameter",
+ args = {int.class, int[].class}
+ )
+ })
+ public void test3_1SetParameterIntInt() throws Exception {
+ getEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, 0);
+ try {
+ int param = EnvironmentalReverb.PARAM_DECAY_TIME;
+ int[] value = new int[1];
+ int status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+ int time = 500;
+ if (value[0] == time) {
+ time = 1000;
+ }
+ status = mEffect.setParameter(param, time);
+ assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
+ status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+ assertTrue("got incorrect decay time",
+ ((float)value[0] > (float)(time / DELAY_TOLERANCE)) &&
+ ((float)value[0] < (float)(time * DELAY_TOLERANCE)));
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("setParameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("setParameter() called in wrong state");
+ } finally {
+ releaseEffect();
+ }
+ }
+
+ //Test case 3.2: test setParameter(int, short) / getParameter(int, short[])
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameter",
+ args = {int.class, short.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getParameter",
+ args = {int.class, short[].class}
+ )
+ })
+ public void test3_2SetParameterIntShort() throws Exception {
+ getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0);
+ try {
+ int param = PresetReverb.PARAM_PRESET;
+ short[] value = new short[1];
+ int status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+ short preset = PresetReverb.PRESET_SMALLROOM;
+ if (value[0] == preset) {
+ preset = PresetReverb.PRESET_MEDIUMROOM;
+ }
+ status = mEffect.setParameter(param, preset);
+ assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
+ status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+ assertEquals("get/set Parameter failed", preset, value[0]);
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("setParameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("setParameter() called in wrong state");
+ } finally {
+ releaseEffect();
+ }
+ }
+
+ //Test case 3.3: test setParameter(int, byte[]) / getParameter(int, byte[])
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameter",
+ args = {int.class, byte[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getParameter",
+ args = {int.class, byte[].class}
+ )
+ })
+ public void test3_3SetParameterIntByteArray() throws Exception {
+ getEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, 0);
+ try {
+ int param = EnvironmentalReverb.PARAM_DECAY_TIME;
+ byte[] value = new byte[4];
+ int status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+ int time = 500;
+ if (mEffect.byteArrayToInt(value) == time) {
+ time = 1000;
+ }
+ value = mEffect.intToByteArray(time);
+ status = mEffect.setParameter(param, value);
+ assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
+ status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+ int time2 = mEffect.byteArrayToInt(value);
+ assertTrue("got incorrect decay time",
+ ((float)time2 > (float)(time / DELAY_TOLERANCE)) &&
+ ((float)time2 < (float)(time * DELAY_TOLERANCE)));
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("setParameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("setParameter() called in wrong state");
+ } finally {
+ releaseEffect();
+ }
+ }
+
+ //Test case 3.4: test setParameter(int[], int[]) / getParameter(int[], int[])
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameter",
+ args = {int[].class, int[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getParameter",
+ args = {int[].class, int[].class}
+ )
+ })
+ public void test3_4SetParameterIntArrayIntArray() throws Exception {
+ getEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, 0);
+ try {
+ int[] param = new int[1];
+ int[] value = new int[1];
+ param[0] = EnvironmentalReverb.PARAM_DECAY_TIME;
+ int status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+ int[] time = new int[1];
+ time[0] = 500;
+ if (value[0] == time[0]) {
+ time[0] = 1000;
+ }
+ status = mEffect.setParameter(param, time);
+ assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
+ status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+ assertTrue("got incorrect decay time",
+ ((float)value[0] > (float)(time[0] / DELAY_TOLERANCE)) &&
+ ((float)value[0] < (float)(time[0] * DELAY_TOLERANCE)));
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("setParameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("setParameter() called in wrong state");
+ } finally {
+ releaseEffect();
+ }
+ }
+
+ //Test case 3.5: test setParameter(int[], short[]) / getParameter(int[], short[])
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameter",
+ args = {int[].class, short[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getParameter",
+ args = {int[].class, short[].class}
+ )
+ })
+
+ public void test3_5SetParameterIntArrayShortArray() throws Exception {
+ getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0);
+ try {
+ int[] param = new int[1];
+ param[0] = PresetReverb.PARAM_PRESET;
+ short[] value = new short[1];
+ int status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+ short[] preset = new short[1];
+ preset[0] = PresetReverb.PRESET_SMALLROOM;
+ if (value[0] == preset[0]) {
+ preset[0] = PresetReverb.PRESET_MEDIUMROOM;
+ }
+ status = mEffect.setParameter(param, preset);
+ assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
+ status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+ assertEquals("get/set Parameter failed", preset[0], value[0]);
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("setParameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("setParameter() called in wrong state");
+ } finally {
+ releaseEffect();
+ }
+ }
+
+ //Test case 3.6: test setParameter(int[], byte[]) / getParameter(int[], byte[])
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameter",
+ args = {int[].class, byte[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getParameter",
+ args = {int[].class, byte[].class}
+ )
+ })
+ public void test3_6SetParameterIntArrayByteArray() throws Exception {
+ getEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, 0);
+ try {
+ int[] param = new int[1];
+ param[0] = EnvironmentalReverb.PARAM_DECAY_TIME;
+ byte[] value = new byte[4];
+ int status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+ int time = 500;
+ if (mEffect.byteArrayToInt(value) == time) {
+ time = 1000;
+ }
+
+ status = mEffect.setParameter(param, mEffect.intToByteArray(time));
+ assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
+ status = mEffect.getParameter(param, value);
+ assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+ int time2 = mEffect.byteArrayToInt(value);
+ assertTrue("got incorrect decay time",
+ ((float)time2 > (float)(time / DELAY_TOLERANCE)) &&
+ ((float)time2 < (float)(time * DELAY_TOLERANCE)));
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("setParameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("setParameter() called in wrong state");
+ } finally {
+ releaseEffect();
+ }
+ }
+
+ //Test case 3.7: test setParameter() throws exception after release()
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameter",
+ args = {int.class, short.class}
+ )
+ })
+ public void test3_7SetParameterAfterRelease() throws Exception {
+ AudioEffect effect = null;
+ try {
+ effect = new AudioEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB,
+ AudioEffect.EFFECT_TYPE_NULL,
+ 0,
+ 0);
+ assertNotNull("could not create AudioEffect", effect);
+ effect.release();
+ effect.setParameter(PresetReverb.PARAM_PRESET, PresetReverb.PRESET_SMALLROOM);
+ fail("setParameter() processed after release");
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("setParameter() rejected");
+ } catch (IllegalStateException e) {
+ // test passed
+ } finally {
+ if (effect != null) {
+ effect.release();
+ }
+ }
+ }
+
+ //Test case 3.8: test getParameter() throws exception after release()
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameter",
+ args = {int.class, short[].class}
+ )
+ })
+ public void test3_8GetParameterAfterRelease() throws Exception {
+ AudioEffect effect = null;
+ try {
+ effect = new AudioEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB,
+ AudioEffect.EFFECT_TYPE_NULL,
+ 0,
+ 0);
+ assertNotNull("could not create AudioEffect", effect);
+ effect.release();
+ short[] value = new short[1];
+ effect.getParameter(PresetReverb.PARAM_PRESET, value);
+ fail("getParameter() processed after release");
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("getParameter() rejected");
+ } catch (IllegalStateException e) {
+ // test passed
+ } finally {
+ if (effect != null) {
+ effect.release();
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 4 priority and listeners
+ //----------------------------------
+
+ //Test case 4.0: test control passed to higher priority client
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "hasControl",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEnabled",
+ args = {}
+ )
+ })
+ public void test4_0setEnabledLowerPriority() throws Exception {
+ 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("could not create AudioEffect", effect1);
+ assertNotNull("could not create AudioEffect", effect2);
+
+ assertTrue("Effect2 does not have control", effect2.hasControl());
+ assertFalse("Effect1 has control", effect1.hasControl());
+ assertTrue("Effect1 can enable",
+ effect1.setEnabled(true) == AudioEffect.ERROR_INVALID_OPERATION);
+ assertFalse("Effect1 has enabled", effect2.getEnabled());
+
+ } catch (IllegalArgumentException e) {
+ fail("Effect not found");
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ } finally {
+ if (effect1 != null) {
+ effect1.release();
+ }
+ if (effect2 != null) {
+ effect2.release();
+ }
+ }
+ }
+
+ //Test case 4.1: test control passed to higher priority client
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameter",
+ args = {int.class, short.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getParameter",
+ args = {int.class, short[].class}
+ )
+ })
+ public void test4_1setParameterLowerPriority() throws Exception {
+ AudioEffect effect1 = null;
+ AudioEffect effect2 = null;
+ try {
+ effect1 = new AudioEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB,
+ AudioEffect.EFFECT_TYPE_NULL,
+ 0,
+ 0);
+ effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB,
+ AudioEffect.EFFECT_TYPE_NULL,
+ 1,
+ 0);
+
+ assertNotNull("could not create AudioEffect", effect1);
+ assertNotNull("could not create AudioEffect", effect2);
+
+ int status = effect2.setParameter(PresetReverb.PARAM_PRESET,
+ PresetReverb.PRESET_SMALLROOM);
+ assertEquals("Effect2 setParameter failed",
+ AudioEffect.SUCCESS, status);
+
+ status = effect1.setParameter(PresetReverb.PARAM_PRESET,
+ PresetReverb.PRESET_MEDIUMROOM);
+ assertEquals("Effect1 setParameter did not fail",
+ AudioEffect.ERROR_INVALID_OPERATION, status);
+
+ short[] value = new short[1];
+ status = effect2.getParameter(PresetReverb.PARAM_PRESET, value);
+ assertEquals("Effect2 getParameter failed",
+ AudioEffect.SUCCESS, status);
+ assertEquals("Effect1 changed parameter", PresetReverb.PRESET_SMALLROOM
+ , value[0]);
+
+
+ } catch (IllegalArgumentException e) {
+ fail("Effect not found");
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ } finally {
+ if (effect1 != null) {
+ effect1.release();
+ }
+ if (effect2 != null) {
+ effect2.release();
+ }
+ }
+ }
+
+ //Test case 4.2: test control status listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setControlStatusListener",
+ args = {AudioEffect.OnControlStatusChangeListener.class}
+ )
+ })
+ public void test4_2ControlStatusListener() throws Exception {
+
+ mHasControl = true;
+ createListenerLooper(true, false, false);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ fail("Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ synchronized(mLock) {
+ try {
+ getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ fail("Create second effect: wait was interrupted.");
+ } finally {
+ releaseEffect();
+ terminateListenerLooper();
+ }
+ }
+ assertFalse("effect control not lost by effect1", mHasControl);
+ }
+
+ //Test case 4.3: test enable status listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnableStatusListener",
+ args = {AudioEffect.OnEnableStatusChangeListener.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEnabled",
+ args = {}
+ )
+ })
+ public void test4_3EnableStatusListener() throws Exception {
+
+ createListenerLooper(false, true, false);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ fail("Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ mEffect2.setEnabled(true);
+ mIsEnabled = true;
+
+ getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0);
+ assertTrue("effect not enabled", mEffect.getEnabled());
+ synchronized(mLock) {
+ try {
+ mEffect.setEnabled(false);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ fail("Second effect setEnabled: wait was interrupted.");
+ } finally {
+ releaseEffect();
+ terminateListenerLooper();
+ }
+ }
+ assertFalse("enable status not updated", mIsEnabled);
+ }
+
+ //Test case 4.4: test parameter changed listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameterListener",
+ args = {AudioEffect.OnParameterChangeListener.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameter",
+ args = {int.class, short.class}
+ )
+ })
+ public void test4_4ParameterChangedListener() throws Exception {
+
+ createListenerLooper(false, false, true);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ fail("Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ int status = mEffect2.setParameter(PresetReverb.PARAM_PRESET,
+ PresetReverb.PRESET_SMALLROOM);
+ assertEquals("mEffect2 setParameter failed",
+ AudioEffect.SUCCESS, status);
+ getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0);
+ synchronized(mLock) {
+ try {
+ mChangedParameter = -1;
+ mEffect.setParameter(PresetReverb.PARAM_PRESET,
+ PresetReverb.PRESET_MEDIUMROOM);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ fail("set Parameter: wait was interrupted.");
+ } finally {
+ releaseEffect();
+ terminateListenerLooper();
+ }
+ }
+ assertEquals("parameter change not received",
+ PresetReverb.PARAM_PRESET, mChangedParameter);
+ }
+
+ //-----------------------------------------------------------------
+ // 5 command method
+ //----------------------------------
+
+
+ //Test case 5.0: test command method
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "command",
+ args = {int.class, byte[].class, byte[].class}
+ )
+ })
+ public void test5_0Command() throws Exception {
+ getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0);
+ try {
+ byte[] cmd = new byte[0];
+ byte[] reply = new byte[4];
+ // command 3 is ENABLE
+ int status = mEffect.command(3, cmd, reply);
+ assertEquals("command failed", AudioEffect.SUCCESS, status);
+ assertTrue("effect not enabled", mEffect.getEnabled());
+
+ } catch (IllegalStateException e) {
+ fail("command in illegal state");
+ } finally {
+ releaseEffect();
+ }
+ }
+
+
+ //-----------------------------------------------------------------
+ // private methods
+ //----------------------------------
+
+ private void getEffect(UUID type, int session) {
+ if (mEffect == null || session != mSession) {
+ if (session != mSession && mEffect != null) {
+ mEffect.release();
+ mEffect = null;
+ }
+ try {
+ mEffect = new AudioEffect(type,
+ AudioEffect.EFFECT_TYPE_NULL,
+ 0,
+ session);
+ mSession = session;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "getEffect() AudioEffect not found exception: "+e);
+ } catch (UnsupportedOperationException e) {
+ Log.e(TAG, "getEffect() Effect library not loaded exception: "+e);
+ }
+ }
+ assertNotNull("could not create mEffect", mEffect);
+ }
+
+ private void releaseEffect() {
+ if (mEffect != null) {
+ mEffect.release();
+ mEffect = null;
+ }
+ }
+
+ // Initializes the equalizer listener looper
+ 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) {
+ mInitialized = false;
+ new ListenerThread(control, enable, parameter) {
+ @Override
+ public void run() {
+ // Set up a looper
+ Looper.prepare();
+
+ // Save the looper so that we can terminate this thread
+ // after we are done with it.
+ mLooper = Looper.myLooper();
+
+ mEffect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB,
+ AudioEffect.EFFECT_TYPE_NULL,
+ 0,
+ 0);
+ assertNotNull("could not create Equalizer2", mEffect2);
+
+ if (mControl) {
+ mEffect2.setControlStatusListener(
+ new AudioEffect.OnControlStatusChangeListener() {
+ public void onControlStatusChange(
+ AudioEffect effect, boolean controlGranted) {
+ synchronized(mLock) {
+ if (effect == mEffect2) {
+ mHasControl = controlGranted;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+ if (mEnable) {
+ mEffect2.setEnableStatusListener(
+ new AudioEffect.OnEnableStatusChangeListener() {
+ public void onEnableStatusChange(AudioEffect effect, boolean enabled) {
+ synchronized(mLock) {
+ if (effect == mEffect2) {
+ mIsEnabled = enabled;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+ if (mParameter) {
+ mEffect2.setParameterListener(new AudioEffect.OnParameterChangeListener() {
+ public void onParameterChange(AudioEffect effect, int status, byte[] param,
+ byte[] value)
+ {
+ synchronized(mLock) {
+ if (effect == mEffect2) {
+ mChangedParameter = mEffect2.byteArrayToInt(param);
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+
+ synchronized(mLock) {
+ mInitialized = true;
+ mLock.notify();
+ }
+ Looper.loop(); // Blocks forever until Looper.quit() is called.
+ }
+ }.start();
+ }
+
+ // Terminates the listener looper thread.
+ private void terminateListenerLooper() {
+ if (mEffect2 != null) {
+ mEffect2.release();
+ mEffect2 = null;
+ }
+ if (mLooper != null) {
+ mLooper.quit();
+ mLooper = null;
+ }
+ }
+
+ /*
+ * Initializes the message looper so that the MediaPlayer object can
+ * receive the callback messages.
+ */
+ private void createMediaPlayerLooper() {
+ mInitialized = false;
+ 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(mLock) {
+ mError = what;
+ mLock.notify();
+ }
+ return true;
+ }
+ });
+ mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+ public void onCompletion(MediaPlayer player) {
+ synchronized(mLock) {
+ mLock.notify();
+ }
+ }
+ });
+ synchronized(mLock) {
+ mInitialized = true;
+ mLock.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();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/tests/tests/media/src/android/media/cts/BassBoostTest.java b/tests/tests/media/src/android/media/cts/BassBoostTest.java
new file mode 100644
index 0000000..d0b16e4
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/BassBoostTest.java
@@ -0,0 +1,506 @@
+/*
+ * 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 android.media.cts;
+
+import android.media.AudioEffect;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.BassBoost;
+import android.os.Looper;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(BassBoost.class)
+public class BassBoostTest extends AndroidTestCase {
+
+ private String TAG = "BassBoostTest";
+ private final static short TEST_STRENGTH = 500;
+ private final static short TEST_STRENGTH2 = 1000;
+ private final static float STRENGTH_TOLERANCE = 1.1f; // 10%
+
+ private BassBoost mBassBoost = null;
+ private BassBoost mBassBoost2 = null;
+ private int mSession = -1;
+ private boolean mHasControl = false;
+ private boolean mIsEnabled = false;
+ private int mChangedParameter = -1;
+ private boolean mInitialized = false;
+ private Looper mLooper = null;
+ private final Object mLock = new Object();
+
+ //-----------------------------------------------------------------
+ // BASS BOOST TESTS:
+ //----------------------------------
+
+ //-----------------------------------------------------------------
+ // 0 - constructor
+ //----------------------------------
+
+ //Test case 0.0: test constructor and release
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "BassBoost",
+ args = {int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getId",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ )
+ })
+ public void test0_0ConstructorAndRelease() throws Exception {
+ BassBoost eq = null;
+ try {
+ eq = new BassBoost(0, 0);
+ assertNotNull("could not create BassBoost", eq);
+ try {
+ assertTrue("invalid effect ID", (eq.getId() != 0));
+ } catch (IllegalStateException e) {
+ fail("BassBoost not initialized");
+ }
+ // test passed
+ } catch (IllegalArgumentException e) {
+ fail("BassBoost not found");
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ } finally {
+ if (eq != null) {
+ eq.release();
+ }
+ }
+ }
+
+
+ //-----------------------------------------------------------------
+ // 1 - get/set parameters
+ //----------------------------------
+
+ //Test case 1.0: test strength
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getStrengthSupported",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setStrength",
+ args = {short.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getRoundedStrength",
+ args = {}
+ )
+ })
+ public void test1_0Strength() throws Exception {
+ getBassBoost(0);
+ try {
+ if (mBassBoost.getStrengthSupported()) {
+ short strength = mBassBoost.getRoundedStrength();
+ strength = (strength == TEST_STRENGTH) ? TEST_STRENGTH2 : TEST_STRENGTH;
+ mBassBoost.setStrength((short)strength);
+ short strength2 = mBassBoost.getRoundedStrength();
+ // allow STRENGTH_TOLERANCE difference between set strength and rounded strength
+ assertTrue("got incorrect strength",
+ ((float)strength2 > (float)strength / STRENGTH_TOLERANCE) &&
+ ((float)strength2 < (float)strength * STRENGTH_TOLERANCE));
+ } else {
+ short strength = mBassBoost.getRoundedStrength();
+ assertTrue("got incorrect strength", strength >= 0 && strength <= 1000);
+ }
+ // test passed
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseBassBoost();
+ }
+ }
+
+ //Test case 1.1: test properties
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getProperties",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setProperties",
+ args = {BassBoost.Settings.class}
+ )
+ })
+ public void test1_1Properties() throws Exception {
+ getBassBoost(0);
+ try {
+ BassBoost.Settings settings = mBassBoost.getProperties();
+ String str = settings.toString();
+ settings = new BassBoost.Settings(str);
+
+ short strength = settings.strength;
+ if (mBassBoost.getStrengthSupported()) {
+ strength = (strength == TEST_STRENGTH) ? TEST_STRENGTH2 : TEST_STRENGTH;
+ }
+ settings.strength = strength;
+ mBassBoost.setProperties(settings);
+ settings = mBassBoost.getProperties();
+
+ if (mBassBoost.getStrengthSupported()) {
+ // allow STRENGTH_TOLERANCE difference between set strength and rounded strength
+ assertTrue("got incorrect strength",
+ ((float)settings.strength > (float)strength / STRENGTH_TOLERANCE) &&
+ ((float)settings.strength < (float)strength * STRENGTH_TOLERANCE));
+ }
+ // test passed
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseBassBoost();
+ }
+ }
+
+ //Test case 1.2: test setStrength() throws exception after release
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setStrength",
+ args = {short.class}
+ )
+ })
+ public void test1_2SetStrengthAfterRelease() throws Exception {
+ getBassBoost(0);
+ mBassBoost.release();
+ try {
+ mBassBoost.setStrength(TEST_STRENGTH);
+ fail("setStrength() processed after release()");
+ } catch (IllegalStateException e) {
+ // test passed
+ } finally {
+ releaseBassBoost();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 2 - Effect enable/disable
+ //----------------------------------
+
+ //Test case 2.0: test setEnabled() and getEnabled() in valid state
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEnabled",
+ args = {}
+ )
+ })
+ public void test2_0SetEnabledGetEnabled() throws Exception {
+ getBassBoost(0);
+ try {
+ mBassBoost.setEnabled(true);
+ assertTrue("invalid state from getEnabled", mBassBoost.getEnabled());
+ mBassBoost.setEnabled(false);
+ assertFalse("invalid state to getEnabled", mBassBoost.getEnabled());
+ // test passed
+ } catch (IllegalStateException e) {
+ fail("setEnabled() in wrong state");
+ } finally {
+ releaseBassBoost();
+ }
+ }
+
+ //Test case 2.1: test setEnabled() throws exception after release
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ )
+ })
+ public void test2_1SetEnabledAfterRelease() throws Exception {
+ getBassBoost(0);
+ mBassBoost.release();
+ try {
+ mBassBoost.setEnabled(true);
+ fail("setEnabled() processed after release()");
+ } catch (IllegalStateException e) {
+ // test passed
+ } finally {
+ releaseBassBoost();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 3 priority and listeners
+ //----------------------------------
+
+ //Test case 3.0: test control status listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setControlStatusListener",
+ args = {AudioEffect.OnControlStatusChangeListener.class}
+ )
+ })
+ public void test3_0ControlStatusListener() throws Exception {
+ mHasControl = true;
+ createListenerLooper(true, false, false);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ synchronized(mLock) {
+ try {
+ getBassBoost(0);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Create second effect: wait was interrupted.");
+ } finally {
+ releaseBassBoost();
+ terminateListenerLooper();
+ }
+ }
+ assertFalse("effect control not lost by effect1", mHasControl);
+ }
+
+ //Test case 3.1: test enable status listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnableStatusListener",
+ args = {AudioEffect.OnEnableStatusChangeListener.class}
+ )
+ })
+ public void test3_1EnableStatusListener() throws Exception {
+ createListenerLooper(false, true, false);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ mBassBoost2.setEnabled(true);
+ mIsEnabled = true;
+ getBassBoost(0);
+ synchronized(mLock) {
+ try {
+ mBassBoost.setEnabled(false);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Create second effect: wait was interrupted.");
+ } finally {
+ releaseBassBoost();
+ terminateListenerLooper();
+ }
+ }
+ assertFalse("enable status not updated", mIsEnabled);
+ }
+
+ //Test case 3.2: test parameter changed listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameterListener",
+ args = {BassBoost.OnParameterChangeListener.class}
+ )
+ })
+ public void test3_2ParameterChangedListener() throws Exception {
+ createListenerLooper(false, false, true);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ getBassBoost(0);
+ synchronized(mLock) {
+ try {
+ mChangedParameter = -1;
+ mBassBoost.setStrength(TEST_STRENGTH);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Create second effect: wait was interrupted.");
+ } finally {
+ releaseBassBoost();
+ terminateListenerLooper();
+ }
+ }
+ assertEquals("parameter change not received",
+ BassBoost.PARAM_STRENGTH, mChangedParameter);
+ }
+
+ //-----------------------------------------------------------------
+ // private methods
+ //----------------------------------
+
+ private void getBassBoost(int session) {
+ if (mBassBoost == null || session != mSession) {
+ if (session != mSession && mBassBoost != null) {
+ mBassBoost.release();
+ mBassBoost = null;
+ }
+ try {
+ mBassBoost = new BassBoost(0, session);
+ mSession = session;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "getBassBoost() BassBoost not found exception: "+e);
+ } catch (UnsupportedOperationException e) {
+ Log.e(TAG, "getBassBoost() Effect library not loaded exception: "+e);
+ }
+ }
+ assertNotNull("could not create mBassBoost", mBassBoost);
+ }
+
+ private void releaseBassBoost() {
+ if (mBassBoost != null) {
+ mBassBoost.release();
+ mBassBoost = null;
+ }
+ }
+
+ // Initializes the bassboot listener looper
+ 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) {
+ mInitialized = false;
+ new ListenerThread(control, enable, parameter) {
+ @Override
+ public void run() {
+ // Set up a looper
+ Looper.prepare();
+
+ // Save the looper so that we can terminate this thread
+ // after we are done with it.
+ mLooper = Looper.myLooper();
+
+ mBassBoost2 = new BassBoost(0, 0);
+ assertNotNull("could not create bassboot2", mBassBoost2);
+
+ if (mControl) {
+ mBassBoost2.setControlStatusListener(
+ new AudioEffect.OnControlStatusChangeListener() {
+ public void onControlStatusChange(
+ AudioEffect effect, boolean controlGranted) {
+ synchronized(mLock) {
+ if (effect == mBassBoost2) {
+ mHasControl = controlGranted;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+ if (mEnable) {
+ mBassBoost2.setEnableStatusListener(
+ new AudioEffect.OnEnableStatusChangeListener() {
+ public void onEnableStatusChange(AudioEffect effect, boolean enabled) {
+ synchronized(mLock) {
+ if (effect == mBassBoost2) {
+ mIsEnabled = enabled;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+ if (mParameter) {
+ mBassBoost2.setParameterListener(new BassBoost.OnParameterChangeListener() {
+ public void onParameterChange(BassBoost effect, int status,
+ int param, short value)
+ {
+ synchronized(mLock) {
+ if (effect == mBassBoost2) {
+ mChangedParameter = param;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+
+ synchronized(mLock) {
+ mInitialized = true;
+ mLock.notify();
+ }
+ Looper.loop(); // Blocks forever until Looper.quit() is called.
+ }
+ }.start();
+ }
+
+ // Terminates the listener looper thread.
+ private void terminateListenerLooper() {
+ if (mBassBoost2 != null) {
+ mBassBoost2.release();
+ mBassBoost2 = null;
+ }
+ if (mLooper != null) {
+ mLooper.quit();
+ mLooper = null;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/tests/tests/media/src/android/media/cts/EnvReverbTest.java b/tests/tests/media/src/android/media/cts/EnvReverbTest.java
new file mode 100644
index 0000000..3854048
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/EnvReverbTest.java
@@ -0,0 +1,698 @@
+/*
+ * 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 android.media.cts;
+
+import android.media.AudioEffect;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.EnvironmentalReverb;
+import android.os.Looper;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(EnvironmentalReverb.class)
+public class EnvReverbTest extends AndroidTestCase {
+
+ private String TAG = "EnvReverbTest";
+ private final static int MILLIBEL_TOLERANCE = 100; // +/-1dB
+ private final static float DELAY_TOLERANCE = 1.05f; // 5%
+ private final static float RATIO_TOLERANCE = 1.05f; // 5%
+
+ private EnvironmentalReverb mReverb = null;
+ private EnvironmentalReverb mReverb2 = null;
+ private int mSession = -1;
+ private boolean mHasControl = false;
+ private boolean mIsEnabled = false;
+ private int mChangedParameter = -1;
+ private boolean mInitialized = false;
+ private Looper mLooper = null;
+ private final Object mLock = new Object();
+
+
+ //-----------------------------------------------------------------
+ // ENVIRONMENTAL REVERB TESTS:
+ //----------------------------------
+
+ //-----------------------------------------------------------------
+ // 0 - constructor
+ //----------------------------------
+
+ //Test case 0.0: test constructor and release
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "EnvironmentalReverb",
+ args = {int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getId",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ )
+ })
+ public void test0_0ConstructorAndRelease() throws Exception {
+ EnvironmentalReverb envReverb = null;
+ try {
+ envReverb = new EnvironmentalReverb(0, 0);
+ assertNotNull("could not create EnvironmentalReverb", envReverb);
+ try {
+ assertTrue("invalid effect ID", (envReverb.getId() != 0));
+ } catch (IllegalStateException e) {
+ fail("EnvironmentalReverb not initialized");
+ }
+ } catch (IllegalArgumentException e) {
+ fail("EnvironmentalReverb not found");
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ } finally {
+ if (envReverb != null) {
+ envReverb.release();
+ }
+ }
+ }
+
+
+ //-----------------------------------------------------------------
+ // 1 - get/set parameters
+ //----------------------------------
+
+ //Test case 1.0: test room level and room HF level
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setRoomLevel",
+ args = {short.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getRoomLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setRoomHFLevel",
+ args = {short.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getRoomHFLevel",
+ args = {}
+ )
+ })
+ public void test1_0Room() throws Exception {
+ getReverb(0);
+ try {
+ short level = mReverb.getRoomLevel();
+ level = (short)((level == 0) ? -1000 : 0);
+ mReverb.setRoomLevel(level);
+ short level2 = mReverb.getRoomLevel();
+ assertTrue("got incorrect room level",
+ (level2 > (level - MILLIBEL_TOLERANCE)) &&
+ (level2 < (level + MILLIBEL_TOLERANCE)));
+
+ level = mReverb.getRoomHFLevel();
+ level = (short)((level == 0) ? -1000 : 0);
+ mReverb.setRoomHFLevel(level);
+ level2 = mReverb.getRoomHFLevel();
+ assertTrue("got incorrect room HF level",
+ (level2 > (level - MILLIBEL_TOLERANCE)) &&
+ (level2 < (level + MILLIBEL_TOLERANCE)));
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseReverb();
+ }
+ }
+
+ //Test case 1.1: test decay time and ratio
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDecayTime",
+ args = {int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getDecayTime",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDecayHFRatio",
+ args = {short.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getDecayHFRatio",
+ args = {}
+ )
+ })
+ public void test1_1Decay() throws Exception {
+ getReverb(0);
+ try {
+ int time = mReverb.getDecayTime();
+ time = (time == 500) ? 1000 : 500;
+ mReverb.setDecayTime(time);
+ int time2 = mReverb.getDecayTime();
+ assertTrue("got incorrect decay time",
+ ((float)time2 > (float)(time / DELAY_TOLERANCE)) &&
+ ((float)time2 < (float)(time * DELAY_TOLERANCE)));
+ short ratio = mReverb.getDecayHFRatio();
+ ratio = (short)((ratio == 500) ? 1000 : 500);
+ mReverb.setDecayHFRatio(ratio);
+ short ratio2 = mReverb.getDecayHFRatio();
+ assertTrue("got incorrect decay HF ratio",
+ ((float)ratio2 > (float)(ratio / RATIO_TOLERANCE)) &&
+ ((float)ratio2 < (float)(ratio * RATIO_TOLERANCE)));
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseReverb();
+ }
+ }
+
+
+ //Test case 1.2: test reverb level and delay
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setReverbLevel",
+ args = {short.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getReverbLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setReverbDelay",
+ args = {int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getReverbDelay",
+ args = {}
+ )
+ })
+ public void test1_2Reverb() throws Exception {
+ getReverb(0);
+ try {
+ short level = mReverb.getReverbLevel();
+ level = (short)((level == 0) ? -1000 : 0);
+ mReverb.setReverbLevel(level);
+ short level2 = mReverb.getReverbLevel();
+ assertTrue("got incorrect reverb level",
+ (level2 > (level - MILLIBEL_TOLERANCE)) &&
+ (level2 < (level + MILLIBEL_TOLERANCE)));
+
+// FIXME:uncomment actual test when early reflections are implemented in the reverb
+// int time = mReverb.getReverbDelay();
+// mReverb.setReverbDelay(time);
+// int time2 = mReverb.getReverbDelay();
+// assertTrue("got incorrect reverb delay",
+// ((float)time2 > (float)(time / DELAY_TOLERANCE)) &&
+// ((float)time2 < (float)(time * DELAY_TOLERANCE)));
+ mReverb.setReverbDelay(0);
+ int time2 = mReverb.getReverbDelay();
+ assertEquals("got incorrect reverb delay", mReverb.getReverbDelay(), 0);
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseReverb();
+ }
+ }
+
+ //Test case 1.3: test early reflections level and delay
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setReflectionsLevel",
+ args = {short.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getReflectionsLevel",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setReflectionsDelay",
+ args = {int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getReflectionsDelay",
+ args = {}
+ )
+ })
+ public void test1_3Reflections() throws Exception {
+ getReverb(0);
+ try {
+// FIXME:uncomment actual test when early reflections are implemented in the reverb
+// short level = mReverb.getReflectionsLevel();
+// level = (short)((level == 0) ? -1000 : 0);
+// mReverb.setReflectionsLevel(level);
+// short level2 = mReverb.getReflectionsLevel();
+// assertTrue("got incorrect reflections level",
+// (level2 > (level - MILLIBEL_TOLERANCE)) &&
+// (level2 < (level + MILLIBEL_TOLERANCE)));
+//
+// int time = mReverb.getReflectionsDelay();
+// time = (time == 20) ? 0 : 20;
+// mReverb.setReflectionsDelay(time);
+// int time2 = mReverb.getReflectionsDelay();
+// assertTrue("got incorrect reflections delay",
+// ((float)time2 > (float)(time / DELAY_TOLERANCE)) &&
+// ((float)time2 < (float)(time * DELAY_TOLERANCE)));
+ mReverb.setReflectionsLevel((short) 0);
+ assertEquals("got incorrect reverb delay",
+ mReverb.getReflectionsLevel(), (short) 0);
+ mReverb.setReflectionsDelay(0);
+ assertEquals("got incorrect reverb delay",
+ mReverb.getReflectionsDelay(), 0);
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseReverb();
+ }
+ }
+
+ //Test case 1.4: test diffusion and density
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDiffusion",
+ args = {short.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getDiffusion",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDensity",
+ args = {short.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getDensity",
+ args = {}
+ )
+ })
+ public void test1_4DiffusionAndDensity() throws Exception {
+ getReverb(0);
+ try {
+ short ratio = mReverb.getDiffusion();
+ ratio = (short)((ratio == 500) ? 1000 : 500);
+ mReverb.setDiffusion(ratio);
+ short ratio2 = mReverb.getDiffusion();
+ assertTrue("got incorrect diffusion",
+ ((float)ratio2 > (float)(ratio / RATIO_TOLERANCE)) &&
+ ((float)ratio2 < (float)(ratio * RATIO_TOLERANCE)));
+
+ ratio = mReverb.getDensity();
+ ratio = (short)((ratio == 500) ? 1000 : 500);
+ mReverb.setDensity(ratio);
+ ratio2 = mReverb.getDensity();
+ assertTrue("got incorrect density",
+ ((float)ratio2 > (float)(ratio / RATIO_TOLERANCE)) &&
+ ((float)ratio2 < (float)(ratio * RATIO_TOLERANCE)));
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseReverb();
+ }
+ }
+
+ //Test case 1.5: test properties
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getProperties",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setProperties",
+ args = {EnvironmentalReverb.Settings.class}
+ )
+ })
+ public void test1_5Properties() throws Exception {
+ getReverb(0);
+ try {
+ EnvironmentalReverb.Settings settings = mReverb.getProperties();
+ String str = settings.toString();
+ settings = new EnvironmentalReverb.Settings(str);
+ short level = (short)((settings.roomLevel == 0) ? -1000 : 0);
+ settings.roomLevel = level;
+ mReverb.setProperties(settings);
+ settings = mReverb.getProperties();
+ assertTrue("setProperties failed",
+ (settings.roomLevel >= (level - MILLIBEL_TOLERANCE)) &&
+ (settings.roomLevel <= (level + MILLIBEL_TOLERANCE)));
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseReverb();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 2 - Effect enable/disable
+ //----------------------------------
+
+ //Test case 2.0: test setEnabled() and getEnabled() in valid state
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEnabled",
+ args = {}
+ )
+ })
+ public void test2_0SetEnabledGetEnabled() throws Exception {
+ getReverb(0);
+ try {
+ mReverb.setEnabled(true);
+ assertTrue("invalid state from getEnabled", mReverb.getEnabled());
+ mReverb.setEnabled(false);
+ assertFalse("invalid state to getEnabled", mReverb.getEnabled());
+ } catch (IllegalStateException e) {
+ fail("setEnabled() in wrong state");
+ } finally {
+ releaseReverb();
+ }
+ }
+
+ //Test case 2.1: test setEnabled() throws exception after release
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ )
+ })
+ public void test2_1SetEnabledAfterRelease() throws Exception {
+ getReverb(0);
+ mReverb.release();
+ try {
+ mReverb.setEnabled(true);
+ fail("setEnabled() processed after release()");
+ } catch (IllegalStateException e) {
+ // test passed
+ } finally {
+ releaseReverb();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 3 priority and listeners
+ //----------------------------------
+
+ //Test case 3.0: test control status listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setControlStatusListener",
+ args = {AudioEffect.OnControlStatusChangeListener.class}
+ )
+ })
+ public void test3_0ControlStatusListener() throws Exception {
+ mHasControl = true;
+ createListenerLooper(true, false, false);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ synchronized(mLock) {
+ try {
+ getReverb(0);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Create second effect: wait was interrupted.");
+ } finally {
+ releaseReverb();
+ terminateListenerLooper();
+ }
+ }
+ assertFalse("effect control not lost by effect1", mHasControl);
+ }
+
+ //Test case 3.1: test enable status listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnableStatusListener",
+ args = {AudioEffect.OnEnableStatusChangeListener.class}
+ )
+ })
+ public void test3_1EnableStatusListener() throws Exception {
+ createListenerLooper(false, true, false);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ mReverb2.setEnabled(true);
+ mIsEnabled = true;
+ getReverb(0);
+ synchronized(mLock) {
+ try {
+ mReverb.setEnabled(false);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Create second effect: wait was interrupted.");
+ } finally {
+ releaseReverb();
+ terminateListenerLooper();
+ }
+ }
+ assertFalse("enable status not updated", mIsEnabled);
+ }
+
+ //Test case 3.2: test parameter changed listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameterListener",
+ args = {EnvironmentalReverb.OnParameterChangeListener.class}
+ )
+ })
+ public void test3_2ParameterChangedListener() throws Exception {
+ createListenerLooper(false, false, true);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ getReverb(0);
+ synchronized(mLock) {
+ try {
+ mChangedParameter = -1;
+ mReverb.setRoomLevel((short)0);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Create second effect: wait was interrupted.");
+ } finally {
+ releaseReverb();
+ terminateListenerLooper();
+ }
+ }
+ assertEquals("parameter change not received",
+ EnvironmentalReverb.PARAM_ROOM_LEVEL, mChangedParameter);
+ }
+
+ //-----------------------------------------------------------------
+ // private methods
+ //----------------------------------
+
+ private void getReverb(int session) {
+ if (mReverb == null || session != mSession) {
+ if (session != mSession && mReverb != null) {
+ mReverb.release();
+ mReverb = null;
+ }
+ try {
+ mReverb = new EnvironmentalReverb(0, session);
+ mSession = session;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "getReverb() EnvironmentalReverb not found exception: "+e);
+ } catch (UnsupportedOperationException e) {
+ Log.e(TAG, "getReverb() Effect library not loaded exception: "+e);
+ }
+ }
+ assertNotNull("could not create mReverb", mReverb);
+ }
+
+ private void releaseReverb() {
+ if (mReverb != null) {
+ mReverb.release();
+ mReverb = null;
+ }
+ }
+
+ // Initializes the reverb listener looper
+ 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) {
+ mInitialized = false;
+ new ListenerThread(control, enable, parameter) {
+ @Override
+ public void run() {
+ // Set up a looper
+ Looper.prepare();
+
+ // Save the looper so that we can terminate this thread
+ // after we are done with it.
+ mLooper = Looper.myLooper();
+
+ mReverb2 = new EnvironmentalReverb(0, 0);
+ assertNotNull("could not create reverb2", mReverb2);
+
+ if (mControl) {
+ mReverb2.setControlStatusListener(
+ new AudioEffect.OnControlStatusChangeListener() {
+ public void onControlStatusChange(
+ AudioEffect effect, boolean controlGranted) {
+ synchronized(mLock) {
+ if (effect == mReverb2) {
+ mHasControl = controlGranted;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+ if (mEnable) {
+ mReverb2.setEnableStatusListener(
+ new AudioEffect.OnEnableStatusChangeListener() {
+ public void onEnableStatusChange(AudioEffect effect, boolean enabled) {
+ synchronized(mLock) {
+ if (effect == mReverb2) {
+ mIsEnabled = enabled;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+ if (mParameter) {
+ mReverb2.setParameterListener(new EnvironmentalReverb.OnParameterChangeListener() {
+ public void onParameterChange(EnvironmentalReverb effect,
+ int status, int param, int value)
+ {
+ synchronized(mLock) {
+ if (effect == mReverb2) {
+ mChangedParameter = param;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+
+ synchronized(mLock) {
+ mInitialized = true;
+ mLock.notify();
+ }
+ Looper.loop(); // Blocks forever until Looper.quit() is called.
+ }
+ }.start();
+ }
+
+ // Terminates the listener looper thread.
+ private void terminateListenerLooper() {
+ if (mReverb2 != null) {
+ mReverb2.release();
+ mReverb2 = null;
+ }
+ if (mLooper != null) {
+ mLooper.quit();
+ mLooper = null;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/tests/tests/media/src/android/media/cts/EqualizerTest.java b/tests/tests/media/src/android/media/cts/EqualizerTest.java
index cb21d47..967a281 100644
--- a/tests/tests/media/src/android/media/cts/EqualizerTest.java
+++ b/tests/tests/media/src/android/media/cts/EqualizerTest.java
@@ -49,13 +49,6 @@
private Looper mLooper = null;
private final Object mLock = new Object();
- private void log(String testName, String message) {
- Log.v(TAG, "[" + testName + "] " + message);
- }
-
- private void loge(String testName, String message) {
- Log.e(TAG, "[" + testName + "] " + message);
- }
//-----------------------------------------------------------------
// EQUALIZER TESTS:
@@ -73,39 +66,35 @@
args = {int.class, int.class}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getId",
- args = {}
+ level = TestLevel.COMPLETE,
+ method = "getId",
+ args = {}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "release",
- args = {}
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
)
})
public void test0_0ConstructorAndRelease() throws Exception {
- boolean result = false;
- String msg = "test1_0ConstructorAndRelease()";
Equalizer eq = null;
- try {
+ try {
eq = new Equalizer(0, 0);
- assertNotNull(msg + ": could not create Equalizer", eq);
+ assertNotNull("could not create Equalizer", eq);
try {
- assertTrue(msg +": invalid effect ID", (eq.getId() != 0));
+ assertTrue("invalid effect ID", (eq.getId() != 0));
} catch (IllegalStateException e) {
- msg = msg.concat(": Equalizer not initialized");
+ fail("Equalizer not initialized");
}
- result = true;
} catch (IllegalArgumentException e) {
- msg = msg.concat(": Equalizer not found");
+ fail("Equalizer not found");
} catch (UnsupportedOperationException e) {
- msg = msg.concat(": Effect library not loaded");
+ fail("Effect library not loaded");
} finally {
if (eq != null) {
eq.release();
}
}
- assertTrue(msg, result);
}
@@ -116,181 +105,161 @@
//Test case 1.0: test setBandLevel() and getBandLevel()
@TestTargets({
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getNumberOfBands",
- args = {}
+ level = TestLevel.COMPLETE,
+ method = "getNumberOfBands",
+ args = {}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getBandLevelRange",
- args = {}
+ level = TestLevel.COMPLETE,
+ method = "getBandLevelRange",
+ args = {}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "setBandLevel",
- args = {short.class, short.class}
+ level = TestLevel.COMPLETE,
+ method = "setBandLevel",
+ args = {short.class, short.class}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getBandLevel",
- args = {short.class}
+ level = TestLevel.COMPLETE,
+ method = "getBandLevel",
+ args = {short.class}
)
})
public void test1_0BandLevel() throws Exception {
- boolean result = false;
- String msg = "test1_0BandLevel()";
getEqualizer(0);
try {
short numBands = mEqualizer.getNumberOfBands();
- assertTrue(msg + ": not enough bands", numBands >= MIN_NUMBER_OF_BANDS);
+ assertTrue("not enough bands", numBands >= MIN_NUMBER_OF_BANDS);
short[] levelRange = mEqualizer.getBandLevelRange();
- assertTrue(msg + ": min level too high", levelRange[0] <= MAX_LEVEL_RANGE_LOW);
- assertTrue(msg + ": max level too low", levelRange[1] >= MIN_LEVEL_RANGE_HIGH);
+ assertTrue("min level too high", levelRange[0] <= MAX_LEVEL_RANGE_LOW);
+ assertTrue("max level too low", levelRange[1] >= MIN_LEVEL_RANGE_HIGH);
mEqualizer.setBandLevel((short)0, levelRange[1]);
short level = mEqualizer.getBandLevel((short)0);
// allow +/- TOLERANCE margin on actual level compared to requested level
- assertTrue(msg + ": setBandLevel failed",
+ assertTrue("setBandLevel failed",
(level >= (levelRange[1] - TOLERANCE)) &&
(level <= (levelRange[1] + TOLERANCE)));
- result = true;
+
} catch (IllegalArgumentException e) {
- msg = msg.concat(": Bad parameter value");
- loge(msg, "Bad parameter value");
+ fail("Bad parameter value");
} catch (UnsupportedOperationException e) {
- msg = msg.concat(": get parameter() rejected");
- loge(msg, "get parameter() rejected");
+ fail("get parameter() rejected");
} catch (IllegalStateException e) {
- msg = msg.concat("get parameter() called in wrong state");
- loge(msg, "get parameter() called in wrong state");
+ fail("get parameter() called in wrong state");
} finally {
releaseEqualizer();
}
- assertTrue(msg, result);
}
//Test case 1.1: test band frequency
@TestTargets({
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getBand",
- args = {int.class}
+ level = TestLevel.COMPLETE,
+ method = "getBand",
+ args = {int.class}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getBandFreqRange",
- args = {short.class}
+ level = TestLevel.COMPLETE,
+ method = "getBandFreqRange",
+ args = {short.class}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getCenterFreq",
- args = {short.class}
+ level = TestLevel.COMPLETE,
+ method = "getCenterFreq",
+ args = {short.class}
)
})
public void test1_1BandFrequency() throws Exception {
- boolean result = false;
- String msg = "test1_1BandFrequency()";
getEqualizer(0);
try {
short band = mEqualizer.getBand(TEST_FREQUENCY_MILLIHERTZ);
- assertTrue(msg + ": getBand failed", band >= 0);
+ assertTrue("getBand failed", band >= 0);
int[] freqRange = mEqualizer.getBandFreqRange(band);
- assertTrue(msg + ": getBandFreqRange failed",
+ assertTrue("getBandFreqRange failed",
(freqRange[0] <= TEST_FREQUENCY_MILLIHERTZ) &&
(freqRange[1] >= TEST_FREQUENCY_MILLIHERTZ));
int freq = mEqualizer.getCenterFreq(band);
- assertTrue(msg + ": getCenterFreq failed",
+ assertTrue("getCenterFreq failed",
(freqRange[0] <= freq) && (freqRange[1] >= freq));
- result = true;
+
} catch (IllegalArgumentException e) {
- msg = msg.concat(": Bad parameter value");
- loge(msg, "Bad parameter value");
+ fail("Bad parameter value");
} catch (UnsupportedOperationException e) {
- msg = msg.concat(": get parameter() rejected");
- loge(msg, "get parameter() rejected");
+ fail("get parameter() rejected");
} catch (IllegalStateException e) {
- msg = msg.concat("get parameter() called in wrong state");
- loge(msg, "get parameter() called in wrong state");
+ fail("get parameter() called in wrong state");
} finally {
releaseEqualizer();
}
- assertTrue(msg, result);
}
//Test case 1.2: test presets
@TestTargets({
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getNumberOfPresets",
- args = {}
+ level = TestLevel.COMPLETE,
+ method = "getNumberOfPresets",
+ args = {}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "usePreset",
- args = {short.class}
+ level = TestLevel.COMPLETE,
+ method = "usePreset",
+ args = {short.class}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getCurrentPreset",
- args = {}
+ level = TestLevel.COMPLETE,
+ method = "getCurrentPreset",
+ args = {}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getPresetName",
- args = {short.class}
+ level = TestLevel.COMPLETE,
+ method = "getPresetName",
+ args = {short.class}
)
})
public void test1_2Presets() throws Exception {
- boolean result = false;
- String msg = "test1_2Presets()";
getEqualizer(0);
try {
short numPresets = mEqualizer.getNumberOfPresets();
- assertTrue(msg + ": getNumberOfPresets failed", numPresets >= MIN_NUMBER_OF_PRESETS);
+ assertTrue("getNumberOfPresets failed", numPresets >= MIN_NUMBER_OF_PRESETS);
if (numPresets > 0) {
mEqualizer.usePreset((short)(numPresets - 1));
short preset = mEqualizer.getCurrentPreset();
- assertEquals(msg + ": usePreset failed", preset, (short)(numPresets - 1));
+ assertEquals("usePreset failed", preset, (short)(numPresets - 1));
String name = mEqualizer.getPresetName(preset);
- assertNotNull(msg + ": getPresetName failed", name);
+ assertNotNull("getPresetName failed", name);
}
- result = true;
+
} catch (IllegalArgumentException e) {
- msg = msg.concat(": Bad parameter value");
- loge(msg, "Bad parameter value");
+ fail("Bad parameter value");
} catch (UnsupportedOperationException e) {
- msg = msg.concat(": get parameter() rejected");
- loge(msg, "get parameter() rejected");
+ fail("get parameter() rejected");
} catch (IllegalStateException e) {
- msg = msg.concat("get parameter() called in wrong state");
- loge(msg, "get parameter() called in wrong state");
+ fail("get parameter() called in wrong state");
} finally {
releaseEqualizer();
}
- assertTrue(msg, result);
}
//Test case 1.3: test properties
@TestTargets({
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getProperties",
- args = {}
+ level = TestLevel.COMPLETE,
+ method = "getProperties",
+ args = {}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "setProperties",
- args = {Equalizer.Settings.class}
+ level = TestLevel.COMPLETE,
+ method = "setProperties",
+ args = {Equalizer.Settings.class}
)
})
public void test1_3Properties() throws Exception {
- boolean result = false;
- String msg = "test1_3Properties()";
getEqualizer(0);
try {
Equalizer.Settings settings = mEqualizer.getProperties();
- assertTrue(msg + ": no enough bands", settings.numBands >= MIN_NUMBER_OF_BANDS);
+ assertTrue("no enough bands", settings.numBands >= MIN_NUMBER_OF_BANDS);
short newLevel = 0;
if (settings.bandLevels[0] == 0) {
newLevel = -600;
@@ -301,54 +270,45 @@
settings.bandLevels[0] = newLevel;
mEqualizer.setProperties(settings);
settings = mEqualizer.getProperties();
- Log.e(TAG, "settings.bandLevels[0]: "+settings.bandLevels[0]+" newLevel: "+newLevel);
- assertTrue(msg + ": setProperties failed",
+ assertTrue("setProperties failed",
(settings.bandLevels[0] >= (newLevel - TOLERANCE)) &&
(settings.bandLevels[0] <= (newLevel + TOLERANCE)));
- result = true;
} catch (IllegalArgumentException e) {
- msg = msg.concat(": Bad parameter value");
- loge(msg, "Bad parameter value");
+ fail("Bad parameter value");
} catch (UnsupportedOperationException e) {
- msg = msg.concat(": get parameter() rejected");
- loge(msg, "get parameter() rejected");
+ fail("get parameter() rejected");
} catch (IllegalStateException e) {
- msg = msg.concat("get parameter() called in wrong state");
- loge(msg, "get parameter() called in wrong state");
+ fail("get parameter() called in wrong state");
} finally {
releaseEqualizer();
}
- assertTrue(msg, result);
}
//Test case 1.4: test setBandLevel() throws exception after release
@TestTargets({
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "release",
- args = {}
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "setBandLevel",
- args = {short.class, short.class}
+ level = TestLevel.COMPLETE,
+ method = "setBandLevel",
+ args = {short.class, short.class}
)
})
public void test1_4SetBandLevelAfterRelease() throws Exception {
- boolean result = false;
- String msg = "test1_4SetBandLevelAfterRelease()";
getEqualizer(0);
mEqualizer.release();
try {
mEqualizer.setBandLevel((short)0, (short)0);
} catch (IllegalStateException e) {
- result = true;
+ // test passed
} finally {
releaseEqualizer();
}
- assertTrue(msg+ ": no exception for setBandLevel() after release()", result);
}
//-----------------------------------------------------------------
@@ -358,62 +318,55 @@
//Test case 2.0: test setEnabled() and getEnabled() in valid state
@TestTargets({
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "setEnabled",
- args = {boolean.class}
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getEnabled",
- args = {}
+ level = TestLevel.COMPLETE,
+ method = "getEnabled",
+ args = {}
)
})
public void test2_0SetEnabledGetEnabled() throws Exception {
- boolean result = false;
- String msg = "test2_0SetEnabledGetEnabled()";
-
getEqualizer(0);
try {
mEqualizer.setEnabled(true);
- assertTrue(msg + ": invalid state from getEnabled", mEqualizer.getEnabled());
+ assertTrue("invalid state from getEnabled", mEqualizer.getEnabled());
mEqualizer.setEnabled(false);
- assertFalse(msg + ": invalid state to getEnabled", mEqualizer.getEnabled());
- result = true;
+ assertFalse("invalid state to getEnabled", mEqualizer.getEnabled());
+
} catch (IllegalStateException e) {
- msg = msg.concat(": setEnabled() in wrong state");
+ fail("setEnabled() in wrong state");
} finally {
releaseEqualizer();
}
- assertTrue(msg, result);
}
//Test case 2.1: test setEnabled() throws exception after release
@TestTargets({
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "release",
- args = {}
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "setEnabled",
- args = {boolean.class}
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
)
})
public void test2_1SetEnabledAfterRelease() throws Exception {
- boolean result = false;
- String msg = "test2_1SetEnabledAfterRelease()";
getEqualizer(0);
mEqualizer.release();
try {
mEqualizer.setEnabled(true);
} catch (IllegalStateException e) {
- result = true;
+ // test passed
} finally {
releaseEqualizer();
}
- assertTrue(msg+ ": no exception for setEnabled() after release()", result);
}
//-----------------------------------------------------------------
@@ -429,8 +382,6 @@
)
})
public void test3_0ControlStatusListener() throws Exception {
- boolean result = false;
- String msg = "test3_0ControlStatusListener()";
mHasControl = true;
createListenerLooper(true, false, false);
synchronized(mLock) {
@@ -452,9 +403,7 @@
terminateListenerLooper();
}
}
- assertFalse(msg + ": effect control not lost by effect1", mHasControl);
- result = true;
- assertTrue(msg, result);
+ assertFalse("effect control not lost by effect1", mHasControl);
}
//Test case 3.1: test enable status listener
@@ -466,8 +415,6 @@
)
})
public void test3_1EnableStatusListener() throws Exception {
- boolean result = false;
- String msg = "test3_1EnableStatusListener()";
createListenerLooper(false, true, false);
synchronized(mLock) {
try {
@@ -491,9 +438,7 @@
terminateListenerLooper();
}
}
- assertFalse(msg + ": enable status not updated", mIsEnabled);
- result = true;
- assertTrue(msg, result);
+ assertFalse("enable status not updated", mIsEnabled);
}
//Test case 3.2: test parameter changed listener
@@ -505,8 +450,6 @@
)
})
public void test3_2ParameterChangedListener() throws Exception {
- boolean result = false;
- String msg = "test3_2ParameterChangedListener()";
createListenerLooper(false, false, true);
synchronized(mLock) {
try {
@@ -529,10 +472,8 @@
terminateListenerLooper();
}
}
- assertEquals(msg + ": parameter change not received",
+ assertEquals("parameter change not received",
Equalizer.PARAM_BAND_LEVEL, mChangedParameter);
- result = true;
- assertTrue(msg, result);
}
//-----------------------------------------------------------------
@@ -579,7 +520,7 @@
}
private void createListenerLooper(boolean control, boolean enable, boolean parameter) {
-
+ mInitialized = false;
new ListenerThread(control, enable, parameter) {
@Override
public void run() {
diff --git a/tests/tests/media/src/android/media/cts/PresetReverbTest.java b/tests/tests/media/src/android/media/cts/PresetReverbTest.java
new file mode 100644
index 0000000..e29192b
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/PresetReverbTest.java
@@ -0,0 +1,452 @@
+/*
+ * 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 android.media.cts;
+
+import android.media.AudioEffect;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.PresetReverb;
+import android.os.Looper;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(PresetReverb.class)
+public class PresetReverbTest extends AndroidTestCase {
+
+ private String TAG = "PresetReverbTest";
+ private final static short FIRST_PRESET = PresetReverb.PRESET_NONE;
+ private final static short LAST_PRESET = PresetReverb.PRESET_PLATE;
+ private PresetReverb mReverb = null;
+ private PresetReverb mReverb2 = null;
+ private int mSession = -1;
+ private boolean mHasControl = false;
+ private boolean mIsEnabled = false;
+ private int mChangedParameter = -1;
+ private boolean mInitialized = false;
+ private Looper mLooper = null;
+ private final Object mLock = new Object();
+
+
+ //-----------------------------------------------------------------
+ // PRESET REVERB TESTS:
+ //----------------------------------
+
+ //-----------------------------------------------------------------
+ // 0 - constructor
+ //----------------------------------
+
+ //Test case 0.0: test constructor and release
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "PresetReverb",
+ args = {int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getId",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ )
+ })
+ public void test0_0ConstructorAndRelease() throws Exception {
+ PresetReverb reverb = null;
+ try {
+ reverb = new PresetReverb(0, 0);
+ assertNotNull("could not create PresetReverb", reverb);
+ try {
+ assertTrue("invalid effect ID", (reverb.getId() != 0));
+ } catch (IllegalStateException e) {
+ fail("PresetReverb not initialized");
+ }
+ } catch (IllegalArgumentException e) {
+ fail("PresetReverb not found");
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ } finally {
+ if (reverb != null) {
+ reverb.release();
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 1 - get/set parameters
+ //----------------------------------
+
+ //Test case 1.0: test presets
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setPreset",
+ args = {short.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getPreset",
+ args = {}
+ )
+ })
+ public void test1_0Presets() throws Exception {
+ getReverb(0);
+ try {
+ for (short preset = FIRST_PRESET;
+ preset <= LAST_PRESET;
+ preset++) {
+ mReverb.setPreset(preset);
+ assertEquals("got incorrect preset", preset, mReverb.getPreset());
+ }
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseReverb();
+ }
+ }
+
+ //Test case 1.1: test properties
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getProperties",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setProperties",
+ args = {PresetReverb.Settings.class}
+ )
+ })
+ public void test1_1Properties() throws Exception {
+ getReverb(0);
+ try {
+ PresetReverb.Settings settings = mReverb.getProperties();
+ String str = settings.toString();
+ settings = new PresetReverb.Settings(str);
+ short preset = (settings.preset == PresetReverb.PRESET_SMALLROOM) ?
+ PresetReverb.PRESET_MEDIUMROOM : PresetReverb.PRESET_SMALLROOM;
+ settings.preset = preset;
+ mReverb.setProperties(settings);
+ settings = mReverb.getProperties();
+ assertEquals("setProperties failed", settings.preset, preset);
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseReverb();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 2 - Effect enable/disable
+ //----------------------------------
+
+ //Test case 2.0: test setEnabled() and getEnabled() in valid state
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEnabled",
+ args = {}
+ )
+ })
+ public void test2_0SetEnabledGetEnabled() throws Exception {
+ getReverb(0);
+ try {
+ mReverb.setEnabled(true);
+ assertTrue("invalid state from getEnabled", mReverb.getEnabled());
+ mReverb.setEnabled(false);
+ assertFalse("invalid state to getEnabled", mReverb.getEnabled());
+ } catch (IllegalStateException e) {
+ fail("setEnabled() in wrong state");
+ } finally {
+ releaseReverb();
+ }
+ }
+
+ //Test case 2.1: test setEnabled() throws exception after release
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ )
+ })
+ public void test2_1SetEnabledAfterRelease() throws Exception {
+ getReverb(0);
+ mReverb.release();
+ try {
+ mReverb.setEnabled(true);
+ } catch (IllegalStateException e) {
+ // test passed
+ } finally {
+ releaseReverb();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 3 priority and listeners
+ //----------------------------------
+
+ //Test case 3.0: test control status listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setControlStatusListener",
+ args = {AudioEffect.OnControlStatusChangeListener.class}
+ )
+ })
+ public void test3_0ControlStatusListener() throws Exception {
+ mHasControl = true;
+ createListenerLooper(true, false, false);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ synchronized(mLock) {
+ try {
+ getReverb(0);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Create second effect: wait was interrupted.");
+ } finally {
+ releaseReverb();
+ terminateListenerLooper();
+ }
+ }
+ assertFalse("effect control not lost by effect1", mHasControl);
+ }
+
+ //Test case 3.1: test enable status listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnableStatusListener",
+ args = {AudioEffect.OnEnableStatusChangeListener.class}
+ )
+ })
+ public void test3_1EnableStatusListener() throws Exception {
+ createListenerLooper(false, true, false);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ mReverb2.setEnabled(true);
+ mIsEnabled = true;
+ getReverb(0);
+ synchronized(mLock) {
+ try {
+ mReverb.setEnabled(false);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Create second effect: wait was interrupted.");
+ } finally {
+ releaseReverb();
+ terminateListenerLooper();
+ }
+ }
+ assertFalse("enable status not updated", mIsEnabled);
+ }
+
+ //Test case 3.2: test parameter changed listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameterListener",
+ args = {PresetReverb.OnParameterChangeListener.class}
+ )
+ })
+ public void test3_2ParameterChangedListener() throws Exception {
+ createListenerLooper(false, false, true);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ getReverb(0);
+ synchronized(mLock) {
+ try {
+ mChangedParameter = -1;
+ mReverb.setPreset(PresetReverb.PRESET_SMALLROOM);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Create second effect: wait was interrupted.");
+ } finally {
+ releaseReverb();
+ terminateListenerLooper();
+ }
+ }
+ assertEquals("parameter change not received",
+ PresetReverb.PARAM_PRESET, mChangedParameter);
+ }
+
+ //-----------------------------------------------------------------
+ // private methods
+ //----------------------------------
+
+ private void getReverb(int session) {
+ if (mReverb == null || session != mSession) {
+ if (session != mSession && mReverb != null) {
+ mReverb.release();
+ mReverb = null;
+ }
+ try {
+ mReverb = new PresetReverb(0, session);
+ mSession = session;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "getReverb() PresetReverb not found exception: "+e);
+ } catch (UnsupportedOperationException e) {
+ Log.e(TAG, "getReverb() Effect library not loaded exception: "+e);
+ }
+ }
+ assertNotNull("could not create mReverb", mReverb);
+ }
+
+ private void releaseReverb() {
+ if (mReverb != null) {
+ mReverb.release();
+ mReverb = null;
+ }
+ }
+
+ // Initializes the reverb listener looper
+ 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) {
+ mInitialized = false;
+ new ListenerThread(control, enable, parameter) {
+ @Override
+ public void run() {
+ // Set up a looper
+ Looper.prepare();
+
+ // Save the looper so that we can terminate this thread
+ // after we are done with it.
+ mLooper = Looper.myLooper();
+
+ mReverb2 = new PresetReverb(0, 0);
+ assertNotNull("could not create Reverb2", mReverb2);
+
+ if (mControl) {
+ mReverb2.setControlStatusListener(
+ new AudioEffect.OnControlStatusChangeListener() {
+ public void onControlStatusChange(
+ AudioEffect effect, boolean controlGranted) {
+ synchronized(mLock) {
+ if (effect == mReverb2) {
+ mHasControl = controlGranted;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+ if (mEnable) {
+ mReverb2.setEnableStatusListener(
+ new AudioEffect.OnEnableStatusChangeListener() {
+ public void onEnableStatusChange(AudioEffect effect, boolean enabled) {
+ synchronized(mLock) {
+ if (effect == mReverb2) {
+ mIsEnabled = enabled;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+ if (mParameter) {
+ mReverb2.setParameterListener(new PresetReverb.OnParameterChangeListener() {
+ public void onParameterChange(PresetReverb effect,
+ int status, int param, short value)
+ {
+ synchronized(mLock) {
+ if (effect == mReverb2) {
+ mChangedParameter = param;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+
+ synchronized(mLock) {
+ mInitialized = true;
+ mLock.notify();
+ }
+ Looper.loop(); // Blocks forever until Looper.quit() is called.
+ }
+ }.start();
+ }
+
+ // Terminates the listener looper thread.
+ private void terminateListenerLooper() {
+ if (mReverb2 != null) {
+ mReverb2.release();
+ mReverb2 = null;
+ }
+ if (mLooper != null) {
+ mLooper.quit();
+ mLooper = null;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/tests/tests/media/src/android/media/cts/VirtualizerTest.java b/tests/tests/media/src/android/media/cts/VirtualizerTest.java
new file mode 100644
index 0000000..07f8894
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/VirtualizerTest.java
@@ -0,0 +1,500 @@
+/*
+ * 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 android.media.cts;
+
+import android.media.AudioEffect;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.Virtualizer;
+import android.os.Looper;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(Virtualizer.class)
+public class VirtualizerTest extends AndroidTestCase {
+
+ private String TAG = "VirtualizerTest";
+ private final static short TEST_STRENGTH = 500;
+ private final static short TEST_STRENGTH2 = 1000;
+ private final static float STRENGTH_TOLERANCE = 1.1f; // 10%
+
+ private Virtualizer mVirtualizer = null;
+ private Virtualizer mVirtualizer2 = null;
+ private int mSession = -1;
+ private boolean mHasControl = false;
+ private boolean mIsEnabled = false;
+ private int mChangedParameter = -1;
+ private boolean mInitialized = false;
+ private Looper mLooper = null;
+ private final Object mLock = new Object();
+
+ //-----------------------------------------------------------------
+ // VIRTUALIZER TESTS:
+ //----------------------------------
+
+ //-----------------------------------------------------------------
+ // 0 - constructor
+ //----------------------------------
+
+ //Test case 0.0: test constructor and release
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "Virtualizer",
+ args = {int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getId",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ )
+ })
+ public void test0_0ConstructorAndRelease() throws Exception {
+ Virtualizer eq = null;
+ try {
+ eq = new Virtualizer(0, 0);
+ assertNotNull(" could not create Virtualizer", eq);
+ try {
+ assertTrue(" invalid effect ID", (eq.getId() != 0));
+ } catch (IllegalStateException e) {
+ fail("Virtualizer not initialized");
+ }
+ } catch (IllegalArgumentException e) {
+ fail("Virtualizer not found");
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ } finally {
+ if (eq != null) {
+ eq.release();
+ }
+ }
+ }
+
+
+ //-----------------------------------------------------------------
+ // 1 - get/set parameters
+ //----------------------------------
+
+ //Test case 1.0: test strength
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getStrengthSupported",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setStrength",
+ args = {short.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getRoundedStrength",
+ args = {}
+ )
+ })
+ public void test1_0Strength() throws Exception {
+ getVirtualizer(0);
+ try {
+ if (mVirtualizer.getStrengthSupported()) {
+ short strength = mVirtualizer.getRoundedStrength();
+ strength = (strength == TEST_STRENGTH) ? TEST_STRENGTH2 : TEST_STRENGTH;
+ mVirtualizer.setStrength((short)strength);
+ short strength2 = mVirtualizer.getRoundedStrength();
+ // allow STRENGTH_TOLERANCE difference between set strength and rounded strength
+ assertTrue("got incorrect strength",
+ ((float)strength2 > (float)strength / STRENGTH_TOLERANCE) &&
+ ((float)strength2 < (float)strength * STRENGTH_TOLERANCE));
+ } else {
+ short strength = mVirtualizer.getRoundedStrength();
+ assertTrue("got incorrect strength", strength >= 0 && strength <= 1000);
+ }
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseVirtualizer();
+ }
+ }
+
+ //Test case 1.1: test properties
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getProperties",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setProperties",
+ args = {Virtualizer.Settings.class}
+ )
+ })
+ public void test1_1Properties() throws Exception {
+ getVirtualizer(0);
+ try {
+ Virtualizer.Settings settings = mVirtualizer.getProperties();
+ String str = settings.toString();
+ settings = new Virtualizer.Settings(str);
+
+ short strength = settings.strength;
+ if (mVirtualizer.getStrengthSupported()) {
+ strength = (strength == TEST_STRENGTH) ? TEST_STRENGTH2 : TEST_STRENGTH;
+ }
+ settings.strength = strength;
+ mVirtualizer.setProperties(settings);
+ settings = mVirtualizer.getProperties();
+
+ if (mVirtualizer.getStrengthSupported()) {
+ // allow STRENGTH_TOLERANCE difference between set strength and rounded strength
+ assertTrue("got incorrect strength",
+ ((float)settings.strength > (float)strength / STRENGTH_TOLERANCE) &&
+ ((float)settings.strength < (float)strength * STRENGTH_TOLERANCE));
+ }
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseVirtualizer();
+ }
+ }
+
+ //Test case 1.2: test setStrength() throws exception after release
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setStrength",
+ args = {short.class}
+ )
+ })
+ public void test1_2SetStrengthAfterRelease() throws Exception {
+ getVirtualizer(0);
+ mVirtualizer.release();
+ try {
+ mVirtualizer.setStrength(TEST_STRENGTH);
+ } catch (IllegalStateException e) {
+ // test passed
+ } finally {
+ releaseVirtualizer();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 2 - Effect enable/disable
+ //----------------------------------
+
+ //Test case 2.0: test setEnabled() and getEnabled() in valid state
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEnabled",
+ args = {}
+ )
+ })
+ public void test2_0SetEnabledGetEnabled() throws Exception {
+ getVirtualizer(0);
+ try {
+ mVirtualizer.setEnabled(true);
+ assertTrue(" invalid state from getEnabled", mVirtualizer.getEnabled());
+ mVirtualizer.setEnabled(false);
+ assertFalse(" invalid state to getEnabled", mVirtualizer.getEnabled());
+ } catch (IllegalStateException e) {
+ fail("setEnabled() in wrong state");
+ } finally {
+ releaseVirtualizer();
+ }
+ }
+
+ //Test case 2.1: test setEnabled() throws exception after release
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ )
+ })
+ public void test2_1SetEnabledAfterRelease() throws Exception {
+ getVirtualizer(0);
+ mVirtualizer.release();
+ try {
+ mVirtualizer.setEnabled(true);
+ } catch (IllegalStateException e) {
+ // test passed
+ } finally {
+ releaseVirtualizer();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 3 priority and listeners
+ //----------------------------------
+
+ //Test case 3.0: test control status listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setControlStatusListener",
+ args = {AudioEffect.OnControlStatusChangeListener.class}
+ )
+ })
+ public void test3_0ControlStatusListener() throws Exception {
+ mHasControl = true;
+ createListenerLooper(true, false, false);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ synchronized(mLock) {
+ try {
+ getVirtualizer(0);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Create second effect: wait was interrupted.");
+ } finally {
+ releaseVirtualizer();
+ terminateListenerLooper();
+ }
+ }
+ assertFalse("effect control not lost by effect1", mHasControl);
+ }
+
+ //Test case 3.1: test enable status listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnableStatusListener",
+ args = {AudioEffect.OnEnableStatusChangeListener.class}
+ )
+ })
+ public void test3_1EnableStatusListener() throws Exception {
+ createListenerLooper(false, true, false);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ mVirtualizer2.setEnabled(true);
+ mIsEnabled = true;
+ getVirtualizer(0);
+ synchronized(mLock) {
+ try {
+ mVirtualizer.setEnabled(false);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Create second effect: wait was interrupted.");
+ } finally {
+ releaseVirtualizer();
+ terminateListenerLooper();
+ }
+ }
+ assertFalse("enable status not updated", mIsEnabled);
+ }
+
+ //Test case 3.2: test parameter changed listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setParameterListener",
+ args = {Virtualizer.OnParameterChangeListener.class}
+ )
+ })
+ public void test3_2ParameterChangedListener() throws Exception {
+ createListenerLooper(false, false, true);
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+ getVirtualizer(0);
+ synchronized(mLock) {
+ try {
+ mChangedParameter = -1;
+ mVirtualizer.setStrength(TEST_STRENGTH);
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Create second effect: wait was interrupted.");
+ } finally {
+ releaseVirtualizer();
+ terminateListenerLooper();
+ }
+ }
+ assertEquals("parameter change not received",
+ Virtualizer.PARAM_STRENGTH, mChangedParameter);
+ }
+
+ //-----------------------------------------------------------------
+ // private methods
+ //----------------------------------
+
+ private void getVirtualizer(int session) {
+ if (mVirtualizer == null || session != mSession) {
+ if (session != mSession && mVirtualizer != null) {
+ mVirtualizer.release();
+ mVirtualizer = null;
+ }
+ try {
+ mVirtualizer = new Virtualizer(0, session);
+ mSession = session;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "getVirtualizer() Virtualizer not found exception: "+e);
+ } catch (UnsupportedOperationException e) {
+ Log.e(TAG, "getVirtualizer() Effect library not loaded exception: "+e);
+ }
+ }
+ assertNotNull("could not create mVirtualizer", mVirtualizer);
+ }
+
+ private void releaseVirtualizer() {
+ if (mVirtualizer != null) {
+ mVirtualizer.release();
+ mVirtualizer = null;
+ }
+ }
+
+ // Initializes the virtualizer listener looper
+ 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) {
+ mInitialized = false;
+ new ListenerThread(control, enable, parameter) {
+ @Override
+ public void run() {
+ // Set up a looper
+ Looper.prepare();
+
+ // Save the looper so that we can terminate this thread
+ // after we are done with it.
+ mLooper = Looper.myLooper();
+
+ mVirtualizer2 = new Virtualizer(0, 0);
+ assertNotNull("could not create virtualizer2", mVirtualizer2);
+
+ if (mControl) {
+ mVirtualizer2.setControlStatusListener(
+ new AudioEffect.OnControlStatusChangeListener() {
+ public void onControlStatusChange(
+ AudioEffect effect, boolean controlGranted) {
+ synchronized(mLock) {
+ if (effect == mVirtualizer2) {
+ mHasControl = controlGranted;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+ if (mEnable) {
+ mVirtualizer2.setEnableStatusListener(
+ new AudioEffect.OnEnableStatusChangeListener() {
+ public void onEnableStatusChange(AudioEffect effect, boolean enabled) {
+ synchronized(mLock) {
+ if (effect == mVirtualizer2) {
+ mIsEnabled = enabled;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+ if (mParameter) {
+ mVirtualizer2.setParameterListener(new Virtualizer.OnParameterChangeListener() {
+ public void onParameterChange(Virtualizer effect, int status,
+ int param, short value)
+ {
+ synchronized(mLock) {
+ if (effect == mVirtualizer2) {
+ mChangedParameter = param;
+ mLock.notify();
+ }
+ }
+ }
+ });
+ }
+
+ synchronized(mLock) {
+ mInitialized = true;
+ mLock.notify();
+ }
+ Looper.loop(); // Blocks forever until Looper.quit() is called.
+ }
+ }.start();
+ }
+
+ // Terminates the listener looper thread.
+ private void terminateListenerLooper() {
+ if (mVirtualizer2 != null) {
+ mVirtualizer2.release();
+ mVirtualizer2 = null;
+ }
+ if (mLooper != null) {
+ mLooper.quit();
+ mLooper = null;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/tests/tests/media/src/android/media/cts/VisualizerTest.java b/tests/tests/media/src/android/media/cts/VisualizerTest.java
new file mode 100644
index 0000000..d23be3f
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/VisualizerTest.java
@@ -0,0 +1,411 @@
+/*
+ * 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 android.media.cts;
+
+import android.media.AudioEffect;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.Visualizer;
+import android.os.Looper;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(Visualizer.class)
+public class VisualizerTest extends AndroidTestCase {
+
+ private String TAG = "VisualizerTest";
+ private final static int MIN_CAPTURE_RATE_MAX = 10000; // 10Hz
+ private final static int MIN_CAPTURE_SIZE_MAX = 1024;
+ private final static int MAX_CAPTURE_SIZE_MIN = 512;
+
+ private Visualizer mVisualizer = null;
+ private int mSession = -1;
+ private boolean mInitialized = false;
+ private Looper mLooper = null;
+ private final Object mLock = new Object();
+ private byte[] mWaveform = null;
+ private byte[] mFft = null;
+ private boolean mCaptureWaveform = false;
+ private boolean mCaptureFft = false;
+
+ //-----------------------------------------------------------------
+ // VISUALIZER TESTS:
+ //----------------------------------
+
+ //-----------------------------------------------------------------
+ // 0 - constructor
+ //----------------------------------
+
+ //Test case 0.0: test constructor and release
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "Visualizer",
+ args = {int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "release",
+ args = {}
+ )
+ })
+ public void test0_0ConstructorAndRelease() throws Exception {
+ Visualizer visualizer = null;
+ try {
+ visualizer = new Visualizer(0);
+ assertNotNull("could not create Visualizer", visualizer);
+ } catch (IllegalArgumentException e) {
+ fail("Visualizer not found");
+ } catch (UnsupportedOperationException e) {
+ fail("Effect library not loaded");
+ } finally {
+ if (visualizer != null) {
+ visualizer.release();
+ }
+ }
+ }
+
+
+ //-----------------------------------------------------------------
+ // 1 - get/set parameters
+ //----------------------------------
+
+ //Test case 1.0: capture rates
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getMaxCaptureRate",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getSamplingRate",
+ args = {}
+ )
+ })
+ public void test1_0CaptureRates() throws Exception {
+ getVisualizer(0);
+ try {
+ int captureRate = mVisualizer.getMaxCaptureRate();
+ assertTrue("insufficient max capture rate",
+ captureRate >= MIN_CAPTURE_RATE_MAX);
+ int samplingRate = mVisualizer.getSamplingRate();
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseVisualizer();
+ }
+ }
+
+ //Test case 1.1: test capture size
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getCaptureSizeRange",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setCaptureSize",
+ args = {int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getCaptureSize",
+ args = {}
+ )
+ })
+ public void test1_1CaptureSize() throws Exception {
+ getVisualizer(0);
+ try {
+ int[] range = mVisualizer.getCaptureSizeRange();
+ assertTrue("insufficient min capture size",
+ range[0] <= MAX_CAPTURE_SIZE_MIN);
+ assertTrue("insufficient min capture size",
+ range[1] >= MIN_CAPTURE_SIZE_MAX);
+ mVisualizer.setCaptureSize(range[0]);
+ assertEquals("insufficient min capture size",
+ range[0], mVisualizer.getCaptureSize());
+ mVisualizer.setCaptureSize(range[1]);
+ assertEquals("insufficient min capture size",
+ range[1], mVisualizer.getCaptureSize());
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } finally {
+ releaseVisualizer();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // 2 - check capture
+ //----------------------------------
+
+ //Test case 2.0: test cature in polling mode
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEnabled",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getWaveForm",
+ args = {byte[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getFft",
+ args = {byte[].class}
+ )
+ })
+ public void test2_0PollingCapture() throws Exception {
+ try {
+ getVisualizer(0);
+ mVisualizer.setEnabled(true);
+ assertTrue("visualizer not enabled", mVisualizer.getEnabled());
+ Thread.sleep(100);
+ // check capture on silence
+ byte[] data = new byte[mVisualizer.getCaptureSize()];
+ mVisualizer.getWaveForm(data);
+ int energy = computeEnergy(data, true);
+ assertEquals("getWaveForm reports energy for silence",
+ 0, energy);
+ mVisualizer.getFft(data);
+ energy = computeEnergy(data, false);
+ assertEquals("getFft reports energy for silence",
+ 0, energy);
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } catch (InterruptedException e) {
+ fail("sleep() interrupted");
+ }
+ finally {
+ releaseVisualizer();
+ }
+ }
+
+ //Test case 2.1: test capture with listener
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setEnabled",
+ args = {boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getEnabled",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setDataCaptureListener",
+ args = {Visualizer.OnDataCaptureListener.class,
+ int.class, boolean.class, boolean.class}
+ )
+ })
+ public void test2_1ListenerCapture() throws Exception {
+ try {
+ getVisualizer(0);
+ createListenerLooper();
+ synchronized(mLock) {
+ try {
+ mLock.wait(1000);
+ } catch(Exception e) {
+ Log.e(TAG, "Looper creation: wait was interrupted.");
+ }
+ }
+ assertTrue(mInitialized);
+
+ mVisualizer.setEnabled(true);
+ assertTrue("visualizer not enabled", mVisualizer.getEnabled());
+
+ Thread.sleep(100);
+ // check capture on silence
+ synchronized(mLock) {
+ try {
+ mCaptureWaveform = true;
+ mLock.wait(1000);
+ mCaptureWaveform = false;
+ } catch(Exception e) {
+ Log.e(TAG, "Capture waveform: wait was interrupted.");
+ }
+ }
+ assertNotNull("waveform capture failed", mWaveform);
+ int energy = computeEnergy(mWaveform, true);
+ assertEquals("getWaveForm reports energy for silence",
+ 0, energy);
+
+ synchronized(mLock) {
+ try {
+ mCaptureFft = true;
+ mLock.wait(1000);
+ mCaptureFft = false;
+ } catch(Exception e) {
+ Log.e(TAG, "Capture FFT: wait was interrupted.");
+ }
+ }
+ assertNotNull("FFT capture failed", mFft);
+ energy = computeEnergy(mFft, false);
+ assertEquals("getFft reports energy for silence",
+ 0, energy);
+
+ } catch (IllegalArgumentException e) {
+ fail("Bad parameter value");
+ } catch (UnsupportedOperationException e) {
+ fail("get parameter() rejected");
+ } catch (IllegalStateException e) {
+ fail("get parameter() called in wrong state");
+ } catch (InterruptedException e) {
+ fail("sleep() interrupted");
+ } finally {
+ terminateListenerLooper();
+ releaseVisualizer();
+ }
+ }
+
+ //-----------------------------------------------------------------
+ // private methods
+ //----------------------------------
+
+ private int computeEnergy(byte[] data, boolean pcm) {
+ int energy = 0;
+ if (data.length != 0) {
+ if (pcm) {
+ for (int i = 0; i < data.length; i++) {
+ int tmp = ((int)data[i] & 0xFF) - 128;
+ energy += tmp*tmp;
+ }
+ } else {
+ energy = (int)data[0] * (int)data[0];
+ for (int i = 2; i < data.length; i += 2) {
+ int real = (int)data[i];
+ int img = (int)data[i + 1];
+ energy += real * real + img * img;
+ }
+ }
+ }
+ return energy;
+ }
+
+ private void getVisualizer(int session) {
+ if (mVisualizer == null || session != mSession) {
+ if (session != mSession && mVisualizer != null) {
+ mVisualizer.release();
+ mVisualizer = null;
+ }
+ try {
+ mVisualizer = new Visualizer(session);
+ mSession = session;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "getVisualizer() Visualizer not found exception: "+e);
+ } catch (UnsupportedOperationException e) {
+ Log.e(TAG, "getVisualizer() Effect library not loaded exception: "+e);
+ }
+ }
+ assertNotNull("could not create mVisualizer", mVisualizer);
+ }
+
+ private void releaseVisualizer() {
+ if (mVisualizer != null) {
+ mVisualizer.release();
+ mVisualizer = null;
+ }
+ }
+
+ private void createListenerLooper() {
+
+ new Thread() {
+ @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();
+
+ if (mVisualizer != null) {
+ mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
+ public void onWaveFormDataCapture(
+ Visualizer visualizer, byte[] waveform, int samplingRate) {
+ synchronized(mLock) {
+ if (visualizer == mVisualizer) {
+ if (mCaptureWaveform) {
+ mWaveform = waveform;
+ mLock.notify();
+ }
+ }
+ }
+ }
+
+ public void onFftDataCapture(
+ Visualizer visualizer, byte[] fft, int samplingRate) {
+ synchronized(mLock) {
+ if (visualizer == mVisualizer) {
+ if (mCaptureFft) {
+ mFft = fft;
+ mLock.notify();
+ }
+ }
+ }
+ }
+ },
+ 10000,
+ true,
+ true);
+ }
+
+ synchronized(mLock) {
+ mInitialized = true;
+ mLock.notify();
+ }
+ Looper.loop(); // Blocks forever until Looper.quit() is called.
+ }
+ }.start();
+ }
+ /*
+ * Terminates the listener looper thread.
+ */
+ private void terminateListenerLooper() {
+ if (mLooper != null) {
+ mLooper.quit();
+ mLooper = null;
+ }
+ }
+}