未验证 提交 87124617 编写于 作者: C Chinmay Garde 提交者: GitHub

Allow custom embedders to post low memory notifications. (#14506)

This is a non-breaking addition to the stable Flutter Embedder API.
上级 3dd67a84
......@@ -1503,6 +1503,37 @@ FlutterEngineResult FlutterEngineRunTask(FLUTTER_API_SYMBOL(FlutterEngine)
"Could not run the specified task.");
}
static bool DispatchJSONPlatformMessage(FLUTTER_API_SYMBOL(FlutterEngine)
engine,
rapidjson::Document document,
const std::string& channel_name) {
if (channel_name.size() == 0) {
return false;
}
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
if (!document.Accept(writer)) {
return false;
}
const char* message = buffer.GetString();
if (message == nullptr || buffer.GetSize() == 0) {
return false;
}
auto platform_message = fml::MakeRefCounted<flutter::PlatformMessage>(
channel_name.c_str(), // channel
std::vector<uint8_t>{message, message + buffer.GetSize()}, // message
nullptr // response
);
return reinterpret_cast<flutter::EmbedderEngine*>(engine)
->SendPlatformMessage(std::move(platform_message));
}
FlutterEngineResult FlutterEngineUpdateLocales(FLUTTER_API_SYMBOL(FlutterEngine)
engine,
const FlutterLocale** locales,
......@@ -1555,27 +1586,8 @@ FlutterEngineResult FlutterEngineUpdateLocales(FLUTTER_API_SYMBOL(FlutterEngine)
}
document.AddMember("args", args, allocator);
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
if (!document.Accept(writer)) {
return LOG_EMBEDDER_ERROR(kInternalInconsistency,
"Could not create locale payload.");
}
const char* message = buffer.GetString();
if (message == nullptr || buffer.GetSize() == 0) {
return LOG_EMBEDDER_ERROR(kInternalInconsistency,
"Could not create locale update message.");
}
auto platform_message = fml::MakeRefCounted<flutter::PlatformMessage>(
"flutter/localization", // channel
std::vector<uint8_t>{message, message + buffer.GetSize()}, // message
nullptr // response
);
return reinterpret_cast<flutter::EmbedderEngine*>(engine)
->SendPlatformMessage(std::move(platform_message))
return DispatchJSONPlatformMessage(engine, std::move(document),
"flutter/localization")
? kSuccess
: LOG_EMBEDDER_ERROR(kInternalInconsistency,
"Could not send message to update locale of "
......@@ -1710,3 +1722,27 @@ FlutterEngineResult FlutterEnginePostDartObject(
typed_data_finalizer.Release();
return kSuccess;
}
FLUTTER_EXPORT
FlutterEngineResult FlutterEngineNotifyLowMemoryWarning(
FLUTTER_API_SYMBOL(FlutterEngine) raw_engine) {
auto engine = reinterpret_cast<flutter::EmbedderEngine*>(raw_engine);
if (engine == nullptr || !engine->IsValid()) {
return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine was invalid.");
}
engine->GetShell().NotifyLowMemoryWarning();
rapidjson::Document document;
auto& allocator = document.GetAllocator();
document.SetObject();
document.AddMember("type", "memoryPressure", allocator);
return DispatchJSONPlatformMessage(raw_engine, std::move(document),
"flutter/system")
? kSuccess
: LOG_EMBEDDER_ERROR(
kInternalInconsistency,
"Could not dispatch the low memory notification message.");
}
......@@ -1626,7 +1626,7 @@ bool FlutterEngineRunsAOTCompiledDartCode(void);
/// `FlutterEngineDeinitialize` or `FlutterEngineShutdown` on
/// another thread.
///
/// @param[in] engine. A running engine instance.
/// @param[in] engine A running engine instance.
/// @param[in] port The send port to send the object to.
/// @param[in] object The object to send to the isolate with the
/// corresponding receive port.
......@@ -1639,6 +1639,27 @@ FlutterEngineResult FlutterEnginePostDartObject(
FlutterEngineDartPort port,
const FlutterEngineDartObject* object);
//------------------------------------------------------------------------------
/// @brief Posts a low memory notification to a running engine instance.
/// The engine will do its best to release non-critical resources in
/// response. It is not guaranteed that the resource would have been
/// collected by the time this call returns however. The
/// notification is posted to engine subsystems that may be
/// operating on other threads.
///
/// Flutter applications can respond to these notifications by
/// setting `WidgetsBindingObserver.didHaveMemoryPressure`
/// observers.
///
/// @param[in] engine A running engine instance.
///
/// @return If the low memory notification was sent to the running engine
/// instance.
///
FLUTTER_EXPORT
FlutterEngineResult FlutterEngineNotifyLowMemoryWarning(
FLUTTER_API_SYMBOL(FlutterEngine) engine);
#if defined(__cplusplus)
} // extern "C"
#endif
......
......@@ -3805,5 +3805,23 @@ TEST_F(EmbedderTest, ObjectsCanBePostedViaPorts) {
buffer_released_latch.Wait();
}
TEST_F(EmbedderTest, CanSendLowMemoryNotification) {
auto& context = GetEmbedderContext();
EmbedderConfigBuilder builder(context);
builder.SetSoftwareRendererConfig();
auto engine = builder.LaunchEngine();
ASSERT_TRUE(engine.is_valid());
// TODO(chinmaygarde): The shell ought to have a mechanism for notification
// dispatch that engine subsystems can register handlers to. This would allow
// the raster cache and the secondary context caches to respond to
// notifications. Once that is in place, this test can be updated to actually
// ensure that the dispatched message is visible to engine subsystems.
ASSERT_EQ(FlutterEngineNotifyLowMemoryWarning(engine.get()), kSuccess);
}
} // namespace testing
} // namespace flutter
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册