Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0d91c7b authored by Insun Kang's avatar Insun Kang
Browse files

Release MediaSession when VideoView2 is detached from window

This change is doing two things:
1) Release MediaSession when VidoeView2 is detached from window.
2) Adjust video size to fit VideoView2's layout

Test: build
Change-Id: Ic3c824a5768d3ccf2274274a6808cfc2ec98300b
parent bd1f9987
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -230,6 +230,15 @@ public class MediaControlView2Impl implements MediaControlView2Provider {
        mController.sendCommand(ACTION_HIDE_SUBTITLE, null, null);
    }

    @Override
    public void onAttachedToWindow_impl() {
        mSuperProvider.onAttachedToWindow_impl();
    }
    @Override
    public void onDetachedFromWindow_impl() {
        mSuperProvider.onDetachedFromWindow_impl();
    }

    @Override
    public CharSequence getAccessibilityClassName_impl() {
        return MediaControlView2.class.getName();
+11 −46
Original line number Diff line number Diff line
@@ -162,57 +162,22 @@ class VideoSurfaceView extends SurfaceView implements VideoViewInterface, Surfac
        int height = getDefaultSize(videoHeight, heightMeasureSpec);

        if (videoWidth > 0 && videoHeight > 0) {
            int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
            int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
            int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

            if (widthSpecMode == MeasureSpec.EXACTLY && heightSpecMode == MeasureSpec.EXACTLY) {
                // the size is fixed
            width = widthSpecSize;
            height = heightSpecSize;

            // for compatibility, we adjust size based on aspect ratio
            if (videoWidth * height < width * videoHeight) {
                    if (DEBUG) {
                        Log.d(TAG, "image too wide, correcting");
                    }
                width = height * videoWidth / videoHeight;
                } else if (videoWidth * height > width * videoHeight) {
                if (DEBUG) {
                        Log.d(TAG, "image too tall, correcting");
                    }
                    height = width * videoHeight / videoWidth;
                }
            } else if (widthSpecMode == MeasureSpec.EXACTLY) {
                // only the width is fixed, adjust the height to match aspect ratio if possible
                width = widthSpecSize;
                height = width * videoHeight / videoWidth;
                if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
                    // couldn't match aspect ratio within the constraints
                    height = heightSpecSize;
                }
            } else if (heightSpecMode == MeasureSpec.EXACTLY) {
                // only the height is fixed, adjust the width to match aspect ratio if possible
                height = heightSpecSize;
                width = height * videoWidth / videoHeight;
                if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
                    // couldn't match aspect ratio within the constraints
                    width = widthSpecSize;
                }
            } else {
                // neither the width nor the height are fixed, try to use actual video size
                width = videoWidth;
                height = videoHeight;
                if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
                    // too tall, decrease both width and height
                    height = heightSpecSize;
                    width = height * videoWidth / videoHeight;
                    Log.d(TAG, "image too wide, correcting. width: " + width);
                }
                if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
                    // too wide, decrease both width and height
                    width = widthSpecSize;
            } else if (videoWidth * height > width * videoHeight) {
                height = width * videoHeight / videoWidth;
                if (DEBUG) {
                    Log.d(TAG, "image too tall, correcting. height: " + height);
                }
            }
        } else {
+11 −46
Original line number Diff line number Diff line
@@ -173,57 +173,22 @@ class VideoTextureView extends TextureView
        int height = getDefaultSize(videoHeight, heightMeasureSpec);

        if (videoWidth > 0 && videoHeight > 0) {
            int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
            int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
            int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

            if (widthSpecMode == MeasureSpec.EXACTLY && heightSpecMode == MeasureSpec.EXACTLY) {
                // the size is fixed
            width = widthSpecSize;
            height = heightSpecSize;

            // for compatibility, we adjust size based on aspect ratio
            if (videoWidth * height < width * videoHeight) {
                    if (DEBUG) {
                        Log.d(TAG, "image too wide, correcting");
                    }
                width = height * videoWidth / videoHeight;
                } else if (videoWidth * height  > width * videoHeight) {
                if (DEBUG) {
                        Log.d(TAG, "image too tall, correcting");
                    }
                    height = width * videoHeight / videoWidth;
                }
            } else if (widthSpecMode == MeasureSpec.EXACTLY) {
                // only the width is fixed, adjust the height to match aspect ratio if possible
                width = widthSpecSize;
                height = width * videoHeight / videoWidth;
                if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
                    // couldn't match aspect ratio within the constraints
                    height = heightSpecSize;
                }
            } else if (heightSpecMode == MeasureSpec.EXACTLY) {
                // only the height is fixed, adjust the width to match aspect ratio if possible
                height = heightSpecSize;
                width = height * videoWidth / videoHeight;
                if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
                    // couldn't match aspect ratio within the constraints
                    width = widthSpecSize;
                }
            } else {
                // neither the width nor the height are fixed, try to use actual video size
                width = videoWidth;
                height = videoHeight;
                if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
                    // too tall, decrease both width and height
                    height = heightSpecSize;
                    width = height * videoWidth / videoHeight;
                    Log.d(TAG, "image too wide, correcting. width: " + width);
                }
                if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
                    // too wide, decrease both width and height
                    width = widthSpecSize;
            } else if (videoWidth * height > width * videoHeight) {
                height = width * videoHeight / videoWidth;
                if (DEBUG) {
                    Log.d(TAG, "image too tall, correcting. height: " + height);
                }
            }
        } else {
+56 −52
Original line number Diff line number Diff line
@@ -98,8 +98,6 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su
    private int mCurrentBufferPercentage;
    private int mSeekWhenPrepared;  // recording the seek position while preparing

    private int mSurfaceWidth;
    private int mSurfaceHeight;
    private int mVideoWidth;
    private int mVideoHeight;

@@ -120,8 +118,6 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su

        mVideoWidth = 0;
        mVideoHeight = 0;
        mSurfaceWidth = 0;
        mSurfaceHeight = 0;
        mSpeed = 1.0f;
        mFallbackSpeed = mSpeed;

@@ -137,7 +133,8 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su
        mTextureView = new VideoTextureView(mInstance.getContext());
        mSurfaceView = new VideoSurfaceView(mInstance.getContext());
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.WRAP_CONTENT);
                LayoutParams.MATCH_PARENT);
        params.gravity = Gravity.CENTER;
        mTextureView.setLayoutParams(params);
        mSurfaceView.setLayoutParams(params);
        mTextureView.setSurfaceListener(this);
