Flutter Engine
The Flutter Engine
external_view_embedder_unittests.cc
Go to the documentation of this file.
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#define FML_USED_ON_EMBEDDER
6
7#include <memory>
8
9#include "flutter/shell/platform/android/external_view_embedder/external_view_embedder.h"
10
11#include "flutter/flow/embedded_views.h"
12#include "flutter/flow/surface.h"
13#include "flutter/fml/raster_thread_merger.h"
14#include "flutter/fml/thread.h"
15#include "flutter/shell/platform/android/jni/jni_mock.h"
16#include "flutter/shell/platform/android/surface/android_surface.h"
17#include "flutter/shell/platform/android/surface/android_surface_mock.h"
18
19#include "gmock/gmock.h"
20#include "gtest/gtest.h"
23
24namespace flutter {
25namespace testing {
26
27using ::testing::ByMove;
28using ::testing::Return;
29
30constexpr int64_t kImplicitViewId = 0;
31
33 public:
35 std::function<std::unique_ptr<AndroidSurface>(void)>;
36 explicit TestAndroidSurfaceFactory(TestSurfaceProducer&& surface_producer) {
37 surface_producer_ = surface_producer;
38 }
39
40 ~TestAndroidSurfaceFactory() override = default;
41
42 std::unique_ptr<AndroidSurface> CreateSurface() override {
43 return surface_producer_();
44 }
45
46 private:
47 TestSurfaceProducer surface_producer_;
48};
49
50class SurfaceMock : public Surface {
51 public:
52 MOCK_METHOD(bool, IsValid, (), (override));
53
54 MOCK_METHOD(std::unique_ptr<SurfaceFrame>,
56 (const SkISize& size),
57 (override));
58
59 MOCK_METHOD(SkMatrix, GetRootTransformation, (), (const, override));
60
62
63 MOCK_METHOD(std::unique_ptr<GLContextResult>,
65 (),
66 (override));
67};
68
70 fml::Thread* rasterizer_thread = nullptr) {
71 // Assume the current thread is the platform thread.
73 auto platform_queue_id = fml::MessageLoop::GetCurrentTaskQueueId();
74
75 if (!rasterizer_thread) {
76 return fml::MakeRefCounted<fml::RasterThreadMerger>(platform_queue_id,
77 platform_queue_id);
78 }
79 auto rasterizer_queue_id =
80 rasterizer_thread->GetTaskRunner()->GetTaskQueueId();
81 return fml::MakeRefCounted<fml::RasterThreadMerger>(platform_queue_id,
82 rasterizer_queue_id);
83}
84
86 fml::Thread* platform_thread) {
87 auto platform_queue_id = platform_thread->GetTaskRunner()->GetTaskQueueId();
88
89 // Assume the current thread is the raster thread.
91 auto rasterizer_queue_id = fml::MessageLoop::GetCurrentTaskQueueId();
92
93 return fml::MakeRefCounted<fml::RasterThreadMerger>(platform_queue_id,
94 rasterizer_queue_id);
95}
96
99 auto& loop = fml::MessageLoop::GetCurrent();
100 return {
101 "test",
102 loop.GetTaskRunner(), // platform
103 loop.GetTaskRunner(), // raster
104 loop.GetTaskRunner(), // ui
105 loop.GetTaskRunner() // io
106 };
107}
108
109TEST(AndroidExternalViewEmbedder, CompositeEmbeddedView) {
110 auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
111 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
112 android_context, nullptr, nullptr, GetTaskRunnersForFixture());
113
114 ASSERT_EQ(nullptr, embedder->CompositeEmbeddedView(0));
115 embedder->PrerollCompositeEmbeddedView(
116 0, std::make_unique<EmbeddedViewParams>());
117 ASSERT_NE(nullptr, embedder->CompositeEmbeddedView(0));
118
119 ASSERT_EQ(nullptr, embedder->CompositeEmbeddedView(1));
120 embedder->PrerollCompositeEmbeddedView(
121 1, std::make_unique<EmbeddedViewParams>());
122 ASSERT_NE(nullptr, embedder->CompositeEmbeddedView(1));
123}
124
126 auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
127 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
128 android_context, nullptr, nullptr, GetTaskRunnersForFixture());
129
130 embedder->PrerollCompositeEmbeddedView(
131 0, std::make_unique<EmbeddedViewParams>());
132 embedder->CancelFrame();
133
134 ASSERT_EQ(embedder->CompositeEmbeddedView(0), nullptr);
135}
136
137TEST(AndroidExternalViewEmbedder, RasterizerRunsOnPlatformThread) {
138 auto jni_mock = std::make_shared<JNIMock>();
139 auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
140 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
141 android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
142
143 fml::Thread rasterizer_thread("rasterizer");
144 auto raster_thread_merger =
145 GetThreadMergerFromPlatformThread(&rasterizer_thread);
146 ASSERT_FALSE(raster_thread_merger->IsMerged());
147
148 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
149 embedder->BeginFrame(nullptr, raster_thread_merger);
150 embedder->PrepareFlutterView(SkISize::Make(10, 20), 1.0);
151
152 // Push a platform view.
153 embedder->PrerollCompositeEmbeddedView(
154 0, std::make_unique<EmbeddedViewParams>());
155
156 auto postpreroll_result = embedder->PostPrerollAction(raster_thread_merger);
157 ASSERT_EQ(PostPrerollResult::kSkipAndRetryFrame, postpreroll_result);
158
159 EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
160 embedder->EndFrame(/*should_resubmit_frame=*/true, raster_thread_merger);
161
162 ASSERT_TRUE(raster_thread_merger->IsMerged());
163
164 int pending_frames = 0;
165 while (raster_thread_merger->IsMerged()) {
166 raster_thread_merger->DecrementLease();
167 pending_frames++;
168 }
169 ASSERT_EQ(10, pending_frames); // kDefaultMergedLeaseDuration
170}
171
172TEST(AndroidExternalViewEmbedder, RasterizerRunsOnRasterizerThread) {
173 auto jni_mock = std::make_shared<JNIMock>();
174 auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
175 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
176 android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
177
178 fml::Thread rasterizer_thread("rasterizer");
179 auto raster_thread_merger =
180 GetThreadMergerFromPlatformThread(&rasterizer_thread);
181 ASSERT_FALSE(raster_thread_merger->IsMerged());
182
183 PostPrerollResult result = embedder->PostPrerollAction(raster_thread_merger);
185
186 EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
187 embedder->EndFrame(/*should_resubmit_frame=*/true, raster_thread_merger);
188
189 ASSERT_FALSE(raster_thread_merger->IsMerged());
190}
191
193 auto jni_mock = std::make_shared<JNIMock>();
194
195 auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
196 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
197 android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
198 fml::Thread rasterizer_thread("rasterizer");
199 auto raster_thread_merger =
200 GetThreadMergerFromPlatformThread(&rasterizer_thread);
201
202 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
203 embedder->BeginFrame(nullptr, raster_thread_merger);
204 embedder->PrepareFlutterView(SkISize::Make(100, 100), 1.5);
205
206 MutatorsStack stack;
208 matrix.setIdentity();
209 // The framework always push a scale matrix based on the screen ratio.
210 matrix.setConcat(matrix, SkMatrix::Scale(1.5, 1.5));
211 matrix.setConcat(matrix, SkMatrix::Translate(10, 20));
212 auto view_params =
213 std::make_unique<EmbeddedViewParams>(matrix, SkSize::Make(30, 40), stack);
214
215 auto view_id = 0;
216 embedder->PrerollCompositeEmbeddedView(view_id, std::move(view_params));
217 ASSERT_EQ(SkRect::MakeXYWH(15, 30, 45, 60), embedder->GetViewRect(view_id));
218}
219
220TEST(AndroidExternalViewEmbedder, PlatformViewRectChangedParams) {
221 auto jni_mock = std::make_shared<JNIMock>();
222
223 auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
224 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
225 android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
226 fml::Thread rasterizer_thread("rasterizer");
227 auto raster_thread_merger =
228 GetThreadMergerFromPlatformThread(&rasterizer_thread);
229
230 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
231 embedder->BeginFrame(nullptr, raster_thread_merger);
232 embedder->PrepareFlutterView(SkISize::Make(100, 100), 1.5);
233
234 auto view_id = 0;
235
236 MutatorsStack stack1;
237 SkMatrix matrix1;
238 matrix1.setIdentity();
239 // The framework always push a scale matrix based on the screen ratio.
240 matrix1.setConcat(SkMatrix::Scale(1.5, 1.5), SkMatrix::Translate(10, 20));
241 auto view_params_1 = std::make_unique<EmbeddedViewParams>(
242 matrix1, SkSize::Make(30, 40), stack1);
243
244 embedder->PrerollCompositeEmbeddedView(view_id, std::move(view_params_1));
245
246 MutatorsStack stack2;
247 SkMatrix matrix2;
248 matrix2.setIdentity();
249 // The framework always push a scale matrix based on the screen ratio.
250 matrix2.setConcat(matrix2, SkMatrix::Scale(1.5, 1.5));
251 matrix2.setConcat(matrix2, SkMatrix::Translate(50, 60));
252 auto view_params_2 = std::make_unique<EmbeddedViewParams>(
253 matrix2, SkSize::Make(70, 80), stack2);
254
255 embedder->PrerollCompositeEmbeddedView(view_id, std::move(view_params_2));
256
257 ASSERT_EQ(SkRect::MakeXYWH(75, 90, 105, 120), embedder->GetViewRect(view_id));
258}
259
261 auto jni_mock = std::make_shared<JNIMock>();
262 auto android_context =
263 std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
264
265 auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
266 auto gr_context = GrDirectContext::MakeMock(nullptr);
267 auto frame_size = SkISize::Make(1000, 1000);
268 SurfaceFrame::FramebufferInfo framebuffer_info;
269 auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
270 [gr_context, window, frame_size, framebuffer_info]() {
271 auto surface_frame_1 = std::make_unique<SurfaceFrame>(
272 SkSurfaces::Null(1000, 1000), framebuffer_info,
273 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
274 return true;
275 },
276 /*frame_size=*/SkISize::Make(800, 600));
277 auto surface_frame_2 = std::make_unique<SurfaceFrame>(
278 SkSurfaces::Null(1000, 1000), framebuffer_info,
279 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
280 return true;
281 },
282 /*frame_size=*/SkISize::Make(800, 600));
283
284 auto surface_mock = std::make_unique<SurfaceMock>();
285 EXPECT_CALL(*surface_mock, AcquireFrame(frame_size))
286 .Times(2 /* frames */)
287 .WillOnce(Return(ByMove(std::move(surface_frame_1))))
288 .WillOnce(Return(ByMove(std::move(surface_frame_2))));
289
290 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
291 EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
292
293 EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
294 .WillOnce(Return(ByMove(std::move(surface_mock))));
295
296 EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
297
298 return android_surface_mock;
299 });
300 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
301 *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
302
303 auto raster_thread_merger = GetThreadMergerFromPlatformThread();
304
305 // ------------------ First frame ------------------ //
306 {
307 auto did_submit_frame = false;
308 auto surface_frame = std::make_unique<SurfaceFrame>(
309 SkSurfaces::Null(1000, 1000), framebuffer_info,
310 [&did_submit_frame](const SurfaceFrame& surface_frame,
311 DlCanvas* canvas) mutable {
312 if (canvas != nullptr) {
313 did_submit_frame = true;
314 }
315 return true;
316 },
317 /*frame_size=*/SkISize::Make(800, 600));
318
319 embedder->SubmitFlutterView(kImplicitViewId, gr_context.get(), nullptr,
320 std::move(surface_frame));
321 // Submits frame if no Android view in the current frame.
322 EXPECT_TRUE(did_submit_frame);
323 // Doesn't resubmit frame.
324 auto postpreroll_result = embedder->PostPrerollAction(raster_thread_merger);
325 ASSERT_EQ(PostPrerollResult::kSuccess, postpreroll_result);
326
327 EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
328 embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
329 }
330
331 // ------------------ Second frame ------------------ //
332 {
333 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
334 embedder->BeginFrame(nullptr, raster_thread_merger);
335 embedder->PrepareFlutterView(frame_size, 1.5);
336
337 // Add an Android view.
338 MutatorsStack stack1;
339 SkMatrix matrix1;
340 matrix1.setIdentity();
341 SkMatrix scale = SkMatrix::Scale(1.5, 1.5);
342 SkMatrix trans = SkMatrix::Translate(100, 100);
343 matrix1.setConcat(scale, trans);
344 stack1.PushTransform(scale);
345 stack1.PushTransform(trans);
346 // TODO(egarciad): Investigate why Flow applies the device pixel ratio to
347 // the offsetPixels, but not the sizePoints.
348 auto view_params_1 = std::make_unique<EmbeddedViewParams>(
349 matrix1, SkSize::Make(200, 200), stack1);
350
351 embedder->PrerollCompositeEmbeddedView(0, std::move(view_params_1));
352 // This is the recording canvas flow writes to.
353 auto canvas_1 = embedder->CompositeEmbeddedView(0);
354
355 auto rect_paint = DlPaint();
356 rect_paint.setColor(DlColor::kCyan());
357 rect_paint.setDrawStyle(DlDrawStyle::kFill);
358
359 // This simulates Flutter UI that doesn't intersect with the Android view.
360 canvas_1->DrawRect(SkRect::MakeXYWH(0, 0, 50, 50), rect_paint);
361 // This simulates Flutter UI that intersects with the Android view.
362 canvas_1->DrawRect(SkRect::MakeXYWH(50, 50, 200, 200), rect_paint);
363 canvas_1->DrawRect(SkRect::MakeXYWH(150, 150, 100, 100), rect_paint);
364
365 // Create a new overlay surface.
366 EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
367 .WillOnce(Return(
368 ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
369 0, window))));
370 // The JNI call to display the Android view.
371 EXPECT_CALL(*jni_mock, FlutterViewOnDisplayPlatformView(
372 0, 150, 150, 300, 300, 300, 300, stack1));
373 // The JNI call to display the overlay surface.
374 EXPECT_CALL(*jni_mock,
375 FlutterViewDisplayOverlaySurface(0, 150, 150, 100, 100));
376
377 auto did_submit_frame = false;
378 auto surface_frame = std::make_unique<SurfaceFrame>(
379 SkSurfaces::Null(1000, 1000), framebuffer_info,
380 [&did_submit_frame](const SurfaceFrame& surface_frame,
381 DlCanvas* canvas) mutable {
382 if (canvas != nullptr) {
383 did_submit_frame = true;
384 }
385 return true;
386 },
387 /*frame_size=*/SkISize::Make(800, 600));
388
389 embedder->SubmitFlutterView(kImplicitViewId, gr_context.get(), nullptr,
390 std::move(surface_frame));
391 // Doesn't submit frame if there aren't Android views in the previous frame.
392 EXPECT_FALSE(did_submit_frame);
393 // Resubmits frame.
394 auto postpreroll_result = embedder->PostPrerollAction(raster_thread_merger);
395 ASSERT_EQ(PostPrerollResult::kResubmitFrame, postpreroll_result);
396
397 EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
398 embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
399 }
400
401 // ------------------ Third frame ------------------ //
402 {
403 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
404 embedder->BeginFrame(nullptr, raster_thread_merger);
405 embedder->PrepareFlutterView(frame_size, 1.5);
406
407 // Add an Android view.
408 MutatorsStack stack1;
409 SkMatrix matrix1;
410 matrix1.setIdentity();
411 SkMatrix scale = SkMatrix::Scale(1.5, 1.5);
412 SkMatrix trans = SkMatrix::Translate(100, 100);
413 matrix1.setConcat(scale, trans);
414 stack1.PushTransform(scale);
415 stack1.PushTransform(trans);
416 // TODO(egarciad): Investigate why Flow applies the device pixel ratio to
417 // the offsetPixels, but not the sizePoints.
418 auto view_params_1 = std::make_unique<EmbeddedViewParams>(
419 matrix1, SkSize::Make(200, 200), stack1);
420
421 embedder->PrerollCompositeEmbeddedView(0, std::move(view_params_1));
422 // This is the recording canvas flow writes to.
423 auto canvas_1 = embedder->CompositeEmbeddedView(0);
424
425 auto rect_paint = DlPaint();
426 rect_paint.setColor(DlColor::kCyan());
427 rect_paint.setDrawStyle(DlDrawStyle::kFill);
428
429 // This simulates Flutter UI that doesn't intersect with the Android view.
430 canvas_1->DrawRect(SkRect::MakeXYWH(0, 0, 50, 50), rect_paint);
431 // This simulates Flutter UI that intersects with the Android view.
432 canvas_1->DrawRect(SkRect::MakeXYWH(50, 50, 200, 200), rect_paint);
433 canvas_1->DrawRect(SkRect::MakeXYWH(150, 150, 100, 100), rect_paint);
434
435 // Don't create a new overlay surface since it's recycled from the first
436 // frame.
437 EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface()).Times(0);
438 // The JNI call to display the Android view.
439 EXPECT_CALL(*jni_mock, FlutterViewOnDisplayPlatformView(
440 0, 150, 150, 300, 300, 300, 300, stack1));
441 // The JNI call to display the overlay surface.
442 EXPECT_CALL(*jni_mock,
443 FlutterViewDisplayOverlaySurface(0, 150, 150, 100, 100));
444
445 auto did_submit_frame = false;
446 auto surface_frame = std::make_unique<SurfaceFrame>(
447 SkSurfaces::Null(1000, 1000), framebuffer_info,
448 [&did_submit_frame](const SurfaceFrame& surface_frame,
449 DlCanvas* canvas) mutable {
450 if (canvas != nullptr) {
451 did_submit_frame = true;
452 }
453 return true;
454 },
455 /*frame_size=*/SkISize::Make(800, 600));
456 embedder->SubmitFlutterView(kImplicitViewId, gr_context.get(), nullptr,
457 std::move(surface_frame));
458 // Submits frame if there are Android views in the previous frame.
459 EXPECT_TRUE(did_submit_frame);
460 // Doesn't resubmit frame.
461 auto postpreroll_result = embedder->PostPrerollAction(raster_thread_merger);
462 ASSERT_EQ(PostPrerollResult::kSuccess, postpreroll_result);
463
464 EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
465 embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
466 }
467}
468
469TEST(AndroidExternalViewEmbedder, OverlayCoverTwoPlatformViews) {
470 // In this test we will simulate two Android views appearing on the screen
471 // with a rect intersecting both of them
472
473 auto jni_mock = std::make_shared<JNIMock>();
474 auto android_context =
475 std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
476
477 auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
478 auto gr_context = GrDirectContext::MakeMock(nullptr);
479 auto frame_size = SkISize::Make(1000, 1000);
480 SurfaceFrame::FramebufferInfo framebuffer_info;
481 auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
482 [gr_context, window, frame_size, framebuffer_info]() {
483 auto surface_frame_1 = std::make_unique<SurfaceFrame>(
484 SkSurfaces::Null(1000, 1000), framebuffer_info,
485 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
486 return true;
487 },
488 /*frame_size=*/SkISize::Make(800, 600));
489
490 auto surface_mock = std::make_unique<SurfaceMock>();
491 EXPECT_CALL(*surface_mock, AcquireFrame(frame_size))
492 .Times(1 /* frames */)
493 .WillOnce(Return(ByMove(std::move(surface_frame_1))));
494
495 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
496 EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
497
498 EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
499 .WillOnce(Return(ByMove(std::move(surface_mock))));
500
501 EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
502 return android_surface_mock;
503 });
504 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
505 *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
506
507 auto raster_thread_merger = GetThreadMergerFromPlatformThread();
508
509 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
510 embedder->BeginFrame(nullptr, raster_thread_merger);
511 embedder->PrepareFlutterView(frame_size, 1.5);
512
513 {
514 // Add first Android view.
516 MutatorsStack stack;
517 embedder->PrerollCompositeEmbeddedView(
518 0, std::make_unique<EmbeddedViewParams>(matrix, SkSize::Make(100, 100),
519 stack));
520 // The JNI call to display the Android view.
521 EXPECT_CALL(*jni_mock, FlutterViewOnDisplayPlatformView(
522 0, 100, 100, 100, 100, 150, 150, stack));
523 }
524
525 {
526 // Add second Android view.
528 MutatorsStack stack;
529 embedder->PrerollCompositeEmbeddedView(
530 1, std::make_unique<EmbeddedViewParams>(matrix, SkSize::Make(100, 100),
531 stack));
532 // The JNI call to display the Android view.
533 EXPECT_CALL(*jni_mock, FlutterViewOnDisplayPlatformView(
534 1, 300, 100, 100, 100, 150, 150, stack));
535 }
536 auto rect_paint = DlPaint();
537 rect_paint.setColor(DlColor::kCyan());
538 rect_paint.setDrawStyle(DlDrawStyle::kFill);
539
540 // This simulates Flutter UI that intersects with the two Android views.
541 // Since we will compute the intersection for each android view in turn, and
542 // finally merge The final size of the overlay will be smaller than the
543 // width and height of the rect.
544 embedder->CompositeEmbeddedView(1)->DrawRect(
545 SkRect::MakeXYWH(150, 50, 200, 200), rect_paint);
546
547 EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
548 .WillRepeatedly([&]() {
549 return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
550 1, window);
551 });
552
553 // The JNI call to display the overlay surface.
554 EXPECT_CALL(*jni_mock,
555 FlutterViewDisplayOverlaySurface(1, 150, 100, 200, 100))
556 .Times(1);
557
558 auto surface_frame = std::make_unique<SurfaceFrame>(
559 SkSurfaces::Null(1000, 1000), framebuffer_info,
560 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) mutable {
561 return true;
562 },
563 /*frame_size=*/SkISize::Make(800, 600));
564
565 embedder->SubmitFlutterView(kImplicitViewId, gr_context.get(), nullptr,
566 std::move(surface_frame));
567
568 EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
569 embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
570}
571
572TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) {
573 auto jni_mock = std::make_shared<JNIMock>();
574 auto android_context =
575 std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
576
577 auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
578 auto gr_context = GrDirectContext::MakeMock(nullptr);
579 auto frame_size = SkISize::Make(1000, 1000);
580 SurfaceFrame::FramebufferInfo framebuffer_info;
581 auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
582 [gr_context, window, frame_size, framebuffer_info]() {
583 auto surface_frame_1 = std::make_unique<SurfaceFrame>(
584 SkSurfaces::Null(1000, 1000), framebuffer_info,
585 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
586 return true;
587 },
588 /*frame_size=*/SkISize::Make(800, 600));
589
590 auto surface_mock = std::make_unique<SurfaceMock>();
591 EXPECT_CALL(*surface_mock, AcquireFrame(frame_size))
592 .Times(1 /* frames */)
593 .WillOnce(Return(ByMove(std::move(surface_frame_1))));
594
595 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
596 EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
597
598 EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
599 .WillOnce(Return(ByMove(std::move(surface_mock))));
600
601 EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
602 return android_surface_mock;
603 });
604 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
605 *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
606
607 auto raster_thread_merger = GetThreadMergerFromPlatformThread();
608
609 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
610 embedder->BeginFrame(nullptr, raster_thread_merger);
611 embedder->PrepareFlutterView(frame_size, 1.5);
612
613 {
614 // Add first Android view.
616 MutatorsStack stack;
618
619 embedder->PrerollCompositeEmbeddedView(
620 0, std::make_unique<EmbeddedViewParams>(matrix, SkSize::Make(200, 200),
621 stack));
622 EXPECT_CALL(*jni_mock, FlutterViewOnDisplayPlatformView(0, 0, 0, 200, 200,
623 300, 300, stack));
624 }
625
626 auto rect_paint = DlPaint();
627 rect_paint.setColor(DlColor::kCyan());
628 rect_paint.setDrawStyle(DlDrawStyle::kFill);
629
630 // This simulates Flutter UI that intersects with the first Android view.
631 embedder->CompositeEmbeddedView(0)->DrawRect(
632 SkRect::MakeXYWH(25, 25, 80, 150), rect_paint);
633
634 {
635 // Add second Android view.
637 MutatorsStack stack;
638 stack.PushTransform(SkMatrix::Translate(0, 100));
639
640 embedder->PrerollCompositeEmbeddedView(
641 1, std::make_unique<EmbeddedViewParams>(matrix, SkSize::Make(100, 100),
642 stack));
643 EXPECT_CALL(*jni_mock, FlutterViewOnDisplayPlatformView(1, 0, 0, 100, 100,
644 150, 150, stack));
645 }
646 // This simulates Flutter UI that intersects with the first and second Android
647 // views.
648 embedder->CompositeEmbeddedView(1)->DrawRect(SkRect::MakeXYWH(25, 25, 80, 50),
649 rect_paint);
650
651 embedder->CompositeEmbeddedView(1)->DrawRect(
652 SkRect::MakeXYWH(75, 75, 30, 100), rect_paint);
653
654 EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
655 .WillRepeatedly([&]() {
656 return std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
657 1, window);
658 });
659
660 EXPECT_CALL(*jni_mock, FlutterViewDisplayOverlaySurface(1, 25, 25, 80, 150))
661 .Times(2);
662
663 auto surface_frame = std::make_unique<SurfaceFrame>(
664 SkSurfaces::Null(1000, 1000), framebuffer_info,
665 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) mutable {
666 return true;
667 },
668 /*frame_size=*/SkISize::Make(800, 600));
669
670 embedder->SubmitFlutterView(kImplicitViewId, gr_context.get(), nullptr,
671 std::move(surface_frame));
672
673 EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
674 embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
675}
676
677TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) {
678 auto jni_mock = std::make_shared<JNIMock>();
679 auto android_context =
680 std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
681
682 auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
683 auto gr_context = GrDirectContext::MakeMock(nullptr);
684 auto frame_size = SkISize::Make(1000, 1000);
685 SurfaceFrame::FramebufferInfo framebuffer_info;
686 auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
687 [gr_context, window, frame_size, framebuffer_info]() {
688 auto surface_frame_1 = std::make_unique<SurfaceFrame>(
689 SkSurfaces::Null(1000, 1000), framebuffer_info,
690 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
691 return true;
692 },
693 /*frame_size=*/SkISize::Make(800, 600));
694
695 auto surface_mock = std::make_unique<SurfaceMock>();
696 EXPECT_CALL(*surface_mock, AcquireFrame(frame_size))
697 .Times(1 /* frames */)
698 .WillOnce(Return(ByMove(std::move(surface_frame_1))));
699
700 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
701 EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
702
703 EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
704 .WillOnce(Return(ByMove(std::move(surface_mock))));
705
706 EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
707 return android_surface_mock;
708 });
709 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
710 *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
711
712 auto raster_thread_merger = GetThreadMergerFromPlatformThread();
713
714 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
715 embedder->BeginFrame(nullptr, raster_thread_merger);
716 embedder->PrepareFlutterView(frame_size, 1.5);
717
718 {
719 // Add Android view.
721 MutatorsStack stack;
723
724 embedder->PrerollCompositeEmbeddedView(
725 0, std::make_unique<EmbeddedViewParams>(matrix, SkSize::Make(200, 200),
726 stack));
727 EXPECT_CALL(*jni_mock, FlutterViewOnDisplayPlatformView(0, 0, 0, 200, 200,
728 300, 300, stack));
729 }
730
731 EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface()).Times(0);
732
733 auto surface_frame = std::make_unique<SurfaceFrame>(
734 SkSurfaces::Null(1000, 1000), framebuffer_info,
735 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) mutable {
736 return true;
737 },
738 /*frame_size=*/SkISize::Make(800, 600));
739
740 embedder->SubmitFlutterView(kImplicitViewId, gr_context.get(), nullptr,
741 std::move(surface_frame));
742
743 EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
744 embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
745}
746
747TEST(AndroidExternalViewEmbedder, DoesNotCallJNIPlatformThreadOnlyMethods) {
748 auto jni_mock = std::make_shared<JNIMock>();
749
750 auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
751 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
752 android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
753
754 // While on the raster thread, don't make JNI calls as these methods can only
755 // run on the platform thread.
756 fml::Thread platform_thread("platform");
757 auto raster_thread_merger = GetThreadMergerFromRasterThread(&platform_thread);
758
759 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()).Times(0);
760 embedder->BeginFrame(nullptr, raster_thread_merger);
761 embedder->PrepareFlutterView(SkISize::Make(10, 20), 1.0);
762
763 EXPECT_CALL(*jni_mock, FlutterViewEndFrame()).Times(0);
764 embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
765}
766
767TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) {
768 auto jni_mock = std::make_shared<JNIMock>();
769
770 auto android_context =
771 std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
772 auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
773 auto gr_context = GrDirectContext::MakeMock(nullptr);
774 auto frame_size = SkISize::Make(1000, 1000);
775 SurfaceFrame::FramebufferInfo framebuffer_info;
776 auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
777 [gr_context, window, frame_size, framebuffer_info]() {
778 auto surface_frame_1 = std::make_unique<SurfaceFrame>(
779 SkSurfaces::Null(1000, 1000), framebuffer_info,
780 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
781 return true;
782 },
783 /*frame_size=*/SkISize::Make(800, 600));
784
785 auto surface_mock = std::make_unique<SurfaceMock>();
786 EXPECT_CALL(*surface_mock, AcquireFrame(frame_size))
787 .WillOnce(Return(ByMove(std::move(surface_frame_1))));
788
789 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
790 EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
791
792 EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
793 .WillOnce(Return(ByMove(std::move(surface_mock))));
794
795 EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
796
797 return android_surface_mock;
798 });
799
800 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
801 *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
802 fml::Thread rasterizer_thread("rasterizer");
803 auto raster_thread_merger =
804 GetThreadMergerFromPlatformThread(&rasterizer_thread);
805
806 // ------------------ First frame ------------------ //
807 {
808 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
809 embedder->BeginFrame(nullptr, raster_thread_merger);
810 embedder->PrepareFlutterView(frame_size, 1.5);
811
812 // Add an Android view.
813 MutatorsStack stack1;
814 // TODO(egarciad): Investigate why Flow applies the device pixel ratio to
815 // the offsetPixels, but not the sizePoints.
816 auto view_params_1 = std::make_unique<EmbeddedViewParams>(
817 SkMatrix(), SkSize::Make(200, 200), stack1);
818
819 embedder->PrerollCompositeEmbeddedView(0, std::move(view_params_1));
820
821 // This simulates Flutter UI that intersects with the Android view.
822 embedder->CompositeEmbeddedView(0)->DrawRect(
823 SkRect::MakeXYWH(50, 50, 200, 200), DlPaint());
824
825 // Create a new overlay surface.
826 EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
827 .WillOnce(Return(
828 ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
829 0, window))));
830 // The JNI call to display the Android view.
831 EXPECT_CALL(*jni_mock, FlutterViewOnDisplayPlatformView(0, 0, 0, 200, 200,
832 300, 300, stack1));
833 EXPECT_CALL(*jni_mock,
834 FlutterViewDisplayOverlaySurface(0, 50, 50, 150, 150));
835
836 SurfaceFrame::FramebufferInfo framebuffer_info;
837 auto surface_frame = std::make_unique<SurfaceFrame>(
838 SkSurfaces::Null(1000, 1000), framebuffer_info,
839 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
840 return true;
841 },
842 /*frame_size=*/SkISize::Make(800, 600));
843 embedder->SubmitFlutterView(kImplicitViewId, gr_context.get(), nullptr,
844 std::move(surface_frame));
845
846 EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
847 embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
848 }
849
850 EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces());
851 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
852 // Change the frame size.
853 embedder->BeginFrame(nullptr, raster_thread_merger);
854 embedder->PrepareFlutterView(SkISize::Make(30, 40), 1.0);
855}
856
857TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) {
858 auto jni_mock = std::make_shared<JNIMock>();
859 auto android_context =
860 std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
861
862 auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
863 auto gr_context = GrDirectContext::MakeMock(nullptr);
864 auto frame_size = SkISize::Make(1000, 1000);
865 SurfaceFrame::FramebufferInfo framebuffer_info;
866 auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
867 [gr_context, window, frame_size, framebuffer_info]() {
868 auto surface_frame_1 = std::make_unique<SurfaceFrame>(
869 SkSurfaces::Null(1000, 1000), framebuffer_info,
870 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
871 return true;
872 },
873 /*frame_size=*/SkISize::Make(800, 600));
874
875 auto surface_mock = std::make_unique<SurfaceMock>();
876 EXPECT_CALL(*surface_mock, AcquireFrame(frame_size))
877 .WillOnce(Return(ByMove(std::move(surface_frame_1))));
878
879 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
880 EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
881
882 EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
883 .WillOnce(Return(ByMove(std::move(surface_mock))));
884
885 EXPECT_CALL(*android_surface_mock, SetNativeWindow(window));
886
887 return android_surface_mock;
888 });
889
890 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
891 *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
892
893 // ------------------ First frame ------------------ //
894 {
895 fml::Thread rasterizer_thread("rasterizer");
896 auto raster_thread_merger =
897 GetThreadMergerFromPlatformThread(&rasterizer_thread);
898 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame());
899 embedder->BeginFrame(nullptr, raster_thread_merger);
900 embedder->PrepareFlutterView(frame_size, 1.5);
901
902 // Add an Android view.
903 MutatorsStack stack1;
904 // TODO(egarciad): Investigate why Flow applies the device pixel ratio to
905 // the offsetPixels, but not the sizePoints.
906 auto view_params_1 = std::make_unique<EmbeddedViewParams>(
907 SkMatrix(), SkSize::Make(200, 200), stack1);
908
909 embedder->PrerollCompositeEmbeddedView(0, std::move(view_params_1));
910
911 // This simulates Flutter UI that intersects with the Android view.
912 embedder->CompositeEmbeddedView(0)->DrawRect(
913 SkRect::MakeXYWH(50, 50, 200, 200), DlPaint());
914
915 // Create a new overlay surface.
916 EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
917 .WillOnce(Return(
918 ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
919 0, window))));
920 // The JNI call to display the Android view.
921 EXPECT_CALL(*jni_mock, FlutterViewOnDisplayPlatformView(0, 0, 0, 200, 200,
922 300, 300, stack1));
923 EXPECT_CALL(*jni_mock,
924 FlutterViewDisplayOverlaySurface(0, 50, 50, 150, 150));
925
926 auto surface_frame = std::make_unique<SurfaceFrame>(
927 SkSurfaces::Null(1000, 1000), framebuffer_info,
928 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
929 return true;
930 },
931 /*frame_size=*/SkISize::Make(800, 600));
932 embedder->SubmitFlutterView(kImplicitViewId, gr_context.get(), nullptr,
933 std::move(surface_frame));
934
935 EXPECT_CALL(*jni_mock, FlutterViewEndFrame());
936 embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
937 }
938
939 EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()).Times(1);
940 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()).Times(0);
941
942 fml::Thread platform_thread("platform");
943 embedder->BeginFrame(nullptr,
944 GetThreadMergerFromRasterThread(&platform_thread));
945 embedder->PrepareFlutterView(SkISize::Make(30, 40), 1.0);
946}
947
948TEST(AndroidExternalViewEmbedder, SupportsDynamicThreadMerging) {
949 auto jni_mock = std::make_shared<JNIMock>();
950 auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
951 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
952 android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
953 ASSERT_TRUE(embedder->SupportsDynamicThreadMerging());
954}
955
956TEST(AndroidExternalViewEmbedder, DisableThreadMerger) {
957 auto jni_mock = std::make_shared<JNIMock>();
958 auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware);
959 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
960 android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
961
962 fml::Thread platform_thread("platform");
963 auto raster_thread_merger = GetThreadMergerFromRasterThread(&platform_thread);
964 ASSERT_FALSE(raster_thread_merger->IsMerged());
965
966 // The shell may disable the thread merger during `OnPlatformViewDestroyed`.
967 raster_thread_merger->Disable();
968
969 EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()).Times(0);
970
971 embedder->BeginFrame(nullptr, raster_thread_merger);
972 embedder->PrepareFlutterView(SkISize::Make(10, 20), 1.0);
973 // Push a platform view.
974 embedder->PrerollCompositeEmbeddedView(
975 0, std::make_unique<EmbeddedViewParams>());
976
977 auto postpreroll_result = embedder->PostPrerollAction(raster_thread_merger);
978 ASSERT_EQ(PostPrerollResult::kSkipAndRetryFrame, postpreroll_result);
979
980 EXPECT_CALL(*jni_mock, FlutterViewEndFrame()).Times(0);
981 embedder->EndFrame(/*should_resubmit_frame=*/true, raster_thread_merger);
982
983 ASSERT_FALSE(raster_thread_merger->IsMerged());
984}
985
987 auto jni_mock = std::make_shared<JNIMock>();
988 auto android_context =
989 std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
990 auto window = fml::MakeRefCounted<AndroidNativeWindow>(nullptr);
991 auto gr_context = GrDirectContext::MakeMock(nullptr);
992 auto frame_size = SkISize::Make(1000, 1000);
993 auto surface_factory = std::make_shared<TestAndroidSurfaceFactory>(
994 [gr_context, window, frame_size]() {
995 SurfaceFrame::FramebufferInfo framebuffer_info;
996 auto surface_frame_1 = std::make_unique<SurfaceFrame>(
997 SkSurfaces::Null(1000, 1000), framebuffer_info,
998 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
999 return true;
1000 },
1001 /*frame_size=*/SkISize::Make(800, 600));
1002
1003 auto surface_mock = std::make_unique<SurfaceMock>();
1004 EXPECT_CALL(*surface_mock, AcquireFrame(frame_size))
1005 .WillOnce(Return(ByMove(std::move(surface_frame_1))));
1006
1007 auto android_surface_mock = std::make_unique<AndroidSurfaceMock>();
1008 EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true));
1009 EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get()))
1010 .WillOnce(Return(ByMove(std::move(surface_mock))));
1011
1012 return android_surface_mock;
1013 });
1014
1015 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
1016 *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture());
1017 fml::Thread rasterizer_thread("rasterizer");
1018 auto raster_thread_merger =
1019 GetThreadMergerFromPlatformThread(&rasterizer_thread);
1020
1021 embedder->BeginFrame(nullptr, raster_thread_merger);
1022 embedder->PrepareFlutterView(frame_size, 1.5);
1023
1024 // Add an Android view.
1025 MutatorsStack stack;
1026 auto view_params = std::make_unique<EmbeddedViewParams>(
1027 SkMatrix(), SkSize::Make(200, 200), stack);
1028
1029 embedder->PrerollCompositeEmbeddedView(0, std::move(view_params));
1030
1031 // This simulates Flutter UI that intersects with the Android view.
1032 embedder->CompositeEmbeddedView(0)->DrawRect(
1033 SkRect::MakeXYWH(50, 50, 200, 200), DlPaint());
1034
1035 // Create a new overlay surface.
1036 EXPECT_CALL(*jni_mock, FlutterViewCreateOverlaySurface())
1037 .WillOnce(Return(
1038 ByMove(std::make_unique<PlatformViewAndroidJNI::OverlayMetadata>(
1039 0, window))));
1040
1041 SurfaceFrame::FramebufferInfo framebuffer_info;
1042 auto surface_frame = std::make_unique<SurfaceFrame>(
1043 SkSurfaces::Null(1000, 1000), framebuffer_info,
1044 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { return true; },
1045 /*frame_size=*/SkISize::Make(800, 600));
1046 embedder->SubmitFlutterView(kImplicitViewId, gr_context.get(), nullptr,
1047 std::move(surface_frame));
1048
1049 embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger);
1050
1051 EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces());
1052 // Teardown.
1053 embedder->Teardown();
1054}
1055
1056TEST(AndroidExternalViewEmbedder, TeardownDoesNotCallJNIMethod) {
1057 auto jni_mock = std::make_shared<JNIMock>();
1058 auto android_context =
1059 std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
1060 auto embedder = std::make_unique<AndroidExternalViewEmbedder>(
1061 *android_context, jni_mock, nullptr, GetTaskRunnersForFixture());
1062
1063 EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()).Times(0);
1064 embedder->Teardown();
1065}
1066
1067} // namespace testing
1068} // namespace flutter
static sk_sp< GrDirectContext > MakeMock(const GrMockOptions *, const GrContextOptions &)
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition: SkMatrix.h:75
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.h:91
SkMatrix & setIdentity()
Definition: SkMatrix.h:626
SkMatrix & setConcat(const SkMatrix &a, const SkMatrix &b)
Definition: SkMatrix.cpp:603
Holds state that is shared across Android surfaces.
Developer-facing API for rendering anything within the engine.
Definition: dl_canvas.h:38
void PushTransform(const SkMatrix &matrix)
Abstract Base Class that represents where we will be rendering content.
Definition: surface.h:24
virtual SkMatrix GetRootTransformation() const =0
virtual std::unique_ptr< SurfaceFrame > AcquireFrame(const SkISize &size)=0
virtual bool IsValid()=0
virtual GrDirectContext * GetContext()=0
virtual std::unique_ptr< GLContextResult > MakeRenderContextCurrent()
Definition: surface.cc:13
MOCK_METHOD(GrDirectContext *, GetContext,(),(override))
MOCK_METHOD(bool, IsValid,(),(override))
MOCK_METHOD(std::unique_ptr< SurfaceFrame >, AcquireFrame,(const SkISize &size),(override))
MOCK_METHOD(SkMatrix, GetRootTransformation,(),(const, override))
MOCK_METHOD(std::unique_ptr< GLContextResult >, MakeRenderContextCurrent,(),(override))
TestAndroidSurfaceFactory(TestSurfaceProducer &&surface_producer)
std::unique_ptr< AndroidSurface > CreateSurface() override
std::function< std::unique_ptr< AndroidSurface >(void)> TestSurfaceProducer
static void EnsureInitializedForCurrentThread()
Definition: message_loop.cc:27
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
Definition: message_loop.cc:19
static TaskQueueId GetCurrentTaskQueueId()
Definition: message_loop.cc:76
virtual TaskQueueId GetTaskQueueId()
Definition: task_runner.cc:38
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
Definition: thread.cc:164
GLFWwindow * window
Definition: main.cc:45
GAsyncResult * result
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
SK_API sk_sp< SkSurface > Null(int width, int height)
fml::RefPtr< fml::RasterThreadMerger > GetThreadMergerFromPlatformThread(fml::Thread *rasterizer_thread=nullptr)
TEST(DisplayListComplexity, EmptyDisplayList)
fml::RefPtr< fml::RasterThreadMerger > GetThreadMergerFromRasterThread(fml::Thread *platform_thread)
constexpr int64_t kImplicitViewId
@ kFill
fills interior of shapes
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
flutter::DlPaint DlPaint
const Scalar scale
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
static constexpr SkSize Make(SkScalar w, SkScalar h)
Definition: SkSize.h:56
static constexpr DlColor kCyan()
Definition: dl_color.h:27
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678