@@ -477,6 +477,108 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) {
477477 }
478478}
479479
480+ TEST (AndroidExternalViewEmbedder, SubmitFrame__overlayComposition) {
481+ auto jni_mock = std::make_shared<JNIMock>();
482+ auto android_context =
483+ std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware );
484+
485+ auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr );
486+ auto gr_context = GrDirectContext::MakeMock (nullptr );
487+ auto frame_size = SkISize::Make (1000 , 1000 );
488+ auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
489+ [&android_context, gr_context, window, frame_size]() {
490+ auto surface_frame_1 = std::make_unique<SurfaceFrame>(
491+ SkSurface::MakeNull (1000 , 1000 ), false ,
492+ [](const SurfaceFrame& surface_frame, SkCanvas* canvas) {
493+ return true ;
494+ });
495+
496+ auto surface_mock = std::make_unique<SurfaceMock>();
497+ EXPECT_CALL (*surface_mock, AcquireFrame (frame_size))
498+ .Times (1 /* frames */ )
499+ .WillOnce (Return (ByMove (std::move (surface_frame_1))));
500+
501+ auto android_surface_mock =
502+ std::make_unique<AndroidSurfaceMock>(android_context);
503+ EXPECT_CALL (*android_surface_mock, IsValid ()).WillOnce (Return (true ));
504+
505+ EXPECT_CALL (*android_surface_mock, CreateGPUSurface (gr_context.get ()))
506+ .WillOnce (Return (ByMove (std::move (surface_mock))));
507+
508+ EXPECT_CALL (*android_surface_mock, SetNativeWindow (window));
509+ return android_surface_mock;
510+ });
511+ auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
512+ *android_context, jni_mock, surface_factory);
513+
514+ auto raster_thread_merger =
515+ GetThreadMergerFromPlatformThread (/* merged=*/ true );
516+
517+ EXPECT_CALL (*jni_mock, FlutterViewBeginFrame ());
518+ embedder->BeginFrame (frame_size, nullptr , 1.5 , raster_thread_merger);
519+
520+ {
521+ // Add first Android view.
522+ SkMatrix matrix;
523+ MutatorsStack stack;
524+ stack.PushTransform (SkMatrix::Translate (0 , 0 ));
525+
526+ embedder->PrerollCompositeEmbeddedView (
527+ 0 , std::make_unique<EmbeddedViewParams>(matrix, SkSize::Make (200 , 200 ),
528+ stack));
529+ EXPECT_CALL (*jni_mock, FlutterViewOnDisplayPlatformView (0 , 0 , 0 , 200 , 200 ,
530+ 300 , 300 , stack));
531+ }
532+
533+ auto rect_paint = SkPaint ();
534+ rect_paint.setColor (SkColors::kCyan );
535+ rect_paint.setStyle (SkPaint::Style::kFill_Style );
536+
537+ // This simulates Flutter UI that intersects with the first Android view.
538+ embedder->CompositeEmbeddedView (0 )->drawRect (
539+ SkRect::MakeXYWH (25 , 25 , 80 , 150 ), rect_paint);
540+
541+ {
542+ // Add second Android view.
543+ SkMatrix matrix;
544+ MutatorsStack stack;
545+ stack.PushTransform (SkMatrix::Translate (0 , 100 ));
546+
547+ embedder->PrerollCompositeEmbeddedView (
548+ 1 , std::make_unique<EmbeddedViewParams>(matrix, SkSize::Make (100 , 100 ),
549+ stack));
550+ EXPECT_CALL (*jni_mock, FlutterViewOnDisplayPlatformView (1 , 0 , 0 , 100 , 100 ,
551+ 150 , 150 , stack));
552+ }
553+ // This simulates Flutter UI that intersects with the first and second Android
554+ // views.
555+ embedder->CompositeEmbeddedView (1 )->drawRect (SkRect::MakeXYWH (25 , 25 , 80 , 50 ),
556+ rect_paint);
557+
558+ embedder->CompositeEmbeddedView (1 )->drawRect (
559+ SkRect::MakeXYWH (75 , 75 , 30 , 100 ), rect_paint);
560+
561+ EXPECT_CALL (*jni_mock, FlutterViewCreateOverlaySurface ())
562+ .WillRepeatedly ([&]() {
563+ return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
564+ 1 , window);
565+ });
566+
567+ EXPECT_CALL (*jni_mock, FlutterViewDisplayOverlaySurface (1 , 25 , 25 , 80 , 150 ))
568+ .Times (2 );
569+
570+ auto surface_frame = std::make_unique<SurfaceFrame>(
571+ SkSurface::MakeNull (1000 , 1000 ), false ,
572+ [](const SurfaceFrame& surface_frame, SkCanvas* canvas) mutable {
573+ return true ;
574+ });
575+
576+ embedder->SubmitFrame (gr_context.get (), std::move (surface_frame), nullptr );
577+
578+ EXPECT_CALL (*jni_mock, FlutterViewEndFrame ());
579+ embedder->EndFrame (/* should_resubmit_frame=*/ false , raster_thread_merger);
580+ }
581+
480582TEST (AndroidExternalViewEmbedder, DoesNotCallJNIPlatformThreadOnlyMethods) {
481583 auto jni_mock = std::make_shared<JNIMock>();
482584
0 commit comments