@@ -158,16 +155,12 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su
        mSubtitleView.setBackgroundColor(0);
        mInstance.addView(mSubtitleView);

        // Create MediaSession
        mMediaSession = new MediaSession(mInstance.getContext(), "VideoView2MediaSession");
        mMediaSession.setCallback(new MediaSessionCallback());

        // TODO: Need a common namespace for attributes those are defined in updatable library.
        boolean enableControlView = (attrs == null) || attrs.getAttributeBooleanValue(
                "http://schemas.android.com/apk/com.android.media.api_provider",
                "http://schemas.android.com/apk/com.android.media.update",
                "enableControlView", true);
        if (enableControlView) {
            setMediaControlView2_impl(new MediaControlView2(mInstance.getContext()));
            mMediaControlView = new MediaControlView2(mInstance.getContext());
        }
    }

@@ -175,15 +168,9 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su
    public void setMediaControlView2_impl(MediaControlView2 mediaControlView) {
        mMediaControlView = mediaControlView;

        // TODO: change this so that the CC button appears only where there is a subtitle track.
        mMediaControlView.showCCButton();

        // Get MediaController from MediaSession and set it inside MediaControlView2
        mMediaControlView.setController(mMediaSession.getController());

        LayoutParams params =
                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mInstance.addView(mMediaControlView, params);
        if (mInstance.isAttachedToWindow()) {
            attachMediaControlView();
        }
    }

    @Override
