Flutter Engine
 
Loading...
Searching...
No Matches
flutter_runner::testing Namespace Reference

Classes

struct  BufferCollectionTokenPair
 
class  ExternalViewEmbedderTest
 
class  FakeFlatland
 
class  FakeFlatlandTest
 
class  FakeFocuser
 
struct  FakeGraph
 
struct  FakeImage
 
class  FakeImeService
 
class  FakeKeyboardService
 
class  FakeMouseSource
 
class  FakePlatformMessageResponse
 
class  FakeTouchSource
 
struct  FakeTransform
 
struct  FakeView
 
struct  FakeViewport
 
class  FakeViewRefFocused
 
struct  FencesPair
 
class  FlatlandConnectionTest
 
class  FocusDelegateTest
 
class  MockInjectorRegistry
 
class  MouseEventBuilder
 
class  PlatformViewTests
 
class  PointerDelegateTest
 
class  PointerInjectorDelegateTest
 
class  TextDelegateTest
 
class  TouchEventBuilder
 
struct  ViewTokenPair
 

Typedefs

using fup_EventPhase = fuchsia::ui::pointer::EventPhase
 
using fup_TouchEvent = fuchsia::ui::pointer::TouchEvent
 
using fup_TouchIxnId = fuchsia::ui::pointer::TouchInteractionId
 
using fup_TouchIxnResult = fuchsia::ui::pointer::TouchInteractionResult
 
using fup_TouchIxnStatus = fuchsia::ui::pointer::TouchInteractionStatus
 
using fup_TouchPointerSample = fuchsia::ui::pointer::TouchPointerSample
 
using fup_TouchResponse = fuchsia::ui::pointer::TouchResponse
 
using fup_TouchResponseType = fuchsia::ui::pointer::TouchResponseType
 
using fup_ViewParameters = fuchsia::ui::pointer::ViewParameters
 
using fup_MouseEvent = fuchsia::ui::pointer::MouseEvent
 
using fup_DeviceType = fuchsia::ui::pointerinjector::DeviceType
 
using fup_DispatchPolicy = fuchsia::ui::pointerinjector::DispatchPolicy
 
using fup_RegistryHandle = fuchsia::ui::pointerinjector::RegistryHandle
 
using fuv_ViewRef = fuchsia::ui::views::ViewRef
 
using FakeContent = std::variant< FakeViewport, FakeImage >
 
using fup_MousePointerSample = fuchsia::ui::pointer::MousePointerSample
 
using fup_MouseDeviceInfo = fuchsia::ui::pointer::MouseDeviceInfo
 

Functions

 TEST_F (FocusDelegateTest, WatchCallbackSeries)
 
 TEST_F (FocusDelegateTest, RequestFocusTest)
 
 TEST_F (FocusDelegateTest, RequestFocusFailTest)
 
 TEST_F (PointerDelegateTest, Data_FuchsiaTimeVersusFlutterTime)
 
 TEST_F (PointerDelegateTest, Phase_FlutterPhasesAreSynthesized)
 
 TEST_F (PointerDelegateTest, Phase_FuchsiaCancelBecomesFlutterCancel)
 
 TEST_F (PointerDelegateTest, Coordinates_CorrectMapping)
 
 TEST_F (PointerDelegateTest, Coordinates_DownEventClampedToView)
 
 TEST_F (PointerDelegateTest, Protocol_FirstResponseIsEmpty)
 
 TEST_F (PointerDelegateTest, Protocol_ResponseMatchesEarlierEvents)
 
 TEST_F (PointerDelegateTest, Protocol_LateGrant)
 
 TEST_F (PointerDelegateTest, Protocol_LateGrantCombo)
 
 TEST_F (PointerDelegateTest, Protocol_EarlyGrant)
 
 TEST_F (PointerDelegateTest, Protocol_LateDeny)
 
 TEST_F (PointerDelegateTest, Protocol_LateDenyCombo)
 
 TEST_F (PointerDelegateTest, Protocol_PointersAreIndependent)
 
 TEST_F (PointerDelegateTest, MouseWheel_TickBased)
 
 TEST_F (PointerDelegateTest, MouseWheel_PixelBased)
 
 TEST_F (PointerDelegateTest, MouseWheel_TouchpadPixelBased)
 
 TEST_P (PointerInjectorDelegateTest, IncorrectPlatformMessage_ShouldFail)
 
 TEST_P (PointerInjectorDelegateTest, ViewsReceiveInjectedEvents)
 
 TEST_P (PointerInjectorDelegateTest, ViewsDontReceivePointerEventsBeforeCreation)
 
 TEST_P (PointerInjectorDelegateTest, ValidRegistrationConfigTest)
 
 TEST_P (PointerInjectorDelegateTest, ValidPointerEventTest)
 
 TEST_P (PointerInjectorDelegateTest, DestroyedViewsDontGetPointerEvents)
 
 TEST_P (PointerInjectorDelegateTest, ViewsGetPointerEventsInFIFO)
 
 TEST_P (PointerInjectorDelegateTest, DeviceRetriesRegisterWhenClosed)
 
 INSTANTIATE_TEST_SUITE_P (PointerInjectorDelegateParameterizedTest, PointerInjectorDelegateTest, ::testing::Bool())
 
 TEST (EngineTest, ThreadNames)
 
 TEST_F (ExternalViewEmbedderTest, RootScene)
 
 TEST_F (ExternalViewEmbedderTest, SimpleScene)
 
 TEST_F (ExternalViewEmbedderTest, SceneWithOneView)
 
 TEST_F (ExternalViewEmbedderTest, SceneWithOneClippedView)
 
 TEST_F (ExternalViewEmbedderTest, SceneWithOneView_NoOverlay)
 
 TEST_F (ExternalViewEmbedderTest, SceneWithOneView_DestroyBeforeDrawing)
 
 TEST_F (ExternalViewEmbedderTest, SimpleScene_DisjointHitRegions)
 
 TEST_F (ExternalViewEmbedderTest, SimpleScene_OverlappingHitRegions)
 
 TEST_F (ExternalViewEmbedderTest, ViewportCoveredWithInputInterceptor)
 
 TEST_F (FakeFlatlandTest, Initialization)
 
 TEST_F (FakeFlatlandTest, DebugLabel)
 
 TEST_F (FakeFlatlandTest, Present)
 
template<typename ZX >
std::pair< zx_koid_t, zx_koid_t > GetKoids (const ZX &kobj)
 
template<typename F >
std::pair< zx_koid_t, zx_koid_t > GetKoids (const fidl::InterfaceHandle< F > &interface_handle)
 
template<typename F >
std::pair< zx_koid_t, zx_koid_t > GetKoids (const fidl::InterfaceRequest< F > &interface_request)
 
template<typename F >
std::pair< zx_koid_t, zx_koid_t > GetKoids (const fidl::InterfacePtr< F > &interface_ptr)
 
template<typename F >
std::pair< zx_koid_t, zx_koid_t > GetKoids (const fidl::Binding< F > &interface_binding)
 
std::pair< zx_koid_t, zx_koid_t > GetKoids (const fuchsia::ui::views::ViewCreationToken &view_token)
 
std::pair< zx_koid_t, zx_koid_t > GetKoids (const fuchsia::ui::views::ViewportCreationToken &viewport_token)
 
std::pair< zx_koid_t, zx_koid_t > GetKoids (const fuchsia::ui::views::ViewRef &view_ref)
 
std::pair< zx_koid_t, zx_koid_t > GetKoids (const fuchsia::ui::views::ViewRefControl &view_ref_control)
 
std::pair< zx_koid_t, zx_koid_t > GetKoids (const fuchsia::ui::composition::BufferCollectionExportToken &buffer_collection_token)
 
std::pair< zx_koid_t, zx_koid_t > GetKoids (const fuchsia::ui::composition::BufferCollectionImportToken &buffer_collection_token)
 
 TEST_F (FlatlandConnectionTest, Initialization)
 
 TEST_F (FlatlandConnectionTest, FlatlandDisconnect)
 
 TEST_F (FlatlandConnectionTest, BasicPresent)
 
 TEST_F (FlatlandConnectionTest, AwaitVsyncsBeforeOnNextFrameBegin)
 
 TEST_F (FlatlandConnectionTest, RunsOutOfFuturePresentationInfos)
 
 TEST_F (FlatlandConnectionTest, PresentCreditExhaustion)
 
FencesPair GetFencesPair (size_t num_fences)
 
void SignalAll (std::vector< zx::event > *fences)
 
void WaitAll (std::vector< zx::event > *fences)
 
 TEST_F (FlatlandConnectionTest, FenceStuffing)
 
 TEST_F (PlatformViewTests, InvalidPlatformMessageRequest)
 
 TEST_F (PlatformViewTests, CreateSurfaceTest)
 
 TEST_F (PlatformViewTests, SetViewportMetrics)
 
 TEST_F (PlatformViewTests, ChangesAccessibilitySettings)
 
 TEST_F (PlatformViewTests, EnableWireframeTest)
 
 TEST_F (PlatformViewTests, CreateViewTest)
 
 TEST_F (PlatformViewTests, UpdateViewTest)
 
 TEST_F (PlatformViewTests, DestroyViewTest)
 
 TEST_F (PlatformViewTests, GetFocusStatesTest)
 
 TEST_F (PlatformViewTests, RequestFocusTest)
 
 TEST_F (PlatformViewTests, RequestFocusNeverCreatedTest)
 
 TEST_F (PlatformViewTests, RequestFocusDisposedTest)
 
 TEST_F (PlatformViewTests, OnKeyEvent)
 
 TEST_F (PlatformViewTests, OnShaderWarmup)
 
 TEST_F (PlatformViewTests, TouchSourceLogicalToPhysicalConversion)
 
static std::string MessageToString (PlatformMessage &message)
 
 TEST_F (TextDelegateTest, ActivateIme)
 
 TEST_F (TextDelegateTest, OnAction)
 

Variables

constexpr std::array< std::array< float, 2 >, 2 > kRect = {{{0, 0}, {20, 20}}}
 
constexpr std::array< float, 9 > kIdentity = {1, 0, 0, 0, 1, 0, 0, 0, 1}
 
constexpr fup_TouchIxnId kIxnOne
 
constexpr uint32_t kMouseDeviceId = 123
 
constexpr std::array< int64_t, 2 > kNoScrollInPhysicalPixelDelta = {0, 0}
 
const bool kNotPrecisionScroll = false
 
const bool kPrecisionScroll = true
 
static constexpr fuchsia::ui::composition::TransformId kInvalidTransformId {0}
 
static constexpr fuchsia::ui::composition::ContentId kInvalidContentId {0}
 
static constexpr fuchsia::ui::composition::HitRegion kInfiniteHitRegion
 

Typedef Documentation

◆ FakeContent

Definition at line 223 of file fake_flatland_types.h.

◆ fup_DeviceType

using flutter_runner::testing::fup_DeviceType = typedef fuchsia::ui::pointerinjector::DeviceType

Definition at line 22 of file pointer_injector_delegate_unittest.cc.

◆ fup_DispatchPolicy

using flutter_runner::testing::fup_DispatchPolicy = typedef fuchsia::ui::pointerinjector::DispatchPolicy

Definition at line 23 of file pointer_injector_delegate_unittest.cc.

◆ fup_EventPhase

typedef fuchsia::ui::pointer::EventPhase flutter_runner::testing::fup_EventPhase

Definition at line 24 of file pointer_delegate_unittests.cc.

◆ fup_MouseDeviceInfo

using flutter_runner::testing::fup_MouseDeviceInfo = typedef fuchsia::ui::pointer::MouseDeviceInfo

Definition at line 17 of file pointer_event_utility.cc.

◆ fup_MouseEvent

typedef fuchsia::ui::pointer::MouseEvent flutter_runner::testing::fup_MouseEvent

Definition at line 33 of file pointer_delegate_unittests.cc.

◆ fup_MousePointerSample

using flutter_runner::testing::fup_MousePointerSample = typedef fuchsia::ui::pointer::MousePointerSample

Definition at line 16 of file pointer_event_utility.cc.

◆ fup_RegistryHandle

using flutter_runner::testing::fup_RegistryHandle = typedef fuchsia::ui::pointerinjector::RegistryHandle

Definition at line 25 of file pointer_injector_delegate_unittest.cc.

◆ fup_TouchEvent

typedef fuchsia::ui::pointer::TouchEvent flutter_runner::testing::fup_TouchEvent

Definition at line 25 of file pointer_delegate_unittests.cc.

◆ fup_TouchIxnId

typedef fuchsia::ui::pointer::TouchInteractionId flutter_runner::testing::fup_TouchIxnId

Definition at line 26 of file pointer_delegate_unittests.cc.

◆ fup_TouchIxnResult

typedef fuchsia::ui::pointer::TouchInteractionResult flutter_runner::testing::fup_TouchIxnResult

Definition at line 27 of file pointer_delegate_unittests.cc.

◆ fup_TouchIxnStatus

using flutter_runner::testing::fup_TouchIxnStatus = typedef fuchsia::ui::pointer::TouchInteractionStatus

Definition at line 28 of file pointer_delegate_unittests.cc.

◆ fup_TouchPointerSample

typedef fuchsia::ui::pointer::TouchPointerSample flutter_runner::testing::fup_TouchPointerSample

Definition at line 29 of file pointer_delegate_unittests.cc.

◆ fup_TouchResponse

using flutter_runner::testing::fup_TouchResponse = typedef fuchsia::ui::pointer::TouchResponse

Definition at line 30 of file pointer_delegate_unittests.cc.

◆ fup_TouchResponseType

using flutter_runner::testing::fup_TouchResponseType = typedef fuchsia::ui::pointer::TouchResponseType

Definition at line 31 of file pointer_delegate_unittests.cc.

◆ fup_ViewParameters

typedef fuchsia::ui::pointer::ViewParameters flutter_runner::testing::fup_ViewParameters

Definition at line 32 of file pointer_delegate_unittests.cc.

◆ fuv_ViewRef

using flutter_runner::testing::fuv_ViewRef = typedef fuchsia::ui::views::ViewRef

Definition at line 26 of file pointer_injector_delegate_unittest.cc.

Function Documentation

◆ GetFencesPair()

FencesPair flutter_runner::testing::GetFencesPair ( size_t  num_fences)

Definition at line 497 of file flatland_connection_unittests.cc.

497 {
498 auto fences = std::make_shared<std::vector<zx::event>>();
499 auto fences_dup = std::make_shared<std::vector<zx::event>>();
500 for (size_t i = 0; i < num_fences; i++) {
501 zx::event fence;
502 auto status = zx::event::create(0u, &fence);
503 EXPECT_EQ(status, ZX_OK);
504
505 zx::event fence_dup;
506 status = fence.duplicate(ZX_RIGHT_SAME_RIGHTS, &fence_dup);
507 EXPECT_EQ(status, ZX_OK);
508
509 fences->push_back(std::move(fence));
510 fences_dup->push_back(std::move(fence_dup));
511 }
512 return FencesPair{
513 .fences = fences,
514 .fences_dup = fences_dup,
515 };
516}

References flutter_runner::testing::FencesPair::fences, and i.

Referenced by TEST_F().

◆ GetKoids() [1/11]

template<typename F >
std::pair< zx_koid_t, zx_koid_t > flutter_runner::testing::GetKoids ( const fidl::Binding< F > &  interface_binding)

Definition at line 294 of file fake_flatland_types.h.

295 {
296 return GetKoids(interface_binding.channel());
297}
std::pair< zx_koid_t, zx_koid_t > GetKoids(const ZX &kobj)

References GetKoids().

◆ GetKoids() [2/11]

template<typename F >
std::pair< zx_koid_t, zx_koid_t > flutter_runner::testing::GetKoids ( const fidl::InterfaceHandle< F > &  interface_handle)

Definition at line 276 of file fake_flatland_types.h.

277 {
278 return GetKoids(interface_handle.channel());
279}

References GetKoids().

◆ GetKoids() [3/11]

template<typename F >
std::pair< zx_koid_t, zx_koid_t > flutter_runner::testing::GetKoids ( const fidl::InterfacePtr< F > &  interface_ptr)

Definition at line 288 of file fake_flatland_types.h.

289 {
290 return GetKoids(interface_ptr.channel());
291}

References GetKoids().

◆ GetKoids() [4/11]

template<typename F >
std::pair< zx_koid_t, zx_koid_t > flutter_runner::testing::GetKoids ( const fidl::InterfaceRequest< F > &  interface_request)

Definition at line 282 of file fake_flatland_types.h.

283 {
284 return GetKoids(interface_request.channel());
285}

References GetKoids().

◆ GetKoids() [5/11]

std::pair< zx_koid_t, zx_koid_t > flutter_runner::testing::GetKoids ( const fuchsia::ui::composition::BufferCollectionExportToken &  buffer_collection_token)
inline

Definition at line 319 of file fake_flatland_types.h.

321 {
322 return GetKoids(buffer_collection_token.value);
323}

References GetKoids().

◆ GetKoids() [6/11]

std::pair< zx_koid_t, zx_koid_t > flutter_runner::testing::GetKoids ( const fuchsia::ui::composition::BufferCollectionImportToken &  buffer_collection_token)
inline

Definition at line 325 of file fake_flatland_types.h.

327 {
328 return GetKoids(buffer_collection_token.value);
329}

References GetKoids().

◆ GetKoids() [7/11]

std::pair< zx_koid_t, zx_koid_t > flutter_runner::testing::GetKoids ( const fuchsia::ui::views::ViewCreationToken &  view_token)
inline

Definition at line 299 of file fake_flatland_types.h.

300 {
301 return GetKoids(view_token.value);
302}

References GetKoids().

◆ GetKoids() [8/11]

std::pair< zx_koid_t, zx_koid_t > flutter_runner::testing::GetKoids ( const fuchsia::ui::views::ViewportCreationToken &  viewport_token)
inline

Definition at line 304 of file fake_flatland_types.h.

305 {
306 return GetKoids(viewport_token.value);
307}

References GetKoids().

◆ GetKoids() [9/11]

std::pair< zx_koid_t, zx_koid_t > flutter_runner::testing::GetKoids ( const fuchsia::ui::views::ViewRef &  view_ref)
inline

Definition at line 309 of file fake_flatland_types.h.

310 {
311 return GetKoids(view_ref.reference);
312}

References GetKoids().

◆ GetKoids() [10/11]

std::pair< zx_koid_t, zx_koid_t > flutter_runner::testing::GetKoids ( const fuchsia::ui::views::ViewRefControl &  view_ref_control)
inline

Definition at line 314 of file fake_flatland_types.h.

315 {
316 return GetKoids(view_ref_control.reference);
317}

References GetKoids().

◆ GetKoids() [11/11]

template<typename ZX >
std::pair< zx_koid_t, zx_koid_t > flutter_runner::testing::GetKoids ( const ZX &  kobj)

Definition at line 266 of file fake_flatland_types.h.

266 {
267 zx_info_handle_basic_t info;
268 zx_status_t status =
269 kobj.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info),
270 /*actual_records*/ nullptr, /*avail_records*/ nullptr);
271 return status == ZX_OK ? std::make_pair(info.koid, info.related_koid)
272 : std::make_pair(zx_koid_t{}, zx_koid_t{});
273}
Definition ref_ptr.h:261

Referenced by GetKoids(), GetKoids(), GetKoids(), GetKoids(), GetKoids(), GetKoids(), GetKoids(), GetKoids(), GetKoids(), and GetKoids().

◆ INSTANTIATE_TEST_SUITE_P()

flutter_runner::testing::INSTANTIATE_TEST_SUITE_P ( PointerInjectorDelegateParameterizedTest  ,
PointerInjectorDelegateTest  ,
::testing::Bool()   
)

◆ MessageToString()

static std::string flutter_runner::testing::MessageToString ( PlatformMessage message)
static

Definition at line 26 of file text_delegate_unittests.cc.

26 {
27 const char* data = reinterpret_cast<const char*>(message.data().GetMapping());
28 return std::string(data, message.data().GetSize());
29}
G_BEGIN_DECLS GBytes * message
std::shared_ptr< const fml::Mapping > data

References data, and message.

Referenced by TEST_F(), and TEST_F().

◆ SignalAll()

void flutter_runner::testing::SignalAll ( std::vector< zx::event > *  fences)

Definition at line 518 of file flatland_connection_unittests.cc.

518 {
519 for (auto& fence : *fences) {
520 const auto status = fence.signal(0, ZX_EVENT_SIGNALED);
521 ASSERT_EQ(status, ZX_OK);
522 }
523}

Referenced by TEST_F().

◆ TEST()

flutter_runner::testing::TEST ( EngineTest  ,
ThreadNames   
)

Definition at line 23 of file engine_unittests.cc.

23 {
24 std::string prefix = GetCurrentTestName();
25 flutter::ThreadHost engine_thread_host = Engine::CreateThreadHost(prefix);
26
27 char thread_name[ZX_MAX_NAME_LEN];
28 zx::thread::self()->get_property(ZX_PROP_NAME, thread_name,
29 sizeof(thread_name));
30 EXPECT_EQ(std::string(thread_name), prefix + std::string(".platform"));
31 EXPECT_EQ(engine_thread_host.platform_thread, nullptr);
32
33 engine_thread_host.raster_thread->GetTaskRunner()->PostTask([&prefix]() {
34 char thread_name[ZX_MAX_NAME_LEN];
35 zx::thread::self()->get_property(ZX_PROP_NAME, thread_name,
36 sizeof(thread_name));
37 EXPECT_EQ(std::string(thread_name), prefix + std::string(".raster"));
38 });
39 engine_thread_host.raster_thread->Join();
40
41 engine_thread_host.ui_thread->GetTaskRunner()->PostTask([&prefix]() {
42 char thread_name[ZX_MAX_NAME_LEN];
43 zx::thread::self()->get_property(ZX_PROP_NAME, thread_name,
44 sizeof(thread_name));
45 EXPECT_EQ(std::string(thread_name), prefix + std::string(".ui"));
46 });
47 engine_thread_host.ui_thread->Join();
48
49 engine_thread_host.io_thread->GetTaskRunner()->PostTask([&prefix]() {
50 char thread_name[ZX_MAX_NAME_LEN];
51 zx::thread::self()->get_property(ZX_PROP_NAME, thread_name,
52 sizeof(thread_name));
53 EXPECT_EQ(std::string(thread_name), prefix + std::string(".io"));
54 });
55 engine_thread_host.io_thread->Join();
56}
The collection of all the threads used by the engine.
Definition thread_host.h:21
std::unique_ptr< fml::Thread > io_thread
Definition thread_host.h:86
std::unique_ptr< fml::Thread > platform_thread
Definition thread_host.h:83
std::unique_ptr< fml::Thread > raster_thread
Definition thread_host.h:85
std::unique_ptr< fml::Thread > ui_thread
Definition thread_host.h:84

References flutter_runner::Engine::CreateThreadHost(), flutter::ThreadHost::io_thread, flutter::ThreadHost::platform_thread, flutter::ThreadHost::raster_thread, and flutter::ThreadHost::ui_thread.

◆ TEST_F() [1/55]

flutter_runner::testing::TEST_F ( ExternalViewEmbedderTest  ,
RootScene   
)

Definition at line 447 of file external_view_embedder_unittests.cc.

447 {
448 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
449 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
450 fuchsia::ui::views::ViewCreationToken view_creation_token;
451 fuchsia::ui::views::ViewRef view_ref_clone;
452 auto view_creation_token_status = zx::channel::create(
453 0u, &viewport_creation_token.value, &view_creation_token.value);
454 ASSERT_EQ(view_creation_token_status, ZX_OK);
455
456 fuchsia::ui::views::ViewRefControl view_ref_control;
457 fuchsia::ui::views::ViewRef view_ref;
458 auto status = zx::eventpair::create(
459 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
460 ASSERT_EQ(status, ZX_OK);
461 view_ref_control.reference.replace(
462 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
463 &view_ref_control.reference);
464 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
465 view_ref.Clone(&view_ref_clone);
466
467 ExternalViewEmbedder external_view_embedder(
468 std::move(view_creation_token),
469 fuchsia::ui::views::ViewIdentityOnCreation{
470 .view_ref = std::move(view_ref),
471 .view_ref_control = std::move(view_ref_control),
472 },
473 fuchsia::ui::composition::ViewBoundProtocols{},
474 parent_viewport_watcher.NewRequest(), flatland_connection(),
475 fake_surface_producer());
476 EXPECT_THAT(fake_flatland().graph(), IsEmptyGraph());
477
478 // Pump the loop; the graph should still be empty because nothing called
479 // `Present` yet.
480 loop().RunUntilIdle();
481 EXPECT_THAT(fake_flatland().graph(), IsEmptyGraph());
482
483 // Pump the loop; the contents of the initial `Present` should be processed.
484 flatland_connection()->Present();
485 loop().RunUntilIdle();
486 EXPECT_THAT(fake_flatland().graph(),
487 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
488 view_ref_clone));
489}

◆ TEST_F() [2/55]

flutter_runner::testing::TEST_F ( ExternalViewEmbedderTest  ,
SceneWithOneClippedView   
)

Definition at line 788 of file external_view_embedder_unittests.cc.

