From d40b5667d71af5fb250c676d7570eea89d22909f Mon Sep 17 00:00:00 2001 From: ramindani Date: Tue, 23 May 2023 21:44:49 +0000 Subject: [PATCH 1/3] [Composer-HAL-AIDL] Interface changes with getDisplayConfigurations Updates to the AIDL interfaces with getDisplayConfigurations This will be replacing the getDisplayConfig api that will be deprecated in the upcoming CL's. implementations will follow in the upcoming CL's Test: device boots, atest libsurfacerflinger_unittest, atest VtsHalGraphicsComposer3_TargetTest BUG: 284866749 BUG: 287517352 Change-Id: I2b64dcaace26a297f308e8f5c2568c35c9cd38cb --- graphics/composer/aidl/Android.bp | 2 +- .../composer3/DisplayConfiguration.aidl | 47 ++++++++++++++ .../graphics/composer3/IComposerClient.aidl | 4 ++ .../composer3/DisplayConfiguration.aidl | 63 +++++++++++++++++++ .../graphics/composer3/IComposerClient.aidl | 25 +++++--- 5 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayConfiguration.aidl create mode 100644 graphics/composer/aidl/android/hardware/graphics/composer3/DisplayConfiguration.aidl diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp index 40448ec43e..88abb7387c 100644 --- a/graphics/composer/aidl/Android.bp +++ b/graphics/composer/aidl/Android.bp @@ -31,7 +31,7 @@ aidl_interface { enabled: true, support_system_process: true, }, - frozen: true, + frozen: false, vndk_use_version: "1", srcs: [ "android/hardware/graphics/composer3/*.aidl", diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayConfiguration.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayConfiguration.aidl new file mode 100644 index 0000000000..908842a467 --- /dev/null +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayConfiguration.aidl @@ -0,0 +1,47 @@ +/** + * Copyright 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.graphics.composer3; +@VintfStability +parcelable DisplayConfiguration { + int configId; + int width; + int height; + @nullable android.hardware.graphics.composer3.DisplayConfiguration.Dpi dpi; + int configGroup; + int vsyncPeriod; + parcelable Dpi { + float x; + float y; + } +} diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl index cb85a88995..2f08b6fbf9 100644 --- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl +++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl @@ -44,6 +44,9 @@ interface IComposerClient { float[] getDataspaceSaturationMatrix(android.hardware.graphics.common.Dataspace dataspace); int getDisplayAttribute(long display, int config, android.hardware.graphics.composer3.DisplayAttribute attribute); android.hardware.graphics.composer3.DisplayCapability[] getDisplayCapabilities(long display); + /** + * @deprecated use getDisplayConfigurations instead. For legacy support getDisplayConfigs should return at least one valid config. All the configs returned from the getDisplayConfigs should also be returned from getDisplayConfigurations. + */ int[] getDisplayConfigs(long display); android.hardware.graphics.composer3.DisplayConnectionType getDisplayConnectionType(long display); android.hardware.graphics.composer3.DisplayIdentification getDisplayIdentificationData(long display); @@ -79,6 +82,7 @@ interface IComposerClient { android.hardware.graphics.common.HdrConversionCapability[] getHdrConversionCapabilities(); android.hardware.graphics.common.Hdr setHdrConversionStrategy(in android.hardware.graphics.common.HdrConversionStrategy conversionStrategy); void setRefreshRateChangedCallbackDebugEnabled(long display, boolean enabled); + android.hardware.graphics.composer3.DisplayConfiguration[] getDisplayConfigurations(long display); const int EX_BAD_CONFIG = 1; const int EX_BAD_DISPLAY = 2; const int EX_BAD_LAYER = 3; diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayConfiguration.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayConfiguration.aidl new file mode 100644 index 0000000000..b0095d2dcd --- /dev/null +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayConfiguration.aidl @@ -0,0 +1,63 @@ +/** + * Copyright 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.graphics.composer3; + +@VintfStability +parcelable DisplayConfiguration { + /** + * The config id, to be used with IComposerClient.setActiveConfig. + */ + int configId; + + /** + * Dimensions in pixels + */ + int width; + int height; + + /** + * Dots per thousand inches. + * If the DPI for a configuration is unavailable or is + * considered unreliable, the device may set null instead. + */ + parcelable Dpi { + float x; + float y; + } + @nullable Dpi dpi; + + /** + * The configuration group ID this config is associated to. + * Switching between configurations within the same group may be + * done seamlessly in some conditions via + * setActiveConfigWithConstraints. Configurations which share the + * same config group are similar in all attributes except for the + * vsync period. + */ + int configGroup; + + /** + * Vsync period in nanoseconds. This period represents the internal + * frequency of the display. IComposerCallback.onVsync is expected + * to be called on each vsync event. For non-VRR configurations, a + * frame can be presented on each vsync event. + * + * A present fence, retrieved from CommandResultPayload.presentFence + * must be signaled on a vsync boundary. + */ + int vsyncPeriod; +} diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl index 4e77f86cf4..5d04a28b00 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl @@ -28,6 +28,7 @@ import android.hardware.graphics.composer3.ContentType; import android.hardware.graphics.composer3.DisplayAttribute; import android.hardware.graphics.composer3.DisplayCapability; import android.hardware.graphics.composer3.DisplayCommand; +import android.hardware.graphics.composer3.DisplayConfiguration; import android.hardware.graphics.composer3.DisplayConnectionType; import android.hardware.graphics.composer3.DisplayContentSample; import android.hardware.graphics.composer3.DisplayContentSamplingAttributes; @@ -263,15 +264,12 @@ interface IComposerClient { DisplayCapability[] getDisplayCapabilities(long display); /** - * Returns handles for all of the valid display configurations on this - * display. - * This should never return INVALID_CONFIGURATION as a valid value. + * @deprecated use getDisplayConfigurations instead. + * For legacy support getDisplayConfigs should return at least one valid config. + * All the configs returned from the getDisplayConfigs should also be returned + * from getDisplayConfigurations. * - * @param display is the display to query. - * - * @return is an array of configuration handles. - * - * @exception EX_BAD_DISPLAY when an invalid display handle was passed in. + * @see getDisplayConfigurations */ int[] getDisplayConfigs(long display); @@ -864,4 +862,15 @@ interface IComposerClient { * false when refresh rate callback is disabled. */ void setRefreshRateChangedCallbackDebugEnabled(long display, boolean enabled); + + /** + * Returns all of the valid display configurations. + * getDisplayConfigurations is the superset of getDisplayConfigs and + * getDisplayConfigs should return at least one config. + * + * @param display is the display for which the configurations are requested. + * + * @see getDisplayConfigs + */ + DisplayConfiguration[] getDisplayConfigurations(long display); } From e50ed5d4e6d983fbf490527c847144e103a61109 Mon Sep 17 00:00:00 2001 From: ramindani Date: Thu, 29 Jun 2023 19:54:40 -0700 Subject: [PATCH 2/3] Upgrade Composer interface version Test: device boots, atest libsurfacerflinger_unittest, atest VtsHalGraphicsComposer3_TargetTest BUG: 284866749 BUG: 287517352 Change-Id: I803a4291c0839857f7e23696da7dac4c15a21e09 --- compatibility_matrices/compatibility_matrix.9.xml | 2 +- graphics/Android.bp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml index 14b921004e..559e7c2a4b 100644 --- a/compatibility_matrices/compatibility_matrix.9.xml +++ b/compatibility_matrices/compatibility_matrix.9.xml @@ -248,7 +248,7 @@ android.hardware.graphics.composer3 - 2 + 3 IComposer default diff --git a/graphics/Android.bp b/graphics/Android.bp index 2fbcb41c47..8a69f0950e 100644 --- a/graphics/Android.bp +++ b/graphics/Android.bp @@ -53,13 +53,13 @@ cc_defaults { cc_defaults { name: "android.hardware.graphics.composer3-ndk_static", static_libs: [ - "android.hardware.graphics.composer3-V2-ndk", + "android.hardware.graphics.composer3-V3-ndk", ], } cc_defaults { name: "android.hardware.graphics.composer3-ndk_shared", shared_libs: [ - "android.hardware.graphics.composer3-V2-ndk", + "android.hardware.graphics.composer3-V3-ndk", ], } From 02fe4772187e6d22d4e16b35327dba5f3234a1be Mon Sep 17 00:00:00 2001 From: ramindani Date: Fri, 30 Jun 2023 18:04:41 -0700 Subject: [PATCH 3/3] [Composer VTS] Adds VTS for getDisplayConfigurations Test getDisplayConfigurations on the version 3 of the composer. Test: atest VtsHalGraphicsComposer3_TargetTest BUG: 287518719 BUG: 284866749 Change-Id: Ibb654dbeb4b164d86f92f51f8083ed1ab06fcfa4 --- .../composer/aidl/vts/VtsComposerClient.cpp | 124 ++++++++++++------ .../composer/aidl/vts/VtsComposerClient.h | 9 +- .../VtsHalGraphicsComposer3_TargetTest.cpp | 109 +++++++++++++++ 3 files changed, 202 insertions(+), 40 deletions(-) diff --git a/graphics/composer/aidl/vts/VtsComposerClient.cpp b/graphics/composer/aidl/vts/VtsComposerClient.cpp index 25b0ca0a17..bf42d8898c 100644 --- a/graphics/composer/aidl/vts/VtsComposerClient.cpp +++ b/graphics/composer/aidl/vts/VtsComposerClient.cpp @@ -58,7 +58,7 @@ bool VtsComposerClient::tearDown() { return verifyComposerCallbackParams() && destroyAllLayers(); } -std::pair VtsComposerClient::getInterfaceVersion() { +std::pair VtsComposerClient::getInterfaceVersion() const { int32_t version = 1; auto status = mComposerClient->getInterfaceVersion(&version); return {std::move(status), version}; @@ -295,7 +295,24 @@ std::pair VtsComposerClient::getDisplayCon std::pair> VtsComposerClient::getDisplayConfigs( int64_t display) { std::vector outConfigs; - return {mComposerClient->getDisplayConfigs(display, &outConfigs), outConfigs}; + if (!getDisplayConfigurationSupported()) { + return {mComposerClient->getDisplayConfigs(display, &outConfigs), outConfigs}; + } + + auto [status, configs] = getDisplayConfigurations(display); + if (!status.isOk()) { + return {std::move(status), outConfigs}; + } + for (const auto& config : configs) { + outConfigs.emplace_back(config.configId); + } + return {std::move(status), outConfigs}; +} + +std::pair> +VtsComposerClient::getDisplayConfigurations(int64_t display) { + std::vector outConfigs; + return {mComposerClient->getDisplayConfigurations(display, &outConfigs), outConfigs}; } std::pair VtsComposerClient::getDisplayVsyncPeriod(int64_t display) { @@ -439,31 +456,41 @@ std::pair> VtsComposerClient::getDisplays vtsDisplays.reserve(displays.size()); for (int64_t display : displays) { auto vtsDisplay = VtsDisplay{display}; - auto configs = getDisplayConfigs(display); - if (!configs.first.isOk()) { - ALOGE("Unable to get the displays for test, failed to get the configs " - "for display %" PRId64, - display); - return {std::move(configs.first), vtsDisplays}; - } - for (int config : configs.second) { - auto status = addDisplayConfig(&vtsDisplay, config); + if (getDisplayConfigurationSupported()) { + auto [status, configs] = getDisplayConfigurations(display); if (!status.isOk()) { - ALOGE("Unable to get the displays for test, failed to add config " + ALOGE("Unable to get the displays for test, failed to get the DisplayConfigs " "for display %" PRId64, display); return {std::move(status), vtsDisplays}; } + addDisplayConfigs(&vtsDisplay, configs); + } else { + auto [status, configs] = getDisplayConfigs(display); + if (!status.isOk()) { + ALOGE("Unable to get the displays for test, failed to get the configs " + "for display %" PRId64, + display); + return {std::move(status), vtsDisplays}; + } + for (int config : configs) { + status = addDisplayConfigLegacy(&vtsDisplay, config); + if (!status.isOk()) { + ALOGE("Unable to get the displays for test, failed to add config " + "for display %" PRId64, + display); + return {std::move(status), vtsDisplays}; + } + } } - - auto config = getActiveConfig(display); - if (!config.first.isOk()) { + auto activeConfig = getActiveConfig(display); + if (!activeConfig.first.isOk()) { ALOGE("Unable to get the displays for test, failed to get active config " - "for display %" PRId64, display); - return {std::move(config.first), vtsDisplays}; + "for display %" PRId64, + display); + return {std::move(activeConfig.first), vtsDisplays}; } - - auto status = updateDisplayProperties(&vtsDisplay, config.second); + auto status = updateDisplayProperties(&vtsDisplay, activeConfig.second); if (!status.isOk()) { ALOGE("Unable to get the displays for test, " "failed to update the properties " @@ -480,39 +507,53 @@ std::pair> VtsComposerClient::getDisplays } } -ScopedAStatus VtsComposerClient::addDisplayConfig(VtsDisplay* vtsDisplay, int32_t config) { - const auto width = - getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH); - const auto height = - getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::HEIGHT); +void VtsComposerClient::addDisplayConfigs(VtsDisplay* vtsDisplay, + const std::vector& configs) { + for (const auto& config : configs) { + vtsDisplay->addDisplayConfig(config.configId, {config.vsyncPeriod, config.configGroup}); + } +} + +ScopedAStatus VtsComposerClient::addDisplayConfigLegacy(VtsDisplay* vtsDisplay, int32_t config) { const auto vsyncPeriod = getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::VSYNC_PERIOD); const auto configGroup = getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::CONFIG_GROUP); - if (width.first.isOk() && height.first.isOk() && vsyncPeriod.first.isOk() && - configGroup.first.isOk()) { + if (vsyncPeriod.first.isOk() && configGroup.first.isOk()) { vtsDisplay->addDisplayConfig(config, {vsyncPeriod.second, configGroup.second}); return ScopedAStatus::ok(); } - LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk() - << ", height: " << height.first.isOk() << ", vsync: " << vsyncPeriod.first.isOk() + LOG(ERROR) << "Failed to update display property vsync: " << vsyncPeriod.first.isOk() << ", config: " << configGroup.first.isOk(); return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG); } ScopedAStatus VtsComposerClient::updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config) { - const auto width = - getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH); - const auto height = - getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::HEIGHT); - if (width.first.isOk() && height.first.isOk()) { - vtsDisplay->setDimensions(width.second, height.second); - return ScopedAStatus::ok(); - } + if (getDisplayConfigurationSupported()) { + auto [status, configs] = getDisplayConfigurations(vtsDisplay->getDisplayId()); + if (status.isOk()) { + for (const auto& displayConfig : configs) { + if (displayConfig.configId == config) { + vtsDisplay->setDimensions(displayConfig.width, displayConfig.height); + return ScopedAStatus::ok(); + } + } + } + LOG(ERROR) << "Failed to update display property with DisplayConfig"; + } else { + const auto width = + getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH); + const auto height = + getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::HEIGHT); + if (width.first.isOk() && height.first.isOk()) { + vtsDisplay->setDimensions(width.second, height.second); + return ScopedAStatus::ok(); + } - LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk() - << ", height: " << height.first.isOk(); + LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk() + << ", height: " << height.first.isOk(); + } return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG); } @@ -576,6 +617,13 @@ bool VtsComposerClient::verifyComposerCallbackParams() { return isValid; } +bool VtsComposerClient::getDisplayConfigurationSupported() const { + auto [status, interfaceVersion] = getInterfaceVersion(); + EXPECT_TRUE(status.isOk()); + // getDisplayConfigurations api is supported starting interface version 3 + return interfaceVersion >= 3; +} + bool VtsComposerClient::destroyAllLayers() { std::unordered_map physicalDisplays; while (!mDisplayResources.empty()) { diff --git a/graphics/composer/aidl/vts/VtsComposerClient.h b/graphics/composer/aidl/vts/VtsComposerClient.h index ea3318c2ce..1add23cadf 100644 --- a/graphics/composer/aidl/vts/VtsComposerClient.h +++ b/graphics/composer/aidl/vts/VtsComposerClient.h @@ -61,7 +61,7 @@ class VtsComposerClient { bool tearDown(); - std::pair getInterfaceVersion(); + std::pair getInterfaceVersion() const; std::pair createVirtualDisplay(int32_t width, int32_t height, PixelFormat pixelFormat, @@ -142,6 +142,9 @@ class VtsComposerClient { std::pair> getDisplayConfigs(int64_t display); + std::pair> getDisplayConfigurations( + int64_t display); + std::pair getDisplayVsyncPeriod(int64_t display); ScopedAStatus setAutoLowLatencyMode(int64_t display, bool isEnabled); @@ -190,7 +193,9 @@ class VtsComposerClient { std::vector takeListOfRefreshRateChangedDebugData(); private: - ScopedAStatus addDisplayConfig(VtsDisplay* vtsDisplay, int32_t config); + void addDisplayConfigs(VtsDisplay*, const std::vector&); + ScopedAStatus addDisplayConfigLegacy(VtsDisplay*, int32_t config); + bool getDisplayConfigurationSupported() const; ScopedAStatus updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config); ScopedAStatus addDisplayToDisplayResources(int64_t display, bool isVirtual); diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp index bbcd36ff7b..d559213129 100644 --- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp +++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp @@ -1208,6 +1208,110 @@ TEST_P(GraphicsComposerAidlV2Test, GetOverlaySupport) { } } +class GraphicsComposerAidlV3Test : public GraphicsComposerAidlTest { + protected: + void SetUp() override { + GraphicsComposerAidlTest::SetUp(); + if (getInterfaceVersion() <= 2) { + GTEST_SKIP() << "Device interface version is expected to be >= 3"; + } + } +}; + +TEST_P(GraphicsComposerAidlV3Test, GetDisplayConfigurations) { + for (const auto& display : mDisplays) { + const auto& [status, displayConfigurations] = + mComposerClient->getDisplayConfigurations(display.getDisplayId()); + EXPECT_TRUE(status.isOk()); + EXPECT_FALSE(displayConfigurations.empty()); + + for (const auto& displayConfig : displayConfigurations) { + EXPECT_NE(-1, displayConfig.width); + EXPECT_NE(-1, displayConfig.height); + EXPECT_NE(-1, displayConfig.vsyncPeriod); + EXPECT_NE(-1, displayConfig.configGroup); + if (displayConfig.dpi) { + EXPECT_NE(-1, displayConfig.dpi->x); + EXPECT_NE(-1, displayConfig.dpi->y); + } + } + } +} + +TEST_P(GraphicsComposerAidlV3Test, GetDisplayConfigsIsSubsetOfGetDisplayConfigurations) { + for (const auto& display : mDisplays) { + const auto& [status, displayConfigurations] = + mComposerClient->getDisplayConfigurations(display.getDisplayId()); + EXPECT_TRUE(status.isOk()); + + const auto& [legacyConfigStatus, legacyConfigs] = + mComposerClient->getDisplayConfigs(display.getDisplayId()); + EXPECT_TRUE(legacyConfigStatus.isOk()); + EXPECT_FALSE(legacyConfigs.empty()); + EXPECT_TRUE(legacyConfigs.size() <= displayConfigurations.size()); + + for (const auto legacyConfigId : legacyConfigs) { + const auto& legacyWidth = mComposerClient->getDisplayAttribute( + display.getDisplayId(), legacyConfigId, DisplayAttribute::WIDTH); + const auto& legacyHeight = mComposerClient->getDisplayAttribute( + display.getDisplayId(), legacyConfigId, DisplayAttribute::HEIGHT); + const auto& legacyVsyncPeriod = mComposerClient->getDisplayAttribute( + display.getDisplayId(), legacyConfigId, DisplayAttribute::VSYNC_PERIOD); + const auto& legacyConfigGroup = mComposerClient->getDisplayAttribute( + display.getDisplayId(), legacyConfigId, DisplayAttribute::CONFIG_GROUP); + const auto& legacyDpiX = mComposerClient->getDisplayAttribute( + display.getDisplayId(), legacyConfigId, DisplayAttribute::DPI_X); + const auto& legacyDpiY = mComposerClient->getDisplayAttribute( + display.getDisplayId(), legacyConfigId, DisplayAttribute::DPI_Y); + + EXPECT_TRUE(legacyWidth.first.isOk() && legacyHeight.first.isOk() && + legacyVsyncPeriod.first.isOk() && legacyConfigGroup.first.isOk()); + + EXPECT_TRUE(std::any_of( + displayConfigurations.begin(), displayConfigurations.end(), + [&](const auto& displayConfiguration) { + const bool requiredAttributesPredicate = + displayConfiguration.configId == legacyConfigId && + displayConfiguration.width == legacyWidth.second && + displayConfiguration.height == legacyHeight.second && + displayConfiguration.vsyncPeriod == legacyVsyncPeriod.second && + displayConfiguration.configGroup == legacyConfigGroup.second; + + if (!requiredAttributesPredicate) { + // Required attributes did not match + return false; + } + + // Check optional attributes + const auto& [legacyDpiXStatus, legacyDpiXValue] = legacyDpiX; + const auto& [legacyDpiYStatus, legacyDpiYValue] = legacyDpiY; + if (displayConfiguration.dpi) { + if (!legacyDpiXStatus.isOk() || !legacyDpiYStatus.isOk()) { + // getDisplayAttribute failed for optional attributes + return false; + } + + // DPI values in DisplayConfigurations are not scaled (* 1000.f) + // the way they are in the legacy DisplayConfigs. + constexpr float kEpsilon = 0.001f; + return std::abs(displayConfiguration.dpi->x - + legacyDpiXValue / 1000.f) < kEpsilon && + std::abs(displayConfiguration.dpi->y - + legacyDpiYValue / 1000.f) < kEpsilon; + } else { + return !legacyDpiXStatus.isOk() && !legacyDpiYStatus.isOk() && + EX_SERVICE_SPECIFIC == legacyDpiXStatus.getExceptionCode() && + EX_SERVICE_SPECIFIC == legacyDpiYStatus.getExceptionCode() && + IComposerClient::EX_UNSUPPORTED == + legacyDpiXStatus.getServiceSpecificError() && + IComposerClient::EX_UNSUPPORTED == + legacyDpiYStatus.getServiceSpecificError(); + } + })); + } + } +} + // Tests for Command. class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest { protected: @@ -2641,6 +2745,11 @@ INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsComposerAidlV2Test, testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)), ::android::PrintInstanceNameToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlV3Test); +INSTANTIATE_TEST_SUITE_P( + PerInstance, GraphicsComposerAidlV3Test, + testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)), + ::android::PrintInstanceNameToString); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV2Test); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsComposerAidlCommandV2Test,