HTML5VideoFullScreen.java revision 10ab654943b386c0816a33dbd639c3b8d6260b01
110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhupackage android.webkit;
310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.content.Context;
510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.media.MediaPlayer;
610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.media.Metadata;
710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.util.Log;
810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.view.Gravity;
910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.view.MotionEvent;
1010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.view.SurfaceHolder;
1110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.view.SurfaceView;
1210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.view.View;
1310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.view.ViewGroup;
1410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.webkit.HTML5VideoView;
1510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.webkit.HTML5VideoViewProxy;
1610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.widget.FrameLayout;
1710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.widget.MediaController;
1810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.widget.MediaController.MediaPlayerControl;
1910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
2010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
2110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu/**
2210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu * @hide This is only used by the browser
2310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu */
2410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhupublic class HTML5VideoFullScreen extends HTML5VideoView
2510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    implements MediaPlayerControl, MediaPlayer.OnPreparedListener,
2610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    View.OnTouchListener {
2710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
2810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private SurfaceView mSurfaceView;
2910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
3010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // We need the full screen state to decide which surface to render to and
3110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // when to create the MediaPlayer accordingly.
3210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    static final int FULLSCREEN_OFF               = 0;
3310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    static final int FULLSCREEN_SURFACECREATING   = 1;
3410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    static final int FULLSCREEN_SURFACECREATED    = 2;
3510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
3610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private int mFullScreenMode;
3710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // The Media Controller only used for full screen mode
3810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private MediaController mMediaController;
3910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
4010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // SurfaceHolder for full screen
4110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private SurfaceHolder mSurfaceHolder = null;
4210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
4310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // Data only for MediaController
4410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private boolean mCanSeekBack;
4510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private boolean mCanSeekForward;
4610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private boolean mCanPause;
4710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private int mCurrentBufferPercentage;
4810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
4910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // The progress view.
5010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private static View mProgressView;
5110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // The container for the progress view and video view
5210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private static FrameLayout mLayout;
5310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
5410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    SurfaceHolder.Callback mSHCallback = new SurfaceHolder.Callback()
5510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    {
5610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        public void surfaceChanged(SurfaceHolder holder, int format,
5710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                                    int w, int h)
5810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        {
5910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            if (mPlayer != null && mMediaController != null
6010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                    && mCurrentState == STATE_PREPARED) {
6110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                if (mMediaController.isShowing()) {
6210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                    // ensure the controller will get repositioned later
6310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                    mMediaController.hide();
6410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                }
6510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                mMediaController.show();
6610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            }
6710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
6810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
6910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        public void surfaceCreated(SurfaceHolder holder)
7010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        {
7110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mSurfaceHolder = holder;
7210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mFullScreenMode = FULLSCREEN_SURFACECREATED;
7310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
7410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            prepareForFullScreen();
7510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
7610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
7710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        public void surfaceDestroyed(SurfaceHolder holder)
7810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        {
7910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            // after we return from this we can't use the surface any more
8010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mSurfaceHolder = null;
8110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            // The current Video View will be destroy when we play a new video.
8210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
8310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    };
8410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
8510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public SurfaceView getSurfaceView() {
8610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return mSurfaceView;
8710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
8810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
8910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    HTML5VideoFullScreen(Context context, int videoLayerId, int position,
9010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            boolean autoStart) {
9110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mSurfaceView = new SurfaceView(context);
9210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mFullScreenMode = FULLSCREEN_OFF;
9310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        init(videoLayerId, position, autoStart);
9410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
9510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
9610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private void setMediaController(MediaController m) {
9710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mMediaController  = m;
9810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        attachMediaController();
9910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
10010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
10110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private void attachMediaController() {
10210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (mPlayer != null && mMediaController != null) {
10310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mMediaController.setMediaPlayer(this);
10410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mMediaController.setAnchorView(mSurfaceView);
10510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            //Will be enabled when prepared
10610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mMediaController.setEnabled(false);
10710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
10810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
10910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
11010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
11110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void decideDisplayMode() {
11210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mPlayer.setDisplay(mSurfaceHolder);
11310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
11410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
11510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
11610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void prepareForFullScreen() {
11710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        // So in full screen, we reset the MediaPlayer
11810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mPlayer.reset();
11910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        setMediaController(new MediaController(mProxy.getContext()));
12010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
12110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        prepareDataAndDisplayMode(mProxy);
12210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
12310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
12410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
12510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private void toggleMediaControlsVisiblity() {
12610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (mMediaController.isShowing()) {
12710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mMediaController.hide();
12810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        } else {
12910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mMediaController.show();
13010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
13110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
13210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
13310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
13410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void onPrepared(MediaPlayer mp) {
13510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        super.onPrepared(mp);
13610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
13710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mSurfaceView.setOnTouchListener(this);
13810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        // Get the capabilities of the player for this stream
13910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        Metadata data = mp.getMetadata(MediaPlayer.METADATA_ALL,
14010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                MediaPlayer.BYPASS_METADATA_FILTER);
14110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (data != null) {
14210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mCanPause = !data.has(Metadata.PAUSE_AVAILABLE)
14310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                    || data.getBoolean(Metadata.PAUSE_AVAILABLE);
14410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mCanSeekBack = !data.has(Metadata.SEEK_BACKWARD_AVAILABLE)
14510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                    || data.getBoolean(Metadata.SEEK_BACKWARD_AVAILABLE);
14610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mCanSeekForward = !data.has(Metadata.SEEK_FORWARD_AVAILABLE)
14710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                    || data.getBoolean(Metadata.SEEK_FORWARD_AVAILABLE);
14810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        } else {
14910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mCanPause = mCanSeekBack = mCanSeekForward = true;
15010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
15110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
15210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        // mMediaController status depends on the Metadata result, so put it
15310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        // after reading the MetaData
15410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (mMediaController != null) {
15510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mMediaController.setEnabled(true);
15610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            // If paused , should show the controller for ever!
15710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            if (getAutostart())
15810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                mMediaController.show();
15910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            else
16010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                mMediaController.show(0);
16110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
16210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
16310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (mProgressView != null) {
16410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mProgressView.setVisibility(View.GONE);
16510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mLayout.removeView(mProgressView);
16610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mProgressView = null;
16710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
16810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
16910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
17010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
17110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private final WebChromeClient.CustomViewCallback mCallback =
17210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        new WebChromeClient.CustomViewCallback() {
17310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            public void onCustomViewHidden() {
17410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                // It listens to SurfaceHolder.Callback.SurfaceDestroyed event
17510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                // which happens when the video view is detached from its parent
17610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                // view. This happens in the WebChromeClient before this method
17710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                // is invoked.
17810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                mTimer.cancel();
17910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                mTimer = null;
18010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
18110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                pauseAndDispatch(mProxy);
18210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
18310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                mLayout.removeView(getSurfaceView());
18410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
18510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                if (mProgressView != null) {
18610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                    mLayout.removeView(mProgressView);
18710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                    mProgressView = null;
18810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                }
18910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                mLayout = null;
19010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                // Re enable plugin views.
19110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                mProxy.getWebView().getViewManager().showAll();
19210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
19310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                mProxy = null;
19410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            }
19510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        };
19610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
19710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
19810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void enterFullScreenVideoState(int layerId,
19910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            HTML5VideoViewProxy proxy, WebView webView) {
20010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mFullScreenMode = FULLSCREEN_SURFACECREATING;
20110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mCurrentBufferPercentage = 0;
20210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
20310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mProxy = proxy;
20410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
20510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mSurfaceView.getHolder().addCallback(mSHCallback);
20610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
20710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mSurfaceView.setFocusable(true);
20810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mSurfaceView.setFocusableInTouchMode(true);
20910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mSurfaceView.requestFocus();
21010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
21110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        // Create a FrameLayout that will contain the VideoView and the
21210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        // progress view (if any).
21310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mLayout = new FrameLayout(mProxy.getContext());
21410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
21510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                            ViewGroup.LayoutParams.WRAP_CONTENT,
21610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                            ViewGroup.LayoutParams.WRAP_CONTENT,
21710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                            Gravity.CENTER);
21810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
21910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mLayout.addView(getSurfaceView(), layoutParams);
22010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
22110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mLayout.setVisibility(View.VISIBLE);
22210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
22310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        WebChromeClient client = webView.getWebChromeClient();
22410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        client.onShowCustomView(mLayout, mCallback);
22510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        // Plugins like Flash will draw over the video so hide
22610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        // them while we're playing.
22710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mProxy.getWebView().getViewManager().hideAll();
22810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
22910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mProgressView = client.getVideoLoadingProgressView();
23010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (mProgressView != null) {
23110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mLayout.addView(mProgressView, layoutParams);
23210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mProgressView.setVisibility(View.VISIBLE);
23310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
23410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
23510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
23610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
23710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    /**
23810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu     * @return true when we are in full screen mode, even the surface not fully
23910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu     * created.
24010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu     */
24110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public boolean isFullScreenMode() {
24210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return true;
24310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
24410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
24510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // MediaController FUNCTIONS:
24610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
24710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public boolean canPause() {
24810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return mCanPause;
24910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
25010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
25110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
25210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public boolean canSeekBackward() {
25310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return mCanSeekBack;
25410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
25510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
25610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
25710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public boolean canSeekForward() {
25810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return mCanSeekForward;
25910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
26010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
26110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
26210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public int getBufferPercentage() {
26310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (mPlayer != null) {
26410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            return mCurrentBufferPercentage;
26510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
26610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    return 0;
26710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
26810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
26910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // Other listeners functions:
27010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener =
27110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        new MediaPlayer.OnBufferingUpdateListener() {
27210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        public void onBufferingUpdate(MediaPlayer mp, int percent) {
27310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mCurrentBufferPercentage = percent;
27410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
27510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    };
27610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
27710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    @Override
27810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public boolean onTouch(View v, MotionEvent event) {
27910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (mFullScreenMode >= FULLSCREEN_SURFACECREATED
28010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu                && mMediaController != null) {
28110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            toggleMediaControlsVisiblity();
28210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
28310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return false;
28410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
28510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
28610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu}
287