Skip to content

Commit

Permalink
Throw IllegalStateException on calls in illegal states (similar to AP…
Browse files Browse the repository at this point in the history
…I MediaPlayer)
  • Loading branch information
protyposis committed Dec 2, 2016
1 parent 8cddd54 commit cced569
Showing 1 changed file with 71 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ public boolean isRenderModeApi21() {

private enum State {
IDLE,
INITIALIZED,
PREPARING,
PREPARED,
STOPPED,
Expand Down Expand Up @@ -195,7 +196,11 @@ public MediaPlayer() {
mCurrentState = State.IDLE;
}

public void setDataSource(MediaSource source) throws IOException {
public void setDataSource(MediaSource source) throws IOException, IllegalStateException {
if(mCurrentState != State.IDLE) {
throw new IllegalStateException();
}

mVideoExtractor = source.getVideoExtractor();
mAudioExtractor = source.getAudioExtractor();

Expand Down Expand Up @@ -244,6 +249,8 @@ public void setDataSource(MediaSource source) throws IOException {
if(mVideoTrackIndex != MediaCodecDecoder.INDEX_NONE && mPlaybackThread == null && mSurface == null) {
Log.i(TAG, "no video output surface specified");
}

mCurrentState = State.INITIALIZED;
}

/**
Expand All @@ -264,12 +271,7 @@ public void setDataSource(Context context, Uri uri) throws IOException {
setDataSource(context, uri, null);
}

/**
* @see android.media.MediaPlayer#prepare()
*/
public void prepare() throws IOException, IllegalStateException {
mCurrentState = State.PREPARING;

private void prepareInternal() throws IOException, IllegalStateException {
if (mAudioFormat != null) {
mAudioPlayback = new AudioPlayback();
// Initialize settings in case they have already been set before the preparation
Expand Down Expand Up @@ -378,10 +380,26 @@ public void onBuffering(MediaCodecDecoder decoder) {
mCurrentState = State.PREPARED;
}

/**
* @see android.media.MediaPlayer#prepare()
*/
public void prepare() throws IOException, IllegalStateException {
if(mCurrentState != State.INITIALIZED && mCurrentState != State.STOPPED) {
throw new IllegalStateException();
}

mCurrentState = State.PREPARING;
prepareInternal();
}

/**
* @see android.media.MediaPlayer#prepareAsync()
*/
public void prepareAsync() throws IllegalStateException {
if(mCurrentState != State.INITIALIZED && mCurrentState != State.STOPPED) {
throw new IllegalStateException();
}

mCurrentState = State.PREPARING;

/* Running prepare() in an AsyncTask leads to severe performance degradations, unless the
Expand All @@ -397,7 +415,7 @@ public void prepareAsync() throws IllegalStateException {
@Override
public void run() {
try {
prepare();
prepareInternal();

if(mCurrentState == State.PREPARED) {
// This event is only triggered after a successful async prepare (not after the sync prepare!)
Expand Down Expand Up @@ -462,11 +480,21 @@ public void setSurface(Surface surface) {
}

public void start() {
if(mCurrentState != State.PREPARED) {
mCurrentState = State.ERROR;
throw new IllegalStateException();
}

mPlaybackThread.play();
stayAwake(true);
}

public void pause() {
if(mCurrentState != State.PREPARED) {
mCurrentState = State.ERROR;
throw new IllegalStateException();
}

mPlaybackThread.pause();
stayAwake(false);
}
Expand All @@ -480,6 +508,11 @@ public void setSeekMode(SeekMode seekMode) {
}

public void seekTo(long usec) {
if(mCurrentState.ordinal() < State.PREPARED.ordinal() && mCurrentState.ordinal() >= State.RELEASING.ordinal()) {
mCurrentState = State.ERROR;
throw new IllegalStateException();
}

/* A seek needs to be performed in the decoding thread to execute commands in the correct
* order. Otherwise it can happen that, after a seek in the media decoder, seeking procedure
* starts, then a frame is decoded, and then the codec is flushed; the PTS of the decoded frame
Expand Down Expand Up @@ -530,6 +563,11 @@ public float getPlaybackSpeed() {
}

public boolean isPlaying() {
if(mCurrentState.ordinal() >= State.RELEASING.ordinal()) {
mCurrentState = State.ERROR;
throw new IllegalStateException();
}

return mPlaybackThread != null && !mPlaybackThread.isPaused();
}

Expand All @@ -553,16 +591,18 @@ public void stop() {
mPlaybackThread = null;
}
stayAwake(false);
mCurrentState = State.STOPPED;
}

public void release() {
mCurrentState = State.RELEASING;
stop();
mCurrentState = MediaPlayer.State.RELEASED;
mCurrentState = State.RELEASED;
}

public void reset() {
stop();
mCurrentState = State.IDLE;
}

/**
Expand Down Expand Up @@ -618,11 +658,20 @@ private void updateSurfaceScreenOn() {
}

public int getDuration() {
if(mCurrentState.ordinal() <= State.PREPARING.ordinal() && mCurrentState.ordinal() >= State.RELEASING.ordinal()) {
mCurrentState = State.ERROR;
throw new IllegalStateException();
}

return mVideoFormat != null ? (int)(mVideoFormat.getLong(MediaFormat.KEY_DURATION)/1000) :
mAudioFormat != null && mAudioFormat.containsKey(MediaFormat.KEY_DURATION) ? (int)(mAudioFormat.getLong(MediaFormat.KEY_DURATION)/1000) : 0;
}

public int getCurrentPosition() {
if(mCurrentState.ordinal() >= State.RELEASING.ordinal()) {
mCurrentState = State.ERROR;
throw new IllegalStateException();
}
/* During a seek, return the temporary seek target time; otherwise a seek bar doesn't
* update to the selected seek position until the seek is finished (which can take a
* while in exact mode). */
Expand All @@ -634,11 +683,21 @@ public int getBufferPercentage() {
}

public int getVideoWidth() {
if(mCurrentState.ordinal() >= State.RELEASING.ordinal()) {
mCurrentState = State.ERROR;
throw new IllegalStateException();
}

return mVideoFormat != null ? (int)(mVideoFormat.getInteger(MediaFormat.KEY_HEIGHT)
* mVideoFormat.getFloat(MediaExtractor.MEDIA_FORMAT_EXTENSION_KEY_DAR)) : 0;
}

public int getVideoHeight() {
if(mCurrentState.ordinal() >= State.RELEASING.ordinal()) {
mCurrentState = State.ERROR;
throw new IllegalStateException();
}

return mVideoFormat != null ? mVideoFormat.getInteger(MediaFormat.KEY_HEIGHT) : 0;
}

Expand Down Expand Up @@ -667,6 +726,9 @@ public void setVolume(float volume) {
* @see android.media.MediaPlayer#setAudioSessionId(int)
*/
public void setAudioSessionId(int sessionId) {
if(mCurrentState != State.IDLE) {
throw new IllegalStateException();
}
mAudioSessionId = sessionId;
}

Expand Down

0 comments on commit cced569

Please sign in to comment.