1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "flutter/shell/platform/embedder/tests/embedder_test_context.h"
6
7 #include "flutter/runtime/dart_vm.h"
8 #include "third_party/skia/include/core/SkSurface.h"
9
10 namespace flutter {
11 namespace testing {
12
EmbedderTestContext(std::string assets_path)13 EmbedderTestContext::EmbedderTestContext(std::string assets_path)
14 : assets_path_(std::move(assets_path)),
15 native_resolver_(std::make_shared<TestDartNativeResolver>()) {
16 auto assets_dir = fml::OpenDirectory(assets_path_.c_str(), false,
17 fml::FilePermission::kRead);
18 vm_snapshot_data_ =
19 fml::FileMapping::CreateReadOnly(assets_dir, "vm_snapshot_data");
20 isolate_snapshot_data_ =
21 fml::FileMapping::CreateReadOnly(assets_dir, "isolate_snapshot_data");
22
23 if (flutter::DartVM::IsRunningPrecompiledCode()) {
24 vm_snapshot_instructions_ =
25 fml::FileMapping::CreateReadExecute(assets_dir, "vm_snapshot_instr");
26 isolate_snapshot_instructions_ = fml::FileMapping::CreateReadExecute(
27 assets_dir, "isolate_snapshot_instr");
28 }
29
30 isolate_create_callbacks_.push_back(
31 [weak_resolver =
32 std::weak_ptr<TestDartNativeResolver>{native_resolver_}]() {
33 if (auto resolver = weak_resolver.lock()) {
34 resolver->SetNativeResolverForIsolate();
35 }
36 });
37 }
38
39 EmbedderTestContext::~EmbedderTestContext() = default;
40
GetAssetsPath() const41 const std::string& EmbedderTestContext::GetAssetsPath() const {
42 return assets_path_;
43 }
44
GetVMSnapshotData() const45 const fml::Mapping* EmbedderTestContext::GetVMSnapshotData() const {
46 return vm_snapshot_data_.get();
47 }
48
GetVMSnapshotInstructions() const49 const fml::Mapping* EmbedderTestContext::GetVMSnapshotInstructions() const {
50 return vm_snapshot_instructions_.get();
51 }
52
GetIsolateSnapshotData() const53 const fml::Mapping* EmbedderTestContext::GetIsolateSnapshotData() const {
54 return isolate_snapshot_data_.get();
55 }
56
GetIsolateSnapshotInstructions() const57 const fml::Mapping* EmbedderTestContext::GetIsolateSnapshotInstructions()
58 const {
59 return isolate_snapshot_instructions_.get();
60 }
61
AddIsolateCreateCallback(fml::closure closure)62 void EmbedderTestContext::AddIsolateCreateCallback(fml::closure closure) {
63 if (closure) {
64 isolate_create_callbacks_.push_back(closure);
65 }
66 }
67
GetIsolateCreateCallbackHook()68 VoidCallback EmbedderTestContext::GetIsolateCreateCallbackHook() {
69 return [](void* user_data) {
70 reinterpret_cast<EmbedderTestContext*>(user_data)
71 ->FireIsolateCreateCallbacks();
72 };
73 }
74
FireIsolateCreateCallbacks()75 void EmbedderTestContext::FireIsolateCreateCallbacks() {
76 for (auto closure : isolate_create_callbacks_) {
77 closure();
78 }
79 }
80
AddNativeCallback(const char * name,Dart_NativeFunction function)81 void EmbedderTestContext::AddNativeCallback(const char* name,
82 Dart_NativeFunction function) {
83 native_resolver_->AddNativeCallback({name}, function);
84 }
85
SetSemanticsNodeCallback(SemanticsNodeCallback update_semantics_node_callback)86 void EmbedderTestContext::SetSemanticsNodeCallback(
87 SemanticsNodeCallback update_semantics_node_callback) {
88 update_semantics_node_callback_ = update_semantics_node_callback;
89 }
90
SetSemanticsCustomActionCallback(SemanticsActionCallback update_semantics_custom_action_callback)91 void EmbedderTestContext::SetSemanticsCustomActionCallback(
92 SemanticsActionCallback update_semantics_custom_action_callback) {
93 update_semantics_custom_action_callback_ =
94 update_semantics_custom_action_callback;
95 }
96
SetPlatformMessageCallback(std::function<void (const FlutterPlatformMessage *)> callback)97 void EmbedderTestContext::SetPlatformMessageCallback(
98 std::function<void(const FlutterPlatformMessage*)> callback) {
99 platform_message_callback_ = callback;
100 }
101
PlatformMessageCallback(const FlutterPlatformMessage * message)102 void EmbedderTestContext::PlatformMessageCallback(
103 const FlutterPlatformMessage* message) {
104 if (platform_message_callback_) {
105 platform_message_callback_(message);
106 }
107 }
108
109 FlutterUpdateSemanticsNodeCallback
GetUpdateSemanticsNodeCallbackHook()110 EmbedderTestContext::GetUpdateSemanticsNodeCallbackHook() {
111 return [](const FlutterSemanticsNode* semantics_node, void* user_data) {
112 auto context = reinterpret_cast<EmbedderTestContext*>(user_data);
113 if (auto callback = context->update_semantics_node_callback_) {
114 callback(semantics_node);
115 }
116 };
117 }
118
119 FlutterUpdateSemanticsCustomActionCallback
GetUpdateSemanticsCustomActionCallbackHook()120 EmbedderTestContext::GetUpdateSemanticsCustomActionCallbackHook() {
121 return [](const FlutterSemanticsCustomAction* action, void* user_data) {
122 auto context = reinterpret_cast<EmbedderTestContext*>(user_data);
123 if (auto callback = context->update_semantics_custom_action_callback_) {
124 callback(action);
125 }
126 };
127 }
128
SetupOpenGLSurface()129 void EmbedderTestContext::SetupOpenGLSurface() {
130 if (!gl_surface_) {
131 gl_surface_ = std::make_unique<TestGLSurface>();
132 }
133 }
134
GLMakeCurrent()135 bool EmbedderTestContext::GLMakeCurrent() {
136 FML_CHECK(gl_surface_) << "GL surface must be initialized.";
137 return gl_surface_->MakeCurrent();
138 }
139
GLClearCurrent()140 bool EmbedderTestContext::GLClearCurrent() {
141 FML_CHECK(gl_surface_) << "GL surface must be initialized.";
142 return gl_surface_->ClearCurrent();
143 }
144
GLPresent()145 bool EmbedderTestContext::GLPresent() {
146 FML_CHECK(gl_surface_) << "GL surface must be initialized.";
147
148 if (next_scene_callback_) {
149 auto raster_snapshot = gl_surface_->GetRasterSurfaceSnapshot();
150 FML_CHECK(raster_snapshot);
151 auto callback = next_scene_callback_;
152 next_scene_callback_ = nullptr;
153 callback(std::move(raster_snapshot));
154 }
155
156 if (!gl_surface_->Present()) {
157 return false;
158 }
159
160 return true;
161 }
162
GLGetFramebuffer()163 uint32_t EmbedderTestContext::GLGetFramebuffer() {
164 FML_CHECK(gl_surface_) << "GL surface must be initialized.";
165 return gl_surface_->GetFramebuffer();
166 }
167
GLMakeResourceCurrent()168 bool EmbedderTestContext::GLMakeResourceCurrent() {
169 FML_CHECK(gl_surface_) << "GL surface must be initialized.";
170 return gl_surface_->MakeResourceCurrent();
171 }
172
GLGetProcAddress(const char * name)173 void* EmbedderTestContext::GLGetProcAddress(const char* name) {
174 FML_CHECK(gl_surface_) << "GL surface must be initialized.";
175 return gl_surface_->GetProcAddress(name);
176 }
177
SetupCompositor()178 void EmbedderTestContext::SetupCompositor() {
179 if (compositor_) {
180 return;
181 }
182 SetupOpenGLSurface();
183 compositor_ =
184 std::make_unique<EmbedderTestCompositor>(gl_surface_->GetGrContext());
185 }
186
GetCompositor()187 EmbedderTestCompositor& EmbedderTestContext::GetCompositor() {
188 FML_CHECK(compositor_)
189 << "Accessed the compositor on a context where one was not setup. Used "
190 "the config builder to setup a context with a custom compositor.";
191 return *compositor_;
192 }
193
SetNextSceneCallback(NextSceneCallback next_scene_callback)194 void EmbedderTestContext::SetNextSceneCallback(
195 NextSceneCallback next_scene_callback) {
196 if (compositor_) {
197 compositor_->SetNextSceneCallback(next_scene_callback);
198 return;
199 }
200 next_scene_callback_ = next_scene_callback;
201 }
202
203 } // namespace testing
204 } // namespace flutter
205