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

Commit 2fa85014 authored by Matt Buckley's avatar Matt Buckley
Browse files

Refactor adpf cpu hints to use TimePoint and Duration

Replace nsecs_t in adpf cpu hint sessions in PowerAdvisor with new
TimePoints and Durations

Additionally, added TimePoint::now() to make getting current time
cleaner

Bug: b/244358432
Test: atest libsurfaceflinger_unittest
Change-Id: I8b4d6f3de8204aa34cd9d8687febfde580deea92
parent 44e612e8
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -243,7 +243,7 @@ bool Display::chooseCompositionStrategy(
        return false;
    }

    const nsecs_t startTime = systemTime();
    const TimePoint startTime = TimePoint::now();

    // Get any composition changes requested by the HWC device, and apply them.
    std::optional<android::HWComposer::DeviceRequestedChanges> changes;
@@ -261,7 +261,7 @@ bool Display::chooseCompositionStrategy(
    }

    if (isPowerHintSessionEnabled()) {
        mPowerAdvisor->setHwcValidateTiming(mId, startTime, systemTime());
        mPowerAdvisor->setHwcValidateTiming(mId, startTime, TimePoint::now());
        mPowerAdvisor->setRequiresClientComposition(mId, requiresClientComposition);
    }

@@ -365,7 +365,7 @@ compositionengine::Output::FrameFences Display::presentAndGetFrameFences() {

    auto& hwc = getCompositionEngine().getHwComposer();

    const nsecs_t startTime = systemTime();
    const TimePoint startTime = TimePoint::now();

    if (isPowerHintSessionEnabled()) {
        if (!getCompositionEngine().getHwComposer().getComposer()->isSupported(
@@ -379,7 +379,7 @@ compositionengine::Output::FrameFences Display::presentAndGetFrameFences() {
                                   getState().previousPresentFence);

    if (isPowerHintSessionEnabled()) {
        mPowerAdvisor->setHwcPresentTiming(mId, startTime, systemTime());
        mPowerAdvisor->setHwcPresentTiming(mId, startTime, TimePoint::now());
    }

    fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt);
+10 −11
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ public:
    MOCK_METHOD(bool, usePowerHintSession, (), (override));
    MOCK_METHOD(bool, supportsPowerHintSession, (), (override));
    MOCK_METHOD(bool, isPowerHintSessionRunning, (), (override));
    MOCK_METHOD(void, setTargetWorkDuration, (int64_t targetDuration), (override));
    MOCK_METHOD(void, setTargetWorkDuration, (Duration targetDuration), (override));
    MOCK_METHOD(void, sendActualWorkDuration, (), (override));
    MOCK_METHOD(void, sendPredictedWorkDuration, (), (override));
    MOCK_METHOD(void, enablePowerHint, (bool enabled), (override));
@@ -46,25 +46,24 @@ public:
    MOCK_METHOD(void, setGpuFenceTime,
                (DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime), (override));
    MOCK_METHOD(void, setHwcValidateTiming,
                (DisplayId displayId, nsecs_t valiateStartTime, nsecs_t validateEndTime),
                (DisplayId displayId, TimePoint validateStartTime, TimePoint validateEndTime),
                (override));
    MOCK_METHOD(void, setHwcPresentTiming,
                (DisplayId displayId, nsecs_t presentStartTime, nsecs_t presentEndTime),
                (DisplayId displayId, TimePoint presentStartTime, TimePoint presentEndTime),
                (override));
    MOCK_METHOD(void, setSkippedValidate, (DisplayId displayId, bool skipped), (override));
    MOCK_METHOD(void, setRequiresClientComposition,
                (DisplayId displayId, bool requiresClientComposition), (override));
    MOCK_METHOD(void, setExpectedPresentTime, (nsecs_t expectedPresentTime), (override));
    MOCK_METHOD(void, setSfPresentTiming, (nsecs_t presentFenceTime, nsecs_t presentEndTime),
    MOCK_METHOD(void, setExpectedPresentTime, (TimePoint expectedPresentTime), (override));
    MOCK_METHOD(void, setSfPresentTiming, (TimePoint presentFenceTime, TimePoint presentEndTime),
                (override));
    MOCK_METHOD(void, setHwcPresentDelayedTime,
                (DisplayId displayId,
                 std::chrono::steady_clock::time_point earliestFrameStartTime));
    MOCK_METHOD(void, setFrameDelay, (nsecs_t frameDelayDuration), (override));
    MOCK_METHOD(void, setCommitStart, (nsecs_t commitStartTime), (override));
    MOCK_METHOD(void, setCompositeEnd, (nsecs_t compositeEndtime), (override));
                (DisplayId displayId, TimePoint earliestFrameStartTime));
    MOCK_METHOD(void, setFrameDelay, (Duration frameDelayDuration), (override));
    MOCK_METHOD(void, setCommitStart, (TimePoint commitStartTime), (override));
    MOCK_METHOD(void, setCompositeEnd, (TimePoint compositeEndTime), (override));
    MOCK_METHOD(void, setDisplays, (std::vector<DisplayId> & displayIds), (override));
    MOCK_METHOD(void, setTotalFrameTargetWorkDuration, (int64_t targetDuration), (override));
    MOCK_METHOD(void, setTotalFrameTargetWorkDuration, (Duration targetDuration), (override));
};

} // namespace mock
+88 −88
Original line number Diff line number Diff line
@@ -59,8 +59,6 @@ using android::hardware::power::IPowerHintSession;
using android::hardware::power::Mode;
using android::hardware::power::WorkDuration;

using scheduler::OneShotTimer;

PowerAdvisor::~PowerAdvisor() = default;

namespace {
@@ -196,7 +194,7 @@ bool PowerAdvisor::isPowerHintSessionRunning() {
    return mPowerHintSessionRunning;
}

void PowerAdvisor::setTargetWorkDuration(int64_t targetDuration) {
void PowerAdvisor::setTargetWorkDuration(Duration targetDuration) {
    if (!usePowerHintSession()) {
        ALOGV("Power hint session target duration cannot be set, skipping");
        return;
@@ -215,13 +213,13 @@ void PowerAdvisor::sendActualWorkDuration() {
        ALOGV("Actual work duration power hint cannot be sent, skipping");
        return;
    }
    const std::optional<nsecs_t> actualDuration = estimateWorkDuration(false);
    const std::optional<Duration> actualDuration = estimateWorkDuration(false);
    if (actualDuration.has_value()) {
        std::lock_guard lock(mPowerHalMutex);
        HalWrapper* const halWrapper = getPowerHal();
        if (halWrapper != nullptr) {
            halWrapper->sendActualWorkDuration(*actualDuration + kTargetSafetyMargin.count(),
                                               systemTime());
            halWrapper->sendActualWorkDuration(*actualDuration + kTargetSafetyMargin,
                                               TimePoint::now());
        }
    }
}
@@ -232,14 +230,14 @@ void PowerAdvisor::sendPredictedWorkDuration() {
        return;
    }

    const std::optional<nsecs_t> predictedDuration = estimateWorkDuration(true);
    const std::optional<Duration> predictedDuration = estimateWorkDuration(true);

    if (predictedDuration.has_value()) {
        std::lock_guard lock(mPowerHalMutex);
        HalWrapper* const halWrapper = getPowerHal();
        if (halWrapper != nullptr) {
            halWrapper->sendActualWorkDuration(*predictedDuration + kTargetSafetyMargin.count(),
                                               systemTime());
            halWrapper->sendActualWorkDuration(*predictedDuration + kTargetSafetyMargin,
                                               TimePoint::now());
        }
    }
}
@@ -281,22 +279,22 @@ void PowerAdvisor::setGpuFenceTime(DisplayId displayId, std::unique_ptr<FenceTim
                }
            }
            displayData.lastValidGpuStartTime = displayData.gpuStartTime;
            displayData.lastValidGpuEndTime = signalTime;
            displayData.lastValidGpuEndTime = TimePoint::fromNs(signalTime);
        }
    }
    displayData.gpuEndFenceTime = std::move(fenceTime);
    displayData.gpuStartTime = systemTime();
    displayData.gpuStartTime = TimePoint::now();
}

