blob: 60f773fcb0a9fb82056d0819f59db09d5f1f529e [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 Laskowskiaf148a22022-11-23 15:45:17 -050045#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/MockSurfaceInterceptor.h"
54#include "mock/MockVsyncController.h"
55#include "mock/system/window/MockNativeWindow.h"
56
57namespace android {
58
59// TODO: Do not polute the android namespace
60namespace hal = android::hardware::graphics::composer::hal;
61
62using testing::_;
63using testing::AnyNumber;
64using testing::DoAll;
65using testing::Mock;
66using testing::ResultOf;
67using testing::Return;
68using testing::SetArgPointee;
69
Leon Scroggins III5967aec2021-12-29 11:14:22 -050070using aidl::android::hardware::graphics::composer3::DisplayCapability;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020071using hal::ColorMode;
72using hal::Connection;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +020073using hal::DisplayType;
74using hal::Error;
75using hal::Hdr;
76using hal::HWDisplayId;
77using hal::IComposer;
78using hal::IComposerClient;
79using hal::PerFrameMetadataKey;
80using hal::PowerMode;
81
82class DisplayTransactionTest : public testing::Test {
83public:
84 ~DisplayTransactionTest() override;
85
86 // --------------------------------------------------------------------
87 // Mock/Fake injection
88
89 void injectMockScheduler();
90 void injectMockComposer(int virtualDisplayCount);
91 void injectFakeBufferQueueFactory();
92 void injectFakeNativeWindowSurfaceFactory();
93 sp<DisplayDevice> injectDefaultInternalDisplay(
Dominik Laskowskiaf148a22022-11-23 15:45:17 -050094 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;
117 sp<mock::NativeWindow> mNativeWindow = new mock::NativeWindow();
118 sp<GraphicBuffer> mBuffer = new GraphicBuffer();
119 Hwc2::mock::PowerAdvisor mPowerAdvisor;
120
Dominik Laskowskiaf148a22022-11-23 15:45:17 -0500121 FakeDisplayInjector mFakeDisplayInjector{mFlinger, mPowerAdvisor, mNativeWindow};
122
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200123 // These mocks are created by the test, but are destroyed by SurfaceFlinger
124 // by virtue of being stored into a std::unique_ptr. However we still need
125 // to keep a reference to them for use in setting up call expectations.
126 renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
127 Hwc2::mock::Composer* mComposer = nullptr;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200128 sp<mock::SurfaceInterceptor> mSurfaceInterceptor = new mock::SurfaceInterceptor;
129
130 mock::VsyncController* mVsyncController = new mock::VsyncController;
131 mock::VSyncTracker* mVSyncTracker = new mock::VSyncTracker;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200132 mock::EventThread* mEventThread = new mock::EventThread;
133 mock::EventThread* mSFEventThread = new mock::EventThread;
134
135 // These mocks are created only when expected to be created via a factory.
136 sp<mock::GraphicBufferConsumer> mConsumer;
137 sp<mock::GraphicBufferProducer> mProducer;
138 surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
139
140protected:
141 DisplayTransactionTest();
142};
143
Marin Shalamanova903d032020-12-29 20:35:13 +0100144constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'667;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200145constexpr int32_t DEFAULT_DPI = 320;
146constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
147
148constexpr int POWER_MODE_LEET = 1337; // An out of range power mode value
149
150/* ------------------------------------------------------------------------
151 * Boolean avoidance
152 *
153 * To make calls and template instantiations more readable, we define some
154 * local enums along with an implicit bool conversion.
155 */
156
157#define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true };
158
159BOOL_SUBSTITUTE(Async);
160BOOL_SUBSTITUTE(Critical);
161BOOL_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.
240template <typename DisplayIdType, int width, int height, Critical critical, Async async,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700241 Secure secure, 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
257 // When creating native window surfaces for the framebuffer, whether those should be critical
258 static constexpr Critical CRITICAL = critical;
259
260 // When creating native window surfaces for the framebuffer, whether those should be async
261 static constexpr Async ASYNC = async;
262
263 // Whether the display should be treated as secure
264 static constexpr Secure SECURE = secure;
265
266 // Whether the display is primary
267 static constexpr Primary PRIMARY = primary;
268
Vishnu Naira119aaa2021-09-24 07:19:35 -0700269 static constexpr int DISPLAY_FLAGS = displayFlags;
270
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200271 static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
272 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder();
Dominik Laskowski13948602021-03-08 20:48:28 -0800273 ceDisplayArgs.setId(DISPLAY_ID::get())
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800274 .setPixels(RESOLUTION)
Dominik Laskowski13948602021-03-08 20:48:28 -0800275 .setPowerAdvisor(&test->mPowerAdvisor);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200276
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200277 auto compositionDisplay =
278 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
279 ceDisplayArgs.build());
280
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200281 auto injector =
282 TestableSurfaceFlinger::FakeDisplayDeviceInjector(test->mFlinger,
283 compositionDisplay,
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700284 CONNECTION_TYPE::value,
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200285 HWC_DISPLAY_ID_OPT::value,
286 static_cast<bool>(PRIMARY));
287
288 injector.setSecure(static_cast<bool>(SECURE));
289 injector.setNativeWindow(test->mNativeWindow);
290
291 // Creating a DisplayDevice requires getting default dimensions from the
292 // native window along with some other initial setup.
293 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
294 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
295 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
296 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
297 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
298 .WillRepeatedly(Return(0));
299 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
300 .WillRepeatedly(Return(0));
301 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
302 .WillRepeatedly(Return(0));
303 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
304 .WillRepeatedly(Return(0));
305
306 return injector;
307 }
308
309 // Called by tests to set up any native window creation call expectations.
310 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
311 EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
312 .WillOnce(Return(test->mNativeWindow));
313
314 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
315 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
316 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
317 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
318 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
319 .WillRepeatedly(Return(0));
320 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
321 .WillRepeatedly(Return(0));
322 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
323 .WillRepeatedly(Return(0));
324 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
325 .WillRepeatedly(Return(0));
326 }
327
328 static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
329 EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
330 EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
331 EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
332 .WillRepeatedly(Return(NO_ERROR));
333 EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
334 .WillRepeatedly(Return(NO_ERROR));
335 EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
336 .WillRepeatedly(Return(NO_ERROR));
337 }
338
339 static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
340 EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
341 }
342};
343
344template <HWDisplayId hwcDisplayId, DisplayType hwcDisplayType, typename DisplayVariant,
345 typename PhysicalDisplay = void>
346struct HwcDisplayVariant {
347 // The display id supplied by the HWC
348 static constexpr HWDisplayId HWC_DISPLAY_ID = hwcDisplayId;
349
350 // The HWC display type
351 static constexpr DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
352
353 // The HWC active configuration id
Marin Shalamanov6e840172020-12-14 22:13:28 +0100354 static constexpr hal::HWConfigId HWC_ACTIVE_CONFIG_ID = 2001;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200355 static constexpr PowerMode INIT_POWER_MODE = hal::PowerMode::ON;
356
357 static void injectPendingHotplugEvent(DisplayTransactionTest* test, Connection connection) {
358 test->mFlinger.mutablePendingHotplugEvents().emplace_back(
359 TestableSurfaceFlinger::HotplugEvent{HWC_DISPLAY_ID, connection});
360 }
361
362 // Called by tests to inject a HWC display setup
363 static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
364 const auto displayId = DisplayVariant::DISPLAY_ID::get();
365 ASSERT_FALSE(GpuVirtualDisplayId::tryCast(displayId));
366 TestableSurfaceFlinger::FakeHwcDisplayInjector(displayId, HWC_DISPLAY_TYPE,
367 static_cast<bool>(DisplayVariant::PRIMARY))
368 .setHwcDisplayId(HWC_DISPLAY_ID)
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800369 .setResolution(DisplayVariant::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200370 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
371 .setPowerMode(INIT_POWER_MODE)
372 .inject(&test->mFlinger, test->mComposer);
373 }
374
375 // Called by tests to inject a HWC display setup
376 static void injectHwcDisplay(DisplayTransactionTest* test) {
377 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
378 .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})),
379 Return(Error::NONE)));
380 EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, INIT_POWER_MODE))
381 .WillOnce(Return(Error::NONE));
382 injectHwcDisplayWithNoDefaultCapabilities(test);
383 }
384
385 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
386 DisplayTransactionTest* test) {
387 const ::testing::TestInfo* const test_info =
388 ::testing::UnitTest::GetInstance()->current_test_info();
389
390 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800391 .setId(DisplayVariant::DISPLAY_ID::get())
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800392 .setPixels(DisplayVariant::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200393 .setIsSecure(static_cast<bool>(DisplayVariant::SECURE))
394 .setPowerAdvisor(&test->mPowerAdvisor)
395 .setName(std::string("Injected display for ") +
396 test_info->test_case_name() + "." + test_info->name())
397 .build();
398
399 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
400 ceDisplayArgs);
401 }
402
Marin Shalamanov6e840172020-12-14 22:13:28 +0100403 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
404 if (HWC_DISPLAY_TYPE == DisplayType::PHYSICAL) {
405 EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
406 .WillRepeatedly(DoAll(SetArgPointee<1>(std::vector<hal::HWConfigId>{
407 HWC_ACTIVE_CONFIG_ID}),
408 Return(Error::NONE)));
409 EXPECT_CALL(*test->mComposer,
410 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
411 IComposerClient::Attribute::WIDTH, _))
412 .WillRepeatedly(
413 DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
414 EXPECT_CALL(*test->mComposer,
415 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
416 IComposerClient::Attribute::HEIGHT, _))
417 .WillRepeatedly(
418 DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
419 EXPECT_CALL(*test->mComposer,
420 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
421 IComposerClient::Attribute::VSYNC_PERIOD, _))
422 .WillRepeatedly(
Marin Shalamanova903d032020-12-29 20:35:13 +0100423 DoAll(SetArgPointee<3>(DEFAULT_VSYNC_PERIOD), Return(Error::NONE)));
Marin Shalamanov6e840172020-12-14 22:13:28 +0100424 EXPECT_CALL(*test->mComposer,
425 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
426 IComposerClient::Attribute::DPI_X, _))
427 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
428 EXPECT_CALL(*test->mComposer,
429 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
430 IComposerClient::Attribute::DPI_Y, _))
431 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
432 EXPECT_CALL(*test->mComposer,
433 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
434 IComposerClient::Attribute::CONFIG_GROUP, _))
435 .WillRepeatedly(DoAll(SetArgPointee<3>(-1), Return(Error::NONE)));
436 } else {
437 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
438 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
439 }
440 }
441
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200442 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
443 constexpr auto CONNECTION_TYPE =
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100444 PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200445 ? IComposerClient::DisplayConnectionType::INTERNAL
446 : IComposerClient::DisplayConnectionType::EXTERNAL;
447
448 EXPECT_CALL(*test->mComposer, getDisplayConnectionType(HWC_DISPLAY_ID, _))
449 .WillOnce(DoAll(SetArgPointee<1>(CONNECTION_TYPE), Return(hal::V2_4::Error::NONE)));
450
451 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_))
452 .WillOnce(Return(hal::Error::NONE));
Marin Shalamanov6e840172020-12-14 22:13:28 +0100453
454 setupHwcGetConfigsCallExpectations(test);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200455
456 if (PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
457 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
458 .WillOnce(DoAll(SetArgPointee<1>(PhysicalDisplay::PORT),
459 SetArgPointee<2>(PhysicalDisplay::GET_IDENTIFICATION_DATA()),
460 Return(Error::NONE)));
461 } else {
462 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
463 .WillOnce(Return(Error::UNSUPPORTED));
464 }
465 }
466
467 // Called by tests to set up HWC call expectations
468 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
469 EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
470 .WillRepeatedly(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
471 }
472};
473
474// Physical displays are expected to be synchronous, secure, and have a HWC display for output.
475constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
476 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
477
Vishnu Naira119aaa2021-09-24 07:19:35 -0700478constexpr int PHYSICAL_DISPLAY_FLAGS = 0x1;
479
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200480template <typename PhysicalDisplay, int width, int height, Critical critical>
481struct PhysicalDisplayVariant
482 : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, critical,
483 Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700484 GRALLOC_USAGE_PHYSICAL_DISPLAY, PHYSICAL_DISPLAY_FLAGS>,
485 HwcDisplayVariant<
486 PhysicalDisplay::HWC_DISPLAY_ID, DisplayType::PHYSICAL,
487 DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, critical,
488 Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
489 GRALLOC_USAGE_PHYSICAL_DISPLAY, PHYSICAL_DISPLAY_FLAGS>,
490 PhysicalDisplay> {};
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200491
492template <bool hasIdentificationData>
493struct PrimaryDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100494 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200495 static constexpr Primary PRIMARY = Primary::TRUE;
496 static constexpr uint8_t PORT = 255;
497 static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
498 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
499 static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
500};
501
502template <bool hasIdentificationData>
503struct ExternalDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100504 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200505 static constexpr Primary PRIMARY = Primary::FALSE;
506 static constexpr uint8_t PORT = 254;
507 static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
508 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
509 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
510};
511
512struct TertiaryDisplay {
513 static constexpr Primary PRIMARY = Primary::FALSE;
514 static constexpr uint8_t PORT = 253;
515 static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
516 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
517};
518
519// A primary display is a physical display that is critical
520using PrimaryDisplayVariant =
521 PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>;
522
523// An external display is physical display that is not critical.
524using ExternalDisplayVariant =
525 PhysicalDisplayVariant<ExternalDisplay<false>, 1920, 1280, Critical::FALSE>;
526
527using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200, Critical::FALSE>;
528
529// A virtual display not supported by the HWC.
530constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
531
Vishnu Naira119aaa2021-09-24 07:19:35 -0700532constexpr int VIRTUAL_DISPLAY_FLAGS = 0x0;
533
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200534template <int width, int height, Secure secure>
535struct NonHwcVirtualDisplayVariant
536 : DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE, secure,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700537 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY,
538 VIRTUAL_DISPLAY_FLAGS> {
539 using Base = DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE,
540 Async::TRUE, secure, Primary::FALSE,
541 GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY, VIRTUAL_DISPLAY_FLAGS>;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200542
543 static void injectHwcDisplay(DisplayTransactionTest*) {}
544
545 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
546 DisplayTransactionTest* test) {
547 const ::testing::TestInfo* const test_info =
548 ::testing::UnitTest::GetInstance()->current_test_info();
549
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200550 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800551 .setId(Base::DISPLAY_ID::get())
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800552 .setPixels(Base::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200553 .setIsSecure(static_cast<bool>(Base::SECURE))
554 .setPowerAdvisor(&test->mPowerAdvisor)
555 .setName(std::string("Injected display for ") +
556 test_info->test_case_name() + "." + test_info->name())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200557 .build();
558
559 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
560 ceDisplayArgs);
561 }
562
Marin Shalamanov6e840172020-12-14 22:13:28 +0100563 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
564 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
565 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
566 }
567
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200568 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
569 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
570 }
571
572 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
573 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
574 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
575 }
576};
577
578// A virtual display supported by the HWC.
579constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
580
581template <int width, int height, Secure secure>
582struct HwcVirtualDisplayVariant
583 : DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700584 secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY,
585 VIRTUAL_DISPLAY_FLAGS>,
586 HwcDisplayVariant<
587 HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
588 DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
589 Async::TRUE, secure, Primary::FALSE,
590 GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY, VIRTUAL_DISPLAY_FLAGS>> {
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200591 using Base = DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
Vishnu Naira119aaa2021-09-24 07:19:35 -0700592 Async::TRUE, secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER,
593 VIRTUAL_DISPLAY_FLAGS>;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200594 using Self = HwcVirtualDisplayVariant<width, height, secure>;
595
596 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
597 DisplayTransactionTest* test) {
598 const ::testing::TestInfo* const test_info =
599 ::testing::UnitTest::GetInstance()->current_test_info();
600
Dominik Laskowski13948602021-03-08 20:48:28 -0800601 const auto displayId = Base::DISPLAY_ID::get();
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200602 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800603 .setId(displayId)
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800604 .setPixels(Base::RESOLUTION)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200605 .setIsSecure(static_cast<bool>(Base::SECURE))
606 .setPowerAdvisor(&test->mPowerAdvisor)
607 .setName(std::string("Injected display for ") +
608 test_info->test_case_name() + "." + test_info->name())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200609 .build();
610
611 auto compositionDisplay =
612 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
613 ceDisplayArgs);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200614
615 // Insert display data so that the HWC thinks it created the virtual display.
Dominik Laskowski13948602021-03-08 20:48:28 -0800616 test->mFlinger.mutableHwcDisplayData().try_emplace(displayId);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200617
618 return compositionDisplay;
619 }
620
621 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
622 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
623 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
624 }
625
626 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
Dominik Laskowski263eec42021-07-21 23:13:24 -0700627 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
628 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200629 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
630 }
631};
632
633// For this variant, the display is not a HWC display, so no HDR support should
634// be configured.
635struct NonHwcDisplayHdrSupportVariant {
636 static constexpr bool HDR10_PLUS_SUPPORTED = false;
637 static constexpr bool HDR10_SUPPORTED = false;
638 static constexpr bool HDR_HLG_SUPPORTED = false;
639 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
640 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
641 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
642 }
643};
644
645// For this variant, the composer should respond with am empty list of HDR
646// modes, so no HDR support should be configured.
647template <typename Display>
648struct HdrNotSupportedVariant {
649 static constexpr bool HDR10_PLUS_SUPPORTED = false;
650 static constexpr bool HDR10_SUPPORTED = false;
651 static constexpr bool HDR_HLG_SUPPORTED = false;
652 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
653 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
654 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
655 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
656 }
657};
658
659struct NonHwcPerFrameMetadataSupportVariant {
660 static constexpr int PER_FRAME_METADATA_KEYS = 0;
661 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
662 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_)).Times(0);
663 }
664};
665
666template <typename Display>
667struct NoPerFrameMetadataSupportVariant {
668 static constexpr int PER_FRAME_METADATA_KEYS = 0;
669 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
670 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
671 .WillOnce(Return(std::vector<PerFrameMetadataKey>()));
672 }
673};
674
675// For this variant, SurfaceFlinger should configure itself with wide display
676// support, but the display should respond with an empty list of supported color
677// modes. Wide-color support for the display should not be configured.
678template <typename Display>
679struct WideColorNotSupportedVariant {
680 static constexpr bool WIDE_COLOR_SUPPORTED = false;
681
682 static void injectConfigChange(DisplayTransactionTest* test) {
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200683 test->mFlinger.mutableHasWideColorDisplay() = true;
684 }
685
686 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
687 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
688 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>()), Return(Error::NONE)));
689 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
690 }
691};
692
693// For this variant, SurfaceFlinger should not configure itself with wide
694// display support, so the display should not be configured for wide-color
695// support.
696struct WideColorSupportNotConfiguredVariant {
697 static constexpr bool WIDE_COLOR_SUPPORTED = false;
698
699 static void injectConfigChange(DisplayTransactionTest* test) {
700 test->mFlinger.mutableHasWideColorDisplay() = false;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200701 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
702 }
703
704 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
705 EXPECT_CALL(*test->mComposer, getColorModes(_, _)).Times(0);
706 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
707 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
708 }
709};
710
711/* ------------------------------------------------------------------------
712 * Typical display configurations to test
713 */
714
715template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy,
716 typename PerFrameMetadataSupportPolicy>
717struct Case {
718 using Display = DisplayPolicy;
719 using WideColorSupport = WideColorSupportPolicy;
720 using HdrSupport = HdrSupportPolicy;
721 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy;
722};
723
724using SimplePrimaryDisplayCase =
725 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
726 HdrNotSupportedVariant<PrimaryDisplayVariant>,
727 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
728using SimpleExternalDisplayCase =
729 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
730 HdrNotSupportedVariant<ExternalDisplayVariant>,
731 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
732using SimpleTertiaryDisplayCase =
733 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
734 HdrNotSupportedVariant<TertiaryDisplayVariant>,
735 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
736
737using NonHwcVirtualDisplayCase =
738 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
739 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant,
740 NonHwcPerFrameMetadataSupportVariant>;
741using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
742using HwcVirtualDisplayCase =
743 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
744 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>,
745 NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>;
746
Dominik Laskowskib0054a22022-03-03 09:03:06 -0800747inline DisplayModePtr createDisplayMode(DisplayModeId modeId, Fps refreshRate, int32_t group = 0,
748 ui::Size resolution = ui::Size(1920, 1080)) {
749 return mock::createDisplayMode(modeId, refreshRate, group, resolution,
750 PrimaryDisplayVariant::DISPLAY_ID::get());
751}
752
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200753} // namespace android
754
755// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +0100756#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"