FileDocCategorySizeDatePackage
MediaPlayerProxyTestCase.javaAPI DocAndroid 5.1 API23920Thu Mar 12 22:22:48 GMT 2015com.android.ex.variablespeed

MediaPlayerProxyTestCase

public abstract class MediaPlayerProxyTestCase extends android.test.InstrumentationTestCase
Base test for checking implementations of {@link MediaPlayerProxy}.

The purpose behind this class is to collect tests that implementations of MediaPlayerProxy should support.

This allows tests to show that the built-in {@link android.media.MediaPlayer} is performing correctly with respect to the contract it provides, i.e. test my understanding of that contract.

It allows us to test the current {@link VariableSpeed} implementation, and make sure that this too corresponds with the MediaPlayer implementation.

These tests cannot be run on their own - you must provide a concrete subclass of this test case - and in that subclass you will provide an implementation of the abstract {@link #createTestMediaPlayer()} method to construct the player you would like to test. Every test will construct the player in {@link #setUp()} and release it in {@link #tearDown()}.

Fields Summary
private static final float
ERROR_TOLERANCE_MILLIS
private static final String
CONTACT_NUMBER
The phone number to use when inserting test data into the content provider.
private final Map
mContentUriMap
A map from filename + mime type to the uri we can use to play from the content provider.

This is lazily filled in by the {@link #getTestContentUri(String, String)} method.

This map is keyed from the concatenation of filename and mime type with a "+" separator, it's not perfect but it doesn't matter in this test code.

private MediaPlayerProxy
mPlayer
The system under test.
private AwaitableCompletionListener
mCompletionListener
private AwaitableErrorListener
mErrorListener
Constructors Summary
Methods Summary
private voidcleanupContentUriIfNecessary()

        for (Uri uri : mContentUriMap.values()) {
            getContentResolver().delete(uri, null, null);
        }
        mContentUriMap.clear();
    
public voidcopyBetweenStreams(java.io.InputStream in, java.io.OutputStream out)

        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = in.read(buffer)) != -1) {
            out.write(buffer, 0, bytesRead);
        }
    
public abstract MediaPlayerProxycreateTestMediaPlayer()

private android.content.res.AssetManagergetAssets()

        return getInstrumentation().getContext().getAssets();
    
private android.content.ContentResolvergetContentResolver()

        return getInstrumentation().getContext().getContentResolver();
    
private android.net.UrigetTestContentUri(java.lang.String assetFilename, java.lang.String assetMimeType)
Gets the {@link Uri} for the test audio content we should play.

If this is the first time we've called this method, for a given file type and mime type, then we'll have to insert some data into the content provider so that we can play it.

This is not thread safe, but doesn't need to be because all unit tests are executed from a single thread, sequentially.

        String key = keyFor(assetFilename, assetMimeType);
        if (mContentUriMap.containsKey(key)) {
            return mContentUriMap.get(key);
        }
        ContentValues values = new ContentValues();
        values.put(VoicemailContract.Voicemails.DATE, String.valueOf(System.currentTimeMillis()));
        values.put(VoicemailContract.Voicemails.NUMBER, CONTACT_NUMBER);
        values.put(VoicemailContract.Voicemails.MIME_TYPE, assetMimeType);
        String packageName = getInstrumentation().getTargetContext().getPackageName();
        Uri uri = getContentResolver().insert(
                VoicemailContract.Voicemails.buildSourceUri(packageName), values);
        AssetManager assets = getAssets();
        OutputStream outputStream = null;
        InputStream inputStream = null;
        try {
            inputStream = assets.open(assetFilename);
            outputStream = getContentResolver().openOutputStream(uri);
            copyBetweenStreams(inputStream, outputStream);
            mContentUriMap.put(key, uri);
            return uri;
        } finally {
            Closeables.closeQuietly(outputStream);
            Closeables.closeQuietly(inputStream);
        }
    
private java.lang.StringkeyFor(java.lang.String assetFilename, java.lang.String assetMimeType)

        return assetFilename + "+" + assetMimeType;
    
protected voidrunTest()

        // Tests annotated with ShouldThrowIllegalStateException will fail if they don't.
        // Tests not annotated this way are run as normal.
        if (getClass().getMethod(getName()).isAnnotationPresent(
                ShouldThrowIllegalStateException.class)) {
            try {
                super.runTest();
                fail("Expected this method to throw an IllegalStateException, but it didn't");
            } catch (IllegalStateException e) {
                // Expected.
            }
        } else {
            super.runTest();
        }
    
private voidsetDataSourceFromContentProvider(MediaPlayerProxy player, java.lang.String assetFilename, java.lang.String assetMimeType)

        player.setDataSource(getInstrumentation().getTargetContext(),
                getTestContentUri(assetFilename, assetMimeType));
    
