[Linux] Fix channel buffers control commands error handling (flutter/engine#45056)

## Description

This PR fixes a mistake I made on https://github.com/flutter/engine/pull/44636 where the error handling code wrongly relied on `fl_method_channel_invoke_method_finish` instead of  `fl_binary_messenger_send_on_channel_finish`.
The error handling code was not called when running the tests added in https://github.com/flutter/engine/pull/44636 so this mistake did not pop up.

@robert-ancell I added a test that simulates an error response and I had to rely on `g_idle_add` to make it works. Is this approach ok?

## Related Issue

Linux implementation for https://github.com/flutter/flutter/issues/132386

## Tests

Adds one test.
This commit is contained in:
Bruno Leroux 2023-09-01 09:40:25 +02:00 committed by GitHub
parent 8a374e0c30
commit 1dc91d901e
2 changed files with 55 additions and 3 deletions

View File

@ -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.

View File

@ -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<GMainLoop*>(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 {