1 /* 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" 22 #pragma clang diagnostic ignored "-Wextra" 23 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 57 namespace android { 58 59 // TODO: Do not polute the android namespace 60 namespace hal = android::hardware::graphics::composer::hal; 61 62 using testing::_; 63 using testing::AnyNumber; 64 using testing::DoAll; 65 using testing::Mock; 66 using testing::ResultOf; 67 using testing::Return; 68 using testing::SetArgPointee; 69 70 using hal::ColorMode; 71 using hal::Connection; 72 using hal::DisplayCapability; 73 using hal::DisplayType; 74 using hal::Error; 75 using hal::Hdr; 76 using hal::HWDisplayId; 77 using hal::IComposer; 78 using hal::IComposerClient; 79 using hal::PerFrameMetadataKey; 80 using hal::PowerMode; 81 82 class DisplayTransactionTest : public testing::Test { 83 public: 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 135 protected: 136 DisplayTransactionTest(); 137 }; 138 139 constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'667; 140 constexpr int32_t DEFAULT_DPI = 320; 141 constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565; 142 143 constexpr 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 154 BOOL_SUBSTITUTE(Async); 155 BOOL_SUBSTITUTE(Critical); 156 BOOL_SUBSTITUTE(Primary); 157 BOOL_SUBSTITUTE(Secure); 158 BOOL_SUBSTITUTE(Virtual); 159 160 template <typename PhysicalDisplay> 161 struct PhysicalDisplayIdType {}; 162 163 template <uint64_t displayId> 164 using HalVirtualDisplayIdType = std::integral_constant<uint64_t, displayId>; 165 166 struct GpuVirtualDisplayIdType {}; 167 168 template <typename> 169 struct IsPhysicalDisplayId : std::bool_constant<false> {}; 170 171 template <typename PhysicalDisplay> 172 struct IsPhysicalDisplayId<PhysicalDisplayIdType<PhysicalDisplay>> : std::bool_constant<true> {}; 173 174 template <typename> 175 struct DisplayIdGetter; 176 177 template <typename PhysicalDisplay> 178 struct 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 193 template <uint64_t displayId> 194 struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> { 195 static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); } 196 }; 197 198 template <> 199 struct DisplayIdGetter<GpuVirtualDisplayIdType> { 200 static GpuVirtualDisplayId get() { return GpuVirtualDisplayId(0); } 201 }; 202 203 template <typename> 204 struct DisplayConnectionTypeGetter { 205 static constexpr std::optional<ui::DisplayConnectionType> value; 206 }; 207 208 template <typename PhysicalDisplay> 209 struct DisplayConnectionTypeGetter<PhysicalDisplayIdType<PhysicalDisplay>> { 210 static constexpr std::optional<ui::DisplayConnectionType> value = 211 PhysicalDisplay::CONNECTION_TYPE; 212 }; 213 214 template <typename> 215 struct HwcDisplayIdGetter { 216 static constexpr std::optional<HWDisplayId> value; 217 }; 218 219 constexpr HWDisplayId HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010; 220 221 template <uint64_t displayId> 222 struct HwcDisplayIdGetter<HalVirtualDisplayIdType<displayId>> { 223 static constexpr std::optional<HWDisplayId> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID; 224 }; 225 226 template <typename PhysicalDisplay> 227 struct 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. 235 template <typename DisplayIdType, int width, int height, Critical critical, Async async, 236 Secure secure, Primary primary, int grallocUsage> 237 struct 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 ceDisplayArgs.setId(DISPLAY_ID::get()) 267 .setPixels({WIDTH, HEIGHT}) 268 .setPowerAdvisor(&test->mPowerAdvisor); 269 270 const auto connectionType = CONNECTION_TYPE::value; 271 if (connectionType) { 272 ceDisplayArgs.setConnectionType(*connectionType); 273 } 274 275 auto compositionDisplay = 276 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), 277 ceDisplayArgs.build()); 278 279 auto injector = 280 TestableSurfaceFlinger::FakeDisplayDeviceInjector(test->mFlinger, 281 compositionDisplay, 282 connectionType, 283 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 342 template <HWDisplayId hwcDisplayId, DisplayType hwcDisplayType, typename DisplayVariant, 343 typename PhysicalDisplay = void> 344 struct 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 352 static constexpr hal::HWConfigId HWC_ACTIVE_CONFIG_ID = 2001; 353 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() 390 .setId(DisplayVariant::DISPLAY_ID::get()) 391 .setConnectionType(PhysicalDisplay::CONNECTION_TYPE) 392 .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 403 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( 423 DoAll(SetArgPointee<3>(DEFAULT_VSYNC_PERIOD), Return(Error::NONE))); 424 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 442 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) { 443 constexpr auto CONNECTION_TYPE = 444 PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal 445 ? 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)); 453 454 setupHwcGetConfigsCallExpectations(test); 455 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. 475 constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY = 476 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB; 477 478 template <typename PhysicalDisplay, int width, int height, Critical critical> 479 struct 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 489 template <bool hasIdentificationData> 490 struct PrimaryDisplay { 491 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal; 492 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 499 template <bool hasIdentificationData> 500 struct ExternalDisplay { 501 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External; 502 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 509 struct 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 517 using PrimaryDisplayVariant = 518 PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>; 519 520 // An external display is physical display that is not critical. 521 using ExternalDisplayVariant = 522 PhysicalDisplayVariant<ExternalDisplay<false>, 1920, 1280, Critical::FALSE>; 523 524 using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200, Critical::FALSE>; 525 526 // A virtual display not supported by the HWC. 527 constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0; 528 529 template <int width, int height, Secure secure> 530 struct 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 544 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() 545 .setId(Base::DISPLAY_ID::get()) 546 .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()) 551 .build(); 552 553 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), 554 ceDisplayArgs); 555 } 556 557 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) { 558 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0); 559 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0); 560 } 561 562 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. 573 constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER; 574 575 template <int width, int height, Secure secure> 576 struct 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 592 const auto displayId = Base::DISPLAY_ID::get(); 593 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() 594 .setId(displayId) 595 .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()) 600 .build(); 601 602 auto compositionDisplay = 603 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), 604 ceDisplayArgs); 605 606 // Insert display data so that the HWC thinks it created the virtual display. 607 test->mFlinger.mutableHwcDisplayData().try_emplace(displayId); 608 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) { 618 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _)) 619 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE))); 620 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. 626 struct 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. 638 template <typename Display> 639 struct 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 650 struct 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 657 template <typename Display> 658 struct 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. 669 template <typename Display> 670 struct 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. 688 struct 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 708 template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy, 709 typename PerFrameMetadataSupportPolicy> 710 struct Case { 711 using Display = DisplayPolicy; 712 using WideColorSupport = WideColorSupportPolicy; 713 using HdrSupport = HdrSupportPolicy; 714 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy; 715 }; 716 717 using SimplePrimaryDisplayCase = 718 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>, 719 HdrNotSupportedVariant<PrimaryDisplayVariant>, 720 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>; 721 using SimpleExternalDisplayCase = 722 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>, 723 HdrNotSupportedVariant<ExternalDisplayVariant>, 724 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>; 725 using SimpleTertiaryDisplayCase = 726 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>, 727 HdrNotSupportedVariant<TertiaryDisplayVariant>, 728 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>; 729 730 using NonHwcVirtualDisplayCase = 731 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>, 732 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant, 733 NonHwcPerFrameMetadataSupportVariant>; 734 using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>; 735 using 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 743 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra" 744