/*
* 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.methodtest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestSuite;
import android.os.Build;
import android.util.Log;
import com.h6ah4i.android.media.IBasicMediaPlayer;
import com.h6ah4i.android.media.IMediaPlayerFactory;
import com.h6ah4i.android.media.openslmediaplayer.base.BasicMediaPlayerStateTestCaseBase;
import com.h6ah4i.android.media.openslmediaplayer.base.TestBasicMediaPlayerWrapper;
import com.h6ah4i.android.media.openslmediaplayer.utils.CompletionListenerObject;
import com.h6ah4i.android.media.openslmediaplayer.utils.ErrorListenerObject;
import com.h6ah4i.android.media.openslmediaplayer.utils.MockBasicMediaPlayer;
import com.h6ah4i.android.media.openslmediaplayer.utils.SeekCompleteListenerObject;
import com.h6ah4i.android.media.openslmediaplayer.testing.ParameterizedTestArgs;
import com.h6ah4i.android.media.openslmediaplayer.testing.ParameterizedTestSuiteBuilder;
public class BasicMediaPlayerTestCase_SetNextMediaPlayerMethod extends
BasicMediaPlayerStateTestCaseBase {
private static final boolean SKIP_HANGUP_SUSPECTED_TEST_CASE =
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH);
public static TestSuite buildTestSuite(
Class<? extends IMediaPlayerFactory> factoryClazz) {
TestSuite suite = new TestSuite();
String[] testsWithBasicTestParams = new String[] {
"testCallbacksOnNextPlayerStart",
"testIsPlayingTransition",
"testSeekToBeforeAttachedAsNextMediaPlayer",
"testSeekToAfterAttachedAsNextMediaPlayer",
"testPlayingStateAsNextMediaPlayer",
"testReinitializeNextMediaPlayer",
"testSetNextMediaPlayerAfterCompletion",
"testPausedStateAsNextMediaPlayer",
"testMultipleSetNextAudioPlayer_1",
"testMultipleSetNextAudioPlayer_2",
};
{
List<TestParams> params = new ArrayList<TestParams>();
for (NextPlayerType nextPlayerType : NextPlayerType.values()) {
params.add(new TestParams(factoryClazz, nextPlayerType));
}
suite.addTest(ParameterizedTestSuiteBuilder
.buildDetail(BasicMediaPlayerTestCase_SetNextMediaPlayerMethod.class,
params,
ParameterizedTestSuiteBuilder.notMatches(testsWithBasicTestParams),
true));
}
{
ParameterizedTestSuiteBuilder.Filter filter =
ParameterizedTestSuiteBuilder.matches(testsWithBasicTestParams);
List<BasicTestParams> params = new ArrayList<BasicTestParams>();
params.add(new BasicTestParams(factoryClazz));
suite.addTest(ParameterizedTestSuiteBuilder.buildDetail(
BasicMediaPlayerTestCase_SetNextMediaPlayerMethod.class,
params, filter, true));
}
return suite;
}
enum NextPlayerType {
NULL, THIS, MOCK_CLASS, IDLE, INITIALIZED, PREPARING, PREPARED, STARTED, PAUSED, STOPPED, PLAYBACK_COMPLETED, ERROR_BEFORE_PREPARED, ERROR_AFTER_PREPARED, END
}
private static final class TestParams extends BasicTestParams {
private final NextPlayerType mNextPlayerType;
public TestParams(Class<? extends IMediaPlayerFactory> factoryClass,
NextPlayerType nextPlayerType) {
super(factoryClass);
mNextPlayerType = nextPlayerType;
}
public NextPlayerType getNextPlayerType() {
return mNextPlayerType;
}
@Override
public String toString() {
return super.toString() + ", " + mNextPlayerType.name();
}
}
public BasicMediaPlayerTestCase_SetNextMediaPlayerMethod(
ParameterizedTestArgs args) {
super(args);
}
private void expectsNoErrors(IBasicMediaPlayer player,
IBasicMediaPlayer next, NextPlayerType type) throws IOException {
final String failmsg = "NextPlayerType = " + type;
Object sharedSyncObj = new Object();
ErrorListenerObject err = new ErrorListenerObject(sharedSyncObj, false);
CompletionListenerObject comp = new CompletionListenerObject(
sharedSyncObj);
// check no errors
player.setOnErrorListener(err);
player.setOnCompletionListener(comp);
setUnwrappedtNextPlayer(player, next);
if (comp.await(SHORT_EVENT_WAIT_DURATION)) {
fail(failmsg + ", " + comp + ", " + err);
}
assertFalse(failmsg, comp.occurred());
assertFalse(failmsg, err.occurred());
}
private void expectsIllegalArgumentException(IBasicMediaPlayer player,
IBasicMediaPlayer next, NextPlayerType type) {
final String failmsg = "NextPlayerType = " + type;
try {
setUnwrappedtNextPlayer(player, next);
} catch (IllegalArgumentException e) {
// expected
return;
}
fail(failmsg);
}
private void expectsIllegalStateException(IBasicMediaPlayer player,
IBasicMediaPlayer next, NextPlayerType type) {
final String failmsg = "NextPlayerType = " + type;
try {
setUnwrappedtNextPlayer(player, next);
} catch (IllegalStateException e) {
// expected
return;
}
fail(failmsg);
}
private void setUnwrappedtNextPlayer(IBasicMediaPlayer player,
IBasicMediaPlayer next) {
player.setNextMediaPlayer(unwrap(next));
}
private IBasicMediaPlayer createNextPlayer(IBasicMediaPlayer player,
NextPlayerType type) throws IOException {
switch (type) {
case NULL:
return null;
case THIS:
return ((TestBasicMediaPlayerWrapper) player).getWrappedInstance();
case MOCK_CLASS:
return new MockBasicMediaPlayer();
case IDLE: {
TestBasicMediaPlayerWrapper wrapper = createWrappedPlayerInstance();
transitStateToIdle(wrapper, null);
return wrapper;
}
case INITIALIZED: {
TestBasicMediaPlayerWrapper wrapper = createWrappedPlayerInstance();
transitStateToInitialized(wrapper, null);
return wrapper;
}
case PREPARING: {
TestBasicMediaPlayerWrapper wrapper = createWrappedPlayerInstance();
transitStateToPreparing(wrapper, null);
return wrapper;
}
case PREPARED: {
TestBasicMediaPlayerWrapper wrapper = createWrappedPlayerInstance();
transitStateToPrepared(wrapper, null);
return wrapper;
}
case STARTED: {
TestBasicMediaPlayerWrapper wrapper = createWrappedPlayerInstance();
transitStateToStarted(wrapper, null);
return wrapper;
}
case PAUSED: {
TestBasicMediaPlayerWrapper wrapper = createWrappedPlayerInstance();
transitStateToPaused(wrapper, null);
return wrapper;
}
case STOPPED: {
TestBasicMediaPlayerWrapper wrapper = createWrappedPlayerInstance();
transitStateToStopped(wrapper, null);
return wrapper;
}
case PLAYBACK_COMPLETED: {
TestBasicMediaPlayerWrapper wrapper = createWrappedPlayerInstance();
transitStateToPlaybackCompleted(wrapper, null);
return wrapper;
}
case ERROR_BEFORE_PREPARED: {
TestBasicMediaPlayerWrapper wrapper = createWrappedPlayerInstance();
transitStateToErrorBeforePrepared(wrapper, null);
return wrapper;
}
case ERROR_AFTER_PREPARED: {
TestBasicMediaPlayerWrapper wrapper = createWrappedPlayerInstance();
transitStateToErrorAfterPrepared(wrapper, null);
return wrapper;
}
case END: {
TestBasicMediaPlayerWrapper wrapper = createWrappedPlayerInstance();
transitStateToEnd(wrapper, null);
return wrapper;
}
default:
throw new IllegalArgumentException();
}
}
private void checkValidState(IBasicMediaPlayer player, Object args)
throws IOException {
TestParams params = (TestParams) args;
NextPlayerType type = params.getNextPlayerType();
IBasicMediaPlayer next = createNextPlayer(player, type);
try {
switch (type) {
case THIS:
case MOCK_CLASS:
expectsIllegalArgumentException(player, next, type);
break;
case NULL:
case PREPARED:
case PAUSED:
case PLAYBACK_COMPLETED:
expectsNoErrors(player, next, type);
break;
case IDLE:
case INITIALIZED:
case PREPARING:
case STARTED:
case STOPPED:
case ERROR_BEFORE_PREPARED:
case ERROR_AFTER_PREPARED:
case END:
expectsIllegalStateException(player, next, type);
break;
default:
fail();
break;
}
} finally {
releaseQuietly(next);
}
}
private void checkInvalidState(IBasicMediaPlayer player, Object args)
throws IOException {
TestParams params = (TestParams) args;
NextPlayerType type = params.getNextPlayerType();
IBasicMediaPlayer next = createNextPlayer(player, type);
try {
switch (type) {
case THIS:
case MOCK_CLASS:
expectsIllegalArgumentException(player, next, type);
break;
default:
expectsIllegalStateException(player, next, type);
break;
}
} finally {
releaseQuietly(next);
}
}
private void checkEndState(IBasicMediaPlayer player, Object args)
throws IOException {
TestParams params = (TestParams) args;
NextPlayerType type = params.getNextPlayerType();
IBasicMediaPlayer next = createNextPlayer(player, type);
try {
expectsIllegalStateException(player, next, type);
} finally {
releaseQuietly(next);
}
}
@Override
protected void onTestStateIdle(IBasicMediaPlayer player, Object args)
throws Throwable {
checkInvalidState(player, args);
}
@Override
protected void onTestStateInitialized(IBasicMediaPlayer player, Object args)
throws Throwable {
checkValidState(player, args);
}
@Override
protected void onTestStatePreparing(IBasicMediaPlayer player, Object args)
throws Throwable {
checkValidState(player, args);
}
@Override
protected void onTestStatePrepared(IBasicMediaPlayer player, Object args)
throws Throwable {
checkValidState(player, args);
}
@Override
protected void onTestStateStarted(IBasicMediaPlayer player, Object args)
throws Throwable {
checkValidState(player, args);
}
@Override
protected void onTestStatePaused(IBasicMediaPlayer player, Object args)
throws Throwable {
checkValidState(player, args);
}
@Override
protected void onTestStateStopped(IBasicMediaPlayer player, Object args)
throws Throwable {
checkValidState(player, args);
}
@Override
protected void onTestStatePlaybackCompleted(IBasicMediaPlayer player,
Object args) throws Throwable {
checkValidState(player, args);
}
@Override
protected void onTestStateErrorBeforePrepared(IBasicMediaPlayer player,
Object args) throws Throwable {
checkInvalidState(player, args);
}
@Override
protected void onTestStateErrorAfterPrepared(IBasicMediaPlayer player,
Object args) throws Throwable {
checkInvalidState(player, args);
}
@Override
protected void onTestStateEnd(IBasicMediaPlayer player, Object args)
throws Throwable {
checkEndState(player, args);
}
public void testCallbacksOnNextPlayerStart() throws Throwable {
IBasicMediaPlayer player = createWrappedPlayerInstance();
IBasicMediaPlayer nextPlayer = null;
Object args = getTestParams();
try {
Object syncObj1 = new Object();
CompletionListenerObject comp1 = new CompletionListenerObject(syncObj1);
SeekCompleteListenerObject seek1 = new SeekCompleteListenerObject(syncObj1);
ErrorListenerObject error1 = new ErrorListenerObject(syncObj1, false);
Object syncObj2 = new Object();
CompletionListenerObject comp2 = new CompletionListenerObject(syncObj2);
SeekCompleteListenerObject seek2 = new SeekCompleteListenerObject(syncObj2);
ErrorListenerObject error2 = new ErrorListenerObject(syncObj2, false);
// prepare
transitStateToPrepared(player, args);
nextPlayer = createNextPlayer(player, NextPlayerType.PREPARED);
setUnwrappedtNextPlayer(player, nextPlayer);
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// set listener objects
player.setOnCompletionListener(comp1);
player.setOnSeekCompleteListener(seek1);
player.setOnErrorListener(error1);
nextPlayer.setOnCompletionListener(comp2);
nextPlayer.setOnSeekCompleteListener(seek2);
nextPlayer.setOnErrorListener(error2);
// start
player.start();
assertTrue(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
Thread.sleep(SHORT_EVENT_WAIT_DURATION);
assertTrue(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// wait for the next player started
int duration1 = player.getDuration();
Thread.sleep(duration1);
assertFalse(player.isPlaying());
assertTrue(nextPlayer.isPlaying());
// check listener objects
assertTrue(comp1.occurred());
assertFalse(seek1.occurred());
assertFalse(error1.occurred());
// wait for the next player completion
int duration2 = nextPlayer.getDuration();
Thread.sleep(duration2 + SHORT_EVENT_WAIT_DURATION);
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// check listener objects
assertTrue(comp2.occurred());
assertFalse(seek2.occurred());
assertFalse(error2.occurred());
} finally {
releaseQuietly(nextPlayer);
releaseQuietly(player);
}
}
public void testIsPlayingTransition() throws Throwable {
IBasicMediaPlayer player = createWrappedPlayerInstance();
IBasicMediaPlayer nextPlayer = null;
Object args = getTestParams();
try {
// prepare
transitStateToPrepared(player, args);
nextPlayer = createNextPlayer(player, NextPlayerType.PREPARED);
setUnwrappedtNextPlayer(player, nextPlayer);
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// start
player.start();
assertTrue(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
Thread.sleep(SHORT_EVENT_WAIT_DURATION);
assertTrue(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// wait for the next player started
int duration1 = player.getDuration();
Thread.sleep(duration1);
assertFalse(player.isPlaying());
assertTrue(nextPlayer.isPlaying());
// wait for the next player completion
int duration2 = nextPlayer.getDuration();
Thread.sleep(duration2 + SHORT_EVENT_WAIT_DURATION);
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
} finally {
releaseQuietly(nextPlayer);
releaseQuietly(player);
}
}
// NOTE: This test case may fails with StandardMediaPlayer (affects: ICS to JB, Lollipop with NuPlayer)
public void testSeekToBeforeAttachedAsNextMediaPlayer() throws Throwable {
IBasicMediaPlayer player = createWrappedPlayerInstance();
IBasicMediaPlayer nextPlayer = null;
Object args = getTestParams();
// NOTE:
// seekTo() call will be ignored if the player is attached as a next
// player.
try {
SeekCompleteListenerObject seekComp = new SeekCompleteListenerObject();
// prepare
transitStateToPrepared(player, args);
nextPlayer = createNextPlayer(player, NextPlayerType.PREPARED);
nextPlayer.setOnSeekCompleteListener(seekComp);
// seek
int seekPosition = nextPlayer.getDuration() / 2;
nextPlayer.seekTo(seekPosition);
if (!seekComp.await(DEFAULT_EVENT_WAIT_DURATION)) {
fail();
}
// NOTE: valid position is returned
assertEquals(seekPosition, nextPlayer.getCurrentPosition());
setUnwrappedtNextPlayer(player, nextPlayer);
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// start
player.start();
assertTrue(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
Thread.sleep(SHORT_EVENT_WAIT_DURATION);
assertTrue(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// wait for the next player started
Thread.sleep(player.getDuration());
// NOTE: StandardMediaPlayer fails on this assertion if using NuPlayer
assertEquals(player.getDuration(), player.getCurrentPosition());
assertFalse(player.isPlaying());
assertTrue(nextPlayer.isPlaying());
// NOTE: valid current position position is returned
assertLargerThanOrEqual(seekPosition,
nextPlayer.getCurrentPosition());
// wait for the next player completion
Thread.sleep(nextPlayer.getDuration() - seekPosition
+ SHORT_EVENT_WAIT_DURATION);
if (true) {
Log.w("XXX",
"testSeekToBeforeAttachedAsNextMediaPlayer() - WORKAROUND");
// WTF! Android's native audio decoder gives very poor seek
// accuracy!
assertFalse(player.isPlaying());
assertTrue(nextPlayer.isPlaying());
// wait for the next player completion
Thread.sleep(seekPosition);
}
assertEquals(nextPlayer.getDuration(),
nextPlayer.getCurrentPosition());
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
} finally {
releaseQuietly(nextPlayer);
releaseQuietly(player);
}
}
// NOTE: This test case may fails with StandardMediaPlayer (affects: ICS to JB, Lollipop with NuPlayer)
public void testSeekToAfterAttachedAsNextMediaPlayer() throws Throwable {
IBasicMediaPlayer player = createWrappedPlayerInstance();
IBasicMediaPlayer nextPlayer = null;
Object args = getTestParams();
// NOTE:
// seekTo() call will be ignored if the player is attached as a next
// player.
try {
// prepare
transitStateToPrepared(player, args);
nextPlayer = createNextPlayer(player, NextPlayerType.PREPARED);
setUnwrappedtNextPlayer(player, nextPlayer);
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// start
player.start();
assertTrue(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
int seekPosition = nextPlayer.getDuration() / 2;
SeekCompleteListenerObject seekComp = new SeekCompleteListenerObject();
nextPlayer.setOnSeekCompleteListener(seekComp);
nextPlayer.seekTo(seekPosition);
if (!seekComp.await(DEFAULT_EVENT_WAIT_DURATION)) {
fail();
}
// NOTE: valid position is returned
assertEquals(seekPosition, nextPlayer.getCurrentPosition());
Thread.sleep(SHORT_EVENT_WAIT_DURATION);
assertTrue(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// wait for the next player started
Thread.sleep(player.getDuration());
// NOTE: StandardMediaPlayer fails on this assertion if using NuPlayer
assertEquals(player.getDuration(), player.getCurrentPosition());
assertFalse(player.isPlaying());
assertTrue(nextPlayer.isPlaying());
// NOTE: valid current position position is returned
// XXX Galaxy S4 (SC-04E, Android 4.4.2) fails on this assertion
assertLargerThanOrEqual(seekPosition,
nextPlayer.getCurrentPosition());
// wait for the next player completion
Thread.sleep(nextPlayer.getDuration() - seekPosition
+ SHORT_EVENT_WAIT_DURATION);
if (true) {
Log.w("XXX",
"testSeekToAfterAttachedAsNextMediaPlayer() - WORKAROUND");
// WTF! Android's native audio decoder gives very poor seek
// accuracy!
assertFalse(player.isPlaying());
assertTrue(nextPlayer.isPlaying());
// wait for the next player completion
Thread.sleep(seekPosition);
}
assertEquals(nextPlayer.getDuration(),
nextPlayer.getCurrentPosition());
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
} finally {
releaseQuietly(nextPlayer);
releaseQuietly(player);
}
}
public void testPlayingStateAsNextMediaPlayer() throws Throwable {
IBasicMediaPlayer player = createWrappedPlayerInstance();
IBasicMediaPlayer nextPlayer = null;
Object args = getTestParams();
try {
// prepare
transitStateToPrepared(player, args);
nextPlayer = createNextPlayer(player, NextPlayerType.PREPARED);
player.setVolume(1.0f, 0.0f);
nextPlayer.setVolume(0.0f, 1.0f);
nextPlayer.start();
Thread.sleep(safeGetDuration(nextPlayer, DURATION_LIMIT) / 2);
try {
setUnwrappedtNextPlayer(player, nextPlayer);
fail();
} catch (IllegalStateException e) {
// expected
}
} finally {
releaseQuietly(nextPlayer);
releaseQuietly(player);
}
}
public void testPausedStateAsNextMediaPlayer() throws Throwable {
if (isStandardPlayer(getFactory()) && SKIP_HANGUP_SUSPECTED_TEST_CASE) {
fail("This test case is skipped to avoid HANGUP");
}
IBasicMediaPlayer player = createWrappedPlayerInstance();
IBasicMediaPlayer nextPlayer = null;
Object args = getTestParams();
try {
// prepare
transitStateToPrepared(player, args);
nextPlayer = createNextPlayer(player, NextPlayerType.PREPARED);
player.setVolume(1.0f, 0.0f);
nextPlayer.setVolume(0.0f, 1.0f);
if (!isStandardPlayer(player)) {
nextPlayer.start();
Thread.sleep(50);
nextPlayer.pause();
Thread.sleep(2000); // wait fade-out completion
} else {
nextPlayer.start();
Thread.sleep(player.getDuration() / 2);
nextPlayer.pause();
}
setUnwrappedtNextPlayer(player, nextPlayer);
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// start
player.start();
assertTrue(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
Thread.sleep(player.getDuration() + SHORT_EVENT_WAIT_DURATION);
assertEquals(player.getDuration(), player.getCurrentPosition());
assertFalse(player.isPlaying());
assertTrue(nextPlayer.isPlaying());
Thread.sleep(nextPlayer.getDuration() / 2
+ SHORT_EVENT_WAIT_DURATION);
assertEquals(nextPlayer.getDuration(),
nextPlayer.getCurrentPosition());
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
} finally {
// NOTE:
// StandardMediaPlayer may hang while calling the release() method...
releaseQuietly(nextPlayer);
releaseQuietly(player);
}
}
public void testSetNextMediaPlayerAfterCompletion() throws Throwable {
IBasicMediaPlayer player = createWrappedPlayerInstance();
IBasicMediaPlayer nextPlayer = null;
Object args = getTestParams();
try {
// prepare
transitStateToPrepared(player, args);
nextPlayer = createNextPlayer(player, NextPlayerType.PREPARED);
player.setVolume(1.0f, 0.0f);
nextPlayer.setVolume(0.0f, 1.0f);
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// start
player.start();
assertTrue(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// wait
Thread.sleep(player.getDuration() + DEFAULT_EVENT_WAIT_DURATION);
assertEquals(player.getDuration(), player.getCurrentPosition());
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
setUnwrappedtNextPlayer(player, nextPlayer);
Thread.sleep(SHORT_EVENT_WAIT_DURATION);
assertEquals(0, nextPlayer.getCurrentPosition());
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
} finally {
releaseQuietly(nextPlayer);
releaseQuietly(player);
}
}
public void testReinitializeNextMediaPlayer() throws Throwable {
IBasicMediaPlayer player = createWrappedPlayerInstance();
IBasicMediaPlayer nextPlayer = null;
Object args = getTestParams();
try {
// prepare
transitStateToPrepared(player, args);
nextPlayer = createNextPlayer(player, NextPlayerType.PREPARED);
player.setVolume(1.0f, 0.0f);
nextPlayer.setVolume(0.0f, 1.0f);
setUnwrappedtNextPlayer(player, nextPlayer);
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// start
player.start();
assertTrue(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
// wait 1/2
Thread.sleep(player.getDuration() / 2);
nextPlayer.reset();
transitStateToPrepared(nextPlayer, null);
Thread.sleep(player.getDuration() / 2 + SHORT_EVENT_WAIT_DURATION);
// NOTE: StandardMediaPlayer fails on this assertion if using NuPlayer
assertEquals(player.getDuration(), player.getCurrentPosition());
assertFalse(player.isPlaying());
assertTrue(nextPlayer.isPlaying());
Thread.sleep(nextPlayer.getDuration() + SHORT_EVENT_WAIT_DURATION);
assertEquals(nextPlayer.getDuration(),
nextPlayer.getCurrentPosition());
assertFalse(player.isPlaying());
assertFalse(nextPlayer.isPlaying());
} finally {
releaseQuietly(nextPlayer);
releaseQuietly(player);
}
}
public void testMultipleSetNextAudioPlayer_1() throws Throwable {
if (isStandardPlayer(getFactory()) && SKIP_HANGUP_SUSPECTED_TEST_CASE) {
fail("This test case is skipped to avoid HANGUP");
}
implMultipleSetNextAudioPlayer(0);
}
public void testMultipleSetNextAudioPlayer_2() throws Throwable {
if (isStandardPlayer(getFactory()) && SKIP_HANGUP_SUSPECTED_TEST_CASE) {
fail("This test case is skipped to avoid HANGUP");
}
implMultipleSetNextAudioPlayer(1);
}
public void implMultipleSetNextAudioPlayer(int order) throws Throwable {
IBasicMediaPlayer player1 = createWrappedPlayerInstance();
IBasicMediaPlayer player2 = createWrappedPlayerInstance();
IBasicMediaPlayer nextPlayer = null;
Object args = getTestParams();
// NOTE:
// seekTo() call will be ignored if the player is attached as a next
// player.
try {
// prepare
transitStateToPrepared(player1, args);
transitStateToPrepared(player2, args);
nextPlayer = createNextPlayer(player1, NextPlayerType.PREPARED);
if (order == 0) {
setUnwrappedtNextPlayer(player1, nextPlayer);
setUnwrappedtNextPlayer(player2, nextPlayer);
} else {
setUnwrappedtNextPlayer(player2, nextPlayer);
setUnwrappedtNextPlayer(player1, nextPlayer);
}
nextPlayer.setVolume(0.5f, 0.51f);
player1.setVolume(0.5f, 0.0f);
player2.setVolume(0.0f, 0.5f);
assertFalse(player1.isPlaying());
assertFalse(player2.isPlaying());
assertFalse(nextPlayer.isPlaying());
// start player 1
player1.start();
assertTrue(player1.isPlaying());
assertFalse(player2.isPlaying());
assertFalse(nextPlayer.isPlaying());
// wait 1/2
Thread.sleep(player1.getDuration() / 2);
assertTrue(player1.isPlaying());
assertFalse(player2.isPlaying());
assertFalse(nextPlayer.isPlaying());
// start player 2
player2.start();
assertTrue(player1.isPlaying());
assertTrue(player2.isPlaying());
assertFalse(nextPlayer.isPlaying());
// wait 1/2 + alpha
Thread.sleep(player1.getDuration() / 2 + SHORT_EVENT_WAIT_DURATION);
assertFalse(player1.isPlaying());
assertTrue(player2.isPlaying());
assertTrue(nextPlayer.isPlaying());
// wait 1/2
Thread.sleep(player1.getDuration() / 2);
assertFalse(player1.isPlaying());
assertFalse(player2.isPlaying());
assertTrue(nextPlayer.isPlaying());
// wait 1/2 + alpha
Thread.sleep(player1.getDuration() / 2 + SHORT_EVENT_WAIT_DURATION);
assertFalse(player1.isPlaying());
assertFalse(player2.isPlaying());
assertFalse(nextPlayer.isPlaying());
} finally {
// NOTE:
// StandardMediaPlayer may hang while calling the release() method...
releaseQuietly(nextPlayer);
releaseQuietly(player2);
releaseQuietly(player1);
}
}
}