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

Commit 3a3f807f authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 9685341 from 9a7999d1 to udc-release

Change-Id: Ida25d75322c4e55b05dc15ede9646bae2f915bcb
parents 6ebf8068 9a7999d1
Loading
Loading
Loading
Loading
+30 −3
Original line number Diff line number Diff line
@@ -29,6 +29,11 @@ void GraphicsComposerCallback::setVsyncAllowed(bool allowed) {
    mVsyncAllowed = allowed;
}

void GraphicsComposerCallback::setRefreshRateChangedDebugDataEnabledCallbackAllowed(bool allowed) {
    std::scoped_lock lock(mMutex);
    mRefreshRateChangedDebugDataEnabledCallbackAllowed = allowed;
}

std::vector<int64_t> GraphicsComposerCallback::getDisplays() const {
    std::scoped_lock lock(mMutex);
    return mDisplays;
@@ -79,6 +84,21 @@ GraphicsComposerCallback::takeLastVsyncPeriodChangeTimeline() {
    return ret;
}

std::vector<RefreshRateChangedDebugData>
GraphicsComposerCallback::takeListOfRefreshRateChangedDebugData() {
    std::scoped_lock lock(mMutex);

    std::vector<RefreshRateChangedDebugData> ret;
    ret.swap(mRefreshRateChangedDebugData);

    return ret;
}

int32_t GraphicsComposerCallback::getInvalidRefreshRateDebugEnabledCallbackCount() const {
    std::scoped_lock lock(mMutex);
    return mInvalidRefreshRateDebugEnabledCallbackCount;
}

::ndk::ScopedAStatus GraphicsComposerCallback::onHotplug(int64_t in_display, bool in_connected) {
    std::scoped_lock lock(mMutex);

@@ -125,9 +145,16 @@ GraphicsComposerCallback::takeLastVsyncPeriodChangeTimeline() {
}

::ndk::ScopedAStatus GraphicsComposerCallback::onRefreshRateChangedDebug(
        const RefreshRateChangedDebugData&) {
    // TODO(b/202734676) Add implementation for Vts tests
    return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
        const RefreshRateChangedDebugData& data) {
    std::scoped_lock lock(mMutex);

    const auto it = std::find(mDisplays.begin(), mDisplays.end(), data.display);
    if (mRefreshRateChangedDebugDataEnabledCallbackAllowed && it != mDisplays.end()) {
        mRefreshRateChangedDebugData.push_back(data);
    } else {
        mInvalidRefreshRateDebugEnabledCallbackCount++;
    }
    return ::ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus GraphicsComposerCallback::onVsyncPeriodTimingChanged(
+11 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ class GraphicsComposerCallback : public BnComposerCallback {
  public:
    void setVsyncAllowed(bool allowed);

    void setRefreshRateChangedDebugDataEnabledCallbackAllowed(bool allowed);

    std::vector<int64_t> getDisplays() const;

    int32_t getInvalidHotplugCount() const;
@@ -44,6 +46,10 @@ class GraphicsComposerCallback : public BnComposerCallback {

    std::optional<VsyncPeriodChangeTimeline> takeLastVsyncPeriodChangeTimeline();

    std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData();

    int32_t getInvalidRefreshRateDebugEnabledCallbackCount() const;

  private:
    virtual ::ndk::ScopedAStatus onHotplug(int64_t in_display, bool in_connected) override;
    virtual ::ndk::ScopedAStatus onRefresh(int64_t in_display) override;
@@ -63,9 +69,13 @@ class GraphicsComposerCallback : public BnComposerCallback {
    std::vector<int64_t> mDisplays GUARDED_BY(mMutex);
    // true only when vsync is enabled
    bool mVsyncAllowed GUARDED_BY(mMutex) = true;
    // true only when RefreshRateChangedCallbackDebugEnabled is set to true.
    bool mRefreshRateChangedDebugDataEnabledCallbackAllowed GUARDED_BY(mMutex) = false;

    std::optional<VsyncPeriodChangeTimeline> mTimeline GUARDED_BY(mMutex);

    std::vector<RefreshRateChangedDebugData> mRefreshRateChangedDebugData GUARDED_BY(mMutex);

    int32_t mVsyncIdleCount GUARDED_BY(mMutex) = 0;
    int64_t mVsyncIdleTime GUARDED_BY(mMutex) = 0;

@@ -75,6 +85,7 @@ class GraphicsComposerCallback : public BnComposerCallback {
    int32_t mInvalidVsyncCount GUARDED_BY(mMutex) = 0;
    int32_t mInvalidVsyncPeriodChangeCount GUARDED_BY(mMutex) = 0;
    int32_t mInvalidSeamlessPossibleCount GUARDED_BY(mMutex) = 0;
    int32_t mInvalidRefreshRateDebugEnabledCallbackCount GUARDED_BY(mMutex) = 0;
};

}  // namespace aidl::android::hardware::graphics::composer3::vts
+31 −4
Original line number Diff line number Diff line
@@ -119,6 +119,24 @@ ScopedAStatus VtsComposerClient::setActiveConfig(VtsDisplay* vtsDisplay, int32_t
    return updateDisplayProperties(vtsDisplay, config);
}

ScopedAStatus VtsComposerClient::setPeakRefreshRateConfig(VtsDisplay* vtsDisplay) {
    const auto displayId = vtsDisplay->getDisplayId();
    auto [activeStatus, activeConfig] = getActiveConfig(displayId);
    EXPECT_TRUE(activeStatus.isOk());
    auto peakDisplayConfig = vtsDisplay->getDisplayConfig(activeConfig);
    auto peakConfig = activeConfig;

    const auto displayConfigs = vtsDisplay->getDisplayConfigs();
    for (const auto [config, displayConfig] : displayConfigs) {
        if (displayConfig.configGroup == peakDisplayConfig.configGroup &&
            displayConfig.vsyncPeriod < peakDisplayConfig.vsyncPeriod) {
            peakDisplayConfig = displayConfig;
            peakConfig = config;
        }
    }
    return setActiveConfig(vtsDisplay, peakConfig);
}

std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayAttribute(
        int64_t display, int32_t config, DisplayAttribute displayAttribute) {
    int32_t outDisplayAttribute;
@@ -375,10 +393,15 @@ int64_t VtsComposerClient::getVsyncIdleTime() {
    return mComposerCallback->getVsyncIdleTime();
}

ndk::ScopedAStatus VtsComposerClient::setRefreshRateChangedCallbackDebugEnabled(
        int64_t /* display */, bool /* enabled */) {
    // TODO(b/202734676) Add implementation for VTS tests
    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
ndk::ScopedAStatus VtsComposerClient::setRefreshRateChangedCallbackDebugEnabled(int64_t display,
                                                                                bool enabled) {
    mComposerCallback->setRefreshRateChangedDebugDataEnabledCallbackAllowed(enabled);
    return mComposerClient->setRefreshRateChangedCallbackDebugEnabled(display, enabled);
}

std::vector<RefreshRateChangedDebugData>
VtsComposerClient::takeListOfRefreshRateChangedDebugData() {
    return mComposerCallback->takeListOfRefreshRateChangedDebugData();
}

int64_t VtsComposerClient::getInvalidDisplayId() {
@@ -545,6 +568,10 @@ bool VtsComposerClient::verifyComposerCallbackParams() {
            ALOGE("Invalid seamless possible count");
            isValid = false;
        }
        if (mComposerCallback->getInvalidRefreshRateDebugEnabledCallbackCount() != 0) {
            ALOGE("Invalid refresh rate debug enabled callback count");
            isValid = false;
        }
    }
    return isValid;
}
+11 −6
Original line number Diff line number Diff line
@@ -77,6 +77,8 @@ class VtsComposerClient {

    ScopedAStatus setActiveConfig(VtsDisplay* vtsDisplay, int32_t config);

    ScopedAStatus setPeakRefreshRateConfig(VtsDisplay* vtsDisplay);

    std::pair<ScopedAStatus, int32_t> getDisplayAttribute(int64_t display, int32_t config,
                                                          DisplayAttribute displayAttribute);

@@ -183,6 +185,10 @@ class VtsComposerClient {

    std::pair<ScopedAStatus, OverlayProperties> getOverlaySupport();

    ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(int64_t display, bool enabled);

    std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData();

  private:
    ScopedAStatus addDisplayConfig(VtsDisplay* vtsDisplay, int32_t config);
    ScopedAStatus updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config);
@@ -197,9 +203,6 @@ class VtsComposerClient {

    bool verifyComposerCallbackParams();

    ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(int64_t /* display */,
                                                                 bool /* enabled */);

    // Keep track of displays and layers. When a test fails/ends,
    // the VtsComposerClient::tearDown should be called from the
    // test tearDown to clean up the resources for the test.
@@ -245,15 +248,17 @@ class VtsDisplay {
    };

    void addDisplayConfig(int32_t config, DisplayConfig displayConfig) {
        displayConfigs.insert({config, displayConfig});
        mDisplayConfigs.insert({config, displayConfig});
    }

    DisplayConfig getDisplayConfig(int32_t config) { return displayConfigs.find(config)->second; }
    DisplayConfig getDisplayConfig(int32_t config) { return mDisplayConfigs.find(config)->second; }

    std::unordered_map<int32_t, DisplayConfig> getDisplayConfigs() { return mDisplayConfigs; }

  private:
    int64_t mDisplayId;
    int32_t mDisplayWidth;
    int32_t mDisplayHeight;
    std::unordered_map<int32_t, DisplayConfig> displayConfigs;
    std::unordered_map<int32_t, DisplayConfig> mDisplayConfigs;
};
}  // namespace aidl::android::hardware::graphics::composer3::vts
+196 −2
Original line number Diff line number Diff line
@@ -1217,6 +1217,14 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
        }
    }

    bool checkIfCallbackRefreshRateChangedDebugEnabledReceived(
            std::function<bool(RefreshRateChangedDebugData)> filter) {
        const auto list = mComposerClient->takeListOfRefreshRateChangedDebugData();
        return std::any_of(list.begin(), list.end(), [&](auto refreshRateChangedDebugData) {
            return filter(refreshRateChangedDebugData);
        });
    }

    sp<GraphicBuffer> allocate(::android::PixelFormat pixelFormat) {
        return sp<GraphicBuffer>::make(
                static_cast<uint32_t>(getPrimaryDisplay().getDisplayWidth()),
@@ -1316,7 +1324,7 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
        return vsyncPeriod;
    }

    int64_t createOnScreenLayer() {
    int64_t createOnScreenLayer(Composition composition = Composition::DEVICE) {
        const auto& [status, layer] =
                mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
        EXPECT_TRUE(status.isOk());
@@ -1324,12 +1332,25 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
                          getPrimaryDisplay().getDisplayHeight()};
        FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
                       (float)getPrimaryDisplay().getDisplayHeight()};
        configureLayer(getPrimaryDisplay(), layer, Composition::DEVICE, displayFrame, cropRect);
        configureLayer(getPrimaryDisplay(), layer, composition, displayFrame, cropRect);
        auto& writer = getWriter(getPrimaryDisplayId());
        writer.setLayerDataspace(getPrimaryDisplayId(), layer, common::Dataspace::UNKNOWN);
        return layer;
    }

    void sendBufferUpdate(int64_t layer) {
        const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
        ASSERT_NE(nullptr, buffer->handle);

        auto& writer = getWriter(getPrimaryDisplayId());
        writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
                              /*acquireFence*/ -1);

        const sp<::android::Fence> presentFence =
                presentAndGetFence(ComposerClientWriter::kNoTimestamp);
        presentFence->waitForever(LOG_TAG);
    }

    bool hasDisplayCapability(int64_t display, DisplayCapability cap) {
        const auto& [status, capabilities] = mComposerClient->getDisplayCapabilities(display);
        EXPECT_TRUE(status.isOk());
@@ -2268,6 +2289,179 @@ TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_Timeout_2) {
    EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
}

TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebug_Unsupported) {
    if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
        auto status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(
                getPrimaryDisplayId(), /*enabled*/ true);
        EXPECT_FALSE(status.isOk());
        EXPECT_NO_FATAL_FAILURE(
                assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));

        status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(getPrimaryDisplayId(),
                                                                            /*enabled*/ false);
        EXPECT_FALSE(status.isOk());
        EXPECT_NO_FATAL_FAILURE(
                assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
    }
}

TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebug_Enabled) {
    if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
        GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
        return;
    }

    const auto displayId = getPrimaryDisplayId();
    EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
    // Enable the callback
    ASSERT_TRUE(mComposerClient
                        ->setRefreshRateChangedCallbackDebugEnabled(displayId,
                                                                    /*enabled*/ true)
                        .isOk());
    std::this_thread::sleep_for(100ms);

    const bool isCallbackReceived = checkIfCallbackRefreshRateChangedDebugEnabledReceived(
            [&](auto refreshRateChangedDebugData) {
                return displayId == refreshRateChangedDebugData.display;
            });

    // Check that we immediately got a callback
    EXPECT_TRUE(isCallbackReceived);

    ASSERT_TRUE(mComposerClient
                        ->setRefreshRateChangedCallbackDebugEnabled(displayId,
                                                                    /*enabled*/ false)
                        .isOk());
}

