blob: d68fff6345a375ae18dec9bda72246aeb4cef72b [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();
266 if (auto displayId = PhysicalDisplayId::tryCast(DISPLAY_ID::get())) {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100267 ceDisplayArgs.setPhysical({*displayId, ui::DisplayConnectionType::Internal});
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200268 } else {
269 // We turn off the use of HwcVirtualDisplays, to prevent Composition Engine
270 // from calling into HWComposer. This way all virtual displays will get
271 // a GpuVirtualDisplayId, even if we are in the HwcVirtualDisplayVariant.
272 // In this case we later override it by calling display.setDisplayIdForTesting().
273 ceDisplayArgs.setUseHwcVirtualDisplays(false);
274
275 GpuVirtualDisplayId desiredDisplayId = GpuVirtualDisplayId::tryCast(DISPLAY_ID::get())
276 .value_or(GpuVirtualDisplayId(0));
277
278 ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
279 .WillByDefault(Return(desiredDisplayId));
280
281 auto& generator = test->mFlinger.gpuVirtualDisplayIdGenerator();
282 ceDisplayArgs.setGpuVirtualDisplayIdGenerator(generator);
283 }
284 ceDisplayArgs.setPixels({WIDTH, HEIGHT}).setPowerAdvisor(&test->mPowerAdvisor);
285
286 auto compositionDisplay =
287 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
288 ceDisplayArgs.build());
289
290 if (HalVirtualDisplayId::tryCast(DISPLAY_ID::get())) {
291 // CompositionEngine has assigned a placeholder GpuVirtualDisplayId and we need to
292 // override it with the correct HalVirtualDisplayId.
293 compositionDisplay->setDisplayIdForTesting(DISPLAY_ID::get());
294 }
295
296 auto injector =
297 TestableSurfaceFlinger::FakeDisplayDeviceInjector(test->mFlinger,
298 compositionDisplay,
299 CONNECTION_TYPE::value,
300 HWC_DISPLAY_ID_OPT::value,
301 static_cast<bool>(PRIMARY));
302
303 injector.setSecure(static_cast<bool>(SECURE));
304 injector.setNativeWindow(test->mNativeWindow);
305
306 // Creating a DisplayDevice requires getting default dimensions from the
307 // native window along with some other initial setup.
308 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
309 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
310 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
311 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
312 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
313 .WillRepeatedly(Return(0));
314 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
315 .WillRepeatedly(Return(0));
316 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
317 .WillRepeatedly(Return(0));
318 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
319 .WillRepeatedly(Return(0));
320
321 return injector;
322 }
323
324 // Called by tests to set up any native window creation call expectations.
325 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
326 EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
327 .WillOnce(Return(test->mNativeWindow));
328
329 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
330 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
331 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
332 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
333 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
334 .WillRepeatedly(Return(0));
335 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
336 .WillRepeatedly(Return(0));
337 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
338 .WillRepeatedly(Return(0));
339 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
340 .WillRepeatedly(Return(0));
341 }
342
343 static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
344 EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
345 EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
346 EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
347 .WillRepeatedly(Return(NO_ERROR));
348 EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
349 .WillRepeatedly(Return(NO_ERROR));
350 EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
351 .WillRepeatedly(Return(NO_ERROR));
352 }
353
354 static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
355 EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
356 }
357};
358
359template <HWDisplayId hwcDisplayId, DisplayType hwcDisplayType, typename DisplayVariant,
360 typename PhysicalDisplay = void>
361struct HwcDisplayVariant {
362 // The display id supplied by the HWC
363 static constexpr HWDisplayId HWC_DISPLAY_ID = hwcDisplayId;
364
365 // The HWC display type
366 static constexpr DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
367
368 // The HWC active configuration id
Marin Shalamanov6e840172020-12-14 22:13:28 +0100369 static constexpr hal::HWConfigId HWC_ACTIVE_CONFIG_ID = 2001;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200370 static constexpr PowerMode INIT_POWER_MODE = hal::PowerMode::ON;
371
372 static void injectPendingHotplugEvent(DisplayTransactionTest* test, Connection connection) {
373 test->mFlinger.mutablePendingHotplugEvents().emplace_back(
374 TestableSurfaceFlinger::HotplugEvent{HWC_DISPLAY_ID, connection});
375 }
376
377 // Called by tests to inject a HWC display setup
378 static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
379 const auto displayId = DisplayVariant::DISPLAY_ID::get();
380 ASSERT_FALSE(GpuVirtualDisplayId::tryCast(displayId));
381 TestableSurfaceFlinger::FakeHwcDisplayInjector(displayId, HWC_DISPLAY_TYPE,
382 static_cast<bool>(DisplayVariant::PRIMARY))
383 .setHwcDisplayId(HWC_DISPLAY_ID)
384 .setWidth(DisplayVariant::WIDTH)
385 .setHeight(DisplayVariant::HEIGHT)
386 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
387 .setPowerMode(INIT_POWER_MODE)
388 .inject(&test->mFlinger, test->mComposer);
389 }
390
391 // Called by tests to inject a HWC display setup
392 static void injectHwcDisplay(DisplayTransactionTest* test) {
393 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
394 .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})),
395 Return(Error::NONE)));
396 EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, INIT_POWER_MODE))
397 .WillOnce(Return(Error::NONE));
398 injectHwcDisplayWithNoDefaultCapabilities(test);
399 }
400
401 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
402 DisplayTransactionTest* test) {
403 const ::testing::TestInfo* const test_info =
404 ::testing::UnitTest::GetInstance()->current_test_info();
405
406 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
407 .setPhysical({DisplayVariant::DISPLAY_ID::get(),
408 PhysicalDisplay::CONNECTION_TYPE})
409 .setPixels({DisplayVariant::WIDTH, DisplayVariant::HEIGHT})
410 .setIsSecure(static_cast<bool>(DisplayVariant::SECURE))
411 .setPowerAdvisor(&test->mPowerAdvisor)
412 .setName(std::string("Injected display for ") +
413 test_info->test_case_name() + "." + test_info->name())
414 .build();
415
416 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
417 ceDisplayArgs);
418 }
419
Marin Shalamanov6e840172020-12-14 22:13:28 +0100420 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
421 if (HWC_DISPLAY_TYPE == DisplayType::PHYSICAL) {
422 EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
423 .WillRepeatedly(DoAll(SetArgPointee<1>(std::vector<hal::HWConfigId>{
424 HWC_ACTIVE_CONFIG_ID}),
425 Return(Error::NONE)));
426 EXPECT_CALL(*test->mComposer,
427 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
428 IComposerClient::Attribute::WIDTH, _))
429 .WillRepeatedly(
430 DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
431 EXPECT_CALL(*test->mComposer,
432 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
433 IComposerClient::Attribute::HEIGHT, _))
434 .WillRepeatedly(
435 DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
436 EXPECT_CALL(*test->mComposer,
437 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
438 IComposerClient::Attribute::VSYNC_PERIOD, _))
439 .WillRepeatedly(
Marin Shalamanova903d032020-12-29 20:35:13 +0100440 DoAll(SetArgPointee<3>(DEFAULT_VSYNC_PERIOD), Return(Error::NONE)));
Marin Shalamanov6e840172020-12-14 22:13:28 +0100441 EXPECT_CALL(*test->mComposer,
442 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
443 IComposerClient::Attribute::DPI_X, _))
444 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
445 EXPECT_CALL(*test->mComposer,
446 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
447 IComposerClient::Attribute::DPI_Y, _))
448 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
449 EXPECT_CALL(*test->mComposer,
450 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
451 IComposerClient::Attribute::CONFIG_GROUP, _))
452 .WillRepeatedly(DoAll(SetArgPointee<3>(-1), Return(Error::NONE)));
453 } else {
454 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
455 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
456 }
457 }
458
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200459 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
460 constexpr auto CONNECTION_TYPE =
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100461 PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200462 ? IComposerClient::DisplayConnectionType::INTERNAL
463 : IComposerClient::DisplayConnectionType::EXTERNAL;
464
465 EXPECT_CALL(*test->mComposer, getDisplayConnectionType(HWC_DISPLAY_ID, _))
466 .WillOnce(DoAll(SetArgPointee<1>(CONNECTION_TYPE), Return(hal::V2_4::Error::NONE)));
467
468 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_))
469 .WillOnce(Return(hal::Error::NONE));
Marin Shalamanov6e840172020-12-14 22:13:28 +0100470
471 setupHwcGetConfigsCallExpectations(test);
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200472
473 if (PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
474 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
475 .WillOnce(DoAll(SetArgPointee<1>(PhysicalDisplay::PORT),
476 SetArgPointee<2>(PhysicalDisplay::GET_IDENTIFICATION_DATA()),
477 Return(Error::NONE)));
478 } else {
479 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
480 .WillOnce(Return(Error::UNSUPPORTED));
481 }
482 }
483
484 // Called by tests to set up HWC call expectations
485 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
486 EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
487 .WillRepeatedly(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
488 }
489};
490
491// Physical displays are expected to be synchronous, secure, and have a HWC display for output.
492constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
493 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
494
495template <typename PhysicalDisplay, int width, int height, Critical critical>
496struct PhysicalDisplayVariant
497 : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, critical,
498 Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
499 GRALLOC_USAGE_PHYSICAL_DISPLAY>,
500 HwcDisplayVariant<PhysicalDisplay::HWC_DISPLAY_ID, DisplayType::PHYSICAL,
501 DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height,
502 critical, Async::FALSE, Secure::TRUE,
503 PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
504 PhysicalDisplay> {};
505
506template <bool hasIdentificationData>
507struct PrimaryDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100508 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200509 static constexpr Primary PRIMARY = Primary::TRUE;
510 static constexpr uint8_t PORT = 255;
511 static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
512 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
513 static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
514};
515
516template <bool hasIdentificationData>
517struct ExternalDisplay {
Marin Shalamanov228f46b2021-01-28 21:11:45 +0100518 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External;
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200519 static constexpr Primary PRIMARY = Primary::FALSE;
520 static constexpr uint8_t PORT = 254;
521 static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
522 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
523 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
524};
525
526struct TertiaryDisplay {
527 static constexpr Primary PRIMARY = Primary::FALSE;
528 static constexpr uint8_t PORT = 253;
529 static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
530 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
531};
532
533// A primary display is a physical display that is critical
534using PrimaryDisplayVariant =
535 PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>;
536
537// An external display is physical display that is not critical.
538using ExternalDisplayVariant =
539 PhysicalDisplayVariant<ExternalDisplay<false>, 1920, 1280, Critical::FALSE>;
540
541using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200, Critical::FALSE>;
542
543// A virtual display not supported by the HWC.
544constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
545
546template <int width, int height, Secure secure>
547struct NonHwcVirtualDisplayVariant
548 : DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE, secure,
549 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY> {
550 using Base =
551 DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE,
552 secure, Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
553
554 static void injectHwcDisplay(DisplayTransactionTest*) {}
555
556 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
557 DisplayTransactionTest* test) {
558 const ::testing::TestInfo* const test_info =
559 ::testing::UnitTest::GetInstance()->current_test_info();
560
561 ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
562 .WillByDefault(Return(Base::DISPLAY_ID::get()));
563
564 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
565 .setPixels({Base::WIDTH, Base::HEIGHT})
566 .setIsSecure(static_cast<bool>(Base::SECURE))
567 .setPowerAdvisor(&test->mPowerAdvisor)
568 .setName(std::string("Injected display for ") +
569 test_info->test_case_name() + "." + test_info->name())
570 .setGpuVirtualDisplayIdGenerator(
571 test->mFlinger.gpuVirtualDisplayIdGenerator())
572 .build();
573
574 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
575 ceDisplayArgs);
576 }
577
Marin Shalamanov6e840172020-12-14 22:13:28 +0100578 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) {
579 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0);
580 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0);
581 }
582
Marin Shalamanov07b1ff32020-10-07 16:57:22 +0200583 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
584 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
585 }
586
587 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
588 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
589 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
590 }
591};
592
593// A virtual display supported by the HWC.
594constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
595
596template <int width, int height, Secure secure>
597struct HwcVirtualDisplayVariant
598 : DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
599 secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
600 HwcDisplayVariant<HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
601 DisplayVariant<HalVirtualDisplayIdType<42>, width, height,
602 Critical::FALSE, Async::TRUE, secure, Primary::FALSE,
603 GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>> {
604 using Base = DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
605 Async::TRUE, secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER>;
606 using Self = HwcVirtualDisplayVariant<width, height, secure>;
607
608 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
609 DisplayTransactionTest* test) {
610 const ::testing::TestInfo* const test_info =
611 ::testing::UnitTest::GetInstance()->current_test_info();
612
613 // In order to prevent compostition engine calling into HWComposer, we
614 // 1. turn off the use of HWC virtual displays,
615 // 2. provide a GpuVirtualDisplayIdGenerator which always returns some fake ID
616 // 3. override the ID by calling setDisplayIdForTesting()
617
618 ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
619 .WillByDefault(Return(GpuVirtualDisplayId(0)));
620
621 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
622 .setUseHwcVirtualDisplays(false)
623 .setPixels({Base::WIDTH, Base::HEIGHT})
624 .setIsSecure(static_cast<bool>(Base::SECURE))
625 .setPowerAdvisor(&test->mPowerAdvisor)
626 .setName(std::string("Injected display for ") +
627 test_info->test_case_name() + "." + test_info->name())
628 .setGpuVirtualDisplayIdGenerator(
629 test->mFlinger.gpuVirtualDisplayIdGenerator())
630 .build();
631
632 auto compositionDisplay =
633 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
634 ceDisplayArgs);
635 compositionDisplay->setDisplayIdForTesting(Base::DISPLAY_ID::get());
636
637 // Insert display data so that the HWC thinks it created the virtual display.
638 if (const auto displayId = Base::DISPLAY_ID::get();
639 HalVirtualDisplayId::tryCast(displayId)) {
640 test->mFlinger.mutableHwcDisplayData().try_emplace(displayId);
641 }
642
643 return compositionDisplay;
644 }
645
646 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
647 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
648 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
649 }
650
651 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
652 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
653 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
654 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
655 }
656};
657
658// For this variant, the display is not a HWC display, so no HDR support should
659// be configured.
660struct NonHwcDisplayHdrSupportVariant {
661 static constexpr bool HDR10_PLUS_SUPPORTED = false;
662 static constexpr bool HDR10_SUPPORTED = false;
663 static constexpr bool HDR_HLG_SUPPORTED = false;
664 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
665 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
666 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
667 }
668};
669
670// For this variant, the composer should respond with am empty list of HDR
671// modes, so no HDR support should be configured.
672template <typename Display>
673struct HdrNotSupportedVariant {
674 static constexpr bool HDR10_PLUS_SUPPORTED = false;
675 static constexpr bool HDR10_SUPPORTED = false;
676 static constexpr bool HDR_HLG_SUPPORTED = false;
677 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
678 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
679 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
680 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
681 }
682};
683
684struct NonHwcPerFrameMetadataSupportVariant {
685 static constexpr int PER_FRAME_METADATA_KEYS = 0;
686 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
687 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_)).Times(0);
688 }
689};
690
691template <typename Display>
692struct NoPerFrameMetadataSupportVariant {
693 static constexpr int PER_FRAME_METADATA_KEYS = 0;
694 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
695 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
696 .WillOnce(Return(std::vector<PerFrameMetadataKey>()));
697 }
698};
699
700// For this variant, SurfaceFlinger should configure itself with wide display
701// support, but the display should respond with an empty list of supported color
702// modes. Wide-color support for the display should not be configured.
703template <typename Display>
704struct WideColorNotSupportedVariant {
705 static constexpr bool WIDE_COLOR_SUPPORTED = false;
706
707 static void injectConfigChange(DisplayTransactionTest* test) {
708 test->mFlinger.mutableUseColorManagement() = true;
709 test->mFlinger.mutableHasWideColorDisplay() = true;
710 }
711
712 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
713 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
714 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>()), Return(Error::NONE)));
715 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
716 }
717};
718
719// For this variant, SurfaceFlinger should not configure itself with wide
720// display support, so the display should not be configured for wide-color
721// support.
722struct WideColorSupportNotConfiguredVariant {
723 static constexpr bool WIDE_COLOR_SUPPORTED = false;
724
725 static void injectConfigChange(DisplayTransactionTest* test) {
726 test->mFlinger.mutableHasWideColorDisplay() = false;
727 test->mFlinger.mutableUseColorManagement() = false;
728 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
729 }
730
731 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
732 EXPECT_CALL(*test->mComposer, getColorModes(_, _)).Times(0);
733 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
734 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
735 }
736};
737
738/* ------------------------------------------------------------------------
739 * Typical display configurations to test
740 */
741
742template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy,
743 typename PerFrameMetadataSupportPolicy>
744struct Case {
745 using Display = DisplayPolicy;
746 using WideColorSupport = WideColorSupportPolicy;
747 using HdrSupport = HdrSupportPolicy;
748 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy;
749};
750
751using SimplePrimaryDisplayCase =
752 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
753 HdrNotSupportedVariant<PrimaryDisplayVariant>,
754 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
755using SimpleExternalDisplayCase =
756 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
757 HdrNotSupportedVariant<ExternalDisplayVariant>,
758 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
759using SimpleTertiaryDisplayCase =
760 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
761 HdrNotSupportedVariant<TertiaryDisplayVariant>,
762 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
763
764using NonHwcVirtualDisplayCase =
765 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
766 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant,
767 NonHwcPerFrameMetadataSupportVariant>;
768using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
769using HwcVirtualDisplayCase =
770 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
771 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>,
772 NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>;
773
774} // namespace android
775
776// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +0100777#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"