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 "DisplayIdentificationTestHelpers.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 "FakeDisplayInjector.h" 46 #include "TestableScheduler.h" 47 #include "TestableSurfaceFlinger.h" 48 #include "mock/DisplayHardware/MockComposer.h" 49 #include "mock/DisplayHardware/MockDisplayMode.h" 50 #include "mock/MockEventThread.h" 51 #include "mock/MockNativeWindowSurface.h" 52 #include "mock/MockVsyncController.h" 53 #include "mock/PowerAdvisor/MockPowerAdvisor.h" 54 #include "mock/system/window/MockNativeWindow.h" 55 56 namespace android { 57 58 // TODO: Do not polute the android namespace 59 namespace hal = android::hardware::graphics::composer::hal; 60 61 using testing::_; 62 using testing::AnyNumber; 63 using testing::DoAll; 64 using testing::Mock; 65 using testing::ResultOf; 66 using testing::Return; 67 using testing::SetArgPointee; 68 69 using aidl::android::hardware::graphics::composer3::DisplayCapability; 70 using hal::ColorMode; 71 using hal::Connection; 72 using hal::DisplayType; 73 using hal::Error; 74 using hal::Hdr; 75 using hal::HWDisplayId; 76 using hal::IComposer; 77 using hal::IComposerClient; 78 using hal::PerFrameMetadataKey; 79 using hal::PowerMode; 80 81 class DisplayTransactionTest : public testing::Test { 82 public: 83 ~DisplayTransactionTest() override; 84 85 // -------------------------------------------------------------------- 86 // Mock/Fake injection 87 88 void injectMockScheduler(PhysicalDisplayId); 89 void injectMockComposer(int virtualDisplayCount); 90 void injectFakeBufferQueueFactory(); 91 void injectFakeNativeWindowSurfaceFactory(); 92 injectDefaultInternalDisplay(std::function<void (TestableSurfaceFlinger::FakeDisplayDeviceInjector &)> injectExtra)93 sp<DisplayDevice> injectDefaultInternalDisplay( 94 std::function<void(TestableSurfaceFlinger::FakeDisplayDeviceInjector&)> injectExtra) { 95 return mFakeDisplayInjector.injectInternalDisplay(injectExtra); 96 } 97 98 // -------------------------------------------------------------------- 99 // Postcondition helpers 100 101 bool hasPhysicalHwcDisplay(hal::HWDisplayId) const; 102 bool hasTransactionFlagSet(int32_t flag) const; 103 104 bool hasDisplayDevice(const sp<IBinder>& displayToken) const; 105 const DisplayDevice& getDisplayDevice(const sp<IBinder>& displayToken) const; 106 107 bool hasCurrentDisplayState(const sp<IBinder>& displayToken) const; 108 const DisplayDeviceState& getCurrentDisplayState(const sp<IBinder>& displayToken) const; 109 110 bool hasDrawingDisplayState(const sp<IBinder>& displayToken) const; 111 const DisplayDeviceState& getDrawingDisplayState(const sp<IBinder>& displayToken) const; 112 113 // -------------------------------------------------------------------- 114 // Test instances 115 116 TestableSurfaceFlinger mFlinger; 117 118 sp<mock::NativeWindow> mNativeWindow = sp<mock::NativeWindow>::make(); 119 sp<compositionengine::mock::DisplaySurface> mDisplaySurface = 120 sp<compositionengine::mock::DisplaySurface>::make(); 121 122 sp<GraphicBuffer> mBuffer = 123 sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_8888, 124 GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_OFTEN); 125 adpf::mock::PowerAdvisor mPowerAdvisor; 126 127 FakeDisplayInjector mFakeDisplayInjector{mFlinger, mPowerAdvisor, mNativeWindow}; 128 129 // These mocks are created by the test, but are destroyed by SurfaceFlinger 130 // by virtue of being stored into a std::unique_ptr. However we still need 131 // to keep a reference to them for use in setting up call expectations. 132 renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); 133 Hwc2::mock::Composer* mComposer = nullptr; 134 135 mock::EventThread* mEventThread = new mock::EventThread; 136 mock::EventThread* mSFEventThread = new mock::EventThread; 137 138 // These mocks are created only when expected to be created via a factory. 139 sp<mock::GraphicBufferConsumer> mConsumer; 140 sp<mock::GraphicBufferProducer> mProducer; 141 surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr; 142 143 protected: 144 DisplayTransactionTest(bool withMockScheduler = true); 145 }; 146 147 constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'667; 148 constexpr int32_t DEFAULT_DPI = 320; 149 constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565; 150 151 constexpr int POWER_MODE_LEET = 1337; // An out of range power mode value 152 153 /* ------------------------------------------------------------------------ 154 * Boolean avoidance 155 * 156 * To make calls and template instantiations more readable, we define some 157 * local enums along with an implicit bool conversion. 158 */ 159 160 #define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true }; 161 162 BOOL_SUBSTITUTE(Async); 163 BOOL_SUBSTITUTE(Primary); 164 BOOL_SUBSTITUTE(Secure); 165 BOOL_SUBSTITUTE(Virtual); 166 167 template <typename PhysicalDisplay> 168 struct PhysicalDisplayIdType {}; 169 170 template <uint64_t displayId> 171 using HalVirtualDisplayIdType = std::integral_constant<uint64_t, displayId>; 172 173 struct GpuVirtualDisplayIdType {}; 174 175 template <typename> 176 struct IsPhysicalDisplayId : std::bool_constant<false> {}; 177 178 template <typename PhysicalDisplay> 179 struct IsPhysicalDisplayId<PhysicalDisplayIdType<PhysicalDisplay>> : std::bool_constant<true> {}; 180 181 template <typename> 182 struct DisplayIdGetter; 183 184 template <typename PhysicalDisplay> 185 struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> { 186 static DisplayIdVariant get() { 187 if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) { 188 return PhysicalDisplayId::fromPort(static_cast<bool>(PhysicalDisplay::PRIMARY) 189 ? LEGACY_DISPLAY_TYPE_PRIMARY 190 : LEGACY_DISPLAY_TYPE_EXTERNAL); 191 } 192 193 const auto info = 194 parseDisplayIdentificationData(PhysicalDisplay::PORT, 195 PhysicalDisplay::GET_IDENTIFICATION_DATA()); 196 return info ? info->id : PhysicalDisplayId::fromPort(PhysicalDisplay::PORT); 197 } 198 }; 199 200 template <VirtualDisplayId::BaseId displayId> 201 struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> { 202 static DisplayIdVariant get() { return HalVirtualDisplayId(displayId); } 203 }; 204 205 template <> 206 struct DisplayIdGetter<GpuVirtualDisplayIdType> { 207 static DisplayIdVariant get() { return GpuVirtualDisplayId(0); } 208 }; 209 210 template <typename> 211 struct DisplayConnectionTypeGetter { 212 static constexpr std::optional<ui::DisplayConnectionType> value; 213 }; 214 215 template <typename PhysicalDisplay> 216 struct DisplayConnectionTypeGetter<PhysicalDisplayIdType<PhysicalDisplay>> { 217 static constexpr std::optional<ui::DisplayConnectionType> value = 218 PhysicalDisplay::CONNECTION_TYPE; 219 }; 220 221 template <typename> 222 struct HwcDisplayIdGetter { 223 static constexpr std::optional<HWDisplayId> value; 224 }; 225 226 constexpr HWDisplayId HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010; 227 228 template <uint64_t displayId> 229 struct HwcDisplayIdGetter<HalVirtualDisplayIdType<displayId>> { 230 static constexpr std::optional<HWDisplayId> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID; 231 }; 232 233 template <typename PhysicalDisplay> 234 struct HwcDisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> { 235 static constexpr std::optional<HWDisplayId> value = PhysicalDisplay::HWC_DISPLAY_ID; 236 }; 237 238 template <typename> 239 struct PortGetter { 240 static constexpr std::optional<uint8_t> value; 241 }; 242 243 template <typename PhysicalDisplay> 244 struct PortGetter<PhysicalDisplayIdType<PhysicalDisplay>> { 245 static constexpr std::optional<uint8_t> value = PhysicalDisplay::PORT; 246 }; 247 248 // DisplayIdType can be: 249 // 1) PhysicalDisplayIdType<...> for generated ID of physical display backed by HWC. 250 // 2) HalVirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC. 251 // 3) GpuVirtualDisplayIdType for virtual display without HWC backing. 252 template <typename DisplayIdType, int width, int height, Async async, Secure secure, 253 Primary primary, int grallocUsage, int displayFlags> 254 struct DisplayVariant { 255 using DISPLAY_ID = DisplayIdGetter<DisplayIdType>; 256 using CONNECTION_TYPE = DisplayConnectionTypeGetter<DisplayIdType>; 257 using HWC_DISPLAY_ID_OPT = HwcDisplayIdGetter<DisplayIdType>; 258 using PORT = PortGetter<DisplayIdType>; 259 260 static constexpr int WIDTH = width; 261 static constexpr int HEIGHT = height; 262 static constexpr ui::Size RESOLUTION{WIDTH, HEIGHT}; 263 264 static constexpr int GRALLOC_USAGE = grallocUsage; 265 266 // Whether the display is virtual or physical 267 static constexpr Virtual VIRTUAL = 268 IsPhysicalDisplayId<DisplayIdType>{} ? Virtual::FALSE : Virtual::TRUE; 269 270 // When creating native window surfaces for the framebuffer, whether those should be async 271 static constexpr Async ASYNC = async; 272 273 // Whether the display should be treated as secure 274 static constexpr Secure SECURE = secure; 275 276 // Whether the display is primary 277 static constexpr Primary PRIMARY = primary; 278 279 static constexpr int DISPLAY_FLAGS = displayFlags; 280 281 static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) { 282 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder(); 283 ceDisplayArgs.setId(DISPLAY_ID::get()) 284 .setPixels(RESOLUTION) 285 .setPowerAdvisor(&test->mPowerAdvisor); 286 287 auto compositionDisplay = 288 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), 289 ceDisplayArgs.build()); 290 291 auto injector = 292 TestableSurfaceFlinger::FakeDisplayDeviceInjector(test->mFlinger, 293 compositionDisplay, 294 CONNECTION_TYPE::value, 295 PORT::value, 296 HWC_DISPLAY_ID_OPT::value, 297 static_cast<bool>(PRIMARY)); 298 299 injector.setSecure(static_cast<bool>(SECURE)); 300 injector.setNativeWindow(test->mNativeWindow); 301 injector.setDisplaySurface(test->mDisplaySurface); 302 303 // Creating a DisplayDevice requires getting default dimensions from the 304 // native window along with some other initial setup. 305 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _)) 306 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0))); 307 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _)) 308 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0))); 309 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)) 310 .WillRepeatedly(Return(0)); 311 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT)) 312 .WillRepeatedly(Return(0)); 313 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)) 314 .WillRepeatedly(Return(0)); 315 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)) 316 .WillRepeatedly(Return(0)); 317 318 return injector; 319 } 320 321 // Called by tests to set up any native window creation call expectations. 322 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) { 323 EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow()) 324 .WillOnce(Return(test->mNativeWindow)); 325 326 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _)) 327 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0))); 328 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _)) 329 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0))); 330 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)) 331 .WillRepeatedly(Return(0)); 332 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT)) 333 .WillRepeatedly(Return(0)); 334 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)) 335 .WillRepeatedly(Return(0)); 336 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)) 337 .WillRepeatedly(Return(0)); 338 } 339 340 static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) { 341 EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR)); 342 EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR)); 343 EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE)) 344 .WillRepeatedly(Return(NO_ERROR)); 345 EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT)) 346 .WillRepeatedly(Return(NO_ERROR)); 347 EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_)) 348 .WillRepeatedly(Return(NO_ERROR)); 349 } 350 351 static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) { 352 EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return()); 353 } 354 }; 355 356 template <HWDisplayId hwcDisplayId, DisplayType hwcDisplayType, typename DisplayVariant, 357 typename PhysicalDisplay = void> 358 struct HwcDisplayVariant { 359 // The display id supplied by the HWC 360 static constexpr HWDisplayId HWC_DISPLAY_ID = hwcDisplayId; 361 362 // The HWC display type 363 static constexpr DisplayType HWC_DISPLAY_TYPE = hwcDisplayType; 364 365 // The HWC active configuration id 366 static constexpr hal::HWConfigId HWC_ACTIVE_CONFIG_ID = 2001; 367 368 static void injectPendingHotplugEvent(DisplayTransactionTest* test, 369 HWComposer::HotplugEvent event) { 370 test->mFlinger.mutablePendingHotplugEvents().emplace_back( 371 TestableSurfaceFlinger::HotplugEvent{HWC_DISPLAY_ID, event}); 372 } 373 374 // Called by tests to inject a HWC display setup 375 template <hal::PowerMode kPowerMode = hal::PowerMode::ON> 376 static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) { 377 TestableSurfaceFlinger::FakeHwcDisplayInjector(DisplayVariant::DISPLAY_ID::get(), 378 HWC_DISPLAY_TYPE, 379 static_cast<bool>(DisplayVariant::PRIMARY)) 380 .setHwcDisplayId(HWC_DISPLAY_ID) 381 .setResolution(DisplayVariant::RESOLUTION) 382 .setActiveConfig(HWC_ACTIVE_CONFIG_ID) 383 .setPowerMode(kPowerMode) 384 .inject(&test->mFlinger, test->mComposer); 385 } 386 387 // Called by tests to inject a HWC display setup 388 // 389 // TODO(b/241285876): The `kExpectSetPowerModeOnce` argument is set to `false` by tests that 390 // power on/off displays several times. Replace those catch-all expectations with `InSequence` 391 // and `RetiresOnSaturation`. 392 // 393 template <hal::PowerMode kPowerMode = hal::PowerMode::ON, bool kExpectSetPowerModeOnce = true> 394 static void injectHwcDisplay(DisplayTransactionTest* test) { 395 if constexpr (kExpectSetPowerModeOnce) { 396 if constexpr (kPowerMode == hal::PowerMode::ON) { 397 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _)) 398 .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})), 399 Return(Error::NONE))); 400 } 401 402 EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, kPowerMode)) 403 .WillOnce(Return(Error::NONE)); 404 } else { 405 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _)) 406 .WillRepeatedly(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})), 407 Return(Error::NONE))); 408 409 EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, _)) 410 .WillRepeatedly(Return(Error::NONE)); 411 } 412 413 injectHwcDisplayWithNoDefaultCapabilities<kPowerMode>(test); 414 } 415 416 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay( 417 DisplayTransactionTest* test) { 418 const ::testing::TestInfo* const test_info = 419 ::testing::UnitTest::GetInstance()->current_test_info(); 420 421 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() 422 .setId(DisplayVariant::DISPLAY_ID::get()) 423 .setPixels(DisplayVariant::RESOLUTION) 424 .setIsSecure(static_cast<bool>(DisplayVariant::SECURE)) 425 .setPowerAdvisor(&test->mPowerAdvisor) 426 .setName(std::string("Injected display for ") + 427 test_info->test_case_name() + "." + test_info->name()) 428 .build(); 429 430 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), 431 ceDisplayArgs); 432 } 433 434 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) { 435 if (HWC_DISPLAY_TYPE == DisplayType::PHYSICAL) { 436 EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _)) 437 .WillRepeatedly(DoAll(SetArgPointee<1>(std::vector<hal::HWConfigId>{ 438 HWC_ACTIVE_CONFIG_ID}), 439 Return(Error::NONE))); 440 EXPECT_CALL(*test->mComposer, 441 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID, 442 IComposerClient::Attribute::WIDTH, _)) 443 .WillRepeatedly( 444 DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE))); 445 EXPECT_CALL(*test->mComposer, 446 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID, 447 IComposerClient::Attribute::HEIGHT, _)) 448 .WillRepeatedly( 449 DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE))); 450 EXPECT_CALL(*test->mComposer, 451 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID, 452 IComposerClient::Attribute::VSYNC_PERIOD, _)) 453 .WillRepeatedly( 454 DoAll(SetArgPointee<3>(DEFAULT_VSYNC_PERIOD), Return(Error::NONE))); 455 EXPECT_CALL(*test->mComposer, 456 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID, 457 IComposerClient::Attribute::DPI_X, _)) 458 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE))); 459 EXPECT_CALL(*test->mComposer, 460 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID, 461 IComposerClient::Attribute::DPI_Y, _)) 462 .WillRepeatedly(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE))); 463 EXPECT_CALL(*test->mComposer, 464 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID, 465 IComposerClient::Attribute::CONFIG_GROUP, _)) 466 .WillRepeatedly(DoAll(SetArgPointee<3>(-1), Return(Error::NONE))); 467 } else { 468 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0); 469 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0); 470 } 471 } 472 473 template <bool kFailedHotplug = false> 474 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) { 475 if constexpr (!kFailedHotplug) { 476 constexpr auto CONNECTION_TYPE = 477 PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal 478 ? IComposerClient::DisplayConnectionType::INTERNAL 479 : IComposerClient::DisplayConnectionType::EXTERNAL; 480 481 using ::testing::AtLeast; 482 EXPECT_CALL(*test->mComposer, getDisplayConnectionType(HWC_DISPLAY_ID, _)) 483 .Times(AtLeast(1)) 484 .WillRepeatedly(DoAll(SetArgPointee<1>(CONNECTION_TYPE), 485 Return(hal::V2_4::Error::NONE))); 486 } 487 488 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)) 489 .WillOnce(Return(hal::Error::NONE)); 490 491 setupHwcGetConfigsCallExpectations(test); 492 493 if (PhysicalDisplay::HAS_IDENTIFICATION_DATA) { 494 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _)) 495 .WillOnce(DoAll(SetArgPointee<1>(PhysicalDisplay::PORT), 496 SetArgPointee<2>(PhysicalDisplay::GET_IDENTIFICATION_DATA()), 497 Return(Error::NONE))); 498 } else { 499 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _)) 500 .WillOnce(Return(Error::UNSUPPORTED)); 501 } 502 } 503 504 // Called by tests to set up HWC call expectations 505 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) { 506 EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _)) 507 .WillRepeatedly(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE))); 508 } 509 }; 510 511 // Physical displays are expected to be synchronous, secure, and have a HWC display for output. 512 constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY = 513 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB; 514 515 constexpr int PHYSICAL_DISPLAY_FLAGS = 0x1; 516 517 template <typename PhysicalDisplay, int width, int height, 518 Secure secure = (PhysicalDisplay::SECURE) ? Secure::TRUE : Secure::FALSE> 519 struct PhysicalDisplayVariant 520 : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, Async::FALSE, secure, 521 PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY, 522 PHYSICAL_DISPLAY_FLAGS>, 523 HwcDisplayVariant<PhysicalDisplay::HWC_DISPLAY_ID, DisplayType::PHYSICAL, 524 DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, 525 Async::FALSE, secure, PhysicalDisplay::PRIMARY, 526 GRALLOC_USAGE_PHYSICAL_DISPLAY, PHYSICAL_DISPLAY_FLAGS>, 527 PhysicalDisplay> {}; 528 529 template <bool hasIdentificationData> 530 struct PrimaryDisplay { 531 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal; 532 static constexpr Primary PRIMARY = Primary::TRUE; 533 static constexpr bool SECURE = true; 534 static constexpr uint8_t PORT = 255; 535 static constexpr HWDisplayId HWC_DISPLAY_ID = 1001; 536 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData; 537 static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid; 538 }; 539 540 template <ui::DisplayConnectionType connectionType, bool hasIdentificationData, bool secure, 541 HWDisplayId hwDisplayId = 1002> 542 struct SecondaryDisplay { 543 static constexpr auto CONNECTION_TYPE = connectionType; 544 static constexpr Primary PRIMARY = Primary::FALSE; 545 static constexpr bool SECURE = secure; 546 static constexpr uint8_t PORT = 254; 547 static constexpr HWDisplayId HWC_DISPLAY_ID = hwDisplayId; 548 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData; 549 static constexpr auto GET_IDENTIFICATION_DATA = 550 connectionType == ui::DisplayConnectionType::Internal ? getInternalEdid 551 : getExternalEdid; 552 }; 553 554 constexpr bool kSecure = true; 555 constexpr bool kNonSecure = false; 556 557 template <bool secure> 558 struct TertiaryDisplay { 559 static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External; 560 static constexpr Primary PRIMARY = Primary::FALSE; 561 static constexpr bool SECURE = secure; 562 static constexpr uint8_t PORT = 253; 563 static constexpr HWDisplayId HWC_DISPLAY_ID = 1003; 564 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid; 565 }; 566 567 using PrimaryDisplayVariant = PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160>; 568 569 using InnerDisplayVariant = PhysicalDisplayVariant<PrimaryDisplay<true>, 1840, 2208>; 570 using OuterDisplayVariant = 571 PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::Internal, 572 /*hasIdentificationData=*/true, kSecure>, 573 1080, 2092>; 574 using OuterDisplayNonSecureVariant = 575 PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::Internal, 576 /*hasIdentificationData=*/true, kNonSecure>, 577 1080, 2092>; 578 579 template <HWDisplayId hwDisplayId = 1002> 580 using ExternalDisplayWithIdentificationVariant = PhysicalDisplayVariant< 581 SecondaryDisplay<ui::DisplayConnectionType::External, 582 /*hasIdentificationData=*/true, kNonSecure, hwDisplayId>, 583 1920, 1280>; 584 using ExternalDisplayVariant = 585 PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External, 586 /*hasIdentificationData=*/false, kSecure>, 587 1920, 1280>; 588 using ExternalDisplayNonSecureVariant = 589 PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External, 590 /*hasIdentificationData=*/false, kNonSecure>, 591 1920, 1280>; 592 593 using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay<kSecure>, 1600, 1200>; 594 using TertiaryDisplayNonSecureVariant = 595 PhysicalDisplayVariant<TertiaryDisplay<kNonSecure>, 1600, 1200>; 596 597 // A virtual display not supported by the HWC. 598 constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0; 599 600 constexpr int VIRTUAL_DISPLAY_FLAGS = 0x0; 601 602 template <int width, int height, Secure secure> 603 struct NonHwcVirtualDisplayVariant 604 : DisplayVariant<GpuVirtualDisplayIdType, width, height, Async::TRUE, secure, Primary::FALSE, 605 GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY, VIRTUAL_DISPLAY_FLAGS> { 606 using Base = DisplayVariant<GpuVirtualDisplayIdType, width, height, Async::TRUE, secure, 607 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY, 608 VIRTUAL_DISPLAY_FLAGS>; 609 610 static void injectHwcDisplay(DisplayTransactionTest*) {} 611 612 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay( 613 DisplayTransactionTest* test) { 614 const ::testing::TestInfo* const test_info = 615 ::testing::UnitTest::GetInstance()->current_test_info(); 616 617 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() 618 .setId(Base::DISPLAY_ID::get()) 619 .setPixels(Base::RESOLUTION) 620 .setIsSecure(static_cast<bool>(Base::SECURE)) 621 .setPowerAdvisor(&test->mPowerAdvisor) 622 .setName(std::string("Injected display for ") + 623 test_info->test_case_name() + "." + test_info->name()) 624 .build(); 625 626 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), 627 ceDisplayArgs); 628 } 629 630 static void setupHwcGetConfigsCallExpectations(DisplayTransactionTest* test) { 631 EXPECT_CALL(*test->mComposer, getDisplayConfigs(_, _)).Times(0); 632 EXPECT_CALL(*test->mComposer, getDisplayAttribute(_, _, _, _)).Times(0); 633 } 634 635 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) { 636 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0); 637 } 638 639 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) { 640 Base::setupNativeWindowSurfaceCreationCallExpectations(test); 641 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1); 642 } 643 }; 644 645 // A virtual display supported by the HWC. 646 constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER; 647 648 template <int width, int height, Secure secure> 649 struct HwcVirtualDisplayVariant 650 : DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Async::TRUE, secure, 651 Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY, VIRTUAL_DISPLAY_FLAGS>, 652 HwcDisplayVariant<HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL, 653 DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Async::TRUE, 654 secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY, 655 VIRTUAL_DISPLAY_FLAGS>> { 656 using Base = DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Async::TRUE, secure, 657 Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER, VIRTUAL_DISPLAY_FLAGS>; 658 using Self = HwcVirtualDisplayVariant<width, height, secure>; 659 660 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay( 661 DisplayTransactionTest* test) { 662 const ::testing::TestInfo* const test_info = 663 ::testing::UnitTest::GetInstance()->current_test_info(); 664 665 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder() 666 .setId(Base::DISPLAY_ID::get()) 667 .setPixels(Base::RESOLUTION) 668 .setIsSecure(static_cast<bool>(Base::SECURE)) 669 .setPowerAdvisor(&test->mPowerAdvisor) 670 .setName(std::string("Injected display for ") + 671 test_info->test_case_name() + "." + test_info->name()) 672 .build(); 673 674 auto compositionDisplay = 675 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(), 676 ceDisplayArgs); 677 678 // Insert display data so that the HWC thinks it created the virtual display. 679 const auto ceDisplayIdVar = compositionDisplay->getDisplayIdVariant(); 680 LOG_ALWAYS_FATAL_IF(!ceDisplayIdVar); 681 EXPECT_EQ(*ceDisplayIdVar, Base::DISPLAY_ID::get()); 682 const auto displayId = asHalDisplayId(*ceDisplayIdVar); 683 LOG_ALWAYS_FATAL_IF(!displayId); 684 test->mFlinger.mutableHwcDisplayData().try_emplace(*displayId); 685 686 return compositionDisplay; 687 } 688 689 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) { 690 Base::setupNativeWindowSurfaceCreationCallExpectations(test); 691 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1); 692 } 693 694 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) { 695 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _)) 696 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE))); 697 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE)); 698 } 699 }; 700 701 // For this variant, the display is not a HWC display, so no HDR support should 702 // be configured. 703 struct NonHwcDisplayHdrSupportVariant { 704 static constexpr bool HDR10_PLUS_SUPPORTED = false; 705 static constexpr bool HDR10_SUPPORTED = false; 706 static constexpr bool HDR_HLG_SUPPORTED = false; 707 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false; 708 static void setupComposerCallExpectations(DisplayTransactionTest* test) { 709 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0); 710 } 711 }; 712 713 // For this variant, the composer should respond with am empty list of HDR 714 // modes, so no HDR support should be configured. 715 template <typename Display> 716 struct HdrNotSupportedVariant { 717 static constexpr bool HDR10_PLUS_SUPPORTED = false; 718 static constexpr bool HDR10_SUPPORTED = false; 719 static constexpr bool HDR_HLG_SUPPORTED = false; 720 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false; 721 static void setupComposerCallExpectations(DisplayTransactionTest* test) { 722 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _)) 723 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE))); 724 } 725 }; 726 727 struct NonHwcPerFrameMetadataSupportVariant { 728 static constexpr int PER_FRAME_METADATA_KEYS = 0; 729 static void setupComposerCallExpectations(DisplayTransactionTest* test) { 730 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_)).Times(0); 731 } 732 }; 733 734 template <typename Display> 735 struct NoPerFrameMetadataSupportVariant { 736 static constexpr int PER_FRAME_METADATA_KEYS = 0; 737 static void setupComposerCallExpectations(DisplayTransactionTest* test) { 738 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID)) 739 .WillOnce(Return(std::vector<PerFrameMetadataKey>())); 740 } 741 }; 742 743 // For this variant, SurfaceFlinger should configure itself with wide display 744 // support, but the display should respond with an empty list of supported color 745 // modes. Wide-color support for the display should not be configured. 746 template <typename Display> 747 struct WideColorNotSupportedVariant { 748 static constexpr bool WIDE_COLOR_SUPPORTED = false; 749 750 static void injectConfigChange(DisplayTransactionTest* test) { 751 test->mFlinger.mutableSupportsWideColor() = true; 752 } 753 754 static void setupComposerCallExpectations(DisplayTransactionTest* test) { 755 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0); 756 } 757 }; 758 759 // For this variant, SurfaceFlinger should not configure itself with wide 760 // display support, so the display should not be configured for wide-color 761 // support. 762 struct WideColorSupportNotConfiguredVariant { 763 static constexpr bool WIDE_COLOR_SUPPORTED = false; 764 765 static void injectConfigChange(DisplayTransactionTest* test) { 766 test->mFlinger.mutableSupportsWideColor() = false; 767 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged; 768 } 769 770 static void setupComposerCallExpectations(DisplayTransactionTest* test) { 771 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0); 772 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0); 773 } 774 }; 775 776 /* ------------------------------------------------------------------------ 777 * Typical display configurations to test 778 */ 779 780 template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy, 781 typename PerFrameMetadataSupportPolicy> 782 struct Case { 783 using Display = DisplayPolicy; 784 using WideColorSupport = WideColorSupportPolicy; 785 using HdrSupport = HdrSupportPolicy; 786 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy; 787 }; 788 789 using SimplePrimaryDisplayCase = 790 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>, 791 HdrNotSupportedVariant<PrimaryDisplayVariant>, 792 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>; 793 using SimpleExternalDisplayCase = 794 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>, 795 HdrNotSupportedVariant<ExternalDisplayVariant>, 796 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>; 797 using SimpleExternalDisplayNonSecureCase = 798 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayNonSecureVariant>, 799 HdrNotSupportedVariant<ExternalDisplayNonSecureVariant>, 800 NoPerFrameMetadataSupportVariant<ExternalDisplayNonSecureVariant>>; 801 using SimpleTertiaryDisplayCase = 802 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>, 803 HdrNotSupportedVariant<TertiaryDisplayVariant>, 804 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>; 805 using SimpleTertiaryDisplayNonSecureCase = 806 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayNonSecureVariant>, 807 HdrNotSupportedVariant<TertiaryDisplayNonSecureVariant>, 808 NoPerFrameMetadataSupportVariant<TertiaryDisplayNonSecureVariant>>; 809 810 using NonHwcVirtualDisplayCase = 811 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>, 812 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant, 813 NonHwcPerFrameMetadataSupportVariant>; 814 using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>; 815 using HwcVirtualDisplayCase = 816 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant, 817 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>, 818 NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>; 819 820 inline DisplayModePtr createDisplayMode(DisplayModeId modeId, Fps refreshRate, int32_t group = 0, 821 ui::Size resolution = ui::Size(1920, 1080)) { 822 const auto physicalDisplayId = asPhysicalDisplayId(PrimaryDisplayVariant::DISPLAY_ID::get()); 823 LOG_ALWAYS_FATAL_IF(!physicalDisplayId); 824 return mock::createDisplayMode(modeId, refreshRate, group, resolution, *physicalDisplayId); 825 } 826 827 } // namespace android 828 829 // TODO(b/129481165): remove the #pragma below and fix conversion issues 830 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra" 831