This source file includes following definitions.
- JNINamespace
- onMeasure
- initResources
- showContentVideoView
- getSurfaceView
- onMediaPlayerError
- onVideoSizeChanged
- onBufferingUpdate
- onPlaybackComplete
- onUpdateMediaMetadata
- surfaceChanged
- surfaceCreated
- surfaceDestroyed
- openVideo
- onCompletion
- isInPlaybackState
- start
- pause
- getDuration
- getCurrentPosition
- seekTo
- isPlaying
- createContentVideoView
- removeSurfaceView
- exitFullscreen
- onExitFullscreen
- destroyContentVideoView
- getContentVideoView
- onKeyUp
- acquireAnchorView
- setAnchorViewPosition
- releaseAnchorView
- getNativeViewAndroid
- nativeGetSingletonJavaContentVideoView
- nativeExitFullscreen
- nativeGetCurrentPosition
- nativeGetDurationInMilliSeconds
- nativeRequestMediaMetadata
- nativeGetVideoWidth
- nativeGetVideoHeight
- nativeIsPlaying
- nativePause
- nativePlay
- nativeSeekTo
- nativeSetSurface
package org.chromium.content.browser;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.base.ThreadUtils;
import org.chromium.ui.base.ViewAndroid;
import org.chromium.ui.base.ViewAndroidDelegate;
import org.chromium.ui.base.WindowAndroid;
@JNINamespace("content")
public class ContentVideoView extends FrameLayout
implements SurfaceHolder.Callback, ViewAndroidDelegate {
private static final String TAG = "ContentVideoView";
private static final int MEDIA_NOP = 0;
private static final int MEDIA_PREPARED = 1;
private static final int MEDIA_PLAYBACK_COMPLETE = 2;
private static final int MEDIA_BUFFERING_UPDATE = 3;
private static final int MEDIA_SEEK_COMPLETE = 4;
private static final int MEDIA_SET_VIDEO_SIZE = 5;
private static final int MEDIA_ERROR = 100;
private static final int MEDIA_INFO = 200;
public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 2;
public static final int MEDIA_ERROR_INVALID_CODE = 3;
private static final int STATE_ERROR = -1;
private static final int STATE_IDLE = 0;
private static final int STATE_PLAYING = 1;
private static final int STATE_PAUSED = 2;
private static final int STATE_PLAYBACK_COMPLETED = 3;
private SurfaceHolder mSurfaceHolder;
private int mVideoWidth;
private int mVideoHeight;
private int mDuration;
private long mNativeContentVideoView;
private int mCurrentState = STATE_IDLE;
private String mPlaybackErrorText;
private String mUnknownErrorText;
private String mErrorButton;
private String mErrorTitle;
private String mVideoLoadingText;
private VideoSurfaceView mVideoSurfaceView;
private View mProgressView;
private ViewAndroid mViewAndroid;
private final ContentVideoViewClient mClient;
private class VideoSurfaceView extends SurfaceView {
public VideoSurfaceView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
if (mVideoWidth > 0 && mVideoHeight > 0) {
if (mVideoWidth * height > width * mVideoHeight) {
height = width * mVideoHeight / mVideoWidth;
} else if (mVideoWidth * height < width * mVideoHeight) {
width = height * mVideoWidth / mVideoHeight;
}
}
setMeasuredDimension(width, height);
}
}
private static class ProgressView extends LinearLayout {
private final ProgressBar mProgressBar;
private final TextView mTextView;
public ProgressView(Context context, String videoLoadingText) {
super(context);
setOrientation(LinearLayout.VERTICAL);
setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
mProgressBar = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge);
mTextView = new TextView(context);
mTextView.setText(videoLoadingText);
addView(mProgressBar);
addView(mTextView);
}
}
private final Runnable mExitFullscreenRunnable = new Runnable() {
@Override
public void run() {
exitFullscreen(true);
}
};
protected ContentVideoView(Context context, long nativeContentVideoView,
ContentVideoViewClient client) {
super(context);
mNativeContentVideoView = nativeContentVideoView;
mViewAndroid = new ViewAndroid(new WindowAndroid(context.getApplicationContext()), this);
mClient = client;
initResources(context);
mVideoSurfaceView = new VideoSurfaceView(context);
showContentVideoView();
setVisibility(View.VISIBLE);
mClient.onShowCustomView(this);
}
private void initResources(Context context) {
if (mPlaybackErrorText != null) return;
mPlaybackErrorText = context.getString(
org.chromium.content.R.string.media_player_error_text_invalid_progressive_playback);
mUnknownErrorText = context.getString(
org.chromium.content.R.string.media_player_error_text_unknown);
mErrorButton = context.getString(
org.chromium.content.R.string.media_player_error_button);
mErrorTitle = context.getString(
org.chromium.content.R.string.media_player_error_title);
mVideoLoadingText = context.getString(
org.chromium.content.R.string.media_player_loading_video);
}
protected void showContentVideoView() {
mVideoSurfaceView.getHolder().addCallback(this);
this.addView(mVideoSurfaceView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
Gravity.CENTER));
mProgressView = mClient.getVideoLoadingProgressView();
if (mProgressView == null) {
mProgressView = new ProgressView(getContext(), mVideoLoadingText);
}
this.addView(mProgressView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
Gravity.CENTER));
}
protected SurfaceView getSurfaceView() {
return mVideoSurfaceView;
}
@CalledByNative
public void onMediaPlayerError(int errorType) {
Log.d(TAG, "OnMediaPlayerError: " + errorType);
if (mCurrentState == STATE_ERROR || mCurrentState == STATE_PLAYBACK_COMPLETED) {
return;
}
if (errorType == MEDIA_ERROR_INVALID_CODE) {
return;
}
mCurrentState = STATE_ERROR;
if (getWindowToken() != null) {
String message;
if (errorType == MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
message = mPlaybackErrorText;
} else {
message = mUnknownErrorText;
}
try {
new AlertDialog.Builder(getContext())
.setTitle(mErrorTitle)
.setMessage(message)
.setPositiveButton(mErrorButton,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
onCompletion();
}
})
.setCancelable(false)
.show();
} catch (RuntimeException e) {
Log.e(TAG, "Cannot show the alert dialog, error message: " + message, e);
}
}
}
@CalledByNative
private void onVideoSizeChanged(int width, int height) {
mVideoWidth = width;
mVideoHeight = height;
mVideoSurfaceView.getHolder().setFixedSize(mVideoWidth, mVideoHeight);
}
@CalledByNative
protected void onBufferingUpdate(int percent) {
}
@CalledByNative
private void onPlaybackComplete() {
onCompletion();
}
@CalledByNative
protected void onUpdateMediaMetadata(
int videoWidth,
int videoHeight,
int duration,
boolean canPause,
boolean canSeekBack,
boolean canSeekForward) {
mDuration = duration;
mProgressView.setVisibility(View.GONE);
mCurrentState = isPlaying() ? STATE_PLAYING : STATE_PAUSED;
onVideoSizeChanged(videoWidth, videoHeight);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mSurfaceHolder = holder;
openVideo();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mNativeContentVideoView != 0) {
nativeSetSurface(mNativeContentVideoView, null);
}
mSurfaceHolder = null;
post(mExitFullscreenRunnable);
}
@CalledByNative
protected void openVideo() {
if (mSurfaceHolder != null) {
mCurrentState = STATE_IDLE;
if (mNativeContentVideoView != 0) {
nativeRequestMediaMetadata(mNativeContentVideoView);
nativeSetSurface(mNativeContentVideoView,
mSurfaceHolder.getSurface());
}
}
}
protected void onCompletion() {
mCurrentState = STATE_PLAYBACK_COMPLETED;
}
protected boolean isInPlaybackState() {
return (mCurrentState != STATE_ERROR && mCurrentState != STATE_IDLE);
}
protected void start() {
if (isInPlaybackState()) {
if (mNativeContentVideoView != 0) {
nativePlay(mNativeContentVideoView);
}
mCurrentState = STATE_PLAYING;
}
}
protected void pause() {
if (isInPlaybackState()) {
if (isPlaying()) {
if (mNativeContentVideoView != 0) {
nativePause(mNativeContentVideoView);
}
mCurrentState = STATE_PAUSED;
}
}
}
protected int getDuration() {
if (isInPlaybackState()) {
if (mDuration > 0) {
return mDuration;
}
if (mNativeContentVideoView != 0) {
mDuration = nativeGetDurationInMilliSeconds(mNativeContentVideoView);
} else {
mDuration = 0;
}
return mDuration;
}
mDuration = -1;
return mDuration;
}
protected int getCurrentPosition() {
if (isInPlaybackState() && mNativeContentVideoView != 0) {
return nativeGetCurrentPosition(mNativeContentVideoView);
}
return 0;
}
protected void seekTo(int msec) {
if (mNativeContentVideoView != 0) {
nativeSeekTo(mNativeContentVideoView, msec);
}
}
protected boolean isPlaying() {
return mNativeContentVideoView != 0 && nativeIsPlaying(mNativeContentVideoView);
}
@CalledByNative
private static ContentVideoView createContentVideoView(
Context context, long nativeContentVideoView, ContentVideoViewClient client,
boolean legacy) {
ThreadUtils.assertOnUiThread();
if (!(context instanceof Activity)) {
Log.w(TAG, "Wrong type of context, can't create fullscreen video");
return null;
}
if (legacy) {
return new ContentVideoViewLegacy(context, nativeContentVideoView, client);
} else {
return new ContentVideoView(context, nativeContentVideoView, client);
}
}
public void removeSurfaceView() {
removeView(mVideoSurfaceView);
removeView(mProgressView);
mVideoSurfaceView = null;
mProgressView = null;
}
public void exitFullscreen(boolean relaseMediaPlayer) {
destroyContentVideoView(false);
if (mNativeContentVideoView != 0) {
nativeExitFullscreen(mNativeContentVideoView, relaseMediaPlayer);
mNativeContentVideoView = 0;
}
}
@CalledByNative
private void onExitFullscreen() {
exitFullscreen(false);
}
@CalledByNative
protected void destroyContentVideoView(boolean nativeViewDestroyed) {
if (mVideoSurfaceView != null) {
removeSurfaceView();
setVisibility(View.GONE);
mClient.onDestroyContentVideoView();
}
if (nativeViewDestroyed) {
mNativeContentVideoView = 0;
}
}
public static ContentVideoView getContentVideoView() {
return nativeGetSingletonJavaContentVideoView();
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
exitFullscreen(false);
return true;
}
return super.onKeyUp(keyCode, event);
}
@Override
public View acquireAnchorView() {
View anchorView = new View(getContext());
addView(anchorView);
return anchorView;
}
@Override
public void setAnchorViewPosition(View view, float x, float y, float width, float height) {
Log.e(TAG, "setAnchorViewPosition isn't implemented");
}
@Override
public void releaseAnchorView(View anchorView) {
removeView(anchorView);
}
@CalledByNative
private long getNativeViewAndroid() {
return mViewAndroid.getNativePointer();
}
private static native ContentVideoView nativeGetSingletonJavaContentVideoView();
private native void nativeExitFullscreen(long nativeContentVideoView,
boolean relaseMediaPlayer);
private native int nativeGetCurrentPosition(long nativeContentVideoView);
private native int nativeGetDurationInMilliSeconds(long nativeContentVideoView);
private native void nativeRequestMediaMetadata(long nativeContentVideoView);
private native int nativeGetVideoWidth(long nativeContentVideoView);
private native int nativeGetVideoHeight(long nativeContentVideoView);
private native boolean nativeIsPlaying(long nativeContentVideoView);
private native void nativePause(long nativeContentVideoView);
private native void nativePlay(long nativeContentVideoView);
private native void nativeSeekTo(long nativeContentVideoView, int msec);
private native void nativeSetSurface(long nativeContentVideoView, Surface surface);
}