14#include "gmock/gmock.h"
16#include "rapidjson/document.h"
17#include "rapidjson/stringbuffer.h"
18#include "rapidjson/writer.h"
26class FontManifestAssetResolver :
public AssetResolver {
28 FontManifestAssetResolver() {}
30 bool IsValid()
const override {
return true; }
32 bool IsValidAfterAssetManagerChange()
const override {
return true; }
39 std::unique_ptr<fml::Mapping> GetAsMapping(
40 const std::string& asset_name)
const override {
42 if (asset_name ==
"FontManifest.json") {
43 return std::make_unique<fml::DataMapping>(
"[{},{},{}]");
48 std::vector<std::unique_ptr<fml::Mapping>> GetAsMappings(
49 const std::string& asset_pattern,
50 const std::optional<std::string>& subdir)
const override {
54 bool operator==(
const AssetResolver& other)
const override {
55 auto mapping = GetAsMapping(
"FontManifest.json");
56 return memcmp(other.GetAsMapping(
"FontManifest.json")->GetMapping(),
57 mapping->GetMapping(), mapping->GetSize()) == 0;
61class MockDelegate :
public Engine::Delegate {
64 OnEngineUpdateSemantics,
68 OnEngineSetApplicationLocale,
71 MOCK_METHOD(
void, OnEngineSetSemanticsTreeEnabled, (
bool), (
override));
73 OnEngineHandlePlatformMessage,
74 (std::unique_ptr<PlatformMessage>),
76 MOCK_METHOD(
void, OnPreEngineRestart, (), (
override));
77 MOCK_METHOD(
void, OnRootIsolateCreated, (), (
override));
79 UpdateIsolateDescription,
80 (
const std::string, int64_t),
82 MOCK_METHOD(
void, SetNeedsReportTimings, (
bool), (
override));
83 MOCK_METHOD(std::unique_ptr<std::vector<std::string>>,
84 ComputePlatformResolvedLocale,
85 (
const std::vector<std::string>&),
87 MOCK_METHOD(
void, RequestDartDeferredLibrary, (intptr_t), (
override));
89 MOCK_METHOD(
const std::shared_ptr<PlatformMessageHandler>&,
90 GetPlatformMessageHandler,
93 MOCK_METHOD(
void, OnEngineChannelUpdate, (std::string,
bool), (
override));
99 RequestViewFocusChange,
100 (
const ViewFocusChangeRequest&),
106 MOCK_METHOD(
void, Complete, (std::unique_ptr<fml::Mapping>
data), (
override));
107 MOCK_METHOD(
void, CompleteEmpty, (), (
override));
110class MockRuntimeDelegate :
public RuntimeDelegate {
112 MOCK_METHOD(std::string, DefaultRouteName, (), (
override));
114 MOCK_METHOD(
void, OnAllViewsRendered, (), (
override));
117 (int64_t, std::unique_ptr<flutter::LayerTree>,
float),
123 MOCK_METHOD(
void, SetApplicationLocale, (
const std::string), (
override));
124 MOCK_METHOD(
void, SetSemanticsTreeEnabled, (
bool), (
override));
126 HandlePlatformMessage,
127 (std::unique_ptr<PlatformMessage>),
129 MOCK_METHOD(FontCollection&, GetFontCollection, (), (
override));
130 MOCK_METHOD(std::shared_ptr<AssetManager>, GetAssetManager, (), (
override));
131 MOCK_METHOD(
void, OnRootIsolateCreated, (), (
override));
133 UpdateIsolateDescription,
134 (
const std::string, int64_t),
136 MOCK_METHOD(
void, SetNeedsReportTimings, (
bool), (
override));
137 MOCK_METHOD(std::unique_ptr<std::vector<std::string>>,
138 ComputePlatformResolvedLocale,
139 (
const std::vector<std::string>&),
141 MOCK_METHOD(
void, RequestDartDeferredLibrary, (intptr_t), (
override));
142 MOCK_METHOD(std::weak_ptr<PlatformMessageHandler>,
143 GetPlatformMessageHandler,
146 MOCK_METHOD(
void, SendChannelUpdate, (std::string,
bool), (
override));
149 (
double font_size,
int configuration_id),
152 RequestViewFocusChange,
153 (
const ViewFocusChangeRequest&),
157class MockRuntimeController :
public RuntimeController {
159 MockRuntimeController(RuntimeDelegate& client,
160 const TaskRunners& p_task_runners)
161 : RuntimeController(client, p_task_runners) {}
162 MOCK_METHOD(
bool, IsRootIsolateRunning, (), (
override,
const));
165 (std::unique_ptr<PlatformMessage>),
168 LoadDartDeferredLibraryError,
169 (intptr_t,
const std::string,
bool),
171 MOCK_METHOD(DartVM*, GetDartVM, (), (
const,
override));
175class MockFontCollection :
public FontCollection {
179 (
const std::shared_ptr<AssetManager>& asset_manager),
183std::unique_ptr<PlatformMessage> MakePlatformMessage(
185 const std::map<std::string, std::string>& values,
187 rapidjson::Document document;
188 auto& allocator = document.GetAllocator();
189 document.SetObject();
191 for (
const auto& pair : values) {
192 rapidjson::Value
key(pair.first.c_str(), strlen(pair.first.c_str()),
194 rapidjson::Value
value(pair.second.c_str(), strlen(pair.second.c_str()),
196 document.AddMember(
key, value, allocator);
199 rapidjson::StringBuffer
buffer;
200 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
201 document.Accept(writer);
202 const uint8_t*
data =
reinterpret_cast<const uint8_t*
>(
buffer.GetString());
204 std::unique_ptr<PlatformMessage>
message = std::make_unique<PlatformMessage>(
209class EngineTest :
public testing::FixtureTest {
213 ThreadHost::Type::kPlatform | ThreadHost::Type::kIo |
214 ThreadHost::Type::kUi | ThreadHost::Type::
kRaster),
223 void PostUITaskSync(
const std::function<
void()>& function) {
233 void SetUp()
override {
254 PostUITaskSync([
this] {
255 auto engine = std::make_unique<Engine>(
263 std::make_shared<FontCollection>(),
265 std::make_shared<fml::SyncSwitch>());
270TEST_F(EngineTest, DispatchPlatformMessageUnknown) {
271 PostUITaskSync([
this] {
272 MockRuntimeDelegate client;
273 auto mock_runtime_controller =
274 std::make_unique<MockRuntimeController>(client,
task_runners_);
275 EXPECT_CALL(*mock_runtime_controller, IsRootIsolateRunning())
276 .WillRepeatedly(::testing::Return(
false));
277 auto engine = std::make_unique<Engine>(
285 std::make_shared<FontCollection>(),
286 std::move(mock_runtime_controller),
287 std::make_shared<fml::SyncSwitch>());
290 fml::MakeRefCounted<MockResponse>();
291 std::unique_ptr<PlatformMessage>
message =
292 std::make_unique<PlatformMessage>(
"foo", response);
297TEST_F(EngineTest, DispatchPlatformMessageInitialRoute) {
298 PostUITaskSync([
this] {
299 MockRuntimeDelegate client;
300 auto mock_runtime_controller =
301 std::make_unique<MockRuntimeController>(client,
task_runners_);
302 EXPECT_CALL(*mock_runtime_controller, IsRootIsolateRunning())
303 .WillRepeatedly(::testing::Return(
false));
304 auto engine = std::make_unique<Engine>(
312 std::make_shared<FontCollection>(),
313 std::move(mock_runtime_controller),
314 std::make_shared<fml::SyncSwitch>());
317 fml::MakeRefCounted<MockResponse>();
318 std::map<std::string, std::string> values{
319 {
"method",
"setInitialRoute"},
320 {
"args",
"test_initial_route"},
322 std::unique_ptr<PlatformMessage>
message =
323 MakePlatformMessage(
"flutter/navigation", values, response);
325 EXPECT_EQ(
engine->InitialRoute(),
"test_initial_route");
329TEST_F(EngineTest, DispatchPlatformMessageInitialRouteIgnored) {
330 PostUITaskSync([
this] {
331 MockRuntimeDelegate client;
332 auto mock_runtime_controller =
333 std::make_unique<MockRuntimeController>(client,
task_runners_);
334 EXPECT_CALL(*mock_runtime_controller, IsRootIsolateRunning())
335 .WillRepeatedly(::testing::Return(
true));
337 .WillRepeatedly(::testing::Return(
true));
338 auto engine = std::make_unique<Engine>(
346 std::make_shared<FontCollection>(),
347 std::move(mock_runtime_controller),
348 std::make_shared<fml::SyncSwitch>());
351 fml::MakeRefCounted<MockResponse>();
352 std::map<std::string, std::string> values{
353 {
"method",
"setInitialRoute"},
354 {
"args",
"test_initial_route"},
356 std::unique_ptr<PlatformMessage>
message =
357 MakePlatformMessage(
"flutter/navigation", values, response);
359 EXPECT_EQ(
engine->InitialRoute(),
"");
363TEST_F(EngineTest, SpawnSharesFontLibrary) {
364 PostUITaskSync([
this] {
365 MockRuntimeDelegate client;
366 auto mock_runtime_controller =
367 std::make_unique<MockRuntimeController>(client,
task_runners_);
369 EXPECT_CALL(*mock_runtime_controller, GetDartVM())
370 .WillRepeatedly(::testing::Return(vm_ref.get()));
371 auto engine = std::make_unique<Engine>(
379 std::make_shared<FontCollection>(),
380 std::move(mock_runtime_controller),
381 std::make_shared<fml::SyncSwitch>());
386 EXPECT_TRUE(spawn !=
nullptr);
387 EXPECT_EQ(&
engine->GetFontCollection(), &spawn->GetFontCollection());
391TEST_F(EngineTest, SpawnWithCustomInitialRoute) {
392 PostUITaskSync([
this] {
393 MockRuntimeDelegate client;
394 auto mock_runtime_controller =
395 std::make_unique<MockRuntimeController>(client,
task_runners_);
397 EXPECT_CALL(*mock_runtime_controller, GetDartVM())
398 .WillRepeatedly(::testing::Return(vm_ref.get()));
399 auto engine = std::make_unique<Engine>(
407 std::make_shared<FontCollection>(),
408 std::move(mock_runtime_controller),
409 std::make_shared<fml::SyncSwitch>());
414 EXPECT_TRUE(spawn !=
nullptr);
415 ASSERT_EQ(
"/foo", spawn->InitialRoute());
419TEST_F(EngineTest, SpawnWithCustomSettings) {
420 PostUITaskSync([
this] {
421 MockRuntimeDelegate client;
422 auto mock_runtime_controller =
423 std::make_unique<MockRuntimeController>(client,
task_runners_);
425 EXPECT_CALL(*mock_runtime_controller, GetDartVM())
426 .WillRepeatedly(::testing::Return(vm_ref.get()));
427 auto engine = std::make_unique<Engine>(
435 std::make_shared<FontCollection>(),
436 std::move(mock_runtime_controller),
437 std::make_shared<fml::SyncSwitch>());
441 std::make_shared<fml::DataMapping>(
"foo");
445 EXPECT_TRUE(spawn !=
nullptr);
446 auto new_persistent_isolate_data =
448 ->GetPersistentIsolateData();
450 new_persistent_isolate_data->GetMapping());
452 new_persistent_isolate_data->GetSize());
456TEST_F(EngineTest, PassesLoadDartDeferredLibraryErrorToRuntime) {
457 PostUITaskSync([
this] {
458 intptr_t error_id = 123;
459 const std::string error_message =
"error message";
460 MockRuntimeDelegate client;
461 auto mock_runtime_controller =
462 std::make_unique<MockRuntimeController>(client,
task_runners_);
463 EXPECT_CALL(*mock_runtime_controller, IsRootIsolateRunning())
464 .WillRepeatedly(::testing::Return(
true));
465 EXPECT_CALL(*mock_runtime_controller,
466 LoadDartDeferredLibraryError(error_id, error_message,
true))
468 auto engine = std::make_unique<Engine>(
476 std::make_shared<FontCollection>(),
477 std::move(mock_runtime_controller),
478 std::make_shared<fml::SyncSwitch>());
480 engine->LoadDartDeferredLibraryError(error_id, error_message,
true);
484TEST_F(EngineTest, SpawnedEngineInheritsAssetManager) {
485 PostUITaskSync([
this] {
486 MockRuntimeDelegate client;
487 auto mock_runtime_controller =
488 std::make_unique<MockRuntimeController>(client,
task_runners_);
490 EXPECT_CALL(*mock_runtime_controller, GetDartVM())
491 .WillRepeatedly(::testing::Return(vm_ref.get()));
496 auto engine = std::make_unique<Engine>(
504 std::make_shared<FontCollection>(),
505 std::move(mock_runtime_controller),
506 std::make_shared<fml::SyncSwitch>());
508 EXPECT_EQ(
engine->GetAssetManager(),
nullptr);
510 auto asset_manager = std::make_shared<AssetManager>();
511 asset_manager->PushBack(std::make_unique<FontManifestAssetResolver>());
512 engine->UpdateAssetManager(asset_manager);
513 EXPECT_EQ(
engine->GetAssetManager(), asset_manager);
518 EXPECT_TRUE(spawn !=
nullptr);
519 EXPECT_EQ(
engine->GetAssetManager(), spawn->GetAssetManager());
523TEST_F(EngineTest, UpdateAssetManagerWithEqualManagers) {
524 PostUITaskSync([
this] {
525 MockRuntimeDelegate client;
526 auto mock_runtime_controller =
527 std::make_unique<MockRuntimeController>(client,
task_runners_);
529 EXPECT_CALL(*mock_runtime_controller, GetDartVM())
530 .WillRepeatedly(::testing::Return(vm_ref.get()));
532 auto mock_font_collection = std::make_shared<MockFontCollection>();
533 EXPECT_CALL(*mock_font_collection, RegisterFonts(::testing::_))
534 .WillOnce(::testing::Return());
535 auto engine = std::make_unique<Engine>(
543 mock_font_collection,
544 std::move(mock_runtime_controller),
545 std::make_shared<fml::SyncSwitch>());
547 EXPECT_EQ(
engine->GetAssetManager(),
nullptr);
549 auto asset_manager = std::make_shared<AssetManager>();
550 asset_manager->PushBack(std::make_unique<FontManifestAssetResolver>());
552 auto asset_manager_2 = std::make_shared<AssetManager>();
553 asset_manager_2->PushBack(std::make_unique<FontManifestAssetResolver>());
555 EXPECT_NE(asset_manager, asset_manager_2);
556 EXPECT_TRUE(*asset_manager == *asset_manager_2);
558 engine->UpdateAssetManager(asset_manager);
559 EXPECT_EQ(
engine->GetAssetManager(), asset_manager);
561 engine->UpdateAssetManager(asset_manager_2);
563 EXPECT_EQ(
engine->GetAssetManager(), asset_manager);
AssetResolverType
Identifies the type of AssetResolver an instance is.
static DartVMRef Create(const Settings &settings, fml::RefPtr< const DartSnapshot > vm_snapshot=nullptr, fml::RefPtr< const DartSnapshot > isolate_snapshot=nullptr)
static MallocMapping Copy(const T *begin, const T *end)
size_t mapping_call_count
@ kRaster
Suitable for thread which raster data.
std::shared_ptr< fml::ConcurrentTaskRunner > image_decoder_task_runner_
std::unique_ptr< RuntimeController > runtime_controller_
TaskRunners task_runners_
fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate_
std::unique_ptr< Animator > animator_
PointerDataDispatcherMaker dispatcher_maker_
fml::WeakPtr< IOManager > io_manager_
G_BEGIN_DECLS GBytes * message
Dart_NativeFunction function
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
std::unordered_map< int32_t, CustomAccessibilityAction > CustomAccessibilityActionUpdates
std::function< std::unique_ptr< PointerDataDispatcher >(PointerDataDispatcher::Delegate &)> PointerDataDispatcherMaker
Signature for constructing PointerDataDispatcher.
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
static void DispatchPlatformMessage(JNIEnv *env, jobject jcaller, jlong shell_holder, jstring channel, jobject message, jint position, jint responseId)
bool operator==(const ViewportMetrics &a, const ViewportMetrics &b)
static void ScheduleFrame(JNIEnv *env, jobject jcaller, jlong shell_holder)
TEST_F(EngineAnimatorTest, AnimatorAcceptsMultipleRenders)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
std::shared_ptr< const fml::Mapping > persistent_isolate_data