@@ -414,6 +401,25 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su
        mOnViewTypeChangedListener = l;
    }

    @Override
    public void onAttachedToWindow_impl() {
        mSuperProvider.onAttachedToWindow_impl();

        // Create MediaSession
        mMediaSession = new MediaSession(mInstance.getContext(), "VideoView2MediaSession");
        mMediaSession.setCallback(new MediaSessionCallback());

        attachMediaControlView();
    }

    @Override
    public void onDetachedFromWindow_impl() {
        mSuperProvider.onDetachedFromWindow_impl();
        mMediaSession.release();
        mMediaSession = null;
    }


    @Override
    public CharSequence getAccessibilityClassName_impl() {
        return VideoView2.class.getName();
@@ -509,9 +515,6 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su
                    + ", mTargetState=" + mTargetState + ", width/height: " + width + "/" + height
                    + ", " + view.toString());
        }
        mSurfaceWidth = width;
        mSurfaceHeight = height;

        if (needToStart()) {
            mInstance.start();
        }
@@ -535,8 +538,6 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su
            Log.d(TAG, "onSurfaceChanged(). width/height: " + width + "/" + height
                    + ", " + view.toString());
        }
        mSurfaceWidth = width;
        mSurfaceHeight = height;
    }

    @Override
@@ -557,6 +558,18 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su
    // Protected or private methods
    ///////////////////////////////////////////////////

    private void attachMediaControlView() {
        // TODO: change this so that the CC button appears only where there is a subtitle track.
        // mMediaControlView.showCCButton();

        // Get MediaController from MediaSession and set it inside MediaControlView
        mMediaControlView.setController(mMediaSession.getController());

        LayoutParams params =
                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mInstance.addView(mMediaControlView, params);
    }

    private boolean isInPlaybackState() {
        return (mMediaPlayer != null
                && mCurrentState != STATE_ERROR
@@ -660,8 +673,6 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su
                mAudioManager.abandonAudioFocus(null);
            }
        }
        mSurfaceWidth = 0;
        mSurfaceHeight = 0;
        mVideoWidth = 0;
        mVideoHeight = 0;
    }
@@ -797,8 +808,8 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su
            if (mMediaControlView != null) {
                mMediaControlView.setEnabled(true);
            }
            mVideoWidth = mp.getVideoWidth();
            mVideoHeight = mp.getVideoHeight();
            int videoWidth = mp.getVideoWidth();
            int videoHeight = mp.getVideoHeight();

            // mSeekWhenPrepared may be changed after seekTo() call
            int seekToPosition = mSeekWhenPrepared;
@@ -816,27 +827,21 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su
                mMediaSession.setMetadata(builder.build());
            }

            if (mVideoWidth != 0 && mVideoHeight != 0) {
                if (mVideoWidth != mSurfaceWidth || mVideoHeight != mSurfaceHeight) {
            if (videoWidth != 0 && videoHeight != 0) {
                if (videoWidth != mVideoWidth || videoHeight != mVideoHeight) {
                    if (DEBUG) {
                        Log.i(TAG, "OnPreparedListener() : ");
                        Log.i(TAG, " video size: " + mVideoWidth + "/" + mVideoHeight);
                        Log.i(TAG, " surface size: " + mSurfaceWidth + "/" + mSurfaceHeight);
                        Log.i(TAG, " video size: " + videoWidth + "/" + videoHeight);
                        Log.i(TAG, " measuredSize: " + mInstance.getMeasuredWidth() + "/"
                                + mInstance.getMeasuredHeight());
                        Log.i(TAG, " viewSize: " + mInstance.getWidth() + "/"
                                + mInstance.getHeight());
                    }

                    // TODO: It seems like that overriding onMeasure() is needed like legacy code.
                    mSurfaceWidth = mVideoWidth;
                    mSurfaceHeight = mVideoHeight;
                    mVideoWidth = videoWidth;
                    mVideoHeight = videoHeight;
                    mInstance.requestLayout();
                }
                if (mSurfaceWidth == mVideoWidth && mSurfaceHeight == mVideoHeight) {
                    // We didn't actually change the size (it was already at the size
                    // we need), so we won't get a "surface changed" callback, so
                    // start the video here instead of in the callback.
                if (needToStart()) {
                    mInstance.start();
                    if (mMediaControlView != null) {
@@ -850,7 +855,6 @@ public class VideoView2Impl implements VideoView2Provider, VideoViewInterface.Su
                        mMediaControlView.show(0);
                    }
                }
                }
            } else {
                // We don't know the video size yet, but should start anyway.
                // The video size might be reported to us later.