Home | History | Annotate | Download | only in impl_with_mp1
      1 /*
      2  * Copyright 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package androidx.media.widget;
     18 
     19 import static androidx.media.widget.VideoView2.VIEW_TYPE_SURFACEVIEW;
     20 
     21 import android.content.Context;
     22 import android.graphics.Rect;
     23 import android.media.MediaPlayer;
     24 import android.util.Log;
     25 import android.view.SurfaceHolder;
     26 import android.view.SurfaceView;
     27 import android.view.View;
     28 
     29 import androidx.annotation.NonNull;
     30 import androidx.annotation.RequiresApi;
     31 
     32 @RequiresApi(21)
     33 class VideoSurfaceViewWithMp1 extends SurfaceView
     34         implements VideoViewInterfaceWithMp1, SurfaceHolder.Callback {
     35     private static final String TAG = "VideoSurfaceViewWithMp1";
     36     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     37     private SurfaceHolder mSurfaceHolder = null;
     38     private SurfaceListener mSurfaceListener = null;
     39     private MediaPlayer mMediaPlayer;
     40     // A flag to indicate taking over other view should be proceed.
     41     private boolean mIsTakingOverOldView;
     42     private VideoViewInterfaceWithMp1 mOldView;
     43 
     44     VideoSurfaceViewWithMp1(Context context) {
     45         super(context, null);
     46         getHolder().addCallback(this);
     47     }
     48 
     49     ////////////////////////////////////////////////////
     50     // implements VideoViewInterfaceWithMp1
     51     ////////////////////////////////////////////////////
     52 
     53     @Override
     54     public boolean assignSurfaceToMediaPlayer(MediaPlayer mp) {
     55         Log.d(TAG, "assignSurfaceToMediaPlayer(): mSurfaceHolder: " + mSurfaceHolder);
     56         if (mp == null || !hasAvailableSurface()) {
     57             return false;
     58         }
     59         mp.setDisplay(mSurfaceHolder);
     60         return true;
     61     }
     62 
     63     @Override
     64     public void setSurfaceListener(SurfaceListener l) {
     65         mSurfaceListener = l;
     66     }
     67 
     68     @Override
     69     public int getViewType() {
     70         return VIEW_TYPE_SURFACEVIEW;
     71     }
     72 
     73     @Override
     74     public void setMediaPlayer(MediaPlayer mp) {
     75         mMediaPlayer = mp;
     76         if (mIsTakingOverOldView) {
     77             takeOver(mOldView);
     78         }
     79     }
     80 
     81     @Override
     82     public void takeOver(@NonNull VideoViewInterfaceWithMp1 oldView) {
     83         if (assignSurfaceToMediaPlayer(mMediaPlayer)) {
     84             ((View) oldView).setVisibility(GONE);
     85             mIsTakingOverOldView = false;
     86             mOldView = null;
     87             if (mSurfaceListener != null) {
     88                 mSurfaceListener.onSurfaceTakeOverDone(this);
     89             }
     90         } else {
     91             mIsTakingOverOldView = true;
     92             mOldView = oldView;
     93         }
     94     }
     95 
     96     @Override
     97     public boolean hasAvailableSurface() {
     98         return (mSurfaceHolder != null && mSurfaceHolder.getSurface() != null);
     99     }
    100 
    101     ////////////////////////////////////////////////////
    102     // implements SurfaceHolder.Callback
    103     ////////////////////////////////////////////////////
    104 
    105     @Override
    106     public void surfaceCreated(SurfaceHolder holder) {
    107         Log.d(TAG, "surfaceCreated: mSurfaceHolder: " + mSurfaceHolder + ", new holder: " + holder);
    108         mSurfaceHolder = holder;
    109         if (mIsTakingOverOldView) {
    110             takeOver(mOldView);
    111         } else {
    112             assignSurfaceToMediaPlayer(mMediaPlayer);
    113         }
    114 
    115         if (mSurfaceListener != null) {
    116             Rect rect = mSurfaceHolder.getSurfaceFrame();
    117             mSurfaceListener.onSurfaceCreated(this, rect.width(), rect.height());
    118         }
    119     }
    120 
    121     @Override
    122     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    123         if (mSurfaceListener != null) {
    124             mSurfaceListener.onSurfaceChanged(this, width, height);
    125         }
    126     }
    127 
    128     @Override
    129     public void surfaceDestroyed(SurfaceHolder holder) {
    130         // After we return from this we can't use the surface any more
    131         mSurfaceHolder = null;
    132         if (mSurfaceListener != null) {
    133             mSurfaceListener.onSurfaceDestroyed(this);
    134         }
    135     }
    136 
    137     @Override
    138     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    139         int videoWidth = (mMediaPlayer == null) ? 0 : mMediaPlayer.getVideoWidth();
    140         int videoHeight = (mMediaPlayer == null) ? 0 : mMediaPlayer.getVideoHeight();
    141         if (DEBUG) {
    142             Log.d(TAG, "onMeasure(" + MeasureSpec.toString(widthMeasureSpec) + ", "
    143                     + MeasureSpec.toString(heightMeasureSpec) + ")");
    144             Log.i(TAG, " measuredSize: " + getMeasuredWidth() + "/" + getMeasuredHeight());
    145             Log.i(TAG, " viewSize: " + getWidth() + "/" + getHeight());
    146             Log.i(TAG, " mVideoWidth/height: " + videoWidth + ", " + videoHeight);
    147         }
    148 
    149         int width = getDefaultSize(videoWidth, widthMeasureSpec);
    150         int height = getDefaultSize(videoHeight, heightMeasureSpec);
    151 
    152         if (videoWidth > 0 && videoHeight > 0) {
    153             int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
    154             int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
    155 
    156             width = widthSpecSize;
    157             height = heightSpecSize;
    158 
    159             // for compatibility, we adjust size based on aspect ratio
    160             if (videoWidth * height < width * videoHeight) {
    161                 width = height * videoWidth / videoHeight;
    162                 if (DEBUG) {
    163                     Log.d(TAG, "image too wide, correcting. width: " + width);
    164                 }
    165             } else if (videoWidth * height > width * videoHeight) {
    166                 height = width * videoHeight / videoWidth;
    167                 if (DEBUG) {
    168                     Log.d(TAG, "image too tall, correcting. height: " + height);
    169                 }
    170             }
    171         } else {
    172             // no size yet, just adopt the given spec sizes
    173         }
    174         setMeasuredDimension(width, height);
    175         if (DEBUG) {
    176             Log.i(TAG, "end of onMeasure()");
    177             Log.i(TAG, " measuredSize: " + getMeasuredWidth() + "/" + getMeasuredHeight());
    178         }
    179     }
    180 }
    181