blob: 565c2445e0bcc9b475eeef625989d8b5f293a984 [file] [log] [blame]
Marin Shalamanov07b1ff32020-10-07 16:57:22 +02001/*
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"
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010022#pragma clang diagnostic ignored "-Wextra"
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020023
24#include <type_traits>
Alec Mouriff793872022-01-13 17:45:06 -080025#include "DisplayIdentificationTestHelpers.h"
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020026
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"
Dominik Laskowskib0054a22022-03-03 09:03:06 -080048#include "mock/DisplayHardware/MockDisplayMode.h"
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020049#include "mock/DisplayHardware/MockPowerAdvisor.h"
50#include "mock/MockEventThread.h"
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020051#include "mock/MockNativeWindowSurface.h"
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020052#include "mock/MockSurfaceInterceptor.h"
53#include "mock/MockVsyncController.h"
54#include "mock/system/window/MockNativeWindow.h"
55
56namespace android {
57
58// TODO: Do not polute the android namespace
59namespace hal = android::hardware::graphics::composer::hal;
60
61using testing::_;
62using testing::AnyNumber;
63using testing::DoAll;
64using testing::Mock;
65using testing::ResultOf;
66using testing::Return;
67using testing::SetArgPointee;
68
Leon Scroggins III5967aec2021-12-29 11:14:22 -050069using aidl::android::hardware::graphics::composer3::DisplayCapability;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020070using hal::ColorMode;
71using hal::Connection;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020072using hal::DisplayType;
73using hal::Error;
74using hal::Hdr;
75using hal::HWDisplayId;
76using hal::IComposer;
77using hal::IComposerClient;
78using hal::PerFrameMetadataKey;
79using hal::PowerMode;
80
81class DisplayTransactionTest : public testing::Test {
82public:
83 ~DisplayTransactionTest() override;
84
85 // --------------------------------------------------------------------
86 // Mock/Fake injection
87
88 void injectMockScheduler();
89 void injectMockComposer(int virtualDisplayCount);
90 void injectFakeBufferQueueFactory();
91 void injectFakeNativeWindowSurfaceFactory();
92 sp<DisplayDevice> injectDefaultInternalDisplay(
93 std::function<void(TestableSurfaceFlinger::FakeDisplayDeviceInjector&)>);
94
95 // --------------------------------------------------------------------
96 // Postcondition helpers
97
98 bool hasPhysicalHwcDisplay(hal::HWDisplayId hwcDisplayId);
99 bool hasTransactionFlagSet(int flag);
100 bool hasDisplayDevice(sp<IBinder> displayToken);
101 sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
102 bool hasCurrentDisplayState(sp<IBinder> displayToken);
103 const DisplayDeviceState& getCurrentDisplayState(sp<IBinder> displayToken);
104 bool hasDrawingDisplayState(sp<IBinder> displayToken);
105 const DisplayDeviceState& getDrawingDisplayState(sp<IBinder> displayToken);
106
107 // --------------------------------------------------------------------
108 // Test instances
109
110 TestableSurfaceFlinger mFlinger;
111 sp<mock::NativeWindow> mNativeWindow = new mock::NativeWindow();
112 sp<GraphicBuffer> mBuffer = new GraphicBuffer();
113 Hwc2::mock::PowerAdvisor mPowerAdvisor;
114
115 // These mocks are created by the test, but are destroyed by SurfaceFlinger
116 // by virtue of being stored into a std::unique_ptr. However we still need
117 // to keep a reference to them for use in setting up call expectations.
118 renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
119 Hwc2::mock::Composer* mComposer = nullptr;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200120 sp<mock::SurfaceInterceptor> mSurfaceInterceptor = new mock::SurfaceInterceptor;
121
122 mock::VsyncController* mVsyncController = new mock::VsyncController;
123 mock::VSyncTracker* mVSyncTracker = new mock::VSyncTracker;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200124 mock::EventThread* mEventThread = new mock::EventThread;
125 mock::EventThread* mSFEventThread = new mock::EventThread;
126
127 // These mocks are created only when expected to be created via a factory.
128 sp<mock::GraphicBufferConsumer> mConsumer;
129 sp<mock::GraphicBufferProducer> mProducer;
130 surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
131
132protected:
133 DisplayTransactionTest();
134};
135
Marin Shalamanova903d032020-12-29 20:35:13 +0100136constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'667;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200137constexpr int32_t DEFAULT_DPI = 320;
138constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
139
140constexpr int POWER_MODE_LEET = 1337; // An out of range power mode value
141
142/* ------------------------------------------------------------------------
143 * Boolean avoidance
144 *
145 * To make calls and template instantiations more readable, we define some
146 * local enums along with an implicit bool conversion.
147 */
148
149#define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true };
150
151BOOL_SUBSTITUTE(Async);
152BOOL_SUBSTITUTE(Critical);
153BOOL_SUBSTITUTE(Primary);
154BOOL_SUBSTITUTE(Secure);
155BOOL_SUBSTITUTE(Virtual);
156
157template <typename PhysicalDisplay>
158struct PhysicalDisplayIdType {};
159
160template <uint64_t displayId>
161using HalVirtualDisplayIdType = std::integral_constant<uint64_t, displayId>;
162
163struct GpuVirtualDisplayIdType {};
164
165template <typename>
166struct IsPhysicalDisplayId : std::bool_constant<false> {};
167
168template <typename PhysicalDisplay>
169struct IsPhysicalDisplayId<PhysicalDisplayIdType<PhysicalDisplay>> : std::bool_constant<true> {};
170
171template <typename>
172struct DisplayIdGetter;
173
174template <typename PhysicalDisplay>
175struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
176 static PhysicalDisplayId get() {
177 if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
178 return PhysicalDisplayId::fromPort(static_cast<bool>(PhysicalDisplay::PRIMARY)
179 ? LEGACY_DISPLAY_TYPE_PRIMARY
180 : LEGACY_DISPLAY_TYPE_EXTERNAL);
181 }
182
183 const auto info =
184 parseDisplayIdentificationData(PhysicalDisplay::PORT,
185 PhysicalDisplay::GET_IDENTIFICATION_DATA());
186 return info ? info->id : PhysicalDisplayId::fromPort(PhysicalDisplay::PORT);
187 }
188};
189
190template <uint64_t displayId>
191struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
192 static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); }
193};
194
195template <>
196struct DisplayIdGetter<GpuVirtualDisplayIdType> {
197 static GpuVirtualDisplayId get() { return GpuVirtualDisplayId(0); }
198};
199
200template <typename>
201struct DisplayConnectionTypeGetter {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100202 static constexpr std::optional<ui::DisplayConnectionType> value;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200203};
204
205template <typename PhysicalDisplay>
206struct DisplayConnectionTypeGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100207 static constexpr std::optional<ui::DisplayConnectionType> value =
208 PhysicalDisplay::CONNECTION_TYPE;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200209};
210
211template <typename>
212struct HwcDisplayIdGetter {
213 static constexpr std::optional<HWDisplayId> value;
214};
215
216constexpr HWDisplayId HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
217
218template <uint64_t displayId>
219struct HwcDisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
220 static constexpr std::optional<HWDisplayId> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
221};
222
223template <typename PhysicalDisplay>
224struct HwcDisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
225 static constexpr std::optional<HWDisplayId> value = PhysicalDisplay::HWC_DISPLAY_ID;
226};
227
228// DisplayIdType can be:
229// 1) PhysicalDisplayIdType<...> for generated ID of physical display backed by HWC.
230// 2) HalVirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC.
231// 3) GpuVirtualDisplayIdType for virtual display without HWC backing.
232template <typename DisplayIdType, int width, int height, Critical critical, Async async,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700233 Secure secure, Primary primary, int grallocUsage, int displayFlags>
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200234struct DisplayVariant {
235 using DISPLAY_ID = DisplayIdGetter<DisplayIdType>;
236 using CONNECTION_TYPE = DisplayConnectionTypeGetter<DisplayIdType>;
237 using HWC_DISPLAY_ID_OPT = HwcDisplayIdGetter<DisplayIdType>;
238
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200239 static constexpr int WIDTH = width;
240 static constexpr int HEIGHT = height;
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800241 static constexpr ui::Size RESOLUTION{WIDTH, HEIGHT};
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200242
243 static constexpr int GRALLOC_USAGE = grallocUsage;
244
245 // Whether the display is virtual or physical
246 static constexpr Virtual VIRTUAL =
247 IsPhysicalDisplayId<DisplayIdType>{} ? Virtual::FALSE : Virtual::TRUE;
248
249 // When creating native window surfaces for the framebuffer, whether those should be critical
250 static constexpr Critical CRITICAL = critical;
251
252 // When creating native window surfaces for the framebuffer, whether those should be async
253 static constexpr Async ASYNC = async;
254
255 // Whether the display should be treated as secure
256 static constexpr Secure SECURE = secure;
257
258 // Whether the display is primary
259 static constexpr Primary PRIMARY = primary;
260
Vishnu Naira119aaa2021-09-24 07:19:35 -0700261 static constexpr int DISPLAY_FLAGS = displayFlags;
262
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200263 static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
264 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder();
Dominik Laskowski13948602021-03-08 20:48:28 -0800265 ceDisplayArgs.setId(DISPLAY_ID::get())
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800266 .setPixels(RESOLUTION)
Dominik Laskowski13948602021-03-08 20:48:28 -0800267 .setPowerAdvisor(&test->mPowerAdvisor);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200268
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200269 auto compositionDisplay =
270 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
271 ceDisplayArgs.build());
272
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200273 auto injector =
274 TestableSurfaceFlinger::FakeDisplayDeviceInjector(test->mFlinger,
275 compositionDisplay,
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700276 CONNECTION_TYPE::value,
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200277 HWC_DISPLAY_ID_OPT::value,
278 static_cast<bool>(PRIMARY));
279
280 injector.setSecure(static_cast<bool>(SECURE));
281 injector.setNativeWindow(test->mNativeWindow);
282
283 // Creating a DisplayDevice requires getting default dimensions from the
284 // native window along with some other initial setup.
285 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
286 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
287 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
288 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
289 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
290 .WillRepeatedly(Return(0));
291 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
292 .WillRepeatedly(Return(0));
293 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
294 .WillRepeatedly(Return(0));
295 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
296 .WillRepeatedly(Return(0));
297
298 return injector;
299 }
300
301 // Called by tests to set up any native window creation call expectations.
302 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
303 EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
304 .WillOnce(Return(test->mNativeWindow));
305
306 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
307 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
308 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
309 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
310 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
311 .WillRepeatedly(Return(0));
312 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
313 .WillRepeatedly(Return(0));
314 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
315 .WillRepeatedly(Return(0));
316 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
317 .WillRepeatedly(Return(0));
318 }
319
320 static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
321 EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
322 EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
323 EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
324 .WillRepeatedly(Return(NO_ERROR));
325 EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
326 .WillRepeatedly(Return(NO_ERROR));
327 EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
328 .WillRepeatedly(Return(NO_ERROR));
329 }
330
331 static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
332 EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
333 }
334};
335
336template <HWDisplayId hwcDisplayId, DisplayType hwcDisplayType, typename DisplayVariant,
337 typename PhysicalDisplay = void>
338struct HwcDisplayVariant {
339 // The display id supplied by the HWC
340 static constexpr HWDisplayId HWC_DISPLAY_ID = hwcDisplayId;
341
342 // The HWC display type
343 static constexpr DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
344
345 // The HWC active configuration id
Marin Shalamanov6e840172020-12-14 22:13:28 +0100346 static constexpr hal::HWConfigId HWC_ACTIVE_CONFIG_ID = 2001;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200347 static constexpr PowerMode INIT_POWER_MODE = hal::PowerMode::ON;
348
349 static void injectPendingHotplugEvent(DisplayTransactionTest* test, Connection connection) {
350 test->mFlinger.mutablePendingHotplugEvents().emplace_back(
351 TestableSurfaceFlinger::HotplugEvent{HWC_DISPLAY_ID, connection});
352 }
353
354 // Called by tests to inject a HWC display setup
355 static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
356 const auto displayId = DisplayVariant::DISPLAY_ID::get();
357 ASSERT_FALSE(GpuVirtualDisplayId::tryCast(displayId));
358 TestableSurfaceFlinger::FakeHwcDisplayInjector(displayId, HWC_DISPLAY_TYPE,
359 static_cast<bool>(DisplayVariant::PRIMARY))
360 .setHwcDisplayId(HWC_DISPLAY_ID)
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800361 .setResolution(DisplayVariant::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200362 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
363 .setPowerMode(INIT_POWER_MODE)
364 .inject(&test->mFlinger, test->mComposer);
365 }
366
367 // Called by tests to inject a HWC display setup
368 static void injectHwcDisplay(DisplayTransactionTest* test) {
369 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
370 .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})),
371 Return(Error::NONE)));
372 EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, INIT_POWER_MODE))
373 .WillOnce(Return(Error::NONE));
374 injectHwcDisplayWithNoDefaultCapabilities(test);
375 }
376
377 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
378 DisplayTransactionTest* test) {
379 const ::testing::TestInfo* const test_info =
380 ::testing::UnitTest::GetInstance()->current_test_info();
381
382 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800383 .setId(DisplayVariant::DISPLAY_ID::get())
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800384 .setPixels(DisplayVariant::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200385 .setIsSecure(static_cast<bool>(DisplayVariant::SECURE))
386 .setPowerAdvisor(&test->mPowerAdvisor)
387 .setName(std::string("Injected display for ") +
388 test_info->test_case_name() + "." + test_info->name())
389 .build();
390
391 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
392 ceDisplayArgs);
393 }
394
Marin Shalamanov6e840172020-12-14 22:13:28 +0100395 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
396 if (HWC_DISPLAY_TYPE == DisplayType::PHYSICAL) {
397 EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
398 .WillRepeatedly(DoAll(SetArgPointee<1>(std::vector<hal::HWConfigId>{
399 HWC_ACTIVE_CONFIG_ID}),
400 Return(Error::NONE)));
401 EXPECT_CALL(*test->mComposer,
402 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
403 IComposerClient::Attribute::WIDTH, _))
404 .WillRepeatedly(
405 DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
406 EXPECT_CALL(*test->mComposer,
407 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
408 IComposerClient::Attribute::HEIGHT, _))
409 .WillRepeatedly(
410 DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
411 EXPECT_CALL(*test->mComposer,
412 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
413 IComposerClient::Attribute::VSYNC_PERIOD, _))
414 .WillRepeatedly(
Marin Shalamanova903d032020-12-29 20:35:13 +0100415 DoAll(SetArgPointee<3>(DEFAULT_VSYNC_PERIOD), Return(Error::NONE)));
Marin Shalamanov6e840172020-12-14 22:13:28 +0100416 EXPECT_CALL(*test->mComposer,
417 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
418 IComposerClient::Attribute::DPI_X, _))
419 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
420 EXPECT_CALL(*test->mComposer,
421 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
422 IComposerClient::Attribute::DPI_Y, _))
423 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
424 EXPECT_CALL(*test->mComposer,
425 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
426 IComposerClient::Attribute::CONFIG_GROUP, _))
427 .WillRepeatedly(DoAll(SetArgPointee<3>(-1), Return(Error::NONE)));
428 } else {
429 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
430 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
431 }
432 }
433
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200434 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
435 constexpr auto CONNECTION_TYPE =
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100436 PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200437 ? IComposerClient::DisplayConnectionType::INTERNAL
438 : IComposerClient::DisplayConnectionType::EXTERNAL;
439
440 EXPECT_CALL(*test->mComposer, getDisplayConnectionType(HWC_DISPLAY_ID, _))
441 .WillOnce(DoAll(SetArgPointee<1>(CONNECTION_TYPE), Return(hal::V2_4::Error::NONE)));
442
443 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_))
444 .WillOnce(Return(hal::Error::NONE));
Marin Shalamanov6e840172020-12-14 22:13:28 +0100445
446 setupHwcGetConfigsCallExpectations(test);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200447
448 if (PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
449 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
450 .WillOnce(DoAll(SetArgPointee<1>(PhysicalDisplay::PORT),
451 SetArgPointee<2>(PhysicalDisplay::GET_IDENTIFICATION_DATA()),
452 Return(Error::NONE)));
453 } else {
454 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
455 .WillOnce(Return(Error::UNSUPPORTED));
456 }
457 }
458
459 // Called by tests to set up HWC call expectations
460 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
461 EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
462 .WillRepeatedly(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
463 }
464};
465
466// Physical displays are expected to be synchronous, secure, and have a HWC display for output.
467constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
468 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
469
Vishnu Naira119aaa2021-09-24 07:19:35 -0700470constexpr int PHYSICAL_DISPLAY_FLAGS = 0x1;
471
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200472template <typename PhysicalDisplay, int width, int height, Critical critical>
473struct PhysicalDisplayVariant
474 : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, critical,
475 Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700476 GRALLOC_USAGE_PHYSICAL_DISPLAY, PHYSICAL_DISPLAY_FLAGS>,
477 HwcDisplayVariant<
478 PhysicalDisplay::HWC_DISPLAY_ID, DisplayType::PHYSICAL,
479 DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, critical,
480 Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
481 GRALLOC_USAGE_PHYSICAL_DISPLAY, PHYSICAL_DISPLAY_FLAGS>,
482 PhysicalDisplay> {};
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200483
484template <bool hasIdentificationData>
485struct PrimaryDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100486 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200487 static constexpr Primary PRIMARY = Primary::TRUE;
488 static constexpr uint8_t PORT = 255;
489 static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
490 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
491 static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
492};
493
494template <bool hasIdentificationData>
495struct ExternalDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100496 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200497 static constexpr Primary PRIMARY = Primary::FALSE;
498 static constexpr uint8_t PORT = 254;
499 static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
500 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
501 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
502};
503
504struct TertiaryDisplay {
505 static constexpr Primary PRIMARY = Primary::FALSE;
506 static constexpr uint8_t PORT = 253;
507 static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
508 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
509};
510
511// A primary display is a physical display that is critical
512using PrimaryDisplayVariant =
513 PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>;
514
515// An external display is physical display that is not critical.
516using ExternalDisplayVariant =
517 PhysicalDisplayVariant<ExternalDisplay<false>, 1920, 1280, Critical::FALSE>;
518
519using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200, Critical::FALSE>;
520
521// A virtual display not supported by the HWC.
522constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
523
Vishnu Naira119aaa2021-09-24 07:19:35 -0700524constexpr int VIRTUAL_DISPLAY_FLAGS = 0x0;
525
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200526template <int width, int height, Secure secure>
527struct NonHwcVirtualDisplayVariant
528 : DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE, secure,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700529 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY,
530 VIRTUAL_DISPLAY_FLAGS> {
531 using Base = DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE,
532 Async::TRUE, secure, Primary::FALSE,
533 GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY, VIRTUAL_DISPLAY_FLAGS>;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200534
535 static void injectHwcDisplay(DisplayTransactionTest*) {}
536
537 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
538 DisplayTransactionTest* test) {
539 const ::testing::TestInfo* const test_info =
540 ::testing::UnitTest::GetInstance()->current_test_info();
541
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200542 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800543 .setId(Base::DISPLAY_ID::get())
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800544 .setPixels(Base::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200545 .setIsSecure(static_cast<bool>(Base::SECURE))
546 .setPowerAdvisor(&test->mPowerAdvisor)
547 .setName(std::string("Injected display for ") +
548 test_info->test_case_name() + "." + test_info->name())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200549 .build();
550
551 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
552 ceDisplayArgs);
553 }
554
Marin Shalamanov6e840172020-12-14 22:13:28 +0100555 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
556 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
557 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
558 }
559
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200560 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
561 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
562 }
563
564 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
565 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
566 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
567 }
568};
569
570// A virtual display supported by the HWC.
571constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
572
573template <int width, int height, Secure secure>
574struct HwcVirtualDisplayVariant
575 : DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700576 secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY,
577 VIRTUAL_DISPLAY_FLAGS>,
578 HwcDisplayVariant<
579 HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
580 DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
581 Async::TRUE, secure, Primary::FALSE,
582 GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY, VIRTUAL_DISPLAY_FLAGS>> {
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200583 using Base = DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700584 Async::TRUE, secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER,
585 VIRTUAL_DISPLAY_FLAGS>;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200586 using Self = HwcVirtualDisplayVariant<width, height, secure>;
587
588 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
589 DisplayTransactionTest* test) {
590 const ::testing::TestInfo* const test_info =
591 ::testing::UnitTest::GetInstance()->current_test_info();
592
Dominik Laskowski13948602021-03-08 20:48:28 -0800593 const auto displayId = Base::DISPLAY_ID::get();
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200594 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800595 .setId(displayId)
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800596 .setPixels(Base::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200597 .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())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200601 .build();
602
603 auto compositionDisplay =
604 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
605 ceDisplayArgs);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200606
607 // Insert display data so that the HWC thinks it created the virtual display.
Dominik Laskowski13948602021-03-08 20:48:28 -0800608 test->mFlinger.mutableHwcDisplayData().try_emplace(displayId);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200609
610 return compositionDisplay;
611 }
612
613 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
614 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
615 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
616 }
617
618 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
Dominik Laskowski263eec42021-07-21 23:13:24 -0700619 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
620 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200621 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
622 }
623};
624
625// For this variant, the display is not a HWC display, so no HDR support should
626// be configured.
627struct NonHwcDisplayHdrSupportVariant {
628 static constexpr bool HDR10_PLUS_SUPPORTED = false;
629 static constexpr bool HDR10_SUPPORTED = false;
630 static constexpr bool HDR_HLG_SUPPORTED = false;
631 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
632 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
633 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
634 }
635};
636
637// For this variant, the composer should respond with am empty list of HDR
638// modes, so no HDR support should be configured.
639template <typename Display>
640struct HdrNotSupportedVariant {
641 static constexpr bool HDR10_PLUS_SUPPORTED = false;
642 static constexpr bool HDR10_SUPPORTED = false;
643 static constexpr bool HDR_HLG_SUPPORTED = false;
644 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
645 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
646 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
647 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
648 }
649};
650
651struct NonHwcPerFrameMetadataSupportVariant {
652 static constexpr int PER_FRAME_METADATA_KEYS = 0;
653 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
654 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_)).Times(0);
655 }
656};
657
658template <typename Display>
659struct NoPerFrameMetadataSupportVariant {
660 static constexpr int PER_FRAME_METADATA_KEYS = 0;
661 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
662 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
663 .WillOnce(Return(std::vector<PerFrameMetadataKey>()));
664 }
665};
666
667// For this variant, SurfaceFlinger should configure itself with wide display
668// support, but the display should respond with an empty list of supported color
669// modes. Wide-color support for the display should not be configured.
670template <typename Display>
671struct WideColorNotSupportedVariant {
672 static constexpr bool WIDE_COLOR_SUPPORTED = false;
673
674 static void injectConfigChange(DisplayTransactionTest* test) {
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200675 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.
688struct WideColorSupportNotConfiguredVariant {
689 static constexpr bool WIDE_COLOR_SUPPORTED = false;
690
691 static void injectConfigChange(DisplayTransactionTest* test) {
692 test->mFlinger.mutableHasWideColorDisplay() = false;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200693 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
694 }
695
696 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
697 EXPECT_CALL(*test->mComposer, getColorModes(_, _)).Times(0);
698 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
699 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
700 }
701};
702
703/* ------------------------------------------------------------------------
704 * Typical display configurations to test
705 */
706
707template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy,
708 typename PerFrameMetadataSupportPolicy>
709struct Case {
710 using Display = DisplayPolicy;
711 using WideColorSupport = WideColorSupportPolicy;
712 using HdrSupport = HdrSupportPolicy;
713 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy;
714};
715
716using SimplePrimaryDisplayCase =
717 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
718 HdrNotSupportedVariant<PrimaryDisplayVariant>,
719 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
720using SimpleExternalDisplayCase =
721 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
722 HdrNotSupportedVariant<ExternalDisplayVariant>,
723 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
724using SimpleTertiaryDisplayCase =
725 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
726 HdrNotSupportedVariant<TertiaryDisplayVariant>,
727 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
728
729using NonHwcVirtualDisplayCase =
730 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
731 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant,
732 NonHwcPerFrameMetadataSupportVariant>;
733using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
734using HwcVirtualDisplayCase =
735 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
736 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>,
737 NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>;
738
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800739inline DisplayModePtr createDisplayMode(DisplayModeId modeId, Fps refreshRate, int32_t group = 0,
740 ui::Size resolution = ui::Size(1920, 1080)) {
741 return mock::createDisplayMode(modeId, refreshRate, group, resolution,
742 PrimaryDisplayVariant::DISPLAY_ID::get());
743}
744
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200745} // namespace android
746
747// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +0100748#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"