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