HTML5VideoView.java revision 158fbdb29b8fdda57f942ec2056d908714c326be
1661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
2661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhupackage android.webkit;
3661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
4661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport android.graphics.SurfaceTexture;
5661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport android.media.MediaPlayer;
6661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport android.util.Log;
710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.view.SurfaceView;
8661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport android.webkit.HTML5VideoViewProxy;
9661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport java.io.IOException;
1010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport java.util.HashMap;
11661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport java.util.Map;
1210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport java.util.Timer;
1310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport java.util.TimerTask;
14661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
15661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu/**
16661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu * @hide This is only used by the browser
17661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu */
18661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhupublic class HTML5VideoView implements MediaPlayer.OnPreparedListener{
19661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
2010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected static final String LOGTAG = "HTML5VideoView";
2110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
2210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected static final String COOKIE = "Cookie";
2310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected static final String HIDE_URL_LOGS = "x-hide-urls-from-log";
24661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
25661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // For handling the seekTo before prepared, we need to know whether or not
26661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // the video is prepared. Therefore, we differentiate the state between
27661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // prepared and not prepared.
28661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // When the video is not prepared, we will have to save the seekTo time,
29661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // and use it when prepared to play.
30265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu    // NOTE: these values are in sync with VideoLayerAndroid.h in webkit side.
31265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu    // Please keep them in sync when changed.
32265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu    static final int STATE_INITIALIZED        = 0;
33265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu    static final int STATE_NOTPREPARED        = 1;
34265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu    static final int STATE_PREPARED           = 2;
35265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu    static final int STATE_PLAYING            = 3;
3610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected int mCurrentState;
37661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
3810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected HTML5VideoViewProxy mProxy;
39661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
40661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // Save the seek time when not prepared. This can happen when switching
41661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // video besides initial load.
4210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected int mSaveSeekTime;
43661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
44661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // This is used to find the VideoLayer on the native side.
4510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected int mVideoLayerId;
46661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
47661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // Every video will have one MediaPlayer. Given the fact we only have one
48661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // SurfaceTexture, there is only one MediaPlayer in action. Every time we
49661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // switch videos, a new instance of MediaPlayer will be created in reset().
5010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // Switching between inline and full screen will also create a new instance.
5110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected MediaPlayer mPlayer;
5210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
5310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // This will be set up every time we create the Video View object.
5410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // Set to true only when switching into full screen while playing
5510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected boolean mAutostart;
5610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
5710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // We need to save such info.
5810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected String mUri;
5910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected Map<String, String> mHeaders;
60661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
6110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // The timer for timeupate events.
6210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // See http://www.whatwg.org/specs/web-apps/current-work/#event-media-timeupdate
6310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected static Timer mTimer;
64661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
6510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // The spec says the timer should fire every 250 ms or less.
6610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private static final int TIMEUPDATE_PERIOD = 250;  // ms
6710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
68158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu    protected boolean mPauseDuringPreparing;
6910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // common Video control FUNCTIONS:
70661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public void start() {
71661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        if (mCurrentState == STATE_PREPARED) {
72cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu            // When replaying the same video, there is no onPrepared call.
73cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu            // Therefore, the timer should be set up here.
74cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu            if (mTimer == null)
75cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu            {
76cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu                mTimer = new Timer();
77cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu                mTimer.schedule(new TimeupdateTask(mProxy), TIMEUPDATE_PERIOD,
78cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu                        TIMEUPDATE_PERIOD);
79cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu            }
80661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu            mPlayer.start();
81661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        }
82661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
83661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
84661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public void pause() {
8510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (mCurrentState == STATE_PREPARED && mPlayer.isPlaying()) {
8610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mPlayer.pause();
87158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu        } else if (mCurrentState == STATE_NOTPREPARED) {
88158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu            mPauseDuringPreparing = true;
8910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
90cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu        // Delete the Timer to stop it since there is no stop call.
9110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (mTimer != null) {
9210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mTimer.purge();
93cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu            mTimer.cancel();
94cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu            mTimer = null;
9510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
96661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
97661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
98661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public int getDuration() {
9910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (mCurrentState == STATE_PREPARED) {
10010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            return mPlayer.getDuration();
10110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        } else {
10210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            return -1;
10310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
104661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
105661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
106661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public int getCurrentPosition() {
10710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (mCurrentState == STATE_PREPARED) {
10810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            return mPlayer.getCurrentPosition();
10910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
11010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return 0;
111661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
112661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
113661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public void seekTo(int pos) {
114661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        if (mCurrentState == STATE_PREPARED)
115661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu            mPlayer.seekTo(pos);
116661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        else
117661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu            mSaveSeekTime = pos;
118661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
119661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
120661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public boolean isPlaying() {
121661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        return mPlayer.isPlaying();
122661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
123661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
124661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public void release() {
125661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        mPlayer.release();
126661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
127661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
128661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public void stopPlayback() {
12910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (mCurrentState == STATE_PREPARED) {
13010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mPlayer.stop();
13110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
132661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
133661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
13410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public boolean getAutostart() {
13510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return mAutostart;
13610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
13710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
138158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu    public boolean getPauseDuringPreparing() {
139158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu        return mPauseDuringPreparing;
140158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu    }
141158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu
14210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // Every time we start a new Video, we create a VideoView and a MediaPlayer
14310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void init(int videoLayerId, int position, boolean autoStart) {
144661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        mPlayer = new MediaPlayer();
145265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu        mCurrentState = STATE_INITIALIZED;
146661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        mProxy = null;
147661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        mVideoLayerId = videoLayerId;
14810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mSaveSeekTime = position;
14910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mAutostart = autoStart;
150cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu        mTimer = null;
151158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu        mPauseDuringPreparing = false;
152661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
153661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
15410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected HTML5VideoView() {
155661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
156661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
15710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    protected static Map<String, String> generateHeaders(String url,
15810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            HTML5VideoViewProxy proxy) {
15910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        boolean isPrivate = proxy.getWebView().isPrivateBrowsingEnabled();
16010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        String cookieValue = CookieManager.getInstance().getCookie(url, isPrivate);
16110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        Map<String, String> headers = new HashMap<String, String>();
16210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (cookieValue != null) {
16310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            headers.put(COOKIE, cookieValue);
16410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
16510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        if (isPrivate) {
16610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            headers.put(HIDE_URL_LOGS, "true");
16710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
168661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
16910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return headers;
170661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
171661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
17210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void setVideoURI(String uri, HTML5VideoViewProxy proxy) {
173661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        // When switching players, surface texture will be reused.
17410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mUri = uri;
17510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        mHeaders = generateHeaders(uri, proxy);
176661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
177661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
178661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // Listeners setup FUNCTIONS:
179661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public void setOnCompletionListener(HTML5VideoViewProxy proxy) {
180661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        mPlayer.setOnCompletionListener(proxy);
181661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
182661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
183661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public void setOnErrorListener(HTML5VideoViewProxy proxy) {
184661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        mPlayer.setOnErrorListener(proxy);
185661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
186661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
187661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public void setOnPreparedListener(HTML5VideoViewProxy proxy) {
188661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        mProxy = proxy;
189661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        mPlayer.setOnPreparedListener(this);
190661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
191661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
19210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // Normally called immediately after setVideoURI. But for full screen,
19310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // this should be after surface holder created
19410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void prepareDataAndDisplayMode(HTML5VideoViewProxy proxy) {
19510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        // SurfaceTexture will be created lazily here for inline mode
19610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        decideDisplayMode();
197661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
19810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        setOnCompletionListener(proxy);
19910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        setOnPreparedListener(proxy);
20010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        setOnErrorListener(proxy);
201661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
20210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        // When there is exception, we could just bail out silently.
20310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        // No Video will be played though. Write the stack for debug
20410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        try {
20510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mPlayer.setDataSource(mUri, mHeaders);
20610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mPlayer.prepareAsync();
20710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        } catch (IllegalArgumentException e) {
20810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            e.printStackTrace();
20910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        } catch (IllegalStateException e) {
21010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            e.printStackTrace();
21110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        } catch (IOException e) {
21210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            e.printStackTrace();
213661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        }
214265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu        mCurrentState = STATE_NOTPREPARED;
215661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
216661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
217661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
21810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // Common code
219661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public int getVideoLayerId() {
220661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        return mVideoLayerId;
221661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
222661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
223265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu
224265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu    public int getCurrentState() {
225265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu        if (mPlayer.isPlaying()) {
226265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu            return STATE_PLAYING;
227265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu        } else {
228265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu            return mCurrentState;
229265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu        }
230265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu    }
231265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu
23210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    private static final class TimeupdateTask extends TimerTask {
23310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        private HTML5VideoViewProxy mProxy;
234661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
23510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        public TimeupdateTask(HTML5VideoViewProxy proxy) {
23610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mProxy = proxy;
23710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
23810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
23910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        @Override
24010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        public void run() {
24110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            mProxy.onTimeupdate();
24210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        }
243661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
244661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
245661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    @Override
246661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public void onPrepared(MediaPlayer mp) {
247661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        mCurrentState = STATE_PREPARED;
248661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        seekTo(mSaveSeekTime);
249cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu        if (mProxy != null) {
250661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu            mProxy.onPrepared(mp);
251cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu        }
252158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu        if (mPauseDuringPreparing) {
253158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu            pauseAndDispatch(mProxy);
254158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu            mPauseDuringPreparing = false;
255158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu        }
256661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
257661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
258661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    // Pause the play and update the play/pause button
259661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    public void pauseAndDispatch(HTML5VideoViewProxy proxy) {
260158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu        pause();
261158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu        if (proxy != null) {
262158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu            proxy.dispatchOnPaused();
263661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu        }
26410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
26510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
26610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // Below are functions that are different implementation on inline and full-
26710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // screen mode. Some are specific to one type, but currently are called
26810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    // directly from the proxy.
26910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void enterFullScreenVideoState(int layerId,
27010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu            HTML5VideoViewProxy proxy, WebView webView) {
27110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
27210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
27310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public boolean isFullScreenMode() {
27410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return false;
27510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
27610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
27710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void decideDisplayMode() {
27810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
27910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
28010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public boolean getReadyToUseSurfTex() {
28110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return false;
28210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
28310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
28410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public SurfaceTexture getSurfaceTexture() {
28510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return null;
28610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
28710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
28810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public void deleteSurfaceTexture() {
28910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    }
29010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu
29110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu    public int getTextureName() {
29210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu        return 0;
293661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu    }
294661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu
295661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu}
296