void PowerAdvisor::setHwcValidateTiming(DisplayId displayId, nsecs_t validateStartTime,
                                        nsecs_t validateEndTime) {
void PowerAdvisor::setHwcValidateTiming(DisplayId displayId, TimePoint validateStartTime,
                                        TimePoint validateEndTime) {
    DisplayTimingData& displayData = mDisplayTimingData[displayId];
    displayData.hwcValidateStartTime = validateStartTime;
    displayData.hwcValidateEndTime = validateEndTime;
}

void PowerAdvisor::setHwcPresentTiming(DisplayId displayId, nsecs_t presentStartTime,
                                       nsecs_t presentEndTime) {
void PowerAdvisor::setHwcPresentTiming(DisplayId displayId, TimePoint presentStartTime,
                                       TimePoint presentEndTime) {
    DisplayTimingData& displayData = mDisplayTimingData[displayId];
    displayData.hwcPresentStartTime = presentStartTime;
    displayData.hwcPresentEndTime = presentEndTime;
@@ -311,43 +309,41 @@ void PowerAdvisor::setRequiresClientComposition(DisplayId displayId,
    mDisplayTimingData[displayId].usedClientComposition = requiresClientComposition;
}

void PowerAdvisor::setExpectedPresentTime(nsecs_t expectedPresentTime) {
void PowerAdvisor::setExpectedPresentTime(TimePoint expectedPresentTime) {
    mExpectedPresentTimes.append(expectedPresentTime);
}

void PowerAdvisor::setSfPresentTiming(nsecs_t presentFenceTime, nsecs_t presentEndTime) {
void PowerAdvisor::setSfPresentTiming(TimePoint presentFenceTime, TimePoint presentEndTime) {
    mLastSfPresentEndTime = presentEndTime;
    mLastPresentFenceTime = presentFenceTime;
}

void PowerAdvisor::setFrameDelay(nsecs_t frameDelayDuration) {
void PowerAdvisor::setFrameDelay(Duration frameDelayDuration) {
    mFrameDelayDuration = frameDelayDuration;
}

void PowerAdvisor::setHwcPresentDelayedTime(
        DisplayId displayId, std::chrono::steady_clock::time_point earliestFrameStartTime) {
    mDisplayTimingData[displayId].hwcPresentDelayedTime =
            (earliestFrameStartTime - std::chrono::steady_clock::now()).count() + systemTime();
void PowerAdvisor::setHwcPresentDelayedTime(DisplayId displayId, TimePoint earliestFrameStartTime) {
    mDisplayTimingData[displayId].hwcPresentDelayedTime = earliestFrameStartTime;
}

void PowerAdvisor::setCommitStart(nsecs_t commitStartTime) {
void PowerAdvisor::setCommitStart(TimePoint commitStartTime) {
    mCommitStartTimes.append(commitStartTime);
}

void PowerAdvisor::setCompositeEnd(nsecs_t compositeEnd) {
    mLastPostcompDuration = compositeEnd - mLastSfPresentEndTime;
void PowerAdvisor::setCompositeEnd(TimePoint compositeEndTime) {
    mLastPostcompDuration = compositeEndTime - mLastSfPresentEndTime;
}

void PowerAdvisor::setDisplays(std::vector<DisplayId>& displayIds) {
    mDisplayIds = displayIds;
}

void PowerAdvisor::setTotalFrameTargetWorkDuration(nsecs_t targetDuration) {
void PowerAdvisor::setTotalFrameTargetWorkDuration(Duration targetDuration) {
    mTotalFrameTargetDuration = targetDuration;
}

std::vector<DisplayId> PowerAdvisor::getOrderedDisplayIds(
        std::optional<nsecs_t> DisplayTimingData::*sortBy) {
        std::optional<TimePoint> DisplayTimingData::*sortBy) {
    std::vector<DisplayId> sortedDisplays;
    std::copy_if(mDisplayIds.begin(), mDisplayIds.end(), std::back_inserter(sortedDisplays),
                 [&](DisplayId id) {
@@ -360,33 +356,34 @@ std::vector<DisplayId> PowerAdvisor::getOrderedDisplayIds(
    return sortedDisplays;
}

std::optional<nsecs_t> PowerAdvisor::estimateWorkDuration(bool earlyHint) {
std::optional<Duration> PowerAdvisor::estimateWorkDuration(bool earlyHint) {
    if (earlyHint && (!mExpectedPresentTimes.isFull() || !mCommitStartTimes.isFull())) {
        return std::nullopt;
    }

    // Tracks when we finish presenting to hwc
    nsecs_t estimatedEndTime = mCommitStartTimes[0];
    TimePoint estimatedEndTime = mCommitStartTimes[0];

    // How long we spent this frame not doing anything, waiting for fences or vsync
    nsecs_t idleDuration = 0;
    Duration idleDuration = 0ns;

    // Most recent previous gpu end time in the current frame, probably from a prior display, used
    // as the start time for the next gpu operation if it ran over time since it probably blocked
    std::optional<nsecs_t> previousValidGpuEndTime;
    std::optional<TimePoint> previousValidGpuEndTime;

    // The currently estimated gpu end time for the frame,
    // used to accumulate gpu time as we iterate over the active displays
    std::optional<nsecs_t> estimatedGpuEndTime;
    std::optional<TimePoint> estimatedGpuEndTime;

    // If we're predicting at the start of the frame, we use last frame as our reference point
    // If we're predicting at the end of the frame, we use the current frame as a reference point
    nsecs_t referenceFrameStartTime = (earlyHint ? mCommitStartTimes[-1] : mCommitStartTimes[0]);
    TimePoint referenceFrameStartTime = (earlyHint ? mCommitStartTimes[-1] : mCommitStartTimes[0]);

    // When the prior frame should be presenting to the display
    // If we're predicting at the start of the frame, we use last frame's expected present time
    // If we're predicting at the end of the frame, the present fence time is already known
    nsecs_t lastFramePresentTime = (earlyHint ? mExpectedPresentTimes[-1] : mLastPresentFenceTime);
    TimePoint lastFramePresentTime =
            (earlyHint ? mExpectedPresentTimes[-1] : mLastPresentFenceTime);

    // The timing info for the previously calculated display, if there was one
    std::optional<DisplayTimeline> previousDisplayReferenceTiming;
@@ -427,10 +424,10 @@ std::optional<nsecs_t> PowerAdvisor::estimateWorkDuration(bool earlyHint) {
        // Track how long we spent waiting for the fence, can be excluded from the timing estimate
        idleDuration += estimatedTiming.probablyWaitsForPresentFence
                ? lastFramePresentTime - estimatedTiming.presentFenceWaitStartTime
                : 0;
                : 0ns;

        // Track how long we spent waiting to present, can be excluded from the timing estimate
        idleDuration += earlyHint ? 0 : referenceTiming.hwcPresentDelayDuration;
        idleDuration += earlyHint ? 0ns : referenceTiming.hwcPresentDelayDuration;

        // Estimate the reference frame's gpu timing
        auto gpuTiming = displayData.estimateGpuTiming(previousValidGpuEndTime);
@@ -438,15 +435,15 @@ std::optional<nsecs_t> PowerAdvisor::estimateWorkDuration(bool earlyHint) {
            previousValidGpuEndTime = gpuTiming->startTime + gpuTiming->duration;

            // Estimate the prediction frame's gpu end time from the reference frame
            estimatedGpuEndTime =
                    std::max(estimatedTiming.hwcPresentStartTime, estimatedGpuEndTime.value_or(0)) +
            estimatedGpuEndTime = std::max(estimatedTiming.hwcPresentStartTime,
                                           estimatedGpuEndTime.value_or(TimePoint{0ns})) +
                    gpuTiming->duration;
        }
        previousDisplayReferenceTiming = referenceTiming;
    }
    ATRACE_INT64("Idle duration", idleDuration);
    ATRACE_INT64("Idle duration", idleDuration.ns());

    nsecs_t estimatedFlingerEndTime = earlyHint ? estimatedEndTime : mLastSfPresentEndTime;
    TimePoint estimatedFlingerEndTime = earlyHint ? estimatedEndTime : mLastSfPresentEndTime;

    // Don't count time spent idly waiting in the estimate as we could do more work in that time
    estimatedEndTime -= idleDuration;
@@ -454,21 +451,22 @@ std::optional<nsecs_t> PowerAdvisor::estimateWorkDuration(bool earlyHint) {

    // We finish the frame when both present and the gpu are done, so wait for the later of the two
    // Also add the frame delay duration since the target did not move while we were delayed
    nsecs_t totalDuration = mFrameDelayDuration +
            std::max(estimatedEndTime, estimatedGpuEndTime.value_or(0)) - mCommitStartTimes[0];
    Duration totalDuration = mFrameDelayDuration +
            std::max(estimatedEndTime, estimatedGpuEndTime.value_or(TimePoint{0ns})) -
            mCommitStartTimes[0];

    // We finish SurfaceFlinger when post-composition finishes, so add that in here
    nsecs_t flingerDuration =
    Duration flingerDuration =
            estimatedFlingerEndTime + mLastPostcompDuration - mCommitStartTimes[0];

    // Combine the two timings into a single normalized one
    nsecs_t combinedDuration = combineTimingEstimates(totalDuration, flingerDuration);
    Duration combinedDuration = combineTimingEstimates(totalDuration, flingerDuration);

    return std::make_optional(combinedDuration);
}

nsecs_t PowerAdvisor::combineTimingEstimates(nsecs_t totalDuration, nsecs_t flingerDuration) {
    nsecs_t targetDuration;
Duration PowerAdvisor::combineTimingEstimates(Duration totalDuration, Duration flingerDuration) {
    Duration targetDuration{0ns};
    {
        std::lock_guard lock(mPowerHalMutex);
        targetDuration = *getPowerHal()->getTargetWorkDuration();
@@ -477,17 +475,18 @@ nsecs_t PowerAdvisor::combineTimingEstimates(nsecs_t totalDuration, nsecs_t flin

    // Normalize total to the flinger target (vsync period) since that's how often we actually send
    // hints
    nsecs_t normalizedTotalDuration = (targetDuration * totalDuration) / *mTotalFrameTargetDuration;
    Duration normalizedTotalDuration = Duration::fromNs((targetDuration.ns() * totalDuration.ns()) /
                                                        mTotalFrameTargetDuration->ns());
    return std::max(flingerDuration, normalizedTotalDuration);
}

PowerAdvisor::DisplayTimeline PowerAdvisor::DisplayTimeline::estimateTimelineFromReference(
        nsecs_t fenceTime, nsecs_t displayStartTime) {
        TimePoint fenceTime, TimePoint displayStartTime) {
    DisplayTimeline estimated;
    estimated.hwcPresentStartTime = displayStartTime;

    // We don't predict waiting for vsync alignment yet
    estimated.hwcPresentDelayDuration = 0;
    estimated.hwcPresentDelayDuration = 0ns;

    // How long we expect to run before we start waiting for the fence
    // For now just re-use last frame's post-present duration and assume it will not change much
@@ -502,12 +501,11 @@ PowerAdvisor::DisplayTimeline PowerAdvisor::DisplayTimeline::estimateTimelineFro
}

PowerAdvisor::DisplayTimeline PowerAdvisor::DisplayTimingData::calculateDisplayTimeline(
        nsecs_t fenceTime) {
        TimePoint fenceTime) {
    DisplayTimeline timeline;
    // How long between calling hwc present and trying to wait on the fence
    const nsecs_t fenceWaitStartDelay =
            (skippedValidate ? kFenceWaitStartDelaySkippedValidate : kFenceWaitStartDelayValidated)
                    .count();
    const Duration fenceWaitStartDelay =
            (skippedValidate ? kFenceWaitStartDelaySkippedValidate : kFenceWaitStartDelayValidated);

    // Did our reference frame wait for an appropriate vsync before calling into hwc
    const bool waitedOnHwcPresentTime = hwcPresentDelayedTime.has_value() &&
@@ -522,7 +520,7 @@ PowerAdvisor::DisplayTimeline PowerAdvisor::DisplayTimingData::calculateDisplayT

    // How long hwc present was delayed waiting for the next appropriate vsync
    timeline.hwcPresentDelayDuration =
            (waitedOnHwcPresentTime ? *hwcPresentDelayedTime - *hwcPresentStartTime : 0);
            (waitedOnHwcPresentTime ? *hwcPresentDelayedTime - *hwcPresentStartTime : 0ns);
    // When we started waiting for the present fence after calling into hwc present
    timeline.presentFenceWaitStartTime =
            timeline.hwcPresentStartTime + timeline.hwcPresentDelayDuration + fenceWaitStartDelay;
@@ -537,23 +535,26 @@ PowerAdvisor::DisplayTimeline PowerAdvisor::DisplayTimingData::calculateDisplayT
}

std::optional<PowerAdvisor::GpuTimeline> PowerAdvisor::DisplayTimingData::estimateGpuTiming(
        std::optional<nsecs_t> previousEnd) {
        std::optional<TimePoint> previousEndTime) {
    if (!(usedClientComposition && lastValidGpuStartTime.has_value() && gpuEndFenceTime)) {
        return std::nullopt;
    }
    const nsecs_t latestGpuStartTime = std::max(previousEnd.value_or(0), *gpuStartTime);
    const nsecs_t latestGpuEndTime = gpuEndFenceTime->getSignalTime();
    nsecs_t gpuDuration = 0;
    if (latestGpuEndTime != Fence::SIGNAL_TIME_INVALID &&
        latestGpuEndTime != Fence::SIGNAL_TIME_PENDING) {
    const TimePoint latestGpuStartTime =
            std::max(previousEndTime.value_or(TimePoint{0ns}), *gpuStartTime);
    const nsecs_t gpuEndFenceSignal = gpuEndFenceTime->getSignalTime();
    Duration gpuDuration{0ns};
    if (gpuEndFenceSignal != Fence::SIGNAL_TIME_INVALID &&
        gpuEndFenceSignal != Fence::SIGNAL_TIME_PENDING) {
        const TimePoint latestGpuEndTime = TimePoint::fromNs(gpuEndFenceSignal);

        // If we know how long the most recent gpu duration was, use that
        gpuDuration = latestGpuEndTime - latestGpuStartTime;
    } else if (lastValidGpuEndTime.has_value()) {
        // If we don't have the fence data, use the most recent information we do have
        gpuDuration = *lastValidGpuEndTime - *lastValidGpuStartTime;
        if (latestGpuEndTime == Fence::SIGNAL_TIME_PENDING) {
        if (gpuEndFenceSignal == Fence::SIGNAL_TIME_PENDING) {
            // If pending but went over the previous duration, use current time as the end
            gpuDuration = std::max(gpuDuration, systemTime() - latestGpuStartTime);
            gpuDuration = std::max(gpuDuration, Duration{TimePoint::now() - latestGpuStartTime});
        }
    }
    return GpuTimeline{.duration = gpuDuration, .startTime = latestGpuStartTime};
@@ -614,15 +615,15 @@ public:

    bool startPowerHintSession() override { return false; }

    void setTargetWorkDuration(int64_t) override {}
    void setTargetWorkDuration(Duration) override {}

    void sendActualWorkDuration(int64_t, nsecs_t) override {}
    void sendActualWorkDuration(Duration, TimePoint) override {}

    bool shouldReconnectHAL() override { return false; }

    std::vector<int32_t> getPowerHintSessionThreadIds() override { return std::vector<int32_t>{}; }

    std::optional<int64_t> getTargetWorkDuration() override { return std::nullopt; }
    std::optional<Duration> getTargetWorkDuration() override { return std::nullopt; }

private:
    const sp<V1_3::IPower> mPowerHal = nullptr;
@@ -727,9 +728,9 @@ bool AidlPowerHalWrapper::startPowerHintSession() {
        ALOGV("Cannot start power hint session, skipping");
        return false;
    }
    auto ret =
            mPowerHal->createHintSession(getpid(), static_cast<int32_t>(getuid()),
                                         mPowerHintThreadIds, mTargetDuration, &mPowerHintSession);
    auto ret = mPowerHal->createHintSession(getpid(), static_cast<int32_t>(getuid()),
                                            mPowerHintThreadIds, mTargetDuration.ns(),
                                            &mPowerHintSession);
    if (!ret.isOk()) {
        ALOGW("Failed to start power hint session with error: %s",
              ret.exceptionToString(ret.exceptionCode()).c_str());
@@ -739,14 +740,14 @@ bool AidlPowerHalWrapper::startPowerHintSession() {
    return isPowerHintSessionRunning();
}

void AidlPowerHalWrapper::setTargetWorkDuration(int64_t targetDuration) {
void AidlPowerHalWrapper::setTargetWorkDuration(Duration targetDuration) {
    ATRACE_CALL();
    mTargetDuration = targetDuration;
    if (sTraceHintSessionData) ATRACE_INT64("Time target", targetDuration);
    if (sTraceHintSessionData) ATRACE_INT64("Time target", targetDuration.ns());
    if (isPowerHintSessionRunning() && (targetDuration != mLastTargetDurationSent)) {
        ALOGV("Sending target time: %" PRId64 "ns", targetDuration);
        ALOGV("Sending target time: %" PRId64 "ns", targetDuration.ns());
        mLastTargetDurationSent = targetDuration;
        auto ret = mPowerHintSession->updateTargetWorkDuration(targetDuration);
        auto ret = mPowerHintSession->updateTargetWorkDuration(targetDuration.ns());
        if (!ret.isOk()) {
            ALOGW("Failed to set power hint target work duration with error: %s",
                  ret.exceptionMessage().c_str());
@@ -755,33 +756,32 @@ void AidlPowerHalWrapper::setTargetWorkDuration(int64_t targetDuration) {
    }
}

void AidlPowerHalWrapper::sendActualWorkDuration(int64_t actualDuration, nsecs_t timestamp) {
void AidlPowerHalWrapper::sendActualWorkDuration(Duration actualDuration, TimePoint timestamp) {
    ATRACE_CALL();

    if (actualDuration < 0 || !isPowerHintSessionRunning()) {
    if (actualDuration < 0ns || !isPowerHintSessionRunning()) {
        ALOGV("Failed to send actual work duration, skipping");
        return;
    }
    const nsecs_t reportedDuration = actualDuration;

    mActualDuration = reportedDuration;
    mActualDuration = actualDuration;
    WorkDuration duration;
    duration.durationNanos = reportedDuration;
    duration.timeStampNanos = timestamp;
    duration.durationNanos = actualDuration.ns();
    duration.timeStampNanos = timestamp.ns();
    mPowerHintQueue.push_back(duration);

    if (sTraceHintSessionData) {
        ATRACE_INT64("Measured duration", actualDuration);
        ATRACE_INT64("Target error term", actualDuration - mTargetDuration);
        ATRACE_INT64("Measured duration", actualDuration.ns());
        ATRACE_INT64("Target error term", Duration{actualDuration - mTargetDuration}.ns());

        ATRACE_INT64("Reported duration", reportedDuration);
        ATRACE_INT64("Reported target", mLastTargetDurationSent);
        ATRACE_INT64("Reported target error term", reportedDuration - mLastTargetDurationSent);
        ATRACE_INT64("Reported duration", actualDuration.ns());
        ATRACE_INT64("Reported target", mLastTargetDurationSent.ns());
        ATRACE_INT64("Reported target error term",
                     Duration{actualDuration - mLastTargetDurationSent}.ns());
    }

    ALOGV("Sending actual work duration of: %" PRId64 " on reported target: %" PRId64
          " with error: %" PRId64,
          reportedDuration, mLastTargetDurationSent, reportedDuration - mLastTargetDurationSent);
          actualDuration.ns(), mLastTargetDurationSent.ns(),
          Duration{actualDuration - mLastTargetDurationSent}.ns());

    auto ret = mPowerHintSession->reportActualWorkDuration(mPowerHintQueue);
    if (!ret.isOk()) {
@@ -800,7 +800,7 @@ std::vector<int32_t> AidlPowerHalWrapper::getPowerHintSessionThreadIds() {
    return mPowerHintThreadIds;
}

std::optional<int64_t> AidlPowerHalWrapper::getTargetWorkDuration() {
std::optional<Duration> AidlPowerHalWrapper::getTargetWorkDuration() {
    return mTargetDuration;
}

@@ -814,7 +814,7 @@ PowerAdvisor::HalWrapper* PowerAdvisor::getPowerHal() {

    // Grab old hint session values before we destroy any existing wrapper
    std::vector<int32_t> oldPowerHintSessionThreadIds;
    std::optional<int64_t> oldTargetWorkDuration;
    std::optional<Duration> oldTargetWorkDuration;

    if (mHalWrapper != nullptr) {
        oldPowerHintSessionThreadIds = mHalWrapper->getPowerHintSessionThreadIds();
Loading