Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02fe4772 authored by ramindani's avatar ramindani
Browse files

[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
parent e50ed5d4
Loading
Loading
Loading
Loading
+86 −38
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ bool VtsComposerClient::tearDown() {
    return verifyComposerCallbackParams() && destroyAllLayers();
}

std::pair<ScopedAStatus, int32_t> VtsComposerClient::getInterfaceVersion() {
std::pair<ScopedAStatus, int32_t> VtsComposerClient::getInterfaceVersion() const {
    int32_t version = 1;
    auto status = mComposerClient->getInterfaceVersion(&version);
    return {std::move(status), version};
@@ -295,9 +295,26 @@ std::pair<ScopedAStatus, DisplayConnectionType> VtsComposerClient::getDisplayCon
std::pair<ScopedAStatus, std::vector<int32_t>> VtsComposerClient::getDisplayConfigs(
        int64_t display) {
    std::vector<int32_t> 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<ScopedAStatus, std::vector<DisplayConfiguration>>
VtsComposerClient::getDisplayConfigurations(int64_t display) {
    std::vector<DisplayConfiguration> outConfigs;
    return {mComposerClient->getDisplayConfigurations(display, &outConfigs), outConfigs};
}

std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayVsyncPeriod(int64_t display) {
    int32_t outVsyncPeriodNanos;
    return {mComposerClient->getDisplayVsyncPeriod(display, &outVsyncPeriodNanos),
@@ -439,15 +456,25 @@ std::pair<ScopedAStatus, std::vector<VtsDisplay>> VtsComposerClient::getDisplays
        vtsDisplays.reserve(displays.size());
        for (int64_t display : displays) {
            auto vtsDisplay = VtsDisplay{display};
            auto configs = getDisplayConfigs(display);
            if (!configs.first.isOk()) {
            if (getDisplayConfigurationSupported()) {
                auto [status, configs] = getDisplayConfigurations(display);
                if (!status.isOk()) {
                    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(configs.first), vtsDisplays};
                    return {std::move(status), vtsDisplays};
                }
            for (int config : configs.second) {
                auto status = addDisplayConfig(&vtsDisplay, config);
                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,
@@ -455,15 +482,15 @@ std::pair<ScopedAStatus, std::vector<VtsDisplay>> VtsComposerClient::getDisplays
                        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,28 +507,41 @@ std::pair<ScopedAStatus, std::vector<VtsDisplay>> 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<DisplayConfiguration>& 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) {
    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 =
@@ -513,6 +553,7 @@ ScopedAStatus VtsComposerClient::updateDisplayProperties(VtsDisplay* vtsDisplay,

        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<int64_t, DisplayResource> physicalDisplays;
    while (!mDisplayResources.empty()) {
+7 −2
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ class VtsComposerClient {

    bool tearDown();

    std::pair<ScopedAStatus, int32_t> getInterfaceVersion();
    std::pair<ScopedAStatus, int32_t> getInterfaceVersion() const;

    std::pair<ScopedAStatus, VirtualDisplay> createVirtualDisplay(int32_t width, int32_t height,
                                                                  PixelFormat pixelFormat,
@@ -142,6 +142,9 @@ class VtsComposerClient {

    std::pair<ScopedAStatus, std::vector<int32_t>> getDisplayConfigs(int64_t display);

    std::pair<ScopedAStatus, std::vector<DisplayConfiguration>> getDisplayConfigurations(
            int64_t display);

    std::pair<ScopedAStatus, int32_t> getDisplayVsyncPeriod(int64_t display);

    ScopedAStatus setAutoLowLatencyMode(int64_t display, bool isEnabled);
@@ -190,7 +193,9 @@ class VtsComposerClient {
    std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData();

  private:
    ScopedAStatus addDisplayConfig(VtsDisplay* vtsDisplay, int32_t config);
    void addDisplayConfigs(VtsDisplay*, const std::vector<DisplayConfiguration>&);
    ScopedAStatus addDisplayConfigLegacy(VtsDisplay*, int32_t config);
    bool getDisplayConfigurationSupported() const;
    ScopedAStatus updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config);

    ScopedAStatus addDisplayToDisplayResources(int64_t display, bool isVirtual);
+109 −0
Original line number Diff line number Diff line
@@ -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,