| Flutter Impeller |

toolkit_android_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "flutter/fml/synchronization/waitable_event.h"
6 #include "flutter/testing/testing.h"
7 #include "impeller/toolkit/android/choreographer.h"
8 #include "impeller/toolkit/android/hardware_buffer.h"
9 #include "impeller/toolkit/android/proc_table.h"
10 #include "impeller/toolkit/android/shadow_realm.h"
11 #include "impeller/toolkit/android/surface_control.h"
12 #include "impeller/toolkit/android/surface_transaction.h"
13
14 namespace impeller::android::testing {
15
16 #define DISABLE_ANDROID_PROC(name) \
17 struct Disable##name { \
18 Disable##name() { \
19 real_proc = GetMutableProcTable().name.proc; \
20 GetMutableProcTable().name.proc = nullptr; \
21 } \
22 ~Disable##name() { \
23 GetMutableProcTable().name.proc = real_proc; \
24 } \
25 decltype(name)* real_proc; \
26 } disable##name;
27
28 TEST(ToolkitAndroidTest, CanCreateProcTable) {
29 ProcTable proc_table;
30 ASSERT_TRUE(proc_table.IsValid());
31 }
32
33 TEST(ToolkitAndroidTest, GuardsAgainstZeroSizedDescriptors) {
34 auto desc = HardwareBufferDescriptor::MakeForSwapchainImage({0, 0});
35 ASSERT_GT(desc.size.width, 0u);
36 ASSERT_GT(desc.size.height, 0u);
37 }
38
39 TEST(ToolkitAndroidTest, CanCreateHardwareBuffer) {
40 if (!HardwareBuffer::IsAvailableOnPlatform()) {
41 GTEST_SKIP() << "Hardware buffers are not supported on this platform.";
42 }
43 ASSERT_TRUE(HardwareBuffer::IsAvailableOnPlatform());
44 auto desc = HardwareBufferDescriptor::MakeForSwapchainImage({100, 100});
45 ASSERT_TRUE(desc.IsAllocatable());
46 HardwareBuffer buffer(desc);
47 ASSERT_TRUE(buffer.IsValid());
48 }
49
50 TEST(ToolkitAndroidTest, CanGetHardwareBufferIDs) {
51 if (!HardwareBuffer::IsAvailableOnPlatform()) {
52 GTEST_SKIP() << "Hardware buffers are not supported on this platform.";
53 }
54 ASSERT_TRUE(HardwareBuffer::IsAvailableOnPlatform());
55 if (!GetProcTable().AHardwareBuffer_getId.IsAvailable()) {
56 GTEST_SKIP() << "Hardware buffer IDs are not available on this platform.";
57 }
58 auto desc = HardwareBufferDescriptor::MakeForSwapchainImage({100, 100});
59 ASSERT_TRUE(desc.IsAllocatable());
60 HardwareBuffer buffer(desc);
61 ASSERT_TRUE(buffer.IsValid());
62 ASSERT_TRUE(buffer.GetSystemUniqueID().has_value());
63 }
64
65 TEST(ToolkitAndroidTest, HardwareBufferNullIDIfAPIUnavailable) {
66 DISABLE_ANDROID_PROC(AHardwareBuffer_getId);
67 ASSERT_FALSE(HardwareBuffer::GetSystemUniqueID(nullptr).has_value());
68 }
69
70 TEST(ToolkitAndroidTest, CanDescribeHardwareBufferHandles) {
71 if (!HardwareBuffer::IsAvailableOnPlatform()) {
72 GTEST_SKIP() << "Hardware buffers are not supported on this platform.";
73 }
74 ASSERT_TRUE(HardwareBuffer::IsAvailableOnPlatform());
75 auto desc = HardwareBufferDescriptor::MakeForSwapchainImage({100, 100});
76 ASSERT_TRUE(desc.IsAllocatable());
77 HardwareBuffer buffer(desc);
78 ASSERT_TRUE(buffer.IsValid());
79 auto a_desc = HardwareBuffer::Describe(buffer.GetHandle());
80 ASSERT_TRUE(a_desc.has_value());
81 ASSERT_EQ(a_desc->width, 100u); // NOLINT
82 ASSERT_EQ(a_desc->height, 100u); // NOLINT
83 }
84
85 TEST(ToolkitAndroidTest, CanApplySurfaceTransaction) {
86 if (!SurfaceTransaction::IsAvailableOnPlatform()) {
87 GTEST_SKIP() << "Surface controls are not supported on this platform.";
88 }
89 ASSERT_TRUE(SurfaceTransaction::IsAvailableOnPlatform());
90 SurfaceTransaction transaction;
91 ASSERT_TRUE(transaction.IsValid());
92 fml::AutoResetWaitableEvent event;
93 ASSERT_TRUE(transaction.Apply([&event](auto) { event.Signal(); }));
94 event.Wait();
95 }
96
97 TEST(ToolkitAndroidTest, SurfacControlsAreAvailable) {
98 if (!SurfaceControl::IsAvailableOnPlatform()) {
99 GTEST_SKIP() << "Surface controls are not supported on this platform.";
100 }
101 ASSERT_TRUE(SurfaceControl::IsAvailableOnPlatform());
102 }
103
104 TEST(ToolkitAndroidTest, ChoreographerIsAvailable) {
105 if (!Choreographer::IsAvailableOnPlatform()) {
106 GTEST_SKIP() << "Choreographer is not supported on this platform.";
107 }
108 ASSERT_TRUE(Choreographer::IsAvailableOnPlatform());
109 }
110
111 TEST(ToolkitAndroidTest, CanPostAndNotWaitForFrameCallbacks) {
112 if (!Choreographer::IsAvailableOnPlatform()) {
113 GTEST_SKIP() << "Choreographer is not supported on this platform.";
114 }
115 const auto& choreographer = Choreographer::GetInstance();
116 ASSERT_TRUE(choreographer.IsValid());
117 ASSERT_TRUE(choreographer.PostFrameCallback([](auto) {}));
118 }
119
120 TEST(ToolkitAndroidTest, CanPostAndWaitForFrameCallbacks) {
121 if (!Choreographer::IsAvailableOnPlatform()) {
122 GTEST_SKIP() << "Choreographer is not supported on this platform.";
123 }
124 if ((true)) {
125 GTEST_SKIP()
126 << "Disabled till the test harness is in an Android activity. "
127 "Running it without one will hang because the choreographer "
128 "frame callback will never execute.";
129 }
130 const auto& choreographer = Choreographer::GetInstance();
131 ASSERT_TRUE(choreographer.IsValid());
132 fml::AutoResetWaitableEvent event;
133 ASSERT_TRUE(choreographer.PostFrameCallback(
134 [&event](auto point) { event.Signal(); }));
135 event.Wait();
136 }
137
138 TEST(ToolkitAndroidTest, ShouldDisableAHB) {
139 EXPECT_FALSE(
140 ShadowRealm::ShouldDisableAHBInternal("android-huawei", "30", 30));
141 EXPECT_FALSE(
142 ShadowRealm::ShouldDisableAHBInternal("something made up", "29", 29));
143
144 EXPECT_TRUE(
145 ShadowRealm::ShouldDisableAHBInternal("android-huawei", "29", 29));
146 EXPECT_TRUE(
147 ShadowRealm::ShouldDisableAHBInternal("something made up", "27", 29));
148 EXPECT_TRUE(
149 ShadowRealm::ShouldDisableAHBInternal("android-huawei", "garbage", 29));
150 }
151
152 } // namespace impeller::android::testing
hardware_buffer.h
impeller::android::HardwareBuffer::IsAvailableOnPlatform
static bool IsAvailableOnPlatform()
Definition: hardware_buffer.cc:107
impeller::android::SurfaceTransaction
A wrapper for ASurfaceTransaction. https://developer.android.com/ndk/reference/group/native-activity#...
Definition: surface_transaction.h:35
impeller::android::HardwareBuffer::GetSystemUniqueID
std::optional< uint64_t > GetSystemUniqueID() const
Get the system wide unique ID of the hardware buffer if possible. This is only available on Android A...
Definition: hardware_buffer.cc:111
impeller::android::SurfaceControl::IsAvailableOnPlatform
static bool IsAvailableOnPlatform()
Definition: surface_control.cc:50
proc_table.h
surface_control.h
impeller::android::testing::TEST
TEST(ToolkitAndroidTest, CanCreateProcTable)
Definition: toolkit_android_unittests.cc:28
DISABLE_ANDROID_PROC
#define DISABLE_ANDROID_PROC(name)
Definition: toolkit_android_unittests.cc:16
impeller::android::testing
Definition: toolkit_android_unittests.cc:14
impeller::android::Choreographer::IsAvailableOnPlatform
static bool IsAvailableOnPlatform()
Definition: choreographer.cc:78
impeller::android::HardwareBufferDescriptor::MakeForSwapchainImage
static HardwareBufferDescriptor MakeForSwapchainImage(const ISize &size)
Create a descriptor of the given size that is suitable for use as a swapchain image.
Definition: hardware_buffer.cc:87
impeller::android::ShadowRealm::ShouldDisableAHBInternal
static bool ShouldDisableAHBInternal(std::string_view clientidbase, std::string_view first_api_level, uint32_t api_level)
Definition: shadow_realm.cc:25
impeller::android::Choreographer::GetInstance
static Choreographer & GetInstance()
Create or get the thread local instance of a choreographer. A message loop will be setup on the calli...
Definition: choreographer.cc:11
impeller::android::HardwareBuffer
A wrapper for AHardwareBuffer https://developer.android.com/ndk/reference/group/a-hardware-buffer.
Definition: hardware_buffer.h:95
impeller::android::SurfaceTransaction::Apply
bool Apply(OnCompleteCallback callback=nullptr)
Applies the updated encoded in the transaction and invokes the callback when the updated are complete...
Definition: surface_transaction.cc:26
impeller::android::ProcTable::IsValid
bool IsValid() const
If a valid proc table could be setup. This may fail in case of setup on non-Android platforms.
Definition: proc_table.cc:65
impeller::android::SurfaceTransaction::IsValid
bool IsValid() const
Definition: surface_transaction.cc:18
impeller::android::HardwareBuffer::GetHandle
AHardwareBuffer * GetHandle() const
Definition: hardware_buffer.cc:83
choreographer.h
surface_transaction.h
impeller::android::HardwareBuffer::Describe
static std::optional< AHardwareBuffer_Desc > Describe(AHardwareBuffer *buffer)
Definition: hardware_buffer.cc:127
shadow_realm.h
impeller::android::GetProcTable
const ProcTable & GetProcTable()
Definition: proc_table.cc:12
impeller::android::HardwareBuffer::IsValid
bool IsValid() const
Definition: hardware_buffer.cc:79
impeller::android::SurfaceTransaction::IsAvailableOnPlatform
static bool IsAvailableOnPlatform()
Definition: surface_transaction.cc:102
impeller::android::ProcTable
The table of Android procs that are resolved dynamically.
Definition: proc_table.h:93