1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 // TODO(b/129481165): remove the #pragma below and fix conversion issues
20 #pragma clang diagnostic push
21 #pragma clang diagnostic ignored "-Wconversion"
22 #pragma clang diagnostic ignored "-Wextra"
23 
24 #include <type_traits>
25 #include "DisplayIdentificationTest.h"
26 
27 #include <binder/IPCThreadState.h>
28 #include <compositionengine/Display.h>
29 #include <compositionengine/DisplayColorProfile.h>
30 #include <compositionengine/impl/Display.h>
31 #include <compositionengine/impl/OutputCompositionState.h>
32 #include <compositionengine/mock/Display.h>
33 #include <compositionengine/mock/DisplayColorProfile.h>
34 #include <compositionengine/mock/DisplaySurface.h>
35 #include <compositionengine/mock/RenderSurface.h>
36 #include <gmock/gmock.h>
37 #include <gtest/gtest.h>
38 #include <gui/mock/GraphicBufferConsumer.h>
39 #include <gui/mock/GraphicBufferProducer.h>
40 #include <log/log.h>
41 #include <private/android_filesystem_config.h>
42 #include <renderengine/mock/RenderEngine.h>
43 #include <ui/DebugUtils.h>
44 
45 #include "TestableScheduler.h"
46 #include "TestableSurfaceFlinger.h"
47 #include "mock/DisplayHardware/MockComposer.h"
48 #include "mock/DisplayHardware/MockPowerAdvisor.h"
49 #include "mock/MockEventThread.h"
50 #include "mock/MockMessageQueue.h"
51 #include "mock/MockNativeWindowSurface.h"
52 #include "mock/MockSchedulerCallback.h"
53 #include "mock/MockSurfaceInterceptor.h"
54 #include "mock/MockVsyncController.h"
55 #include "mock/system/window/MockNativeWindow.h"
56 
57 namespace android {
58 
59 // TODO: Do not polute the android namespace
60 namespace hal = android::hardware::graphics::composer::hal;
61 
62 using testing::_;
63 using testing::AnyNumber;
64 using testing::DoAll;
65 using testing::Mock;
66 using testing::ResultOf;
67 using testing::Return;
68 using testing::SetArgPointee;
69 
70 using hal::ColorMode;
71 using hal::Connection;
72 using hal::DisplayCapability;
73 using hal::DisplayType;
74 using hal::Error;
75 using hal::Hdr;
76 using hal::HWDisplayId;
77 using hal::IComposer;
78 using hal::IComposerClient;
79 using hal::PerFrameMetadataKey;
80 using hal::PowerMode;
81 
82 class DisplayTransactionTest : public testing::Test {
83 public:
84     ~DisplayTransactionTest() override;
85 
86     // --------------------------------------------------------------------
87     // Mock/Fake injection
88 
89     void injectMockScheduler();
90     void injectMockComposer(int virtualDisplayCount);
91     void injectFakeBufferQueueFactory();
92     void injectFakeNativeWindowSurfaceFactory();
93     sp<DisplayDevice> injectDefaultInternalDisplay(
94             std::function<void(TestableSurfaceFlinger::FakeDisplayDeviceInjector&)>);
95 
96     // --------------------------------------------------------------------
97     // Postcondition helpers
98 
99     bool hasPhysicalHwcDisplay(hal::HWDisplayId hwcDisplayId);
100     bool hasTransactionFlagSet(int flag);
101     bool hasDisplayDevice(sp<IBinder> displayToken);
102     sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
103     bool hasCurrentDisplayState(sp<IBinder> displayToken);
104     const DisplayDeviceState& getCurrentDisplayState(sp<IBinder> displayToken);
105     bool hasDrawingDisplayState(sp<IBinder> displayToken);
106     const DisplayDeviceState& getDrawingDisplayState(sp<IBinder> displayToken);
107 
108     // --------------------------------------------------------------------
109     // Test instances
110 
111     TestableSurfaceFlinger mFlinger;
112     sp<mock::NativeWindow> mNativeWindow = new mock::NativeWindow();
113     sp<GraphicBuffer> mBuffer = new GraphicBuffer();
114     Hwc2::mock::PowerAdvisor mPowerAdvisor;
115 
116     // These mocks are created by the test, but are destroyed by SurfaceFlinger
117     // by virtue of being stored into a std::unique_ptr. However we still need
118     // to keep a reference to them for use in setting up call expectations.
119     renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
120     Hwc2::mock::Composer* mComposer = nullptr;
121     mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
122     sp<mock::SurfaceInterceptor> mSurfaceInterceptor = new mock::SurfaceInterceptor;
123 
124     mock::VsyncController* mVsyncController = new mock::VsyncController;
125     mock::VSyncTracker* mVSyncTracker = new mock::VSyncTracker;
126     mock::SchedulerCallback mSchedulerCallback;
127     mock::EventThread* mEventThread = new mock::EventThread;
128     mock::EventThread* mSFEventThread = new mock::EventThread;
129 
130     // These mocks are created only when expected to be created via a factory.
131     sp<mock::GraphicBufferConsumer> mConsumer;
132     sp<mock::GraphicBufferProducer> mProducer;
133     surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
134 
135 protected:
136     DisplayTransactionTest();
137 };
138 
139 constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'667;
140 constexpr int32_t DEFAULT_DPI = 320;
141 constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
142 
143 constexpr int POWER_MODE_LEET = 1337; // An out of range power mode value
144 
145 /* ------------------------------------------------------------------------
146  * Boolean avoidance
147  *
148  * To make calls and template instantiations more readable, we define some
149  * local enums along with an implicit bool conversion.
150  */
151 
152 #define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true };
153 
154 BOOL_SUBSTITUTE(Async);
155 BOOL_SUBSTITUTE(Critical);
156 BOOL_SUBSTITUTE(Primary);
157 BOOL_SUBSTITUTE(Secure);
158 BOOL_SUBSTITUTE(Virtual);
159 
160 template <typename PhysicalDisplay>
161 struct PhysicalDisplayIdType {};
162 
163 template <uint64_t displayId>
164 using HalVirtualDisplayIdType = std::integral_constant<uint64_t, displayId>;
165 
166 struct GpuVirtualDisplayIdType {};
167 
168 template <typename>
169 struct IsPhysicalDisplayId : std::bool_constant<false> {};
170 
171 template <typename PhysicalDisplay>
172 struct IsPhysicalDisplayId<PhysicalDisplayIdType<PhysicalDisplay>> : std::bool_constant<true> {};
173 
174 template <typename>
175 struct DisplayIdGetter;
176 
177 template <typename PhysicalDisplay>
178 struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
179     static PhysicalDisplayId get() {
180         if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
181             return PhysicalDisplayId::fromPort(static_cast<bool>(PhysicalDisplay::PRIMARY)
182                                                        ? LEGACY_DISPLAY_TYPE_PRIMARY
183                                                        : LEGACY_DISPLAY_TYPE_EXTERNAL);
184         }
185 
186         const auto info =
187                 parseDisplayIdentificationData(PhysicalDisplay::PORT,
188                                                PhysicalDisplay::GET_IDENTIFICATION_DATA());
189         return info ? info->id : PhysicalDisplayId::fromPort(PhysicalDisplay::PORT);
190     }
191 };
192 
193 template <uint64_t displayId>
194 struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
195     static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); }
196 };
197 
198 template <>
199 struct DisplayIdGetter<GpuVirtualDisplayIdType> {
200     static GpuVirtualDisplayId get() { return GpuVirtualDisplayId(0); }
201 };
202 
203 template <typename>
204 struct DisplayConnectionTypeGetter {
205     static constexpr std::optional<ui::DisplayConnectionType> value;
206 };
207 
208 template <typename PhysicalDisplay>
209 struct DisplayConnectionTypeGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
210     static constexpr std::optional<ui::DisplayConnectionType> value =
211             PhysicalDisplay::CONNECTION_TYPE;
212 };
213 
214 template <typename>
215 struct HwcDisplayIdGetter {
216     static constexpr std::optional<HWDisplayId> value;
217 };
218 
219 constexpr HWDisplayId HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
220 
221 template <uint64_t displayId>
222 struct HwcDisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
223     static constexpr std::optional<HWDisplayId> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
224 };
225 
226 template <typename PhysicalDisplay>
227 struct HwcDisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
228     static constexpr std::optional<HWDisplayId> value = PhysicalDisplay::HWC_DISPLAY_ID;
229 };
230 
231 // DisplayIdType can be:
232 //     1) PhysicalDisplayIdType<...> for generated ID of physical display backed by HWC.
233 //     2) HalVirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC.
234 //     3) GpuVirtualDisplayIdType for virtual display without HWC backing.
235 template <typename DisplayIdType, int width, int height, Critical critical, Async async,
236           Secure secure, Primary primary, int grallocUsage>
237 struct DisplayVariant {
238     using DISPLAY_ID = DisplayIdGetter<DisplayIdType>;
239     using CONNECTION_TYPE = DisplayConnectionTypeGetter<DisplayIdType>;
240     using HWC_DISPLAY_ID_OPT = HwcDisplayIdGetter<DisplayIdType>;
241 
242     // The display width and height
243     static constexpr int WIDTH = width;
244     static constexpr int HEIGHT = height;
245 
246     static constexpr int GRALLOC_USAGE = grallocUsage;
247 
248     // Whether the display is virtual or physical
249     static constexpr Virtual VIRTUAL =
250             IsPhysicalDisplayId<DisplayIdType>{} ? Virtual::FALSE : Virtual::TRUE;
251 
252     // When creating native window surfaces for the framebuffer, whether those should be critical
253     static constexpr Critical CRITICAL = critical;
254 
255     // When creating native window surfaces for the framebuffer, whether those should be async
256     static constexpr Async ASYNC = async;
257 
258     // Whether the display should be treated as secure
259     static constexpr Secure SECURE = secure;
260 
261     // Whether the display is primary
262     static constexpr Primary PRIMARY = primary;
263 
264     static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
265         auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder();
266         ceDisplayArgs.setId(DISPLAY_ID::get())
267                 .setPixels({WIDTH, HEIGHT})
268                 .setPowerAdvisor(&test->mPowerAdvisor);
269 
270         const auto connectionType = CONNECTION_TYPE::value;
271         if (connectionType) {
272             ceDisplayArgs.setConnectionType(*connectionType);
273         }
274 
275         auto compositionDisplay =
276                 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
277                                                        ceDisplayArgs.build());
278 
279         auto injector =
280                 TestableSurfaceFlinger::FakeDisplayDeviceInjector(test->mFlinger,
281                                                                   compositionDisplay,
282                                                                   connectionType,
283                                                                   HWC_DISPLAY_ID_OPT::value,
284                                                                   static_cast<bool>(PRIMARY));
285 
286         injector.setSecure(static_cast<bool>(SECURE));
287         injector.setNativeWindow(test->mNativeWindow);
288 
289         // Creating a DisplayDevice requires getting default dimensions from the
290         // native window along with some other initial setup.
291         EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
292                 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
293         EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
294                 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
295         EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
296                 .WillRepeatedly(Return(0));
297         EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
298                 .WillRepeatedly(Return(0));
299         EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
300                 .WillRepeatedly(Return(0));
301         EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
302                 .WillRepeatedly(Return(0));
303 
304         return injector;
305     }
306 
307     // Called by tests to set up any native window creation call expectations.
308     static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
309         EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
310                 .WillOnce(Return(test->mNativeWindow));
311 
312         EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
313                 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
314         EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
315                 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
316         EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
317                 .WillRepeatedly(Return(0));
318         EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
319                 .WillRepeatedly(Return(0));
320         EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
321                 .WillRepeatedly(Return(0));
322         EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
323                 .WillRepeatedly(Return(0));
324     }
325 
326     static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
327         EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
328         EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
329         EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
330                 .WillRepeatedly(Return(NO_ERROR));
331         EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
332                 .WillRepeatedly(Return(NO_ERROR));
333         EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
334                 .WillRepeatedly(Return(NO_ERROR));
335     }
336 
337     static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
338         EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
339     }
340 };
341 
342 template <HWDisplayId hwcDisplayId, DisplayType hwcDisplayType, typename DisplayVariant,
343           typename PhysicalDisplay = void>
344 struct HwcDisplayVariant {
345     // The display id supplied by the HWC
346     static constexpr HWDisplayId HWC_DISPLAY_ID = hwcDisplayId;
347 
348     // The HWC display type
349     static constexpr DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
350 
351     // The HWC active configuration id
352     static constexpr hal::HWConfigId HWC_ACTIVE_CONFIG_ID = 2001;
353     static constexpr PowerMode INIT_POWER_MODE = hal::PowerMode::ON;
354 
355     static void injectPendingHotplugEvent(DisplayTransactionTest* test, Connection connection) {
356         test->mFlinger.mutablePendingHotplugEvents().emplace_back(
357                 TestableSurfaceFlinger::HotplugEvent{HWC_DISPLAY_ID, connection});
358     }
359 
360     // Called by tests to inject a HWC display setup
361     static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
362         const auto displayId = DisplayVariant::DISPLAY_ID::get();
363         ASSERT_FALSE(GpuVirtualDisplayId::tryCast(displayId));
364         TestableSurfaceFlinger::FakeHwcDisplayInjector(displayId, HWC_DISPLAY_TYPE,
365                                                        static_cast<bool>(DisplayVariant::PRIMARY))
366                 .setHwcDisplayId(HWC_DISPLAY_ID)
367                 .setWidth(DisplayVariant::WIDTH)
368                 .setHeight(DisplayVariant::HEIGHT)
369                 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
370                 .setPowerMode(INIT_POWER_MODE)
371                 .inject(&test->mFlinger, test->mComposer);
372     }
373 
374     // Called by tests to inject a HWC display setup
375     static void injectHwcDisplay(DisplayTransactionTest* test) {
376         EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
377                 .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})),
378                                 Return(Error::NONE)));
379         EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, INIT_POWER_MODE))
380                 .WillOnce(Return(Error::NONE));
381         injectHwcDisplayWithNoDefaultCapabilities(test);
382     }
383 
384     static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
385             DisplayTransactionTest* test) {
386         const ::testing::TestInfo* const test_info =
387                 ::testing::UnitTest::GetInstance()->current_test_info();
388 
389         auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
390                                      .setId(DisplayVariant::DISPLAY_ID::get())
391                                      .setConnectionType(PhysicalDisplay::CONNECTION_TYPE)
392                                      .setPixels({DisplayVariant::WIDTH, DisplayVariant::HEIGHT})
393                                      .setIsSecure(static_cast<bool>(DisplayVariant::SECURE))
394                                      .setPowerAdvisor(&test->mPowerAdvisor)
395                                      .setName(std::string("Injected display for ") +
396                                               test_info->test_case_name() + "." + test_info->name())
397                                      .build();
398 
399         return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
400                                                       ceDisplayArgs);
401     }
402 
403     static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
404         if (HWC_DISPLAY_TYPE == DisplayType::PHYSICAL) {
405             EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
406                     .WillRepeatedly(DoAll(SetArgPointee<1>(std::vector<hal::HWConfigId>{
407                                                   HWC_ACTIVE_CONFIG_ID}),
408                                           Return(Error::NONE)));
409             EXPECT_CALL(*test->mComposer,
410                         getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
411                                             IComposerClient::Attribute::WIDTH, _))
412                     .WillRepeatedly(
413                             DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
414             EXPECT_CALL(*test->mComposer,
415                         getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
416                                             IComposerClient::Attribute::HEIGHT, _))
417                     .WillRepeatedly(
418                             DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
419             EXPECT_CALL(*test->mComposer,
420                         getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
421                                             IComposerClient::Attribute::VSYNC_PERIOD, _))
422                     .WillRepeatedly(
423                             DoAll(SetArgPointee<3>(DEFAULT_VSYNC_PERIOD), Return(Error::NONE)));
424             EXPECT_CALL(*test->mComposer,
425                         getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
426                                             IComposerClient::Attribute::DPI_X, _))
427                     .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
428             EXPECT_CALL(*test->mComposer,
429                         getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
430                                             IComposerClient::Attribute::DPI_Y, _))
431                     .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
432             EXPECT_CALL(*test->mComposer,
433                         getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
434                                             IComposerClient::Attribute::CONFIG_GROUP, _))
435                     .WillRepeatedly(DoAll(SetArgPointee<3>(-1), Return(Error::NONE)));
436         } else {
437             EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
438             EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
439         }
440     }
441 
442     static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
443         constexpr auto CONNECTION_TYPE =
444                 PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal
445                 ? IComposerClient::DisplayConnectionType::INTERNAL
446                 : IComposerClient::DisplayConnectionType::EXTERNAL;
447 
448         EXPECT_CALL(*test->mComposer, getDisplayConnectionType(HWC_DISPLAY_ID, _))
449                 .WillOnce(DoAll(SetArgPointee<1>(CONNECTION_TYPE), Return(hal::V2_4::Error::NONE)));
450 
451         EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_))
452                 .WillOnce(Return(hal::Error::NONE));
453 
454         setupHwcGetConfigsCallExpectations(test);
455 
456         if (PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
457             EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
458                     .WillOnce(DoAll(SetArgPointee<1>(PhysicalDisplay::PORT),
459                                     SetArgPointee<2>(PhysicalDisplay::GET_IDENTIFICATION_DATA()),
460                                     Return(Error::NONE)));
461         } else {
462             EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
463                     .WillOnce(Return(Error::UNSUPPORTED));
464         }
465     }
466 
467     // Called by tests to set up HWC call expectations
468     static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
469         EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
470                 .WillRepeatedly(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
471     }
472 };
473 
474 // Physical displays are expected to be synchronous, secure, and have a HWC display for output.
475 constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
476         GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
477 
478 template <typename PhysicalDisplay, int width, int height, Critical critical>
479 struct PhysicalDisplayVariant
480       : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, critical,
481                        Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
482                        GRALLOC_USAGE_PHYSICAL_DISPLAY>,
483         HwcDisplayVariant<PhysicalDisplay::HWC_DISPLAY_ID, DisplayType::PHYSICAL,
484                           DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height,
485                                          critical, Async::FALSE, Secure::TRUE,
486                                          PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
487                           PhysicalDisplay> {};
488 
489 template <bool hasIdentificationData>
490 struct PrimaryDisplay {
491     static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal;
492     static constexpr Primary PRIMARY = Primary::TRUE;
493     static constexpr uint8_t PORT = 255;
494     static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
495     static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
496     static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
497 };
498 
499 template <bool hasIdentificationData>
500 struct ExternalDisplay {
501     static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External;
502     static constexpr Primary PRIMARY = Primary::FALSE;
503     static constexpr uint8_t PORT = 254;
504     static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
505     static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
506     static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
507 };
508 
509 struct TertiaryDisplay {
510     static constexpr Primary PRIMARY = Primary::FALSE;
511     static constexpr uint8_t PORT = 253;
512     static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
513     static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
514 };
515 
516 // A primary display is a physical display that is critical
517 using PrimaryDisplayVariant =
518         PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>;
519 
520 // An external display is physical display that is not critical.
521 using ExternalDisplayVariant =
522         PhysicalDisplayVariant<ExternalDisplay<false>, 1920, 1280, Critical::FALSE>;
523 
524 using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200, Critical::FALSE>;
525 
526 // A virtual display not supported by the HWC.
527 constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
528 
529 template <int width, int height, Secure secure>
530 struct NonHwcVirtualDisplayVariant
531       : DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE, secure,
532                        Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY> {
533     using Base =
534             DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE,
535                            secure, Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
536 
537     static void injectHwcDisplay(DisplayTransactionTest*) {}
538 
539     static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
540             DisplayTransactionTest* test) {
541         const ::testing::TestInfo* const test_info =
542                 ::testing::UnitTest::GetInstance()->current_test_info();
543 
544         auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
545                                      .setId(Base::DISPLAY_ID::get())
546                                      .setPixels({Base::WIDTH, Base::HEIGHT})
547                                      .setIsSecure(static_cast<bool>(Base::SECURE))
548                                      .setPowerAdvisor(&test->mPowerAdvisor)
549                                      .setName(std::string("Injected display for ") +
550                                               test_info->test_case_name() + "." + test_info->name())
551                                      .build();
552 
553         return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
554                                                       ceDisplayArgs);
555     }
556 
557     static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
558         EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
559         EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
560     }
561 
562     static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
563         EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
564     }
565 
566     static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
567         Base::setupNativeWindowSurfaceCreationCallExpectations(test);
568         EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
569     }
570 };
571 
572 // A virtual display supported by the HWC.
573 constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
574 
575 template <int width, int height, Secure secure>
576 struct HwcVirtualDisplayVariant
577       : DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
578                        secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
579         HwcDisplayVariant<HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
580                           DisplayVariant<HalVirtualDisplayIdType<42>, width, height,
581                                          Critical::FALSE, Async::TRUE, secure, Primary::FALSE,
582                                          GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>> {
583     using Base = DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
584                                 Async::TRUE, secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER>;
585     using Self = HwcVirtualDisplayVariant<width, height, secure>;
586 
587     static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
588             DisplayTransactionTest* test) {
589         const ::testing::TestInfo* const test_info =
590                 ::testing::UnitTest::GetInstance()->current_test_info();
591 
592         const auto displayId = Base::DISPLAY_ID::get();
593         auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
594                                      .setId(displayId)
595                                      .setPixels({Base::WIDTH, Base::HEIGHT})
596                                      .setIsSecure(static_cast<bool>(Base::SECURE))
597                                      .setPowerAdvisor(&test->mPowerAdvisor)
598                                      .setName(std::string("Injected display for ") +
599                                               test_info->test_case_name() + "." + test_info->name())
600                                      .build();
601 
602         auto compositionDisplay =
603                 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
604                                                        ceDisplayArgs);
605 
606         // Insert display data so that the HWC thinks it created the virtual display.
607         test->mFlinger.mutableHwcDisplayData().try_emplace(displayId);
608 
609         return compositionDisplay;
610     }
611 
612     static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
613         Base::setupNativeWindowSurfaceCreationCallExpectations(test);
614         EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
615     }
616 
617     static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
618         EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
619                 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
620         EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
621     }
622 };
623 
624 // For this variant, the display is not a HWC display, so no HDR support should
625 // be configured.
626 struct NonHwcDisplayHdrSupportVariant {
627     static constexpr bool HDR10_PLUS_SUPPORTED = false;
628     static constexpr bool HDR10_SUPPORTED = false;
629     static constexpr bool HDR_HLG_SUPPORTED = false;
630     static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
631     static void setupComposerCallExpectations(DisplayTransactionTest* test) {
632         EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
633     }
634 };
635 
636 // For this variant, the composer should respond with am empty list of HDR
637 // modes, so no HDR support should be configured.
638 template <typename Display>
639 struct HdrNotSupportedVariant {
640     static constexpr bool HDR10_PLUS_SUPPORTED = false;
641     static constexpr bool HDR10_SUPPORTED = false;
642     static constexpr bool HDR_HLG_SUPPORTED = false;
643     static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
644     static void setupComposerCallExpectations(DisplayTransactionTest* test) {
645         EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
646                 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
647     }
648 };
649 
650 struct NonHwcPerFrameMetadataSupportVariant {
651     static constexpr int PER_FRAME_METADATA_KEYS = 0;
652     static void setupComposerCallExpectations(DisplayTransactionTest* test) {
653         EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_)).Times(0);
654     }
655 };
656 
657 template <typename Display>
658 struct NoPerFrameMetadataSupportVariant {
659     static constexpr int PER_FRAME_METADATA_KEYS = 0;
660     static void setupComposerCallExpectations(DisplayTransactionTest* test) {
661         EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
662                 .WillOnce(Return(std::vector<PerFrameMetadataKey>()));
663     }
664 };
665 
666 // For this variant, SurfaceFlinger should configure itself with wide display
667 // support, but the display should respond with an empty list of supported color
668 // modes. Wide-color support for the display should not be configured.
669 template <typename Display>
670 struct WideColorNotSupportedVariant {
671     static constexpr bool WIDE_COLOR_SUPPORTED = false;
672 
673     static void injectConfigChange(DisplayTransactionTest* test) {
674         test->mFlinger.mutableUseColorManagement() = true;
675         test->mFlinger.mutableHasWideColorDisplay() = true;
676     }
677 
678     static void setupComposerCallExpectations(DisplayTransactionTest* test) {
679         EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
680                 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>()), Return(Error::NONE)));
681         EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
682     }
683 };
684 
685 // For this variant, SurfaceFlinger should not configure itself with wide
686 // display support, so the display should not be configured for wide-color
687 // support.
688 struct WideColorSupportNotConfiguredVariant {
689     static constexpr bool WIDE_COLOR_SUPPORTED = false;
690 
691     static void injectConfigChange(DisplayTransactionTest* test) {
692         test->mFlinger.mutableHasWideColorDisplay() = false;
693         test->mFlinger.mutableUseColorManagement() = false;
694         test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
695     }
696 
697     static void setupComposerCallExpectations(DisplayTransactionTest* test) {
698         EXPECT_CALL(*test->mComposer, getColorModes(_, _)).Times(0);
699         EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
700         EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
701     }
702 };
703 
704 /* ------------------------------------------------------------------------
705  * Typical display configurations to test
706  */
707 
708 template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy,
709           typename PerFrameMetadataSupportPolicy>
710 struct Case {
711     using Display = DisplayPolicy;
712     using WideColorSupport = WideColorSupportPolicy;
713     using HdrSupport = HdrSupportPolicy;
714     using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy;
715 };
716 
717 using SimplePrimaryDisplayCase =
718         Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
719              HdrNotSupportedVariant<PrimaryDisplayVariant>,
720              NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
721 using SimpleExternalDisplayCase =
722         Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
723              HdrNotSupportedVariant<ExternalDisplayVariant>,
724              NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
725 using SimpleTertiaryDisplayCase =
726         Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
727              HdrNotSupportedVariant<TertiaryDisplayVariant>,
728              NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
729 
730 using NonHwcVirtualDisplayCase =
731         Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
732              WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant,
733              NonHwcPerFrameMetadataSupportVariant>;
734 using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
735 using HwcVirtualDisplayCase =
736         Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
737              HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>,
738              NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>;
739 
740 } // namespace android
741 
742 // TODO(b/129481165): remove the #pragma below and fix conversion issues
743 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
744