Resubmit frame when the surface is switched (#19555)

diff --git a/shell/platform/android/external_view_embedder/external_view_embedder.cc b/shell/platform/android/external_view_embedder/external_view_embedder.cc
index e94b703..d564a8f 100644
--- a/shell/platform/android/external_view_embedder/external_view_embedder.cc
+++ b/shell/platform/android/external_view_embedder/external_view_embedder.cc
@@ -146,7 +146,8 @@
   // Submit the background canvas frame before switching the GL context to
   // the overlay surfaces.
   //
-  // Skip a frame if the embedding is switching surfaces.
+  // Skip a frame if the embedding is switching surfaces, and indicate in
+  // `PostPrerollAction` that this frame must be resubmitted.
   auto should_submit_current_frame =
       previous_frame_view_count_ > 0 || current_frame_view_count == 0;
   if (should_submit_current_frame) {
@@ -233,6 +234,10 @@
       CancelFrame();
       return PostPrerollResult::kResubmitFrame;
     }
+    // Surface switch requires to resubmit the frame.
+    if (previous_frame_view_count_ == 0) {
+      return PostPrerollResult::kResubmitFrame;
+    }
   }
   return PostPrerollResult::kSuccess;
 }
diff --git a/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc b/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc
index 1ad2be5..2f375ec 100644
--- a/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc
+++ b/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc
@@ -43,15 +43,19 @@
               (override));
 };
 
-fml::RefPtr<fml::RasterThreadMerger> GetThreadMergerFromPlatformThread() {
-  auto rasterizer_thread = new fml::Thread("rasterizer");
-  auto rasterizer_queue_id =
-      rasterizer_thread->GetTaskRunner()->GetTaskQueueId();
-
+fml::RefPtr<fml::RasterThreadMerger> GetThreadMergerFromPlatformThread(
+    bool merged = false) {
   // Assume the current thread is the platform thread.
   fml::MessageLoop::EnsureInitializedForCurrentThread();
   auto platform_queue_id = fml::MessageLoop::GetCurrentTaskQueueId();
 
+  if (merged) {
+    return fml::MakeRefCounted<fml::RasterThreadMerger>(platform_queue_id,
+                                                        platform_queue_id);
+  }
+  auto rasterizer_thread = new fml::Thread("rasterizer");
+  auto rasterizer_queue_id =
+      rasterizer_thread->GetTaskRunner()->GetTaskQueueId();
   return fml::MakeRefCounted<fml::RasterThreadMerger>(platform_queue_id,
                                                       rasterizer_queue_id);
 }
@@ -291,7 +295,9 @@
       };
   auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
       android_context, jni_mock, surface_factory);
-  auto raster_thread_merger = GetThreadMergerFromPlatformThread();
+
+  auto raster_thread_merger =
+      GetThreadMergerFromPlatformThread(/*merged=*/true);
 
   // ------------------ First frame ------------------ //
   {
@@ -309,6 +315,9 @@
     embedder->SubmitFrame(gr_context.get(), std::move(surface_frame));
     // Submits frame if no Android view in the current frame.
     EXPECT_TRUE(did_submit_frame);
+    // Doesn't resubmit frame.
+    auto postpreroll_result = embedder->PostPrerollAction(raster_thread_merger);
+    ASSERT_EQ(PostPrerollResult::kSuccess, postpreroll_result);
 
     EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
     embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
@@ -373,6 +382,9 @@
     embedder->SubmitFrame(gr_context.get(), std::move(surface_frame));
     // Doesn't submit frame if there aren't Android views in the previous frame.
     EXPECT_FALSE(did_submit_frame);
+    // Resubmits frame.
+    auto postpreroll_result = embedder->PostPrerollAction(raster_thread_merger);
+    ASSERT_EQ(PostPrerollResult::kResubmitFrame, postpreroll_result);
 
     EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
     embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
@@ -434,6 +446,9 @@
     embedder->SubmitFrame(gr_context.get(), std::move(surface_frame));
     // Submits frame if there are Android views in the previous frame.
     EXPECT_TRUE(did_submit_frame);
+    // Doesn't resubmit frame.
+    auto postpreroll_result = embedder->PostPrerollAction(raster_thread_merger);
+    ASSERT_EQ(PostPrerollResult::kSuccess, postpreroll_result);
 
     EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
     embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);