tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SurfaceViewWrapper.java (5670B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 package org.mozilla.gecko;
      6 
      7 import android.content.Context;
      8 import android.graphics.Color;
      9 import android.graphics.PixelFormat;
     10 import android.graphics.SurfaceTexture;
     11 import android.os.Build;
     12 import android.util.Log;
     13 import android.view.Surface;
     14 import android.view.SurfaceControl;
     15 import android.view.SurfaceHolder;
     16 import android.view.SurfaceView;
     17 import android.view.TextureView;
     18 import android.view.View;
     19 
     20 /** Provides transparent access to either a SurfaceView or TextureView */
     21 public class SurfaceViewWrapper {
     22  private static final String LOGTAG = "SurfaceViewWrapper";
     23 
     24  private ListenerWrapper mListenerWrapper;
     25  private View mView;
     26 
     27  // Only one of these will be non-null at any point in time
     28  SurfaceView mSurfaceView;
     29  TextureView mTextureView;
     30 
     31  public SurfaceViewWrapper(final Context context) {
     32    // By default, use SurfaceView
     33    mListenerWrapper = new ListenerWrapper();
     34    initSurfaceView(context);
     35  }
     36 
     37  private void initSurfaceView(final Context context) {
     38    mSurfaceView = new MagnifiableSurfaceView(context);
     39    mSurfaceView.setBackgroundColor(Color.TRANSPARENT);
     40    mSurfaceView.getHolder().setFormat(PixelFormat.TRANSPARENT);
     41    mView = mSurfaceView;
     42  }
     43 
     44  public void useSurfaceView(final Context context) {
     45    if (mTextureView != null) {
     46      mListenerWrapper.onSurfaceTextureDestroyed(mTextureView.getSurfaceTexture());
     47      mTextureView = null;
     48    }
     49    mListenerWrapper.reset();
     50    initSurfaceView(context);
     51  }
     52 
     53  public void useTextureView(final Context context) {
     54    if (mSurfaceView != null) {
     55      mListenerWrapper.surfaceDestroyed(mSurfaceView.getHolder());
     56      mSurfaceView = null;
     57    }
     58    mListenerWrapper.reset();
     59    mTextureView = new TextureView(context);
     60    mTextureView.setSurfaceTextureListener(mListenerWrapper);
     61    mView = mTextureView;
     62  }
     63 
     64  public void setBackgroundColor(final int color) {
     65    if (mSurfaceView != null) {
     66      mSurfaceView.setBackgroundColor(color);
     67    } else {
     68      Log.e(LOGTAG, "TextureView doesn't support background color.");
     69    }
     70  }
     71 
     72  public void setListener(final Listener listener) {
     73    mListenerWrapper.mListener = listener;
     74    mSurfaceView.getHolder().addCallback(mListenerWrapper);
     75  }
     76 
     77  public int getWidth() {
     78    if (mSurfaceView != null) {
     79      return mSurfaceView.getHolder().getSurfaceFrame().right;
     80    }
     81    return mListenerWrapper.mWidth;
     82  }
     83 
     84  public int getHeight() {
     85    if (mSurfaceView != null) {
     86      return mSurfaceView.getHolder().getSurfaceFrame().bottom;
     87    }
     88    return mListenerWrapper.mHeight;
     89  }
     90 
     91  /**
     92   * Returns the SurfaceControl associated with the SurfaceView, or null on unsupported SDK versions
     93   * or when using the TextureView backend.
     94   */
     95  public SurfaceControl getSurfaceControl() {
     96    if (mSurfaceView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
     97      return mSurfaceView.getSurfaceControl();
     98    }
     99 
    100    return null;
    101  }
    102 
    103  public Surface getSurface() {
    104    if (mSurfaceView != null) {
    105      return mSurfaceView.getHolder().getSurface();
    106    }
    107 
    108    return mListenerWrapper.mSurface;
    109  }
    110 
    111  public View getView() {
    112    return mView;
    113  }
    114 
    115  /**
    116   * Translates SurfaceTextureListener and SurfaceHolder.Callback into a common interface
    117   * SurfaceViewWrapper.Listener
    118   */
    119  private class ListenerWrapper
    120      implements TextureView.SurfaceTextureListener, SurfaceHolder.Callback {
    121    private Listener mListener;
    122 
    123    // TextureView doesn't provide getters for these so we keep track of them here
    124    private Surface mSurface;
    125    private int mWidth;
    126    private int mHeight;
    127 
    128    public void reset() {
    129      mWidth = 0;
    130      mHeight = 0;
    131      mSurface = null;
    132    }
    133 
    134    // TextureView
    135    @Override
    136    public void onSurfaceTextureAvailable(
    137        final SurfaceTexture surface, final int width, final int height) {
    138      mSurface = new Surface(surface);
    139      mWidth = width;
    140      mHeight = height;
    141      if (mListener != null) {
    142        mListener.onSurfaceChanged(mSurface, null, width, height);
    143      }
    144    }
    145 
    146    @Override
    147    public void onSurfaceTextureSizeChanged(
    148        final SurfaceTexture surface, final int width, final int height) {
    149      mWidth = width;
    150      mHeight = height;
    151      if (mListener != null) {
    152        mListener.onSurfaceChanged(mSurface, null, mWidth, mHeight);
    153      }
    154    }
    155 
    156    @Override
    157    public boolean onSurfaceTextureDestroyed(final SurfaceTexture surface) {
    158      if (mListener != null) {
    159        mListener.onSurfaceDestroyed();
    160      }
    161      mSurface = null;
    162      return false;
    163    }
    164 
    165    @Override
    166    public void onSurfaceTextureUpdated(final SurfaceTexture surface) {
    167      mSurface = new Surface(surface);
    168      if (mListener != null) {
    169        mListener.onSurfaceChanged(mSurface, null, mWidth, mHeight);
    170      }
    171    }
    172 
    173    // SurfaceView
    174    @Override
    175    public void surfaceCreated(final SurfaceHolder holder) {}
    176 
    177    @Override
    178    public void surfaceChanged(
    179        final SurfaceHolder holder, final int format, final int width, final int height) {
    180      if (mListener != null) {
    181        mListener.onSurfaceChanged(holder.getSurface(), getSurfaceControl(), width, height);
    182      }
    183    }
    184 
    185    @Override
    186    public void surfaceDestroyed(final SurfaceHolder holder) {
    187      if (mListener != null) {
    188        mListener.onSurfaceDestroyed();
    189      }
    190    }
    191  }
    192 
    193  public interface Listener {
    194    void onSurfaceChanged(Surface surface, SurfaceControl surfaceControl, int width, int height);
    195 
    196    void onSurfaceDestroyed();
    197  }
    198 }