788 {
789 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
790 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
791 fuchsia::ui::views::ViewCreationToken view_creation_token;
792 fuchsia::ui::views::ViewRef view_ref_clone;
793 auto view_creation_token_status = zx::channel::create(
794 0u, &viewport_creation_token.value, &view_creation_token.value);
795 ASSERT_EQ(view_creation_token_status, ZX_OK);
796
797 fuchsia::ui::views::ViewRefControl view_ref_control;
798 fuchsia::ui::views::ViewRef view_ref;
799 auto status = zx::eventpair::create(
800 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
801 ASSERT_EQ(status, ZX_OK);
802 view_ref_control.reference.replace(
803 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
804 &view_ref_control.reference);
805 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
806 view_ref.Clone(&view_ref_clone);
807
808 // Create the `ExternalViewEmbedder` and pump the message loop until
809 // the initial scene graph is setup.
810 ExternalViewEmbedder external_view_embedder(
811 std::move(view_creation_token),
812 fuchsia::ui::views::ViewIdentityOnCreation{
813 .view_ref = std::move(view_ref),
814 .view_ref_control = std::move(view_ref_control),
815 },
816 fuchsia::ui::composition::ViewBoundProtocols{},
817 parent_viewport_watcher.NewRequest(), flatland_connection(),
818 fake_surface_producer());
819 flatland_connection()->Present();
820 loop().RunUntilIdle();
821 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
822 loop().RunUntilIdle();
823 EXPECT_THAT(fake_flatland().graph(),
824 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
825 view_ref_clone));
826
827 // Create the view before drawing the scene.
828 const DlSize child_view_size_signed = DlSize(256.f, 512.f);
829 const fuchsia::math::SizeU child_view_size{
830 static_cast<uint32_t>(child_view_size_signed.width),
831 static_cast<uint32_t>(child_view_size_signed.height)};
832 auto [child_view_token, child_viewport_token] = ViewTokenPair::New();
833 const uint32_t child_view_id = child_viewport_token.value.get();
834
835 const uint8_t kOpacity = 200u;
836 const float kOpacityFloat = DlColor::toOpacity(kOpacity);
837 const fuchsia::math::VecF kScale{3.0f, 4.0f};
838 const int kTranslateX = 10;
839 const int kTranslateY = 20;
840
841 DlMatrix matrix = DlMatrix::MakeTranslation({kTranslateX, kTranslateY}) *
842 DlMatrix::MakeScale({kScale.x, kScale.y, 1});
843
844 DlRect kClipRect = DlRect::MakeXYWH(30, 40, child_view_size_signed.width - 50,
845 child_view_size_signed.height - 60);
846 fuchsia::math::Rect kClipInMathRect = {
847 static_cast<int32_t>(kClipRect.GetX()),
848 static_cast<int32_t>(kClipRect.GetY()),
849 static_cast<int32_t>(kClipRect.GetWidth()),
850 static_cast<int32_t>(kClipRect.GetHeight())};
851
852 auto mutators_stack = flutter::MutatorsStack();
853 mutators_stack.PushOpacity(kOpacity);
854 mutators_stack.PushTransform(matrix);
855 mutators_stack.PushClipRect(kClipRect);
856
857 flutter::EmbeddedViewParams child_view_params(matrix, child_view_size_signed,
858 mutators_stack);
859 external_view_embedder.CreateView(
860 child_view_id, []() {},
861 [](fuchsia::ui::composition::ContentId,
862 fuchsia::ui::composition::ChildViewWatcherHandle) {});
863 const SkRect child_view_occlusion_hint = SkRect::MakeLTRB(1, 2, 3, 4);
864 const fuchsia::math::Inset child_view_inset{
865 static_cast<int32_t>(child_view_occlusion_hint.top()),
866 static_cast<int32_t>(child_view_occlusion_hint.right()),
867 static_cast<int32_t>(child_view_occlusion_hint.bottom()),
868 static_cast<int32_t>(child_view_occlusion_hint.left())};
869 external_view_embedder.SetViewProperties(
870 child_view_id, child_view_occlusion_hint, /*hit_testable=*/false,
871 /*focusable=*/false);
872
873 // We must take into account the effect of DPR on the view scale.
874 const float kDPR = 2.0f;
875 const float kInvDPR = 1.f / kDPR;
876
877 // Draw the scene. The scene graph shouldn't change yet.
878 const DlISize frame_size_signed = DlISize(512, 512);
879 const fuchsia::math::SizeU frame_size{
880 static_cast<uint32_t>(frame_size_signed.width),
881 static_cast<uint32_t>(frame_size_signed.height)};
882 DrawFrameWithView(
883 external_view_embedder, frame_size_signed, kDPR, child_view_id,
884 child_view_params,
885 [](flutter::DlCanvas* canvas) {
886 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
887 flutter::DlPaint rect_paint;
889 canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
890 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
891 },
892 [](flutter::DlCanvas* canvas) {
893 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
894 flutter::DlPaint rect_paint;
895 rect_paint.setColor(flutter::DlColor::kRed());
896 canvas->Translate(canvas_size.width * 3.f / 4.f,
897 canvas_size.height / 2.f);
898 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
899 });
900 EXPECT_THAT(fake_flatland().graph(),
901 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
902 view_ref_clone));
903
904 // Pump the message loop. The scene updates should propagate to flatland.
905 loop().RunUntilIdle();
906 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
907 loop().RunUntilIdle();
908
909 EXPECT_THAT(
910 fake_flatland().graph(),
911 IsFlutterGraph(
912 parent_viewport_watcher, viewport_creation_token,
913 view_ref_clone, /*layers*/
914 {IsImageLayer(
915 frame_size, kFirstLayerBlendMode,
916 {IsHitRegion(
917 /* x */ 128.f,
918 /* y */ 256.f,
919 /* width */ 16.f,
920 /* height */ 16.f,
921 /* hit_test */
922 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
923 IsClipTransformLayer(
924 {kTranslateX, kTranslateY}, kScale, kClipInMathRect,
925 IsViewportLayer(child_view_token, child_view_size,
926 child_view_inset, {0, 0},
927 FakeTransform::kDefaultScale, kOpacityFloat)),
928 IsImageLayer(
929 frame_size, kUpperLayerBlendMode,
930 {IsHitRegion(
931 /* x */ 384.f,
932 /* y */ 256.f,
933 /* width */ 16.f,
934 /* height */ 16.f,
935 /* hit_test */
936 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})},
937 {kInvDPR, kInvDPR}));
938
939 // Draw another frame with view, but get rid of the clips this time. This
940 // should remove all ClipTransformLayer instances.
941 DlMatrix new_matrix = DlMatrix::MakeScale({kScale.x, kScale.y, 1});
942 auto new_mutators_stack = flutter::MutatorsStack();
943 new_mutators_stack.PushOpacity(kOpacity);
944 new_mutators_stack.PushTransform(new_matrix);
945 flutter::EmbeddedViewParams new_child_view_params(
946 new_matrix, child_view_size_signed, new_mutators_stack);
947 DrawFrameWithView(
948 external_view_embedder, frame_size_signed, kDPR, child_view_id,
949 new_child_view_params,
950 [](flutter::DlCanvas* canvas) {
951 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
952 flutter::DlPaint rect_paint;
954 canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
955 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
956 },
957 [](flutter::DlCanvas* canvas) {
958 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
959 flutter::DlPaint rect_paint;
960 rect_paint.setColor(flutter::DlColor::kRed());
961 canvas->Translate(canvas_size.width * 3.f / 4.f,
962 canvas_size.height / 2.f);
963 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
964 });
965 loop().RunUntilIdle();
966 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
967 loop().RunUntilIdle();
968 EXPECT_THAT(
969 fake_flatland().graph(),
970 IsFlutterGraph(
971 parent_viewport_watcher, viewport_creation_token,
972 view_ref_clone, /*layers*/
973 {IsImageLayer(
974 frame_size, kFirstLayerBlendMode,
975 {IsHitRegion(
976 /* x */ 128.f,
977 /* y */ 256.f,
978 /* width */ 16.f,
979 /* height */ 16.f,
980 /* hit_test */
981 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
982 IsViewportLayer(child_view_token, child_view_size, child_view_inset,
983 {0, 0}, kScale, kOpacityFloat),
984 IsImageLayer(
985 frame_size, kUpperLayerBlendMode,
986 {IsHitRegion(
987 /* x */ 384.f,
988 /* y */ 256.f,
989 /* width */ 16.f,
990 /* height */ 16.f,
991 /* hit_test */
992 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})},
993 {kInvDPR, kInvDPR}));
994
995 // Destroy the view and draw another frame without the view.
996 external_view_embedder.DestroyView(
997 child_view_id, [](fuchsia::ui::composition::ContentId) {});
998 DrawSimpleFrame(
999 external_view_embedder, frame_size_signed, 1.f,
1000 [](flutter::DlCanvas* canvas) {
1001 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
1002 flutter::DlPaint rect_paint;
1003 rect_paint.setColor(flutter::DlColor::kGreen());
1004 canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
1005 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1006 });
1007 loop().RunUntilIdle();
1008 EXPECT_THAT(
1009 fake_flatland().graph(),
1010 IsFlutterGraph(
1011 parent_viewport_watcher, viewport_creation_token,
1012 view_ref_clone, /*layers*/
1013 {IsImageLayer(
1014 frame_size, kFirstLayerBlendMode,
1015 {IsHitRegion(
1016 /* x */ 128.f,
1017 /* y */ 256.f,
1018 /* width */ 16.f,
1019 /* height */ 16.f,
1020 /* hit_test */
1021 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1022}
Developer-facing API for rendering anything within the engine.
Definition dl_canvas.h:32
virtual DlISize GetBaseLayerDimensions() const =0
virtual void DrawRect(const DlRect &rect, const DlPaint &paint)=0
virtual void Translate(DlScalar tx, DlScalar ty)=0
DlPaint & setColor(DlColor color)
Definition dl_paint.h:70
impeller::Matrix DlMatrix
impeller::Rect DlRect
impeller::ISize32 DlISize
impeller::Size DlSize
static constexpr DlScalar toOpacity(uint8_t alpha)
Definition dl_color.h:65
static constexpr DlColor kRed()
Definition dl_color.h:71
static constexpr DlColor kGreen()
Definition dl_color.h:72

References flutter::DlCanvas::DrawRect(), flutter::DlCanvas::GetBaseLayerDimensions(), flutter_runner::testing::FakeTransform::kDefaultScale, flutter::DlColor::kGreen(), flutter::DlColor::kRed(), flutter_runner::testing::ViewTokenPair::New(), flutter::DlPaint::setColor(), and flutter::DlCanvas::Translate().

◆ TEST_F() [3/55]

flutter_runner::testing::TEST_F ( ExternalViewEmbedderTest  ,
SceneWithOneView   
)

Definition at line 567 of file external_view_embedder_unittests.cc.

567 {
568 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
569 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
570 fuchsia::ui::views::ViewCreationToken view_creation_token;
571 fuchsia::ui::views::ViewRef view_ref_clone;
572 auto view_creation_token_status = zx::channel::create(
573 0u, &viewport_creation_token.value, &view_creation_token.value);
574 ASSERT_EQ(view_creation_token_status, ZX_OK);
575
576 fuchsia::ui::views::ViewRefControl view_ref_control;
577 fuchsia::ui::views::ViewRef view_ref;
578 auto status = zx::eventpair::create(
579 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
580 ASSERT_EQ(status, ZX_OK);
581 view_ref_control.reference.replace(
582 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
583 &view_ref_control.reference);
584 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
585 view_ref.Clone(&view_ref_clone);
586
587 // Create the `ExternalViewEmbedder` and pump the message loop until
588 // the initial scene graph is setup.
589 ExternalViewEmbedder external_view_embedder(
590 std::move(view_creation_token),
591 fuchsia::ui::views::ViewIdentityOnCreation{
592 .view_ref = std::move(view_ref),
593 .view_ref_control = std::move(view_ref_control),
594 },
595 fuchsia::ui::composition::ViewBoundProtocols{},
596 parent_viewport_watcher.NewRequest(), flatland_connection(),
597 fake_surface_producer());
598 flatland_connection()->Present();
599 loop().RunUntilIdle();
600 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
601 loop().RunUntilIdle();
602 EXPECT_THAT(fake_flatland().graph(),
603 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
604 view_ref_clone));
605
606 // Create the view before drawing the scene.
607 const DlSize child_view_size_signed = DlSize(256.f, 512.f);
608 const fuchsia::math::SizeU child_view_size{
609 static_cast<uint32_t>(child_view_size_signed.width),
610 static_cast<uint32_t>(child_view_size_signed.height)};
611 auto [child_view_token, child_viewport_token] = ViewTokenPair::New();
612 const uint32_t child_view_id = child_viewport_token.value.get();
613
614 const uint8_t kOpacity = 200u;
615 const float kOpacityFloat = DlColor::toOpacity(kOpacity);
616 const fuchsia::math::VecF kScale{3.0f, 4.0f};
617
618 DlMatrix matrix = DlMatrix::MakeScale({kScale.x, kScale.y, 1});
619
620 auto mutators_stack = flutter::MutatorsStack();
621 mutators_stack.PushOpacity(kOpacity);
622 mutators_stack.PushTransform(matrix);
623
624 flutter::EmbeddedViewParams child_view_params(matrix, child_view_size_signed,
625 mutators_stack);
626 external_view_embedder.CreateView(
627 child_view_id, []() {},
628 [](fuchsia::ui::composition::ContentId,
629 fuchsia::ui::composition::ChildViewWatcherHandle) {});
630 const SkRect child_view_occlusion_hint = SkRect::MakeLTRB(1, 2, 3, 4);
631 const fuchsia::math::Inset child_view_inset{
632 static_cast<int32_t>(child_view_occlusion_hint.top()),
633 static_cast<int32_t>(child_view_occlusion_hint.right()),
634 static_cast<int32_t>(child_view_occlusion_hint.bottom()),
635 static_cast<int32_t>(child_view_occlusion_hint.left())};
636 external_view_embedder.SetViewProperties(
637 child_view_id, child_view_occlusion_hint, /*hit_testable=*/false,
638 /*focusable=*/false);
639
640 // We must take into account the effect of DPR on the view scale.
641 const float kDPR = 2.0f;
642 const float kInvDPR = 1.f / kDPR;
643
644 // Draw the scene. The scene graph shouldn't change yet.
645 const DlISize frame_size_signed = DlISize(512, 512);
646 const fuchsia::math::SizeU frame_size{
647 static_cast<uint32_t>(frame_size_signed.width),
648 static_cast<uint32_t>(frame_size_signed.height)};
649 DrawFrameWithView(
650 external_view_embedder, frame_size_signed, kDPR, child_view_id,
651 child_view_params,
652 [](flutter::DlCanvas* canvas) {
653 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
654 flutter::DlPaint rect_paint;
656 canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
657 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
658 },
659 [](flutter::DlCanvas* canvas) {
660 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
661 flutter::DlPaint rect_paint;
662 rect_paint.setColor(flutter::DlColor::kRed());
663 canvas->Translate(canvas_size.width * 3.f / 4.f,
664 canvas_size.height / 2.f);
665 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
666 });
667 EXPECT_THAT(fake_flatland().graph(),
668 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
669 view_ref_clone));
670
671 // Pump the message loop. The scene updates should propagate to flatland.
672 loop().RunUntilIdle();
673 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
674 loop().RunUntilIdle();
675
676 EXPECT_THAT(
677 fake_flatland().graph(),
678 IsFlutterGraph(
679 parent_viewport_watcher, viewport_creation_token,
680 view_ref_clone, /*layers*/
681 {IsImageLayer(
682 frame_size, kFirstLayerBlendMode,
683 {IsHitRegion(
684 /* x */ 128.f,
685 /* y */ 256.f,
686 /* width */ 16.f,
687 /* height */ 16.f,
688 /* hit_test */
689 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
690 IsViewportLayer(child_view_token, child_view_size, child_view_inset,
691 {0, 0}, kScale, kOpacityFloat),
692 IsImageLayer(
693 frame_size, kUpperLayerBlendMode,
694 {IsHitRegion(
695 /* x */ 384.f,
696 /* y */ 256.f,
697 /* width */ 16.f,
698 /* height */ 16.f,
699 /* hit_test */
700 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})},
701 {kInvDPR, kInvDPR}));
702
703 // Destroy the view. The scene graph shouldn't change yet.
704 external_view_embedder.DestroyView(
705 child_view_id, [](fuchsia::ui::composition::ContentId) {});
706 EXPECT_THAT(
707 fake_flatland().graph(),
708 IsFlutterGraph(
709 parent_viewport_watcher, viewport_creation_token,
710 view_ref_clone, /*layers*/
711 {IsImageLayer(
712 frame_size, kFirstLayerBlendMode,
713 {IsHitRegion(
714 /* x */ 128.f,
715 /* y */ 256.f,
716 /* width */ 16.f,
717 /* height */ 16.f,
718 /* hit_test */
719 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
720 IsViewportLayer(child_view_token, child_view_size, child_view_inset,
721 {0, 0}, kScale, kOpacityFloat),
722 IsImageLayer(
723 frame_size, kUpperLayerBlendMode,
724 {IsHitRegion(
725 /* x */ 384.f,
726 /* y */ 256.f,
727 /* width */ 16.f,
728 /* height */ 16.f,
729 /* hit_test */
730 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})},
731 {kInvDPR, kInvDPR}));
732
733 // Draw another frame without the view. The scene graph shouldn't change yet.
734 DrawSimpleFrame(
735 external_view_embedder, frame_size_signed, 1.f,
736 [](flutter::DlCanvas* canvas) {
737 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
738 flutter::DlPaint rect_paint;
740 canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
741 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
742 });
743 EXPECT_THAT(
744 fake_flatland().graph(),
745 IsFlutterGraph(
746 parent_viewport_watcher, viewport_creation_token,
747 view_ref_clone, /*layers*/
748 {IsImageLayer(
749 frame_size, kFirstLayerBlendMode,
750 {IsHitRegion(
751 /* x */ 128.f,
752 /* y */ 256.f,
753 /* width */ 16.f,
754 /* height */ 16.f,
755 /* hit_test */
756 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
757 IsViewportLayer(child_view_token, child_view_size, child_view_inset,
758 {0, 0}, kScale, kOpacityFloat),
759 IsImageLayer(
760 frame_size, kUpperLayerBlendMode,
761 {IsHitRegion(
762 /* x */ 384.f,
763 /* y */ 256.f,
764 /* width */ 16.f,
765 /* height */ 16.f,
766 /* hit_test */
767 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})},
768 {kInvDPR, kInvDPR}));
769
770 // Pump the message loop. The scene updates should propagate to flatland.
771 loop().RunUntilIdle();
772 EXPECT_THAT(
773 fake_flatland().graph(),
774 IsFlutterGraph(
775 parent_viewport_watcher, viewport_creation_token,
776 view_ref_clone, /*layers*/
777 {IsImageLayer(
778 frame_size, kFirstLayerBlendMode,
779 {IsHitRegion(
780 /* x */ 128.f,
781 /* y */ 256.f,
782 /* width */ 16.f,
783 /* height */ 16.f,
784 /* hit_test */
785 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
786}

References flutter::DlCanvas::DrawRect(), flutter::DlCanvas::GetBaseLayerDimensions(), flutter::DlColor::kGreen(), flutter::DlColor::kRed(), flutter_runner::testing::ViewTokenPair::New(), flutter::DlPaint::setColor(), and flutter::DlCanvas::Translate().

◆ TEST_F() [4/55]

flutter_runner::testing::TEST_F ( ExternalViewEmbedderTest  ,
SceneWithOneView_DestroyBeforeDrawing   
)

Definition at line 1198 of file external_view_embedder_unittests.cc.

1198 {
1199 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
1200 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
1201 fuchsia::ui::views::ViewCreationToken view_creation_token;
1202 fuchsia::ui::views::ViewRef view_ref_clone;
1203 auto view_creation_token_status = zx::channel::create(
1204 0u, &viewport_creation_token.value, &view_creation_token.value);
1205 ASSERT_EQ(view_creation_token_status, ZX_OK);
1206
1207 fuchsia::ui::views::ViewRefControl view_ref_control;
1208 fuchsia::ui::views::ViewRef view_ref;
1209 auto status = zx::eventpair::create(
1210 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
1211 ASSERT_EQ(status, ZX_OK);
1212 view_ref_control.reference.replace(
1213 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
1214 &view_ref_control.reference);
1215 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
1216 view_ref.Clone(&view_ref_clone);
1217
1218 // Create the `ExternalViewEmbedder` and pump the message loop until
1219 // the initial scene graph is setup.
1220 ExternalViewEmbedder external_view_embedder(
1221 std::move(view_creation_token),
1222 fuchsia::ui::views::ViewIdentityOnCreation{
1223 .view_ref = std::move(view_ref),
1224 .view_ref_control = std::move(view_ref_control),
1225 },
1226 fuchsia::ui::composition::ViewBoundProtocols{},
1227 parent_viewport_watcher.NewRequest(), flatland_connection(),
1228 fake_surface_producer());
1229 flatland_connection()->Present();
1230 loop().RunUntilIdle();
1231 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1232 loop().RunUntilIdle();
1233 EXPECT_THAT(fake_flatland().graph(),
1234 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1235 view_ref_clone));
1236
1237 // Create the view before drawing the scene.
1238 auto [child_view_token, child_viewport_token] = ViewTokenPair::New();
1239 const uint32_t child_view_id = child_viewport_token.value.get();
1240 external_view_embedder.CreateView(
1241 child_view_id, []() {},
1242 [](fuchsia::ui::composition::ContentId,
1243 fuchsia::ui::composition::ChildViewWatcherHandle) {});
1244
1245 // Draw the scene without the view. The scene graph shouldn't change yet.
1246 const DlISize frame_size_signed = DlISize(512, 512);
1247 const fuchsia::math::SizeU frame_size{
1248 static_cast<uint32_t>(frame_size_signed.width),
1249 static_cast<uint32_t>(frame_size_signed.height)};
1250 DrawSimpleFrame(
1251 external_view_embedder, frame_size_signed, 1.f,
1252 [](flutter::DlCanvas* canvas) {
1253 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
1254 flutter::DlPaint rect_paint;
1255 rect_paint.setColor(flutter::DlColor().kGreen());
1256 canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
1257 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1258 });
1259
1260 // Pump the message loop. The scene updates should propagate to flatland.
1261 loop().RunUntilIdle();
1262 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1263 loop().RunUntilIdle();
1264 EXPECT_THAT(
1265 fake_flatland().graph(),
1266 IsFlutterGraph(
1267 parent_viewport_watcher, viewport_creation_token, view_ref_clone,
1268 /*layers*/
1269 {IsImageLayer(
1270 frame_size, kFirstLayerBlendMode,
1271 {IsHitRegion(
1272 /* x */ 128.f,
1273 /* y */ 256.f,
1274 /* width */ 16.f,
1275 /* height */ 16.f,
1276 /* hit_test */
1277 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1278
1279 // Destroy the view. The scene graph shouldn't change yet.
1280 external_view_embedder.DestroyView(
1281 child_view_id, [](fuchsia::ui::composition::ContentId) {});
1282 EXPECT_THAT(
1283 fake_flatland().graph(),
1284 IsFlutterGraph(
1285 parent_viewport_watcher, viewport_creation_token, view_ref_clone,
1286 /*layers*/
1287 {IsImageLayer(
1288 frame_size, kFirstLayerBlendMode,
1289 {IsHitRegion(
1290 /* x */ 128.f,
1291 /* y */ 256.f,
1292 /* width */ 16.f,
1293 /* height */ 16.f,
1294 /* hit_test */
1295 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1296
1297 // Draw another frame without the view and change the size. The scene graph
1298 // shouldn't change yet.
1299 const DlISize new_frame_size_signed = DlISize(256, 256);
1300 const fuchsia::math::SizeU new_frame_size{
1301 static_cast<uint32_t>(new_frame_size_signed.width),
1302 static_cast<uint32_t>(new_frame_size_signed.height)};
1303 DrawSimpleFrame(
1304 external_view_embedder, new_frame_size_signed, 1.f,
1305 [](flutter::DlCanvas* canvas) {
1306 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
1307 flutter::DlPaint rect_paint;
1308 rect_paint.setColor(flutter::DlColor::kGreen());
1309 canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
1310 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1311 });
1312 EXPECT_THAT(
1313 fake_flatland().graph(),
1314 IsFlutterGraph(
1315 parent_viewport_watcher, viewport_creation_token, view_ref_clone,
1316 /*layers*/
1317 {IsImageLayer(
1318 frame_size, kFirstLayerBlendMode,
1319 {IsHitRegion(
1320 /* x */ 128.f,
1321 /* y */ 256.f,
1322 /* width */ 16.f,
1323 /* height */ 16.f,
1324 /* hit_test */
1325 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1326
1327 // Pump the message loop. The scene updates should propagate to flatland.
1328 loop().RunUntilIdle();
1329 EXPECT_THAT(
1330 fake_flatland().graph(),
1331 IsFlutterGraph(
1332 parent_viewport_watcher, viewport_creation_token,
1333 view_ref_clone, /*layers*/
1334 {IsImageLayer(
1335 new_frame_size, kFirstLayerBlendMode,
1336 {IsHitRegion(
1337 /* x */ 64.f,
1338 /* y */ 128.f,
1339 /* width */ 8.f,
1340 /* height */ 8.f,
1341 /* hit_test */
1342 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1343}

References flutter::DlCanvas::DrawRect(), flutter::DlCanvas::GetBaseLayerDimensions(), flutter::DlColor::kGreen(), flutter_runner::testing::ViewTokenPair::New(), flutter::DlPaint::setColor(), and flutter::DlCanvas::Translate().

◆ TEST_F() [5/55]

flutter_runner::testing::TEST_F ( ExternalViewEmbedderTest  ,
SceneWithOneView_NoOverlay   
)

Definition at line 1024 of file external_view_embedder_unittests.cc.

1024 {
1025 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
1026 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
1027 fuchsia::ui::views::ViewCreationToken view_creation_token;
1028 fuchsia::ui::views::ViewRef view_ref_clone;
1029 auto view_creation_token_status = zx::channel::create(
1030 0u, &viewport_creation_token.value, &view_creation_token.value);
1031 ASSERT_EQ(view_creation_token_status, ZX_OK);
1032
1033 fuchsia::ui::views::ViewRefControl view_ref_control;
1034 fuchsia::ui::views::ViewRef view_ref;
1035 auto status = zx::eventpair::create(
1036 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
1037 ASSERT_EQ(status, ZX_OK);
1038 view_ref_control.reference.replace(
1039 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
1040 &view_ref_control.reference);
1041 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
1042 view_ref.Clone(&view_ref_clone);
1043
1044 // Create the `ExternalViewEmbedder` and pump the message loop until
1045 // the initial scene graph is setup.
1046 ExternalViewEmbedder external_view_embedder(
1047 std::move(view_creation_token),
1048 fuchsia::ui::views::ViewIdentityOnCreation{
1049 .view_ref = std::move(view_ref),
1050 .view_ref_control = std::move(view_ref_control),
1051 },
1052 fuchsia::ui::composition::ViewBoundProtocols{},
1053 parent_viewport_watcher.NewRequest(), flatland_connection(),
1054 fake_surface_producer());
1055 flatland_connection()->Present();
1056 loop().RunUntilIdle();
1057 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1058 loop().RunUntilIdle();
1059 EXPECT_THAT(fake_flatland().graph(),
1060 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1061 view_ref_clone));
1062
1063 // Create the view before drawing the scene.
1064 const DlSize child_view_size_signed = DlSize(256.f, 512.f);
1065 const fuchsia::math::SizeU child_view_size{
1066 static_cast<uint32_t>(child_view_size_signed.width),
1067 static_cast<uint32_t>(child_view_size_signed.height)};
1068 auto [child_view_token, child_viewport_token] = ViewTokenPair::New();
1069 const uint32_t child_view_id = child_viewport_token.value.get();
1070
1071 const uint8_t kOpacity = 125u;
1072 const float kOpacityFloat = DlColor::toOpacity(kOpacity);
1073 const fuchsia::math::VecF kScale{2.f, 3.0f};
1074
1075 DlMatrix matrix = DlMatrix::MakeScale({kScale.x, kScale.y, 1});
1076
1077 auto mutators_stack = flutter::MutatorsStack();
1078 mutators_stack.PushOpacity(kOpacity);
1079 mutators_stack.PushTransform(matrix);
1080
1081 flutter::EmbeddedViewParams child_view_params(matrix, child_view_size_signed,
1082 mutators_stack);
1083 external_view_embedder.CreateView(
1084 child_view_id, []() {},
1085 [](fuchsia::ui::composition::ContentId,
1086 fuchsia::ui::composition::ChildViewWatcherHandle) {});
1087
1088 // Draw the scene. The scene graph shouldn't change yet.
1089 const DlISize frame_size_signed = DlISize(512, 512);
1090 const fuchsia::math::SizeU frame_size{
1091 static_cast<uint32_t>(frame_size_signed.width),
1092 static_cast<uint32_t>(frame_size_signed.height)};
1093 DrawFrameWithView(
1094 external_view_embedder, frame_size_signed, 1.f, child_view_id,
1095 child_view_params,
1096 [](flutter::DlCanvas* canvas) {
1097 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
1098 flutter::DlPaint rect_paint;
1099 rect_paint.setColor(flutter::DlColor::kGreen());
1100 canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
1101 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1102 },
1103 [](flutter::DlCanvas* canvas) {});
1104 EXPECT_THAT(fake_flatland().graph(),
1105 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1106 view_ref_clone));
1107
1108 // Pump the message loop. The scene updates should propagate to flatland.
1109 loop().RunUntilIdle();
1110 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1111 loop().RunUntilIdle();
1112 EXPECT_THAT(
1113 fake_flatland().graph(),
1114 IsFlutterGraph(
1115 parent_viewport_watcher, viewport_creation_token,
1116 view_ref_clone, /*layers*/
1117 {IsImageLayer(
1118 frame_size, kFirstLayerBlendMode,
1119 {IsHitRegion(
1120 /* x */ 128.f,
1121 /* y */ 256.f,
1122 /* width */ 16.f,
1123 /* height */ 16.f,
1124 /* hit_test */
1125 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
1126 IsViewportLayer(child_view_token, child_view_size,
1127 FakeViewport::kDefaultViewportInset, {0, 0}, kScale,
1128 kOpacityFloat)}));
1129
1130 // Destroy the view. The scene graph shouldn't change yet.
1131 external_view_embedder.DestroyView(
1132 child_view_id, [](fuchsia::ui::composition::ContentId) {});
1133 EXPECT_THAT(
1134 fake_flatland().graph(),
1135 IsFlutterGraph(
1136 parent_viewport_watcher, viewport_creation_token,
1137 view_ref_clone, /*layers*/
1138 {IsImageLayer(
1139 frame_size, kFirstLayerBlendMode,
1140 {IsHitRegion(
1141 /* x */ 128.f,
1142 /* y */ 256.f,
1143 /* width */ 16.f,
1144 /* height */ 16.f,
1145 /* hit_test */
1146 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
1147 IsViewportLayer(child_view_token, child_view_size,
1148 FakeViewport::kDefaultViewportInset, {0, 0}, kScale,
1149 kOpacityFloat)}));
1150
1151 // Draw another frame without the view. The scene graph shouldn't change yet.
1152 DrawSimpleFrame(
1153 external_view_embedder, frame_size_signed, 1.f,
1154 [](flutter::DlCanvas* canvas) {
1155 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
1156 flutter::DlPaint rect_paint;
1157 rect_paint.setColor(flutter::DlColor::kGreen());
1158 canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
1159 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1160 });
1161
1162 EXPECT_THAT(
1163 fake_flatland().graph(),
1164 IsFlutterGraph(
1165 parent_viewport_watcher, viewport_creation_token,
1166 view_ref_clone, /*layers*/
1167 {IsImageLayer(
1168 frame_size, kFirstLayerBlendMode,
1169 {IsHitRegion(
1170 /* x */ 128.f,
1171 /* y */ 256.f,
1172 /* width */ 16.f,
1173 /* height */ 16.f,
1174 /* hit_test */
1175 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
1176 IsViewportLayer(child_view_token, child_view_size,
1177 FakeViewport::kDefaultViewportInset, {0, 0}, kScale,
1178 kOpacityFloat)}));
1179
1180 // Pump the message loop. The scene updates should propagate to flatland.
1181 loop().RunUntilIdle();
1182 EXPECT_THAT(
1183 fake_flatland().graph(),
1184 IsFlutterGraph(
1185 parent_viewport_watcher, viewport_creation_token,
1186 view_ref_clone, /*layers*/
1187 {IsImageLayer(
1188 frame_size, kFirstLayerBlendMode,
1189 {IsHitRegion(
1190 /* x */ 128.f,
1191 /* y */ 256.f,
1192 /* width */ 16.f,
1193 /* height */ 16.f,
1194 /* hit_test */
1195 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1196}

References flutter::DlCanvas::DrawRect(), flutter::DlCanvas::GetBaseLayerDimensions(), flutter_runner::testing::FakeViewport::kDefaultViewportInset, flutter::DlColor::kGreen(), flutter_runner::testing::ViewTokenPair::New(), flutter::DlPaint::setColor(), and flutter::DlCanvas::Translate().

◆ TEST_F() [6/55]

flutter_runner::testing::TEST_F ( ExternalViewEmbedderTest  ,
SimpleScene   
)

Definition at line 491 of file external_view_embedder_unittests.cc.

491 {
492 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
493 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
494 fuchsia::ui::views::ViewCreationToken view_creation_token;
495 fuchsia::ui::views::ViewRef view_ref_clone;
496 auto view_creation_token_status = zx::channel::create(
497 0u, &viewport_creation_token.value, &view_creation_token.value);
498 ASSERT_EQ(view_creation_token_status, ZX_OK);
499
500 fuchsia::ui::views::ViewRefControl view_ref_control;
501 fuchsia::ui::views::ViewRef view_ref;
502 auto status = zx::eventpair::create(
503 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
504 ASSERT_EQ(status, ZX_OK);
505 view_ref_control.reference.replace(
506 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
507 &view_ref_control.reference);
508 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
509 view_ref.Clone(&view_ref_clone);
510
511 // Create the `ExternalViewEmbedder` and pump the message loop until
512 // the initial scene graph is setup.
513 ExternalViewEmbedder external_view_embedder(
514 std::move(view_creation_token),
515 fuchsia::ui::views::ViewIdentityOnCreation{
516 .view_ref = std::move(view_ref),
517 .view_ref_control = std::move(view_ref_control),
518 },
519 fuchsia::ui::composition::ViewBoundProtocols{},
520 parent_viewport_watcher.NewRequest(), flatland_connection(),
521 fake_surface_producer());
522 flatland_connection()->Present();
523 loop().RunUntilIdle();
524 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
525 loop().RunUntilIdle();
526 EXPECT_THAT(fake_flatland().graph(),
527 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
528 view_ref_clone));
529
530 // Draw the scene. The scene graph shouldn't change yet.
531 const DlISize frame_size_signed = DlISize(512, 512);
532 const fuchsia::math::SizeU frame_size{
533 static_cast<uint32_t>(frame_size_signed.width),
534 static_cast<uint32_t>(frame_size_signed.height)};
535 DrawSimpleFrame(
536 external_view_embedder, frame_size_signed, 1.f,
537 [](flutter::DlCanvas* canvas) {
538 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
539 flutter::DlPaint rect_paint;
541 canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
542 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
543 });
544 EXPECT_THAT(fake_flatland().graph(),
545 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
546 view_ref_clone));
547
548 // Pump the message loop. The scene updates should propagate to flatland.
549 loop().RunUntilIdle();
550
551 EXPECT_THAT(
552 fake_flatland().graph(),
553 IsFlutterGraph(
554 parent_viewport_watcher, viewport_creation_token, view_ref_clone,
555 /*layers*/
556 {IsImageLayer(
557 frame_size, kFirstLayerBlendMode,
558 {IsHitRegion(
559 /* x */ 128.f,
560 /* y */ 256.f,
561 /* width */ 16.f,
562 /* height */ 16.f,
563 /* hit_test */
564 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
565}

References flutter::DlCanvas::DrawRect(), flutter::DlCanvas::GetBaseLayerDimensions(), flutter::DlColor::kGreen(), flutter::DlPaint::setColor(), and flutter::DlCanvas::Translate().

◆ TEST_F() [7/55]

flutter_runner::testing::TEST_F ( ExternalViewEmbedderTest  ,
SimpleScene_DisjointHitRegions   
)

Definition at line 1348 of file external_view_embedder_unittests.cc.

1348 {
1349 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
1350 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
1351 fuchsia::ui::views::ViewCreationToken view_creation_token;
1352 fuchsia::ui::views::ViewRef view_ref_clone;
1353 auto view_creation_token_status = zx::channel::create(
1354 0u, &viewport_creation_token.value, &view_creation_token.value);
1355 ASSERT_EQ(view_creation_token_status, ZX_OK);
1356
1357 fuchsia::ui::views::ViewRefControl view_ref_control;
1358 fuchsia::ui::views::ViewRef view_ref;
1359 auto status = zx::eventpair::create(
1360 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
1361 ASSERT_EQ(status, ZX_OK);
1362 view_ref_control.reference.replace(
1363 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
1364 &view_ref_control.reference);
1365 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
1366 view_ref.Clone(&view_ref_clone);
1367
1368 // Create the `ExternalViewEmbedder` and pump the message loop until
1369 // the initial scene graph is setup.
1370 ExternalViewEmbedder external_view_embedder(
1371 std::move(view_creation_token),
1372 fuchsia::ui::views::ViewIdentityOnCreation{
1373 .view_ref = std::move(view_ref),
1374 .view_ref_control = std::move(view_ref_control),
1375 },
1376 fuchsia::ui::composition::ViewBoundProtocols{},
1377 parent_viewport_watcher.NewRequest(), flatland_connection(),
1378 fake_surface_producer());
1379 flatland_connection()->Present();
1380 loop().RunUntilIdle();
1381 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1382 loop().RunUntilIdle();
1383 EXPECT_THAT(fake_flatland().graph(),
1384 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1385 view_ref_clone));
1386
1387 // Draw the scene. The scene graph shouldn't change yet.
1388 const DlISize frame_size_signed = DlISize(512, 512);
1389 const fuchsia::math::SizeU frame_size{
1390 static_cast<uint32_t>(frame_size_signed.width),
1391 static_cast<uint32_t>(frame_size_signed.height)};
1392 DrawSimpleFrame(external_view_embedder, frame_size_signed, 1.f,
1393 [](flutter::DlCanvas* canvas) {
1394 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
1395
1396 DlRect paint_region_1, paint_region_2;
1397
1398 paint_region_1 = DlRect::MakeXYWH(
1399 canvas_size.width / 4.f, canvas_size.height / 2.f,
1400 canvas_size.width / 32.f, canvas_size.height / 32.f);
1401
1402 flutter::DlPaint rect_paint;
1403 rect_paint.setColor(flutter::DlColor::kGreen());
1404 canvas->DrawRect(paint_region_1, rect_paint);
1405
1406 paint_region_2 = DlRect::MakeXYWH(
1407 canvas_size.width * 3.f / 4.f, canvas_size.height / 2.f,
1408 canvas_size.width / 32.f, canvas_size.height / 32.f);
1409
1410 rect_paint.setColor(flutter::DlColor::kRed());
1411 canvas->DrawRect(paint_region_2, rect_paint);
1412 });
1413 EXPECT_THAT(fake_flatland().graph(),
1414 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1415 view_ref_clone));
1416
1417 // Pump the message loop. The scene updates should propagate to flatland.
1418 loop().RunUntilIdle();
1419
1420 EXPECT_THAT(
1421 fake_flatland().graph(),
1422 IsFlutterGraph(
1423 parent_viewport_watcher, viewport_creation_token, view_ref_clone,
1424 /*layers*/
1425 {IsImageLayer(
1426 frame_size, kFirstLayerBlendMode,
1427 {IsHitRegion(
1428 /* x */ 128.f,
1429 /* y */ 256.f,
1430 /* width */ 16.f,
1431 /* height */ 16.f,
1432 /* hit_test */
1433 fuchsia::ui::composition::HitTestInteraction::DEFAULT),
1434 IsHitRegion(
1435 /* x */ 384.f,
1436 /* y */ 256.f,
1437 /* width */ 16.f,
1438 /* height */ 16.f,
1439 /* hit_test */
1440 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1441}

References flutter::DlCanvas::DrawRect(), flutter::DlCanvas::GetBaseLayerDimensions(), flutter::DlColor::kGreen(), flutter::DlColor::kRed(), and flutter::DlPaint::setColor().

◆ TEST_F() [8/55]

flutter_runner::testing::TEST_F ( ExternalViewEmbedderTest  ,
SimpleScene_OverlappingHitRegions   
)

Definition at line 1447 of file external_view_embedder_unittests.cc.

1447 {
1448 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
1449 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
1450 fuchsia::ui::views::ViewCreationToken view_creation_token;
1451 fuchsia::ui::views::ViewRef view_ref_clone;
1452 auto view_creation_token_status = zx::channel::create(
1453 0u, &viewport_creation_token.value, &view_creation_token.value);
1454 ASSERT_EQ(view_creation_token_status, ZX_OK);
1455
1456 fuchsia::ui::views::ViewRefControl view_ref_control;
1457 fuchsia::ui::views::ViewRef view_ref;
1458 auto status = zx::eventpair::create(
1459 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
1460 ASSERT_EQ(status, ZX_OK);
1461 view_ref_control.reference.replace(
1462 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
1463 &view_ref_control.reference);
1464 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
1465 view_ref.Clone(&view_ref_clone);
1466
1467 // Create the `ExternalViewEmbedder` and pump the message loop until
1468 // the initial scene graph is setup.
1469 ExternalViewEmbedder external_view_embedder(
1470 std::move(view_creation_token),
1471 fuchsia::ui::views::ViewIdentityOnCreation{
1472 .view_ref = std::move(view_ref),
1473 .view_ref_control = std::move(view_ref_control),
1474 },
1475 fuchsia::ui::composition::ViewBoundProtocols{},
1476 parent_viewport_watcher.NewRequest(), flatland_connection(),
1477 fake_surface_producer());
1478 flatland_connection()->Present();
1479 loop().RunUntilIdle();
1480 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1481 loop().RunUntilIdle();
1482 EXPECT_THAT(fake_flatland().graph(),
1483 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1484 view_ref_clone));
1485
1486 // Draw the scene. The scene graph shouldn't change yet.
1487 const DlISize frame_size_signed = DlISize(512, 512);
1488 const fuchsia::math::SizeU frame_size{
1489 static_cast<uint32_t>(frame_size_signed.width),
1490 static_cast<uint32_t>(frame_size_signed.height)};
1491 DrawSimpleFrame(
1492 external_view_embedder, frame_size_signed, 1.f,
1493 [](flutter::DlCanvas* canvas) {
1494 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
1495
1496 DlRect paint_region_1, paint_region_2;
1497
1498 paint_region_1 = DlRect::MakeXYWH(
1499 canvas_size.width / 4.f, canvas_size.height / 2.f,
1500 3.f * canvas_size.width / 8.f, canvas_size.height / 4.f);
1501
1502 flutter::DlPaint rect_paint;
1503 rect_paint.setColor(flutter::DlColor::kGreen());
1504 canvas->DrawRect(paint_region_1, rect_paint);
1505
1506 paint_region_2 = DlRect::MakeXYWH(
1507 canvas_size.width * 3.f / 8.f, canvas_size.height / 2.f,
1508 3.f * canvas_size.width / 8.f, canvas_size.height / 4.f);
1509
1510 rect_paint.setColor(flutter::DlColor::kRed());
1511 canvas->DrawRect(paint_region_2, rect_paint);
1512 });
1513 EXPECT_THAT(fake_flatland().graph(),
1514 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1515 view_ref_clone));
1516
1517 // Pump the message loop. The scene updates should propagate to flatland.
1518 loop().RunUntilIdle();
1519
1520 EXPECT_THAT(
1521 fake_flatland().graph(),
1522 IsFlutterGraph(
1523 parent_viewport_watcher, viewport_creation_token, view_ref_clone,
1524 /*layers*/
1525 {IsImageLayer(
1526 frame_size, kFirstLayerBlendMode,
1527 {IsHitRegion(
1528 /* x */ 128.f,
1529 /* y */ 256.f,
1530 /* width */ 256.f,
1531 /* height */ 128.f,
1532 /* hit_test */
1533 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1534}

References flutter::DlCanvas::DrawRect(), flutter::DlCanvas::GetBaseLayerDimensions(), flutter::DlColor::kGreen(), flutter::DlColor::kRed(), and flutter::DlPaint::setColor().

◆ TEST_F() [9/55]

flutter_runner::testing::TEST_F ( ExternalViewEmbedderTest  ,
ViewportCoveredWithInputInterceptor   
)

Definition at line 1536 of file external_view_embedder_unittests.cc.

1536 {
1537 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
1538 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
1539 fuchsia::ui::views::ViewCreationToken view_creation_token;
1540 fuchsia::ui::views::ViewRef view_ref_clone;
1541 auto view_creation_token_status = zx::channel::create(
1542 0u, &viewport_creation_token.value, &view_creation_token.value);
1543 ASSERT_EQ(view_creation_token_status, ZX_OK);
1544
1545 fuchsia::ui::views::ViewRefControl view_ref_control;
1546 fuchsia::ui::views::ViewRef view_ref;
1547 auto status = zx::eventpair::create(
1548 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
1549 ASSERT_EQ(status, ZX_OK);
1550 view_ref_control.reference.replace(
1551 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
1552 &view_ref_control.reference);
1553 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
1554 view_ref.Clone(&view_ref_clone);
1555
1556 // Create the `ExternalViewEmbedder` and pump the message loop until
1557 // the initial scene graph is setup.
1558 ExternalViewEmbedder external_view_embedder(
1559 std::move(view_creation_token),
1560 fuchsia::ui::views::ViewIdentityOnCreation{
1561 .view_ref = std::move(view_ref),
1562 .view_ref_control = std::move(view_ref_control),
1563 },
1564 fuchsia::ui::composition::ViewBoundProtocols{},
1565 parent_viewport_watcher.NewRequest(), flatland_connection(),
1566 fake_surface_producer(),
1567 /*intercept_all_input=*/true // Enables the interceptor.
1568 );
1569 flatland_connection()->Present();
1570 loop().RunUntilIdle();
1571 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1572 loop().RunUntilIdle();
1573 EXPECT_THAT(fake_flatland().graph(),
1574 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1575 view_ref_clone, {IsInputShield()}));
1576
1577 // Create the view before drawing the scene.
1578 const DlSize child_view_size_signed = DlSize(256.f, 512.f);
1579 const fuchsia::math::SizeU child_view_size{
1580 static_cast<uint32_t>(child_view_size_signed.width),
1581 static_cast<uint32_t>(child_view_size_signed.height)};
1582 auto [child_view_token, child_viewport_token] = ViewTokenPair::New();
1583 const uint32_t child_view_id = child_viewport_token.value.get();
1584
1585 const uint8_t kOpacity = 200u;
1586 const float kOpacityFloat = DlColor::toOpacity(kOpacity);
1587 const fuchsia::math::VecF kScale{3.0f, 4.0f};
1588
1589 DlMatrix matrix = DlMatrix::MakeScale({kScale.x, kScale.y, 1});
1590
1591 auto mutators_stack = flutter::MutatorsStack();
1592 mutators_stack.PushOpacity(kOpacity);
1593 mutators_stack.PushTransform(matrix);
1594
1595 flutter::EmbeddedViewParams child_view_params(matrix, child_view_size_signed,
1596 mutators_stack);
1597 external_view_embedder.CreateView(
1598 child_view_id, []() {},
1599 [](fuchsia::ui::composition::ContentId,
1600 fuchsia::ui::composition::ChildViewWatcherHandle) {});
1601 const SkRect child_view_occlusion_hint = SkRect::MakeLTRB(1, 2, 3, 4);
1602 const fuchsia::math::Inset child_view_inset{
1603 static_cast<int32_t>(child_view_occlusion_hint.top()),
1604 static_cast<int32_t>(child_view_occlusion_hint.right()),
1605 static_cast<int32_t>(child_view_occlusion_hint.bottom()),
1606 static_cast<int32_t>(child_view_occlusion_hint.left())};
1607 external_view_embedder.SetViewProperties(
1608 child_view_id, child_view_occlusion_hint, /*hit_testable=*/false,
1609 /*focusable=*/false);
1610
1611 // We must take into account the effect of DPR on the view scale.
1612 const float kDPR = 2.0f;
1613 const float kInvDPR = 1.f / kDPR;
1614
1615 // Draw the scene. The scene graph shouldn't change yet.
1616 const DlISize frame_size_signed = DlISize(512, 512);
1617 const fuchsia::math::SizeU frame_size{
1618 static_cast<uint32_t>(frame_size_signed.width),
1619 static_cast<uint32_t>(frame_size_signed.height)};
1620 auto background_draw_callback = [](flutter::DlCanvas* canvas) {
1621 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
1622 flutter::DlPaint rect_paint;
1623 rect_paint.setColor(flutter::DlColor::kGreen());
1624 canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
1625 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1626 };
1627 auto overlay_draw_callback = [](flutter::DlCanvas* canvas) {
1628 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
1629 flutter::DlPaint rect_paint;
1630 rect_paint.setColor(flutter::DlColor::kRed());
1631 canvas->Translate(canvas_size.width * 3.f / 4.f, canvas_size.height / 2.f);
1632 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1633 };
1634 DrawFrameWithView(external_view_embedder, frame_size_signed, kDPR,
1635 child_view_id, child_view_params, background_draw_callback,
1636 overlay_draw_callback);
1637 EXPECT_THAT(fake_flatland().graph(),
1638 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1639 view_ref_clone, {IsInputShield()}));
1640
1641 // Pump the message loop. The scene updates should propagate to flatland.
1642 loop().RunUntilIdle();
1643 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1644 loop().RunUntilIdle();
1645
1646 EXPECT_THAT(
1647 fake_flatland().graph(),
1648 IsFlutterGraph(
1649 parent_viewport_watcher, viewport_creation_token,
1650 view_ref_clone, /*layers*/
1651 {IsImageLayer(
1652 frame_size, kFirstLayerBlendMode,
1653 {IsHitRegion(
1654 /* x */ 128.f,
1655 /* y */ 256.f,
1656 /* width */ 16.f,
1657 /* height */ 16.f,
1658 /* hit_test */
1659 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
1660 IsViewportLayer(child_view_token, child_view_size, child_view_inset,
1661 {0, 0}, kScale, kOpacityFloat),
1662 IsImageLayer(
1663 frame_size, kUpperLayerBlendMode,
1664 {IsHitRegion(
1665 /* x */ 384.f,
1666 /* y */ 256.f,
1667 /* width */ 16.f,
1668 /* height */ 16.f,
1669 /* hit_test */
1670 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
1671 IsInputShield()},
1672 {kInvDPR, kInvDPR}));
1673}

References flutter::DlColor::kGreen(), flutter::DlColor::kRed(), flutter_runner::testing::ViewTokenPair::New(), and flutter::DlPaint::setColor().

◆ TEST_F() [10/55]

flutter_runner::testing::TEST_F ( FakeFlatlandTest  ,
DebugLabel   
)

Definition at line 62 of file fake_flatland_unittests.cc.

62 {
63 const std::string debug_label = GetCurrentTestName();
64 fuchsia::ui::composition::FlatlandPtr flatland = ConnectFlatland();
65
66 // Set the flatland's debug name. The `SetDebugName` hasn't been processed
67 // yet, so the flatland's view of the debug name is still empty.
68 flatland->SetDebugName(debug_label);
69 EXPECT_EQ(fake_flatland().debug_name(), "");
70
71 // Pump the loop; the contents of the initial `SetDebugName` should be
72 // processed.
73 loop().RunUntilIdle();
74 EXPECT_EQ(fake_flatland().debug_name(), debug_label);
75}

◆ TEST_F() [11/55]

flutter_runner::testing::TEST_F ( FakeFlatlandTest  ,
Initialization   
)

Definition at line 54 of file fake_flatland_unittests.cc.

54 {
55 EXPECT_EQ(fake_flatland().debug_name(), "");
56
57 // Pump the loop one time; the flatland should retain its initial state.
58 loop().RunUntilIdle();
59 EXPECT_EQ(fake_flatland().debug_name(), "");
60}

◆ TEST_F() [12/55]

flutter_runner::testing::TEST_F ( FakeFlatlandTest  ,
Present   
)

Definition at line 77 of file fake_flatland_unittests.cc.

77 {
78 fuchsia::ui::composition::FlatlandPtr flatland = ConnectFlatland();
79
80 // Fire an OnNextFrameBegin event and verify the test receives it.
81 constexpr uint64_t kOnNextFrameAdditionalPresentCredits = 10u;
82 uint64_t on_next_frame_additional_present_credits = 0u;
83 fuchsia::ui::composition::OnNextFrameBeginValues on_next_frame_begin_values;
84 on_next_frame_begin_values.set_additional_present_credits(
85 kOnNextFrameAdditionalPresentCredits);
86 flatland.events().OnNextFrameBegin =
87 [&on_next_frame_additional_present_credits](
88 auto on_next_frame_begin_values) {
89 static bool called_once = false;
90 EXPECT_FALSE(called_once);
91
92 on_next_frame_additional_present_credits =
93 on_next_frame_begin_values.additional_present_credits();
94 called_once = true;
95 };
96 fake_flatland().FireOnNextFrameBeginEvent(
97 std::move(on_next_frame_begin_values));
98 EXPECT_EQ(on_next_frame_additional_present_credits, 0u);
99 loop().RunUntilIdle();
100 EXPECT_EQ(on_next_frame_additional_present_credits,
101 kOnNextFrameAdditionalPresentCredits);
102
103 // Fire an OnFramePresented event and verify the test receives it.
104 constexpr uint64_t kOnFramePresentedNumPresentsAllowed = 20u;
105 uint64_t frame_presented_num_presents_allowed = 0u;
106 flatland.events().OnFramePresented =
107 [&frame_presented_num_presents_allowed](auto frame_presented_info) {
108 static bool called_once = false;
109 EXPECT_FALSE(called_once);
110
111 frame_presented_num_presents_allowed =
112 frame_presented_info.num_presents_allowed;
113 called_once = true;
114 };
115 fake_flatland().FireOnFramePresentedEvent(
116 fuchsia::scenic::scheduling::FramePresentedInfo{
117 .actual_presentation_time = 0,
118 .num_presents_allowed = kOnFramePresentedNumPresentsAllowed,
119 });
120 EXPECT_EQ(frame_presented_num_presents_allowed, 0u);
121 loop().RunUntilIdle();
122 EXPECT_EQ(frame_presented_num_presents_allowed,
123 kOnFramePresentedNumPresentsAllowed);
124
125 // Call Present and verify the fake handled it.
126 constexpr int64_t kPresentRequestedTime = 42;
127 int64_t present_requested_time = 0;
128 fuchsia::ui::composition::PresentArgs present_args;
129 present_args.set_requested_presentation_time(kPresentRequestedTime);
130 fake_flatland().SetPresentHandler(
131 [&present_requested_time](auto present_args) {
132 static bool called_once = false;
133 EXPECT_FALSE(called_once);
134
135 present_requested_time = present_args.requested_presentation_time();
136 called_once = true;
137 });
138 flatland->Present(std::move(present_args));
139 EXPECT_EQ(present_requested_time, 0);
140 loop().RunUntilIdle();
141 EXPECT_EQ(present_requested_time, kPresentRequestedTime);
142}

◆ TEST_F() [13/55]

flutter_runner::testing::TEST_F ( FlatlandConnectionTest  ,
AwaitVsyncsBeforeOnNextFrameBegin   
)

Definition at line 250 of file flatland_connection_unittests.cc.

250 {
251 // Set up callbacks which allow sensing of how many presents were handled.
252 size_t presents_called = 0u;
253 fake_flatland().SetPresentHandler(
254 [&presents_called](auto present_args) { presents_called++; });
255
256 // Create the FlatlandConnection but don't pump the loop. No FIDL calls are
257 // completed yet.
258 flutter_runner::FlatlandConnection flatland_connection(
259 GetCurrentTestName(), TakeFlatlandHandle(), []() { FAIL(); },
260 [](auto...) {}, loop().dispatcher());
261 EXPECT_EQ(presents_called, 0u);
262
263 // Pump the loop. Nothing is called.
264 loop().RunUntilIdle();
265 EXPECT_EQ(presents_called, 0u);
266
267 // Simulate an AwaitVsync that comes before the first Present.
268 bool await_vsync_callback_fired = false;
269 AwaitVsyncChecked(flatland_connection, await_vsync_callback_fired,
270 kInitialFlatlandVsyncOffset);
271 EXPECT_TRUE(await_vsync_callback_fired);
272
273 // AwaitVsync that comes before the first Present.
274 bool await_vsync_secondary_callback_fired = false;
275 flatland_connection.AwaitVsyncForSecondaryCallback(
276 [&await_vsync_secondary_callback_fired](fml::TimePoint frame_start,
277 fml::TimePoint frame_end) {
278 await_vsync_secondary_callback_fired = true;
279 });
280 EXPECT_TRUE(await_vsync_secondary_callback_fired);
281}

References flutter_runner::kInitialFlatlandVsyncOffset.

◆ TEST_F() [14/55]

flutter_runner::testing::TEST_F ( FlatlandConnectionTest  ,
BasicPresent   
)

Definition at line 164 of file flatland_connection_unittests.cc.

164 {
165 // Set up callbacks which allow sensing of how many presents were handled.
166 size_t presents_called = 0u;
167 zx_handle_t release_fence_handle;
168 fake_flatland().SetPresentHandler([&presents_called,
169 &release_fence_handle](auto present_args) {
170 presents_called++;
171 release_fence_handle = present_args.release_fences().empty()
172 ? ZX_HANDLE_INVALID
173 : present_args.release_fences().front().get();
174 });
175
176 // Set up a callback which allows sensing of how many vsync's
177 // (`OnFramePresented` events) were handled.
178 size_t vsyncs_handled = 0u;
179 on_frame_presented_event on_frame_presented = [&vsyncs_handled](auto...) {
180 vsyncs_handled++;
181 };
182
183 // Create the FlatlandConnection but don't pump the loop. No FIDL calls are
184 // completed yet.
185 flutter_runner::FlatlandConnection flatland_connection(
186 GetCurrentTestName(), TakeFlatlandHandle(), []() { FAIL(); },
187 std::move(on_frame_presented), loop().dispatcher());
188 EXPECT_EQ(presents_called, 0u);
189 EXPECT_EQ(vsyncs_handled, 0u);
190
191 // Pump the loop. Nothing is called.
192 loop().RunUntilIdle();
193 EXPECT_EQ(presents_called, 0u);
194 EXPECT_EQ(vsyncs_handled, 0u);
195
196 // Simulate an AwaitVsync that comes after the first call.
197 bool await_vsync_fired = false;
198 AwaitVsyncChecked(flatland_connection, await_vsync_fired,
199 kInitialFlatlandVsyncOffset);
200 EXPECT_TRUE(await_vsync_fired);
201
202 // Call Present and Pump the loop; `Present` and its callback is called. No
203 // release fence should be queued.
204 await_vsync_fired = false;
205 zx::event first_release_fence;
206 zx::event::create(0u, &first_release_fence);
207 const zx_handle_t first_release_fence_handle = first_release_fence.get();
208 flatland_connection.EnqueueReleaseFence(std::move(first_release_fence));
209 flatland_connection.Present();
210 loop().RunUntilIdle();
211 EXPECT_EQ(presents_called, 1u);
212 EXPECT_EQ(release_fence_handle, ZX_HANDLE_INVALID);
213 EXPECT_EQ(vsyncs_handled, 0u);
214 EXPECT_FALSE(await_vsync_fired);
215
216 // Fire the `OnNextFrameBegin` event. AwaitVsync should be fired.
217 const auto now = fml::TimePoint::Now();
218 const auto kPresentationTime1 = now + fml::TimeDelta::FromSeconds(100);
219 const auto kPresentationTime2 = now + fml::TimeDelta::FromSeconds(200);
220 fuchsia::ui::composition::OnNextFrameBeginValues on_next_frame_begin_values;
221 on_next_frame_begin_values.set_additional_present_credits(3);
222 on_next_frame_begin_values.set_future_presentation_infos(
223 CreateFuturePresentationInfos(kPresentationTime1, kPresentationTime2));
224 fake_flatland().FireOnNextFrameBeginEvent(
225 std::move(on_next_frame_begin_values));
226 loop().RunUntilIdle();
227 AwaitVsyncChecked(flatland_connection, await_vsync_fired, kPresentationTime1);
228 EXPECT_TRUE(await_vsync_fired);
229
230 // Fire the `OnFramePresented` event associated with the first `Present`,
231 fake_flatland().FireOnFramePresentedEvent(
232 fuchsia::scenic::scheduling::FramePresentedInfo());
233 loop().RunUntilIdle();
234 EXPECT_EQ(vsyncs_handled, 1u);
235
236 // Call Present for a second time and Pump the loop; `Present` and its
237 // callback is called. Release fences for the earlier present is used.
238 await_vsync_fired = false;
239 flatland_connection.Present();
240 loop().RunUntilIdle();
241 EXPECT_EQ(presents_called, 2u);
242 EXPECT_EQ(release_fence_handle, first_release_fence_handle);
243
244 // AwaitVsync should be fired with the second present.
245 await_vsync_fired = false;
246 AwaitVsyncChecked(flatland_connection, await_vsync_fired, kPresentationTime2);
247 EXPECT_TRUE(await_vsync_fired);
248}
static constexpr TimeDelta FromSeconds(int64_t seconds)
Definition time_delta.h:49
static TimePoint Now()
Definition time_point.cc:49
std::function< void(fuchsia::scenic::scheduling::FramePresentedInfo)> on_frame_presented_event

References fml::TimeDelta::FromSeconds(), flutter_runner::kInitialFlatlandVsyncOffset, and fml::TimePoint::Now().

◆ TEST_F() [15/55]

flutter_runner::testing::TEST_F ( FlatlandConnectionTest  ,
FenceStuffing   
)

Definition at line 535 of file flatland_connection_unittests.cc.

535 {
536 // Set up callbacks which allow sensing of how many presents were handled.
537 size_t num_presents_called = 0u;
538 size_t num_release_fences = 0u;
539 size_t num_acquire_fences = 0u;
540
541 auto reset_test_counters = [&num_presents_called, &num_acquire_fences,
542 &num_release_fences]() {
543 num_presents_called = 0u;
544 num_release_fences = 0u;
545 num_acquire_fences = 0u;
546 };
547
548 fuchsia::ui::composition::PresentArgs last_present_args;
549 fake_flatland().SetPresentHandler(
550 [&num_presents_called, &num_acquire_fences, &num_release_fences,
551 &last_present_args](fuchsia::ui::composition::PresentArgs present_args) {
552 num_presents_called++;
553 num_acquire_fences = present_args.acquire_fences().size();
554 num_release_fences = present_args.release_fences().size();
555
556 last_present_args = std::move(present_args);
557 });
558
559 // Create the FlatlandConnection but don't pump the loop. No FIDL calls are
560 // completed yet.
561 on_frame_presented_event on_frame_presented = [](auto...) {};
562 flutter_runner::FlatlandConnection flatland_connection(
563 GetCurrentTestName(), TakeFlatlandHandle(), []() { FAIL(); },
564 std::move(on_frame_presented), subloop_dispatcher());
565 EXPECT_EQ(num_presents_called, 0u);
566
567 // Pump the loop. Nothing is called.
568 loop().RunUntilIdle();
569 EXPECT_EQ(num_presents_called, 0u);
570
571 // Simulate an AwaitVsync that comes before the first Present.
572 flatland_connection.AwaitVsync([](fml::TimePoint, fml::TimePoint) {});
573 loop().RunUntilIdle();
574 EXPECT_EQ(num_presents_called, 0u);
575
576 constexpr size_t kMaxFences = 16;
577
578 // We must signal these.
579 FencesPair acquire = GetFencesPair(kMaxFences + 1);
580 // Flatland will signal these.
581 FencesPair release = GetFencesPair(kMaxFences + 1);
582
583 auto fire_callback = [dispatcher = loop().dispatcher(), &flatland_connection,
584 rfd = release.fences_dup, afd = acquire.fences_dup](
585 fml::TimePoint frame_start,
586 fml::TimePoint frame_end) mutable {
587 async::PostTask(dispatcher, [&flatland_connection, rf = rfd, af = afd]() {
588 for (auto& fence : *rf) {
589 zx::event fence_dup;
590 const auto status = fence.duplicate(ZX_RIGHT_SAME_RIGHTS, &fence_dup);
591 ASSERT_EQ(status, ZX_OK);
592 flatland_connection.EnqueueReleaseFence(std::move(fence_dup));
593 }
594 for (auto& fence : *af) {
595 zx::event fence_dup;
596 const auto status = fence.duplicate(ZX_RIGHT_SAME_RIGHTS, &fence_dup);
597 ASSERT_EQ(status, ZX_OK);
598 flatland_connection.EnqueueAcquireFence(std::move(fence_dup));
599 }
600 flatland_connection.Present();
601 });
602 };
603
604 SignalAll(acquire.fences.get());
605
606 // Call Await Vsync with a callback that triggers Present and consumes the one
607 // and only present credit we start with.
608 reset_test_counters();
609 flatland_connection.AwaitVsync(fire_callback);
610
611 loop().RunUntilIdle();
612
613 EXPECT_EQ(num_presents_called, 1u);
614 EXPECT_EQ(num_acquire_fences, 16u);
615 EXPECT_EQ(num_release_fences, 0u);
616
617 // Move on to next present call. Reset all the expectations and callbacks.
618 reset_test_counters();
619 OnNextFrameBegin(1);
620 // Replenish present credits.
621 loop().RunUntilIdle();
622
623 flatland_connection.AwaitVsync([dispatcher = subloop_dispatcher(),
624 &flatland_connection](fml::TimePoint,
626 async::PostTask(dispatcher,
627 [&flatland_connection] { flatland_connection.Present(); });
628 });
629 loop().RunUntilIdle();
630
631 // Simulate Flatland signaling all release fences. Note that the set of
632 // release fences here is only the first ~15 of the fences, the rest are
633 // released indirectly via the overflow mechanism.
634 SignalAll(last_present_args.mutable_release_fences());
635
636 loop().RunUntilIdle();
637
638 // At this point all release fences from prior frame should have been released
639 // by Flatland.
640 EXPECT_EQ(num_presents_called, 1u);
641 EXPECT_EQ(num_acquire_fences, 0u);
642 EXPECT_EQ(num_release_fences, 16u);
643
644 // Prove that all release fences have been signaled. If not, this will block
645 // forever.
646 WaitAll(release.fences.get());
647}
std::string GetCurrentTestName()
Gets the name of the currently running test. This is useful in generating logs or assets based on tes...
Definition testing.cc:14
void SignalAll(std::vector< zx::event > *fences)
void WaitAll(std::vector< zx::event > *fences)
FencesPair GetFencesPair(size_t num_fences)

References flutter_runner::testing::FencesPair::fences, flutter_runner::testing::FencesPair::fences_dup, GetFencesPair(), flutter_runner::kMaxFences, SignalAll(), and WaitAll().

◆ TEST_F() [16/55]

flutter_runner::testing::TEST_F ( FlatlandConnectionTest  ,
FlatlandDisconnect   
)

Definition at line 144 of file flatland_connection_unittests.cc.

144 {
145 // Set up a callback which allows sensing of the error state.
146 bool error_fired = false;
147 fml::closure on_session_error = [&error_fired]() { error_fired = true; };
148
149 // Create the FlatlandConnection but don't pump the loop. No FIDL calls are
150 // completed yet.
151 flutter_runner::FlatlandConnection flatland_connection(
152 GetCurrentTestName(), TakeFlatlandHandle(), std::move(on_session_error),
153 [](auto...) { FAIL(); }, loop().dispatcher());
154 EXPECT_FALSE(error_fired);
155
156 // Simulate a flatland disconnection, then Pump the loop. The error callback
157 // will fire.
158 fake_flatland().Disconnect(
159 fuchsia::ui::composition::FlatlandError::BAD_OPERATION);
160 loop().RunUntilIdle();
161 EXPECT_TRUE(error_fired);
162}
std::function< void()> closure
Definition closure.h:14

◆ TEST_F() [17/55]

flutter_runner::testing::TEST_F ( FlatlandConnectionTest  ,
Initialization   
)

Definition at line 124 of file flatland_connection_unittests.cc.

124 {
125 // Create the FlatlandConnection but don't pump the loop. No FIDL calls are
126 // completed yet.
127 const std::string debug_name = GetCurrentTestName();
128 flutter_runner::FlatlandConnection flatland_connection(
129 debug_name, TakeFlatlandHandle(), []() { FAIL(); },
130 [](auto...) { FAIL(); }, loop().dispatcher());
131 EXPECT_EQ(fake_flatland().debug_name(), "");
132
133 // Simulate an AwaitVsync that returns immediately.
134 bool await_vsync_fired = false;
135 AwaitVsyncChecked(flatland_connection, await_vsync_fired,
136 kInitialFlatlandVsyncOffset);
137 EXPECT_TRUE(await_vsync_fired);
138
139 // Ensure the debug name is set.
140 loop().RunUntilIdle();
141 EXPECT_EQ(fake_flatland().debug_name(), debug_name);
142}

References flutter_runner::kInitialFlatlandVsyncOffset.

◆ TEST_F() [18/55]

flutter_runner::testing::TEST_F ( FlatlandConnectionTest  ,
PresentCreditExhaustion   
)

Definition at line 347 of file flatland_connection_unittests.cc.

347 {
348 // Set up callbacks which allow sensing of how many presents were handled.
349 size_t num_presents_called = 0u;
350 size_t num_release_fences = 0u;
351 size_t num_acquire_fences = 0u;
352
353 auto reset_test_counters = [&num_presents_called, &num_acquire_fences,
354 &num_release_fences]() {
355 num_presents_called = 0u;
356 num_release_fences = 0u;
357 num_acquire_fences = 0u;
358 };
359
360 fake_flatland().SetPresentHandler(
361 [&num_presents_called, &num_acquire_fences, &num_release_fences](
362 fuchsia::ui::composition::PresentArgs present_args) {
363 num_presents_called++;
364 num_acquire_fences = present_args.acquire_fences().size();
365 num_release_fences = present_args.release_fences().size();
366 });
367
368 // Create the FlatlandConnection but don't pump the loop. No FIDL calls are
369 // completed yet.
370 on_frame_presented_event on_frame_presented = [](auto...) {};
371 flutter_runner::FlatlandConnection flatland_connection(
372 GetCurrentTestName(), TakeFlatlandHandle(), []() { FAIL(); },
373 std::move(on_frame_presented), loop().dispatcher());
374 EXPECT_EQ(num_presents_called, 0u);
375
376 // Pump the loop. Nothing is called.
377 loop().RunUntilIdle();
378 EXPECT_EQ(num_presents_called, 0u);
379
380 // Simulate an AwaitVsync that comes before the first Present.
381 flatland_connection.AwaitVsync([](fml::TimePoint, fml::TimePoint) {});
382 loop().RunUntilIdle();
383 EXPECT_EQ(num_presents_called, 0u);
384
385 // This test uses a fire callback that triggers Present() with a single
386 // acquire and release fence in order to approximate the behavior of the real
387 // flutter fire callback and let us drive presents with ONFBs
388 auto fire_callback = [dispatcher = loop().dispatcher(), &flatland_connection](
389 fml::TimePoint frame_start,
390 fml::TimePoint frame_end) {
391 async::PostTask(dispatcher, [&flatland_connection]() {
392 zx::event acquire_fence;
393 zx::event::create(0u, &acquire_fence);
394 zx::event release_fence;
395 zx::event::create(0u, &release_fence);
396 flatland_connection.EnqueueAcquireFence(std::move(acquire_fence));
397 flatland_connection.EnqueueReleaseFence(std::move(release_fence));
398 flatland_connection.Present();
399 });
400 };
401
402 // Call Await Vsync with a callback that triggers Present and consumes the one
403 // and only present credit we start with.
404 reset_test_counters();
405 flatland_connection.AwaitVsync(fire_callback);
406 loop().RunUntilIdle();
407 EXPECT_EQ(num_presents_called, 1u);
408 EXPECT_EQ(num_acquire_fences, 1u);
409 EXPECT_EQ(num_release_fences, 0u);
410
411 // Do it again, but this time we should not get a present because the client
412 // has exhausted its present credits.
413 reset_test_counters();
414 flatland_connection.AwaitVsync(fire_callback);
415 OnNextFrameBegin(0);
416 loop().RunUntilIdle();
417 EXPECT_EQ(num_presents_called, 0u);
418
419 // Supply a present credit but dont set a new fire callback. Fire callback
420 // from previous ONFB should fire and trigger a Present()
421 reset_test_counters();
422 OnNextFrameBegin(1);
423 loop().RunUntilIdle();
424 EXPECT_EQ(num_presents_called, 1u);
425 EXPECT_EQ(num_acquire_fences, 1u);
426 EXPECT_EQ(num_release_fences, 1u);
427
428 // From here on we are testing handling of a race condition where a fire
429 // callback is fired but another ONFB arrives before the present from the
430 // first fire callback comes in, causing present_credits to be negative
431 // within Present().
432
433 uint num_onfb = 5;
434 uint num_deferred_callbacks = 0;
435 // This callback will accumulate num_onfb+1 calls before firing all
436 // of their presents at once.
437 auto accumulating_fire_callback = [&](fml::TimePoint frame_start,
438 fml::TimePoint frame_end) {
439 num_deferred_callbacks++;
440 if (num_deferred_callbacks > num_onfb) {
442 for (uint i = 0; i < num_onfb + 1; i++) {
443 fire_callback(now, now);
444 num_deferred_callbacks--;
445 }
446 }
447 };
448
449 reset_test_counters();
450 for (uint i = 0; i < num_onfb; i++) {
451 flatland_connection.AwaitVsync(accumulating_fire_callback);
452 // only supply a present credit on the first call. Since Presents are being
453 // deferred this credit will not be used up, but we need a credit to call
454 // the accumulating_fire_callback
455 OnNextFrameBegin(i == 0 ? 1 : 0);
456 loop().RunUntilIdle();
457 EXPECT_EQ(num_presents_called, 0u);
458 }
459
460 // This is the num_onfb+1 call to accumulating_fire_callback which triggers
461 // all of the "racing" presents to fire. the first one should be fired,
462 // but the other num_onfb Presents should be deferred.
463 flatland_connection.AwaitVsync(accumulating_fire_callback);
464 OnNextFrameBegin(0);
465 loop().RunUntilIdle();
466 EXPECT_EQ(num_presents_called, 1u);
467 EXPECT_EQ(num_acquire_fences, 1u);
468 EXPECT_EQ(num_release_fences, 1u);
469
470 // Supply a present credit, but pass an empty lambda to AwaitVsync so
471 // that it doesnt call Present(). Should get a deferred present with
472 // all the accumulate acuire fences
473 reset_test_counters();
474 flatland_connection.AwaitVsync([](fml::TimePoint, fml::TimePoint) {});
475 OnNextFrameBegin(1);
476 loop().RunUntilIdle();
477 EXPECT_EQ(num_presents_called, 1u);
478 EXPECT_EQ(num_acquire_fences, num_onfb);
479 EXPECT_EQ(num_release_fences, 1u);
480
481 // Pump another frame to check that release fences accumulate as expected
482 reset_test_counters();
483 flatland_connection.AwaitVsync(fire_callback);
484 OnNextFrameBegin(1);
485 loop().RunUntilIdle();
486 EXPECT_EQ(num_presents_called, 1u);
487 EXPECT_EQ(num_acquire_fences, 1u);
488 EXPECT_EQ(num_release_fences, num_onfb);
489}

References i, and fml::TimePoint::Now().

◆ TEST_F() [19/55]

flutter_runner::testing::TEST_F ( FlatlandConnectionTest  ,
RunsOutOfFuturePresentationInfos   
)

Definition at line 283 of file flatland_connection_unittests.cc.

283 {
284 // Set up callbacks which allow sensing of how many presents were handled.
285 size_t presents_called = 0u;
286 fake_flatland().SetPresentHandler(
287 [&presents_called](auto present_args) { presents_called++; });
288
289 // Set up a callback which allows sensing of how many vsync's
290 // (`OnFramePresented` events) were handled.
291 size_t vsyncs_handled = 0u;
292 on_frame_presented_event on_frame_presented = [&vsyncs_handled](auto...) {
293 vsyncs_handled++;
294 };
295
296 // Create the FlatlandConnection but don't pump the loop. No FIDL calls are
297 // completed yet.
298 flutter_runner::FlatlandConnection flatland_connection(
299 GetCurrentTestName(), TakeFlatlandHandle(), []() { FAIL(); },
300 std::move(on_frame_presented), loop().dispatcher());
301 EXPECT_EQ(presents_called, 0u);
302 EXPECT_EQ(vsyncs_handled, 0u);
303
304 // Pump the loop. Nothing is called.
305 loop().RunUntilIdle();
306 EXPECT_EQ(presents_called, 0u);
307 EXPECT_EQ(vsyncs_handled, 0u);
308
309 // Simulate an AwaitVsync that comes before the first Present.
310 bool await_vsync_callback_fired = false;
311 AwaitVsyncChecked(flatland_connection, await_vsync_callback_fired,
312 kInitialFlatlandVsyncOffset);
313 EXPECT_TRUE(await_vsync_callback_fired);
314
315 // Queue Present.
316 flatland_connection.Present();
317 loop().RunUntilIdle();
318 EXPECT_EQ(presents_called, 1u);
319
320 // Fire the `OnNextFrameBegin` event. AwaitVsync callback should be fired with
321 // the first presentation time.
322 await_vsync_callback_fired = false;
323 const auto kPresentationTime1 =
325 const auto kVsyncInterval = fml::TimeDelta::FromSeconds(234);
326 const auto kPresentationTime2 = kPresentationTime1 + kVsyncInterval;
327 OnNextFrameBegin(1, kPresentationTime1, kPresentationTime2);
328 loop().RunUntilIdle();
329 AwaitVsyncChecked(flatland_connection, await_vsync_callback_fired,
330 kPresentationTime1);
331 EXPECT_TRUE(await_vsync_callback_fired);
332
333 // Second consecutive AwaitVsync callback should be fired with
334 // the second presentation time.
335 await_vsync_callback_fired = false;
336 AwaitVsyncChecked(flatland_connection, await_vsync_callback_fired,
337 kPresentationTime2);
338 EXPECT_TRUE(await_vsync_callback_fired);
339
340 // Another AwaitVsync callback should be fired with vsync_interval.
341 await_vsync_callback_fired = false;
342 AwaitVsyncChecked(flatland_connection, await_vsync_callback_fired,
343 kPresentationTime2 + kVsyncInterval);
344 EXPECT_TRUE(await_vsync_callback_fired);
345}

References fml::TimeDelta::FromSeconds(), flutter_runner::kInitialFlatlandVsyncOffset, and fml::TimePoint::Now().

◆ TEST_F() [20/55]

flutter_runner::testing::TEST_F ( FocusDelegateTest  ,
RequestFocusFailTest   
)

Definition at line 163 of file focus_delegate_unittests.cc.

163 {
164 // This "Mock" ViewRef serves as the target for the RequestFocus operation.
165 fuchsia::ui::views::ViewRefControl view_ref_control;
166 fuchsia::ui::views::ViewRef view_ref;
167 auto status = zx::eventpair::create(
168 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
169 ZX_ASSERT(status == ZX_OK);
170 view_ref_control.reference.replace(
171 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
172 &view_ref_control.reference);
173 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
174 // We're testing the focus failure case.
175 focuser_->fail_request_focus();
176 // Create the platform message request.
177 std::ostringstream message;
178 message << "{" << " \"method\":\"View.focus.request\","
179 << " \"args\": {"
180 << " \"viewRef\":" << view_ref.reference.get() << " }"
181 << "}";
182
183 // Dispatch the plaform message request with an expected completion response.
184 auto response = FakePlatformMessageResponse::Create();
185 EXPECT_TRUE(focus_delegate_->HandlePlatformMessage(
186 ParsePlatformMessage(message.str()), response));
187 RunLoopUntilIdle();
188
189 response->ExpectCompleted(
190 "[" +
191 std::to_string(
192 static_cast<std::underlying_type_t<fuchsia::ui::views::Error>>(
193 fuchsia::ui::views::Error::DENIED)) +
194 "]");
195 EXPECT_TRUE(focuser_->request_focus_called());
196}
rapidjson::Value ParsePlatformMessage(std::string json)

References flutter_runner::testing::FakePlatformMessageResponse::Create(), message, and ParsePlatformMessage().

◆ TEST_F() [21/55]

flutter_runner::testing::TEST_F ( FocusDelegateTest  ,
RequestFocusTest   
)

Definition at line 132 of file focus_delegate_unittests.cc.

132 {
133 // This "Mock" ViewRef serves as the target for the RequestFocus operation.
134 fuchsia::ui::views::ViewRefControl view_ref_control;
135 fuchsia::ui::views::ViewRef view_ref;
136 auto status = zx::eventpair::create(
137 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
138 ZX_ASSERT(status == ZX_OK);
139 view_ref_control.reference.replace(
140 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
141 &view_ref_control.reference);
142 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
143
144 // Create the platform message request.
145 std::ostringstream message;
146 message << "{" << " \"method\":\"View.focus.request\","
147 << " \"args\": {"
148 << " \"viewRef\":" << view_ref.reference.get() << " }"
149 << "}";
150
151 // Dispatch the plaform message request with an expected completion response.
152 auto response = FakePlatformMessageResponse::Create();
153 EXPECT_TRUE(focus_delegate_->HandlePlatformMessage(
154 ParsePlatformMessage(message.str()), response));
155 RunLoopUntilIdle();
156
157 response->ExpectCompleted("[0]");
158 EXPECT_TRUE(focuser_->request_focus_called());
159}

References flutter_runner::testing::FakePlatformMessageResponse::Create(), message, and ParsePlatformMessage().

◆ TEST_F() [22/55]

flutter_runner::testing::TEST_F ( FocusDelegateTest  ,
WatchCallbackSeries   
)

Definition at line 65 of file focus_delegate_unittests.cc.

65 {
66 std::vector<bool> vrf_states{false, true, true, false,
67 true, false, true, true};
68 std::size_t vrf_index = 0;
69 std::size_t callback_index = 0;
70 focus_delegate_->WatchLoop([&](bool focus_state) {
71 // Make sure the focus state that FocusDelegate gives us is consistent with
72 // what was fired from the vrf.
73 EXPECT_EQ(vrf_states[callback_index], focus_state);
74
75 // View.focus.getCurrent should complete with the current (up to date) focus
76 // state.
77 auto response = FakePlatformMessageResponse::Create();
78 EXPECT_TRUE(focus_delegate_->HandlePlatformMessage(
79 ParsePlatformMessage("{\"method\":\"View.focus.getCurrent\"}"),
80 response));
81 response->ExpectCompleted(focus_state ? "[true]" : "[false]");
82
83 // Ensure this callback always happens in lockstep with
84 // vrf_->ScheduleCallback.
85 EXPECT_EQ(vrf_index, callback_index++);
86 });
87
88 // Subsequent WatchLoop calls should not be respected.
89 focus_delegate_->WatchLoop([](bool _) {
90 ADD_FAILURE() << "Subsequent WatchLoops should not be respected!";
91 });
92
93 do {
94 // Ensure the next focus state is handled correctly.
95 auto response1 = FakePlatformMessageResponse::Create();
96 EXPECT_TRUE(focus_delegate_->HandlePlatformMessage(
97 ParsePlatformMessage("{\"method\":\"View.focus.getNext\"}"),
98 response1));
99
100 // Since there's already an outstanding PlatformMessageResponse, this one
101 // should be completed null.
102 auto response2 = FakePlatformMessageResponse::Create();
103 EXPECT_TRUE(focus_delegate_->HandlePlatformMessage(
104 ParsePlatformMessage("{\"method\":\"View.focus.getNext\"}"),
105 response2));
106 response2->ExpectCompleted("[null]");
107
108 // Post watch events and trigger the next vrf event.
109 RunLoopUntilIdle();
110 vrf_->ScheduleCallback(vrf_states[vrf_index]);
111 RunLoopUntilIdle();
112
113 // Next focus state should be completed by now.
114 response1->ExpectCompleted(vrf_states[vrf_index] ? "[true]" : "[false]");
115
116 // Check View.focus.getCurrent again, and increment vrf_index since we move
117 // on to the next focus state.
118 auto response3 = FakePlatformMessageResponse::Create();
119 EXPECT_TRUE(focus_delegate_->HandlePlatformMessage(
120 ParsePlatformMessage("{\"method\":\"View.focus.getCurrent\"}"),
121 response3));
122 response3->ExpectCompleted(vrf_states[vrf_index++] ? "[true]" : "[false]");
123
124 // vrf_->times_watched should always be 1 more than the amount of vrf events
125 // emitted.
126 EXPECT_EQ(vrf_index + 1, vrf_->times_watched);
127 } while (vrf_index < vrf_states.size());
128}

References flutter_runner::testing::FakePlatformMessageResponse::Create(), and ParsePlatformMessage().

◆ TEST_F() [23/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
ChangesAccessibilitySettings   
)

Definition at line 707 of file platform_view_unittest.cc.

707 {
708 MockPlatformViewDelegate delegate;
709 flutter::TaskRunners task_runners =
710 flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);
711
712 EXPECT_FALSE(delegate.semantics_enabled());
713 EXPECT_EQ(delegate.semantics_features(), 0);
714
715 auto platform_view =
716 PlatformViewBuilder(delegate, std::move(task_runners)).Build();
717
718 RunLoopUntilIdle();
719
720 platform_view.SetSemanticsEnabled(true);
721
722 EXPECT_TRUE(delegate.semantics_enabled());
723 EXPECT_EQ(delegate.semantics_features(),
724 static_cast<int32_t>(
726
727 platform_view.SetSemanticsEnabled(false);
728
729 EXPECT_FALSE(delegate.semantics_enabled());
730 EXPECT_EQ(delegate.semantics_features(), 0);
731}
std::unique_ptr< flutter::PlatformViewIOS > platform_view

References flutter::kAccessibleNavigation, and platform_view.

◆ TEST_F() [24/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
CreateSurfaceTest   
)

Definition at line 641 of file platform_view_unittest.cc.

641 {
642 MockPlatformViewDelegate delegate;
643
644 flutter::TaskRunners task_runners =
645 flutter::TaskRunners("test_runners", // label
646 nullptr, // platform
648 async_get_default_dispatcher()), // raster
649 nullptr, // ui
650 nullptr // io
651 );
652
653 // Test create surface callback function.
654 sk_sp<GrDirectContext> gr_context = GrDirectContext::MakeMock(
655 nullptr,
657 std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
658 std::make_shared<MockExternalViewEmbedder>();
659 auto CreateSurfaceCallback = [&external_view_embedder, gr_context]() {
660 return std::make_unique<flutter_runner::Surface>(
661 "PlatformViewTest", external_view_embedder, gr_context.get());
662 };
663
664 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
665 .SetCreateSurfaceCallback(CreateSurfaceCallback)
666 .SetExternalViewEmbedder(external_view_embedder)
667 .Build();
668 platform_view.NotifyCreated();
669
670 RunLoopUntilIdle();
671
672 EXPECT_EQ(gr_context.get(), delegate.surface()->GetContext());
673 EXPECT_EQ(external_view_embedder.get(),
674 platform_view.CreateExternalViewEmbedder().get());
675}
fml::RefPtr< fml::TaskRunner > CreateFMLTaskRunner(async_dispatcher_t *dispatcher)
GrContextOptions MakeDefaultContextOptions(ContextType type, std::optional< GrBackendApi > api)
Initializes GrContextOptions with values suitable for Flutter. The options can be further tweaked bef...
@ kRender
The context is used to render to a texture or renderbuffer.

References flutter_runner::CreateFMLTaskRunner(), flutter::kRender, flutter::MakeDefaultContextOptions(), and platform_view.

◆ TEST_F() [25/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
CreateViewTest   
)

Definition at line 779 of file platform_view_unittest.cc.

779 {
780 MockPlatformViewDelegate delegate;
781 const uint64_t view_id = 42;
782 flutter::TaskRunners task_runners =
783 flutter::TaskRunners("test_runners", // label
785 async_get_default_dispatcher()), // platform
786 nullptr, // raster
787 nullptr, // ui
788 nullptr // io
789 );
790
791 // Test wireframe callback function. If the message sent to the platform
792 // view was properly handled and parsed, this function should be called,
793 // setting |wireframe_enabled| to true.
794 bool create_view_called = false;
795 auto CreateViewCallback =
796 [&create_view_called, this](
797 int64_t view_id, flutter_runner::ViewCallback on_view_created,
798 flutter_runner::ViewCreatedCallback on_view_bound, bool hit_testable,
799 bool focusable) {
800 create_view_called = true;
801 on_view_created();
802 fuchsia::ui::composition::ContentId content_id;
803 on_view_bound(std::move(content_id), MakeChildViewWatcher());
804 };
805
806 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
807 .SetCreateViewCallback(CreateViewCallback)
808 .Build();
809
810 // Cast platform_view to its base view so we can have access to the public
811 // "HandlePlatformMessage" function.
812 auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
813 EXPECT_TRUE(base_view);
814
815 // JSON for the message to be passed into the PlatformView.
816 std::ostringstream create_view_message;
817 create_view_message << "{" << " \"method\":\"View.create\","
818 << " \"args\":{" << " \"viewId\":" << view_id << ","
819 << " \"hitTestable\":true," << " \"focusable\":true"
820 << " }" << "}";
821
822 std::string create_view_call = create_view_message.str();
823 std::unique_ptr<flutter::PlatformMessage> message =
824 std::make_unique<flutter::PlatformMessage>(
825 "flutter/platform_views",
826 fml::MallocMapping::Copy(create_view_call.c_str(),
827 create_view_call.size()),
829 base_view->HandlePlatformMessage(std::move(message));
830
831 RunLoopUntilIdle();
832
833 EXPECT_TRUE(create_view_called);
834
835 // Platform view forwards the 'View.viewConnected' message on the
836 // 'flutter/platform_views' channel when a view gets created.
837 std::ostringstream view_connected_expected_out;
838 view_connected_expected_out << "{" << "\"method\":\"View.viewConnected\","
839 << "\"args\":{" << " \"viewId\":" << view_id
840 << " }" << "}";
841
842 ASSERT_NE(delegate.message(), nullptr);
843 EXPECT_EQ(view_connected_expected_out.str(),
844 ToString(delegate.message()->data()));
845}
Platform views are created by the shell on the platform task runner. Unless explicitly specified,...
static MallocMapping Copy(const T *begin, const T *end)
Definition mapping.h:162
G_BEGIN_DECLS FlutterViewId view_id
std::function< void()> ViewCallback
std::function< void(fuchsia::ui::composition::ContentId, fuchsia::ui::composition::ChildViewWatcherHandle child_view_watcher)> ViewCreatedCallback

References fml::MallocMapping::Copy(), flutter_runner::CreateFMLTaskRunner(), message, platform_view, and view_id.

◆ TEST_F() [26/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
DestroyViewTest   
)

Definition at line 964 of file platform_view_unittest.cc.

964 {
965 MockPlatformViewDelegate delegate;
966 const uint64_t view_id = 42;
967
968 flutter::TaskRunners task_runners =
969 flutter::TaskRunners("test_runners", // label
971 async_get_default_dispatcher()), // platform
972 nullptr, // raster
973 nullptr, // ui
974 nullptr // io
975 );
976
977 bool destroy_view_called = false;
978
979 auto on_destroy_view = [&destroy_view_called](
980 int64_t view_id,
981 flutter_runner::ViewIdCallback on_view_unbound) {
982 destroy_view_called = true;
983 fuchsia::ui::composition::ContentId content_id;
984 on_view_unbound(std::move(content_id));
985 };
986
987 bool create_view_called = false;
988 auto on_create_view = [&create_view_called, this](
989 int64_t view_id,
990 flutter_runner::ViewCallback on_view_created,
992 bool hit_testable, bool focusable) {
993 create_view_called = true;
994 on_view_created();
995 fuchsia::ui::composition::ContentId content_id;
996 on_view_bound(std::move(content_id), MakeChildViewWatcher());
997 };
998
999 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
1000 .SetCreateViewCallback(on_create_view)
1001 .SetDestroyViewCallback(on_destroy_view)
1002 .Build();
1003
1004 // Cast platform_view to its base view so we can have access to the public
1005 // "HandlePlatformMessage" function.
1006 auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
1007 EXPECT_TRUE(base_view);
1008
1009 std::ostringstream create_message;
1010 create_message << "{" << " \"method\":\"View.create\","
1011 << " \"args\": {" << " \"viewId\":" << view_id << ","
1012 << " \"hitTestable\":true,"
1013 << " \"focusable\":true" << " }" << "}";
1014
1015 auto create_response = FakePlatformMessageResponse::Create();
1016 base_view->HandlePlatformMessage(create_response->WithMessage(
1017 "flutter/platform_views", create_message.str()));
1018 RunLoopUntilIdle();
1019
1020 delegate.Reset();
1021
1022 // JSON for the message to be passed into the PlatformView.
1023 std::ostringstream dispose_message;
1024 dispose_message << "{" << " \"method\":\"View.dispose\","
1025 << " \"args\": {" << " \"viewId\":" << view_id
1026 << " }" << "}";
1027
1028 std::string dispose_view_call = dispose_message.str();
1029 std::unique_ptr<flutter::PlatformMessage> message =
1030 std::make_unique<flutter::PlatformMessage>(
1031 "flutter/platform_views",
1032 fml::MallocMapping::Copy(dispose_view_call.c_str(),
1033 dispose_view_call.size()),
1035 base_view->HandlePlatformMessage(std::move(message));
1036
1037 RunLoopUntilIdle();
1038
1039 EXPECT_TRUE(destroy_view_called);
1040
1041 // Platform view forwards the 'View.viewDisconnected' message on the
1042 // 'flutter/platform_views' channel when a view gets destroyed.
1043 std::ostringstream view_disconnected_expected_out;
1044 view_disconnected_expected_out
1045 << "{" << "\"method\":\"View.viewDisconnected\"," << "\"args\":{"
1046 << " \"viewId\":" << view_id << " }" << "}";
1047
1048 ASSERT_NE(delegate.message(), nullptr);
1049 EXPECT_EQ(view_disconnected_expected_out.str(),
1050 ToString(delegate.message()->data()));
1051}
std::function< void(fuchsia::ui::composition::ContentId)> ViewIdCallback

References fml::MallocMapping::Copy(), flutter_runner::testing::FakePlatformMessageResponse::Create(), flutter_runner::CreateFMLTaskRunner(), message, platform_view, and view_id.

◆ TEST_F() [27/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
EnableWireframeTest   
)

Definition at line 735 of file platform_view_unittest.cc.

735 {
736 MockPlatformViewDelegate delegate;
737 flutter::TaskRunners task_runners =
738 flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);
739
740 // Test wireframe callback function. If the message sent to the platform
741 // view was properly handled and parsed, this function should be called,
742 // setting |wireframe_enabled| to true.
743 bool wireframe_enabled = false;
744 auto EnableWireframeCallback = [&wireframe_enabled](bool should_enable) {
745 wireframe_enabled = should_enable;
746 };
747
748 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
749 .SetEnableWireframeCallback(EnableWireframeCallback)
750 .Build();
751
752 // Cast platform_view to its base view so we can have access to the public
753 // "HandlePlatformMessage" function.
754 auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
755 EXPECT_TRUE(base_view);
756
757 // JSON for the message to be passed into the PlatformView.
758 const uint8_t txt[] =
759 "{"
760 " \"method\":\"View.enableWireframe\","
761 " \"args\": {"
762 " \"enable\":true"
763 " }"
764 "}";
765
766 std::unique_ptr<flutter::PlatformMessage> message =
767 std::make_unique<flutter::PlatformMessage>(
768 "flutter/platform_views", fml::MallocMapping::Copy(txt, sizeof(txt)),
770 base_view->HandlePlatformMessage(std::move(message));
771
772 RunLoopUntilIdle();
773
774 EXPECT_TRUE(wireframe_enabled);
775}

References fml::MallocMapping::Copy(), message, and platform_view.

◆ TEST_F() [28/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
GetFocusStatesTest   
)

Definition at line 1056 of file platform_view_unittest.cc.

1056 {
1057 MockPlatformViewDelegate delegate;
1058 flutter::TaskRunners task_runners =
1059 flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);
1060
1062 fidl::BindingSet<fuchsia::ui::views::ViewRefFocused> vrf_bindings;
1063 auto vrf_handle = vrf_bindings.AddBinding(&vrf);
1064
1065 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
1066 .SetViewRefFocused(std::move(vrf_handle))
1067 .Build();
1068
1069 // Cast platform_view to its base view so we can have access to the public
1070 // "HandlePlatformMessage" function.
1071 auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
1072 EXPECT_TRUE(base_view);
1073
1074 std::vector<bool> vrf_states{false, true, true, false,
1075 true, false, true, true};
1076
1077 for (std::size_t i = 0; i < vrf_states.size(); ++i) {
1078 // View.focus.getNext should complete with the next focus state.
1079 auto response1 = FakePlatformMessageResponse::Create();
1080 base_view->HandlePlatformMessage(response1->WithMessage(
1081 "flutter/platform_views", "{\"method\":\"View.focus.getNext\"}"));
1082 // Duplicate View.focus.getNext requests should complete empty.
1083 auto response2 = FakePlatformMessageResponse::Create();
1084 base_view->HandlePlatformMessage(response2->WithMessage(
1085 "flutter/platform_views", "{\"method\":\"View.focus.getNext\"}"));
1086
1087 // Post watch events and make sure the hanging get is invoked each time.
1088 RunLoopUntilIdle();
1089 EXPECT_EQ(vrf.times_watched, i + 1);
1090
1091 // Dispatch the next vrf event.
1092 vrf.ScheduleCallback(vrf_states[i]);
1093 RunLoopUntilIdle();
1094
1095 // Make sure View.focus.getCurrent completes with the current focus state.
1096 auto response3 = FakePlatformMessageResponse::Create();
1097 base_view->HandlePlatformMessage(response3->WithMessage(
1098 "flutter/platform_views", "{\"method\":\"View.focus.getCurrent\"}"));
1099 // Duplicate View.focus.getCurrent are allowed.
1100 auto response4 = FakePlatformMessageResponse::Create();
1101 base_view->HandlePlatformMessage(response4->WithMessage(
1102 "flutter/platform_views", "{\"method\":\"View.focus.getCurrent\"}"));
1103
1104 // Run event loop and check our results.
1105 RunLoopUntilIdle();
1106 response1->ExpectCompleted(vrf_states[i] ? "[true]" : "[false]");
1107 response2->ExpectCompleted("[null]");
1108 response3->ExpectCompleted(vrf_states[i] ? "[true]" : "[false]");
1109 response4->ExpectCompleted(vrf_states[i] ? "[true]" : "[false]");
1110 }
1111}

References flutter_runner::testing::FakePlatformMessageResponse::Create(), i, platform_view, flutter_runner::testing::FakeViewRefFocused::ScheduleCallback(), and flutter_runner::testing::FakeViewRefFocused::times_watched.

◆ TEST_F() [29/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
InvalidPlatformMessageRequest   
)

Definition at line 579 of file platform_view_unittest.cc.

579 {
580 MockPlatformViewDelegate delegate;
581 flutter::TaskRunners task_runners =
582 flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);
583
585 fidl::BindingSet<fuchsia::ui::views::ViewRefFocused> vrf_bindings;
586 auto vrf_handle = vrf_bindings.AddBinding(&vrf);
587
588 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
589 .SetViewRefFocused(std::move(vrf_handle))
590 .Build();
591
592 // Cast platform_view to its base view so we can have access to the public
593 // "HandlePlatformMessage" function.
594 auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
595 EXPECT_TRUE(base_view);
596
597 // Invalid platform channel.
598 auto response1 = FakePlatformMessageResponse::Create();
599 base_view->HandlePlatformMessage(response1->WithMessage(
600 "flutter/invalid", "{\"method\":\"Invalid.invalidMethod\"}"));
601
602 // Invalid json.
603 auto response2 = FakePlatformMessageResponse::Create();
604 base_view->HandlePlatformMessage(
605 response2->WithMessage("flutter/platform_views", "{Invalid JSON"));
606
607 // Invalid method.
608 auto response3 = FakePlatformMessageResponse::Create();
609 base_view->HandlePlatformMessage(response3->WithMessage(
610 "flutter/platform_views", "{\"method\":\"View.focus.invalidMethod\"}"));
611
612 // Missing arguments.
613 auto response4 = FakePlatformMessageResponse::Create();
614 base_view->HandlePlatformMessage(response4->WithMessage(
615 "flutter/platform_views", "{\"method\":\"View.update\"}"));
616 auto response5 = FakePlatformMessageResponse::Create();
617 base_view->HandlePlatformMessage(
618 response5->WithMessage("flutter/platform_views",
619 "{\"method\":\"View.update\",\"args\":{"
620 "\"irrelevantField\":\"irrelevantValue\"}}"));
621
622 // Wrong argument types.
623 auto response6 = FakePlatformMessageResponse::Create();
624 base_view->HandlePlatformMessage(response6->WithMessage(
625 "flutter/platform_views",
626 "{\"method\":\"View.update\",\"args\":{\"viewId\":false,\"hitTestable\":"
627 "123,\"focusable\":\"yes\"}}"));
628
629 // Run the event loop and check our responses.
630 RunLoopUntilIdle();
631 response1->ExpectCompleted("");
632 response2->ExpectCompleted("");
633 response3->ExpectCompleted("");
634 response4->ExpectCompleted("");
635 response5->ExpectCompleted("");
636 response6->ExpectCompleted("");
637}

References flutter_runner::testing::FakePlatformMessageResponse::Create(), and platform_view.

◆ TEST_F() [30/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
OnKeyEvent   
)

Definition at line 1326 of file platform_view_unittest.cc.

1326 {
1327 struct EventFlow {
1328 fuchsia::ui::input3::KeyEvent event;
1329 fuchsia::ui::input3::KeyEventStatus expected_key_event_status;
1330 std::string expected_platform_message;
1331 };
1332
1333 MockPlatformViewDelegate delegate;
1334 flutter::TaskRunners task_runners =
1335 flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);
1336
1337 fuchsia::ui::input3::KeyboardHandle keyboard_service;
1338 MockKeyboard keyboard(keyboard_service.NewRequest());
1339
1340 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
1341 .SetKeyboard(std::move(keyboard_service))
1342 .Build();
1343 RunLoopUntilIdle();
1344
1345 std::vector<EventFlow> events;
1346 // Press A. Get 'a'.
1347 // The HID usage for the key A is 0x70004, or 458756.
1348 events.emplace_back(EventFlow{
1349 MakeEvent(fuchsia::ui::input3::KeyEventType::PRESSED, std::nullopt,
1350 fuchsia::input::Key::A),
1351 fuchsia::ui::input3::KeyEventStatus::HANDLED,
1352 R"({"type":"keydown","keymap":"fuchsia","hidUsage":458756,"codePoint":97,"modifiers":0})",
1353 });
1354 // Release A. Get 'a' release.
1355 events.emplace_back(EventFlow{
1356 MakeEvent(fuchsia::ui::input3::KeyEventType::RELEASED, std::nullopt,
1357 fuchsia::input::Key::A),
1358 fuchsia::ui::input3::KeyEventStatus::HANDLED,
1359 R"({"type":"keyup","keymap":"fuchsia","hidUsage":458756,"codePoint":97,"modifiers":0})",
1360 });
1361 // Press CAPS_LOCK. Modifier now active.
1362 events.emplace_back(EventFlow{
1363 MakeEvent(fuchsia::ui::input3::KeyEventType::PRESSED,
1364 fuchsia::ui::input3::Modifiers::CAPS_LOCK,
1365 fuchsia::input::Key::CAPS_LOCK),
1366 fuchsia::ui::input3::KeyEventStatus::HANDLED,
1367 R"({"type":"keydown","keymap":"fuchsia","hidUsage":458809,"codePoint":0,"modifiers":1})",
1368 });
1369 // Press A. Get 'A'.
1370 events.emplace_back(EventFlow{
1371 MakeEvent(fuchsia::ui::input3::KeyEventType::PRESSED, std::nullopt,
1372 fuchsia::input::Key::A),
1373 fuchsia::ui::input3::KeyEventStatus::HANDLED,
1374 R"({"type":"keydown","keymap":"fuchsia","hidUsage":458756,"codePoint":65,"modifiers":1})",
1375 });
1376 // Release CAPS_LOCK.
1377 events.emplace_back(EventFlow{
1378 MakeEvent(fuchsia::ui::input3::KeyEventType::RELEASED,
1379 fuchsia::ui::input3::Modifiers::CAPS_LOCK,
1380 fuchsia::input::Key::CAPS_LOCK),
1381 fuchsia::ui::input3::KeyEventStatus::HANDLED,
1382 R"({"type":"keyup","keymap":"fuchsia","hidUsage":458809,"codePoint":0,"modifiers":1})",
1383 });
1384 // Press A again. This time get 'A'.
1385 // CAPS_LOCK is latched active even if it was just released.
1386 events.emplace_back(EventFlow{
1387 MakeEvent(fuchsia::ui::input3::KeyEventType::PRESSED, std::nullopt,
1388 fuchsia::input::Key::A),
1389 fuchsia::ui::input3::KeyEventStatus::HANDLED,
1390 R"({"type":"keydown","keymap":"fuchsia","hidUsage":458756,"codePoint":65,"modifiers":1})",
1391 });
1392
1393 for (const auto& event : events) {
1394 fuchsia::ui::input3::KeyEvent e;
1395 event.event.Clone(&e);
1396 fuchsia::ui::input3::KeyEventStatus key_event_status{0u};
1397 keyboard.listener_->OnKeyEvent(
1398 std::move(e),
1399 [&key_event_status](fuchsia::ui::input3::KeyEventStatus status) {
1400 key_event_status = status;
1401 });
1402 RunLoopUntilIdle();
1403
1404 ASSERT_NOTNULL(delegate.message());
1405 EXPECT_EQ(event.expected_platform_message,
1406 ToString(delegate.message()->data()));
1407 EXPECT_EQ(event.expected_key_event_status, key_event_status);
1408 }
1409}
const char * ToString(ax::mojom::Event event)

References platform_view.

◆ TEST_F() [31/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
OnShaderWarmup   
)

Definition at line 1411 of file platform_view_unittest.cc.

1411 {
1412 MockPlatformViewDelegate delegate;
1413 flutter::TaskRunners task_runners =
1414 flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);
1415
1416 uint64_t width = 200;
1417 uint64_t height = 100;
1418 std::vector<std::string> shaders = {"foo.skp", "bar.skp", "baz.skp"};
1419
1420 OnShaderWarmupCallback on_shader_warmup_callback =
1421 [&](const std::vector<std::string>& shaders_in,
1422 std::function<void(uint32_t)> completion_callback, uint64_t width_in,
1423 uint64_t height_in) {
1424 ASSERT_EQ(shaders.size(), shaders_in.size());
1425 for (size_t i = 0; i < shaders_in.size(); i++) {
1426 ASSERT_EQ(shaders[i], shaders_in[i]);
1427 }
1428 ASSERT_EQ(width, width_in);
1429 ASSERT_EQ(height, height_in);
1430
1431 completion_callback(shaders_in.size());
1432 };
1433
1434 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
1435 .SetShaderWarmupCallback(on_shader_warmup_callback)
1436 .Build();
1437
1438 std::ostringstream shaders_array_ostream;
1439 shaders_array_ostream << "[ ";
1440 for (auto it = shaders.begin(); it != shaders.end(); ++it) {
1441 shaders_array_ostream << "\"" << *it << "\"";
1442 if (std::next(it) != shaders.end()) {
1443 shaders_array_ostream << ", ";
1444 }
1445 }
1446 shaders_array_ostream << "]";
1447
1448 std::string shaders_array_string = shaders_array_ostream.str();
1449
1450 // Create initial view for testing.
1451 std::ostringstream warmup_shaders_ostream;
1452 warmup_shaders_ostream << "{" << " \"method\":\"WarmupSkps\","
1453 << " \"args\":{"
1454 << " \"shaders\":" << shaders_array_string << ","
1455 << " \"width\":" << width << ","
1456 << " \"height\":" << height << " }" << "}\n";
1457 std::string warmup_shaders_string = warmup_shaders_ostream.str();
1458
1460 new TestPlatformMessageResponse);
1461 static_cast<flutter::PlatformView*>(&platform_view)
1462 ->HandlePlatformMessage(std::make_unique<flutter::PlatformMessage>(
1463 "fuchsia/shader_warmup",
1464 fml::MallocMapping::Copy(warmup_shaders_string.c_str(),
1465 warmup_shaders_string.size()),
1466 response));
1467 RunLoopUntilIdle();
1468 ASSERT_TRUE(response->is_complete());
1469
1470 std::ostringstream expected_result_ostream;
1471 expected_result_ostream << "[" << shaders.size() << "]";
1472 std::string expected_result_string = expected_result_ostream.str();
1473 EXPECT_EQ(expected_result_string, response->result_string);
1474}
std::function< void(const std::vector< std::string > &, std::function< void(uint32_t)>, uint64_t, uint64_t)> OnShaderWarmupCallback
int32_t height
int32_t width

References fml::MallocMapping::Copy(), height, i, platform_view, and width.

◆ TEST_F() [32/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
RequestFocusDisposedTest   
)

Definition at line 1236 of file platform_view_unittest.cc.

1236 {
1237 MockPlatformViewDelegate delegate;
1238 flutter::TaskRunners task_runners =
1239 flutter::TaskRunners("test_runners", // label
1241 async_get_default_dispatcher()), // platform
1242 nullptr, // raster
1243 nullptr, // ui
1244 nullptr // io
1245 );
1246
1247 FakeFocuser focuser;
1248 fidl::BindingSet<fuchsia::ui::views::Focuser> focuser_bindings;
1249 auto focuser_handle = focuser_bindings.AddBinding(&focuser);
1250
1251 bool create_view_called = false;
1252 auto on_create_view = [&create_view_called, this](
1253 int64_t view_id,
1254 flutter_runner::ViewCallback on_view_created,
1256 bool hit_testable, bool focusable) {
1257 create_view_called = true;
1258 on_view_created();
1259 fuchsia::ui::composition::ContentId content_id;
1260 on_view_bound(std::move(content_id), MakeChildViewWatcher());
1261 };
1262
1263 bool destroy_view_called = false;
1264
1265 auto on_destroy_view = [&destroy_view_called](
1266 int64_t view_id,
1267 flutter_runner::ViewIdCallback on_view_unbound) {
1268 destroy_view_called = true;
1269 fuchsia::ui::composition::ContentId content_id;
1270 on_view_unbound(std::move(content_id));
1271 };
1272
1273 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
1274 .SetFocuser(std::move(focuser_handle))
1275 .SetCreateViewCallback(on_create_view)
1276 .SetDestroyViewCallback(on_destroy_view)
1277 .Build();
1278
1279 auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
1280 EXPECT_TRUE(base_view);
1281
1282 uint64_t view_id = 42;
1283
1284 // Create a new view
1285 std::ostringstream create_message;
1286 create_message << "{" << " \"method\":\"View.create\","
1287 << " \"args\": {" << " \"viewId\":" << view_id << ","
1288 << " \"hitTestable\":true,"
1289 << " \"focusable\":true" << " }" << "}";
1290
1291 auto create_response = FakePlatformMessageResponse::Create();
1292 base_view->HandlePlatformMessage(create_response->WithMessage(
1293 "flutter/platform_views", create_message.str()));
1294 RunLoopUntilIdle();
1295
1296 EXPECT_FALSE(destroy_view_called);
1297 // Dispose of the view
1298 std::ostringstream dispose_message;
1299 dispose_message << "{" << " \"method\":\"View.dispose\","
1300 << " \"args\": {" << " \"viewId\":" << view_id
1301 << " }" << "}";
1302
1303 auto dispose_response = FakePlatformMessageResponse::Create();
1304 base_view->HandlePlatformMessage(dispose_response->WithMessage(
1305 "flutter/platform_views", dispose_message.str()));
1306 RunLoopUntilIdle();
1307 EXPECT_TRUE(destroy_view_called);
1308
1309 // Request focus on newly disposed view
1310 std::ostringstream focus_message;
1311 focus_message << "{" << " \"method\":\"View.focus.requestById\","
1312 << " \"args\": {" << " \"viewId\":" << view_id
1313 << " }" << "}";
1314
1315 auto focus_response = FakePlatformMessageResponse::Create();
1316 base_view->HandlePlatformMessage(focus_response->WithMessage(
1317 "flutter/platform_views", focus_message.str()));
1318 RunLoopUntilIdle();
1319
1320 // Expect it to fail
1321 focus_response->ExpectCompleted("[1]");
1322 EXPECT_FALSE(focuser.request_focus_called());
1323}

References flutter_runner::testing::FakePlatformMessageResponse::Create(), flutter_runner::CreateFMLTaskRunner(), platform_view, flutter_runner::testing::FakeFocuser::request_focus_called(), and view_id.

◆ TEST_F() [33/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
RequestFocusNeverCreatedTest   
)

Definition at line 1184 of file platform_view_unittest.cc.

1184 {
1185 MockPlatformViewDelegate delegate;
1186 flutter::TaskRunners task_runners =
1187 flutter::TaskRunners("test_runners", // label
1189 async_get_default_dispatcher()), // platform
1190 nullptr, // raster
1191 nullptr, // ui
1192 nullptr // io
1193 );
1194
1195 FakeFocuser focuser;
1196 fidl::BindingSet<fuchsia::ui::views::Focuser> focuser_bindings;
1197 auto focuser_handle = focuser_bindings.AddBinding(&focuser);
1198
1199 bool create_view_called = false;
1200 auto on_create_view = [&create_view_called, this](
1201 int64_t view_id,
1202 flutter_runner::ViewCallback on_view_created,
1204 bool hit_testable, bool focusable) {
1205 create_view_called = true;
1206 on_view_created();
1207 fuchsia::ui::composition::ContentId content_id;
1208 on_view_bound(std::move(content_id), MakeChildViewWatcher());
1209 };
1210
1211 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
1212 .SetFocuser(std::move(focuser_handle))
1213 .SetCreateViewCallback(on_create_view)
1214 .Build();
1215
1216 auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
1217 EXPECT_TRUE(base_view);
1218
1219 uint64_t view_id = 42;
1220
1221 std::ostringstream focus_message;
1222 focus_message << "{" << " \"method\":\"View.focus.requestById\","
1223 << " \"args\": {" << " \"viewId\":" << view_id
1224 << " }" << "}";
1225
1226 // Dispatch the plaform message request.
1227 auto focus_response = FakePlatformMessageResponse::Create();
1228 base_view->HandlePlatformMessage(focus_response->WithMessage(
1229 "flutter/platform_views", focus_message.str()));
1230 RunLoopUntilIdle();
1231
1232 focus_response->ExpectCompleted("[1]");
1233 EXPECT_FALSE(focuser.request_focus_called());
1234}

References flutter_runner::testing::FakePlatformMessageResponse::Create(), flutter_runner::CreateFMLTaskRunner(), platform_view, flutter_runner::testing::FakeFocuser::request_focus_called(), and view_id.

◆ TEST_F() [34/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
RequestFocusTest   
)

Definition at line 1115 of file platform_view_unittest.cc.

1115 {
1116 MockPlatformViewDelegate delegate;
1117 flutter::TaskRunners task_runners =
1118 flutter::TaskRunners("test_runners", // label
1120 async_get_default_dispatcher()), // platform
1121 nullptr, // raster
1122 nullptr, // ui
1123 nullptr // io
1124 );
1125
1126 FakeFocuser focuser;
1127 fidl::BindingSet<fuchsia::ui::views::Focuser> focuser_bindings;
1128 auto focuser_handle = focuser_bindings.AddBinding(&focuser);
1129
1130 bool create_view_called = false;
1131 auto on_create_view = [&create_view_called, this](
1132 int64_t view_id,
1133 flutter_runner::ViewCallback on_view_created,
1135 bool hit_testable, bool focusable) {
1136 create_view_called = true;
1137 on_view_created();
1138 fuchsia::ui::composition::ContentId content_id;
1139 on_view_bound(std::move(content_id), MakeChildViewWatcher());
1140 };
1141
1142 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
1143 .SetFocuser(std::move(focuser_handle))
1144 .SetCreateViewCallback(on_create_view)
1145 .Build();
1146
1147 // Cast platform_view to its base view so we can have access to the public
1148 // "HandlePlatformMessage" function.
1149 auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
1150 EXPECT_TRUE(base_view);
1151
1152 uint64_t view_id = 42;
1153
1154 std::ostringstream create_message;
1155 create_message << "{" << " \"method\":\"View.create\","
1156 << " \"args\": {" << " \"viewId\":" << view_id << ","
1157 << " \"hitTestable\":true,"
1158 << " \"focusable\":true" << " }" << "}";
1159
1160 // Dispatch the plaform message request.
1161 auto create_response = FakePlatformMessageResponse::Create();
1162 base_view->HandlePlatformMessage(create_response->WithMessage(
1163 "flutter/platform_views", create_message.str()));
1164
1165 RunLoopUntilIdle();
1166
1167 // JSON for the message to be passed into the PlatformView.
1168 std::ostringstream focus_message;
1169 focus_message << "{" << " \"method\":\"View.focus.requestById\","
1170 << " \"args\": {" << " \"viewId\":" << view_id
1171 << " }" << "}";
1172
1173 // Dispatch the plaform message request.
1174 auto focus_response = FakePlatformMessageResponse::Create();
1175 base_view->HandlePlatformMessage(focus_response->WithMessage(
1176 "flutter/platform_views", focus_message.str()));
1177 RunLoopUntilIdle();
1178
1179 focus_response->ExpectCompleted("[0]");
1180 EXPECT_TRUE(focuser.request_focus_called());
1181}

References flutter_runner::testing::FakePlatformMessageResponse::Create(), flutter_runner::CreateFMLTaskRunner(), platform_view, flutter_runner::testing::FakeFocuser::request_focus_called(), and view_id.

◆ TEST_F() [35/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
SetViewportMetrics   
)

Definition at line 680 of file platform_view_unittest.cc.

680 {
681 constexpr float kDPR = 2;
682 constexpr uint32_t width = 640;
683 constexpr uint32_t height = 480;
684
685 MockPlatformViewDelegate delegate;
686 EXPECT_EQ(delegate.metrics(), flutter::ViewportMetrics());
687
688 MockParentViewportWatcher watcher;
689 flutter::TaskRunners task_runners("test_runners", nullptr, nullptr, nullptr,
690 nullptr);
691 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
692 .SetParentViewportWatcher(watcher.GetHandle())
693 .Build();
694 RunLoopUntilIdle();
695 EXPECT_EQ(delegate.metrics(), flutter::ViewportMetrics());
696
697 watcher.SetLayout(width, height, kDPR);
698 RunLoopUntilIdle();
699 EXPECT_EQ(delegate.metrics(),
700 flutter::ViewportMetrics(kDPR, std::round(width * kDPR),
701 std::round(height * kDPR), -1.0, 0));
702}

References height, platform_view, and width.

◆ TEST_F() [36/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
TouchSourceLogicalToPhysicalConversion   
)

Definition at line 1476 of file platform_view_unittest.cc.

1476 {
1477 constexpr uint32_t width = 640;
1478 constexpr uint32_t height = 480;
1479 constexpr std::array<std::array<float, 2>, 2> kRect = {
1480 {{0, 0}, {width, height}}};
1481 constexpr std::array<float, 9> kIdentity = {1, 0, 0, 0, 1, 0, 0, 0, 1};
1482 constexpr fuchsia::ui::pointer::TouchInteractionId kIxnOne = {
1483 .device_id = 0u, .pointer_id = 1u, .interaction_id = 2u};
1484
1485 MockPlatformViewDelegate delegate;
1486 flutter::TaskRunners task_runners("test_runners", nullptr, nullptr, nullptr,
1487 nullptr);
1488
1489 MockParentViewportWatcher viewport_watcher;
1490 FakeTouchSource touch_server;
1491 fidl::BindingSet<fuchsia::ui::pointer::TouchSource> touch_bindings;
1492 auto touch_handle = touch_bindings.AddBinding(&touch_server);
1493 auto platform_view =
1494 PlatformViewBuilder(delegate, std::move(task_runners))
1495 .SetParentViewportWatcher(viewport_watcher.GetHandle())
1496 .SetTouchSource(std::move(touch_handle))
1497 .Build();
1498 RunLoopUntilIdle();
1499 EXPECT_EQ(delegate.pointer_packets().size(), 0u);
1500
1501 viewport_watcher.SetLayout(width, height);
1502 RunLoopUntilIdle();
1503 EXPECT_EQ(delegate.metrics(),
1505
1506 // Inject
1507 std::vector<fuchsia::ui::pointer::TouchEvent> events =
1508 TouchEventBuilder::New()
1509 .AddTime(/* in nanoseconds */ 1111789u)
1510 .AddViewParameters(kRect, kRect, kIdentity)
1511 .AddSample(kIxnOne, fuchsia::ui::pointer::EventPhase::ADD,
1512 {width / 2, height / 2})
1513 .AddResult(
1514 {.interaction = kIxnOne,
1515 .status = fuchsia::ui::pointer::TouchInteractionStatus::GRANTED})
1516 .BuildAsVector();
1517 touch_server.ScheduleCallback(std::move(events));
1518 RunLoopUntilIdle();
1519
1520 // Unpack
1521 std::vector<std::unique_ptr<flutter::PointerDataPacket>> packets =
1522 delegate.TakePointerDataPackets();
1523 ASSERT_EQ(packets.size(), 1u);
1524 std::vector<flutter::PointerData> flutter_events;
1525 UnpackPointerPacket(flutter_events, std::move(packets[0]));
1526
1527 // Examine phases
1528 ASSERT_EQ(flutter_events.size(), 2u);
1529 EXPECT_EQ(flutter_events[0].change, flutter::PointerData::Change::kAdd);
1530 EXPECT_EQ(flutter_events[1].change, flutter::PointerData::Change::kDown);
1531
1532 // Examine coordinates
1533 EXPECT_EQ(flutter_events[0].physical_x, width / 2);
1534 EXPECT_EQ(flutter_events[0].physical_y, height / 2);
1535 EXPECT_EQ(flutter_events[1].physical_x, width / 2);
1536 EXPECT_EQ(flutter_events[1].physical_y, height / 2);
1537}
void UnpackPointerPacket(std::vector< PointerData > &output, std::unique_ptr< PointerDataPacket > packet)
constexpr std::array< std::array< float, 2 >, 2 > kRect
constexpr std::array< float, 9 > kIdentity
constexpr fup_TouchIxnId kIxnOne

References flutter_runner::testing::TouchEventBuilder::AddSample(), flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), height, flutter::PointerData::kAdd, flutter::PointerData::kDown, kIdentity, kIxnOne, kRect, flutter_runner::testing::TouchEventBuilder::New(), platform_view, flutter_runner::testing::FakeTouchSource::ScheduleCallback(), and width.

◆ TEST_F() [37/55]

flutter_runner::testing::TEST_F ( PlatformViewTests  ,
UpdateViewTest   
)

Definition at line 849 of file platform_view_unittest.cc.

849 {
850 MockPlatformViewDelegate delegate;
851 flutter::TaskRunners task_runners =
852 flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr);
853
854 std::optional<SkRect> occlusion_hint_for_test;
855 std::optional<bool> hit_testable_for_test;
856 std::optional<bool> focusable_for_test;
857 auto UpdateViewCallback = [&occlusion_hint_for_test, &hit_testable_for_test,
858 &focusable_for_test](
859 int64_t view_id, SkRect occlusion_hint,
860 bool hit_testable, bool focusable) {
861 occlusion_hint_for_test = occlusion_hint;
862 hit_testable_for_test = hit_testable;
863 focusable_for_test = focusable;
864 };
865
866 auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners))
867 .SetUpdateViewCallback(UpdateViewCallback)
868 .Build();
869
870 // Cast platform_view to its base view so we can have access to the public
871 // "HandlePlatformMessage" function.
872 auto base_view = static_cast<flutter::PlatformView*>(&platform_view);
873 EXPECT_TRUE(base_view);
874
875 // Send a basic message.
876 const uint8_t json[] =
877 "{"
878 " \"method\":\"View.update\","
879 " \"args\": {"
880 " \"viewId\":42,"
881 " \"hitTestable\":true,"
882 " \"focusable\":true"
883 " }"
884 "}";
885 std::unique_ptr<flutter::PlatformMessage> message =
886 std::make_unique<flutter::PlatformMessage>(
887 "flutter/platform_views",
888 fml::MallocMapping::Copy(json, sizeof(json)),
890 base_view->HandlePlatformMessage(std::move(message));
891
892 RunLoopUntilIdle();
893 ASSERT_TRUE(occlusion_hint_for_test.has_value());
894 ASSERT_TRUE(hit_testable_for_test.has_value());
895 ASSERT_TRUE(focusable_for_test.has_value());
896 EXPECT_EQ(occlusion_hint_for_test.value(), SkRect::MakeEmpty());
897 EXPECT_EQ(hit_testable_for_test.value(), true);
898 EXPECT_EQ(focusable_for_test.value(), true);
899
900 // Reset for the next message.
901 occlusion_hint_for_test.reset();
902 hit_testable_for_test.reset();
903 focusable_for_test.reset();
904
905 // Send another basic message.
906 const uint8_t json_false[] =
907 "{"
908 " \"method\":\"View.update\","
909 " \"args\": {"
910 " \"viewId\":42,"
911 " \"hitTestable\":false,"
912 " \"focusable\":false"
913 " }"
914 "}";
915 std::unique_ptr<flutter::PlatformMessage> message_false =
916 std::make_unique<flutter::PlatformMessage>(
917 "flutter/platform_views",
918 fml::MallocMapping::Copy(json_false, sizeof(json_false)),
920 base_view->HandlePlatformMessage(std::move(message_false));
921 RunLoopUntilIdle();
922 ASSERT_TRUE(occlusion_hint_for_test.has_value());
923 ASSERT_TRUE(hit_testable_for_test.has_value());
924 ASSERT_TRUE(focusable_for_test.has_value());
925 EXPECT_EQ(occlusion_hint_for_test.value(), SkRect::MakeEmpty());
926 EXPECT_EQ(hit_testable_for_test.value(), false);
927 EXPECT_EQ(focusable_for_test.value(), false);
928
929 // Reset for the next message.
930 occlusion_hint_for_test.reset();
931 hit_testable_for_test.reset();
932 focusable_for_test.reset();
933
934 // Send a message including an occlusion hint.
935 const uint8_t json_occlusion_hint[] =
936 "{"
937 " \"method\":\"View.update\","
938 " \"args\": {"
939 " \"viewId\":42,"
940 " \"hitTestable\":true,"
941 " \"focusable\":true,"
942 " \"viewOcclusionHintLTRB\":[0.1,0.2,0.3,0.4]"
943 " }"
944 "}";
945 std::unique_ptr<flutter::PlatformMessage> message_occlusion_hint =
946 std::make_unique<flutter::PlatformMessage>(
947 "flutter/platform_views",
948 fml::MallocMapping::Copy(json_occlusion_hint,
949 sizeof(json_occlusion_hint)),
951 base_view->HandlePlatformMessage(std::move(message_occlusion_hint));
952 RunLoopUntilIdle();
953 ASSERT_TRUE(occlusion_hint_for_test.has_value());
954 ASSERT_TRUE(hit_testable_for_test.has_value());
955 ASSERT_TRUE(focusable_for_test.has_value());
956 EXPECT_EQ(occlusion_hint_for_test.value(),
957 SkRect::MakeLTRB(0.1, 0.2, 0.3, 0.4));
958 EXPECT_EQ(hit_testable_for_test.value(), true);
959 EXPECT_EQ(focusable_for_test.value(), true);
960}

References fml::MallocMapping::Copy(), message, platform_view, and view_id.

◆ TEST_F() [38/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Coordinates_CorrectMapping   
)

Definition at line 187 of file pointer_delegate_unittests.cc.

187 {
188 std::optional<std::vector<flutter::PointerData>> pointers;
189 pointer_delegate_->WatchLoop(
190 [&pointers](std::vector<flutter::PointerData> events) {
191 pointers = std::move(events);
192 });
193 RunLoopUntilIdle(); // Server gets watch call.
194
195 // Fuchsia ADD event, with a view parameter that maps the viewport identically
196 // to the view. Then the center point of the viewport should map to the center
197 // of the view, (10.f, 10.f).
198 std::vector<fup_TouchEvent> events =
199 TouchEventBuilder::New()
200 .AddTime(2222000u)
201 .AddViewParameters(/*view*/ {{{0, 0}, {20, 20}}},
202 /*viewport*/ {{{0, 0}, {20, 20}}},
203 /*matrix*/ {1, 0, 0, 0, 1, 0, 0, 0, 1})
204 .AddSample(kIxnOne, fup_EventPhase::ADD, {10.f, 10.f})
205 .AddResult(
206 {.interaction = kIxnOne, .status = fup_TouchIxnStatus::GRANTED})
207 .BuildAsVector();
208 touch_source_->ScheduleCallback(std::move(events));
209 RunLoopUntilIdle();
210
211 ASSERT_TRUE(pointers.has_value());
212 ASSERT_EQ(pointers->size(), 2u); // ADD - DOWN
213 EXPECT_FLOAT_EQ((*pointers)[0].physical_x, 10.f);
214 EXPECT_FLOAT_EQ((*pointers)[0].physical_y, 10.f);
215 pointers = {};
216
217 // Fuchsia CHANGE event, with a view parameter that translates the viewport by
218 // (10, 10) within the view. Then the minimal point in the viewport (its
219 // origin) should map to the center of the view, (10.f, 10.f).
220 events = TouchEventBuilder::New()
221 .AddTime(2222000u)
222 .AddViewParameters(/*view*/ {{{0, 0}, {20, 20}}},
223 /*viewport*/ {{{0, 0}, {20, 20}}},
224 /*matrix*/ {1, 0, 0, 0, 1, 0, 10, 10, 1})
225 .AddSample(kIxnOne, fup_EventPhase::CHANGE, {0.f, 0.f})
226 .BuildAsVector();
227 touch_source_->ScheduleCallback(std::move(events));
228 RunLoopUntilIdle();
229
230 ASSERT_TRUE(pointers.has_value());
231 ASSERT_EQ(pointers->size(), 1u); // MOVE
232 EXPECT_FLOAT_EQ((*pointers)[0].physical_x, 10.f);
233 EXPECT_FLOAT_EQ((*pointers)[0].physical_y, 10.f);
234
235 // Fuchsia CHANGE event, with a view parameter that scales the viewport by
236 // (0.5, 0.5) within the view. Then the maximal point in the viewport should
237 // map to the center of the view, (10.f, 10.f).
238 events = TouchEventBuilder::New()
239 .AddTime(2222000u)
240 .AddViewParameters(/*view*/ {{{0, 0}, {20, 20}}},
241 /*viewport*/ {{{0, 0}, {20, 20}}},
242 /*matrix*/ {0.5f, 0, 0, 0, 0.5f, 0, 0, 0, 1})
243 .AddSample(kIxnOne, fup_EventPhase::CHANGE, {20.f, 20.f})
244 .BuildAsVector();
245 touch_source_->ScheduleCallback(std::move(events));
246 RunLoopUntilIdle();
247
248 ASSERT_TRUE(pointers.has_value());
249 ASSERT_EQ(pointers->size(), 1u); // MOVE
250 EXPECT_FLOAT_EQ((*pointers)[0].physical_x, 10.f);
251 EXPECT_FLOAT_EQ((*pointers)[0].physical_y, 10.f);
252}

References flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), kIxnOne, and flutter_runner::testing::TouchEventBuilder::New().

◆ TEST_F() [39/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Coordinates_DownEventClampedToView   
)

Definition at line 254 of file pointer_delegate_unittests.cc.

254 {
255 const float kSmallDiscrepancy = -0.00003f;
256
257 std::optional<std::vector<flutter::PointerData>> pointers;
258 pointer_delegate_->WatchLoop(
259 [&pointers](std::vector<flutter::PointerData> events) {
260 pointers = std::move(events);
261 });
262 RunLoopUntilIdle(); // Server gets watch call.
263
264 std::vector<fup_TouchEvent> events =
265 TouchEventBuilder::New()
266 .AddTime(1111000u)
267 .AddViewParameters(kRect, kRect, kIdentity)
268 .AddSample(kIxnOne, fup_EventPhase::ADD, {10.f, kSmallDiscrepancy})
269 .AddResult(
270 {.interaction = kIxnOne, .status = fup_TouchIxnStatus::GRANTED})
271 .BuildAsVector();
272 touch_source_->ScheduleCallback(std::move(events));
273 RunLoopUntilIdle();
274
275 ASSERT_TRUE(pointers.has_value());
276 ASSERT_EQ(pointers->size(), 2u);
277
278 const auto& add_event = (*pointers)[0];
279 EXPECT_FLOAT_EQ(add_event.physical_x, 10.f);
280 EXPECT_FLOAT_EQ(add_event.physical_y, kSmallDiscrepancy);
281
282 const auto& down_event = (*pointers)[1];
283 EXPECT_FLOAT_EQ(down_event.physical_x, 10.f);
284 EXPECT_EQ(down_event.physical_y, 0.f);
285}

References flutter_runner::testing::TouchEventBuilder::AddSample(), flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), kIdentity, kIxnOne, kRect, and flutter_runner::testing::TouchEventBuilder::New().

◆ TEST_F() [40/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Data_FuchsiaTimeVersusFlutterTime   
)

Definition at line 72 of file pointer_delegate_unittests.cc.

72 {
73 std::optional<std::vector<flutter::PointerData>> pointers;
74 pointer_delegate_->WatchLoop(
75 [&pointers](std::vector<flutter::PointerData> events) {
76 pointers = std::move(events);
77 });
78 RunLoopUntilIdle(); // Server gets watch call.
79
80 // Fuchsia ADD -> Flutter ADD+DOWN
81 std::vector<fup_TouchEvent> events =
82 TouchEventBuilder::New()
83 .AddTime(/* in nanoseconds */ 1111789u)
84 .AddViewParameters(kRect, kRect, kIdentity)
85 .AddSample(kIxnOne, fup_EventPhase::ADD, {10.f, 10.f})
86 .AddResult(
87 {.interaction = kIxnOne, .status = fup_TouchIxnStatus::GRANTED})
88 .BuildAsVector();
89 touch_source_->ScheduleCallback(std::move(events));
90 RunLoopUntilIdle();
91
92 ASSERT_TRUE(pointers.has_value());
93 ASSERT_EQ(pointers->size(), 2u);
94 EXPECT_EQ((*pointers)[0].time_stamp, /* in microseconds */ 1111u);
95 EXPECT_EQ((*pointers)[1].time_stamp, /* in microseconds */ 1111u);
96}

References flutter_runner::testing::TouchEventBuilder::AddSample(), flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), kIdentity, kIxnOne, kRect, and flutter_runner::testing::TouchEventBuilder::New().

◆ TEST_F() [41/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
MouseWheel_PixelBased   
)

Definition at line 738 of file pointer_delegate_unittests.cc.

738 {
739 std::optional<std::vector<flutter::PointerData>> pointers;
740 pointer_delegate_->WatchLoop(
741 [&pointers](std::vector<flutter::PointerData> events) {
742 pointers = std::move(events);
743 });
744 RunLoopUntilIdle(); // Server gets watch call.
745
746 std::vector<fup_MouseEvent> events =
747 MouseEventBuilder()
748 .AddTime(1111789u)
749 .AddViewParameters(kRect, kRect, kIdentity)
750 .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {0, 1}, {0, 120},
752 .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
753 .BuildAsVector();
754 mouse_source_->ScheduleCallback(std::move(events));
755 RunLoopUntilIdle();
756
757 ASSERT_TRUE(pointers.has_value());
758 ASSERT_EQ(pointers.value().size(), 1u);
759 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kHover);
760 EXPECT_EQ(pointers.value()[0].signal_kind,
762 EXPECT_EQ(pointers.value()[0].kind, flutter::PointerData::DeviceKind::kMouse);
763 EXPECT_EQ(pointers.value()[0].buttons, 0);
764 EXPECT_EQ(pointers.value()[0].scroll_delta_x, 0);
765 EXPECT_EQ(pointers.value()[0].scroll_delta_y, -120);
766 pointers = {};
767
768 // receive a horizontal scroll
769 events = MouseEventBuilder()
770 .AddTime(1111789u)
771 .AddViewParameters(kRect, kRect, kIdentity)
772 .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {1, 0}, {120, 0},
774 .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
775 .BuildAsVector();
776 mouse_source_->ScheduleCallback(std::move(events));
777 RunLoopUntilIdle();
778
779 ASSERT_TRUE(pointers.has_value());
780 ASSERT_EQ(pointers.value().size(), 1u);
781 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kHover);
782 EXPECT_EQ(pointers.value()[0].signal_kind,
784 EXPECT_EQ(pointers.value()[0].kind, flutter::PointerData::DeviceKind::kMouse);
785 EXPECT_EQ(pointers.value()[0].buttons, 0);
786 EXPECT_EQ(pointers.value()[0].scroll_delta_x, 120);
787 EXPECT_EQ(pointers.value()[0].scroll_delta_y, 0);
788 pointers = {};
789}

References flutter_runner::testing::MouseEventBuilder::AddSample(), flutter_runner::testing::MouseEventBuilder::AddTime(), flutter_runner::testing::MouseEventBuilder::AddViewParameters(), flutter::PointerData::kHover, kIdentity, flutter::PointerData::kMouse, kMouseDeviceId, kNotPrecisionScroll, kRect, and flutter::PointerData::kScroll.

◆ TEST_F() [42/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
MouseWheel_TickBased   
)

Definition at line 685 of file pointer_delegate_unittests.cc.

685 {
686 std::optional<std::vector<flutter::PointerData>> pointers;
687 pointer_delegate_->WatchLoop(
688 [&pointers](std::vector<flutter::PointerData> events) {
689 pointers = std::move(events);
690 });
691 RunLoopUntilIdle(); // Server gets watch call.
692
693 std::vector<fup_MouseEvent> events =
694 MouseEventBuilder()
695 .AddTime(1111789u)
696 .AddViewParameters(kRect, kRect, kIdentity)
697 .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {0, 1},
699 .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
700 .BuildAsVector();
701 mouse_source_->ScheduleCallback(std::move(events));
702 RunLoopUntilIdle();
703
704 ASSERT_TRUE(pointers.has_value());
705 ASSERT_EQ(pointers.value().size(), 1u);
706 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kHover);
707 EXPECT_EQ(pointers.value()[0].signal_kind,
709 EXPECT_EQ(pointers.value()[0].kind, flutter::PointerData::DeviceKind::kMouse);
710 EXPECT_EQ(pointers.value()[0].buttons, 0);
711 EXPECT_EQ(pointers.value()[0].scroll_delta_x, 0);
712 EXPECT_EQ(pointers.value()[0].scroll_delta_y, -20);
713 pointers = {};
714
715 // receive a horizontal scroll
716 events = MouseEventBuilder()
717 .AddTime(1111789u)
718 .AddViewParameters(kRect, kRect, kIdentity)
719 .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {1, 0},
721 .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
722 .BuildAsVector();
723 mouse_source_->ScheduleCallback(std::move(events));
724 RunLoopUntilIdle();
725
726 ASSERT_TRUE(pointers.has_value());
727 ASSERT_EQ(pointers.value().size(), 1u);
728 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kHover);
729 EXPECT_EQ(pointers.value()[0].signal_kind,
731 EXPECT_EQ(pointers.value()[0].kind, flutter::PointerData::DeviceKind::kMouse);
732 EXPECT_EQ(pointers.value()[0].buttons, 0);
733 EXPECT_EQ(pointers.value()[0].scroll_delta_x, 20);
734 EXPECT_EQ(pointers.value()[0].scroll_delta_y, 0);
735 pointers = {};
736}
constexpr std::array< int64_t, 2 > kNoScrollInPhysicalPixelDelta

References flutter_runner::testing::MouseEventBuilder::AddSample(), flutter_runner::testing::MouseEventBuilder::AddTime(), flutter_runner::testing::MouseEventBuilder::AddViewParameters(), flutter::PointerData::kHover, kIdentity, flutter::PointerData::kMouse, kMouseDeviceId, kNoScrollInPhysicalPixelDelta, kNotPrecisionScroll, kRect, and flutter::PointerData::kScroll.

◆ TEST_F() [43/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
MouseWheel_TouchpadPixelBased   
)

Definition at line 791 of file pointer_delegate_unittests.cc.

791 {
792 std::optional<std::vector<flutter::PointerData>> pointers;
793 pointer_delegate_->WatchLoop(
794 [&pointers](std::vector<flutter::PointerData> events) {
795 pointers = std::move(events);
796 });
797 RunLoopUntilIdle(); // Server gets watch call.
798
799 std::vector<fup_MouseEvent> events =
800 MouseEventBuilder()
801 .AddTime(1111789u)
802 .AddViewParameters(kRect, kRect, kIdentity)
803 .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {0, 1}, {0, 120},
805 .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
806 .BuildAsVector();
807 mouse_source_->ScheduleCallback(std::move(events));
808 RunLoopUntilIdle();
809
810 ASSERT_TRUE(pointers.has_value());
811 ASSERT_EQ(pointers.value().size(), 1u);
812 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kHover);
813 EXPECT_EQ(pointers.value()[0].signal_kind,
815 EXPECT_EQ(pointers.value()[0].kind, flutter::PointerData::DeviceKind::kMouse);
816 EXPECT_EQ(pointers.value()[0].buttons, 0);
817 EXPECT_EQ(pointers.value()[0].scroll_delta_x, 0);
818 EXPECT_EQ(pointers.value()[0].scroll_delta_y, -120);
819 pointers = {};
820
821 // receive a horizontal scroll
822 events = MouseEventBuilder()
823 .AddTime(1111789u)
824 .AddViewParameters(kRect, kRect, kIdentity)
825 .AddSample(kMouseDeviceId, {10.f, 10.f}, {}, {1, 0}, {120, 0},
827 .AddMouseDeviceInfo(kMouseDeviceId, {0, 1, 2})
828 .BuildAsVector();
829 mouse_source_->ScheduleCallback(std::move(events));
830 RunLoopUntilIdle();
831
832 ASSERT_TRUE(pointers.has_value());
833 ASSERT_EQ(pointers.value().size(), 1u);
834 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kHover);
835 EXPECT_EQ(pointers.value()[0].signal_kind,
837 EXPECT_EQ(pointers.value()[0].kind, flutter::PointerData::DeviceKind::kMouse);
838 EXPECT_EQ(pointers.value()[0].buttons, 0);
839 EXPECT_EQ(pointers.value()[0].scroll_delta_x, 120);
840 EXPECT_EQ(pointers.value()[0].scroll_delta_y, 0);
841 pointers = {};
842}

References flutter_runner::testing::MouseEventBuilder::AddSample(), flutter_runner::testing::MouseEventBuilder::AddTime(), flutter_runner::testing::MouseEventBuilder::AddViewParameters(), flutter::PointerData::kHover, kIdentity, flutter::PointerData::kMouse, kMouseDeviceId, kPrecisionScroll, kRect, and flutter::PointerData::kScroll.

◆ TEST_F() [44/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Phase_FlutterPhasesAreSynthesized   
)

Definition at line 98 of file pointer_delegate_unittests.cc.

98 {
99 std::optional<std::vector<flutter::PointerData>> pointers;
100 pointer_delegate_->WatchLoop(
101 [&pointers](std::vector<flutter::PointerData> events) {
102 pointers = std::move(events);
103 });
104 RunLoopUntilIdle(); // Server gets watch call.
105
106 // Fuchsia ADD -> Flutter ADD+DOWN
107 std::vector<fup_TouchEvent> events =
108 TouchEventBuilder::New()
109 .AddTime(1111000u)
110 .AddViewParameters(kRect, kRect, kIdentity)
111 .AddSample(kIxnOne, fup_EventPhase::ADD, {10.f, 10.f})
112 .AddResult(
113 {.interaction = kIxnOne, .status = fup_TouchIxnStatus::GRANTED})
114 .BuildAsVector();
115 touch_source_->ScheduleCallback(std::move(events));
116 RunLoopUntilIdle();
117
118 ASSERT_TRUE(pointers.has_value());
119 ASSERT_EQ(pointers->size(), 2u);
120 EXPECT_EQ((*pointers)[0].change, flutter::PointerData::Change::kAdd);
121 EXPECT_EQ((*pointers)[1].change, flutter::PointerData::Change::kDown);
122
123 // Fuchsia CHANGE -> Flutter MOVE
124 events = TouchEventBuilder::New()
125 .AddTime(2222000u)
126 .AddSample(kIxnOne, fup_EventPhase::CHANGE, {10.f, 10.f})
127 .BuildAsVector();
128 touch_source_->ScheduleCallback(std::move(events));
129 RunLoopUntilIdle();
130
131 ASSERT_TRUE(pointers.has_value());
132 ASSERT_EQ(pointers->size(), 1u);
133 EXPECT_EQ((*pointers)[0].change, flutter::PointerData::Change::kMove);
134
135 // Fuchsia REMOVE -> Flutter UP+REMOVE
136 events = TouchEventBuilder::New()
137 .AddTime(3333000u)
138 .AddSample(kIxnOne, fup_EventPhase::REMOVE, {10.f, 10.f})
139 .BuildAsVector();
140 touch_source_->ScheduleCallback(std::move(events));
141 RunLoopUntilIdle();
142
143 ASSERT_TRUE(pointers.has_value());
144 ASSERT_EQ(pointers->size(), 2u);
145 EXPECT_EQ((*pointers)[0].change, flutter::PointerData::Change::kUp);
146 EXPECT_EQ((*pointers)[1].change, flutter::PointerData::Change::kRemove);
147}

References flutter_runner::testing::TouchEventBuilder::AddSample(), flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), flutter::PointerData::kAdd, flutter::PointerData::kDown, kIdentity, kIxnOne, flutter::PointerData::kMove, kRect, flutter::PointerData::kRemove, flutter::PointerData::kUp, and flutter_runner::testing::TouchEventBuilder::New().

◆ TEST_F() [45/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Phase_FuchsiaCancelBecomesFlutterCancel   
)

Definition at line 149 of file pointer_delegate_unittests.cc.

149 {
150 std::optional<std::vector<flutter::PointerData>> pointers;
151 pointer_delegate_->WatchLoop(
152 [&pointers](std::vector<flutter::PointerData> events) {
153 pointers = std::move(events);
154 });
155 RunLoopUntilIdle(); // Server gets watch call.
156
157 // Fuchsia ADD -> Flutter ADD+DOWN
158 std::vector<fup_TouchEvent> events =
159 TouchEventBuilder::New()
160 .AddTime(1111000u)
161 .AddViewParameters(kRect, kRect, kIdentity)
162 .AddSample(kIxnOne, fup_EventPhase::ADD, {10.f, 10.f})
163 .AddResult(
164 {.interaction = kIxnOne, .status = fup_TouchIxnStatus::GRANTED})
165 .BuildAsVector();
166 touch_source_->ScheduleCallback(std::move(events));
167 RunLoopUntilIdle();
168
169 ASSERT_TRUE(pointers.has_value());
170 ASSERT_EQ(pointers->size(), 2u);
171 EXPECT_EQ((*pointers)[0].change, flutter::PointerData::Change::kAdd);
172 EXPECT_EQ((*pointers)[1].change, flutter::PointerData::Change::kDown);
173
174 // Fuchsia CANCEL -> Flutter CANCEL
175 events = TouchEventBuilder::New()
176 .AddTime(2222000u)
177 .AddSample(kIxnOne, fup_EventPhase::CANCEL, {10.f, 10.f})
178 .BuildAsVector();
179 touch_source_->ScheduleCallback(std::move(events));
180 RunLoopUntilIdle();
181
182 ASSERT_TRUE(pointers.has_value());
183 ASSERT_EQ(pointers->size(), 1u);
184 EXPECT_EQ((*pointers)[0].change, flutter::PointerData::Change::kCancel);
185}

References flutter_runner::testing::TouchEventBuilder::AddSample(), flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), flutter::PointerData::kAdd, flutter::PointerData::kCancel, flutter::PointerData::kDown, kIdentity, kIxnOne, kRect, and flutter_runner::testing::TouchEventBuilder::New().

◆ TEST_F() [46/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Protocol_EarlyGrant   
)

Definition at line 479 of file pointer_delegate_unittests.cc.

479 {
480 std::optional<std::vector<flutter::PointerData>> pointers;
481 pointer_delegate_->WatchLoop(
482 [&pointers](std::vector<flutter::PointerData> events) {
483 pointers = std::move(events);
484 });
485 RunLoopUntilIdle(); // Server gets watch call.
486
487 // Fuchsia ADD, with grant result - release immediately.
488 std::vector<fup_TouchEvent> events =
489 TouchEventBuilder::New()
490 .AddTime(1111000u)
491 .AddViewParameters(kRect, kRect, kIdentity)
492 .AddSample(kIxnOne, fup_EventPhase::ADD, {10.f, 10.f})
493 .AddResult({kIxnOne, fup_TouchIxnStatus::GRANTED})
494 .BuildAsVector();
495 touch_source_->ScheduleCallback(std::move(events));
496 RunLoopUntilIdle();
497
498 ASSERT_TRUE(pointers.has_value());
499 ASSERT_EQ(pointers.value().size(), 2u);
500 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kAdd);
501 EXPECT_EQ(pointers.value()[1].change, flutter::PointerData::Change::kDown);
502 pointers = {};
503
504 // Fuchsia CHANGE, after grant result - release immediately.
505 events = TouchEventBuilder::New()
506 .AddTime(2222000u)
507 .AddSample(kIxnOne, fup_EventPhase::CHANGE, {10.f, 10.f})
508 .BuildAsVector();
509 touch_source_->ScheduleCallback(std::move(events));
510 RunLoopUntilIdle();
511
512 ASSERT_TRUE(pointers.has_value());
513 ASSERT_EQ(pointers.value().size(), 1u);
514 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kMove);
515 pointers = {};
516}

References flutter_runner::testing::TouchEventBuilder::AddSample(), flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), flutter::PointerData::kAdd, flutter::PointerData::kDown, kIdentity, kIxnOne, flutter::PointerData::kMove, kRect, and flutter_runner::testing::TouchEventBuilder::New().

◆ TEST_F() [47/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Protocol_FirstResponseIsEmpty   
)

Definition at line 287 of file pointer_delegate_unittests.cc.

287 {
288 bool called = false;
289 pointer_delegate_->WatchLoop(
290 [&called](std::vector<flutter::PointerData> events) { called = true; });
291 RunLoopUntilIdle(); // Server gets Watch call.
292
293 EXPECT_FALSE(called); // No events yet received to forward to client.
294 // Server sees an initial "response" from client, which is empty, by contract.
295 const auto responses = touch_source_->UploadedResponses();
296 ASSERT_TRUE(responses.has_value());
297 ASSERT_EQ(responses->size(), 0u);
298}

◆ TEST_F() [48/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Protocol_LateDeny   
)

Definition at line 518 of file pointer_delegate_unittests.cc.

518 {
519 std::optional<std::vector<flutter::PointerData>> pointers;
520 pointer_delegate_->WatchLoop(
521 [&pointers](std::vector<flutter::PointerData> events) {
522 pointers = std::move(events);
523 });
524 RunLoopUntilIdle(); // Server gets watch call.
525
526 // Fuchsia ADD, no grant result - buffer it.
527 std::vector<fup_TouchEvent> events =
528 TouchEventBuilder::New()
529 .AddTime(1111000u)
530 .AddViewParameters(kRect, kRect, kIdentity)
531 .AddSample(kIxnOne, fup_EventPhase::ADD, {10.f, 10.f})
532 .BuildAsVector();
533 touch_source_->ScheduleCallback(std::move(events));
534 RunLoopUntilIdle();
535
536 ASSERT_TRUE(pointers.has_value());
537 EXPECT_EQ(pointers.value().size(), 0u);
538 pointers = {};
539
540 // Fuchsia CHANGE, no grant result - buffer it.
541 events = TouchEventBuilder::New()
542 .AddTime(2222000u)
543 .AddSample(kIxnOne, fup_EventPhase::CHANGE, {10.f, 10.f})
544 .BuildAsVector();
545 touch_source_->ScheduleCallback(std::move(events));
546 RunLoopUntilIdle();
547
548 ASSERT_TRUE(pointers.has_value());
549 EXPECT_EQ(pointers.value().size(), 0u);
550 pointers = {};
551
552 // Fuchsia result: ownership denied. Buffered pointers deleted.
553 events = TouchEventBuilder::New()
554 .AddTime(3333000u)
555 .AddResult({kIxnOne, fup_TouchIxnStatus::DENIED})
556 .BuildAsVector();
557 touch_source_->ScheduleCallback(std::move(events));
558 RunLoopUntilIdle();
559
560 ASSERT_TRUE(pointers.has_value());
561 ASSERT_EQ(pointers.value().size(), 0u); // Do not release to client!
562 pointers = {};
563}

References flutter_runner::testing::TouchEventBuilder::AddResult(), flutter_runner::testing::TouchEventBuilder::AddSample(), flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), kIdentity, kIxnOne, kRect, and flutter_runner::testing::TouchEventBuilder::New().

◆ TEST_F() [49/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Protocol_LateDenyCombo   
)

Definition at line 565 of file pointer_delegate_unittests.cc.

565 {
566 std::optional<std::vector<flutter::PointerData>> pointers;
567 pointer_delegate_->WatchLoop(
568 [&pointers](std::vector<flutter::PointerData> events) {
569 pointers = std::move(events);
570 });
571 RunLoopUntilIdle(); // Server gets watch call.
572
573 // Fuchsia ADD, no grant result - buffer it.
574 std::vector<fup_TouchEvent> events =
575 TouchEventBuilder::New()
576 .AddTime(1111000u)
577 .AddViewParameters(kRect, kRect, kIdentity)
578 .AddSample(kIxnOne, fup_EventPhase::ADD, {10.f, 10.f})
579 .BuildAsVector();
580 touch_source_->ScheduleCallback(std::move(events));
581 RunLoopUntilIdle();
582
583 ASSERT_TRUE(pointers.has_value());
584 EXPECT_EQ(pointers.value().size(), 0u);
585 pointers = {};
586
587 // Fuchsia CHANGE, no grant result - buffer it.
588 events = TouchEventBuilder::New()
589 .AddTime(2222000u)
590 .AddSample(kIxnOne, fup_EventPhase::CHANGE, {10.f, 10.f})
591 .BuildAsVector();
592 touch_source_->ScheduleCallback(std::move(events));
593 RunLoopUntilIdle();
594
595 ASSERT_TRUE(pointers.has_value());
596 EXPECT_EQ(pointers.value().size(), 0u);
597 pointers = {};
598
599 // Fuchsia result: ownership denied. Buffered pointers deleted.
600 events = TouchEventBuilder::New()
601 .AddTime(3333000u)
602 .AddSample(kIxnOne, fup_EventPhase::CANCEL, {10.f, 10.f})
603 .AddResult({kIxnOne, fup_TouchIxnStatus::DENIED})
604 .BuildAsVector();
605 touch_source_->ScheduleCallback(std::move(events));
606 RunLoopUntilIdle();
607
608 ASSERT_TRUE(pointers.has_value());
609 ASSERT_EQ(pointers.value().size(), 0u); // Do not release to client!
610 pointers = {};
611}

References flutter_runner::testing::TouchEventBuilder::AddSample(), flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), kIdentity, kIxnOne, kRect, and flutter_runner::testing::TouchEventBuilder::New().

◆ TEST_F() [50/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Protocol_LateGrant   
)

Definition at line 359 of file pointer_delegate_unittests.cc.

359 {
360 std::optional<std::vector<flutter::PointerData>> pointers;
361 pointer_delegate_->WatchLoop(
362 [&pointers](std::vector<flutter::PointerData> events) {
363 pointers = std::move(events);
364 });
365 RunLoopUntilIdle(); // Server gets watch call.
366
367 // Fuchsia ADD, no grant result - buffer it.
368 std::vector<fup_TouchEvent> events =
369 TouchEventBuilder::New()
370 .AddTime(1111000u)
371 .AddViewParameters(kRect, kRect, kIdentity)
372 .AddSample(kIxnOne, fup_EventPhase::ADD, {10.f, 10.f})
373 .BuildAsVector();
374 touch_source_->ScheduleCallback(std::move(events));
375 RunLoopUntilIdle();
376
377 ASSERT_TRUE(pointers.has_value());
378 EXPECT_EQ(pointers.value().size(), 0u);
379 pointers = {};
380
381 // Fuchsia CHANGE, no grant result - buffer it.
382 events = TouchEventBuilder::New()
383 .AddTime(2222000u)
384 .AddSample(kIxnOne, fup_EventPhase::CHANGE, {10.f, 10.f})
385 .BuildAsVector();
386 touch_source_->ScheduleCallback(std::move(events));
387 RunLoopUntilIdle();
388
389 ASSERT_TRUE(pointers.has_value());
390 EXPECT_EQ(pointers.value().size(), 0u);
391 pointers = {};
392
393 // Fuchsia result: ownership granted. Buffered pointers released.
394 events = TouchEventBuilder::New()
395 .AddTime(3333000u)
396 .AddResult({kIxnOne, fup_TouchIxnStatus::GRANTED})
397 .BuildAsVector();
398 touch_source_->ScheduleCallback(std::move(events));
399 RunLoopUntilIdle();
400
401 ASSERT_TRUE(pointers.has_value());
402 ASSERT_EQ(pointers.value().size(), 3u); // ADD - DOWN - MOVE
403 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kAdd);
404 EXPECT_EQ(pointers.value()[1].change, flutter::PointerData::Change::kDown);
405 EXPECT_EQ(pointers.value()[2].change, flutter::PointerData::Change::kMove);
406 pointers = {};
407
408 // Fuchsia CHANGE, grant result - release immediately.
409 events = TouchEventBuilder::New()
410 .AddTime(/* in nanoseconds */ 4444000u)
411 .AddSample(kIxnOne, fup_EventPhase::CHANGE, {10.f, 10.f})
412 .BuildAsVector();
413 touch_source_->ScheduleCallback(std::move(events));
414 RunLoopUntilIdle();
415
416 ASSERT_TRUE(pointers.has_value());
417 ASSERT_EQ(pointers.value().size(), 1u);
418 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kMove);
419 EXPECT_EQ(pointers.value()[0].time_stamp, /* in microseconds */ 4444u);
420 pointers = {};
421}

References flutter_runner::testing::TouchEventBuilder::AddResult(), flutter_runner::testing::TouchEventBuilder::AddSample(), flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), flutter::PointerData::kAdd, flutter::PointerData::kDown, kIdentity, kIxnOne, flutter::PointerData::kMove, kRect, and flutter_runner::testing::TouchEventBuilder::New().

◆ TEST_F() [51/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Protocol_LateGrantCombo   
)

Definition at line 423 of file pointer_delegate_unittests.cc.

423 {
424 std::optional<std::vector<flutter::PointerData>> pointers;
425 pointer_delegate_->WatchLoop(
426 [&pointers](std::vector<flutter::PointerData> events) {
427 pointers = std::move(events);
428 });
429 RunLoopUntilIdle(); // Server gets watch call.
430
431 // Fuchsia ADD, no grant result - buffer it.
432 std::vector<fup_TouchEvent> events =
433 TouchEventBuilder::New()
434 .AddTime(1111000u)
435 .AddViewParameters(kRect, kRect, kIdentity)
436 .AddSample(kIxnOne, fup_EventPhase::ADD, {10.f, 10.f})
437 .BuildAsVector();
438 touch_source_->ScheduleCallback(std::move(events));
439 RunLoopUntilIdle();
440
441 ASSERT_TRUE(pointers.has_value());
442 EXPECT_EQ(pointers.value().size(), 0u);
443 pointers = {};
444
445 // Fuchsia CHANGE, no grant result - buffer it.
446 events = TouchEventBuilder::New()
447 .AddTime(2222000u)
448 .AddSample(kIxnOne, fup_EventPhase::CHANGE, {10.f, 10.f})
449 .BuildAsVector();
450 touch_source_->ScheduleCallback(std::move(events));
451 RunLoopUntilIdle();
452
453 ASSERT_TRUE(pointers.has_value());
454 EXPECT_EQ(pointers.value().size(), 0u);
455 pointers = {};
456
457 // Fuchsia CHANGE, with grant result - release buffered events.
458 events = TouchEventBuilder::New()
459 .AddTime(3333000u)
460 .AddSample(kIxnOne, fup_EventPhase::CHANGE, {10.f, 10.f})
461 .AddResult({kIxnOne, fup_TouchIxnStatus::GRANTED})
462 .BuildAsVector();
463 touch_source_->ScheduleCallback(std::move(events));
464 RunLoopUntilIdle();
465
466 ASSERT_TRUE(pointers.has_value());
467 ASSERT_EQ(pointers.value().size(), 4u); // ADD - DOWN - MOVE - MOVE
468 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kAdd);
469 EXPECT_EQ(pointers.value()[0].time_stamp, 1111u);
470 EXPECT_EQ(pointers.value()[1].change, flutter::PointerData::Change::kDown);
471 EXPECT_EQ(pointers.value()[1].time_stamp, 1111u);
472 EXPECT_EQ(pointers.value()[2].change, flutter::PointerData::Change::kMove);
473 EXPECT_EQ(pointers.value()[2].time_stamp, 2222u);
474 EXPECT_EQ(pointers.value()[3].change, flutter::PointerData::Change::kMove);
475 EXPECT_EQ(pointers.value()[3].time_stamp, 3333u);
476 pointers = {};
477}

References flutter_runner::testing::TouchEventBuilder::AddSample(), flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), flutter::PointerData::kAdd, flutter::PointerData::kDown, kIdentity, kIxnOne, flutter::PointerData::kMove, kRect, and flutter_runner::testing::TouchEventBuilder::New().

◆ TEST_F() [52/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Protocol_PointersAreIndependent   
)

Definition at line 613 of file pointer_delegate_unittests.cc.

613 {
614 std::optional<std::vector<flutter::PointerData>> pointers;
615 pointer_delegate_->WatchLoop(
616 [&pointers](std::vector<flutter::PointerData> events) {
617 pointers = std::move(events);
618 });
619 RunLoopUntilIdle(); // Server gets watch call.
620
621 constexpr fup_TouchIxnId kIxnTwo = {
622 .device_id = 1u, .pointer_id = 2u, .interaction_id = 2u};
623
624 // Fuchsia ptr1 ADD and ptr2 ADD, no grant result for either - buffer them.
625 std::vector<fup_TouchEvent> events =
626 TouchEventBuilder::New()
627 .AddTime(1111000u)
628 .AddViewParameters(kRect, kRect, kIdentity)
629 .AddSample(kIxnOne, fup_EventPhase::ADD, {10.f, 10.f})
630 .BuildAsVector();
631 fup_TouchEvent ptr2 =
632 TouchEventBuilder::New()
633 .AddTime(1111000u)
634 .AddSample(kIxnTwo, fup_EventPhase::ADD, {15.f, 15.f})
635 .Build();
636 events.emplace_back(std::move(ptr2));
637 touch_source_->ScheduleCallback(std::move(events));
638 RunLoopUntilIdle();
639
640 ASSERT_TRUE(pointers.has_value());
641 EXPECT_EQ(pointers.value().size(), 0u);
642 pointers = {};
643
644 // Server grants win to pointer 2.
645 events = TouchEventBuilder::New()
646 .AddTime(2222000u)
647 .AddResult({kIxnTwo, fup_TouchIxnStatus::GRANTED})
648 .BuildAsVector();
649 touch_source_->ScheduleCallback(std::move(events));
650 RunLoopUntilIdle();
651
652 // Note: Fuchsia's device and pointer IDs (both 32 bit) are coerced together
653 // to fit in Flutter's 64-bit device ID. However, Flutter's pointer_identifier
654 // is not set by platform runner code - PointerDataCaptureConverter (PDPC)
655 // sets it.
656 ASSERT_TRUE(pointers.has_value());
657 ASSERT_EQ(pointers.value().size(), 2u);
658 EXPECT_EQ(pointers.value()[0].pointer_identifier, 0); // reserved for PDPC
659 EXPECT_EQ(pointers.value()[0].device, (int64_t)((1ul << 32) | 2u));
660 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kAdd);
661 EXPECT_EQ(pointers.value()[1].pointer_identifier, 0); // reserved for PDPC
662 EXPECT_EQ(pointers.value()[1].device, (int64_t)((1ul << 32) | 2u));
663 EXPECT_EQ(pointers.value()[1].change, flutter::PointerData::Change::kDown);
664 pointers = {};
665
666 // Server grants win to pointer 1.
667 events = TouchEventBuilder::New()
668 .AddTime(3333000u)
669 .AddResult({kIxnOne, fup_TouchIxnStatus::GRANTED})
670 .BuildAsVector();
671 touch_source_->ScheduleCallback(std::move(events));
672 RunLoopUntilIdle();
673
674 ASSERT_TRUE(pointers.has_value());
675 ASSERT_EQ(pointers.value().size(), 2u);
676 EXPECT_EQ(pointers.value()[0].pointer_identifier, 0); // reserved for PDPC
677 EXPECT_EQ(pointers.value()[0].device, (int64_t)((1ul << 32) | 1u));
678 EXPECT_EQ(pointers.value()[0].change, flutter::PointerData::Change::kAdd);
679 EXPECT_EQ(pointers.value()[1].pointer_identifier, 0); // reserved for PDPC
680 EXPECT_EQ(pointers.value()[1].device, (int64_t)((1ul << 32) | 1u));
681 EXPECT_EQ(pointers.value()[1].change, flutter::PointerData::Change::kDown);
682 pointers = {};
683}
fuchsia::ui::pointer::TouchEvent fup_TouchEvent

References flutter_runner::testing::TouchEventBuilder::AddResult(), flutter_runner::testing::TouchEventBuilder::AddSample(), flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), flutter::PointerData::kAdd, flutter::PointerData::kDown, kIdentity, kIxnOne, kRect, and flutter_runner::testing::TouchEventBuilder::New().

◆ TEST_F() [53/55]

flutter_runner::testing::TEST_F ( PointerDelegateTest  ,
Protocol_ResponseMatchesEarlierEvents   
)

Definition at line 300 of file pointer_delegate_unittests.cc.

300 {
301 std::optional<std::vector<flutter::PointerData>> pointers;
302 pointer_delegate_->WatchLoop(
303 [&pointers](std::vector<flutter::PointerData> events) {
304 pointers = std::move(events);
305 });
306 RunLoopUntilIdle(); // Server gets watch call.
307
308 // Fuchsia view parameter only. Empty response.
309 std::vector<fup_TouchEvent> events =
310 TouchEventBuilder::New()
311 .AddTime(1111000u)
312 .AddViewParameters(kRect, kRect, kIdentity)
313 .BuildAsVector();
314
315 // Fuchsia ptr 1 ADD sample. Yes response.
317 TouchEventBuilder::New()
318 .AddTime(1111000u)
319 .AddViewParameters(kRect, kRect, kIdentity)
320 .AddSample({.device_id = 0u, .pointer_id = 1u, .interaction_id = 3u},
321 fup_EventPhase::ADD, {10.f, 10.f})
322 .Build();
323 events.emplace_back(std::move(e1));
324
325 // Fuchsia ptr 2 ADD sample. Yes response.
327 TouchEventBuilder::New()
328 .AddTime(1111000u)
329 .AddSample({.device_id = 0u, .pointer_id = 2u, .interaction_id = 3u},
330 fup_EventPhase::ADD, {5.f, 5.f})
331 .Build();
332 events.emplace_back(std::move(e2));
333
334 // Fuchsia ptr 3 ADD sample. Yes response.
336 TouchEventBuilder::New()
337 .AddTime(1111000u)
338 .AddSample({.device_id = 0u, .pointer_id = 3u, .interaction_id = 3u},
339 fup_EventPhase::ADD, {1.f, 1.f})
340 .Build();
341 events.emplace_back(std::move(e3));
342 touch_source_->ScheduleCallback(std::move(events));
343 RunLoopUntilIdle();
344
345 const auto responses = touch_source_->UploadedResponses();
346 ASSERT_TRUE(responses.has_value());
347 ASSERT_EQ(responses.value().size(), 4u);
348 // Event 0 did not carry a sample, so no response.
349 EXPECT_FALSE(responses.value()[0].has_response_type());
350 // Events 1-3 had a sample, must have a response.
351 EXPECT_TRUE(responses.value()[1].has_response_type());
352 EXPECT_EQ(responses.value()[1].response_type(), fup_TouchResponseType::YES);
353 EXPECT_TRUE(responses.value()[2].has_response_type());
354 EXPECT_EQ(responses.value()[2].response_type(), fup_TouchResponseType::YES);
355 EXPECT_TRUE(responses.value()[3].has_response_type());
356 EXPECT_EQ(responses.value()[3].response_type(), fup_TouchResponseType::YES);
357}
Vector3 e3
Vector3 e2
Vector3 e1

References flutter_runner::testing::TouchEventBuilder::AddSample(), flutter_runner::testing::TouchEventBuilder::AddTime(), flutter_runner::testing::TouchEventBuilder::AddViewParameters(), flutter_runner::testing::TouchEventBuilder::BuildAsVector(), e1, e2, e3, kIdentity, kRect, and flutter_runner::testing::TouchEventBuilder::New().

◆ TEST_F() [54/55]

flutter_runner::testing::TEST_F ( TextDelegateTest  ,
ActivateIme   
)

Definition at line 139 of file text_delegate_unittests.cc.

139 {
140 auto fake_platform_message_response = FakePlatformMessageResponse::Create();
141 {
142 // Initialize the editor. Without this initialization, the protocol code
143 // will crash.
144 const auto set_client_msg = R"(
145 {
146 "method": "TextInput.setClient",
147 "args": [
148 7,
149 {
150 "inputType": {
151 "name": "TextInputType.multiline",
152 "signed":null,
153 "decimal":null
154 },
155 "readOnly": false,
156 "obscureText": false,
157 "autocorrect":true,
158 "smartDashesType":"1",
159 "smartQuotesType":"1",
160 "enableSuggestions":true,
161 "enableInteractiveSelection":true,
162 "actionLabel":null,
163 "inputAction":"TextInputAction.newline",
164 "textCapitalization":"TextCapitalization.none",
165 "keyboardAppearance":"Brightness.dark",
166 "enableIMEPersonalizedLearning":true,
167 "enableDeltaModel":false
168 }
169 ]
170 }
171 )";
172 auto message = fake_platform_message_response->WithMessage(
173 kTextInputChannel, set_client_msg);
174 text_delegate_->HandleFlutterTextInputChannelPlatformMessage(
175 std::move(message));
176 RunLoopUntilIdle();
177 EXPECT_EQ(ime_service_.action_,
178 fuchsia::ui::input::InputMethodAction::NEWLINE);
179 EXPECT_FALSE(ime_service_.IsKeyboardShown());
180 }
181
182 {
183 // Verify that showing keyboard results in the correct platform effect.
184 const auto set_client_msg = R"(
185 {
186 "method": "TextInput.show"
187 }
188 )";
189 auto message = fake_platform_message_response->WithMessage(
190 kTextInputChannel, set_client_msg);
191 text_delegate_->HandleFlutterTextInputChannelPlatformMessage(
192 std::move(message));
193 RunLoopUntilIdle();
194 EXPECT_TRUE(ime_service_.IsKeyboardShown());
195 }
196
197 {
198 // Verify that hiding keyboard results in the correct platform effect.
199 const auto set_client_msg = R"(
200 {
201 "method": "TextInput.hide"
202 }
203 )";
204 auto message = fake_platform_message_response->WithMessage(
205 kTextInputChannel, set_client_msg);
206 text_delegate_->HandleFlutterTextInputChannelPlatformMessage(
207 std::move(message));
208 RunLoopUntilIdle();
209 EXPECT_FALSE(ime_service_.IsKeyboardShown());
210 }
211
212 {
213 // Update the editing state from the Fuchsia platform side.
214 fuchsia::ui::input::TextInputState state = {
215 .revision = 42,
216 .text = "Foo",
217 .selection = fuchsia::ui::input::TextSelection{},
218 .composing = fuchsia::ui::input::TextRange{},
219 };
220 auto input_event = std::make_unique<fuchsia::ui::input::InputEvent>();
221 ime_service_.client_->DidUpdateState(std::move(state),
222 std::move(input_event));
223 RunLoopUntilIdle();
224 EXPECT_EQ(
225 R"({"method":"TextInputClient.updateEditingState","args":[7,{"text":"Foo","selectionBase":0,"selectionExtent":0,"selectionAffinity":"TextAffinity.upstream","selectionIsDirectional":true,"composingBase":-1,"composingExtent":-1}]})",
226 MessageToString(*last_message_));
227 }
228
229 {
230 // Notify Flutter that the action key has been pressed.
231 ime_service_.client_->OnAction(fuchsia::ui::input::InputMethodAction::DONE);
232 RunLoopUntilIdle();
233 EXPECT_EQ(
234 R"({"method":"TextInputClient.performAction","args":[7,"TextInputAction.done"]})",
235 MessageToString(*last_message_));
236 }
237}
static NSString *const kTextInputChannel
static std::string MessageToString(PlatformMessage &message)

References flutter_runner::testing::FakePlatformMessageResponse::Create(), flutter_runner::kTextInputChannel, message, and MessageToString().

◆ TEST_F() [55/55]

flutter_runner::testing::TEST_F ( TextDelegateTest  ,
OnAction   
)

Definition at line 242 of file text_delegate_unittests.cc.

242 {
243 {
244 // A sensible key event is converted into a platform message.
245 fuchsia::ui::input3::KeyEvent key_event;
246 *key_event.mutable_type() = fuchsia::ui::input3::KeyEventType::PRESSED;
247 *key_event.mutable_key() = fuchsia::input::Key::A;
248 key_event.mutable_key_meaning()->set_codepoint('a');
249
250 fuchsia::ui::input3::KeyEventStatus status;
251 keyboard_service_.listener_->OnKeyEvent(
252 std::move(key_event), [&status](fuchsia::ui::input3::KeyEventStatus s) {
253 status = std::move(s);
254 });
255 RunLoopUntilIdle();
256 EXPECT_EQ(fuchsia::ui::input3::KeyEventStatus::HANDLED, status);
257 EXPECT_EQ(
258 R"({"type":"keydown","keymap":"fuchsia","hidUsage":458756,"codePoint":97,"modifiers":0})",
259 MessageToString(*last_message_));
260 }
261
262 {
263 // SYNC event is not handled.
264 // This is currently expected, though we may need to change that behavior.
265 fuchsia::ui::input3::KeyEvent key_event;
266 *key_event.mutable_type() = fuchsia::ui::input3::KeyEventType::SYNC;
267
268 fuchsia::ui::input3::KeyEventStatus status;
269 keyboard_service_.listener_->OnKeyEvent(
270 std::move(key_event), [&status](fuchsia::ui::input3::KeyEventStatus s) {
271 status = std::move(s);
272 });
273 RunLoopUntilIdle();
274 EXPECT_EQ(fuchsia::ui::input3::KeyEventStatus::NOT_HANDLED, status);
275 }
276
277 {
278 // CANCEL event is not handled.
279 // This is currently expected, though we may need to change that behavior.
280 fuchsia::ui::input3::KeyEvent key_event;
281 *key_event.mutable_type() = fuchsia::ui::input3::KeyEventType::CANCEL;
282
283 fuchsia::ui::input3::KeyEventStatus status;
284 keyboard_service_.listener_->OnKeyEvent(
285 std::move(key_event), [&status](fuchsia::ui::input3::KeyEventStatus s) {
286 status = std::move(s);
287 });
288 RunLoopUntilIdle();
289 EXPECT_EQ(fuchsia::ui::input3::KeyEventStatus::NOT_HANDLED, status);
290 }
291}
FlutterKeyEvent key_event

References key_event, and MessageToString().

◆ TEST_P() [1/8]

flutter_runner::testing::TEST_P ( PointerInjectorDelegateTest  ,
DestroyedViewsDontGetPointerEvents   
)

Definition at line 569 of file pointer_injector_delegate_unittest.cc.

569 {
570 const uint64_t view_id = 1, num_events = 150;
571
572 fuchsia::ui::views::ViewRefControl view_ref_control;
573 fuchsia::ui::views::ViewRef view_ref;
574 auto status = zx::eventpair::create(
575 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
576 ZX_ASSERT(status == ZX_OK);
577 view_ref_control.reference.replace(
578 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
579 &view_ref_control.reference);
580 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
581
582 // Create the view.
583 CreateView(view_id);
584
585 // Inject |num_events| platform messages.
586 for (size_t i = 0; i < num_events; i++) {
587 auto response = FakePlatformMessageResponse::Create();
588
589 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
590 PlatformMessageBuilder().SetViewId(view_id).Build(), response));
591
592 response->ExpectCompleted("[0]");
593 }
594
595 // Destroy the view.
596 pointer_injector_delegate_->OnDestroyView(view_id);
597
598 // The view does not receive |num_events| pointer events as it gets destroyed
599 // before all the pointer events could be dispatched.
600 const zx::duration timeout = zx::sec(1), step = zx::msec(10);
601 EXPECT_FALSE(RunLoopWithTimeoutOrUntil(
602 [this] { return registry_->num_events_received() == num_events; },
603 timeout, step));
604
605 EXPECT_LT(registry_->num_events_received(), num_events);
606}

References i, and view_id.

◆ TEST_P() [2/8]

flutter_runner::testing::TEST_P ( PointerInjectorDelegateTest  ,
DeviceRetriesRegisterWhenClosed   
)

Definition at line 668 of file pointer_injector_delegate_unittest.cc.

668 {
669 const uint64_t view_id = 1;
670 const int pointer_id = 1;
671 fuchsia::ui::views::ViewRefControl view_ref_control;
672 fuchsia::ui::views::ViewRef view_ref;
673 auto status = zx::eventpair::create(
674 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
675 ZX_ASSERT(status == ZX_OK);
676 view_ref_control.reference.replace(
677 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
678 &view_ref_control.reference);
679 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
680
681 auto response = FakePlatformMessageResponse::Create();
682 auto response_2 = FakePlatformMessageResponse::Create();
683
684 // Create the view.
685 fuv_ViewRef view_ref_clone;
686 fidl::Clone(view_ref, &view_ref_clone);
687 CreateView(view_id, std::move(view_ref_clone));
688
689 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
690 PlatformMessageBuilder()
691 .SetViewId(view_id)
692 .SetPointerId(pointer_id)
693 .Build(),
694 response));
695
696 response->ExpectCompleted("[0]");
697
698 // The mock Pointerinjector registry server receives a pointer event from
699 // |f.u.p.Device.Inject| call for the view.
700 RunLoopUntil([this] { return registry_->num_events_received() == 1; });
701
702 // The mock Pointerinjector registry server receives a
703 // |f.u.p.Registry.Register| call for the view.
704 ASSERT_TRUE(registry_->num_register_calls() == 1);
705
706 // Close the device channel.
707 registry_->ClearBindings();
708 RunLoopUntilIdle();
709
710 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
711 PlatformMessageBuilder()
712 .SetViewId(view_id)
713 .SetPointerId(pointer_id)
714 .Build(),
715 response_2));
716
717 response_2->ExpectCompleted("[0]");
718
719 // The mock Pointerinjector registry server receives a pointer event from
720 // |f.u.p.Device.Inject| call for the view.
721 RunLoopUntil([this] { return registry_->num_events_received() == 2; });
722
723 // The device tries to register again as the channel got closed.
724 ASSERT_TRUE(registry_->num_register_calls() == 2);
725}

References view_id.

◆ TEST_P() [3/8]

flutter_runner::testing::TEST_P ( PointerInjectorDelegateTest  ,
IncorrectPlatformMessage_ShouldFail   
)

Definition at line 255 of file pointer_injector_delegate_unittest.cc.

255 {
256 const uint64_t view_id = 1;
257
258 // Create a view.
259 CreateView(view_id);
260
261 // A platform message in incorrect JSON format should fail.
262 {
263 auto response = FakePlatformMessageResponse::Create();
264
265 EXPECT_FALSE(pointer_injector_delegate_->HandlePlatformMessage(
266 ParsePlatformMessage("{Incorrect Json}"), response));
267 }
268
269 // |PointerInjectorDelegate| only handles "View.Pointerinjector.inject"
270 // platform messages.
271 {
272 auto response = FakePlatformMessageResponse::Create();
273
274 EXPECT_FALSE(pointer_injector_delegate_->HandlePlatformMessage(
275 ParsePlatformMessage("{\"method\":\"View.focus.getCurrent\"}"),
276 response));
277 }
278
279 // A platform message with no args should fail.
280 {
281 auto response = FakePlatformMessageResponse::Create();
282
283 EXPECT_FALSE(pointer_injector_delegate_->HandlePlatformMessage(
284 ParsePlatformMessage("{\"method\":\"View.Pointerinjector.inject\"}"),
285 response));
286 }
287}

References ParsePlatformMessage(), and view_id.

◆ TEST_P() [4/8]

flutter_runner::testing::TEST_P ( PointerInjectorDelegateTest  ,
ValidPointerEventTest   
)

Definition at line 495 of file pointer_injector_delegate_unittest.cc.

495 {
496 const uint64_t view_id = 1;
497
498 const float x = 2.f, y = 2.f, width = 5.f, height = 5.f;
499 const int phase = 2, pointer_id = 5, trace_flow_id = 5, timestamp = 10;
500
501 auto response = FakePlatformMessageResponse::Create();
502
503 fuchsia::ui::views::ViewRefControl view_ref_control;
504 fuchsia::ui::views::ViewRef view_ref;
505 auto status = zx::eventpair::create(
506 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
507 ZX_ASSERT(status == ZX_OK);
508 view_ref_control.reference.replace(
509 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
510 &view_ref_control.reference);
511 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
512
513 // Create the view.
514 fuv_ViewRef view_ref_clone;
515 fidl::Clone(view_ref, &view_ref_clone);
516 CreateView(view_id, std::move(view_ref_clone));
517
518 // Inject a platform message.
519 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
520 PlatformMessageBuilder()
521 .SetViewId(view_id)
522 .SetPointerX(x)
523 .SetPointerY(y)
524 .SetPhase(phase)
525 .SetPointerId(pointer_id)
526 .SetTraceFlowId(trace_flow_id)
527 .SetLogicalWidth(width)
528 .SetLogicalHeight(height)
529 .SetTimestamp(timestamp)
530 .Build(),
531 response));
532
533 response->ExpectCompleted("[0]");
534
535 // The mock Pointerinjector registry server receives a pointer event from
536 // |f.u.p.Device.Inject| call for the view.
537 RunLoopUntil([this] { return registry_->num_events_received() == 1; });
538
539 // The mock Pointerinjector registry server receives a
540 // |f.u.p.Registry.Register| call for the view.
541 ASSERT_TRUE(registry_->num_register_calls() == 1);
542
543 const auto& events = registry_->events();
544
545 ASSERT_EQ(events.size(), 1u);
546
547 const auto& event = events[0];
548
549 ASSERT_TRUE(event.has_timestamp());
550 EXPECT_EQ(event.timestamp(), timestamp);
551
552 ASSERT_TRUE(event.has_trace_flow_id());
553 EXPECT_EQ(event.trace_flow_id(), static_cast<uint64_t>(trace_flow_id));
554
555 ASSERT_TRUE(event.has_data());
556 ASSERT_TRUE(event.data().is_pointer_sample());
557
558 const auto& pointer_sample = event.data().pointer_sample();
559
560 ASSERT_TRUE(pointer_sample.has_pointer_id());
561 ASSERT_TRUE(pointer_sample.has_phase());
562 ASSERT_TRUE(pointer_sample.has_position_in_viewport());
563 EXPECT_EQ(pointer_sample.pointer_id(), static_cast<uint32_t>(pointer_id));
564 EXPECT_EQ(pointer_sample.phase(), static_cast<fup_EventPhase>(phase));
565 EXPECT_THAT(pointer_sample.position_in_viewport(),
566 ::testing::ElementsAre(x, y));
567}
int32_t x
double y
fuchsia::ui::pointer::EventPhase fup_EventPhase

References height, view_id, width, x, and y.

◆ TEST_P() [5/8]

flutter_runner::testing::TEST_P ( PointerInjectorDelegateTest  ,
ValidRegistrationConfigTest   
)

Definition at line 417 of file pointer_injector_delegate_unittest.cc.

417 {
418 const uint64_t view_id = 1;
419
420 const float x = 2.f, y = 2.f, width = 5.f, height = 5.f;
421 const int phase = 2, pointer_id = 5, trace_flow_id = 5, timestamp = 10;
422
423 auto response = FakePlatformMessageResponse::Create();
424
425 fuchsia::ui::views::ViewRefControl view_ref_control;
426 fuchsia::ui::views::ViewRef view_ref;
427 auto status = zx::eventpair::create(
428 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
429 ZX_ASSERT(status == ZX_OK);
430 view_ref_control.reference.replace(
431 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
432 &view_ref_control.reference);
433 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
434
435 // Create the view.
436 fuv_ViewRef view_ref_clone;
437 fidl::Clone(view_ref, &view_ref_clone);
438 CreateView(view_id, std::move(view_ref_clone));
439
440 // Inject a platform message.
441 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
442 PlatformMessageBuilder()
443 .SetViewId(view_id)
444 .SetPointerX(x)
445 .SetPointerY(y)
446 .SetPhase(phase)
447 .SetPointerId(pointer_id)
448 .SetTraceFlowId(trace_flow_id)
449 .SetLogicalWidth(width)
450 .SetLogicalHeight(height)
451 .SetTimestamp(timestamp)
452 .Build(),
453 response));
454
455 response->ExpectCompleted("[0]");
456
457 // The mock Pointerinjector registry server receives a pointer event from
458 // |f.u.p.Device.Inject| call for the view.
459 RunLoopUntil([this] { return registry_->num_events_received() == 1; });
460
461 // The mock Pointerinjector registry server receives a
462 // |f.u.p.Registry.Register| call for the view.
463 ASSERT_TRUE(registry_->num_register_calls() == 1);
464
465 const auto& config = registry_->config();
466
467 ASSERT_TRUE(config.has_device_id());
468 EXPECT_EQ(config.device_id(), 1u);
469
470 ASSERT_TRUE(config.has_device_type());
471 EXPECT_EQ(config.device_type(), fup_DeviceType::TOUCH);
472
473 ASSERT_TRUE(config.has_dispatch_policy());
474 EXPECT_EQ(config.dispatch_policy(), fup_DispatchPolicy::EXCLUSIVE_TARGET);
475
476 ASSERT_TRUE(config.has_context());
477 ASSERT_TRUE(config.context().is_view());
478 EXPECT_EQ(ExtractKoid(config.context().view()), ExtractKoid(host_view_ref_));
479
480 ASSERT_TRUE(config.has_target());
481 ASSERT_TRUE(config.target().is_view());
482 EXPECT_EQ(ExtractKoid(config.target().view()), ExtractKoid(view_ref));
483
484 ASSERT_TRUE(config.has_viewport());
485 ASSERT_TRUE(config.viewport().has_viewport_to_context_transform());
486 EXPECT_EQ(config.viewport().viewport_to_context_transform(), kIdentityMatrix);
487
488 std::array<std::array<float, 2>, 2> extents{{{0, 0}, {width, height}}};
489 ASSERT_TRUE(config.viewport().has_extents());
490 EXPECT_EQ(config.viewport().extents(), extents);
491}

References height, view_id, width, x, and y.

◆ TEST_P() [6/8]

flutter_runner::testing::TEST_P ( PointerInjectorDelegateTest  ,
ViewsDontReceivePointerEventsBeforeCreation   
)

Definition at line 354 of file pointer_injector_delegate_unittest.cc.

355 {
356 const uint64_t num_events = 150;
357 const uint64_t view_id_1 = 1;
358
359 // Inject |num_events| platform messages for |view_id_1|.
360 {
361 fuchsia::ui::views::ViewRefControl view_ref_control;
362 fuchsia::ui::views::ViewRef view_ref;
363 auto status = zx::eventpair::create(
364 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
365 ASSERT_EQ(status, ZX_OK);
366 view_ref_control.reference.replace(
367 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
368 &view_ref_control.reference);
369 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
370
371 for (size_t i = 0; i < num_events; i++) {
372 auto response = FakePlatformMessageResponse::Create();
373
374 // The platform message is *silently* accepted for non-existent views, in
375 // order to cleanly handle the lifecycle case where the child view is
376 // forcibly killed. By doing so, products avoid "MissingPluginException"
377 // log spam.
378 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
379 PlatformMessageBuilder().SetViewId(view_id_1).Build(), response));
380 }
381 }
382
383 const uint64_t view_id_2 = 2;
384
385 // Inject |num_events| platform messages for |view_id_2|.
386 {
387 fuchsia::ui::views::ViewRefControl view_ref_control;
388 fuchsia::ui::views::ViewRef view_ref;
389 auto status = zx::eventpair::create(
390 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
391 ASSERT_EQ(status, ZX_OK);
392 view_ref_control.reference.replace(
393 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
394 &view_ref_control.reference);
395 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
396
397 for (size_t i = 0; i < num_events; i++) {
398 auto response = FakePlatformMessageResponse::Create();
399
400 // The platform message is *silently* accepted for non-existent views, in
401 // order to cleanly handle the lifecycle case where the child view is
402 // forcibly killed. By doing so, products avoid "MissingPluginException"
403 // log spam.
404 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
405 PlatformMessageBuilder().SetViewId(view_id_2).Build(), response));
406 }
407 }
408
409 RunLoopUntilIdle();
410
411 // The views do not receive any pointer events till they get created.
412 EXPECT_TRUE(registry_->num_events_received() == 0);
413}

References i.

◆ TEST_P() [7/8]

flutter_runner::testing::TEST_P ( PointerInjectorDelegateTest  ,
ViewsGetPointerEventsInFIFO   
)

Definition at line 608 of file pointer_injector_delegate_unittest.cc.

608 {
609 const uint64_t view_id = 1, num_events = 150;
610
611 fuchsia::ui::views::ViewRefControl view_ref_control;
612 fuchsia::ui::views::ViewRef view_ref;
613 auto status = zx::eventpair::create(
614 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
615 ZX_ASSERT(status == ZX_OK);
616 view_ref_control.reference.replace(
617 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
618 &view_ref_control.reference);
619 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
620
621 // Create the view.
622 CreateView(view_id);
623
624 // Inject |num_events| platform messages.
625 for (size_t i = 0; i < num_events; i++) {
626 auto response = FakePlatformMessageResponse::Create();
627
628 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
629 PlatformMessageBuilder()
630 .SetViewId(view_id)
631 .SetPointerId(static_cast<uint32_t>(i))
632 .Build(),
633 response));
634
635 response->ExpectCompleted("[0]");
636 }
637
638 // The mock Pointerinjector registry server receives |num_events| pointer
639 // events from |f.u.p.Device.Inject| call for the view.
640 RunLoopUntil(
641 [this] { return registry_->num_events_received() == num_events; });
642
643 // The mock Pointerinjector registry server receives a
644 // |f.u.p.Registry.Register| call for the view.
645 ASSERT_TRUE(registry_->num_register_calls() == 1);
646
647 auto& events = registry_->events();
648
649 // The view should receive the pointer events in a FIFO order. As we injected
650 // platform messages with an increasing |pointer_id|, the received pointer
651 // events should also have the |pointer_id| in an increasing order.
652 for (size_t i = 0; i < events.size() - 1; i++) {
653 ASSERT_TRUE(events[i].has_data());
654 ASSERT_TRUE(events[i + 1].has_data());
655 ASSERT_TRUE(events[i].data().is_pointer_sample());
656 ASSERT_TRUE(events[i + 1].data().is_pointer_sample());
657
658 const auto& pointer_sample_1 = events[i].data().pointer_sample();
659 const auto& pointer_sample_2 = events[i + 1].data().pointer_sample();
660
661 ASSERT_TRUE(pointer_sample_1.has_pointer_id());
662 ASSERT_TRUE(pointer_sample_2.has_pointer_id());
663
664 EXPECT_TRUE(pointer_sample_1.pointer_id() < pointer_sample_2.pointer_id());
665 }
666}

References data, i, and view_id.

◆ TEST_P() [8/8]

flutter_runner::testing::TEST_P ( PointerInjectorDelegateTest  ,
ViewsReceiveInjectedEvents   
)

Definition at line 289 of file pointer_injector_delegate_unittest.cc.

289 {
290 const uint64_t num_events = 150;
291
292 // Inject |num_events| platform messages for view 1.
293 {
294 const uint64_t view_id = 1;
295
296 CreateView(view_id);
297
298 fuchsia::ui::views::ViewRefControl view_ref_control;
299 fuchsia::ui::views::ViewRef view_ref;
300 auto status = zx::eventpair::create(
301 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
302 ASSERT_EQ(status, ZX_OK);
303 view_ref_control.reference.replace(
304 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
305 &view_ref_control.reference);
306 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
307
308 for (size_t i = 0; i < num_events; i++) {
309 auto response = FakePlatformMessageResponse::Create();
310
311 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
312 PlatformMessageBuilder().SetViewId(view_id).Build(), response));
313
314 response->ExpectCompleted("[0]");
315 }
316 }
317
318 // Inject |num_events| platform messages for view 2.
319 {
320 const uint64_t view_id = 2;
321
322 CreateView(view_id);
323
324 fuchsia::ui::views::ViewRefControl view_ref_control;
325 fuchsia::ui::views::ViewRef view_ref;
326 auto status = zx::eventpair::create(
327 /*options*/ 0u, &view_ref_control.reference, &view_ref.reference);
328 ASSERT_EQ(status, ZX_OK);
329 view_ref_control.reference.replace(
330 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
331 &view_ref_control.reference);
332 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
333
334 for (size_t i = 0; i < num_events; i++) {
335 auto response = FakePlatformMessageResponse::Create();
336
337 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
338 PlatformMessageBuilder().SetViewId(view_id).Build(), response));
339
340 response->ExpectCompleted("[0]");
341 }
342 }
343
344 // The mock Pointerinjector registry server receives |num_events| pointer
345 // events from |f.u.p.Device.Inject| calls for each view.
346 RunLoopUntil(
347 [this] { return registry_->num_events_received() == 2 * num_events; });
348
349 // The mock Pointerinjector registry server receives a
350 // |f.u.p.Registry.Register| call for each view.
351 EXPECT_TRUE(registry_->num_register_calls() == 2);
352}

References i, and view_id.

◆ WaitAll()

void flutter_runner::testing::WaitAll ( std::vector< zx::event > *  fences)

Definition at line 525 of file flatland_connection_unittests.cc.

525 {
526 for (auto& fence : *fences) {
527 zx_signals_t ignored;
528 // Maybe the timeout here should be finite.
529 const auto status =
530 fence.wait_one(ZX_EVENT_SIGNALED, zx::time::infinite(), &ignored);
531 ASSERT_EQ(status, ZX_OK);
532 }
533}

Referenced by TEST_F().

Variable Documentation

◆ kIdentity

constexpr std::array<float, 9> flutter_runner::testing::kIdentity = {1, 0, 0, 0, 1, 0, 0, 0, 1}
constexpr

Definition at line 36 of file pointer_delegate_unittests.cc.

36{1, 0, 0, 0, 1, 0, 0, 0, 1};

Referenced by TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().

◆ kInfiniteHitRegion

constexpr fuchsia::ui::composition::HitRegion flutter_runner::testing::kInfiniteHitRegion
staticconstexpr
Initial value:
= {
.region = {-FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX}}

Definition at line 152 of file fake_flatland_types.h.

152 {
153 .region = {-FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX}};

◆ kInvalidContentId

constexpr fuchsia::ui::composition::ContentId flutter_runner::testing::kInvalidContentId {0}
staticconstexpr

Definition at line 151 of file fake_flatland_types.h.

151{0};

◆ kInvalidTransformId

constexpr fuchsia::ui::composition::TransformId flutter_runner::testing::kInvalidTransformId {0}
staticconstexpr

Definition at line 150 of file fake_flatland_types.h.

150{0};

◆ kIxnOne

constexpr fup_TouchIxnId flutter_runner::testing::kIxnOne
constexpr
Initial value:
= {.device_id = 1u,
.pointer_id = 1u,
.interaction_id = 2u}

Definition at line 37 of file pointer_delegate_unittests.cc.

37 {.device_id = 1u,
38 .pointer_id = 1u,
39 .interaction_id = 2u};

Referenced by TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().

◆ kMouseDeviceId

constexpr uint32_t flutter_runner::testing::kMouseDeviceId = 123
constexpr

Definition at line 41 of file pointer_delegate_unittests.cc.

Referenced by TEST_F(), TEST_F(), and TEST_F().

◆ kNoScrollInPhysicalPixelDelta

constexpr std::array<int64_t, 2> flutter_runner::testing::kNoScrollInPhysicalPixelDelta = {0, 0}
constexpr

Definition at line 42 of file pointer_delegate_unittests.cc.

42{0, 0};

Referenced by TEST_F().

◆ kNotPrecisionScroll

const bool flutter_runner::testing::kNotPrecisionScroll = false

Definition at line 43 of file pointer_delegate_unittests.cc.

Referenced by TEST_F(), and TEST_F().

◆ kPrecisionScroll

const bool flutter_runner::testing::kPrecisionScroll = true

Definition at line 44 of file pointer_delegate_unittests.cc.

Referenced by TEST_F().

◆ kRect

constexpr std::array<std::array<float, 2>, 2> flutter_runner::testing::kRect = {{{0, 0}, {20, 20}}}
constexpr

Definition at line 35 of file pointer_delegate_unittests.cc.

35{{{0, 0}, {20, 20}}};

Referenced by TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().