From 76d310e42c0696c469fe77387c95f9b35a597f02 Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Fri, 18 Oct 2024 07:01:28 -0700 Subject: [PATCH] On a merged UI/platform thread, immediately execute platform message handlers and then run microtasks (#55933) Shell::OnPlatformViewDispatchPlatformMessage is called on the platform thread and must invoke the message handler on the UI thread. If the platform and UI threads are merged, then the handler can be run immediately. The shell can then post an empty task to the UI thread to make the UI message loop run the task observer that drains the microtask queue. Fixes https://github.com/flutter/flutter/issues/156595 --- shell/common/shell.cc | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 453845b3b7836..e634941db1660 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1064,28 +1064,14 @@ void Shell::OnPlatformViewDispatchPlatformMessage( } #endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG - // If the root isolate is not yet running this may be the navigation - // channel initial route and must be dispatched immediately so that - // it can be set before isolate creation. - static constexpr char kNavigationChannel[] = "flutter/navigation"; - if (!engine_->GetRuntimeController()->IsRootIsolateRunning() && - message->channel() == kNavigationChannel) { - // The static leak checker gets confused by the use of fml::MakeCopyable. - // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) - fml::TaskRunner::RunNowOrPostTask( - task_runners_.GetUITaskRunner(), - fml::MakeCopyable([engine = engine_->GetWeakPtr(), - message = std::move(message)]() mutable { - if (engine) { - engine->DispatchPlatformMessage(std::move(message)); - } - })); - } else { - // In all other cases, the message must be dispatched via a new task so - // that the completion of the platform channel response future is guaranteed - // to wake up the Dart event loop, even in cases where the platform and UI - // threads are the same. + if (task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread()) { + engine_->DispatchPlatformMessage(std::move(message)); + // Post an empty task to make the UI message loop run its task observers. + // The observers will execute any Dart microtasks queued by the platform + // message handler. + task_runners_.GetUITaskRunner()->PostTask([] {}); + } else { // The static leak checker gets confused by the use of fml::MakeCopyable. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) task_runners_.GetUITaskRunner()->PostTask(