19730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson/*
29730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * Copyright (C) 2011 The Android Open Source Project
39730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson *
49730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * Licensed under the Apache License, Version 2.0 (the "License");
59730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * you may not use this file except in compliance with the License.
69730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * You may obtain a copy of the License at
79730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson *
89730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson *      http://www.apache.org/licenses/LICENSE-2.0
99730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson *
109730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * Unless required by applicable law or agreed to in writing, software
119730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * distributed under the License is distributed on an "AS IS" BASIS,
129730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * See the License for the specific language governing permissions and
149730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * limitations under the License.
159730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson */
169730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
179730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonpackage com.android.ex.variablespeed;
189730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
199730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport com.google.common.io.Closeables;
209730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
219730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport android.content.ContentResolver;
229730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport android.content.ContentValues;
239730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport android.content.res.AssetManager;
249730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport android.net.Uri;
259730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport android.provider.VoicemailContract;
269730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport android.test.InstrumentationTestCase;
279730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
289730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport java.io.IOException;
299730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport java.io.InputStream;
309730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport java.io.OutputStream;
319730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport java.lang.annotation.Retention;
329730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport java.lang.annotation.RetentionPolicy;
339730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport java.util.HashMap;
349730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport java.util.Map;
359730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport java.util.concurrent.TimeUnit;
369730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
379730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson/**
389730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * Base test for checking implementations of {@link MediaPlayerProxy}.
399730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * <p>
409730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * The purpose behind this class is to collect tests that implementations of
419730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * MediaPlayerProxy should support.
429730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * <p>
439730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * This allows tests to show that the built-in {@link android.media.MediaPlayer} is performing
449730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * correctly with respect to the contract it provides, i.e. test my understanding of that contract.
459730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * <p>
469730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * It allows us to test the current {@link VariableSpeed} implementation, and make sure that this
479730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * too corresponds with the MediaPlayer implementation.
489730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * <p>
499730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * These tests cannot be run on their own - you must provide a concrete subclass of this test case -
509730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * and in that subclass you will provide an implementation of the abstract
519730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * {@link #createTestMediaPlayer()} method to construct the player you would like to test. Every
529730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * test will construct the player in {@link #setUp()} and release it in {@link #tearDown()}.
539730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson */
549730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonpublic abstract class MediaPlayerProxyTestCase extends InstrumentationTestCase {
559730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private static final float ERROR_TOLERANCE_MILLIS = 1000f;
569730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
579730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    /** The phone number to use when inserting test data into the content provider. */
589730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private static final String CONTACT_NUMBER = "01234567890";
599730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
609730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    /**
619730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * A map from filename + mime type to the uri we can use to play from the content provider.
629730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * <p>
639730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * This is lazily filled in by the {@link #getTestContentUri(String, String)} method.
649730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * <p>
659730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * This map is keyed from the concatenation of filename and mime type with a "+" separator, it's
669730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * not perfect but it doesn't matter in this test code.
679730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     */
689730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private final Map<String, Uri> mContentUriMap = new HashMap<String, Uri>();
699730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
709730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    /** The system under test. */
719730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private MediaPlayerProxy mPlayer;
729730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
739730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private AwaitableCompletionListener mCompletionListener;
749730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private AwaitableErrorListener mErrorListener;
759730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
769730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    @Override
779730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    protected void setUp() throws Exception {
789730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        super.setUp();
799730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer = createTestMediaPlayer();
809730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener = new AwaitableCompletionListener();
819730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mErrorListener = new AwaitableErrorListener();
829730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
839730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
849730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    @Override
859730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    protected void tearDown() throws Exception {
869730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener = null;
879730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mErrorListener = null;
889730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.release();
899730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer = null;
909730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        cleanupContentUriIfNecessary();
919730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        super.tearDown();
929730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
939730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
949730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public abstract MediaPlayerProxy createTestMediaPlayer() throws Exception;
959730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
969730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    /** Annotation to indicate that test should throw an {@link IllegalStateException}. */
979730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    @Retention(RetentionPolicy.RUNTIME)
989730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public @interface ShouldThrowIllegalStateException {
999730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1009730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1019730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    @Override
1029730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    protected void runTest() throws Throwable {
1039730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        // Tests annotated with ShouldThrowIllegalStateException will fail if they don't.
1049730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        // Tests not annotated this way are run as normal.
1059730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        if (getClass().getMethod(getName()).isAnnotationPresent(
1069730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson                ShouldThrowIllegalStateException.class)) {
1079730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            try {
1089730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson                super.runTest();
1099730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson                fail("Expected this method to throw an IllegalStateException, but it didn't");
1109730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            } catch (IllegalStateException e) {
1119730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson                // Expected.
1129730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            }
1139730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        } else {
1149730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            super.runTest();
1159730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        }
1169730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1179730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1189730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testReleaseMultipleTimesHasNoEffect() throws Exception {
1199730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.release();
1209730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.release();
1219730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1229730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1239730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testResetOnNewlyCreatedObject() throws Exception {
1249730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.reset();
1259730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1269730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1279730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testSetDataSource() throws Exception {
1289730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
1299730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1309730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1319730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    @ShouldThrowIllegalStateException
1329730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testSetDataSourceTwice_ShouldFailWithIllegalState() throws Exception {
1339730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
1349730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
1359730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1369730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1379730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    @ShouldThrowIllegalStateException
1389730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testSetDataSourceAfterRelease_ShouldFailWithIllegalState() throws Exception {
1399730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.release();
1409730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
1419730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1429730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1439730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testPrepare() throws Exception {
1449730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
1459730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
1469730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1479730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1489730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    @ShouldThrowIllegalStateException
1499730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testPrepareBeforeSetDataSource_ShouldFail() throws Exception {
1509730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
1519730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1529730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1539730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    @ShouldThrowIllegalStateException
1549730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testPrepareTwice_ShouldFailWithIllegalState() throws Exception {
1559730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
1569730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
1579730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
1589730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1599730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1609730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testStartThenImmediatelyRelease() throws Exception {
1619730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
1629730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
1639730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
1649730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1659730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1669730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testPlayABitThenRelease() throws Exception {
1679730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
1689730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
1699730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
1709730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(2000);
1719730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1729730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1739730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testPlayFully() throws Exception {
1749730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
1759730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
1769730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
1779730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
1789730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
1799730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1809730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1819730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testGetDuration() throws Exception {
1829730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
1839730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
1849730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        int duration = mPlayer.getDuration();
1859730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        assertTrue("duration was " + duration, duration > 0);
1869730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
1879730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
1889730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        assertEquals(duration, mPlayer.getDuration());
1899730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
1909730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        assertEquals(duration, mPlayer.getDuration());
1919730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1929730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
1939730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    @ShouldThrowIllegalStateException
1949730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testGetDurationAfterRelease_ShouldFail() throws Exception {
1959730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
1969730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.release();
1979730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.getDuration();
1989730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
1999730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
2009730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    @ShouldThrowIllegalStateException
2019730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testGetPositionAfterRelease_ShouldFail() throws Exception {
2029730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2039730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.release();
2049730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.getCurrentPosition();
2059730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
2069730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
2079730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testGetCurrentPosition_ZeroBeforePlaybackBegins() throws Exception {
2089730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2099730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        assertEquals(0, mPlayer.getCurrentPosition());
2109730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
2119730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        assertEquals(0, mPlayer.getCurrentPosition());
2129730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
2139730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
2149730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testGetCurrentPosition_DuringPlayback() throws Exception {
2159730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2169730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
2179730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
2189730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(2000);
2199730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        assertEquals(2000, mPlayer.getCurrentPosition(), ERROR_TOLERANCE_MILLIS);
2209730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
2219730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
2229730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testGetCurrentPosition_FinishedPlaying() throws Exception {
2239730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2249730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
2259730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
2269730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
2279730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
2289730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        assertEquals(mPlayer.getDuration(), mPlayer.getCurrentPosition(), ERROR_TOLERANCE_MILLIS);
2299730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
2309730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
2319730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testGetCurrentPosition_DuringPlaybackWithSeek() throws Exception {
2329730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2339730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
2349730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.seekTo(1500);
2359730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
2369730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(1500);
2379730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        assertEquals(3000, mPlayer.getCurrentPosition(), ERROR_TOLERANCE_MILLIS);
2389730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
2399730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
2409730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testSeekHalfWayBeforePlaying() throws Exception {
2419730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2429730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
2439730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        assertTrue(mPlayer.getDuration() > 0);
2449730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.seekTo(mPlayer.getDuration() / 2);
2459730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
2469730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
2475f65e43cf103514ddb69abca7cc78dfe99cd329cHugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
2485f65e43cf103514ddb69abca7cc78dfe99cd329cHugo Hudson    }
2495f65e43cf103514ddb69abca7cc78dfe99cd329cHugo Hudson
2505f65e43cf103514ddb69abca7cc78dfe99cd329cHugo Hudson    public void testHalfWaySeekWithStutteringAudio() throws Exception {
2515f65e43cf103514ddb69abca7cc78dfe99cd329cHugo Hudson        // The audio contained in this file has a stutter if we seek to half way and play.
2525f65e43cf103514ddb69abca7cc78dfe99cd329cHugo Hudson        // It shouldn't have.
2535f65e43cf103514ddb69abca7cc78dfe99cd329cHugo Hudson        setDataSourceFromContentProvider(mPlayer, "fake_voicemail2.mp3", "audio/mp3");
2545f65e43cf103514ddb69abca7cc78dfe99cd329cHugo Hudson        mPlayer.prepare();
2555f65e43cf103514ddb69abca7cc78dfe99cd329cHugo Hudson        assertTrue(mPlayer.getDuration() > 0);
2565f65e43cf103514ddb69abca7cc78dfe99cd329cHugo Hudson        mPlayer.seekTo(mPlayer.getDuration() / 2);
2575f65e43cf103514ddb69abca7cc78dfe99cd329cHugo Hudson        mPlayer.start();
2585f65e43cf103514ddb69abca7cc78dfe99cd329cHugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
2599730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
2609730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
2619730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
2629730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testResetWithoutReleaseAndThenReUse() throws Exception {
2639730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2649730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.reset();
2659730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2669730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
2679730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.seekTo(mPlayer.getDuration() / 2);
2689730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
2699730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(1000);
2709730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
2719730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
2729730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testResetAfterPlaybackThenReUse() throws Exception {
2739730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2749730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
2759730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
2769730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
2779730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
2789730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.reset();
2799730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2809730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
2819730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
2829730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(2000);
2839730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
2849730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
2859730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testResetDuringPlaybackThenReUse() throws Exception {
2869730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2879730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
2889730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
2899730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(2000);
2909730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.reset();
2919730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2929730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
2939730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
2949730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(2000);
2959730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
2969730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
2979730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testFinishPlayingThenSeekToHalfWayThenPlayAgain() throws Exception {
2989730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
2999730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
3009730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
3019730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3029730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
3039730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.seekTo(mPlayer.getDuration() / 2);
3049730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3059730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
3069730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
3079730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
3089730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testPause_DuringPlayback() throws Exception {
3099730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
3109730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
3119730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3129730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        assertTrue(mPlayer.isPlaying());
3139730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(2000);
3149730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        assertTrue(mPlayer.isPlaying());
3159730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.pause();
3169730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        assertFalse(mPlayer.isPlaying());
3179730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
3189730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
3199730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testPause_DoesNotInvokeCallback() throws Exception {
3209730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
3219730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
3229730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
3239730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3249730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.pause();
3259730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(200);
3269730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.assertNoMoreCallbacks();
3279730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
3289730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
3299730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testReset_DoesNotInvokeCallback() throws Exception {
3309730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
3319730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
3329730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
3339730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3349730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.reset();
3359730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(200);
3369730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.assertNoMoreCallbacks();
3379730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
3389730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
3399730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testPause_MultipleTimes() throws Exception {
3409730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
3419730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
3429730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3439730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(2000);
3449730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.pause();
3459730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.pause();
3469730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
3479730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
3489730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testDoubleStartWaitingForFinish() throws Exception {
3499730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
3509730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
3519730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
3529730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3539730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
3549730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3559730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
3569730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
3579730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
3589730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testTwoFastConsecutiveStarts() throws Exception {
3599730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
3609730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
3619730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
3629730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3639730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3649730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
3659730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(200);
3669730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.assertNoMoreCallbacks();
3679730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
3689730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
3699730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testThreeFastConsecutiveStarts() throws Exception {
3709730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
3719730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
3729730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
3739730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3749730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3759730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3769730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
3779730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(4000);
3789730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.assertNoMoreCallbacks();
3799730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
3809730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
3819730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testSeekDuringPlayback() throws Exception {
3829730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
3839730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
3849730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
3859730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3869730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(2000);
3879730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.seekTo(0);
3889730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
3899730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(200);
3909730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.assertNoMoreCallbacks();
3919730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
3929730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
3939730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testPlaySingleChannelLowSampleRate3gppFile() throws Exception {
3949730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "count_and_test.3gpp", "audio/3gpp");
3959730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
3969730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
3979730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
3989730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
3999730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
4009730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
4019730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testPlayTwoDifferentTypesWithSameMediaPlayer() throws Exception {
4029730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
4039730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
4049730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
4059730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
4069730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
4079730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.reset();
4089730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "count_and_test.3gpp", "audio/3gpp");
4099730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
4109730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
4119730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
4129730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
4139730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
4149730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testIllegalPreparingDoesntFireErrorListener() throws Exception {
4159730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnErrorListener(mErrorListener);
4169730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        try {
4179730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            mPlayer.prepare();
4189730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            fail("This should have thrown an IllegalStateException");
4199730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        } catch (IllegalStateException e) {
4209730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            // Good, expected.
4219730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        }
4229730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mErrorListener.assertNoMoreCallbacks();
4239730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
4249730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
4259730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testSetDataSourceForMissingFile_ThrowsIOExceptionInPrepare() throws Exception {
4269730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnErrorListener(mErrorListener);
4279730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setDataSource("/this/file/does/not/exist/");
4289730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        try {
4299730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            mPlayer.prepare();
4309730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            fail("Should have thrown IOException");
4319730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        } catch (IOException e) {
4329730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            // Good, expected.
4339730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        }
4349730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        // Synchronous prepare does not report errors to the error listener.
4359730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mErrorListener.assertNoMoreCallbacks();
4369730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
4379730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
4389730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testRepeatedlySeekingDuringPlayback() throws Exception {
4399730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        // Start playback then seek repeatedly during playback to the same point.
4409730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        // The real media player should play a stuttering audio, hopefully my player does too.
4419730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
4429730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
4439730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
4449730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
4459730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(500);
4469730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        for (int i = 0; i < 40; ++i) {
4479730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            Thread.sleep(200);
4489730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            mPlayer.seekTo(2000);
4499730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        }
4509730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
4519730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
4529730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
4539730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void testRepeatedlySeekingDuringPlaybackRandomAndVeryFast() throws Exception {
4549730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "quick_test_recording.mp3", "audio/mp3");
4559730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.prepare();
4569730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
4579730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mPlayer.start();
4589730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Thread.sleep(500);
4599730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        for (int i = 0; i < 40; ++i) {
4609730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            Thread.sleep(250);
4619730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            mPlayer.seekTo(1500 + (int) (Math.random() * 1000));
4629730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        }
4639730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
4649730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
4659730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
46664f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson    public void testSeekToEndThenPlayThenRateChangeCrash() throws Exception {
46764f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        // Unit test for this bug: http://b/5140693
46864f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        // This test proves that the bug is fixed.
46964f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "fake_voicemail.mp3", "audio/mp3");
47064f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        mPlayer.prepare();
47164f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        mPlayer.seekTo(mPlayer.getDuration() - 1);
47264f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
47364f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        mPlayer.start();
47464f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
47564f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        // Prior to the fix, this next line was causing a crash.
47664f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        // The reason behind this was due to our having seeked so close to the end of the file
47764f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        // that insufficient data was being read, and thus we weren't able to yet determine the
47864f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        // sample rate and number of channels, which was causing an assertion failure when trying
47964f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        // to create the time scaler.
48064f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        setVariableSpeedRateIfSupported(1.0f);
48164f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson    }
48264f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson
48364f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson    public void testVariableSpeedRateChangeAtDifferentTimes() throws Exception {
48464f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        // Just check that we can set the rate at any point during playback.
48564f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        setVariableSpeedRateIfSupported(1.05f);
48664f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        setDataSourceFromContentProvider(mPlayer, "fake_voicemail.mp3", "audio/mp3");
48764f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        setVariableSpeedRateIfSupported(1.10f);
48864f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        mPlayer.prepare();
48964f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        setVariableSpeedRateIfSupported(1.15f);
49064f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        mPlayer.seekTo(mPlayer.getDuration() / 2);
49164f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        setVariableSpeedRateIfSupported(1.20f);
49264f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        mPlayer.setOnCompletionListener(mCompletionListener);
49364f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        setVariableSpeedRateIfSupported(1.25f);
49464f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        mPlayer.start();
49564f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        setVariableSpeedRateIfSupported(1.30f);
49664f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        mCompletionListener.awaitOneCallback(10, TimeUnit.SECONDS);
49764f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        setVariableSpeedRateIfSupported(1.35f);
49864f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson    }
49964f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson
50064f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson    /**
50164f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson     * If we have a variable speed media player proxy, set the variable speed rate.
50264f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson     * <p>
50364f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson     * If we don't have a variable speed media player proxy, this method will be a no-op.
50464f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson     */
50564f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson    private void setVariableSpeedRateIfSupported(float rate) {
50664f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        if (mPlayer instanceof SingleThreadedMediaPlayerProxy) {
50764f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson            ((SingleThreadedMediaPlayerProxy) mPlayer).setVariableSpeed(rate);
50864f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        } else if (mPlayer instanceof VariableSpeed) {
50964f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson            ((VariableSpeed) mPlayer).setVariableSpeed(rate);
51064f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson        }
51164f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson    }
51264f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson
5139730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    /**
5149730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * Gets the {@link Uri} for the test audio content we should play.
5159730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * <p>
5169730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * If this is the first time we've called this method, for a given file type and mime type, then
5179730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * we'll have to insert some data into the content provider so that we can play it.
5189730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * <p>
5199730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * This is not thread safe, but doesn't need to be because all unit tests are executed from a
5209730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     * single thread, sequentially.
5219730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson     */
5229730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private Uri getTestContentUri(String assetFilename, String assetMimeType) throws IOException {
5239730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        String key = keyFor(assetFilename, assetMimeType);
5249730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        if (mContentUriMap.containsKey(key)) {
5259730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            return mContentUriMap.get(key);
5269730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        }
5279730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        ContentValues values = new ContentValues();
5289730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        values.put(VoicemailContract.Voicemails.DATE, String.valueOf(System.currentTimeMillis()));
5299730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        values.put(VoicemailContract.Voicemails.NUMBER, CONTACT_NUMBER);
5309730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        values.put(VoicemailContract.Voicemails.MIME_TYPE, assetMimeType);
5319730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        String packageName = getInstrumentation().getTargetContext().getPackageName();
5329730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        Uri uri = getContentResolver().insert(
5339730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson                VoicemailContract.Voicemails.buildSourceUri(packageName), values);
5349730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        AssetManager assets = getAssets();
5359730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        OutputStream outputStream = null;
5369730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        InputStream inputStream = null;
5379730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        try {
5389730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            inputStream = assets.open(assetFilename);
5399730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            outputStream = getContentResolver().openOutputStream(uri);
5409730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            copyBetweenStreams(inputStream, outputStream);
5419730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            mContentUriMap.put(key, uri);
5429730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            return uri;
5439730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        } finally {
5449730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            Closeables.closeQuietly(outputStream);
5459730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            Closeables.closeQuietly(inputStream);
5469730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        }
5479730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
5489730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
5499730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private String keyFor(String assetFilename, String assetMimeType) {
5509730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        return assetFilename + "+" + assetMimeType;
5519730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
5529730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
5539730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void copyBetweenStreams(InputStream in, OutputStream out) throws IOException {
5549730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        byte[] buffer = new byte[1024];
5559730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        int bytesRead;
5569730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        while ((bytesRead = in.read(buffer)) != -1) {
5579730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            out.write(buffer, 0, bytesRead);
5589730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        }
5599730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
5609730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
5619730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private void cleanupContentUriIfNecessary() {
5629730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        for (Uri uri : mContentUriMap.values()) {
5639730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            getContentResolver().delete(uri, null, null);
5649730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        }
5659730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mContentUriMap.clear();
5669730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
5679730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
5689730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private void setDataSourceFromContentProvider(MediaPlayerProxy player, String assetFilename,
5699730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            String assetMimeType) throws IOException {
5709730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        player.setDataSource(getInstrumentation().getTargetContext(),
5719730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson                getTestContentUri(assetFilename, assetMimeType));
5729730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
5739730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
5749730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private ContentResolver getContentResolver() {
5759730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        return getInstrumentation().getContext().getContentResolver();
5769730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
5779730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
5789730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private AssetManager getAssets() {
5799730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        return getInstrumentation().getContext().getAssets();
5809730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
5819730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson}
582