TEST_P(GraphicsComposerAidlCommandTest,
       SetRefreshRateChangedCallbackDebugEnabled_noCallbackWhenIdle) {
    if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
        GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
        return;
    }

    auto display = getEditablePrimaryDisplay();
    const auto displayId = display.getDisplayId();

    if (!hasDisplayCapability(displayId, DisplayCapability::DISPLAY_IDLE_TIMER)) {
        GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
        return;
    }

    EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
    EXPECT_TRUE(mComposerClient->setPeakRefreshRateConfig(&display).isOk());

    ASSERT_TRUE(mComposerClient->setIdleTimerEnabled(displayId, /*timeoutMs*/ 500).isOk());
    // Enable the callback
    ASSERT_TRUE(mComposerClient
                        ->setRefreshRateChangedCallbackDebugEnabled(displayId,
                                                                    /*enabled*/ true)
                        .isOk());

    const bool isCallbackReceived = checkIfCallbackRefreshRateChangedDebugEnabledReceived(
            [&](auto refreshRateChangedDebugData) {
                return displayId == refreshRateChangedDebugData.display;
            });

    int retryCount = 3;
    do {
        // Wait for 1s so that we enter the idle state
        std::this_thread::sleep_for(1s);
        if (!isCallbackReceived) {
            // DID NOT receive a callback, we are in the idle state.
            break;
        }
    } while (--retryCount > 0);

    if (retryCount == 0) {
        GTEST_SUCCEED() << "Unable to enter the idle mode";
        return;
    }

    // Send the REFRESH_RATE_INDICATOR update
    ASSERT_NO_FATAL_FAILURE(
            sendBufferUpdate(createOnScreenLayer(Composition::REFRESH_RATE_INDICATOR)));
    std::this_thread::sleep_for(1s);
    EXPECT_FALSE(isCallbackReceived)
            << "A callback should not be received for REFRESH_RATE_INDICATOR";

    EXPECT_TRUE(mComposerClient
                        ->setRefreshRateChangedCallbackDebugEnabled(displayId,
                                                                    /*enabled*/ false)
                        .isOk());
}

