root/content/public/android/java/src/org/chromium/content/browser/ContentVideoViewLegacy.java

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. onMediaControlsVisibilityChanged
  2. show
  3. hide
  4. showContentVideoView
  5. onMediaPlayerError
  6. onBufferingUpdate
  7. onUpdateMediaMetadata
  8. surfaceChanged
  9. openVideo
  10. onCompletion
  11. onTrackballEvent
  12. toggleMediaControlsVisiblity
  13. destroyContentVideoView
  14. onTouchEvent
  15. setListener

// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.content.browser;

import android.content.Context;
import android.graphics.Color;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.MediaController;

/**
 * Adds Android media controller to ContentVideoView.
 * The sole purpose of this class is to maintain legacy behavior while we test
 * the blink-based media controller.
 * https://code.google.com/p/chromium/issues/detail?id=331966
 */
public class ContentVideoViewLegacy extends ContentVideoView {
    private FullScreenMediaController mMediaController;
    private boolean mCanPause;
    private boolean mCanSeekBackward;
    private boolean mCanSeekForward;
    private int mCurrentBufferPercentage;
    private MediaControlsVisibilityListener mListener;

    /**
     * A listener for changes in the MediaController visibility.
     */
    public interface MediaControlsVisibilityListener {
        /**
         * Callback for when the visibility of the media controls changes.
         *
         * @param shown true if the media controls are shown to the user, false otherwise
         */
        public void onMediaControlsVisibilityChanged(boolean shown);
    }

    private static class FullScreenMediaController extends MediaController {

        final View mVideoView;
        final MediaControlsVisibilityListener mListener;

        /**
         * @param context The context.
         * @param video The full screen video container view.
         * @param listener A listener that listens to the visibility of media controllers.
         */
        public FullScreenMediaController(
                Context context,
                View video,
                MediaControlsVisibilityListener listener) {
            super(context);
            mVideoView = video;
            mListener = listener;
        }

        @Override
        public void show() {
            super.show();
            if (mListener != null) mListener.onMediaControlsVisibilityChanged(true);
            if (mVideoView != null) {
                mVideoView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
            }
        }

        @Override
        public void hide() {
            if (mVideoView != null) {
                mVideoView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
            }
            if (mListener != null)  mListener.onMediaControlsVisibilityChanged(false);
            super.hide();
        }
    }

    ContentVideoViewLegacy(Context context, long nativeContentVideoView,
            ContentVideoViewClient client) {
        super(context, nativeContentVideoView, client);
        setBackgroundColor(Color.BLACK);
        mCurrentBufferPercentage = 0;
    }

