/*
* 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.standard;
class MediaPlayerStateManager {
public static final int STATE_IDLE = 0;
public static final int STATE_INITIALIZED = 1;
public static final int STATE_PREPARING = 2;
public static final int STATE_PREPARED = 3;
public static final int STATE_STARTED = 4;
public static final int STATE_PAUSED = 5;
public static final int STATE_PLAYBACK_COMPLETED = 6;
public static final int STATE_STOPPED = 7;
public static final int STATE_ERROR = 8;
public static final int STATE_END = 9;
private int mState;
private int mPrevErrorState;
public MediaPlayerStateManager() {
mState = STATE_IDLE;
mPrevErrorState = STATE_IDLE;
}
public int getState() {
return mState;
}
public int getPrevErrorState() {
return mPrevErrorState;
}
private static boolean canTransitToInitialized(int state) {
return state == STATE_IDLE;
}
private static boolean canTransitToPrepared(int state) {
return state == STATE_INITIALIZED ||
state == STATE_PREPARING ||
state == STATE_STOPPED;
}
private static boolean canTransitToPreparing(int state) {
return state == STATE_INITIALIZED ||
state == STATE_STOPPED;
}
private static boolean canTransitToStarted(int state) {
return state == STATE_PREPARED ||
state == STATE_STARTED ||
state == STATE_PAUSED ||
state == STATE_PLAYBACK_COMPLETED;
}
private static boolean canTransitToPaused(int state) {
return state == STATE_STARTED ||
state == STATE_PAUSED;
}
private static boolean canTransitToStopped(int state) {
return state == STATE_PREPARED ||
state == STATE_STARTED ||
state == STATE_PAUSED ||
state == STATE_PLAYBACK_COMPLETED ||
state == STATE_STOPPED;
}
private static boolean canTransitToIdle(int state) {
return state != STATE_END;
}
private static boolean canTransitToPlaybackCompleted(int state) {
return state == STATE_STARTED;
}
private static boolean canTransitToError(int state) {
return state != STATE_END;
}
private static boolean canTransitToEnd(int state) {
return true;
}
public boolean canCallSetDataSource() {
return canTransitToInitialized(mState);
}
public boolean canCallPrepare() {
final int state = mState;
return state == STATE_INITIALIZED || state == STATE_STOPPED;
}
public boolean canCallPrepareAsync() {
return canTransitToPreparing(mState);
}
public boolean canCallStart() {
return canTransitToStarted(mState);
}
public boolean canCallPause() {
return canTransitToPaused(mState) || (mState == STATE_PLAYBACK_COMPLETED);
}
public boolean canCallStop() {
return canTransitToStopped(mState);
}
public boolean canCallReset() {
return canTransitToIdle(mState);
}
public boolean canCallSeekTo() {
final int state = mState;
return (state == STATE_PREPARED || state == STATE_STARTED ||
state == STATE_PAUSED || state == STATE_PLAYBACK_COMPLETED);
}
public boolean canCallGetDuration() {
final int state = mState;
return (state == STATE_PREPARED || state == STATE_STARTED ||
state == STATE_PAUSED || state == STATE_STOPPED ||
state == STATE_PLAYBACK_COMPLETED);
}
public boolean canCallGetCurrentPosition() {
final int state = mState;
return (state == STATE_IDLE || state == STATE_INITIALIZED ||
state == STATE_PREPARED || state == STATE_STARTED ||
state == STATE_PAUSED || state == STATE_STOPPED ||
state == STATE_PLAYBACK_COMPLETED);
}
private boolean setState(int state) {
if (verifyStateTransition(mState, state)) {
if (state == STATE_ERROR && mState != STATE_ERROR) {
// save current state
mPrevErrorState = mState;
}
mState = state;
return false;
} else {
return false;
}
}
public void transitToIdleState() {
setState(STATE_IDLE);
}
public void transitToErrorState() {
setState(STATE_ERROR);
}
public void transitToEndState() {
if (setState(STATE_END)) {
mPrevErrorState = STATE_IDLE;
}
}
public void transitToInitialized() {
if (setState(STATE_INITIALIZED)) {
mPrevErrorState = STATE_IDLE;
}
}
public void transitToPreparingState() {
setState(STATE_PREPARING);
}
public void transitToPreparedState() {
setState(STATE_PREPARED);
}
public void transitToStartedState() {
setState(STATE_STARTED);
}
public void transitToStoppedState() {
setState(STATE_STOPPED);
}
public void transitToPausedState() {
setState(STATE_PAUSED);
}
public void transitToPlaybackCompleted() {
setState(STATE_PLAYBACK_COMPLETED);
}
public boolean isStateEnd() {
return (mState == STATE_END);
}
public boolean isStateError() {
return (mState == STATE_ERROR);
}
public String getCurrentStateCodeString() {
return getStateCodeString(mState);
}
public static String getStateCodeString(int state) {
switch (state) {
case STATE_IDLE:
return "IDLE";
case STATE_INITIALIZED:
return "INITIALIZED";
case STATE_PREPARING:
return "PREPARING";
case STATE_PREPARED:
return "PREPARED";
case STATE_STARTED:
return "STARTED";
case STATE_PAUSED:
return "PAUSED";
case STATE_PLAYBACK_COMPLETED:
return "PLAYBACK_COMPLETED";
case STATE_STOPPED:
return "STOPPED";
case STATE_ERROR:
return "ERROR";
case STATE_END:
return "END";
default:
throw new IllegalArgumentException("Unknown state code(state = " + state + ")");
}
}
private boolean verifyStateTransition(int current, int next) {
switch (next) {
case STATE_IDLE:
return canTransitToIdle(current);
case STATE_INITIALIZED:
return canTransitToInitialized(current);
case STATE_PREPARING:
return canTransitToPreparing(current);
case STATE_PREPARED:
return canTransitToPrepared(current);
case STATE_STARTED:
return canTransitToStarted(current);
case STATE_PAUSED:
return canTransitToPaused(current);
case STATE_PLAYBACK_COMPLETED:
return canTransitToPlaybackCompleted(current);
case STATE_STOPPED:
return canTransitToStopped(current);
case STATE_ERROR:
return canTransitToError(current);
case STATE_END:
return canTransitToEnd(current);
default:
throw new IllegalArgumentException("Unknown state code(current = " + current + ", next = " + next + ")");
}
}
}