blob: 20e776f1f2ec3d7bb01b037ef7ed48b4b2d29226 [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
Dominik Laskowskieb627312022-04-07 09:13:16 -070098 bool hasPhysicalHwcDisplay(hal::HWDisplayId) const;
99 bool hasTransactionFlagSet(int32_t flag) const;
100
101 bool hasDisplayDevice(const sp<IBinder>& displayToken) const;
102 const DisplayDevice& getDisplayDevice(const sp<IBinder>& displayToken) const;
103
104 bool hasCurrentDisplayState(const sp<IBinder>& displayToken) const;
105 const DisplayDeviceState& getCurrentDisplayState(const sp<IBinder>& displayToken) const;
106
107 bool hasDrawingDisplayState(const sp<IBinder>& displayToken) const;
108 const DisplayDeviceState& getDrawingDisplayState(const sp<IBinder>& displayToken) const;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200109
110 // --------------------------------------------------------------------
111 // Test instances
112
113 TestableSurfaceFlinger mFlinger;
Ady Abrahamd11bade2022-08-01 16:18:03 -0700114 sp<mock::NativeWindow> mNativeWindow = sp<mock::NativeWindow>::make();
115 sp<GraphicBuffer> mBuffer = sp<GraphicBuffer>::make();
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200116 Hwc2::mock::PowerAdvisor mPowerAdvisor;
117
118 // These mocks are created by the test, but are destroyed by SurfaceFlinger
119 // by virtue of being stored into a std::unique_ptr. However we still need
120 // to keep a reference to them for use in setting up call expectations.
121 renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
122 Hwc2::mock::Composer* mComposer = nullptr;
Ady Abrahamd11bade2022-08-01 16:18:03 -0700123 sp<mock::SurfaceInterceptor> mSurfaceInterceptor = sp<mock::SurfaceInterceptor>::make();
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200124
125 mock::VsyncController* mVsyncController = new mock::VsyncController;
126 mock::VSyncTracker* mVSyncTracker = new mock::VSyncTracker;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200127 mock::EventThread* mEventThread = new mock::EventThread;
128 mock::EventThread* mSFEventThread = new mock::EventThread;
129
130 // These mocks are created only when expected to be created via a factory.
131 sp<mock::GraphicBufferConsumer> mConsumer;
132 sp<mock::GraphicBufferProducer> mProducer;
133 surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
134
135protected:
136 DisplayTransactionTest();
137};
138
Marin Shalamanova903d032020-12-29 20:35:13 +0100139constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'667;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200140constexpr int32_t DEFAULT_DPI = 320;
141constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
142
143constexpr int POWER_MODE_LEET = 1337; // An out of range power mode value
144
145/* ------------------------------------------------------------------------
146 * Boolean avoidance
147 *
148 * To make calls and template instantiations more readable, we define some
149 * local enums along with an implicit bool conversion.
150 */
151
152#define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true };
153
154BOOL_SUBSTITUTE(Async);
155BOOL_SUBSTITUTE(Critical);
156BOOL_SUBSTITUTE(Primary);
157BOOL_SUBSTITUTE(Secure);
158BOOL_SUBSTITUTE(Virtual);
159
160template <typename PhysicalDisplay>
161struct PhysicalDisplayIdType {};
162
163template <uint64_t displayId>
164using HalVirtualDisplayIdType = std::integral_constant<uint64_t, displayId>;
165
166struct GpuVirtualDisplayIdType {};
167
168template <typename>
169struct IsPhysicalDisplayId : std::bool_constant<false> {};
170
171template <typename PhysicalDisplay>
172struct IsPhysicalDisplayId<PhysicalDisplayIdType<PhysicalDisplay>> : std::bool_constant<true> {};
173
174template <typename>
175struct DisplayIdGetter;
176
177template <typename PhysicalDisplay>
178struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
179 static PhysicalDisplayId get() {
180 if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
181 return PhysicalDisplayId::fromPort(static_cast<bool>(PhysicalDisplay::PRIMARY)
182 ? LEGACY_DISPLAY_TYPE_PRIMARY
183 : LEGACY_DISPLAY_TYPE_EXTERNAL);
184 }
185
186 const auto info =
187 parseDisplayIdentificationData(PhysicalDisplay::PORT,
188 PhysicalDisplay::GET_IDENTIFICATION_DATA());
189 return info ? info->id : PhysicalDisplayId::fromPort(PhysicalDisplay::PORT);
190 }
191};
192
193template <uint64_t displayId>
194struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
195 static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); }
196};
197
198template <>
199struct DisplayIdGetter<GpuVirtualDisplayIdType> {
200 static GpuVirtualDisplayId get() { return GpuVirtualDisplayId(0); }
201};
202
203template <typename>
204struct DisplayConnectionTypeGetter {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100205 static constexpr std::optional<ui::DisplayConnectionType> value;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200206};
207
208template <typename PhysicalDisplay>
209struct DisplayConnectionTypeGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100210 static constexpr std::optional<ui::DisplayConnectionType> value =
211 PhysicalDisplay::CONNECTION_TYPE;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200212};
213
214template <typename>
215struct HwcDisplayIdGetter {
216 static constexpr std::optional<HWDisplayId> value;
217};
218
219constexpr HWDisplayId HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
220
221template <uint64_t displayId>
222struct HwcDisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
223 static constexpr std::optional<HWDisplayId> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
224};
225
226template <typename PhysicalDisplay>
227struct HwcDisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
228 static constexpr std::optional<HWDisplayId> value = PhysicalDisplay::HWC_DISPLAY_ID;
229};
230
231// DisplayIdType can be:
232// 1) PhysicalDisplayIdType<...> for generated ID of physical display backed by HWC.
233// 2) HalVirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC.
234// 3) GpuVirtualDisplayIdType for virtual display without HWC backing.
235template <typename DisplayIdType, int width, int height, Critical critical, Async async,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700236 Secure secure, Primary primary, int grallocUsage, int displayFlags>
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200237struct DisplayVariant {
238 using DISPLAY_ID = DisplayIdGetter<DisplayIdType>;
239 using CONNECTION_TYPE = DisplayConnectionTypeGetter<DisplayIdType>;
240 using HWC_DISPLAY_ID_OPT = HwcDisplayIdGetter<DisplayIdType>;
241
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200242 static constexpr int WIDTH = width;
243 static constexpr int HEIGHT = height;
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800244 static constexpr ui::Size RESOLUTION{WIDTH, HEIGHT};
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200245
246 static constexpr int GRALLOC_USAGE = grallocUsage;
247
248 // Whether the display is virtual or physical
249 static constexpr Virtual VIRTUAL =
250 IsPhysicalDisplayId<DisplayIdType>{} ? Virtual::FALSE : Virtual::TRUE;
251
252 // When creating native window surfaces for the framebuffer, whether those should be critical
253 static constexpr Critical CRITICAL = critical;
254
255 // When creating native window surfaces for the framebuffer, whether those should be async
256 static constexpr Async ASYNC = async;
257
258 // Whether the display should be treated as secure
259 static constexpr Secure SECURE = secure;
260
261 // Whether the display is primary
262 static constexpr Primary PRIMARY = primary;
263
Vishnu Naira119aaa2021-09-24 07:19:35 -0700264 static constexpr int DISPLAY_FLAGS = displayFlags;
265
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200266 static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
267 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder();
Dominik Laskowski13948602021-03-08 20:48:28 -0800268 ceDisplayArgs.setId(DISPLAY_ID::get())
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800269 .setPixels(RESOLUTION)
Dominik Laskowski13948602021-03-08 20:48:28 -0800270 .setPowerAdvisor(&test->mPowerAdvisor);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200271
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200272 auto compositionDisplay =
273 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
274 ceDisplayArgs.build());
275
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200276 auto injector =
277 TestableSurfaceFlinger::FakeDisplayDeviceInjector(test->mFlinger,
278 compositionDisplay,
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700279 CONNECTION_TYPE::value,
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200280 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
339template <HWDisplayId hwcDisplayId, DisplayType hwcDisplayType, typename DisplayVariant,
340 typename PhysicalDisplay = void>
341struct 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
Marin Shalamanov6e840172020-12-14 22:13:28 +0100349 static constexpr hal::HWConfigId HWC_ACTIVE_CONFIG_ID = 2001;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200350 static constexpr PowerMode INIT_POWER_MODE = hal::PowerMode::ON;
351
352 static void injectPendingHotplugEvent(DisplayTransactionTest* test, Connection connection) {
353 test->mFlinger.mutablePendingHotplugEvents().emplace_back(
354 TestableSurfaceFlinger::HotplugEvent{HWC_DISPLAY_ID, connection});
355 }
356
357 // Called by tests to inject a HWC display setup
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)
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800364 .setResolution(DisplayVariant::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200365 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
366 .setPowerMode(INIT_POWER_MODE)
367 .inject(&test->mFlinger, test->mComposer);
368 }
369
370 // Called by tests to inject a HWC display setup
371 static void injectHwcDisplay(DisplayTransactionTest* test) {
372 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
373 .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})),
374 Return(Error::NONE)));
375 EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, INIT_POWER_MODE))
376 .WillOnce(Return(Error::NONE));
377 injectHwcDisplayWithNoDefaultCapabilities(test);
378 }
379
380 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
381 DisplayTransactionTest* test) {
382 const ::testing::TestInfo* const test_info =
383 ::testing::UnitTest::GetInstance()->current_test_info();
384
385 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800386 .setId(DisplayVariant::DISPLAY_ID::get())
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800387 .setPixels(DisplayVariant::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200388 .setIsSecure(static_cast<bool>(DisplayVariant::SECURE))
389 .setPowerAdvisor(&test->mPowerAdvisor)
390 .setName(std::string("Injected display for ") +
391 test_info->test_case_name() + "." + test_info->name())
392 .build();
393
394 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
395 ceDisplayArgs);
396 }
397
Marin Shalamanov6e840172020-12-14 22:13:28 +0100398 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
399 if (HWC_DISPLAY_TYPE == DisplayType::PHYSICAL) {
400 EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
401 .WillRepeatedly(DoAll(SetArgPointee<1>(std::vector<hal::HWConfigId>{
402 HWC_ACTIVE_CONFIG_ID}),
403 Return(Error::NONE)));
404 EXPECT_CALL(*test->mComposer,
405 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
406 IComposerClient::Attribute::WIDTH, _))
407 .WillRepeatedly(
408 DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
409 EXPECT_CALL(*test->mComposer,
410 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
411 IComposerClient::Attribute::HEIGHT, _))
412 .WillRepeatedly(
413 DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
414 EXPECT_CALL(*test->mComposer,
415 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
416 IComposerClient::Attribute::VSYNC_PERIOD, _))
417 .WillRepeatedly(
Marin Shalamanova903d032020-12-29 20:35:13 +0100418 DoAll(SetArgPointee<3>(DEFAULT_VSYNC_PERIOD), Return(Error::NONE)));
Marin Shalamanov6e840172020-12-14 22:13:28 +0100419 EXPECT_CALL(*test->mComposer,
420 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
421 IComposerClient::Attribute::DPI_X, _))
422 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
423 EXPECT_CALL(*test->mComposer,
424 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
425 IComposerClient::Attribute::DPI_Y, _))
426 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
427 EXPECT_CALL(*test->mComposer,
428 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
429 IComposerClient::Attribute::CONFIG_GROUP, _))
430 .WillRepeatedly(DoAll(SetArgPointee<3>(-1), Return(Error::NONE)));
431 } else {
432 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
433 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
434 }
435 }
436
Dominik Laskowskibab51282022-08-12 09:28:55 -0700437 template <bool kFailedHotplug = false>
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200438 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
Dominik Laskowskibab51282022-08-12 09:28:55 -0700439 if constexpr (!kFailedHotplug) {
440 constexpr auto CONNECTION_TYPE =
441 PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal
442 ? IComposerClient::DisplayConnectionType::INTERNAL
443 : IComposerClient::DisplayConnectionType::EXTERNAL;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200444
Dominik Laskowskibab51282022-08-12 09:28:55 -0700445 EXPECT_CALL(*test->mComposer, getDisplayConnectionType(HWC_DISPLAY_ID, _))
446 .WillOnce(DoAll(SetArgPointee<1>(CONNECTION_TYPE),
447 Return(hal::V2_4::Error::NONE)));
448 }
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200449
450 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_))
451 .WillOnce(Return(hal::Error::NONE));
Marin Shalamanov6e840172020-12-14 22:13:28 +0100452
453 setupHwcGetConfigsCallExpectations(test);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200454
455 if (PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
456 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
457 .WillOnce(DoAll(SetArgPointee<1>(PhysicalDisplay::PORT),
458 SetArgPointee<2>(PhysicalDisplay::GET_IDENTIFICATION_DATA()),
459 Return(Error::NONE)));
460 } else {
461 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
462 .WillOnce(Return(Error::UNSUPPORTED));
463 }
464 }
465
466 // Called by tests to set up HWC call expectations
467 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
468 EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
469 .WillRepeatedly(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
470 }
471};
472
473// Physical displays are expected to be synchronous, secure, and have a HWC display for output.
474constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
475 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
476
Vishnu Naira119aaa2021-09-24 07:19:35 -0700477constexpr int PHYSICAL_DISPLAY_FLAGS = 0x1;
478
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200479template <typename PhysicalDisplay, int width, int height, Critical critical>
480struct PhysicalDisplayVariant
481 : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, critical,
482 Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700483 GRALLOC_USAGE_PHYSICAL_DISPLAY, PHYSICAL_DISPLAY_FLAGS>,
484 HwcDisplayVariant<
485 PhysicalDisplay::HWC_DISPLAY_ID, DisplayType::PHYSICAL,
486 DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, critical,
487 Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
488 GRALLOC_USAGE_PHYSICAL_DISPLAY, PHYSICAL_DISPLAY_FLAGS>,
489 PhysicalDisplay> {};
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200490
491template <bool hasIdentificationData>
492struct PrimaryDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100493 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200494 static constexpr Primary PRIMARY = Primary::TRUE;
495 static constexpr uint8_t PORT = 255;
496 static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
497 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
498 static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
499};
500
501template <bool hasIdentificationData>
502struct ExternalDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100503 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200504 static constexpr Primary PRIMARY = Primary::FALSE;
505 static constexpr uint8_t PORT = 254;
506 static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
507 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
508 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
509};
510
511struct TertiaryDisplay {
512 static constexpr Primary PRIMARY = Primary::FALSE;
513 static constexpr uint8_t PORT = 253;
514 static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
515 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
516};
517
518// A primary display is a physical display that is critical
519using PrimaryDisplayVariant =
520 PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>;
521
522// An external display is physical display that is not critical.
523using ExternalDisplayVariant =
524 PhysicalDisplayVariant<ExternalDisplay<false>, 1920, 1280, Critical::FALSE>;
525
526using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200, Critical::FALSE>;
527
528// A virtual display not supported by the HWC.
529constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
530
Vishnu Naira119aaa2021-09-24 07:19:35 -0700531constexpr int VIRTUAL_DISPLAY_FLAGS = 0x0;
532
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200533template <int width, int height, Secure secure>
534struct NonHwcVirtualDisplayVariant
535 : DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE, secure,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700536 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY,
537 VIRTUAL_DISPLAY_FLAGS> {
538 using Base = DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE,
539 Async::TRUE, secure, Primary::FALSE,
540 GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY, VIRTUAL_DISPLAY_FLAGS>;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200541
542 static void injectHwcDisplay(DisplayTransactionTest*) {}
543
544 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
545 DisplayTransactionTest* test) {
546 const ::testing::TestInfo* const test_info =
547 ::testing::UnitTest::GetInstance()->current_test_info();
548
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200549 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800550 .setId(Base::DISPLAY_ID::get())
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800551 .setPixels(Base::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200552 .setIsSecure(static_cast<bool>(Base::SECURE))
553 .setPowerAdvisor(&test->mPowerAdvisor)
554 .setName(std::string("Injected display for ") +
555 test_info->test_case_name() + "." + test_info->name())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200556 .build();
557
558 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
559 ceDisplayArgs);
560 }
561
Marin Shalamanov6e840172020-12-14 22:13:28 +0100562 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
563 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
564 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
565 }
566
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200567 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
568 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
569 }
570
571 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
572 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
573 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
574 }
575};
576
577// A virtual display supported by the HWC.
578constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
579
580template <int width, int height, Secure secure>
581struct HwcVirtualDisplayVariant
582 : DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700583 secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY,
584 VIRTUAL_DISPLAY_FLAGS>,
585 HwcDisplayVariant<
586 HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
587 DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
588 Async::TRUE, secure, Primary::FALSE,
589 GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY, VIRTUAL_DISPLAY_FLAGS>> {
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200590 using Base = DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700591 Async::TRUE, secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER,
592 VIRTUAL_DISPLAY_FLAGS>;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200593 using Self = HwcVirtualDisplayVariant<width, height, secure>;
594
595 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
596 DisplayTransactionTest* test) {
597 const ::testing::TestInfo* const test_info =
598 ::testing::UnitTest::GetInstance()->current_test_info();
599
Dominik Laskowski13948602021-03-08 20:48:28 -0800600 const auto displayId = Base::DISPLAY_ID::get();
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200601 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800602 .setId(displayId)
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800603 .setPixels(Base::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200604 .setIsSecure(static_cast<bool>(Base::SECURE))
605 .setPowerAdvisor(&test->mPowerAdvisor)
606 .setName(std::string("Injected display for ") +
607 test_info->test_case_name() + "." + test_info->name())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200608 .build();
609
610 auto compositionDisplay =
611 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
612 ceDisplayArgs);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200613
614 // Insert display data so that the HWC thinks it created the virtual display.
Dominik Laskowski13948602021-03-08 20:48:28 -0800615 test->mFlinger.mutableHwcDisplayData().try_emplace(displayId);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200616
617 return compositionDisplay;
618 }
619
620 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
621 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
622 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
623 }
624
625 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
Dominik Laskowski263eec42021-07-21 23:13:24 -0700626 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
627 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200628 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
629 }
630};
631
632// For this variant, the display is not a HWC display, so no HDR support should
633// be configured.
634struct NonHwcDisplayHdrSupportVariant {
635 static constexpr bool HDR10_PLUS_SUPPORTED = false;
636 static constexpr bool HDR10_SUPPORTED = false;
637 static constexpr bool HDR_HLG_SUPPORTED = false;
638 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
639 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
640 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
641 }
642};
643
644// For this variant, the composer should respond with am empty list of HDR
645// modes, so no HDR support should be configured.
646template <typename Display>
647struct HdrNotSupportedVariant {
648 static constexpr bool HDR10_PLUS_SUPPORTED = false;
649 static constexpr bool HDR10_SUPPORTED = false;
650 static constexpr bool HDR_HLG_SUPPORTED = false;
651 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
652 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
653 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
654 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
655 }
656};
657
658struct NonHwcPerFrameMetadataSupportVariant {
659 static constexpr int PER_FRAME_METADATA_KEYS = 0;
660 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
661 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_)).Times(0);
662 }
663};
664
665template <typename Display>
666struct NoPerFrameMetadataSupportVariant {
667 static constexpr int PER_FRAME_METADATA_KEYS = 0;
668 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
669 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
670 .WillOnce(Return(std::vector<PerFrameMetadataKey>()));
671 }
672};
673
674// For this variant, SurfaceFlinger should configure itself with wide display
675// support, but the display should respond with an empty list of supported color
676// modes. Wide-color support for the display should not be configured.
677template <typename Display>
678struct WideColorNotSupportedVariant {
679 static constexpr bool WIDE_COLOR_SUPPORTED = false;
680
681 static void injectConfigChange(DisplayTransactionTest* test) {
Dominik Laskowski788945b2022-08-30 12:10:56 -0700682 test->mFlinger.mutableSupportsWideColor() = true;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200683 }
684
685 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200686 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
687 }
688};
689
690// For this variant, SurfaceFlinger should not configure itself with wide
691// display support, so the display should not be configured for wide-color
692// support.
693struct WideColorSupportNotConfiguredVariant {
694 static constexpr bool WIDE_COLOR_SUPPORTED = false;
695
696 static void injectConfigChange(DisplayTransactionTest* test) {
Dominik Laskowski788945b2022-08-30 12:10:56 -0700697 test->mFlinger.mutableSupportsWideColor() = false;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200698 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
699 }
700
701 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200702 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
703 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
704 }
705};
706
707/* ------------------------------------------------------------------------
708 * Typical display configurations to test
709 */
710
711template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy,
712 typename PerFrameMetadataSupportPolicy>
713struct Case {
714 using Display = DisplayPolicy;
715 using WideColorSupport = WideColorSupportPolicy;
716 using HdrSupport = HdrSupportPolicy;
717 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy;
718};
719
720using SimplePrimaryDisplayCase =
721 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
722 HdrNotSupportedVariant<PrimaryDisplayVariant>,
723 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
724using SimpleExternalDisplayCase =
725 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
726 HdrNotSupportedVariant<ExternalDisplayVariant>,
727 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
728using SimpleTertiaryDisplayCase =
729 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
730 HdrNotSupportedVariant<TertiaryDisplayVariant>,
731 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
732
733using NonHwcVirtualDisplayCase =
734 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
735 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant,
736 NonHwcPerFrameMetadataSupportVariant>;
737using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
738using HwcVirtualDisplayCase =
739 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
740 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>,
741 NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>;
742
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800743inline DisplayModePtr createDisplayMode(DisplayModeId modeId, Fps refreshRate, int32_t group = 0,
744 ui::Size resolution = ui::Size(1920, 1080)) {
745 return mock::createDisplayMode(modeId, refreshRate, group, resolution,
746 PrimaryDisplayVariant::DISPLAY_ID::get());
747}
748
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200749} // namespace android
750
751// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +0100752#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"