Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit ee1ded6

Browse files
Fix memory leaks in some embedder unit tests that send key events (#49548)
FlutterEngineSendKeyEvent sends a platform message. The test's embedder configuration must have a platform message callback that calls FlutterEngineSendPlatformMessageResponse to free the message's response handle.
1 parent b4c4dfc commit ee1ded6

File tree

1 file changed

+86
-35
lines changed

1 file changed

+86
-35
lines changed

shell/platform/embedder/tests/embedder_unittests.cc

Lines changed: 86 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,21 +2128,33 @@ TEST_F(EmbedderTest, KeyDataIsCorrectlySerialized) {
21282128
message_latch->Signal();
21292129
};
21302130

2131-
auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2132-
EmbedderConfigBuilder builder(context);
2133-
builder.SetSoftwareRendererConfig();
2134-
builder.SetDartEntrypoint("key_data_echo");
2131+
auto platform_task_runner = CreateNewThread("platform_thread");
2132+
2133+
UniqueEngine engine;
21352134
fml::AutoResetWaitableEvent ready;
2136-
context.AddNativeCallback(
2137-
"SignalNativeTest",
2138-
CREATE_NATIVE_ENTRY(
2139-
[&ready](Dart_NativeArguments args) { ready.Signal(); }));
2135+
platform_task_runner->PostTask([&]() {
2136+
auto& context =
2137+
GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2138+
EmbedderConfigBuilder builder(context);
2139+
builder.SetSoftwareRendererConfig();
2140+
builder.SetDartEntrypoint("key_data_echo");
2141+
builder.SetPlatformMessageCallback(
2142+
[&](const FlutterPlatformMessage* message) {
2143+
FlutterEngineSendPlatformMessageResponse(
2144+
engine.get(), message->response_handle, nullptr, 0);
2145+
});
2146+
context.AddNativeCallback(
2147+
"SignalNativeTest",
2148+
CREATE_NATIVE_ENTRY(
2149+
[&ready](Dart_NativeArguments args) { ready.Signal(); }));
21402150

2141-
context.AddNativeCallback("EchoKeyEvent",
2142-
CREATE_NATIVE_ENTRY(native_echo_event));
2151+
context.AddNativeCallback("EchoKeyEvent",
2152+
CREATE_NATIVE_ENTRY(native_echo_event));
2153+
2154+
engine = builder.LaunchEngine();
2155+
ASSERT_TRUE(engine.is_valid());
2156+
});
21432157

2144-
auto engine = builder.LaunchEngine();
2145-
ASSERT_TRUE(engine.is_valid());
21462158
ready.Wait();
21472159

21482160
// A normal down event
@@ -2156,8 +2168,10 @@ TEST_F(EmbedderTest, KeyDataIsCorrectlySerialized) {
21562168
.synthesized = false,
21572169
.device_type = kFlutterKeyEventDeviceTypeKeyboard,
21582170
};
2159-
FlutterEngineSendKeyEvent(engine.get(), &down_event_upper_a, nullptr,
2160-
nullptr);
2171+
platform_task_runner->PostTask([&]() {
2172+
FlutterEngineSendKeyEvent(engine.get(), &down_event_upper_a, nullptr,
2173+
nullptr);
2174+
});
21612175
message_latch->Wait();
21622176

21632177
ExpectKeyEventEq(echoed_event, down_event_upper_a);
@@ -2174,8 +2188,10 @@ TEST_F(EmbedderTest, KeyDataIsCorrectlySerialized) {
21742188
.synthesized = false,
21752189
.device_type = kFlutterKeyEventDeviceTypeKeyboard,
21762190
};
2177-
FlutterEngineSendKeyEvent(engine.get(), &repeat_event_wide_char, nullptr,
2178-
nullptr);
2191+
platform_task_runner->PostTask([&]() {
2192+
FlutterEngineSendKeyEvent(engine.get(), &repeat_event_wide_char, nullptr,
2193+
nullptr);
2194+
});
21792195
message_latch->Wait();
21802196

21812197
ExpectKeyEventEq(echoed_event, repeat_event_wide_char);
@@ -2192,11 +2208,20 @@ TEST_F(EmbedderTest, KeyDataIsCorrectlySerialized) {
21922208
.synthesized = true,
21932209
.device_type = kFlutterKeyEventDeviceTypeKeyboard,
21942210
};
2195-
FlutterEngineSendKeyEvent(engine.get(), &up_event, nullptr, nullptr);
2211+
platform_task_runner->PostTask([&]() {
2212+
FlutterEngineSendKeyEvent(engine.get(), &up_event, nullptr, nullptr);
2213+
});
21962214
message_latch->Wait();
21972215

21982216
ExpectKeyEventEq(echoed_event, up_event);
21992217
EXPECT_EQ(echoed_char, 0llu);
2218+
2219+
fml::AutoResetWaitableEvent shutdown_latch;
2220+
platform_task_runner->PostTask([&]() {
2221+
engine.reset();
2222+
shutdown_latch.Signal();
2223+
});
2224+
shutdown_latch.Wait();
22002225
}
22012226

