blob: 6ce281d4035ee9de95644442bd1eab848f2501e0 [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>
25#include "DisplayIdentificationTest.h"
26
27#include <binder/IPCThreadState.h>
28#include <compositionengine/Display.h>
29#include <compositionengine/DisplayColorProfile.h>
30#include <compositionengine/impl/Display.h>
31#include <compositionengine/impl/OutputCompositionState.h>
32#include <compositionengine/mock/Display.h>
33#include <compositionengine/mock/DisplayColorProfile.h>
34#include <compositionengine/mock/DisplaySurface.h>
35#include <compositionengine/mock/RenderSurface.h>
36#include <gmock/gmock.h>
37#include <gtest/gtest.h>
38#include <gui/mock/GraphicBufferConsumer.h>
39#include <gui/mock/GraphicBufferProducer.h>
40#include <log/log.h>
41#include <private/android_filesystem_config.h>
42#include <renderengine/mock/RenderEngine.h>
43#include <ui/DebugUtils.h>
44
45#include "TestableScheduler.h"
46#include "TestableSurfaceFlinger.h"
47#include "mock/DisplayHardware/MockComposer.h"
48#include "mock/DisplayHardware/MockPowerAdvisor.h"
49#include "mock/MockEventThread.h"
50#include "mock/MockMessageQueue.h"
51#include "mock/MockNativeWindowSurface.h"
52#include "mock/MockSchedulerCallback.h"
53#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
70using hal::ColorMode;
71using hal::Connection;
72using hal::DisplayCapability;
73using 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(
94 std::function<void(TestableSurfaceFlinger::FakeDisplayDeviceInjector&)>);
95
96 // --------------------------------------------------------------------
97 // Postcondition helpers
98
99 bool hasPhysicalHwcDisplay(hal::HWDisplayId hwcDisplayId);
100 bool hasTransactionFlagSet(int flag);
101 bool hasDisplayDevice(sp<IBinder> displayToken);
102 sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
103 bool hasCurrentDisplayState(sp<IBinder> displayToken);
104 const DisplayDeviceState& getCurrentDisplayState(sp<IBinder> displayToken);
105 bool hasDrawingDisplayState(sp<IBinder> displayToken);
106 const DisplayDeviceState& getDrawingDisplayState(sp<IBinder> displayToken);
107
108 // --------------------------------------------------------------------
109 // Test instances
110
111 TestableSurfaceFlinger mFlinger;
112 sp<mock::NativeWindow> mNativeWindow = new mock::NativeWindow();
113 sp<GraphicBuffer> mBuffer = new GraphicBuffer();
114 Hwc2::mock::PowerAdvisor mPowerAdvisor;
115
116 // These mocks are created by the test, but are destroyed by SurfaceFlinger
117 // by virtue of being stored into a std::unique_ptr. However we still need
118 // to keep a reference to them for use in setting up call expectations.
119 renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
120 Hwc2::mock::Composer* mComposer = nullptr;
121 mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
122 sp<mock::SurfaceInterceptor> mSurfaceInterceptor = new mock::SurfaceInterceptor;
123
124 mock::VsyncController* mVsyncController = new mock::VsyncController;
125 mock::VSyncTracker* mVSyncTracker = new mock::VSyncTracker;
126 mock::SchedulerCallback mSchedulerCallback;
127 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,
236 Secure secure, Primary primary, int grallocUsage>
237struct DisplayVariant {
238 using DISPLAY_ID = DisplayIdGetter<DisplayIdType>;
239 using CONNECTION_TYPE = DisplayConnectionTypeGetter<DisplayIdType>;
240 using HWC_DISPLAY_ID_OPT = HwcDisplayIdGetter<DisplayIdType>;
241
242 // The display width and height
243 static constexpr int WIDTH = width;
244 static constexpr int HEIGHT = height;
245
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
264 static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
265 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder();
Dominik Laskowski13948602021-03-08 20:48:28 -0800266 ceDisplayArgs.setId(DISPLAY_ID::get())
267 .setPixels({WIDTH, HEIGHT})
268 .setPowerAdvisor(&test->mPowerAdvisor);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200269
Dominik Laskowski13948602021-03-08 20:48:28 -0800270 const auto connectionType = CONNECTION_TYPE::value;
271 if (connectionType) {
272 ceDisplayArgs.setConnectionType(*connectionType);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200273 }
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200274
275 auto compositionDisplay =
276 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
277 ceDisplayArgs.build());
278
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200279 auto injector =
280 TestableSurfaceFlinger::FakeDisplayDeviceInjector(test->mFlinger,
281 compositionDisplay,
Dominik Laskowski13948602021-03-08 20:48:28 -0800282 connectionType,
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200283 HWC_DISPLAY_ID_OPT::value,
284 static_cast<bool>(PRIMARY));
285
286 injector.setSecure(static_cast<bool>(SECURE));
287 injector.setNativeWindow(test->mNativeWindow);
288
289 // Creating a DisplayDevice requires getting default dimensions from the
290 // native window along with some other initial setup.
291 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
292 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
293 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
294 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
295 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
296 .WillRepeatedly(Return(0));
297 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
298 .WillRepeatedly(Return(0));
299 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
300 .WillRepeatedly(Return(0));
301 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
302 .WillRepeatedly(Return(0));
303
304 return injector;
305 }
306
307 // Called by tests to set up any native window creation call expectations.
308 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
309 EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
310 .WillOnce(Return(test->mNativeWindow));
311
312 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
313 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
314 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
315 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
316 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
317 .WillRepeatedly(Return(0));
318 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
319 .WillRepeatedly(Return(0));
320 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
321 .WillRepeatedly(Return(0));
322 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
323 .WillRepeatedly(Return(0));
324 }
325
326 static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
327 EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
328 EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
329 EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
330 .WillRepeatedly(Return(NO_ERROR));
331 EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
332 .WillRepeatedly(Return(NO_ERROR));
333 EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
334 .WillRepeatedly(Return(NO_ERROR));
335 }
336
337 static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
338 EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
339 }
340};
341
342template <HWDisplayId hwcDisplayId, DisplayType hwcDisplayType, typename DisplayVariant,
343 typename PhysicalDisplay = void>
344struct HwcDisplayVariant {
345 // The display id supplied by the HWC
346 static constexpr HWDisplayId HWC_DISPLAY_ID = hwcDisplayId;
347
348 // The HWC display type
349 static constexpr DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
350
351 // The HWC active configuration id
Marin Shalamanov6e840172020-12-14 22:13:28 +0100352 static constexpr hal::HWConfigId HWC_ACTIVE_CONFIG_ID = 2001;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200353 static constexpr PowerMode INIT_POWER_MODE = hal::PowerMode::ON;
354
355 static void injectPendingHotplugEvent(DisplayTransactionTest* test, Connection connection) {
356 test->mFlinger.mutablePendingHotplugEvents().emplace_back(
357 TestableSurfaceFlinger::HotplugEvent{HWC_DISPLAY_ID, connection});
358 }
359
360 // Called by tests to inject a HWC display setup
361 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)
367 .setWidth(DisplayVariant::WIDTH)
368 .setHeight(DisplayVariant::HEIGHT)
369 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
370 .setPowerMode(INIT_POWER_MODE)
371 .inject(&test->mFlinger, test->mComposer);
372 }
373
374 // Called by tests to inject a HWC display setup
375 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)));
379 EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, INIT_POWER_MODE))
380 .WillOnce(Return(Error::NONE));
381 injectHwcDisplayWithNoDefaultCapabilities(test);
382 }
383
384 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
385 DisplayTransactionTest* test) {
386 const ::testing::TestInfo* const test_info =
387 ::testing::UnitTest::GetInstance()->current_test_info();
388
389 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800390 .setId(DisplayVariant::DISPLAY_ID::get())
391 .setConnectionType(PhysicalDisplay::CONNECTION_TYPE)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200392 .setPixels({DisplayVariant::WIDTH, DisplayVariant::HEIGHT})
393 .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
478template <typename PhysicalDisplay, int width, int height, Critical critical>
479struct PhysicalDisplayVariant
480 : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, critical,
481 Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
482 GRALLOC_USAGE_PHYSICAL_DISPLAY>,
483 HwcDisplayVariant<PhysicalDisplay::HWC_DISPLAY_ID, DisplayType::PHYSICAL,
484 DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height,
485 critical, Async::FALSE, Secure::TRUE,
486 PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
487 PhysicalDisplay> {};
488
489template <bool hasIdentificationData>
490struct PrimaryDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100491 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200492 static constexpr Primary PRIMARY = Primary::TRUE;
493 static constexpr uint8_t PORT = 255;
494 static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
495 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
496 static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
497};
498
499template <bool hasIdentificationData>
500struct ExternalDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100501 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200502 static constexpr Primary PRIMARY = Primary::FALSE;
503 static constexpr uint8_t PORT = 254;
504 static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
505 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
506 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
507};
508
509struct TertiaryDisplay {
510 static constexpr Primary PRIMARY = Primary::FALSE;
511 static constexpr uint8_t PORT = 253;
512 static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
513 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
514};
515
516// A primary display is a physical display that is critical
517using PrimaryDisplayVariant =
518 PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>;
519
520// An external display is physical display that is not critical.
521using ExternalDisplayVariant =
522 PhysicalDisplayVariant<ExternalDisplay<false>, 1920, 1280, Critical::FALSE>;
523
524using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200, Critical::FALSE>;
525
526// A virtual display not supported by the HWC.
527constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
528
529template <int width, int height, Secure secure>
530struct NonHwcVirtualDisplayVariant
531 : DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE, secure,
532 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY> {
533 using Base =
534 DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE,
535 secure, Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
536
537 static void injectHwcDisplay(DisplayTransactionTest*) {}
538
539 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
540 DisplayTransactionTest* test) {
541 const ::testing::TestInfo* const test_info =
542 ::testing::UnitTest::GetInstance()->current_test_info();
543
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200544 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800545 .setId(Base::DISPLAY_ID::get())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200546 .setPixels({Base::WIDTH, Base::HEIGHT})
547 .setIsSecure(static_cast<bool>(Base::SECURE))
548 .setPowerAdvisor(&test->mPowerAdvisor)
549 .setName(std::string("Injected display for ") +
550 test_info->test_case_name() + "." + test_info->name())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200551 .build();
552
553 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
554 ceDisplayArgs);
555 }
556
Marin Shalamanov6e840172020-12-14 22:13:28 +0100557 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
558 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
559 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
560 }
561
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200562 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
563 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
564 }
565
566 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
567 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
568 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
569 }
570};
571
572// A virtual display supported by the HWC.
573constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
574
575template <int width, int height, Secure secure>
576struct HwcVirtualDisplayVariant
577 : DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
578 secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
579 HwcDisplayVariant<HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
580 DisplayVariant<HalVirtualDisplayIdType<42>, width, height,
581 Critical::FALSE, Async::TRUE, secure, Primary::FALSE,
582 GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>> {
583 using Base = DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
584 Async::TRUE, secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER>;
585 using Self = HwcVirtualDisplayVariant<width, height, secure>;
586
587 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
588 DisplayTransactionTest* test) {
589 const ::testing::TestInfo* const test_info =
590 ::testing::UnitTest::GetInstance()->current_test_info();
591
Dominik Laskowski13948602021-03-08 20:48:28 -0800592 const auto displayId = Base::DISPLAY_ID::get();
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200593 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
Dominik Laskowski13948602021-03-08 20:48:28 -0800594 .setId(displayId)
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200595 .setPixels({Base::WIDTH, Base::HEIGHT})
596 .setIsSecure(static_cast<bool>(Base::SECURE))
597 .setPowerAdvisor(&test->mPowerAdvisor)
598 .setName(std::string("Injected display for ") +
599 test_info->test_case_name() + "." + test_info->name())
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200600 .build();
601
602 auto compositionDisplay =
603 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
604 ceDisplayArgs);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200605
606 // Insert display data so that the HWC thinks it created the virtual display.
Dominik Laskowski13948602021-03-08 20:48:28 -0800607 test->mFlinger.mutableHwcDisplayData().try_emplace(displayId);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200608
609 return compositionDisplay;
610 }
611
612 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
613 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
614 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
615 }
616
617 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
Dominik Laskowski13948602021-03-08 20:48:28 -0800618 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _, _))
619 .WillOnce(DoAll(SetArgPointee<4>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200620 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
621 }
622};
623
624// For this variant, the display is not a HWC display, so no HDR support should
625// be configured.
626struct NonHwcDisplayHdrSupportVariant {
627 static constexpr bool HDR10_PLUS_SUPPORTED = false;
628 static constexpr bool HDR10_SUPPORTED = false;
629 static constexpr bool HDR_HLG_SUPPORTED = false;
630 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
631 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
632 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
633 }
634};
635
636// For this variant, the composer should respond with am empty list of HDR
637// modes, so no HDR support should be configured.
638template <typename Display>
639struct HdrNotSupportedVariant {
640 static constexpr bool HDR10_PLUS_SUPPORTED = false;
641 static constexpr bool HDR10_SUPPORTED = false;
642 static constexpr bool HDR_HLG_SUPPORTED = false;
643 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
644 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
645 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
646 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
647 }
648};
649
650struct NonHwcPerFrameMetadataSupportVariant {
651 static constexpr int PER_FRAME_METADATA_KEYS = 0;
652 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
653 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_)).Times(0);
654 }
655};
656
657template <typename Display>
658struct NoPerFrameMetadataSupportVariant {
659 static constexpr int PER_FRAME_METADATA_KEYS = 0;
660 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
661 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
662 .WillOnce(Return(std::vector<PerFrameMetadataKey>()));
663 }
664};
665
666// For this variant, SurfaceFlinger should configure itself with wide display
667// support, but the display should respond with an empty list of supported color
668// modes. Wide-color support for the display should not be configured.
669template <typename Display>
670struct WideColorNotSupportedVariant {
671 static constexpr bool WIDE_COLOR_SUPPORTED = false;
672
673 static void injectConfigChange(DisplayTransactionTest* test) {
674 test->mFlinger.mutableUseColorManagement() = true;
675 test->mFlinger.mutableHasWideColorDisplay() = true;
676 }
677
678 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
679 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
680 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>()), Return(Error::NONE)));
681 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
682 }
683};
684
685// For this variant, SurfaceFlinger should not configure itself with wide
686// display support, so the display should not be configured for wide-color
687// support.
688struct WideColorSupportNotConfiguredVariant {
689 static constexpr bool WIDE_COLOR_SUPPORTED = false;
690
691 static void injectConfigChange(DisplayTransactionTest* test) {
692 test->mFlinger.mutableHasWideColorDisplay() = false;
693 test->mFlinger.mutableUseColorManagement() = false;
694 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
695 }
696
697 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
698 EXPECT_CALL(*test->mComposer, getColorModes(_, _)).Times(0);
699 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
700 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
701 }
702};
703
704/* ------------------------------------------------------------------------
705 * Typical display configurations to test
706 */
707
708template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy,
709 typename PerFrameMetadataSupportPolicy>
710struct Case {
711 using Display = DisplayPolicy;
712 using WideColorSupport = WideColorSupportPolicy;
713 using HdrSupport = HdrSupportPolicy;
714 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy;
715};
716
717using SimplePrimaryDisplayCase =
718 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
719 HdrNotSupportedVariant<PrimaryDisplayVariant>,
720 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
721using SimpleExternalDisplayCase =
722 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
723 HdrNotSupportedVariant<ExternalDisplayVariant>,
724 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
725using SimpleTertiaryDisplayCase =
726 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
727 HdrNotSupportedVariant<TertiaryDisplayVariant>,
728 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
729
730using NonHwcVirtualDisplayCase =
731 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
732 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant,
733 NonHwcPerFrameMetadataSupportVariant>;
734using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
735using HwcVirtualDisplayCase =
736 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
737 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>,
738 NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>;
739
740} // namespace android
741
742// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +0100743#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"