Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2144e552 authored by Hui (QRD) Yu's avatar Hui (QRD) Yu Committed by Ricardo Cerqueira
Browse files

VideoView: Implement the suspend/resume operation in VideoView

- To use the new APIs (suspend/resume) of MediaPlayer
- Add a new status "SUSPENDED"

Change-Id: I7a829b116e5df698fd4b0a5708f06927571d198c
parent a3a45e40
Loading
Loading
Loading
Loading
+73 −2
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ public class VideoView extends SurfaceView
    private static final int STATE_PLAYING            = 3;
    private static final int STATE_PAUSED             = 4;
    private static final int STATE_PLAYBACK_COMPLETED = 5;
    private static final int STATE_SUSPENDED          = 6;

    // mCurrentState is a VideoView object's current state.
    // mTargetState is the state that a method caller intends to reach.
@@ -403,6 +404,23 @@ public class VideoView extends SurfaceView
        }
    }

    private boolean isHTTPStreaming(Uri mUri) {
        if (mUri != null) {
            String scheme = mUri.getScheme();
            if (scheme.equals("http") || scheme.equals("https")) {
                String path = mUri.getPath();
                if (path == null || path.endsWith(".m3u8") || path.endsWith(".m3u")
                        || path.endsWith(".mpd")) {
                    // HLS or DASH streaming source
                    return false;
                }
                // HTTP progressive download streaming source
                return true;
            }
        }
        return false;
    }

    MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =
        new MediaPlayer.OnVideoSizeChangedListener() {
            public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
@@ -626,6 +644,23 @@ public class VideoView extends SurfaceView
        public void surfaceCreated(SurfaceHolder holder)
        {
            mSurfaceHolder = holder;
            // if current state is suspended, call resume() to init the decoders again
            if (mCurrentState == STATE_SUSPENDED && mMediaPlayer != null) {
                mMediaPlayer.setDisplay(mSurfaceHolder);
                if (mMediaPlayer.resume()) {
                    mCurrentState = STATE_PREPARED;
                    if (mSeekWhenPrepared != 0) {
                        // seek if necessary
                        seekTo(mSeekWhenPrepared);
                    }
                    if (mTargetState == STATE_PLAYING) {
                        start();
                    }
                    return;
                } else {
                    release(false);
                }
            }
            openVideo();
        }

@@ -633,7 +668,12 @@ public class VideoView extends SurfaceView
        {
            // after we return from this we can't use the surface any more
            mSurfaceHolder = null;
            if (mMediaController != null) mMediaController.hide();
            if (mMediaController != null)
                mMediaController.hide();
            if (isHTTPStreaming(mUri) && mCurrentState == STATE_SUSPENDED) {
                // don't call release() while suspending
                return;
            }
            release(true);
        }
    };
@@ -741,10 +781,40 @@ public class VideoView extends SurfaceView
    }

    public void suspend() {
        // HTTP streaming will call MediaPlayer::suspend() for suspend operation, others will call release()
        if (isHTTPStreaming(mUri) && mCurrentState > STATE_PREPARING && mMediaPlayer != null) {
            if (mMediaPlayer.suspend()) {
                mTargetState = mCurrentState;
                mCurrentState = STATE_SUSPENDED;
                return;
            }
        }
        release(false);
    }

    public void resume() {
        // HTTP streaming (with suspended status) will call MediaPlayer::resume(), others will call openVideo()
        if (mCurrentState == STATE_SUSPENDED && mMediaPlayer != null) {
            if (mSurfaceHolder != null) {
                if (mMediaPlayer.resume()) {
                    mCurrentState = STATE_PREPARED;
                    if (mSeekWhenPrepared != 0) {
                        // seek if necessary
                        seekTo(mSeekWhenPrepared);
                    }
                    if (mTargetState == STATE_PLAYING) {
                        start();
                    }
                    return;
                } else {
                    // resume failed, so call release() before openVideo()
                    release(false);
                }
            } else {
                // the surface has been destroyed, resume() will be called after surface created
                return;
            }
        }
        openVideo();
    }

@@ -792,7 +862,8 @@ public class VideoView extends SurfaceView
        return (mMediaPlayer != null &&
                mCurrentState != STATE_ERROR &&
                mCurrentState != STATE_IDLE &&
                mCurrentState != STATE_PREPARING);
                mCurrentState != STATE_PREPARING &&
                mCurrentState != STATE_SUSPENDED);
    }

    @Override