5package io.flutter.embedding.android;
8import android.graphics.SurfaceTexture;
12import androidx.annotation.NonNull;
13import androidx.annotation.Nullable;
14import androidx.annotation.VisibleForTesting;
16import io.flutter.embedding.engine.renderer.FlutterRenderer;
17import io.flutter.embedding.engine.renderer.RenderSurface;
35 private static final String TAG =
"FlutterTextureView";
37 private boolean isSurfaceAvailableForRendering =
false;
38 private boolean isPaused =
false;
40 @Nullable
private Surface renderSurface;
42 private boolean shouldNotify() {
43 return flutterRenderer !=
null && !isPaused;
50 private final SurfaceTextureListener surfaceTextureListener =
51 new SurfaceTextureListener() {
53 public void onSurfaceTextureAvailable(
54 SurfaceTexture surfaceTexture,
int width,
int height) {
55 Log.
v(
TAG,
"SurfaceTextureListener.onSurfaceTextureAvailable()");
56 isSurfaceAvailableForRendering =
true;
62 connectSurfaceToRenderer();
67 public void onSurfaceTextureSizeChanged(
69 Log.
v(
TAG,
"SurfaceTextureListener.onSurfaceTextureSizeChanged()");
76 public void onSurfaceTextureUpdated(@NonNull SurfaceTexture
surface) {
81 public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture
surface) {
82 Log.
v(
TAG,
"SurfaceTextureListener.onSurfaceTextureDestroyed()");
83 isSurfaceAvailableForRendering =
false;
89 disconnectSurfaceFromRenderer();
93 if (renderSurface !=
null) {
94 renderSurface.release();
111 super(context, attrs);
115 private void init() {
118 setSurfaceTextureListener(surfaceTextureListener);
124 return flutterRenderer;
128 boolean isSurfaceAvailableForRendering() {
129 return isSurfaceAvailableForRendering;
146 Log.
v(
TAG,
"Attaching to FlutterRenderer.");
147 if (this.flutterRenderer !=
null) {
150 "Already connected to a FlutterRenderer. Detaching from old one and attaching to new"
152 this.flutterRenderer.stopRenderingToSurface();
155 this.flutterRenderer = flutterRenderer;
168 if (flutterRenderer !=
null) {
173 if (getWindowToken() !=
null) {
174 Log.
v(
TAG,
"Disconnecting FlutterRenderer from Android surface.");
175 disconnectSurfaceFromRenderer();
178 flutterRenderer =
null;
180 Log.
w(
TAG,
"detachFromRenderer() invoked when no FlutterRenderer was attached.");
188 public void pause() {
189 if (flutterRenderer ==
null) {
190 Log.
w(
TAG,
"pause() invoked when no FlutterRenderer was attached.");
197 if (flutterRenderer ==
null) {
198 Log.
w(
TAG,
"resume() invoked when no FlutterRenderer was attached.");
204 if (isSurfaceAvailableForRendering()) {
207 "Surface is available for rendering. Connecting FlutterRenderer to Android surface.");
208 connectSurfaceToRenderer();
219 public void setRenderSurface(Surface renderSurface) {
220 this.renderSurface = renderSurface;
224 private void connectSurfaceToRenderer() {
225 if (flutterRenderer ==
null || getSurfaceTexture() ==
null) {
226 throw new IllegalStateException(
227 "connectSurfaceToRenderer() should only be called when flutterRenderer and"
228 +
" getSurfaceTexture() are non-null.");
232 if (renderSurface !=
null) {
233 renderSurface.release();
234 renderSurface =
null;
237 renderSurface =
new Surface(getSurfaceTexture());
238 flutterRenderer.startRenderingToSurface(renderSurface, isPaused);
242 private void changeSurfaceSize(
int width,
int height) {
243 if (flutterRenderer ==
null) {
244 throw new IllegalStateException(
245 "changeSurfaceSize() should only be called when flutterRenderer is non-null.");
250 "Notifying FlutterRenderer that Android surface size has changed to "
258 private void disconnectSurfaceFromRenderer() {
259 if (flutterRenderer ==
null) {
260 throw new IllegalStateException(
261 "disconnectSurfaceFromRenderer() should only be called when flutterRenderer is"
265 flutterRenderer.stopRenderingToSurface();
266 if (renderSurface !=
null) {
267 renderSurface.release();
268 renderSurface =
null;
static void v(@NonNull String tag, @NonNull String message)
static void w(@NonNull String tag, @NonNull String message)
void detachFromRenderer()
void attachToRenderer(@NonNull FlutterRenderer renderer)
FlutterRenderer getAttachedRenderer()