15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package org.chromium.content.browser;
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.app.Activity;
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.app.AlertDialog;
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.Context;
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.DialogInterface;
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.graphics.Color;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.os.Handler;
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.os.Message;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.os.RemoteException;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.util.Log;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.Gravity;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.KeyEvent;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.MotionEvent;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.Surface;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.SurfaceHolder;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.SurfaceView;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.View;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.ViewGroup;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.widget.FrameLayout;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.widget.LinearLayout;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.widget.MediaController;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.widget.ProgressBar;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.widget.TextView;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.lang.ref.WeakReference;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.chromium.base.CalledByNative;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.chromium.base.JNINamespace;
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import org.chromium.base.ThreadUtils;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.content.common.IChildProcessService;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.content.R;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@JNINamespace("content")
397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochpublic class ContentVideoView
407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        extends FrameLayout
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        implements ContentVideoViewControls.Delegate,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SurfaceHolder.Callback, View.OnTouchListener, View.OnKeyListener {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String TAG = "ContentVideoView";
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Do not change these values without updating their counterparts
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * in include/media/mediaplayer.h!
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int MEDIA_NOP = 0; // interface test message
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int MEDIA_PREPARED = 1;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int MEDIA_PLAYBACK_COMPLETE = 2;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int MEDIA_BUFFERING_UPDATE = 3;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int MEDIA_SEEK_COMPLETE = 4;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int MEDIA_SET_VIDEO_SIZE = 5;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int MEDIA_ERROR = 100;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int MEDIA_INFO = 200;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    /**
59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch     * Keep these error codes in sync with the code we defined in
60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch     * MediaPlayerListener.java.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 2;
63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    public static final int MEDIA_ERROR_INVALID_CODE = 3;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // all possible internal states
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int STATE_ERROR              = -1;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int STATE_IDLE               = 0;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int STATE_PLAYING            = 1;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int STATE_PAUSED             = 2;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int STATE_PLAYBACK_COMPLETED = 3;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private SurfaceHolder mSurfaceHolder;
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private int mVideoWidth;
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private int mVideoHeight;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private int mCurrentBufferPercentage;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private int mDuration;
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    private ContentVideoViewControls mControls;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private boolean mCanPause;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private boolean mCanSeekBack;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private boolean mCanSeekForward;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Native pointer to C++ ContentVideoView object.
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private int mNativeContentVideoView;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // webkit should have prepared the media
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private int mCurrentState = STATE_IDLE;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Strings for displaying media player errors
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private String mPlaybackErrorText;
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private String mUnknownErrorText;
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private String mErrorButton;
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private String mErrorTitle;
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private String mVideoLoadingText;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This view will contain the video.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private VideoSurfaceView mVideoSurfaceView;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Progress view when the video is loading.
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private View mProgressView;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private Surface mSurface;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private ContentVideoViewClient mClient;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private class VideoSurfaceView extends SurfaceView {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        public VideoSurfaceView(Context context) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            super(context);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @Override
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            if (mVideoWidth == 0 && mVideoHeight == 0) {
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                setMeasuredDimension(1, 1);
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (mVideoWidth > 0 && mVideoHeight > 0) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if ( mVideoWidth * height  > width * mVideoHeight ) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    height = width * mVideoHeight / mVideoWidth;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                } else if ( mVideoWidth * height  < width * mVideoHeight ) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    width = height * mVideoWidth / mVideoHeight;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            setMeasuredDimension(width, height);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static class ProgressView extends LinearLayout {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        private ProgressBar mProgressBar;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        private TextView mTextView;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        public ProgressView(Context context, String videoLoadingText) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            super(context);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            setOrientation(LinearLayout.VERTICAL);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            setLayoutParams(new LinearLayout.LayoutParams(
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    LinearLayout.LayoutParams.WRAP_CONTENT,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    LinearLayout.LayoutParams.WRAP_CONTENT));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mProgressBar = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mTextView = new TextView(context);
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            mTextView.setText(videoLoadingText);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            addView(mProgressBar);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            addView(mTextView);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    private static class FullScreenControls implements ContentVideoViewControls {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        View mVideoView;
1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        MediaController mMediaController;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        public FullScreenControls(Context context, View video) {
1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mMediaController = new MediaController(context);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mVideoView = video;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @Override
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        public void show() {
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mMediaController.show();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (mVideoView != null) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mVideoView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @Override
1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        public void show(int timeout_ms) {
1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mMediaController.show(timeout_ms);
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        @Override
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        public void hide() {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (mVideoView != null) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mVideoView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mMediaController.hide();
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        @Override
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        public boolean isShowing() {
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            return mMediaController.isShowing();
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        @Override
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        public void setEnabled(boolean enabled) {
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mMediaController.setEnabled(enabled);
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        @Override
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        public void setDelegate(Delegate delegate) {
1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mMediaController.setMediaPlayer(delegate);
1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        @Override
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        public void setAnchorView(View view) {
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mMediaController.setAnchorView(view);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private Runnable mExitFullscreenRunnable = new Runnable() {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @Override
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        public void run() {
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            exitFullscreen(true);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private ContentVideoView(Context context, int nativeContentVideoView,
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            ContentVideoViewClient client) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        super(context);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mNativeContentVideoView = nativeContentVideoView;
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        mClient = client;
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        initResources(context);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mCurrentBufferPercentage = 0;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVideoSurfaceView = new VideoSurfaceView(context);
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        setBackgroundColor(Color.BLACK);
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        showContentVideoView();
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        setVisibility(View.VISIBLE);
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        mClient.onShowCustomView(this);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private void initResources(Context context) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mPlaybackErrorText != null) return;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mPlaybackErrorText = context.getString(
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                org.chromium.content.R.string.media_player_error_text_invalid_progressive_playback);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mUnknownErrorText = context.getString(
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                org.chromium.content.R.string.media_player_error_text_unknown);
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mErrorButton = context.getString(
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                org.chromium.content.R.string.media_player_error_button);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mErrorTitle = context.getString(
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                org.chromium.content.R.string.media_player_error_title);
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mVideoLoadingText = context.getString(
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                org.chromium.content.R.string.media_player_loading_video);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private void showContentVideoView() {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ViewGroup.LayoutParams.WRAP_CONTENT,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ViewGroup.LayoutParams.WRAP_CONTENT,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                Gravity.CENTER);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.addView(mVideoSurfaceView, layoutParams);
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        View progressView = mClient.getVideoLoadingProgressView();
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (progressView != null) {
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            mProgressView = progressView;
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            mProgressView = new ProgressView(getContext(), mVideoLoadingText);
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.addView(mProgressView, layoutParams);
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mVideoSurfaceView.setZOrderOnTop(true);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVideoSurfaceView.setOnKeyListener(this);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVideoSurfaceView.setOnTouchListener(this);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVideoSurfaceView.getHolder().addCallback(this);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVideoSurfaceView.setFocusable(true);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVideoSurfaceView.setFocusableInTouchMode(true);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVideoSurfaceView.requestFocus();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @CalledByNative
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void onMediaPlayerError(int errorType) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Log.d(TAG, "OnMediaPlayerError: " + errorType);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mCurrentState == STATE_ERROR || mCurrentState == STATE_PLAYBACK_COMPLETED) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        // Ignore some invalid error codes.
266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        if (errorType == MEDIA_ERROR_INVALID_CODE) {
267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            return;
268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        }
269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mCurrentState = STATE_ERROR;
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (mControls != null) {
2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls.hide();
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Pop up an error dialog so the user knows that
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * something bad has happened. Only try and pop up the dialog
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * if we're attached to a window. When we're going away and no
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * longer have a window, don't bother showing the user an error.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * TODO(qinmin): We need to review whether this Dialog is OK with
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * the rest of the browser UI elements.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (getWindowToken() != null) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            String message;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (errorType == MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                message = mPlaybackErrorText;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                message = mUnknownErrorText;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            new AlertDialog.Builder(getContext())
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                .setTitle(mErrorTitle)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                .setMessage(message)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                .setPositiveButton(mErrorButton,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        new DialogInterface.OnClickListener() {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    public void onClick(DialogInterface dialog, int whichButton) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /* Inform that the video is over.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         */
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        onCompletion();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                })
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                .setCancelable(false)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                .show();
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @CalledByNative
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private void onVideoSizeChanged(int width, int height) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVideoWidth = width;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVideoHeight = height;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mVideoWidth != 0 && mVideoHeight != 0) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mVideoSurfaceView.getHolder().setFixedSize(mVideoWidth, mVideoHeight);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @CalledByNative
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private void onBufferingUpdate(int percent) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mCurrentBufferPercentage = percent;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @CalledByNative
323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private void onPlaybackComplete() {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        onCompletion();
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @CalledByNative
328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private void onUpdateMediaMetadata(
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int videoWidth,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int videoHeight,
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int duration,
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            boolean canPause,
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            boolean canSeekBack,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            boolean canSeekForward) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mProgressView.setVisibility(View.GONE);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mDuration = duration;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mCanPause = canPause;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mCanSeekBack = canSeekBack;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mCanSeekForward = canSeekForward;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mCurrentState = isPlaying() ? STATE_PLAYING : STATE_PAUSED;
3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (mControls != null) {
3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls.setEnabled(true);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // If paused , should show the controller for ever.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (isPlaying())
3457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                mControls.show();
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
3477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                mControls.show(0);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        onVideoSizeChanged(videoWidth, videoHeight);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVideoSurfaceView.setFocusable(true);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVideoSurfaceView.setFocusableInTouchMode(true);
3577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (isInPlaybackState() && mControls != null) {
3587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls.show();
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void surfaceCreated(SurfaceHolder holder) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mSurfaceHolder = holder;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        openVideo();
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void surfaceDestroyed(SurfaceHolder holder) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mNativeContentVideoView != 0) {
371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            nativeSetSurface(mNativeContentVideoView, null);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        mSurfaceHolder = null;
374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        post(mExitFullscreenRunnable);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    private void setControls(ContentVideoViewControls controls) {
3787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (mControls != null) {
3797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls.hide();
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        mControls = controls;
3827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        attachControls();
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    private void attachControls() {
3867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (mControls != null) {
3877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls.setDelegate(this);
3887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls.setAnchorView(mVideoSurfaceView);
3897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls.setEnabled(false);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @CalledByNative
394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private void openVideo() {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mSurfaceHolder != null) {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mCurrentState = STATE_IDLE;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mCurrentBufferPercentage = 0;
3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            ContentVideoViewControls controls = mClient.createControls();
3997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            if (controls == null) {
4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                controls = new FullScreenControls(getContext(), this);
4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            }
4027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            setControls(controls);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (mNativeContentVideoView != 0) {
404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                nativeUpdateMediaMetadata(mNativeContentVideoView);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                nativeSetSurface(mNativeContentVideoView,
406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        mSurfaceHolder.getSurface());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private void onCompletion() {
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mCurrentState = STATE_PLAYBACK_COMPLETED;
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (mControls != null) {
4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls.hide();
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean onTouch(View v, MotionEvent event) {
4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (isInPlaybackState() && mControls != null &&
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                event.getAction() == MotionEvent.ACTION_DOWN) {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toggleMediaControlsVisiblity();
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean onTrackballEvent(MotionEvent ev) {
4297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (isInPlaybackState() && mControls != null) {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toggleMediaControlsVisiblity();
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean onKey(View v, int keyCode, KeyEvent event) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        boolean isKeyCodeSupported = keyCode != KeyEvent.KEYCODE_BACK &&
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     keyCode != KeyEvent.KEYCODE_VOLUME_UP &&
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     keyCode != KeyEvent.KEYCODE_VOLUME_DOWN &&
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     keyCode != KeyEvent.KEYCODE_VOLUME_MUTE &&
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     keyCode != KeyEvent.KEYCODE_CALL &&
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     keyCode != KeyEvent.KEYCODE_MENU &&
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     keyCode != KeyEvent.KEYCODE_SEARCH &&
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     keyCode != KeyEvent.KEYCODE_ENDCALL;
4457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (isInPlaybackState() && isKeyCodeSupported && mControls != null) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK ||
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (isPlaying()) {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    pause();
4507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    mControls.show();
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                } else {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    start();
4537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    mControls.hide();
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return true;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (!isPlaying()) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    start();
4597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    mControls.hide();
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return true;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    || keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (isPlaying()) {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    pause();
4667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    mControls.show();
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return true;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                toggleMediaControlsVisiblity();
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            exitFullscreen(false);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return true;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else if (keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_SEARCH) {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return true;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return super.onKeyDown(keyCode, event);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private void toggleMediaControlsVisiblity() {
4827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (mControls.isShowing()) {
4837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls.hide();
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
4857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls.show();
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private boolean isInPlaybackState() {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return (mCurrentState != STATE_ERROR && mCurrentState != STATE_IDLE);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    @Override
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void start() {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (isInPlaybackState()) {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (mNativeContentVideoView != 0) {
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                nativePlay(mNativeContentVideoView);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mCurrentState = STATE_PLAYING;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    @Override
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void pause() {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (isInPlaybackState()) {
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (isPlaying()) {
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (mNativeContentVideoView != 0) {
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    nativePause(mNativeContentVideoView);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mCurrentState = STATE_PAUSED;
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cache duration as mDuration for faster access
516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    @Override
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public int getDuration() {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (isInPlaybackState()) {
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (mDuration > 0) {
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return mDuration;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (mNativeContentVideoView != 0) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mDuration = nativeGetDurationInMilliSeconds(mNativeContentVideoView);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mDuration = 0;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return mDuration;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mDuration = -1;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return mDuration;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    @Override
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public int getCurrentPosition() {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (isInPlaybackState() && mNativeContentVideoView != 0) {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return nativeGetCurrentPosition(mNativeContentVideoView);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 0;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    @Override
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void seekTo(int msec) {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mNativeContentVideoView != 0) {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            nativeSeekTo(mNativeContentVideoView, msec);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    @Override
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean isPlaying() {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return mNativeContentVideoView != 0 && nativeIsPlaying(mNativeContentVideoView);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    @Override
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public int getBufferPercentage() {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return mCurrentBufferPercentage;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    @Override
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean canPause() {
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return mCanPause;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    @Override
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean canSeekBackward() {
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return mCanSeekBack;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    @Override
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean canSeekForward() {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return mCanSeekForward;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5732d519ce2457219605d4f472da8d2ffd469796035Marco Nelissen    public int getAudioSessionId() {
5742d519ce2457219605d4f472da8d2ffd469796035Marco Nelissen        return 0;
5752d519ce2457219605d4f472da8d2ffd469796035Marco Nelissen    }
5762d519ce2457219605d4f472da8d2ffd469796035Marco Nelissen
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @CalledByNative
578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private static ContentVideoView createContentVideoView(
579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            Context context, int nativeContentVideoView, ContentVideoViewClient client) {
580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        ThreadUtils.assertOnUiThread();
581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        // The context needs be Activity to create the ContentVideoView correctly.
582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        if (!(context instanceof Activity)) {
583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            Log.w(TAG, "Wrong type of context, can't create fullscreen video");
584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            return null;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return new ContentVideoView(context, nativeContentVideoView, client);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    private void removeControls() {
5907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (mControls != null) {
5917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls.setEnabled(false);
5927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls.hide();
5937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            mControls = null;
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void removeSurfaceView() {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        removeView(mVideoSurfaceView);
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        removeView(mProgressView);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVideoSurfaceView = null;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mProgressView = null;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    public void exitFullscreen(boolean relaseMediaPlayer) {
605a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        destroyContentVideoView(false);
606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        if (mNativeContentVideoView != 0) {
607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            nativeExitFullscreen(mNativeContentVideoView, relaseMediaPlayer);
608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            mNativeContentVideoView = 0;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /**
613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)     * This method shall only be called by native and exitFullscreen,
614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)     * To exit fullscreen, use exitFullscreen in Java.
615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)     */
616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    @CalledByNative
617a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    private void destroyContentVideoView(boolean nativeViewDestroyed) {
618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        if (mVideoSurfaceView != null) {
6197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            removeControls();
620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            removeSurfaceView();
621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            setVisibility(View.GONE);
62209a5f9adc1f076db40e62b6ba3bd6758a0eec16dboliu@chromium.org
62309a5f9adc1f076db40e62b6ba3bd6758a0eec16dboliu@chromium.org            // To prevent re-entrance, call this after removeSurfaceView.
62409a5f9adc1f076db40e62b6ba3bd6758a0eec16dboliu@chromium.org            mClient.onDestroyContentVideoView();
625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        }
626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        if (nativeViewDestroyed) {
627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            mNativeContentVideoView = 0;
628a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        }
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    public static ContentVideoView getContentVideoView() {
632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return nativeGetSingletonJavaContentVideoView();
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean onTouchEvent(MotionEvent ev) {
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean onKeyDown(int keyCode, KeyEvent event) {
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            exitFullscreen(false);
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return true;
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return super.onKeyDown(keyCode, event);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    private static native ContentVideoView nativeGetSingletonJavaContentVideoView();
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private native void nativeExitFullscreen(int nativeContentVideoView, boolean relaseMediaPlayer);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private native int nativeGetCurrentPosition(int nativeContentVideoView);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private native int nativeGetDurationInMilliSeconds(int nativeContentVideoView);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private native void nativeUpdateMediaMetadata(int nativeContentVideoView);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private native int nativeGetVideoWidth(int nativeContentVideoView);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private native int nativeGetVideoHeight(int nativeContentVideoView);
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private native boolean nativeIsPlaying(int nativeContentVideoView);
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private native void nativePause(int nativeContentVideoView);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private native void nativePlay(int nativeContentVideoView);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private native void nativeSeekTo(int nativeContentVideoView, int msec);
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private native void nativeSetSurface(int nativeContentVideoView, Surface surface);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
662