Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 4c7b301

Browse files
committed
Fix disposeNullAndroidView with Robolectric 4.8.1
Before Robolectric 4.8, Surface#lockHardwareCanvas will throw exception at PlatformViewWrapper#setTexture, because Robolectric doesn't support to shadow Surface#lockHardwareCanvas, and it uses real Android logic with native pointer address is 0. This failure will ensure embeddedView's parent is null, because PlatformViewsController#createForTextureLayer will fail because of previous mentioned error, and PlatformViewsController#createForTextureLayer will not add embeddedView to wrapperView. So this test can pass. From Robolectric 4.8, it supports to shadow Surface#lockHardwareCanvas and it can pass with default true valid value, and PlatformViewsController#createForTextureLayer will run correctly and add embeddedView to wrapperView, and initializePlatformViewIfNeeded will fail because embeddedView's parent is not null. So adding a new shadow class called ShadowReleasedSurface to simulate previous Surface#lockHardwareCanvas failure to ensure this test can work with Robolectric 4.8 and later versions. But it is just a workaround, the root cause is this test case depends on just-failure behavior of Surface#lockHardwareCanvas in old Robolectric. Signed-off-by: utzcoz <[email protected]>
1 parent efbcb7b commit 4c7b301

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import android.content.Context;
1111
import android.content.MutableContextWrapper;
1212
import android.content.res.AssetManager;
13+
import android.graphics.Canvas;
1314
import android.graphics.SurfaceTexture;
1415
import android.util.SparseArray;
1516
import android.view.MotionEvent;
@@ -53,6 +54,7 @@
5354
import org.robolectric.annotation.Config;
5455
import org.robolectric.annotation.Implementation;
5556
import org.robolectric.annotation.Implements;
57+
import org.robolectric.shadows.ShadowSurface;
5658
import org.robolectric.shadows.ShadowSurfaceView;
5759

5860
@Config(manifest = Config.NONE)
@@ -691,7 +693,12 @@ public void disposeAndroidView__hybridComposition() {
691693
}
692694

693695
@Test
694-
@Config(shadows = {ShadowFlutterJNI.class, ShadowPlatformTaskQueue.class})
696+
@Config(
697+
shadows = {
698+
ShadowFlutterJNI.class,
699+
ShadowReleasedSurface.class,
700+
ShadowPlatformTaskQueue.class
701+
})
695702
public void disposeNullAndroidView() {
696703
PlatformViewsController platformViewsController = new PlatformViewsController();
697704

@@ -711,6 +718,20 @@ public void disposeNullAndroidView() {
711718
attach(jni, platformViewsController);
712719

713720
// Simulate create call from the framework.
721+
// Before Robolectric 4.8, Surface#lockHardwareCanvas will throw exception at
722+
// PlatformViewWrapper#setTexture, because Robolectric doesn't support to shadow
723+
// Surface#lockHardwareCanvas, and it uses real Android logic with native pointer address is 0.
724+
// This failure will ensure embeddedView's parent is null, because
725+
// PlatformViewsController#createForTextureLayer will fail because of previous mentioned error,
726+
// and PlatformViewsController#createForTextureLayer will not add embeddedView to wrapperView.
727+
// So this test can pass. From Robolectric 4.8, it supports to shadow Surface#lockHardwareCanvas
728+
// and it can pass with default true valid value, and
729+
// PlatformViewsController#createForTextureLayer will run correctly and add embeddedView to
730+
// wrapperView, and initializePlatformViewIfNeeded will fail because embeddedView's parent is
731+
// not null. So adding a new shadow class called ShadowReleasedSurface to simulate previous
732+
// Surface#lockHardwareCanvas failure to ensure this test can work with Robolectric 4.8 and
733+
// later versions. But it is just a workaround, the root cause is this test case depends on
734+
// just-failure behavior of Surface#lockHardwareCanvas in old Robolectric.
714735
createPlatformView(
715736
jni, platformViewsController, platformViewId, "testType", /* hybrid=*/ false);
716737
platformViewsController.initializePlatformViewIfNeeded(platformViewId);
@@ -1339,6 +1360,22 @@ public void dispatch(Runnable runnable) {
13391360
}
13401361
}
13411362

1363+
/**
1364+
* The shadow class of {@link Surface} to simulate released surface.
1365+
*
1366+
* <p>This shadow class's usage is restricted, not for normal purpose.
1367+
*/
1368+
@Implements(Surface.class)
1369+
public static class ShadowReleasedSurface extends ShadowSurface {
1370+
public ShadowReleasedSurface() {}
1371+
1372+
@Implementation
1373+
@Override
1374+
protected Canvas lockHardwareCanvas() {
1375+
throw new IllegalStateException("Surface has already been released.");
1376+
}
1377+
}
1378+
13421379
@Implements(FlutterJNI.class)
13431380
public static class ShadowFlutterJNI {
13441381
private static SparseArray<ByteBuffer> replies = new SparseArray<>();

0 commit comments

Comments
 (0)