| // Copyright 2025 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/graphics/display/lib/api-protocols/cpp/mock-display-engine.h" |
| |
| #include <fidl/fuchsia.sysmem2/cpp/wire.h> |
| #include <lib/stdcompat/span.h> |
| #include <lib/zx/result.h> |
| #include <zircon/assert.h> |
| |
| #include <cstdint> |
| #include <mutex> |
| #include <utility> |
| |
| #include "src/graphics/display/lib/api-types/cpp/config-check-result.h" |
| #include "src/graphics/display/lib/api-types/cpp/display-id.h" |
| #include "src/graphics/display/lib/api-types/cpp/driver-buffer-collection-id.h" |
| #include "src/graphics/display/lib/api-types/cpp/driver-capture-image-id.h" |
| #include "src/graphics/display/lib/api-types/cpp/driver-config-stamp.h" |
| #include "src/graphics/display/lib/api-types/cpp/driver-image-id.h" |
| #include "src/graphics/display/lib/api-types/cpp/driver-layer.h" |
| #include "src/graphics/display/lib/api-types/cpp/image-buffer-usage.h" |
| #include "src/graphics/display/lib/api-types/cpp/image-metadata.h" |
| #include "src/graphics/display/lib/api-types/cpp/mode-id.h" |
| |
| namespace display::testing { |
| |
| struct MockDisplayEngine::Expectation { |
| CompleteCoordinatorConnectionChecker complete_coordinator_connection_checker; |
| ImportBufferCollectionChecker import_buffer_collection_checker; |
| ReleaseBufferCollectionChecker release_buffer_collection_checker; |
| ImportImageChecker import_image_checker; |
| ImportImageForCaptureChecker import_image_for_capture_checker; |
| ReleaseImageChecker release_image_checker; |
| CheckConfigurationChecker check_configuration_checker; |
| ApplyConfigurationChecker apply_configuration_checker; |
| SetBufferCollectionConstraintsChecker set_buffer_collection_constraints_checker; |
| SetDisplayPowerChecker set_display_power_checker; |
| IsCaptureSupportedChecker is_capture_supported_checker; |
| StartCaptureChecker start_capture_checker; |
| ReleaseCaptureChecker release_capture_checker; |
| SetMinimumRgbChecker set_minimum_rgb_checker; |
| }; |
| |
| MockDisplayEngine::MockDisplayEngine() = default; |
| |
| MockDisplayEngine::~MockDisplayEngine() { |
| ZX_ASSERT_MSG(check_all_calls_replayed_called_, "CheckAllCallsReplayed() not called on a mock"); |
| } |
| |
| void MockDisplayEngine::ExpectCompleteCoordinatorConnection( |
| CompleteCoordinatorConnectionChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.complete_coordinator_connection_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectImportBufferCollection(ImportBufferCollectionChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.import_buffer_collection_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectReleaseBufferCollection(ReleaseBufferCollectionChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.release_buffer_collection_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectImportImage(ImportImageChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.import_image_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectImportImageForCapture(ImportImageForCaptureChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.import_image_for_capture_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectReleaseImage(ReleaseImageChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.release_image_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectCheckConfiguration(CheckConfigurationChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.check_configuration_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectApplyConfiguration(ApplyConfigurationChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.apply_configuration_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectSetBufferCollectionConstraints( |
| SetBufferCollectionConstraintsChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.set_buffer_collection_constraints_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectSetDisplayPower(SetDisplayPowerChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.set_display_power_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectIsCaptureSupported(IsCaptureSupportedChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.is_capture_supported_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectStartCapture(StartCaptureChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.start_capture_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectReleaseCapture(ReleaseCaptureChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.release_capture_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::ExpectSetMinimumRgb(SetMinimumRgbChecker checker) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| expectations_.push_back({.set_minimum_rgb_checker = std::move(checker)}); |
| } |
| |
| void MockDisplayEngine::CheckAllCallsReplayed() { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(expectations_.size() == call_index_, "%zu expected calls were not received", |
| expectations_.size() - call_index_); |
| check_all_calls_replayed_called_ = true; |
| } |
| |
| display::EngineInfo MockDisplayEngine::CompleteCoordinatorConnection() { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.complete_coordinator_connection_checker != nullptr, |
| "Received call type does not match expected call type"); |
| return call_expectation.complete_coordinator_connection_checker(); |
| } |
| |
| zx::result<> MockDisplayEngine::ImportBufferCollection( |
| display::DriverBufferCollectionId buffer_collection_id, |
| fidl::ClientEnd<fuchsia_sysmem2::BufferCollectionToken> buffer_collection_token) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.import_buffer_collection_checker != nullptr, |
| "Received call type does not match expected call type"); |
| return call_expectation.import_buffer_collection_checker(buffer_collection_id, |
| std::move(buffer_collection_token)); |
| } |
| |
| zx::result<> MockDisplayEngine::ReleaseBufferCollection( |
| display::DriverBufferCollectionId buffer_collection_id) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.release_buffer_collection_checker != nullptr, |
| "Received call type does not match expected call type"); |
| return call_expectation.release_buffer_collection_checker(buffer_collection_id); |
| } |
| |
| zx::result<display::DriverImageId> MockDisplayEngine::ImportImage( |
| const display::ImageMetadata& image_metadata, |
| display::DriverBufferCollectionId buffer_collection_id, uint32_t buffer_index) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.import_image_checker != nullptr, |
| "Received call type does not match expected call type"); |
| return call_expectation.import_image_checker(image_metadata, buffer_collection_id, buffer_index); |
| } |
| |
| zx::result<display::DriverCaptureImageId> MockDisplayEngine::ImportImageForCapture( |
| display::DriverBufferCollectionId buffer_collection_id, uint32_t buffer_index) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.import_image_for_capture_checker != nullptr, |
| "Received call type does not match expected call type"); |
| return call_expectation.import_image_for_capture_checker(buffer_collection_id, buffer_index); |
| } |
| |
| void MockDisplayEngine::ReleaseImage(display::DriverImageId driver_image_id) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.release_image_checker != nullptr, |
| "Received call type does not match expected call type"); |
| call_expectation.release_image_checker(driver_image_id); |
| } |
| |
| display::ConfigCheckResult MockDisplayEngine::CheckConfiguration( |
| display::DisplayId display_id, display::ModeId display_mode_id, |
| display::ColorConversion color_conversion, cpp20::span<const display::DriverLayer> layers) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.check_configuration_checker != nullptr, |
| "Received call type does not match expected call type"); |
| return call_expectation.check_configuration_checker(display_id, display_mode_id, color_conversion, |
| layers); |
| } |
| |
| void MockDisplayEngine::ApplyConfiguration(display::DisplayId display_id, |
| display::ModeId display_mode_id, |
| display::ColorConversion color_conversion, |
| cpp20::span<const display::DriverLayer> layers, |
| display::DriverConfigStamp config_stamp) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.apply_configuration_checker != nullptr, |
| "Received call type does not match expected call type"); |
| call_expectation.apply_configuration_checker(display_id, display_mode_id, color_conversion, |
| layers, config_stamp); |
| } |
| |
| zx::result<> MockDisplayEngine::SetBufferCollectionConstraints( |
| const display::ImageBufferUsage& image_buffer_usage, |
| display::DriverBufferCollectionId buffer_collection_id) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.set_buffer_collection_constraints_checker != nullptr, |
| "Received call type does not match expected call type"); |
| return call_expectation.set_buffer_collection_constraints_checker(image_buffer_usage, |
| buffer_collection_id); |
| } |
| |
| zx::result<> MockDisplayEngine::SetDisplayPower(display::DisplayId display_id, bool power_on) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.set_display_power_checker != nullptr, |
| "Received call type does not match expected call type"); |
| return call_expectation.set_display_power_checker(display_id, power_on); |
| } |
| |
| zx::result<> MockDisplayEngine::StartCapture(display::DriverCaptureImageId capture_image_id) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.start_capture_checker != nullptr, |
| "Received call type does not match expected call type"); |
| return call_expectation.start_capture_checker(capture_image_id); |
| } |
| |
| zx::result<> MockDisplayEngine::ReleaseCapture(display::DriverCaptureImageId capture_image_id) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.release_capture_checker != nullptr, |
| "Received call type does not match expected call type"); |
| return call_expectation.release_capture_checker(capture_image_id); |
| } |
| |
| zx::result<> MockDisplayEngine::SetMinimumRgb(uint8_t minimum_rgb) { |
| std::lock_guard<std::mutex> lock(mutex_); |
| ZX_ASSERT_MSG(call_index_ < expectations_.size(), "All expected calls were already received"); |
| Expectation& call_expectation = expectations_[call_index_]; |
| ++call_index_; |
| |
| ZX_ASSERT_MSG(call_expectation.set_minimum_rgb_checker != nullptr, |
| "Received call type does not match expected call type"); |
| return call_expectation.set_minimum_rgb_checker(minimum_rgb); |
| } |
| |
| } // namespace display::testing |