未验证 提交 e55af0eb 编写于 作者: G Gary Qian 提交者: GitHub

Desktop embedder ComputePlatformResolvedLocale entrypoint (#19597)

上级 b1142063
......@@ -6,6 +6,9 @@
#define RAPIDJSON_HAS_STDSTRING 1
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include "flutter/fml/build_config.h"
#include "flutter/fml/closure.h"
......@@ -910,6 +913,54 @@ FlutterEngineResult FlutterEngineInitialize(size_t version,
};
}
flutter::PlatformViewEmbedder::ComputePlatformResolvedLocaleCallback
compute_platform_resolved_locale_callback = nullptr;
if (SAFE_ACCESS(args, compute_platform_resolved_locale_callback, nullptr) !=
nullptr) {
compute_platform_resolved_locale_callback =
[ptr = args->compute_platform_resolved_locale_callback](
const std::vector<std::string>& supported_locales_data) {
const size_t number_of_strings_per_locale = 3;
size_t locale_count =
supported_locales_data.size() / number_of_strings_per_locale;
std::vector<FlutterLocale> supported_locales;
std::vector<const FlutterLocale*> supported_locales_ptr;
for (size_t i = 0; i < locale_count; ++i) {
supported_locales.push_back(
{.struct_size = sizeof(FlutterLocale),
.language_code =
supported_locales_data[i * number_of_strings_per_locale +
0]
.c_str(),
.country_code =
supported_locales_data[i * number_of_strings_per_locale +
1]
.c_str(),
.script_code =
supported_locales_data[i * number_of_strings_per_locale +
2]
.c_str(),
.variant_code = nullptr});
supported_locales_ptr.push_back(&supported_locales[i]);
}
const FlutterLocale* result =
ptr(supported_locales_ptr.data(), locale_count);
std::unique_ptr<std::vector<std::string>> out =
std::make_unique<std::vector<std::string>>();
if (result) {
std::string language_code(SAFE_ACCESS(result, language_code, ""));
if (language_code != "") {
out->push_back(language_code);
out->emplace_back(SAFE_ACCESS(result, country_code, ""));
out->emplace_back(SAFE_ACCESS(result, script_code, ""));
}
}
return out;
};
}
auto external_view_embedder_result =
InferExternalViewEmbedderFromArgs(SAFE_ACCESS(args, compositor, nullptr));
if (external_view_embedder_result.second) {
......@@ -919,10 +970,11 @@ FlutterEngineResult FlutterEngineInitialize(size_t version,
flutter::PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table =
{
update_semantics_nodes_callback, //
update_semantics_custom_actions_callback, //
platform_message_response_callback, //
vsync_callback, //
update_semantics_nodes_callback, //
update_semantics_custom_actions_callback, //
platform_message_response_callback, //
vsync_callback, //
compute_platform_resolved_locale_callback, //
};
auto on_create_platform_view = InferPlatformViewCreationCallback(
......@@ -1058,17 +1110,17 @@ FlutterEngineResult FlutterEngineRunInitialized(
auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
// The engine must not already be running. Initialize may only be called once
// on an engine instance.
// The engine must not already be running. Initialize may only be called
// once on an engine instance.
if (embedder_engine->IsValid()) {
return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
}
// Step 1: Launch the shell.
if (!embedder_engine->LaunchShell()) {
return LOG_EMBEDDER_ERROR(
kInvalidArguments,
"Could not launch the engine using supplied initialization arguments.");
return LOG_EMBEDDER_ERROR(kInvalidArguments,
"Could not launch the engine using supplied "
"initialization arguments.");
}
// Step 2: Tell the platform view to initialize itself.
......@@ -1193,8 +1245,8 @@ inline int64_t PointerDataButtonsForLegacyEvent(
switch (change) {
case flutter::PointerData::Change::kDown:
case flutter::PointerData::Change::kMove:
// These kinds of change must have a non-zero `buttons`, otherwise gesture
// recognizers will ignore these events.
// These kinds of change must have a non-zero `buttons`, otherwise
// gesture recognizers will ignore these events.
return flutter::kPointerButtonMousePrimary;
case flutter::PointerData::Change::kCancel:
case flutter::PointerData::Change::kAdd:
......@@ -1236,16 +1288,17 @@ FlutterEngineResult FlutterEngineSendPointerEvent(
pointer_data.physical_delta_x = 0.0;
pointer_data.physical_delta_y = 0.0;
pointer_data.device = SAFE_ACCESS(current, device, 0);
// Pointer identifier will be generated in pointer_data_packet_converter.cc.
// Pointer identifier will be generated in
// pointer_data_packet_converter.cc.
pointer_data.pointer_identifier = 0;
pointer_data.signal_kind = ToPointerDataSignalKind(
SAFE_ACCESS(current, signal_kind, kFlutterPointerSignalKindNone));
pointer_data.scroll_delta_x = SAFE_ACCESS(current, scroll_delta_x, 0.0);
pointer_data.scroll_delta_y = SAFE_ACCESS(current, scroll_delta_y, 0.0);
FlutterPointerDeviceKind device_kind = SAFE_ACCESS(current, device_kind, 0);
// For backwards compatibility with embedders written before the device kind
// and buttons were exposed, if the device kind is not set treat it as a
// mouse, with a synthesized primary button state based on the phase.
// For backwards compatibility with embedders written before the device
// kind and buttons were exposed, if the device kind is not set treat it
// as a mouse, with a synthesized primary button state based on the phase.
if (device_kind == 0) {
pointer_data.kind = flutter::PointerData::DeviceKind::kMouse;
pointer_data.buttons =
......@@ -1356,9 +1409,9 @@ FlutterEngineResult FlutterPlatformMessageCreateResponseHandle(
auto handle = new FlutterPlatformMessageResponseHandle();
handle->message = fml::MakeRefCounted<flutter::PlatformMessage>(
"", // The channel is empty and unused as the response handle is going to
// referenced directly in the |FlutterEngineSendPlatformMessage| with
// the container message discarded.
"", // The channel is empty and unused as the response handle is going
// to referenced directly in the |FlutterEngineSendPlatformMessage|
// with the container message discarded.
fml::MakeRefCounted<flutter::EmbedderPlatformMessageResponse>(
std::move(platform_task_runner), response_callback));
*response_out = handle;
......@@ -1791,14 +1844,14 @@ FlutterEngineResult FlutterEnginePostDartObject(
peer->trampoline = callback;
// This finalizer is set so that in case of failure of the
// Dart_PostCObject below, we collect the peer. The embedder is still
// responsible for collecting the buffer in case of non-kSuccess returns
// from this method. This finalizer must be released in case of kSuccess
// returns from this method.
// responsible for collecting the buffer in case of non-kSuccess
// returns from this method. This finalizer must be released in case
// of kSuccess returns from this method.
typed_data_finalizer.SetClosure([peer]() {
// This is the tiny object we use as the peer to the Dart call so that
// we can attach the a trampoline to the embedder supplied callback.
// In case of error, we need to collect this object lest we introduce
// a tiny leak.
// This is the tiny object we use as the peer to the Dart call so
// that we can attach the a trampoline to the embedder supplied
// callback. In case of error, we need to collect this object lest
// we introduce a tiny leak.
delete peer;
});
dart_object.type = Dart_CObject_kExternalTypedData;
......
......@@ -861,6 +861,10 @@ typedef struct {
const char* variant_code;
} FlutterLocale;
typedef const FlutterLocale* (*FlutterComputePlatformResolvedLocaleCallback)(
const FlutterLocale** /* supported_locales*/,
size_t /* Number of locales*/);
typedef int64_t FlutterEngineDartPort;
typedef enum {
......@@ -1205,6 +1209,17 @@ typedef struct {
///
/// Embedders can provide either snapshot buffers or aot_data, but not both.
FlutterEngineAOTData aot_data;
/// A callback that computes the locale the platform would natively resolve
/// to.
///
/// The input parameter is an array of FlutterLocales which represent the
/// locales supported by the app. One of the input supported locales should
/// be selected and returned to best match with the user/device's preferred
/// locale. The implementation should produce a result that as closely
/// matches what the platform would natively resolve to as possible.
FlutterComputePlatformResolvedLocaleCallback
compute_platform_resolved_locale_callback;
} FlutterProjectArgs;
//------------------------------------------------------------------------------
......
......@@ -97,6 +97,11 @@ std::unique_ptr<VsyncWaiter> PlatformViewEmbedder::CreateVSyncWaiter() {
std::unique_ptr<std::vector<std::string>>
PlatformViewEmbedder::ComputePlatformResolvedLocales(
const std::vector<std::string>& supported_locale_data) {
if (platform_dispatch_table_.compute_platform_resolved_locale_callback !=
nullptr) {
return platform_dispatch_table_.compute_platform_resolved_locale_callback(
supported_locale_data);
}
std::unique_ptr<std::vector<std::string>> out =
std::make_unique<std::vector<std::string>>();
return out;
......
......@@ -25,6 +25,9 @@ class PlatformViewEmbedder final : public PlatformView {
std::function<void(flutter::CustomAccessibilityActionUpdates actions)>;
using PlatformMessageResponseCallback =
std::function<void(fml::RefPtr<flutter::PlatformMessage>)>;
using ComputePlatformResolvedLocaleCallback =
std::function<std::unique_ptr<std::vector<std::string>>(
const std::vector<std::string>& supported_locale_data)>;
struct PlatformDispatchTable {
UpdateSemanticsNodesCallback update_semantics_nodes_callback; // optional
......@@ -33,6 +36,8 @@ class PlatformViewEmbedder final : public PlatformView {
PlatformMessageResponseCallback
platform_message_response_callback; // optional
VsyncWaiterEmbedder::VsyncCallback vsync_callback; // optional
ComputePlatformResolvedLocaleCallback
compute_platform_resolved_locale_callback;
};
// Creates a platform view that sets up an OpenGL rasterizer.
......
......@@ -80,6 +80,7 @@ EmbedderConfigBuilder::EmbedderConfigBuilder(
SetAssetsPath();
SetIsolateCreateCallbackHook();
SetSemanticsCallbackHooks();
SetLocalizationCallbackHooks();
AddCommandLineArgument("--disable-observatory");
if (preference == InitializationPreference::kSnapshotsInitialize ||
......@@ -157,6 +158,11 @@ void EmbedderConfigBuilder::SetSemanticsCallbackHooks() {
EmbedderTestContext::GetUpdateSemanticsCustomActionCallbackHook();
}
void EmbedderConfigBuilder::SetLocalizationCallbackHooks() {
project_args_.compute_platform_resolved_locale_callback =
EmbedderTestContext::GetComputePlatformResolvedLocaleCallbackHook();
}
void EmbedderConfigBuilder::SetDartEntrypoint(std::string entrypoint) {
if (entrypoint.size() == 0) {
return;
......
......@@ -59,6 +59,8 @@ class EmbedderConfigBuilder {
void SetSemanticsCallbackHooks();
void SetLocalizationCallbackHooks();
void SetDartEntrypoint(std::string entrypoint);
void AddCommandLineArgument(std::string arg);
......
......@@ -160,6 +160,14 @@ EmbedderTestContext::GetUpdateSemanticsCustomActionCallbackHook() {
};
}
FlutterComputePlatformResolvedLocaleCallback
EmbedderTestContext::GetComputePlatformResolvedLocaleCallbackHook() {
return [](const FlutterLocale** supported_locales,
size_t length) -> const FlutterLocale* {
return supported_locales[0];
};
}
void EmbedderTestContext::SetupOpenGLSurface(SkISize surface_size) {
FML_CHECK(!gl_surface_);
gl_surface_ = std::make_unique<TestGLSurface>(surface_size);
......
......@@ -112,6 +112,9 @@ class EmbedderTestContext {
static FlutterUpdateSemanticsCustomActionCallback
GetUpdateSemanticsCustomActionCallbackHook();
static FlutterComputePlatformResolvedLocaleCallback
GetComputePlatformResolvedLocaleCallbackHook();
void SetupAOTMappingsIfNecessary();
void SetupAOTDataIfNecessary();
......
......@@ -5,6 +5,7 @@
#define FML_USED_ON_EMBEDDER
#include <string>
#include <vector>
#include "embedder.h"
#include "embedder_engine.h"
......@@ -2889,6 +2890,33 @@ TEST_F(EmbedderTest, CanUpdateLocales) {
check_latch.Wait();
}
TEST_F(EmbedderTest, LocalizationCallbacksCalled) {
auto& context = GetEmbedderContext();
fml::AutoResetWaitableEvent latch;
context.AddIsolateCreateCallback([&latch]() { latch.Signal(); });
EmbedderConfigBuilder builder(context);
builder.SetSoftwareRendererConfig();
auto engine = builder.LaunchEngine();
ASSERT_TRUE(engine.is_valid());
// Wait for the root isolate to launch.
latch.Wait();
flutter::Shell& shell = ToEmbedderEngine(engine.get())->GetShell();
std::vector<std::string> supported_locales;
supported_locales.push_back("es");
supported_locales.push_back("MX");
supported_locales.push_back("");
auto result = shell.GetPlatformView()->ComputePlatformResolvedLocales(
supported_locales);
ASSERT_EQ((*result).size(), supported_locales.size()); // 3
ASSERT_EQ((*result)[0], supported_locales[0]);
ASSERT_EQ((*result)[1], supported_locales[1]);
ASSERT_EQ((*result)[2], supported_locales[2]);
engine.reset();
}
TEST_F(EmbedderTest, CanQueryDartAOTMode) {
ASSERT_EQ(FlutterEngineRunsAOTCompiledDartCode(),
flutter::DartVM::IsRunningPrecompiledCode());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册