77
88import android .content .Context ;
99import android .content .res .AssetManager ;
10+ import android .graphics .SurfaceTexture ;
1011import android .util .SparseArray ;
1112import android .view .MotionEvent ;
1213import android .view .Surface ;
1314import android .view .SurfaceHolder ;
1415import android .view .SurfaceView ;
1516import android .view .View ;
1617import android .view .ViewParent ;
18+ import android .widget .FrameLayout .LayoutParams ;
1719import io .flutter .embedding .android .FlutterImageView ;
1820import io .flutter .embedding .android .FlutterView ;
1921import io .flutter .embedding .android .MotionEventTracker ;
3234import io .flutter .plugin .common .MethodCall ;
3335import io .flutter .plugin .common .StandardMethodCodec ;
3436import io .flutter .plugin .localization .LocalizationPlugin ;
37+ import io .flutter .view .TextureRegistry ;
3538import java .nio .ByteBuffer ;
3639import java .util .Arrays ;
3740import java .util .HashMap ;
@@ -232,7 +235,7 @@ public void getPlatformViewById__hybridComposition() {
232235 attach (jni , platformViewsController );
233236
234237 // Simulate create call from the framework.
235- createPlatformView (jni , platformViewsController , platformViewId , "testType" );
238+ createPlatformView (jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ true );
236239
237240 platformViewsController .initializePlatformViewIfNeeded (platformViewId );
238241
@@ -259,7 +262,7 @@ public void createPlatformViewMessage__initializesAndroidView() {
259262 attach (jni , platformViewsController );
260263
261264 // Simulate create call from the framework.
262- createPlatformView (jni , platformViewsController , platformViewId , "testType" );
265+ createPlatformView (jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ true );
263266 verify (viewFactory , times (1 )).create (any (), eq (platformViewId ), any ());
264267 }
265268
@@ -281,7 +284,7 @@ public void createPlatformViewMessage__throwsIfViewIsNull() {
281284 attach (jni , platformViewsController );
282285
283286 // Simulate create call from the framework.
284- createPlatformView (jni , platformViewsController , platformViewId , "testType" );
287+ createPlatformView (jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ true );
285288 assertEquals (ShadowFlutterJNI .getResponses ().size (), 1 );
286289
287290 assertThrows (
@@ -291,6 +294,66 @@ public void createPlatformViewMessage__throwsIfViewIsNull() {
291294 });
292295 }
293296
297+ @ Test
298+ @ Config (shadows = {ShadowFlutterJNI .class })
299+ public void onDetachedFromJNI_clearsPlatformViewContext () {
300+ PlatformViewsController platformViewsController = new PlatformViewsController ();
301+
302+ int platformViewId = 0 ;
303+ assertNull (platformViewsController .getPlatformViewById (platformViewId ));
304+
305+ PlatformViewFactory viewFactory = mock (PlatformViewFactory .class );
306+ PlatformView platformView = mock (PlatformView .class );
307+
308+ View pv = mock (View .class );
309+ when (pv .getLayoutParams ()).thenReturn (new LayoutParams (1 , 1 ));
310+
311+ when (platformView .getView ()).thenReturn (pv );
312+ when (viewFactory .create (any (), eq (platformViewId ), any ())).thenReturn (platformView );
313+ platformViewsController .getRegistry ().registerViewFactory ("testType" , viewFactory );
314+
315+ FlutterJNI jni = new FlutterJNI ();
316+ attach (jni , platformViewsController );
317+
318+ // Simulate create call from the framework.
319+ createPlatformView (
320+ jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ false );
321+
322+ assertFalse (platformViewsController .contextToPlatformView .isEmpty ());
323+ platformViewsController .onDetachedFromJNI ();
324+ assertTrue (platformViewsController .contextToPlatformView .isEmpty ());
325+ }
326+
327+ @ Test
328+ @ Config (shadows = {ShadowFlutterJNI .class })
329+ public void onPreEngineRestart_clearsPlatformViewContext () {
330+ PlatformViewsController platformViewsController = new PlatformViewsController ();
331+
332+ int platformViewId = 0 ;
333+ assertNull (platformViewsController .getPlatformViewById (platformViewId ));
334+
335+ PlatformViewFactory viewFactory = mock (PlatformViewFactory .class );
336+ PlatformView platformView = mock (PlatformView .class );
337+
338+ View pv = mock (View .class );
339+ when (pv .getLayoutParams ()).thenReturn (new LayoutParams (1 , 1 ));
340+
341+ when (platformView .getView ()).thenReturn (pv );
342+ when (viewFactory .create (any (), eq (platformViewId ), any ())).thenReturn (platformView );
343+ platformViewsController .getRegistry ().registerViewFactory ("testType" , viewFactory );
344+
345+ FlutterJNI jni = new FlutterJNI ();
346+ attach (jni , platformViewsController );
347+
348+ // Simulate create call from the framework.
349+ createPlatformView (
350+ jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ false );
351+
352+ assertFalse (platformViewsController .contextToPlatformView .isEmpty ());
353+ platformViewsController .onDetachedFromJNI ();
354+ assertTrue (platformViewsController .contextToPlatformView .isEmpty ());
355+ }
356+
294357 @ Test
295358 @ Config (shadows = {ShadowFlutterJNI .class })
296359 public void createPlatformViewMessage__throwsIfViewHasParent () {
@@ -311,7 +374,7 @@ public void createPlatformViewMessage__throwsIfViewHasParent() {
311374 attach (jni , platformViewsController );
312375
313376 // Simulate create call from the framework.
314- createPlatformView (jni , platformViewsController , platformViewId , "testType" );
377+ createPlatformView (jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ true );
315378 assertEquals (ShadowFlutterJNI .getResponses ().size (), 1 );
316379
317380 assertThrows (
@@ -343,7 +406,7 @@ public void disposeAndroidView__hybridComposition() {
343406 attach (jni , platformViewsController );
344407
345408 // Simulate create call from the framework.
346- createPlatformView (jni , platformViewsController , platformViewId , "testType" );
409+ createPlatformView (jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ true );
347410 platformViewsController .initializePlatformViewIfNeeded (platformViewId );
348411
349412 assertNotNull (androidView .getParent ());
@@ -354,7 +417,7 @@ public void disposeAndroidView__hybridComposition() {
354417 assertNull (androidView .getParent ());
355418
356419 // Simulate create call from the framework.
357- createPlatformView (jni , platformViewsController , platformViewId , "testType" );
420+ createPlatformView (jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ true );
358421 platformViewsController .initializePlatformViewIfNeeded (platformViewId );
359422
360423 assertNotNull (androidView .getParent ());
@@ -384,7 +447,7 @@ public void onEndFrame__destroysOverlaySurfaceAfterFrameOnFlutterSurfaceView() {
384447 jni .onFirstFrame ();
385448
386449 // Simulate create call from the framework.
387- createPlatformView (jni , platformViewsController , platformViewId , "testType" );
450+ createPlatformView (jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ true );
388451
389452 // Produce a frame that displays a platform view and an overlay surface.
390453 platformViewsController .onBeginFrame ();
@@ -447,7 +510,7 @@ public void onEndFrame__removesPlatformView() {
447510 jni .onFirstFrame ();
448511
449512 // Simulate create call from the framework.
450- createPlatformView (jni , platformViewsController , platformViewId , "testType" );
513+ createPlatformView (jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ true );
451514
452515 // Simulate first frame from the framework.
453516 jni .onFirstFrame ();
@@ -484,7 +547,7 @@ public void onEndFrame__removesPlatformViewParent() {
484547 jni .onFirstFrame ();
485548
486549 // Simulate create call from the framework.
487- createPlatformView (jni , platformViewsController , platformViewId , "testType" );
550+ createPlatformView (jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ true );
488551 platformViewsController .initializePlatformViewIfNeeded (platformViewId );
489552 assertEquals (flutterView .getChildCount (), 2 );
490553
@@ -520,7 +583,7 @@ public void detach__destroysOverlaySurfaces() {
520583 jni .onFirstFrame ();
521584
522585 // Simulate create call from the framework.
523- createPlatformView (jni , platformViewsController , platformViewId , "testType" );
586+ createPlatformView (jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ true );
524587
525588 // Produce a frame that displays a platform view and an overlay surface.
526589 platformViewsController .onBeginFrame ();
@@ -653,7 +716,7 @@ public void convertPlatformViewRenderSurfaceAsDefault() {
653716 jni .onFirstFrame ();
654717
655718 // Simulate create call from the framework.
656- createPlatformView (jni , platformViewsController , platformViewId , "testType" );
719+ createPlatformView (jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ true );
657720
658721 // Produce a frame that displays a platform view and an overlay surface.
659722 platformViewsController .onBeginFrame ();
@@ -702,7 +765,7 @@ public void dontConverRenderSurfaceWhenFlagIsTrue() {
702765 synchronizeToNativeViewHierarchy (jni , platformViewsController , false );
703766
704767 // Simulate create call from the framework.
705- createPlatformView (jni , platformViewsController , platformViewId , "testType" );
768+ createPlatformView (jni , platformViewsController , platformViewId , "testType" , /* hybrid=*/ true );
706769
707770 // Produce a frame that displays a platform view and an overlay surface.
708771 platformViewsController .onBeginFrame ();
@@ -734,12 +797,16 @@ private static void createPlatformView(
734797 FlutterJNI jni ,
735798 PlatformViewsController platformViewsController ,
736799 int platformViewId ,
737- String viewType ) {
800+ String viewType ,
801+ boolean hybrid ) {
738802 final Map <String , Object > platformViewCreateArguments = new HashMap <>();
739- platformViewCreateArguments .put ("hybrid" , true );
803+ platformViewCreateArguments .put ("hybrid" , hybrid );
740804 platformViewCreateArguments .put ("id" , platformViewId );
741805 platformViewCreateArguments .put ("viewType" , viewType );
742806 platformViewCreateArguments .put ("direction" , 0 );
807+ platformViewCreateArguments .put ("width" , 1.0 );
808+ platformViewCreateArguments .put ("height" , 1.0 );
809+
743810 final MethodCall platformCreateMethodCall =
744811 new MethodCall ("create" , platformViewCreateArguments );
745812
@@ -776,7 +843,30 @@ private static FlutterView attach(
776843 executor .onAttachedToJNI ();
777844
778845 final Context context = RuntimeEnvironment .application .getApplicationContext ();
779- platformViewsController .attach (context , null , executor );
846+ final TextureRegistry registry =
847+ new TextureRegistry () {
848+ public void TextureRegistry () {}
849+
850+ @ Override
851+ public SurfaceTextureEntry createSurfaceTexture () {
852+ return new SurfaceTextureEntry () {
853+ @ Override
854+ public SurfaceTexture surfaceTexture () {
855+ return mock (SurfaceTexture .class );
856+ }
857+
858+ @ Override
859+ public long id () {
860+ return 0 ;
861+ }
862+
863+ @ Override
864+ public void release () {}
865+ };
866+ }
867+ };
868+
869+ platformViewsController .attach (context , registry , executor );
780870
781871 final FlutterView view =
782872 new FlutterView (context , FlutterView .RenderMode .surface ) {
0 commit comments