protected voidsetUp()


    
         
        super.setUp();
        mPlayer = createTestMediaPlayer();
        mCompletionListener = new AwaitableCompletionListener();
        mErrorListener = new AwaitableErrorListener();
    
private voidsetVariableSpeedRateIfSupported(float rate)
If we have a variable speed media player proxy, set the variable speed rate.

If we don't have a variable speed media player proxy, this method will be a no-op.

        if (mPlayer instanceof SingleThreadedMediaPlayerProxy) {
            ((SingleThreadedMediaPlayerProxy) mPlayer).setVariableSpeed(rate);
        } else if (mPlayer instanceof VariableSpeed) {
            ((VariableSpeed) mPlayer).setVariableSpeed(rate);
        }
    
protected voidtearDown()

        mCompletionListener = null;
        mErrorListener = null;
        mPlayer.release();
        mPlayer = null;
        cleanupContentUriIfNecessary();
        super.tearDown();
    
public voidtestDoubleStartWaitingForFinish()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
    
public voidtestFinishPlayingThenSeekToHalfWayThenPlayAgain()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
        mPlayer.seekTo(mPlayer.getDuration() / 2);
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
    
public voidtestGetCurrentPosition_DuringPlayback()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.start();
        Thread.sleep(2000);
        assertEquals(2000, mPlayer.getCurrentPosition(), ERROR_TOLERANCE_MILLIS);
    
public voidtestGetCurrentPosition_DuringPlaybackWithSeek()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.seekTo(1500);
        mPlayer.start();
        Thread.sleep(1500);
        assertEquals(3000, mPlayer.getCurrentPosition(), ERROR_TOLERANCE_MILLIS);
    
public voidtestGetCurrentPosition_FinishedPlaying()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
        assertEquals(mPlayer.getDuration(), mPlayer.getCurrentPosition(), ERROR_TOLERANCE_MILLIS);
    
public voidtestGetCurrentPosition_ZeroBeforePlaybackBegins()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        assertEquals(0, mPlayer.getCurrentPosition());
        mPlayer.prepare();
        assertEquals(0, mPlayer.getCurrentPosition());
    
public voidtestGetDuration()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        int duration = mPlayer.getDuration();
        assertTrue("duration was " + duration, duration > 0);
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        assertEquals(duration, mPlayer.getDuration());
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
        assertEquals(duration, mPlayer.getDuration());
    
public voidtestGetDurationAfterRelease_ShouldFail()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.release();
        mPlayer.getDuration();
    
public voidtestGetPositionAfterRelease_ShouldFail()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.release();
        mPlayer.getCurrentPosition();
    
public voidtestHalfWaySeekWithStutteringAudio()

        // The audio contained in this file has a stutter if we seek to half way and play.
        // It shouldn't have.
        setDataSourceFromContentProvider(mPlayer, "fake_voicemail2.mp3", "audio/mp3");
        mPlayer.prepare();
        assertTrue(mPlayer.getDuration() > 0);
        mPlayer.seekTo(mPlayer.getDuration() / 2);
        mPlayer.start();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
    
public voidtestIllegalPreparingDoesntFireErrorListener()

        mPlayer.setOnErrorListener(mErrorListener);
        try {
            mPlayer.prepare();
            fail("This should have thrown an IllegalStateException");
        } catch (IllegalStateException e) {
            // Good, expected.
        }
        mErrorListener.assertNoMoreCallbacks();
    
public voidtestPause_DoesNotInvokeCallback()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        mPlayer.pause();
        Thread.sleep(200);
        mCompletionListener.assertNoMoreCallbacks();
    
public voidtestPause_DuringPlayback()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.start();
        assertTrue(mPlayer.isPlaying());
        Thread.sleep(2000);
        assertTrue(mPlayer.isPlaying());
        mPlayer.pause();
        assertFalse(mPlayer.isPlaying());
    
public voidtestPause_MultipleTimes()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.start();
        Thread.sleep(2000);
        mPlayer.pause();
        mPlayer.pause();
    
public voidtestPlayABitThenRelease()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.start();
        Thread.sleep(2000);
    
public voidtestPlayFully()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
    
public voidtestPlaySingleChannelLowSampleRate3gppFile()

        setDataSourceFromContentProvider(mPlayer, "count_and_test.3gpp", "audio/3gpp");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
    
public voidtestPlayTwoDifferentTypesWithSameMediaPlayer()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
        mPlayer.reset();
        setDataSourceFromContentProvider(mPlayer, "count_and_test.3gpp", "audio/3gpp");
        mPlayer.prepare();
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
    
public voidtestPrepare()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
    
public voidtestPrepareBeforeSetDataSource_ShouldFail()

        mPlayer.prepare();
    
public voidtestPrepareTwice_ShouldFailWithIllegalState()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.prepare();
    
