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