/*
* Copyright (C) 2014 Haruki Hasegawa
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.h6ah4i.android.media.openslmediaplayer.classtest;
import com.h6ah4i.android.media.IBasicMediaPlayer;
import com.h6ah4i.android.media.IMediaPlayerFactory;
import com.h6ah4i.android.media.audiofx.IAudioEffect;
import com.h6ah4i.android.media.audiofx.IPreAmp;
import com.h6ah4i.android.media.openslmediaplayer.base.BasicMediaPlayerTestCaseBase;
import com.h6ah4i.android.media.openslmediaplayer.utils.CompletionListenerObject;
import com.h6ah4i.android.media.openslmediaplayer.utils.ErrorListenerObject;
import com.h6ah4i.android.media.openslmediaplayer.utils.SeekCompleteListenerObject;
import com.h6ah4i.android.media.openslmediaplayer.testing.ParameterizedTestArgs;
import com.h6ah4i.android.media.openslmediaplayer.testing.ParameterizedTestSuiteBuilder;
import junit.framework.TestSuite;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class PreAmpTestCase
extends BasicMediaPlayerTestCaseBase {
private static final class TestParams extends BasicTestParams {
private final PlayerState mPlayerState;
private final boolean mEnabled;
public TestParams(
Class<? extends IMediaPlayerFactory> factoryClass,
PlayerState playerState,
boolean enabled) {
super(factoryClass);
mPlayerState = playerState;
mEnabled = enabled;
}
public PlayerState getPlayerState() {
return mPlayerState;
}
public boolean getPreAmpEnabled() {
return mEnabled;
}
@Override
public String toString() {
return super.toString() + ", " + mPlayerState + ", " + mEnabled;
}
}
public static TestSuite buildTestSuite(
Class<? extends IMediaPlayerFactory> factoryClazz) {
TestSuite suite = new TestSuite();
String[] testsWithoutPreconditionPreAmpEnabled = new String[] {
"testDefaultParameters",
"testSetAndGetEnabled",
"testAfterRelease",
"testPlayerReleasedBeforeEffect",
"testHasControl",
"testMultiInstanceBehavior",
};
String[] testsJustUseBasicTestParams = new String[] {
"testPlayerStateTransition",
};
// use TestParam.getEualizerEnabled()
{
List<String> excludes = new ArrayList<String>();
excludes.addAll(Arrays.asList(testsWithoutPreconditionPreAmpEnabled));
excludes.addAll(Arrays.asList(testsJustUseBasicTestParams));
ParameterizedTestSuiteBuilder.Filter filter =
ParameterizedTestSuiteBuilder.notMatches(excludes);
List<TestParams> params = new ArrayList<TestParams>();
List<PlayerState> playerStates = new ArrayList<PlayerState>();
playerStates.addAll(Arrays.asList(PlayerState.values()));
playerStates.remove(PlayerState.End);
for (PlayerState playerState : playerStates) {
params.add(new TestParams(factoryClazz, playerState, false));
params.add(new TestParams(factoryClazz, playerState, true));
}
suite.addTest(ParameterizedTestSuiteBuilder.buildDetail(
PreAmpTestCase.class, params, filter, false));
}
// don't use TestParam.getEualizerEnabled()
{
ParameterizedTestSuiteBuilder.Filter filter =
ParameterizedTestSuiteBuilder.matches(
testsWithoutPreconditionPreAmpEnabled);
List<TestParams> params = new ArrayList<TestParams>();
List<PlayerState> playerStates = new ArrayList<PlayerState>();
playerStates.addAll(Arrays.asList(PlayerState.values()));
playerStates.remove(PlayerState.End);
for (PlayerState playerState : playerStates) {
params.add(new TestParams(factoryClazz, playerState, false));
}
suite.addTest(ParameterizedTestSuiteBuilder.buildDetail(
PreAmpTestCase.class, params, filter, false));
}
// not parameterized tests
for (String testName : testsJustUseBasicTestParams) {
suite.addTest(makeSingleBasicTest(
PreAmpTestCase.class, testName, factoryClazz));
}
return suite;
}
public PreAmpTestCase(ParameterizedTestArgs args) {
super(args);
}
private IPreAmp createPreAmp() {
return getFactory().createPreAmp();
}
//
// Exposed test cases
//
public void testDefaultParameters() throws Throwable {
TestParams params = (TestParams) getTestParams();
checkWithNoPlayerErrors(
params,
new BasicMediaPlayerTestRunnable() {
@Override
public void run(IBasicMediaPlayer player, Object args) throws Throwable {
checkDefaultParameters(player);
}
});
}
public void testSetAndGetEnabled() throws Throwable {
final TestParams params = (TestParams) getTestParams();
checkWithNoPlayerErrors(
params,
new BasicMediaPlayerTestRunnable() {
@Override
public void run(IBasicMediaPlayer player, Object args) throws Throwable {
checkSetAndGetEnabled(player, params);
}
});
}
public void testLevelParamWithValidRange() throws Throwable {
final TestParams params = (TestParams) getTestParams();
checkWithNoPlayerErrors(
params,
new BasicMediaPlayerTestRunnable() {
@Override
public void run(IBasicMediaPlayer player, Object args) throws Throwable {
checkLevelParamWithValidRange(player, params);
}
});
}
public void testLevelParamWithInvalidLevelRange() throws Throwable {
final TestParams params = (TestParams) getTestParams();
checkWithNoPlayerErrors(
params,
new BasicMediaPlayerTestRunnable() {
@Override
public void run(IBasicMediaPlayer player, Object args) throws Throwable {
checkLevelParamWithInvalidLevelRange(player, params);
}
});
}
public void testPropertiesWithValidLevels() throws Throwable {
final TestParams params = (TestParams) getTestParams();
checkWithNoPlayerErrors(
params,
new BasicMediaPlayerTestRunnable() {
@Override
public void run(IBasicMediaPlayer player, Object args) throws Throwable {
checkPropertiesWithValidLevels(player, params);
}
});
}
public void testPropertiesWithInvalidLevels() throws Throwable {
final TestParams params = (TestParams) getTestParams();
checkWithNoPlayerErrors(
params,
new BasicMediaPlayerTestRunnable() {
@Override
public void run(IBasicMediaPlayer player, Object args) throws Throwable {
checkPropertiesWithInvalidLevels(player, params);
}
});
}
public void testPropertiesCompatWithNullSettings() throws Throwable {
TestParams params = (TestParams) getTestParams();
checkWithNoPlayerErrors(
params,
new BasicMediaPlayerTestRunnable() {
@Override
public void run(IBasicMediaPlayer player, Object args) throws Throwable {
checkPropertiesCompatWithNullSettings(player);
}
});
}
public void testAfterRelease() throws Throwable {
final TestParams params = (TestParams) getTestParams();
checkWithNoPlayerErrors(
params,
new BasicMediaPlayerTestRunnable() {
@Override
public void run(IBasicMediaPlayer player, Object args) throws Throwable {
checkAfterRelease(player, params);
}
});
}
public void testHasControl() throws Throwable {
final TestParams params = (TestParams) getTestParams();
checkWithNoPlayerErrors(
params,
new BasicMediaPlayerTestRunnable() {
@Override
public void run(IBasicMediaPlayer player, Object args) throws Throwable {
checkHasControl(player, params);
}
});
}
public void testAfterControlLost() throws Throwable {
TestParams params = (TestParams) getTestParams();
checkWithNoPlayerErrors(
params,
new BasicMediaPlayerTestRunnable() {
@Override
public void run(IBasicMediaPlayer player, Object args) throws Throwable {
checkAfterControlLost(player);
}
});
}
public void testMultiInstanceBehavior() throws Throwable {
TestParams params = (TestParams) getTestParams();
checkWithNoPlayerErrors(
params,
new BasicMediaPlayerTestRunnable() {
@Override
public void run(IBasicMediaPlayer player, Object args) throws Throwable {
checkMultiInstanceBehavior(player);
}
});
}
public void testPlayerReleasedBeforeEffect() throws Throwable {
final TestParams params = (TestParams) getTestParams();
checkWithNoPlayerErrors(
params,
new BasicMediaPlayerTestRunnable() {
@Override
public void run(IBasicMediaPlayer player, Object args) throws Throwable {
checkPlayerReleasedBeforeEffect(player, params);
}
});
}
public void testPlayerStateTransition() throws Exception {
IBasicMediaPlayer player = null;
IPreAmp effect = null;
try {
// check effect settings are preserved along player state transition
Object waitObj = new Object();
CompletionListenerObject comp = new CompletionListenerObject(waitObj);
SeekCompleteListenerObject seekComp = new SeekCompleteListenerObject(waitObj);
player = createWrappedPlayerInstance();
effect = createPreAmp();
player.setOnCompletionListener(comp);
player.setOnSeekCompleteListener(seekComp);
// configure
assertEquals(IAudioEffect.SUCCESS, effect.setEnabled(true));
effect.setLevel(0.5f);
final IPreAmp.Settings expectedSettings = effect.getProperties();
// player: idle
// player: initialized
setDataSourceForCommonTests(player, null);
assertTrue(effect.getEnabled());
assertEquals(expectedSettings, effect.getProperties());
// player: prepared
player.prepare();
assertTrue(effect.getEnabled());
assertEquals(expectedSettings, effect.getProperties());
// player: started
player.start();
assertTrue(effect.getEnabled());
assertEquals(expectedSettings, effect.getProperties());
// player: paused
player.pause();
assertTrue(effect.getEnabled());
assertEquals(expectedSettings, effect.getProperties());
// player: playback completed
player.seekTo(player.getDuration());
if (!seekComp.await(DEFAULT_EVENT_WAIT_DURATION)) {
fail();
}
player.start();
if (!comp.await(SHORT_EVENT_WAIT_DURATION)) {
fail();
}
assertTrue(effect.getEnabled());
assertEquals(expectedSettings, effect.getProperties());
// player: stop
player.stop();
assertTrue(effect.getEnabled());
assertEquals(expectedSettings, effect.getProperties());
// player: idle
player.reset();
assertTrue(effect.getEnabled());
assertEquals(expectedSettings, effect.getProperties());
// player: end
player.release();
player = null;
assertTrue(effect.getEnabled());
assertEquals(expectedSettings, effect.getProperties());
} finally {
releaseQuietly(player);
releaseQuietly(effect);
}
}
//
// Implementations
//
private void checkSetAndGetEnabled(IBasicMediaPlayer player, TestParams params) {
IPreAmp effect = null;
try {
effect = createPreAmp();
assertEquals(false, effect.getEnabled());
effect.setEnabled(false);
assertEquals(false, effect.getEnabled());
effect.setEnabled(true);
assertEquals(true, effect.getEnabled());
} finally {
releaseQuietly(effect);
}
}
private void checkDefaultParameters(IBasicMediaPlayer player) {
IPreAmp effect = null;
try {
effect = createPreAmp();
// check
checkIsDefaultState(effect);
// modify parameters
effect.setEnabled(true);
effect.setLevel(0.5f);
// release
effect.release();
effect = null;
// re-confirm with new instance
effect = createPreAmp();
checkIsDefaultState(effect);
} finally {
releaseQuietly(effect);
}
}
private void checkLevelParamWithValidRange(
IBasicMediaPlayer player, TestParams params) {
IPreAmp effect = null;
try {
effect = createPreAmp();
effect.setEnabled(params.getPreAmpEnabled());
setAndCheckVaildLevel(effect);
} finally {
releaseQuietly(effect);
}
}
private void checkLevelParamWithInvalidLevelRange(
IBasicMediaPlayer player, TestParams params) {
IPreAmp effect = null;
try {
effect = createPreAmp();
effect.setEnabled(params.getPreAmpEnabled());
setAndCheckLevelWithInvalidLevel(effect);
} finally {
releaseQuietly(effect);
}
}
private void checkPropertiesWithValidLevels(
IBasicMediaPlayer player, TestParams params) {
IPreAmp effect = null;
try {
effect = createPreAmp();
effect.setEnabled(params.getPreAmpEnabled());
setAndCheckValidLevelsProperties(effect);
} finally {
releaseQuietly(effect);
}
}
private void checkPropertiesWithInvalidLevels(
IBasicMediaPlayer player, TestParams params) {
IPreAmp effect = null;
try {
effect = createPreAmp();
effect.setEnabled(params.getPreAmpEnabled());
setAndCheckInvalidLevelsProperties(effect);
} finally {
releaseQuietly(effect);
}
}
private void checkPropertiesCompatWithNullSettings(IBasicMediaPlayer player) {
IPreAmp effect = null;
try {
effect = createPreAmp();
try {
effect.setProperties(null);
fail();
} catch (IllegalArgumentException e) {
// expected
}
} finally {
releaseQuietly(effect);
}
}
private void checkAfterRelease(IBasicMediaPlayer player, TestParams params) {
try {
createReleasedPreAmp(player).getId();
fail();
} catch (IllegalStateException e) {
// expected
}
try {
createReleasedPreAmp(player).getEnabled();
fail();
} catch (IllegalStateException e) {
// expected
}
try {
createReleasedPreAmp(player).hasControl();
fail();
} catch (IllegalStateException e) {
// expected
}
try {
createReleasedPreAmp(player).setEnabled(true);
fail();
} catch (IllegalStateException e) {
// expected
}
try {
createReleasedPreAmp(player).setEnabled(false);
fail();
} catch (IllegalStateException e) {
// expected
}
try {
createReleasedPreAmp(player).getLevel();
fail();
} catch (IllegalStateException e) {
// expected
}
try {
createReleasedPreAmp(player).getProperties();
fail();
} catch (IllegalStateException e) {
// expected
}
try {
IPreAmp preamp = createPreAmp();
IPreAmp.Settings settings = new IPreAmp.Settings();
preamp.release();
createReleasedPreAmp(player).setProperties(settings);
fail();
} catch (IllegalStateException e) {
// expected
}
}
private void checkHasControl(IBasicMediaPlayer player, TestParams params) {
IPreAmp effect1 = null, effect2 = null, effect3 = null;
try {
// create instance 1
// NOTE: [1]: has control, [2] not created, [3] not created
effect1 = createPreAmp();
assertTrue(effect1.hasControl());
// create instance 2
// NOTE: [1]: lost control, [2] has control, [3] not created
effect2 = createPreAmp();
assertFalse(effect1.hasControl());
assertTrue(effect2.hasControl());
assertEquals(
IAudioEffect.ERROR_INVALID_OPERATION,
effect1.setEnabled(false));
assertEquals(
IAudioEffect.ERROR_INVALID_OPERATION,
effect1.setEnabled(true));
assertEquals(
IAudioEffect.SUCCESS,
effect2.setEnabled(true));
assertEquals(
IAudioEffect.SUCCESS,
effect2.setEnabled(false));
// create instance 3
// NOTE: [1]: lost control, [2] lost control, [3] has control
effect3 = createPreAmp();
assertFalse(effect1.hasControl());
assertFalse(effect2.hasControl());
assertTrue(effect3.hasControl());
assertEquals(
IAudioEffect.ERROR_INVALID_OPERATION,
effect1.setEnabled(true));
assertEquals(
IAudioEffect.ERROR_INVALID_OPERATION,
effect2.setEnabled(true));
assertEquals(
IAudioEffect.SUCCESS,
effect3.setEnabled(true));
assertEquals(
IAudioEffect.SUCCESS,
effect3.setEnabled(false));
// release the instance 3
// NOTE: [1]: lost control, [2] has control, [3] released
effect3.release();
effect3 = null;
assertFalse(effect1.hasControl());
assertTrue(effect2.hasControl());
assertEquals(
IAudioEffect.ERROR_INVALID_OPERATION,
effect1.setEnabled(true));
assertEquals(
IAudioEffect.SUCCESS,
effect2.setEnabled(true));
assertEquals(
IAudioEffect.SUCCESS,
effect2.setEnabled(false));
// release the instance 2
// NOTE: [1]: has control, [2] released, [3] released
effect2.release();
effect2 = null;
assertTrue(effect1.hasControl());
assertEquals(
IAudioEffect.SUCCESS,
effect1.setEnabled(true));
assertEquals(
IAudioEffect.SUCCESS,
effect1.setEnabled(false));
} finally {
releaseQuietly(effect1);
effect1 = null;
releaseQuietly(effect2);
effect2 = null;
releaseQuietly(effect3);
effect3 = null;
}
}
private void checkAfterControlLost(IBasicMediaPlayer player) {
IPreAmp effect1 = null, effect2 = null;
try {
effect1 = createPreAmp();
effect2 = createPreAmp();
final boolean initialEnabledState = effect2.getEnabled();
final IPreAmp.Settings initialSettings = effect2.getProperties();
assertFalse(effect1.hasControl());
assertTrue(effect2.hasControl());
// no state changing methods should not raise any errors
assertEquals(effect2.getEnabled(), effect1.getEnabled());
assertEquals(effect2.getId(), effect1.getId());
assertEquals(effect2.getLevel(), effect1.getLevel());
assertEquals(effect2.getProperties(), effect1.getProperties());
// setEnabled() should return IAudioEffect.ERROR_INVALID_OPERATION
assertEquals(IAudioEffect.ERROR_INVALID_OPERATION, effect1.setEnabled(false));
assertEquals(IAudioEffect.ERROR_INVALID_OPERATION, effect1.setEnabled(true));
// state changing methods should raise UnsupportedOperationException
try {
effect1.setLevel(0.5f);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
try {
IPreAmp.Settings settings = new IPreAmp.Settings();
settings.level = 0.5f;
effect1.setProperties(settings);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
// confirm object state
assertEquals(initialEnabledState, effect1.getEnabled());
assertEquals(initialSettings, effect1.getProperties());
} finally {
releaseQuietly(effect1);
effect1 = null;
releaseQuietly(effect2);
effect2 = null;
}
}
private void checkMultiInstanceBehavior(IBasicMediaPlayer player) {
IPreAmp effect1 = null, effect2 = null;
try {
effect1 = createPreAmp();
effect2 = createPreAmp();
// check pre. conditions
assertFalse(effect1.hasControl());
assertTrue(effect2.hasControl());
assertFalse(effect1.getEnabled());
assertFalse(effect2.getEnabled());
assertEquals(1.0f, effect1.getLevel());
assertEquals(1.0f, effect2.getLevel());
effect2.setLevel(0.25f);
IPreAmp.Settings expectedSettings = effect2.getProperties();
// check effect 1 lost controls
assertEquals(IAudioEffect.ERROR_INVALID_OPERATION, effect1.setEnabled(false));
try {
effect1.setLevel(0.5f);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
assertNotEquals(expectedSettings.level, 0.5f);
assertEquals(expectedSettings.level, effect1.getLevel());
try {
IPreAmp.Settings settings = new IPreAmp.Settings();
settings.level = 0.5f;
effect1.setProperties(settings);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
assertEquals(expectedSettings, effect1.getProperties());
// change states
assertEquals(IAudioEffect.SUCCESS, effect2.setEnabled(true));
// check post conditions
assertFalse(effect1.hasControl());
assertTrue(effect2.hasControl());
assertTrue(effect1.getEnabled());
assertTrue(effect2.getEnabled());
assertEquals(expectedSettings, effect1.getProperties());
assertEquals(expectedSettings, effect2.getProperties());
// release effect 2
effect2.release();
effect2 = null;
// check effect 1 gains control
assertTrue(effect1.hasControl());
assertEquals(IAudioEffect.SUCCESS, effect1.setEnabled(false));
} finally {
releaseQuietly(effect1);
releaseQuietly(effect2);
}
}
private void checkPlayerReleasedBeforeEffect(IBasicMediaPlayer player, TestParams params) {
IPreAmp effect = null;
try {
effect = createPreAmp();
// pre. check
assertTrue(effect.hasControl());
assertEquals(IAudioEffect.SUCCESS, effect.setEnabled(true));
// release player
player.release();
player = null;
// post check
assertTrue(effect.hasControl());
assertEquals(true, effect.getEnabled());
// Prepared, ErrorBeforePrepared or ErrorAfterPrepared state.
assertEquals(IAudioEffect.SUCCESS, effect.setEnabled(false));
// release effect
effect.release();
effect = null;
} finally {
releaseQuietly(effect);
effect = null;
}
}
private void setAndCheckVaildLevel(IPreAmp preamp) {
final float[] TEST_VALUES = {
-0.0f, +0.0f, 0.5f, 1.5f, 2.0f
};
for (float v : TEST_VALUES) {
preamp.setLevel(v);
assertEquals(v, preamp.getLevel());
}
}
private void setAndCheckLevelWithInvalidLevel(IPreAmp preamp) {
final float[] TEST_VALUES = {
-0.1f, 2.1f,
Float.MAX_VALUE,
Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY,
Float.NaN
};
for (float v : TEST_VALUES) {
final float prevLevel = preamp.getLevel();
try {
preamp.setLevel(v);
fail();
} catch (IllegalArgumentException e) {
// expected
}
assertEquals(prevLevel, preamp.getLevel());
}
}
private void setAndCheckValidLevelsProperties(IPreAmp preamp) {
final float[] TEST_VALUES = {
-0.0f, +0.0f, 0.5f, 1.5f, 2.0f
};
for (float v : TEST_VALUES) {
final IPreAmp.Settings settings = preamp.getProperties();
settings.level = v;
preamp.setProperties(settings);
assertEquals(settings, preamp.getProperties());
}
}
private void setAndCheckInvalidLevelsProperties(IPreAmp preamp) {
final float[] TEST_VALUES = {
-0.1f, 2.1f,
Float.MAX_VALUE,
Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY,
Float.NaN
};
for (float v : TEST_VALUES) {
final IPreAmp.Settings prevSettings = preamp.getProperties();
final IPreAmp.Settings settings = prevSettings.clone();
try {
settings.level = v;
preamp.setProperties(settings);
fail();
} catch (IllegalArgumentException e) {
// expected
}
assertEquals(prevSettings, preamp.getProperties());
}
}
//
// Utilities
//
private static void assertEquals(IPreAmp.Settings expected, IPreAmp.Settings actual) {
assertEquals(expected.toString(), actual.toString());
}
private IPreAmp createReleasedPreAmp(IBasicMediaPlayer player) {
IPreAmp preamp = createPreAmp();
preamp.release();
return preamp;
}
private static interface BasicMediaPlayerTestRunnable {
public void run(IBasicMediaPlayer player, Object args) throws Throwable;
}
private void checkWithNoPlayerErrors(
TestParams params, BasicMediaPlayerTestRunnable checkProcess) throws Throwable {
IBasicMediaPlayer player = null;
try {
player = createWrappedPlayerInstance();
transitState(params.getPlayerState(), player, null);
Object sharedSyncObj = new Object();
ErrorListenerObject err = new ErrorListenerObject(sharedSyncObj, false);
// set callbacks
player.setOnErrorListener(err);
// check
checkProcess.run(unwrap(player), null);
// expects no errors
assertFalse(err.occurred());
} finally {
releaseQuietly(player);
}
}
private void checkIsDefaultState(IPreAmp effect) {
assertEquals(false, effect.getEnabled());
assertEquals(1.0f, effect.getLevel());
}
}