    @Override
    protected void showContentVideoView() {
        SurfaceView surfaceView = getSurfaceView();
        surfaceView.setZOrderOnTop(true);
        surfaceView.setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                boolean isKeyCodeSupported = (
                        keyCode != KeyEvent.KEYCODE_BACK &&
                        keyCode != KeyEvent.KEYCODE_VOLUME_UP &&
                        keyCode != KeyEvent.KEYCODE_VOLUME_DOWN &&
                        keyCode != KeyEvent.KEYCODE_VOLUME_MUTE &&
                        keyCode != KeyEvent.KEYCODE_CALL &&
                        keyCode != KeyEvent.KEYCODE_MENU &&
                        keyCode != KeyEvent.KEYCODE_SEARCH &&
                        keyCode != KeyEvent.KEYCODE_ENDCALL);
                if (isInPlaybackState() && isKeyCodeSupported && mMediaController != null) {
                    if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK ||
                            keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {
                        if (isPlaying()) {
                            pause();
                            mMediaController.show();
                        } else {
                            start();
                            mMediaController.hide();
                        }
                        return true;
                    } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) {
                        if (!isPlaying()) {
                            start();
                            mMediaController.hide();
                        }
                        return true;
                    } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP
                            || keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {
                        if (isPlaying()) {
                            pause();
                            mMediaController.show();
                        }
                        return true;
                    } else {
                        toggleMediaControlsVisiblity();
                    }
                } else if (keyCode == KeyEvent.KEYCODE_BACK &&
                        event.getAction() == KeyEvent.ACTION_UP) {
                    exitFullscreen(false);
                    return true;
                } else if (keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_SEARCH) {
                    return true;
                }
                return false;
            }
        });
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (isInPlaybackState() && mMediaController != null &&
                        event.getAction() == MotionEvent.ACTION_DOWN) {
                    toggleMediaControlsVisiblity();
                }
                return true;
            }
        });
        surfaceView.setFocusable(true);
        surfaceView.setFocusableInTouchMode(true);
        surfaceView.requestFocus();
        super.showContentVideoView();
    }

    @Override
    public void onMediaPlayerError(int errorType) {
        super.onMediaPlayerError(errorType);
        if (errorType == MEDIA_ERROR_INVALID_CODE) return;
        if (mMediaController != null) mMediaController.hide();
    }

    @Override
    protected void onBufferingUpdate(int percent) {
        super.onBufferingUpdate(percent);
        mCurrentBufferPercentage = percent;
    }

    @Override
    protected void onUpdateMediaMetadata(
            int videoWidth,
            int videoHeight,
            int duration,
            boolean canPause,
            boolean canSeekBack,
            boolean canSeekForward) {
        super.onUpdateMediaMetadata(videoWidth, videoHeight, duration,
                canPause, canSeekBack, canSeekForward);
        mCanPause = canPause;
        mCanSeekBackward = canSeekBack;
        mCanSeekForward = canSeekForward;

        if (mMediaController == null) return;

        mMediaController.setEnabled(true);
        // If paused , should show the controller forever.
        if (isPlaying()) {
            mMediaController.show();
        } else {
            mMediaController.show(0);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        super.surfaceChanged(holder, format, width, height);
        SurfaceView surfaceView = getSurfaceView();
        surfaceView.setFocusable(true);
        surfaceView.setFocusableInTouchMode(true);
        if (isInPlaybackState() && mMediaController != null) {
            mMediaController.show();
        }
    }

    @Override
    protected void openVideo() {
        super.openVideo();

        mCurrentBufferPercentage = 0;

        if (mMediaController != null) return;
        mMediaController = new FullScreenMediaController(getContext(), this, mListener);
        mMediaController.setMediaPlayer(new MediaController.MediaPlayerControl() {
            @Override public boolean canPause() { return mCanPause; }
            @Override public boolean canSeekBackward() { return mCanSeekBackward; }
            @Override public boolean canSeekForward() { return mCanSeekForward; }
            @Override public int getAudioSessionId() { return 0; }
            @Override public int getBufferPercentage() { return mCurrentBufferPercentage; }

            @Override
            public int getCurrentPosition() {
                return ContentVideoViewLegacy.this.getCurrentPosition();
            }

            @Override
            public int getDuration() {
                return ContentVideoViewLegacy.this.getDuration();
            }

            @Override
            public boolean isPlaying() {
                return ContentVideoViewLegacy.this.isPlaying();
            }

            @Override
            public void pause() {
                ContentVideoViewLegacy.this.pause();
            }

            @Override
            public void seekTo(int pos) {
                ContentVideoViewLegacy.this.seekTo(pos);
            }

            @Override
            public void start() {
                ContentVideoViewLegacy.this.start();
            }
        });
        mMediaController.setAnchorView(getSurfaceView());
        mMediaController.setEnabled(false);
    }

    @Override
    protected void onCompletion() {
        super.onCompletion();
        if (mMediaController != null) {
            mMediaController.hide();
        }
    }

    @Override
    public boolean onTrackballEvent(MotionEvent ev) {
        if (isInPlaybackState() && mMediaController != null) {
            toggleMediaControlsVisiblity();
        }
        return false;
    }

    private void toggleMediaControlsVisiblity() {
        if (mMediaController.isShowing()) {
            mMediaController.hide();
        } else {
            mMediaController.show();
        }
    }

    @Override
    protected void destroyContentVideoView(boolean nativeViewDestroyed) {
        if (mMediaController != null) {
            mMediaController.setEnabled(false);
            mMediaController.hide();
            mMediaController = null;
        }
        super.destroyContentVideoView(nativeViewDestroyed);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return true;
    }

    /**
     * Sets the MediaControlsVisibilityListener that wants to listen to visibility change events.
     *
     * @param listener the listener to send the events to.
     */
    public void setListener(MediaControlsVisibilityListener listener) {
        mListener = listener;
    }

}

/* [<][>][^][v][top][bottom][index][help] */