diff --git a/engine/src/flutter/shell/platform/linux/fl_binary_messenger.cc b/engine/src/flutter/shell/platform/linux/fl_binary_messenger.cc index 892c477f651..dae96402cbb 100644 --- a/engine/src/flutter/shell/platform/linux/fl_binary_messenger.cc +++ b/engine/src/flutter/shell/platform/linux/fl_binary_messenger.cc @@ -324,12 +324,14 @@ static GBytes* send_on_channel_finish(FlBinaryMessenger* messenger, static gboolean finish_method(GObject* object, GAsyncResult* result, GError** error) { - g_autoptr(FlMethodResponse) response = fl_method_channel_invoke_method_finish( - FL_METHOD_CHANNEL(object), result, error); + g_autoptr(GBytes) response = fl_binary_messenger_send_on_channel_finish( + FL_BINARY_MESSENGER(object), result, error); if (response == nullptr) { return FALSE; } - return fl_method_response_get_result(response, error) != nullptr; + g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new(); + return fl_method_codec_decode_response(FL_METHOD_CODEC(codec), response, + error) != nullptr; } // Called when a response is received for the resize channel message. diff --git a/engine/src/flutter/shell/platform/linux/fl_binary_messenger_test.cc b/engine/src/flutter/shell/platform/linux/fl_binary_messenger_test.cc index 3f445e9d9f9..d045cd2c0e9 100644 --- a/engine/src/flutter/shell/platform/linux/fl_binary_messenger_test.cc +++ b/engine/src/flutter/shell/platform/linux/fl_binary_messenger_test.cc @@ -501,6 +501,56 @@ TEST(FlBinaryMessengerTest, AllowOverflowChannel) { EXPECT_TRUE(called); } +static gboolean quit_main_loop_cb(gpointer user_data) { + g_main_loop_quit(static_cast(user_data)); + return FALSE; +} + +// Checks if error returned when invoking a command on the control channel +// are handled. +TEST(FlBinaryMessengerTest, ControlChannelErrorResponse) { + g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0); + g_autoptr(FlEngine) engine = make_mock_engine(); + FlBinaryMessenger* messenger = fl_binary_messenger_new(engine); + + g_autoptr(GError) error = nullptr; + EXPECT_TRUE(fl_engine_start(engine, &error)); + EXPECT_EQ(error, nullptr); + + FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine); + + bool called = false; + + FlutterEngineSendPlatformMessageFnPtr old_handler = + embedder_api->SendPlatformMessage; + embedder_api->SendPlatformMessage = MOCK_ENGINE_PROC( + SendPlatformMessage, + ([&called, old_handler, loop](auto engine, + const FlutterPlatformMessage* message) { + // Expect to receive a message on the "control" channel. + if (strcmp(message->channel, "dev.flutter/channel-buffers") != 0) { + return old_handler(engine, message); + } + + called = true; + + // Register a callback to quit the main loop when binary messenger work + // ends. + g_idle_add(quit_main_loop_cb, loop); + + // Simulates an internal error. + return kInvalidArguments; + })); + + fl_binary_messenger_set_allow_channel_overflow(messenger, "flutter/test", + true); + + EXPECT_TRUE(called); + + // Blocks here until quit_main_loop_cb is called. + g_main_loop_run(loop); +} + // NOLINTEND(clang-analyzer-core.StackAddressEscape) struct RespondsOnBackgroundThreadInfo {