// WTF! Android's native audio decoder gives very poor seek
// accuracy!
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);
        }
    }
Log.w("XXX",
"testSeekToAfterAttachedAsNextMediaPlayer() - WORKAROUND");
// WTF! Android's native audio decoder gives very poor seek
// accuracy!
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 {
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);
}
}