From 92cc1aac8a58816fd5327b341ea30dffa787a900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mahmut=20Ta=C5=9Fk=C4=B1ran?= Date: Tue, 24 Sep 2024 22:43:06 +0400 Subject: [PATCH] Add a check for the surface if it is valid (flutter/engine#55277) Fixes an issue where the Surface is not valid and the `draw` method is crashing. https://github.com/flutter/flutter/issues/155018 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- .../plugin/platform/PlatformViewWrapper.java | 6 ++++ .../platform/PlatformViewWrapperTest.java | 33 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewWrapper.java b/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewWrapper.java index 1b202c14cb5..1bce76fd09b 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewWrapper.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewWrapper.java @@ -165,7 +165,13 @@ public class PlatformViewWrapper extends FrameLayout { Log.e(TAG, "Platform view cannot be composed without a RenderTarget."); return; } + final Surface targetSurface = renderTarget.getSurface(); + if (!targetSurface.isValid()) { + Log.e(TAG, "Platform view cannot be composed without a valid RenderTarget surface."); + return; + } + final Canvas targetCanvas = targetSurface.lockHardwareCanvas(); if (targetCanvas == null) { // Cannot render right now. diff --git a/engine/src/flutter/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewWrapperTest.java b/engine/src/flutter/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewWrapperTest.java index 64fd84f9374..11c3094f982 100644 --- a/engine/src/flutter/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewWrapperTest.java +++ b/engine/src/flutter/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewWrapperTest.java @@ -15,6 +15,7 @@ import android.annotation.TargetApi; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; +import android.view.Surface; import android.view.View; import android.view.View.OnFocusChangeListener; import android.view.ViewGroup; @@ -23,6 +24,7 @@ import android.view.accessibility.AccessibilityEvent; import android.widget.FrameLayout; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; +import io.flutter.embedding.engine.renderer.FlutterRenderer; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -63,6 +65,37 @@ public class PlatformViewWrapperTest { verify(canvas, times(1)).drawColor(Color.RED); } + @Test + public void draw_withoutValidSurface() { + FlutterRenderer.debugDisableSurfaceClear = true; + final Surface surface = mock(Surface.class); + when(surface.isValid()).thenReturn(false); + final PlatformViewRenderTarget renderTarget = mock(PlatformViewRenderTarget.class); + when(renderTarget.getSurface()).thenReturn(surface); + + final PlatformViewWrapper wrapper = new PlatformViewWrapper(ctx, renderTarget); + final Canvas canvas = mock(Canvas.class); + wrapper.draw(canvas); + + verify(canvas, times(0)).drawColor(Color.TRANSPARENT, android.graphics.PorterDuff.Mode.CLEAR); + } + + @Test + public void draw_withValidSurface() { + FlutterRenderer.debugDisableSurfaceClear = true; + final Canvas canvas = mock(Canvas.class); + final Surface surface = mock(Surface.class); + when(surface.isValid()).thenReturn(true); + final PlatformViewRenderTarget renderTarget = mock(PlatformViewRenderTarget.class); + when(renderTarget.getSurface()).thenReturn(surface); + when(surface.lockHardwareCanvas()).thenReturn(canvas); + final PlatformViewWrapper wrapper = new PlatformViewWrapper(ctx, renderTarget); + + wrapper.draw(canvas); + + verify(canvas, times(1)).drawColor(Color.TRANSPARENT, android.graphics.PorterDuff.Mode.CLEAR); + } + @Test public void focusChangeListener_hasFocus() { final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);