Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.SurfaceTexture;
import android.os.Build;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
/** Provides transparent access to either a SurfaceView or TextureView */
public class SurfaceViewWrapper {
private static final String LOGTAG = "SurfaceViewWrapper";
private ListenerWrapper mListenerWrapper;
private View mView;
// Only one of these will be non-null at any point in time
SurfaceView mSurfaceView;
TextureView mTextureView;
public SurfaceViewWrapper(final Context context) {
// By default, use SurfaceView
mListenerWrapper = new ListenerWrapper();
initSurfaceView(context);
}
private void initSurfaceView(final Context context) {
mSurfaceView = new MagnifiableSurfaceView(context);
mSurfaceView.setBackgroundColor(Color.TRANSPARENT);
mSurfaceView.getHolder().setFormat(PixelFormat.TRANSPARENT);
mView = mSurfaceView;
}
public void useSurfaceView(final Context context) {
if (mTextureView != null) {
mListenerWrapper.onSurfaceTextureDestroyed(mTextureView.getSurfaceTexture());
mTextureView = null;
}
mListenerWrapper.reset();
initSurfaceView(context);
}
public void useTextureView(final Context context) {
if (mSurfaceView != null) {
mListenerWrapper.surfaceDestroyed(mSurfaceView.getHolder());
mSurfaceView = null;
}
mListenerWrapper.reset();
mTextureView = new TextureView(context);
mTextureView.setSurfaceTextureListener(mListenerWrapper);
mView = mTextureView;
}
public void setBackgroundColor(final int color) {
if (mSurfaceView != null) {
mSurfaceView.setBackgroundColor(color);
} else {
Log.e(LOGTAG, "TextureView doesn't support background color.");
}
}
public void setListener(final Listener listener) {
mListenerWrapper.mListener = listener;
mSurfaceView.getHolder().addCallback(mListenerWrapper);
}
public int getWidth() {
if (mSurfaceView != null) {
return mSurfaceView.getHolder().getSurfaceFrame().right;
}
return mListenerWrapper.mWidth;
}
public int getHeight() {
if (mSurfaceView != null) {
return mSurfaceView.getHolder().getSurfaceFrame().bottom;
}
return mListenerWrapper.mHeight;
}
/**
* Returns the SurfaceControl associated with the SurfaceView, or null on unsupported SDK versions
* or when using the TextureView backend.
*/
public SurfaceControl getSurfaceControl() {
if (mSurfaceView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
return mSurfaceView.getSurfaceControl();
}
return null;
}
public Surface getSurface() {
if (mSurfaceView != null) {
return mSurfaceView.getHolder().getSurface();
}
return mListenerWrapper.mSurface;
}
public View getView() {
return mView;
}
/**
* Translates SurfaceTextureListener and SurfaceHolder.Callback into a common interface
* SurfaceViewWrapper.Listener
*/
private class ListenerWrapper
implements TextureView.SurfaceTextureListener, SurfaceHolder.Callback {
private Listener mListener;
// TextureView doesn't provide getters for these so we keep track of them here
private Surface mSurface;
private int mWidth;
private int mHeight;
public void reset() {
mWidth = 0;
mHeight = 0;
mSurface = null;
}
// TextureView
@Override
public void onSurfaceTextureAvailable(
final SurfaceTexture surface, final int width, final int height) {
mSurface = new Surface(surface);
mWidth = width;
mHeight = height;
if (mListener != null) {
mListener.onSurfaceChanged(mSurface, null, width, height);
}
}
@Override
public void onSurfaceTextureSizeChanged(
final SurfaceTexture surface, final int width, final int height) {
mWidth = width;
mHeight = height;
if (mListener != null) {
mListener.onSurfaceChanged(mSurface, null, mWidth, mHeight);
}
}
@Override
public boolean onSurfaceTextureDestroyed(final SurfaceTexture surface) {
if (mListener != null) {
mListener.onSurfaceDestroyed();
}
mSurface = null;
return false;
}
@Override
public void onSurfaceTextureUpdated(final SurfaceTexture surface) {
mSurface = new Surface(surface);
if (mListener != null) {
mListener.onSurfaceChanged(mSurface, null, mWidth, mHeight);
}
}
// SurfaceView
@Override
public void surfaceCreated(final SurfaceHolder holder) {}
@Override
public void surfaceChanged(
final SurfaceHolder holder, final int format, final int width, final int height) {
if (mListener != null) {
mListener.onSurfaceChanged(holder.getSurface(), getSurfaceControl(), width, height);
}
}
@Override
public void surfaceDestroyed(final SurfaceHolder holder) {
if (mListener != null) {
mListener.onSurfaceDestroyed();
}
}
}
public interface Listener {
void onSurfaceChanged(Surface surface, SurfaceControl surfaceControl, int width, int height);
void onSurfaceDestroyed();
}
}