TEST_P(GraphicsComposerAidlCommandTest,
       SetRefreshRateChangedCallbackDebugEnabled_SetActiveConfigWithConstraints) {
    if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
        GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
        return;
    }

    VsyncPeriodChangeConstraints constraints;
    constraints.seamlessRequired = false;
    constraints.desiredTimeNanos = systemTime();

    for (VtsDisplay& display : mDisplays) {
        const auto displayId = display.getDisplayId();
        EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());

        // Enable the callback
        ASSERT_TRUE(mComposerClient
                            ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ true)
                            .isOk());

        forEachTwoConfigs(displayId, [&](int32_t config1, int32_t config2) {
            const int32_t vsyncPeriod1 = display.getDisplayConfig(config1).vsyncPeriod;
            const int32_t vsyncPeriod2 = display.getDisplayConfig(config2).vsyncPeriod;

            if (vsyncPeriod1 == vsyncPeriod2) {
                return;  // continue
            }

            EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
            sendRefreshFrame(display, nullptr);

            const auto& [status, timeline] =
                    mComposerClient->setActiveConfigWithConstraints(&display, config2, constraints);
            EXPECT_TRUE(status.isOk());

            if (timeline.refreshRequired) {
                sendRefreshFrame(display, &timeline);
            }

            const auto isCallbackReceived = checkIfCallbackRefreshRateChangedDebugEnabledReceived(
                    [&](auto refreshRateChangedDebugData) {
                        constexpr int kVsyncThreshold = 1000;
                        return displayId == refreshRateChangedDebugData.display &&
                               std::abs(vsyncPeriod2 -
                                        refreshRateChangedDebugData.vsyncPeriodNanos) <=
                                       kVsyncThreshold;
                    });

            int retryCount = 3;
            do {
                std::this_thread::sleep_for(100ms);
                if (isCallbackReceived) {
                    GTEST_SUCCEED() << "Received a callback successfully";
                    break;
                }
            } while (--retryCount > 0);

            if (retryCount == 0) {
                GTEST_FAIL() << "failed to get a callback for the display " << displayId
                             << " with config " << config2;
            }
        });

        EXPECT_TRUE(
                mComposerClient
                        ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ false)
                        .isOk());
    }
}

/*
 * Test that no two display configs are exactly the same.
 */
Loading