5package io.flutter.embedding.android;
8import android.graphics.PixelFormat;
10import android.util.AttributeSet;
11import android.view.SurfaceHolder;
13import androidx.annotation.NonNull;
14import androidx.annotation.Nullable;
15import androidx.annotation.VisibleForTesting;
17import io.flutter.embedding.engine.renderer.FlutterRenderer;
18import io.flutter.embedding.engine.renderer.FlutterUiDisplayListener;
19import io.flutter.embedding.engine.renderer.RenderSurface;
37 private static final String TAG =
"FlutterSurfaceView";
39 private final boolean renderTransparently;
40 private boolean isSurfaceAvailableForRendering =
false;
41 private boolean isPaused =
false;
44 private boolean shouldNotify() {
45 return flutterRenderer !=
null && !isPaused;
51 private final SurfaceHolder.Callback surfaceCallback =
52 new SurfaceHolder.Callback() {
54 public void surfaceCreated(@NonNull SurfaceHolder holder) {
55 Log.
v(
TAG,
"SurfaceHolder.Callback.startRenderingToSurface()");
56 isSurfaceAvailableForRendering =
true;
59 connectSurfaceToRenderer();
64 public void surfaceChanged(
66 Log.
v(
TAG,
"SurfaceHolder.Callback.surfaceChanged()");
73 public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
74 Log.
v(
TAG,
"SurfaceHolder.Callback.stopRenderingToSurface()");
75 isSurfaceAvailableForRendering =
false;
78 disconnectSurfaceFromRenderer();
86 public void onFlutterUiDisplayed() {
87 Log.
v(
TAG,
"onFlutterUiDisplayed()");
91 if (flutterRenderer !=
null) {
92 flutterRenderer.removeIsDisplayingFlutterUiListener(
this);
97 public void onFlutterUiNoLongerDisplayed() {
104 this(context,
null,
false);
112 this(context,
null, renderTransparently);
117 this(context, attrs,
false);
121 @NonNull Context context, @Nullable
AttributeSet attrs,
boolean renderTransparently) {
122 super(context, attrs);
123 this.renderTransparently = renderTransparently;
127 private void init() {
130 if (renderTransparently) {
132 setZOrderOnTop(
true);
137 getHolder().addCallback(surfaceCallback);
151 public boolean gatherTransparentRegion(Region
region) {
152 if (getAlpha() < 1.0
f) {
155 final int[] location =
new int[2];
156 getLocationInWindow(location);
160 location[0] + getRight() - getLeft(),
161 location[1] + getBottom() - getTop(),
162 Region.Op.DIFFERENCE);
169 return flutterRenderer;
173 boolean isSurfaceAvailableForRendering() {
174 return isSurfaceAvailableForRendering;
190 Log.
v(
TAG,
"Attaching to FlutterRenderer.");
191 if (this.flutterRenderer !=
null) {
194 "Already connected to a FlutterRenderer. Detaching from old one and attaching to new"
196 this.flutterRenderer.stopRenderingToSurface();
197 this.flutterRenderer.removeIsDisplayingFlutterUiListener(flutterUiDisplayListener);
200 this.flutterRenderer = flutterRenderer;
213 if (flutterRenderer !=
null) {
218 if (getWindowToken() !=
null) {
219 Log.
v(
TAG,
"Disconnecting FlutterRenderer from Android surface.");
220 disconnectSurfaceFromRenderer();
225 flutterRenderer.removeIsDisplayingFlutterUiListener(flutterUiDisplayListener);
226 flutterRenderer =
null;
229 Log.
w(
TAG,
"detachFromRenderer() invoked when no FlutterRenderer was attached.");
237 public void pause() {
238 if (flutterRenderer ==
null) {
239 Log.
w(
TAG,
"pause() invoked when no FlutterRenderer was attached.");
246 if (flutterRenderer ==
null) {
247 Log.
w(
TAG,
"resume() invoked when no FlutterRenderer was attached.");
250 this.flutterRenderer.addIsDisplayingFlutterUiListener(flutterUiDisplayListener);
254 if (isSurfaceAvailableForRendering()) {
257 "Surface is available for rendering. Connecting FlutterRenderer to Android surface.");
258 connectSurfaceToRenderer();
264 private void connectSurfaceToRenderer() {
265 if (flutterRenderer ==
null || getHolder() ==
null) {
266 throw new IllegalStateException(
267 "connectSurfaceToRenderer() should only be called when flutterRenderer and getHolder()"
276 flutterRenderer.startRenderingToSurface(getHolder().getSurface(), isPaused);
280 private void changeSurfaceSize(
int width,
int height) {
281 if (flutterRenderer ==
null) {
282 throw new IllegalStateException(
283 "changeSurfaceSize() should only be called when flutterRenderer is non-null.");
288 "Notifying FlutterRenderer that Android surface size has changed to "
296 private void disconnectSurfaceFromRenderer() {
297 if (flutterRenderer ==
null) {
298 throw new IllegalStateException(
299 "disconnectSurfaceFromRenderer() should only be called when flutterRenderer is"
303 flutterRenderer.stopRenderingToSurface();
bool op(const SkIRect &rect, Op op)
static void v(@NonNull String tag, @NonNull String message)
static void w(@NonNull String tag, @NonNull String message)
uint32_t uint32_t * format
void detachFromRenderer()
void attachToRenderer(@NonNull FlutterRenderer renderer)
FlutterRenderer getAttachedRenderer()
ClipOpAndAA opAA SkRegion region
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...