public voidtestReleaseMultipleTimesHasNoEffect()

        mPlayer.release();
        mPlayer.release();
    
public voidtestRepeatedlySeekingDuringPlayback()

        // Start playback then seek repeatedly during playback to the same point.
        // The real media player should play a stuttering audio, hopefully my player does too.
        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        Thread.sleep(500);
        for (int i = 0; i < 40; ++i) {
            Thread.sleep(200);
            mPlayer.seekTo(2000);
        }
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
    
public voidtestRepeatedlySeekingDuringPlaybackRandomAndVeryFast()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        Thread.sleep(500);
        for (int i = 0; i < 40; ++i) {
            Thread.sleep(250);
            mPlayer.seekTo(1500 + (int) (Math.random() * 1000));
        }
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
    
public voidtestResetAfterPlaybackThenReUse()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.prepare();
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
        mPlayer.reset();
        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.start();
        Thread.sleep(2000);
    
public voidtestResetDuringPlaybackThenReUse()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.start();
        Thread.sleep(2000);
        mPlayer.reset();
        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.start();
        Thread.sleep(2000);
    
public voidtestResetOnNewlyCreatedObject()

        mPlayer.reset();
    
public voidtestResetWithoutReleaseAndThenReUse()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.reset();
        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.seekTo(mPlayer.getDuration() / 2);
        mPlayer.start();
        Thread.sleep(1000);
    
public voidtestReset_DoesNotInvokeCallback()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        mPlayer.reset();
        Thread.sleep(200);
        mCompletionListener.assertNoMoreCallbacks();
    
public voidtestSeekDuringPlayback()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        Thread.sleep(2000);
        mPlayer.seekTo(0);
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
        Thread.sleep(200);
        mCompletionListener.assertNoMoreCallbacks();
    
public voidtestSeekHalfWayBeforePlaying()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        assertTrue(mPlayer.getDuration() > 0);
        mPlayer.seekTo(mPlayer.getDuration() / 2);
        mPlayer.start();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
    
public voidtestSeekToEndThenPlayThenRateChangeCrash()

        // Unit test for this bug: http://b/5140693
        // This test proves that the bug is fixed.
        setDataSourceFromContentProvider(mPlayer, "fake_voicemail.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.seekTo(mPlayer.getDuration() - 1);
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
        // Prior to the fix, this next line was causing a crash.
        // The reason behind this was due to our having seeked so close to the end of the file
        // that insufficient data was being read, and thus we weren't able to yet determine the
        // sample rate and number of channels, which was causing an assertion failure when trying
        // to create the time scaler.
        setVariableSpeedRateIfSupported(1.0f);
    
public voidtestSetDataSource()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
    
public voidtestSetDataSourceAfterRelease_ShouldFailWithIllegalState()

        mPlayer.release();
        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
    
public voidtestSetDataSourceForMissingFile_ThrowsIOExceptionInPrepare()

        mPlayer.setOnErrorListener(mErrorListener);
        mPlayer.setDataSource("/this/file/does/not/exist/");
        try {
            mPlayer.prepare();
            fail("Should have thrown IOException");
        } catch (IOException e) {
            // Good, expected.
        }
        // Synchronous prepare does not report errors to the error listener.
        mErrorListener.assertNoMoreCallbacks();
    
public voidtestSetDataSourceTwice_ShouldFailWithIllegalState()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
    
public voidtestStartThenImmediatelyRelease()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.start();
    
public voidtestThreeFastConsecutiveStarts()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        mPlayer.start();
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
        Thread.sleep(4000);
        mCompletionListener.assertNoMoreCallbacks();
    
public voidtestTwoFastConsecutiveStarts()

        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
        mPlayer.prepare();
        mPlayer.setOnCompletionListener(mCompletionListener);
        mPlayer.start();
        mPlayer.start();
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
        Thread.sleep(200);
        mCompletionListener.assertNoMoreCallbacks();
    
public voidtestVariableSpeedRateChangeAtDifferentTimes()

        // Just check that we can set the rate at any point during playback.
        setVariableSpeedRateIfSupported(1.05f);
        setDataSourceFromContentProvider(mPlayer, "fake_voicemail.mp3", "audio/mp3");
        setVariableSpeedRateIfSupported(1.10f);
        mPlayer.prepare();
        setVariableSpeedRateIfSupported(1.15f);
        mPlayer.seekTo(mPlayer.getDuration() / 2);
        setVariableSpeedRateIfSupported(1.20f);
        mPlayer.setOnCompletionListener(mCompletionListener);
        setVariableSpeedRateIfSupported(1.25f);
        mPlayer.start();
        setVariableSpeedRateIfSupported(1.30f);
        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
        setVariableSpeedRateIfSupported(1.35f);