22022227
TEST_F(EmbedderTest, KeyDataAreBuffered) {
@@ -2225,21 +2250,32 @@ TEST_F(EmbedderTest, KeyDataAreBuffered) {
22252250
message_latch->Signal();
22262251
};
22272252

2228-
auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2229-
EmbedderConfigBuilder builder(context);
2230-
builder.SetSoftwareRendererConfig();
2231-
builder.SetDartEntrypoint("key_data_late_echo");
2253+
auto platform_task_runner = CreateNewThread("platform_thread");
2254+
2255+
UniqueEngine engine;
22322256
fml::AutoResetWaitableEvent ready;
2233-
context.AddNativeCallback(
2234-
"SignalNativeTest",
2235-
CREATE_NATIVE_ENTRY(
2236-
[&ready](Dart_NativeArguments args) { ready.Signal(); }));
2257+
platform_task_runner->PostTask([&]() {
2258+
auto& context =
2259+
GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2260+
EmbedderConfigBuilder builder(context);
2261+
builder.SetSoftwareRendererConfig();
2262+
builder.SetDartEntrypoint("key_data_late_echo");
2263+
builder.SetPlatformMessageCallback(
2264+
[&](const FlutterPlatformMessage* message) {
2265+
FlutterEngineSendPlatformMessageResponse(
2266+
engine.get(), message->response_handle, nullptr, 0);
2267+
});
2268+
context.AddNativeCallback(
2269+
"SignalNativeTest",
2270+
CREATE_NATIVE_ENTRY(
2271+
[&ready](Dart_NativeArguments args) { ready.Signal(); }));
22372272

2238-
context.AddNativeCallback("EchoKeyEvent",
2239-
CREATE_NATIVE_ENTRY(native_echo_event));
2273+
context.AddNativeCallback("EchoKeyEvent",
2274+
CREATE_NATIVE_ENTRY(native_echo_event));
22402275

2241-
auto engine = builder.LaunchEngine();
2242-
ASSERT_TRUE(engine.is_valid());
2276+
engine = builder.LaunchEngine();
2277+
ASSERT_TRUE(engine.is_valid());
2278+
});
22432279
ready.Wait();
22442280

22452281
FlutterKeyEvent sample_event{
@@ -2254,7 +2290,11 @@ TEST_F(EmbedderTest, KeyDataAreBuffered) {
22542290

22552291
// Send an event.
22562292
sample_event.timestamp = 1.0l;
2257-
FlutterEngineSendKeyEvent(engine.get(), &sample_event, nullptr, nullptr);
2293+
platform_task_runner->PostTask([&]() {
2294+
FlutterEngineSendKeyEvent(engine.get(), &sample_event, nullptr, nullptr);
2295+
message_latch->Signal();
2296+
});
2297+
message_latch->Wait();
22582298

22592299
// Should not receive echos because the callback is not set yet.
22602300
EXPECT_EQ(echoed_events.size(), 0u);
@@ -2273,11 +2313,13 @@ TEST_F(EmbedderTest, KeyDataAreBuffered) {
22732313
.response_handle = response_handle,
22742314
};
22752315

2276-
FlutterEngineResult result =
2277-
FlutterEngineSendPlatformMessage(engine.get(), &message);
2278-
ASSERT_EQ(result, kSuccess);
2316+
platform_task_runner->PostTask([&]() {
2317+
FlutterEngineResult result =
2318+
FlutterEngineSendPlatformMessage(engine.get(), &message);
2319+
ASSERT_EQ(result, kSuccess);
22792320

2280-
FlutterPlatformMessageReleaseResponseHandle(engine.get(), response_handle);
2321+
FlutterPlatformMessageReleaseResponseHandle(engine.get(), response_handle);
2322+
});
22812323

22822324
// message_latch->Wait();
22832325
message_latch->Wait();
@@ -2286,11 +2328,20 @@ TEST_F(EmbedderTest, KeyDataAreBuffered) {
22862328

22872329
// Send a second event.
22882330
sample_event.timestamp = 10.0l;
2289-
FlutterEngineSendKeyEvent(engine.get(), &sample_event, nullptr, nullptr);
2331+
platform_task_runner->PostTask([&]() {
2332+
FlutterEngineSendKeyEvent(engine.get(), &sample_event, nullptr, nullptr);
2333+
});
22902334
message_latch->Wait();
22912335

22922336
// The event should be echoed, too.
22932337
EXPECT_EQ(echoed_events.size(), 2u);
2338+
2339+
fml::AutoResetWaitableEvent shutdown_latch;
2340+
platform_task_runner->PostTask([&]() {
2341+
engine.reset();
2342+
shutdown_latch.Signal();
2343+
});
2344+
shutdown_latch.Wait();
22942345
}
22952346

22962347
TEST_F(EmbedderTest, KeyDataResponseIsCorrectlyInvoked) {

0 commit comments

Comments
 (0)