blob: 57d1d9c4d2155e83880e257a241c840544dac2a3 [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
Dominik Laskowski327d6092022-10-11 18:05:08 -040045#include "FakeDisplayInjector.h"
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020046#include "TestableScheduler.h"
47#include "TestableSurfaceFlinger.h"
48#include "mock/DisplayHardware/MockComposer.h"
Dominik Laskowskib0054a22022-03-03 09:03:06 -080049#include "mock/DisplayHardware/MockDisplayMode.h"
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020050#include "mock/DisplayHardware/MockPowerAdvisor.h"
51#include "mock/MockEventThread.h"
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020052#include "mock/MockNativeWindowSurface.h"
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020053#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
Dominik Laskowskiaee9a622023-02-11 14:24:19 -050088 void injectMockScheduler(PhysicalDisplayId);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020089 void injectMockComposer(int virtualDisplayCount);
90 void injectFakeBufferQueueFactory();
91 void injectFakeNativeWindowSurfaceFactory();
Dominik Laskowski327d6092022-10-11 18:05:08 -040092
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020093 sp<DisplayDevice> injectDefaultInternalDisplay(
Dominik Laskowski327d6092022-10-11 18:05:08 -040094 std::function<void(TestableSurfaceFlinger::FakeDisplayDeviceInjector&)> injectExtra) {
95 return mFakeDisplayInjector.injectInternalDisplay(injectExtra);
96 }
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020097
98 // --------------------------------------------------------------------
99 // Postcondition helpers
100
Dominik Laskowskieb627312022-04-07 09:13:16 -0700101 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;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200112
113 // --------------------------------------------------------------------
114 // Test instances
115
116 TestableSurfaceFlinger mFlinger;
Ady Abrahamd11bade2022-08-01 16:18:03 -0700117 sp<mock::NativeWindow> mNativeWindow = sp<mock::NativeWindow>::make();
Brian Lindahlf5ab5ae2022-12-21 14:27:15 -0700118 sp<GraphicBuffer> mBuffer =
119 sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_8888,
120 GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200121 Hwc2::mock::PowerAdvisor mPowerAdvisor;
122
Dominik Laskowski327d6092022-10-11 18:05:08 -0400123 FakeDisplayInjector mFakeDisplayInjector{mFlinger, mPowerAdvisor, mNativeWindow};
124
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200125 // These mocks are created by the test, but are destroyed by SurfaceFlinger
126 // by virtue of being stored into a std::unique_ptr. However we still need
127 // to keep a reference to them for use in setting up call expectations.
128 renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
129 Hwc2::mock::Composer* mComposer = nullptr;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200130
Leon Scroggins IIIdb16a2b2023-02-06 17:50:05 -0500131 mock::VsyncController* mVsyncController = new mock::VsyncController;
132 mock::VSyncTracker* mVSyncTracker = new mock::VSyncTracker;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200133 mock::EventThread* mEventThread = new mock::EventThread;
134 mock::EventThread* mSFEventThread = new mock::EventThread;
135
136 // These mocks are created only when expected to be created via a factory.
137 sp<mock::GraphicBufferConsumer> mConsumer;
138 sp<mock::GraphicBufferProducer> mProducer;
139 surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
140
141protected:
Dominik Laskowskiaee9a622023-02-11 14:24:19 -0500142 DisplayTransactionTest(bool withMockScheduler = true);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200143};
144
Marin Shalamanova903d032020-12-29 20:35:13 +0100145constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'667;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200146constexpr int32_t DEFAULT_DPI = 320;
147constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
148
149constexpr int POWER_MODE_LEET = 1337; // An out of range power mode value
150
151/* ------------------------------------------------------------------------
152 * Boolean avoidance
153 *
154 * To make calls and template instantiations more readable, we define some
155 * local enums along with an implicit bool conversion.
156 */
157
158#define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true };
159
160BOOL_SUBSTITUTE(Async);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200161BOOL_SUBSTITUTE(Primary);
162BOOL_SUBSTITUTE(Secure);
163BOOL_SUBSTITUTE(Virtual);
164
165template <typename PhysicalDisplay>
166struct PhysicalDisplayIdType {};
167
168template <uint64_t displayId>
169using HalVirtualDisplayIdType = std::integral_constant<uint64_t, displayId>;
170
171struct GpuVirtualDisplayIdType {};
172
173template <typename>
174struct IsPhysicalDisplayId : std::bool_constant<false> {};
175
176template <typename PhysicalDisplay>
177struct IsPhysicalDisplayId<PhysicalDisplayIdType<PhysicalDisplay>> : std::bool_constant<true> {};
178
179template <typename>
180struct DisplayIdGetter;
181
182template <typename PhysicalDisplay>
183struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
184 static PhysicalDisplayId get() {
185 if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
186 return PhysicalDisplayId::fromPort(static_cast<bool>(PhysicalDisplay::PRIMARY)
187 ? LEGACY_DISPLAY_TYPE_PRIMARY
188 : LEGACY_DISPLAY_TYPE_EXTERNAL);
189 }
190
191 const auto info =
192 parseDisplayIdentificationData(PhysicalDisplay::PORT,
193 PhysicalDisplay::GET_IDENTIFICATION_DATA());
194 return info ? info->id : PhysicalDisplayId::fromPort(PhysicalDisplay::PORT);
195 }
196};
197
198template <uint64_t displayId>
199struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
200 static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); }
201};
202
203template <>
204struct DisplayIdGetter<GpuVirtualDisplayIdType> {
205 static GpuVirtualDisplayId get() { return GpuVirtualDisplayId(0); }
206};
207
208template <typename>
209struct DisplayConnectionTypeGetter {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100210 static constexpr std::optional<ui::DisplayConnectionType> value;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200211};
212
213template <typename PhysicalDisplay>
214struct DisplayConnectionTypeGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100215 static constexpr std::optional<ui::DisplayConnectionType> value =
216 PhysicalDisplay::CONNECTION_TYPE;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200217};
218
219template <typename>
220struct HwcDisplayIdGetter {
221 static constexpr std::optional<HWDisplayId> value;
222};
223
224constexpr HWDisplayId HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
225
226template <uint64_t displayId>
227struct HwcDisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
228 static constexpr std::optional<HWDisplayId> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
229};
230
231template <typename PhysicalDisplay>
232struct HwcDisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
233 static constexpr std::optional<HWDisplayId> value = PhysicalDisplay::HWC_DISPLAY_ID;
234};
235
236// DisplayIdType can be:
237// 1) PhysicalDisplayIdType<...> for generated ID of physical display backed by HWC.
238// 2) HalVirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC.
239// 3) GpuVirtualDisplayIdType for virtual display without HWC backing.
Dominik Laskowskie80bd312023-02-11 16:23:34 -0500240template <typename DisplayIdType, int width, int height, Async async, Secure secure,
241 Primary primary, int grallocUsage, int displayFlags>
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200242struct DisplayVariant {
243 using DISPLAY_ID = DisplayIdGetter<DisplayIdType>;
244 using CONNECTION_TYPE = DisplayConnectionTypeGetter<DisplayIdType>;
245 using HWC_DISPLAY_ID_OPT = HwcDisplayIdGetter<DisplayIdType>;
246
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200247 static constexpr int WIDTH = width;
248 static constexpr int HEIGHT = height;
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800249 static constexpr ui::Size RESOLUTION{WIDTH, HEIGHT};
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200250
251 static constexpr int GRALLOC_USAGE = grallocUsage;
252
253 // Whether the display is virtual or physical
254 static constexpr Virtual VIRTUAL =
255 IsPhysicalDisplayId<DisplayIdType>{} ? Virtual::FALSE : Virtual::TRUE;
256
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200257 // When creating native window surfaces for the framebuffer, whether those should be async
258 static constexpr Async ASYNC = async;
259
260 // Whether the display should be treated as secure
261 static constexpr Secure SECURE = secure;
262
263 // Whether the display is primary
264 static constexpr Primary PRIMARY = primary;
265
Vishnu Naira119aaa2021-09-24 07:19:35 -0700266 static constexpr int DISPLAY_FLAGS = displayFlags;
267
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200268 static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
269 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder();
Dominik Laskowski13948602021-03-08 20:48:28 -0800270 ceDisplayArgs.setId(DISPLAY_ID::get())
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800271 .setPixels(RESOLUTION)
Dominik Laskowski13948602021-03-08 20:48:28 -0800272 .setPowerAdvisor(&test->mPowerAdvisor);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200273
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200274 auto compositionDisplay =
275 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
276 ceDisplayArgs.build());
277
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200278 auto injector =
279 TestableSurfaceFlinger::FakeDisplayDeviceInjector(test->mFlinger,
280 compositionDisplay,
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700281 CONNECTION_TYPE::value,
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200282 HWC_DISPLAY_ID_OPT::value,
283 static_cast<bool>(PRIMARY));
284
285 injector.setSecure(static_cast<bool>(SECURE));
286 injector.setNativeWindow(test->mNativeWindow);
287
288 // Creating a DisplayDevice requires getting default dimensions from the
289 // native window along with some other initial setup.
290 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
291 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
292 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
293 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
294 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
295 .WillRepeatedly(Return(0));
296 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
297 .WillRepeatedly(Return(0));
298 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
299 .WillRepeatedly(Return(0));
300 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
301 .WillRepeatedly(Return(0));
302
303 return injector;
304 }
305
306 // Called by tests to set up any native window creation call expectations.
307 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
308 EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
309 .WillOnce(Return(test->mNativeWindow));
310
311 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
312 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
313 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
314 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
315 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
316 .WillRepeatedly(Return(0));
317 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
318 .WillRepeatedly(Return(0));
319 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
320 .WillRepeatedly(Return(0));
321 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
322 .WillRepeatedly(Return(0));
323 }
324
325 static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
326 EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
327 EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
328 EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
329 .WillRepeatedly(Return(NO_ERROR));
330 EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
331 .WillRepeatedly(Return(NO_ERROR));
332 EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
333 .WillRepeatedly(Return(NO_ERROR));
334 }
335
336 static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
337 EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
338 }
339};
340
341template <HWDisplayId hwcDisplayId, DisplayType hwcDisplayType, typename DisplayVariant,
342 typename PhysicalDisplay = void>
343struct HwcDisplayVariant {
344 // The display id supplied by the HWC
345 static constexpr HWDisplayId HWC_DISPLAY_ID = hwcDisplayId;
346
347 // The HWC display type
348 static constexpr DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
349
350 // The HWC active configuration id
Marin Shalamanov6e840172020-12-14 22:13:28 +0100351 static constexpr hal::HWConfigId HWC_ACTIVE_CONFIG_ID = 2001;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200352 static constexpr PowerMode INIT_POWER_MODE = hal::PowerMode::ON;
353
354 static void injectPendingHotplugEvent(DisplayTransactionTest* test, Connection connection) {
355 test->mFlinger.mutablePendingHotplugEvents().emplace_back(
356 TestableSurfaceFlinger::HotplugEvent{HWC_DISPLAY_ID, connection});
357 }
358
359 // Called by tests to inject a HWC display setup
Dominik Laskowskic132a152022-11-30 15:44:52 -0500360 template <bool kInitPowerMode = true>
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200361 static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
362 const auto displayId = DisplayVariant::DISPLAY_ID::get();
363 ASSERT_FALSE(GpuVirtualDisplayId::tryCast(displayId));
364 TestableSurfaceFlinger::FakeHwcDisplayInjector(displayId, HWC_DISPLAY_TYPE,
365 static_cast<bool>(DisplayVariant::PRIMARY))
366 .setHwcDisplayId(HWC_DISPLAY_ID)
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800367 .setResolution(DisplayVariant::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200368 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
Dominik Laskowskic132a152022-11-30 15:44:52 -0500369 .setPowerMode(kInitPowerMode ? std::make_optional(INIT_POWER_MODE) : std::nullopt)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200370 .inject(&test->mFlinger, test->mComposer);
371 }
372
373 // Called by tests to inject a HWC display setup
Dominik Laskowskic132a152022-11-30 15:44:52 -0500374 template <bool kInitPowerMode = true>
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200375 static void injectHwcDisplay(DisplayTransactionTest* test) {
376 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
377 .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})),
378 Return(Error::NONE)));
Dominik Laskowskic132a152022-11-30 15:44:52 -0500379 if constexpr (kInitPowerMode) {
380 EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, INIT_POWER_MODE))
381 .WillOnce(Return(Error::NONE));
382 }
383 injectHwcDisplayWithNoDefaultCapabilities<kInitPowerMode>(test);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200384 }
385
386 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
387 DisplayTransactionTest* test) {
388 const ::testing::TestInfo* const test_info =
389 ::testing::UnitTest::GetInstance()->current_test_info();
390
391 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800392 .setId(DisplayVariant::DISPLAY_ID::get())
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800393 .setPixels(DisplayVariant::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200394 .setIsSecure(static_cast<bool>(DisplayVariant::SECURE))
395 .setPowerAdvisor(&test->mPowerAdvisor)
396 .setName(std::string("Injected display for ") +
397 test_info->test_case_name() + "." + test_info->name())
398 .build();
399
400 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
401 ceDisplayArgs);
402 }
403
Marin Shalamanov6e840172020-12-14 22:13:28 +0100404 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
405 if (HWC_DISPLAY_TYPE == DisplayType::PHYSICAL) {
406 EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
407 .WillRepeatedly(DoAll(SetArgPointee<1>(std::vector<hal::HWConfigId>{
408 HWC_ACTIVE_CONFIG_ID}),
409 Return(Error::NONE)));
410 EXPECT_CALL(*test->mComposer,
411 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
412 IComposerClient::Attribute::WIDTH, _))
413 .WillRepeatedly(
414 DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
415 EXPECT_CALL(*test->mComposer,
416 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
417 IComposerClient::Attribute::HEIGHT, _))
418 .WillRepeatedly(
419 DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
420 EXPECT_CALL(*test->mComposer,
421 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
422 IComposerClient::Attribute::VSYNC_PERIOD, _))
423 .WillRepeatedly(
Marin Shalamanova903d032020-12-29 20:35:13 +0100424 DoAll(SetArgPointee<3>(DEFAULT_VSYNC_PERIOD), Return(Error::NONE)));
Marin Shalamanov6e840172020-12-14 22:13:28 +0100425 EXPECT_CALL(*test->mComposer,
426 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
427 IComposerClient::Attribute::DPI_X, _))
428 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
429 EXPECT_CALL(*test->mComposer,
430 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
431 IComposerClient::Attribute::DPI_Y, _))
432 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
433 EXPECT_CALL(*test->mComposer,
434 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
435 IComposerClient::Attribute::CONFIG_GROUP, _))
436 .WillRepeatedly(DoAll(SetArgPointee<3>(-1), Return(Error::NONE)));
437 } else {
438 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
439 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
440 }
441 }
442
Dominik Laskowskibab51282022-08-12 09:28:55 -0700443 template <bool kFailedHotplug = false>
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200444 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
Dominik Laskowskibab51282022-08-12 09:28:55 -0700445 if constexpr (!kFailedHotplug) {
446 constexpr auto CONNECTION_TYPE =
447 PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal
448 ? IComposerClient::DisplayConnectionType::INTERNAL
449 : IComposerClient::DisplayConnectionType::EXTERNAL;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200450
Dominik Laskowskibab51282022-08-12 09:28:55 -0700451 EXPECT_CALL(*test->mComposer, getDisplayConnectionType(HWC_DISPLAY_ID, _))
452 .WillOnce(DoAll(SetArgPointee<1>(CONNECTION_TYPE),
453 Return(hal::V2_4::Error::NONE)));
454 }
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200455
456 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_))
457 .WillOnce(Return(hal::Error::NONE));
Marin Shalamanov6e840172020-12-14 22:13:28 +0100458
459 setupHwcGetConfigsCallExpectations(test);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200460
461 if (PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
462 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
463 .WillOnce(DoAll(SetArgPointee<1>(PhysicalDisplay::PORT),
464 SetArgPointee<2>(PhysicalDisplay::GET_IDENTIFICATION_DATA()),
465 Return(Error::NONE)));
466 } else {
467 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
468 .WillOnce(Return(Error::UNSUPPORTED));
469 }
470 }
471
472 // Called by tests to set up HWC call expectations
473 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
474 EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
475 .WillRepeatedly(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
476 }
477};
478
479// Physical displays are expected to be synchronous, secure, and have a HWC display for output.
480constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
481 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
482
Vishnu Naira119aaa2021-09-24 07:19:35 -0700483constexpr int PHYSICAL_DISPLAY_FLAGS = 0x1;
484
Dominik Laskowskie80bd312023-02-11 16:23:34 -0500485template <typename PhysicalDisplay, int width, int height>
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200486struct PhysicalDisplayVariant
Dominik Laskowskie80bd312023-02-11 16:23:34 -0500487 : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, Async::FALSE,
488 Secure::TRUE, PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY,
489 PHYSICAL_DISPLAY_FLAGS>,
490 HwcDisplayVariant<PhysicalDisplay::HWC_DISPLAY_ID, DisplayType::PHYSICAL,
491 DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height,
492 Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
493 GRALLOC_USAGE_PHYSICAL_DISPLAY, PHYSICAL_DISPLAY_FLAGS>,
494 PhysicalDisplay> {};
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200495
496template <bool hasIdentificationData>
497struct PrimaryDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100498 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200499 static constexpr Primary PRIMARY = Primary::TRUE;
500 static constexpr uint8_t PORT = 255;
501 static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
502 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
503 static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
504};
505
Dominik Laskowski06e5db02023-02-11 16:55:47 -0500506template <ui::DisplayConnectionType connectionType, bool hasIdentificationData>
507struct SecondaryDisplay {
508 static constexpr auto CONNECTION_TYPE = connectionType;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200509 static constexpr Primary PRIMARY = Primary::FALSE;
510 static constexpr uint8_t PORT = 254;
511 static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
512 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
Dominik Laskowski06e5db02023-02-11 16:55:47 -0500513 static constexpr auto GET_IDENTIFICATION_DATA =
514 connectionType == ui::DisplayConnectionType::Internal ? getInternalEdid
515 : getExternalEdid;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200516};
517
518struct TertiaryDisplay {
519 static constexpr Primary PRIMARY = Primary::FALSE;
520 static constexpr uint8_t PORT = 253;
521 static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
522 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
523};
524
Dominik Laskowskie80bd312023-02-11 16:23:34 -0500525using PrimaryDisplayVariant = PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160>;
Dominik Laskowski06e5db02023-02-11 16:55:47 -0500526
527using InnerDisplayVariant = PhysicalDisplayVariant<PrimaryDisplay<true>, 1840, 2208>;
528using OuterDisplayVariant =
529 PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::Internal, true>, 1080,
530 2092>;
531
532using ExternalDisplayVariant =
533 PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External, false>, 1920,
534 1280>;
535
Dominik Laskowskie80bd312023-02-11 16:23:34 -0500536using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200>;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200537
538// A virtual display not supported by the HWC.
539constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
540
Vishnu Naira119aaa2021-09-24 07:19:35 -0700541constexpr int VIRTUAL_DISPLAY_FLAGS = 0x0;
542
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200543template <int width, int height, Secure secure>
544struct NonHwcVirtualDisplayVariant
Dominik Laskowskie80bd312023-02-11 16:23:34 -0500545 : DisplayVariant<GpuVirtualDisplayIdType, width, height, Async::TRUE, secure, Primary::FALSE,
546 GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY, VIRTUAL_DISPLAY_FLAGS> {
547 using Base = DisplayVariant<GpuVirtualDisplayIdType, width, height, Async::TRUE, secure,
548 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY,
549 VIRTUAL_DISPLAY_FLAGS>;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200550
551 static void injectHwcDisplay(DisplayTransactionTest*) {}
552
553 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
554 DisplayTransactionTest* test) {
555 const ::testing::TestInfo* const test_info =
556 ::testing::UnitTest::GetInstance()->current_test_info();
557
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200558 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800559 .setId(Base::DISPLAY_ID::get())
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800560 .setPixels(Base::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200561 .setIsSecure(static_cast<bool>(Base::SECURE))
562 .setPowerAdvisor(&test->mPowerAdvisor)
563 .setName(std::string("Injected display for ") +
564 test_info->test_case_name() + "." + test_info->name())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200565 .build();
566
567 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
568 ceDisplayArgs);
569 }
570
Marin Shalamanov6e840172020-12-14 22:13:28 +0100571 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
572 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
573 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
574 }
575
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200576 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
577 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
578 }
579
580 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
581 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
582 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
583 }
584};
585
586// A virtual display supported by the HWC.
587constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
588
589template <int width, int height, Secure secure>
590struct HwcVirtualDisplayVariant
Dominik Laskowskie80bd312023-02-11 16:23:34 -0500591 : DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Async::TRUE, secure,
592 Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY, VIRTUAL_DISPLAY_FLAGS>,
593 HwcDisplayVariant<HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
594 DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Async::TRUE,
595 secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY,
596 VIRTUAL_DISPLAY_FLAGS>> {
597 using Base = DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Async::TRUE, secure,
598 Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER, VIRTUAL_DISPLAY_FLAGS>;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200599 using Self = HwcVirtualDisplayVariant<width, height, secure>;
600
601 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
602 DisplayTransactionTest* test) {
603 const ::testing::TestInfo* const test_info =
604 ::testing::UnitTest::GetInstance()->current_test_info();
605
Dominik Laskowski13948602021-03-08 20:48:28 -0800606 const auto displayId = Base::DISPLAY_ID::get();
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200607 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800608 .setId(displayId)
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800609 .setPixels(Base::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200610 .setIsSecure(static_cast<bool>(Base::SECURE))
611 .setPowerAdvisor(&test->mPowerAdvisor)
612 .setName(std::string("Injected display for ") +
613 test_info->test_case_name() + "." + test_info->name())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200614 .build();
615
616 auto compositionDisplay =
617 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
618 ceDisplayArgs);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200619
620 // Insert display data so that the HWC thinks it created the virtual display.
Dominik Laskowski13948602021-03-08 20:48:28 -0800621 test->mFlinger.mutableHwcDisplayData().try_emplace(displayId);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200622
623 return compositionDisplay;
624 }
625
626 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
627 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
628 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
629 }
630
631 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
Dominik Laskowski263eec42021-07-21 23:13:24 -0700632 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
633 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200634 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
635 }
636};
637
638// For this variant, the display is not a HWC display, so no HDR support should
639// be configured.
640struct NonHwcDisplayHdrSupportVariant {
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(_, _, _, _, _)).Times(0);
647 }
648};
649
650// For this variant, the composer should respond with am empty list of HDR
651// modes, so no HDR support should be configured.
652template <typename Display>
653struct HdrNotSupportedVariant {
654 static constexpr bool HDR10_PLUS_SUPPORTED = false;
655 static constexpr bool HDR10_SUPPORTED = false;
656 static constexpr bool HDR_HLG_SUPPORTED = false;
657 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
658 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
659 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
660 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
661 }
662};
663
664struct NonHwcPerFrameMetadataSupportVariant {
665 static constexpr int PER_FRAME_METADATA_KEYS = 0;
666 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
667 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_)).Times(0);
668 }
669};
670
671template <typename Display>
672struct NoPerFrameMetadataSupportVariant {
673 static constexpr int PER_FRAME_METADATA_KEYS = 0;
674 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
675 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
676 .WillOnce(Return(std::vector<PerFrameMetadataKey>()));
677 }
678};
679
680// For this variant, SurfaceFlinger should configure itself with wide display
681// support, but the display should respond with an empty list of supported color
682// modes. Wide-color support for the display should not be configured.
683template <typename Display>
684struct WideColorNotSupportedVariant {
685 static constexpr bool WIDE_COLOR_SUPPORTED = false;
686
687 static void injectConfigChange(DisplayTransactionTest* test) {
Dominik Laskowski788945b2022-08-30 12:10:56 -0700688 test->mFlinger.mutableSupportsWideColor() = true;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200689 }
690
691 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200692 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
693 }
694};
695
696// For this variant, SurfaceFlinger should not configure itself with wide
697// display support, so the display should not be configured for wide-color
698// support.
699struct WideColorSupportNotConfiguredVariant {
700 static constexpr bool WIDE_COLOR_SUPPORTED = false;
701
702 static void injectConfigChange(DisplayTransactionTest* test) {
Dominik Laskowski788945b2022-08-30 12:10:56 -0700703 test->mFlinger.mutableSupportsWideColor() = false;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200704 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
705 }
706
707 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200708 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
709 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
710 }
711};
712
713/* ------------------------------------------------------------------------
714 * Typical display configurations to test
715 */
716
717template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy,
718 typename PerFrameMetadataSupportPolicy>
719struct Case {
720 using Display = DisplayPolicy;
721 using WideColorSupport = WideColorSupportPolicy;
722 using HdrSupport = HdrSupportPolicy;
723 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy;
724};
725
726using SimplePrimaryDisplayCase =
727 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
728 HdrNotSupportedVariant<PrimaryDisplayVariant>,
729 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
730using SimpleExternalDisplayCase =
731 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
732 HdrNotSupportedVariant<ExternalDisplayVariant>,
733 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
734using SimpleTertiaryDisplayCase =
735 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
736 HdrNotSupportedVariant<TertiaryDisplayVariant>,
737 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
738
739using NonHwcVirtualDisplayCase =
740 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
741 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant,
742 NonHwcPerFrameMetadataSupportVariant>;
743using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
744using HwcVirtualDisplayCase =
745 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
746 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>,
747 NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>;
748
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800749inline DisplayModePtr createDisplayMode(DisplayModeId modeId, Fps refreshRate, int32_t group = 0,
750 ui::Size resolution = ui::Size(1920, 1080)) {
751 return mock::createDisplayMode(modeId, refreshRate, group, resolution,
752 PrimaryDisplayVariant::DISPLAY_ID::get());
753}
754
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200755} // namespace android
756
757// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +0100758#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"