1010import android .content .Context ;
1111import android .content .MutableContextWrapper ;
1212import android .content .res .AssetManager ;
13+ import android .graphics .Canvas ;
1314import android .graphics .SurfaceTexture ;
1415import android .util .SparseArray ;
1516import android .view .MotionEvent ;
5354import org .robolectric .annotation .Config ;
5455import org .robolectric .annotation .Implementation ;
5556import org .robolectric .annotation .Implements ;
57+ import org .robolectric .shadows .ShadowSurface ;
5658import org .robolectric .shadows .ShadowSurfaceView ;
5759
5860@ Config (manifest = Config .NONE )
@@ -647,7 +649,12 @@ public void disposeAndroidView__hybridComposition() {
647649 }
648650
649651 @ Test
650- @ Config (shadows = {ShadowFlutterJNI .class , ShadowPlatformTaskQueue .class })
652+ @ Config (
653+ shadows = {
654+ ShadowFlutterJNI .class ,
655+ ShadowReleasedSurface .class ,
656+ ShadowPlatformTaskQueue .class
657+ })
651658 public void disposeNullAndroidView () {
652659 PlatformViewsController platformViewsController = new PlatformViewsController ();
653660
@@ -667,6 +674,20 @@ public void disposeNullAndroidView() {
667674 attach (jni , platformViewsController );
668675
669676 // Simulate create call from the framework.
677+ // Before Robolectric 4.8, Surface#lockHardwareCanvas will throw exception at
678+ // PlatformViewWrapper#setTexture, because Robolectric doesn't support to shadow
679+ // Surface#lockHardwareCanvas, and it uses real Android logic with native pointer address is 0.
680+ // This failure will ensure embeddedView's parent is null, because
681+ // PlatformViewsController#createForTextureLayer will fail because of previous mentioned error,
682+ // and PlatformViewsController#createForTextureLayer will not add embeddedView to wrapperView.
683+ // So this test can pass. From Robolectric 4.8, it supports to shadow Surface#lockHardwareCanvas
684+ // and it can pass with default true valid value, and
685+ // PlatformViewsController#createForTextureLayer will run correctly and add embeddedView to
686+ // wrapperView, and initializePlatformViewIfNeeded will fail because embeddedView's parent is
687+ // not null. So adding a new shadow class called ShadowReleasedSurface to simulate previous
688+ // Surface#lockHardwareCanvas failure to ensure this test can work with Robolectric 4.8 and
689+ // later versions. But it is just a workaround, the root cause is this test case depends on
690+ // just-failure behavior of Surface#lockHardwareCanvas in old Robolectric.
670691 createPlatformView (
671692 jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ false );
672693 platformViewsController .initializePlatformViewIfNeeded (platformViewId );
@@ -1295,6 +1316,22 @@ public void dispatch(Runnable runnable) {
12951316 }
12961317 }
12971318
1319+ /**
1320+ * The shadow class of {@link Surface} to simulate released surface.
1321+ *
1322+ * <p>This shadow class's usage is restricted, not for normal purpose.
1323+ */
1324+ @ Implements (Surface .class )
1325+ public static class ShadowReleasedSurface extends ShadowSurface {
1326+ public ShadowReleasedSurface () {}
1327+
1328+ @ Implementation
1329+ @ Override
1330+ protected Canvas lockHardwareCanvas () {
1331+ throw new IllegalStateException ("Surface has already been released." );
1332+ }
1333+ }
1334+
12981335 @ Implements (FlutterJNI .class )
12991336 public static class ShadowFlutterJNI {
13001337 private static SparseArray <ByteBuffer > replies = new SparseArray <>();
0 commit comments