diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index 44c086d..05f488b 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -32,7 +32,6 @@
 #include <utils/Trace.h>
 
 #include <android/hardware/power/1.3/IPower.h>
-#include <android/hardware/power/IPower.h>
 #include <android/hardware/power/IPowerHintSession.h>
 #include <android/hardware/power/WorkDuration.h>
 
@@ -62,8 +61,6 @@
 
 using scheduler::OneShotTimer;
 
-class AidlPowerHalWrapper;
-
 PowerAdvisor::~PowerAdvisor() = default;
 
 namespace {
@@ -294,259 +291,232 @@
     const sp<V1_3::IPower> mPowerHal = nullptr;
 };
 
-class AidlPowerHalWrapper : public PowerAdvisor::HalWrapper {
-public:
-    AidlPowerHalWrapper(sp<IPower> powerHal) : mPowerHal(std::move(powerHal)) {
-        auto ret = mPowerHal->isModeSupported(Mode::EXPENSIVE_RENDERING, &mHasExpensiveRendering);
-        if (!ret.isOk()) {
-            mHasExpensiveRendering = false;
-        }
-
-        ret = mPowerHal->isBoostSupported(Boost::DISPLAY_UPDATE_IMMINENT,
-                                          &mHasDisplayUpdateImminent);
-        if (!ret.isOk()) {
-            mHasDisplayUpdateImminent = false;
-        }
-
-        mSupportsPowerHint = checkPowerHintSessionSupported();
+AidlPowerHalWrapper::AidlPowerHalWrapper(sp<IPower> powerHal) : mPowerHal(std::move(powerHal)) {
+    auto ret = mPowerHal->isModeSupported(Mode::EXPENSIVE_RENDERING, &mHasExpensiveRendering);
+    if (!ret.isOk()) {
+        mHasExpensiveRendering = false;
     }
 
-    ~AidlPowerHalWrapper() override {
-        if (mPowerHintSession != nullptr) {
-            mPowerHintSession->close();
-            mPowerHintSession = nullptr;
-        }
-    };
-
-    static std::unique_ptr<HalWrapper> connect() {
-        // This only waits if the service is actually declared
-        sp<IPower> powerHal = waitForVintfService<IPower>();
-        if (powerHal == nullptr) {
-            return nullptr;
-        }
-        ALOGI("Loaded AIDL Power HAL service");
-
-        return std::make_unique<AidlPowerHalWrapper>(std::move(powerHal));
+    ret = mPowerHal->isBoostSupported(Boost::DISPLAY_UPDATE_IMMINENT, &mHasDisplayUpdateImminent);
+    if (!ret.isOk()) {
+        mHasDisplayUpdateImminent = false;
     }
 
-    bool setExpensiveRendering(bool enabled) override {
-        ALOGV("AIDL setExpensiveRendering %s", enabled ? "T" : "F");
-        if (!mHasExpensiveRendering) {
-            ALOGV("Skipped sending EXPENSIVE_RENDERING because HAL doesn't support it");
-            return true;
-        }
+    mSupportsPowerHint = checkPowerHintSessionSupported();
+}
 
-        auto ret = mPowerHal->setMode(Mode::EXPENSIVE_RENDERING, enabled);
-        if (ret.isOk()) {
-            traceExpensiveRendering(enabled);
-        }
-        return ret.isOk();
+AidlPowerHalWrapper::~AidlPowerHalWrapper() {
+    if (mPowerHintSession != nullptr) {
+        mPowerHintSession->close();
+        mPowerHintSession = nullptr;
     }
-
-    bool notifyDisplayUpdateImminent() override {
-        ALOGV("AIDL notifyDisplayUpdateImminent");
-        if (!mHasDisplayUpdateImminent) {
-            ALOGV("Skipped sending DISPLAY_UPDATE_IMMINENT because HAL doesn't support it");
-            return true;
-        }
-
-        auto ret = mPowerHal->setBoost(Boost::DISPLAY_UPDATE_IMMINENT, 0);
-        return ret.isOk();
-    }
-
-    // only version 2+ of the aidl supports power hint sessions, hidl has no support
-    bool supportsPowerHintSession() override { return mSupportsPowerHint; }
-
-    bool checkPowerHintSessionSupported() {
-        int64_t unused;
-        // Try to get preferred rate to determine if hint sessions are supported
-        // We check for isOk not EX_UNSUPPORTED_OPERATION to lump other errors
-        return mPowerHal->getHintSessionPreferredRate(&unused).isOk();
-    }
-
-    bool isPowerHintSessionRunning() override { return mPowerHintSession != nullptr; }
-
-    void closePowerHintSession() {
-        if (mPowerHintSession != nullptr) {
-            mPowerHintSession->close();
-            mPowerHintSession = nullptr;
-        }
-    }
-
-    void restartPowerHintSession() {
-        closePowerHintSession();
-        startPowerHintSession();
-    }
-
-    void setPowerHintSessionThreadIds(const std::vector<int32_t>& threadIds) override {
-        if (threadIds != mPowerHintThreadIds) {
-            mPowerHintThreadIds = threadIds;
-            if (isPowerHintSessionRunning()) {
-                restartPowerHintSession();
-            }
-        }
-    }
-
-    bool startPowerHintSession() override {
-        if (mPowerHintSession != nullptr || mPowerHintThreadIds.empty()) {
-            ALOGV("Cannot start power hint session, skipping");
-            return false;
-        }
-        auto ret = mPowerHal->createHintSession(getpid(), static_cast<int32_t>(getuid()),
-                                                mPowerHintThreadIds, mTargetDuration,
-                                                &mPowerHintSession);
-        if (!ret.isOk()) {
-            ALOGW("Failed to start power hint session with error: %s",
-                  ret.exceptionToString(ret.exceptionCode()).c_str());
-        } else {
-            mLastTargetDurationSent = mTargetDuration;
-        }
-        return isPowerHintSessionRunning();
-    }
-
-    bool shouldSetTargetDuration(int64_t targetDurationNanos) {
-        // report if the change in target from our last submission to now exceeds the threshold
-        return abs(1.0 -
-                   static_cast<double>(mLastTargetDurationSent) /
-                           static_cast<double>(targetDurationNanos)) >=
-                kAllowedTargetDeviationPercent;
-    }
-
-    void setTargetWorkDuration(int64_t targetDurationNanos) override {
-        ATRACE_CALL();
-        mTargetDuration = targetDurationNanos;
-        if (sTraceHintSessionData) ATRACE_INT64("Time target", targetDurationNanos);
-        if (!sNormalizeTarget && shouldSetTargetDuration(targetDurationNanos) &&
-            isPowerHintSessionRunning()) {
-            if (mLastActualDurationSent.has_value()) {
-                // update the error term here since we are actually sending an update to powerhal
-                if (sTraceHintSessionData)
-                    ATRACE_INT64("Target error term",
-                                 targetDurationNanos - *mLastActualDurationSent);
-            }
-            ALOGV("Sending target time: %lld ns", static_cast<long long>(targetDurationNanos));
-            mLastTargetDurationSent = targetDurationNanos;
-            auto ret = mPowerHintSession->updateTargetWorkDuration(targetDurationNanos);
-            if (!ret.isOk()) {
-                ALOGW("Failed to set power hint target work duration with error: %s",
-                      ret.exceptionMessage().c_str());
-                mShouldReconnectHal = true;
-            }
-        }
-    }
-
-    bool shouldReportActualDurationsNow() {
-        // report if we have never reported before or are approaching a stale session
-        if (!mLastActualDurationSent.has_value() ||
-            (systemTime() - mLastActualReportTimestamp) > kStaleTimeout.count()) {
-            return true;
-        }
-
-        if (!mActualDuration.has_value()) {
-            return false;
-        }
-
-        // duration of most recent timing
-        const double mostRecentActualDuration = static_cast<double>(*mActualDuration);
-        // duration of the last timing actually reported to the powerhal
-        const double lastReportedActualDuration = static_cast<double>(*mLastActualDurationSent);
-
-        // report if the change in duration from then to now exceeds the threshold
-        return abs(1.0 - mostRecentActualDuration / lastReportedActualDuration) >=
-                kAllowedActualDeviationPercent;
-    }
-
-    void sendActualWorkDuration(int64_t actualDurationNanos, nsecs_t timeStampNanos) override {
-        ATRACE_CALL();
-
-        if (actualDurationNanos < 0 || !isPowerHintSessionRunning()) {
-            ALOGV("Failed to send actual work duration, skipping");
-            return;
-        }
-
-        WorkDuration duration;
-        duration.durationNanos = actualDurationNanos;
-        mActualDuration = actualDurationNanos;
-
-        // normalize the sent values to a pre-set target
-        if (sNormalizeTarget) {
-            duration.durationNanos += mLastTargetDurationSent - mTargetDuration;
-        }
-        duration.timeStampNanos = timeStampNanos;
-        mPowerHintQueue.push_back(duration);
-
-        long long targetNsec = mTargetDuration;
-        long long durationNsec = actualDurationNanos;
-
-        if (sTraceHintSessionData) {
-            ATRACE_INT64("Measured duration", durationNsec);
-            ATRACE_INT64("Target error term", targetNsec - durationNsec);
-        }
-
-        ALOGV("Sending actual work duration of: %lld on target: %lld with error: %lld",
-              durationNsec, targetNsec, targetNsec - durationNsec);
-
-        // This rate limiter queues similar duration reports to the powerhal into
-        // batches to avoid excessive binder calls. The criteria to send a given batch
-        // are outlined in shouldReportActualDurationsNow()
-        if (shouldReportActualDurationsNow()) {
-            ALOGV("Sending hint update batch");
-            mLastActualReportTimestamp = systemTime();
-            auto ret = mPowerHintSession->reportActualWorkDuration(mPowerHintQueue);
-            if (!ret.isOk()) {
-                ALOGW("Failed to report actual work durations with error: %s",
-                      ret.exceptionMessage().c_str());
-                mShouldReconnectHal = true;
-            }
-            mPowerHintQueue.clear();
-            // we save the non-normalized value here to detect % changes
-            mLastActualDurationSent = actualDurationNanos;
-        }
-    }
-
-    bool shouldReconnectHAL() override { return mShouldReconnectHal; }
-
-    std::vector<int32_t> getPowerHintSessionThreadIds() override { return mPowerHintThreadIds; }
-
-    std::optional<int64_t> getTargetWorkDuration() override { return mTargetDuration; }
-
-private:
-    const sp<IPower> mPowerHal = nullptr;
-    bool mHasExpensiveRendering = false;
-    bool mHasDisplayUpdateImminent = false;
-    // Used to indicate an error state and need for reconstruction
-    bool mShouldReconnectHal = false;
-    // This is not thread safe, but is currently protected by mPowerHalMutex so it needs no lock
-    sp<IPowerHintSession> mPowerHintSession = nullptr;
-    // Queue of actual durations saved to report
-    std::vector<WorkDuration> mPowerHintQueue;
-    // The latest un-normalized values we have received for target and actual
-    int64_t mTargetDuration = kDefaultTarget.count();
-    std::optional<int64_t> mActualDuration;
-    // The list of thread ids, stored so we can restart the session from this class if needed
-    std::vector<int32_t> mPowerHintThreadIds;
-    bool mSupportsPowerHint;
-    // Keep track of the last messages sent for rate limiter change detection
-    std::optional<int64_t> mLastActualDurationSent;
-    // timestamp of the last report we sent, used to avoid stale sessions
-    int64_t mLastActualReportTimestamp = 0;
-    int64_t mLastTargetDurationSent = kDefaultTarget.count();
-    // Whether to normalize all the actual values as error terms relative to a constant target
-    // This saves a binder call by not setting the target, and should not affect the pid values
-    static const bool sNormalizeTarget;
-    // Whether we should emit ATRACE_INT data for hint sessions
-    static const bool sTraceHintSessionData;
-    // Max percent the actual duration can vary without causing a report (eg: 0.1 = 10%)
-    static constexpr double kAllowedActualDeviationPercent = 0.1;
-    // Max percent the target duration can vary without causing a report (eg: 0.05 = 5%)
-    static constexpr double kAllowedTargetDeviationPercent = 0.05;
-    // Target used for init and normalization, the actual value does not really matter
-    static constexpr const std::chrono::nanoseconds kDefaultTarget = 50ms;
-    // Amount of time after the last message was sent before the session goes stale
-    // actually 100ms but we use 80 here to ideally avoid going stale
-    static constexpr const std::chrono::nanoseconds kStaleTimeout = 80ms;
 };
 
+std::unique_ptr<PowerAdvisor::HalWrapper> AidlPowerHalWrapper::connect() {
+    // This only waits if the service is actually declared
+    sp<IPower> powerHal = waitForVintfService<IPower>();
+    if (powerHal == nullptr) {
+        return nullptr;
+    }
+    ALOGI("Loaded AIDL Power HAL service");
+
+    return std::make_unique<AidlPowerHalWrapper>(std::move(powerHal));
+}
+
+bool AidlPowerHalWrapper::setExpensiveRendering(bool enabled) {
+    ALOGV("AIDL setExpensiveRendering %s", enabled ? "T" : "F");
+    if (!mHasExpensiveRendering) {
+        ALOGV("Skipped sending EXPENSIVE_RENDERING because HAL doesn't support it");
+        return true;
+    }
+
+    auto ret = mPowerHal->setMode(Mode::EXPENSIVE_RENDERING, enabled);
+    if (ret.isOk()) {
+        traceExpensiveRendering(enabled);
+    }
+    return ret.isOk();
+}
+
+bool AidlPowerHalWrapper::notifyDisplayUpdateImminent() {
+    ALOGV("AIDL notifyDisplayUpdateImminent");
+    if (!mHasDisplayUpdateImminent) {
+        ALOGV("Skipped sending DISPLAY_UPDATE_IMMINENT because HAL doesn't support it");
+        return true;
+    }
+
+    auto ret = mPowerHal->setBoost(Boost::DISPLAY_UPDATE_IMMINENT, 0);
+    return ret.isOk();
+}
+
+// only version 2+ of the aidl supports power hint sessions, hidl has no support
+bool AidlPowerHalWrapper::supportsPowerHintSession() {
+    return mSupportsPowerHint;
+}
+
+bool AidlPowerHalWrapper::checkPowerHintSessionSupported() {
+    int64_t unused;
+    // Try to get preferred rate to determine if hint sessions are supported
+    // We check for isOk not EX_UNSUPPORTED_OPERATION to lump together errors
+    return mPowerHal->getHintSessionPreferredRate(&unused).isOk();
+}
+
+bool AidlPowerHalWrapper::isPowerHintSessionRunning() {
+    return mPowerHintSession != nullptr;
+}
+
+void AidlPowerHalWrapper::closePowerHintSession() {
+    if (mPowerHintSession != nullptr) {
+        mPowerHintSession->close();
+        mPowerHintSession = nullptr;
+    }
+}
+
+void AidlPowerHalWrapper::restartPowerHintSession() {
+    closePowerHintSession();
+    startPowerHintSession();
+}
+
+void AidlPowerHalWrapper::setPowerHintSessionThreadIds(const std::vector<int32_t>& threadIds) {
+    if (threadIds != mPowerHintThreadIds) {
+        mPowerHintThreadIds = threadIds;
+        if (isPowerHintSessionRunning()) {
+            restartPowerHintSession();
+        }
+    }
+}
+
+bool AidlPowerHalWrapper::startPowerHintSession() {
+    if (mPowerHintSession != nullptr || mPowerHintThreadIds.empty()) {
+        ALOGV("Cannot start power hint session, skipping");
+        return false;
+    }
+    auto ret =
+            mPowerHal->createHintSession(getpid(), static_cast<int32_t>(getuid()),
+                                         mPowerHintThreadIds, mTargetDuration, &mPowerHintSession);
+    if (!ret.isOk()) {
+        ALOGW("Failed to start power hint session with error: %s",
+              ret.exceptionToString(ret.exceptionCode()).c_str());
+    } else {
+        mLastTargetDurationSent = mTargetDuration;
+    }
+    return isPowerHintSessionRunning();
+}
+
+bool AidlPowerHalWrapper::shouldSetTargetDuration(int64_t targetDurationNanos) {
+    if (targetDurationNanos <= 0) {
+        return false;
+    }
+    // report if the change in target from our last submission to now exceeds the threshold
+    return abs(1.0 -
+               static_cast<double>(mLastTargetDurationSent) /
+                       static_cast<double>(targetDurationNanos)) >= kAllowedTargetDeviationPercent;
+}
+
+void AidlPowerHalWrapper::setTargetWorkDuration(int64_t targetDurationNanos) {
+    ATRACE_CALL();
+    mTargetDuration = targetDurationNanos;
+    if (sTraceHintSessionData) ATRACE_INT64("Time target", targetDurationNanos);
+    if (!sNormalizeTarget && isPowerHintSessionRunning() &&
+        shouldSetTargetDuration(targetDurationNanos)) {
+        if (mLastActualDurationSent.has_value()) {
+            // update the error term here since we are actually sending an update to powerhal
+            if (sTraceHintSessionData)
+                ATRACE_INT64("Target error term", targetDurationNanos - *mLastActualDurationSent);
+        }
+        ALOGV("Sending target time: %" PRId64 "ns", targetDurationNanos);
+        mLastTargetDurationSent = targetDurationNanos;
+        auto ret = mPowerHintSession->updateTargetWorkDuration(targetDurationNanos);
+        if (!ret.isOk()) {
+            ALOGW("Failed to set power hint target work duration with error: %s",
+                  ret.exceptionMessage().c_str());
+            mShouldReconnectHal = true;
+        }
+    }
+}
+
+bool AidlPowerHalWrapper::shouldReportActualDurationsNow() {
+    // report if we have never reported before or are approaching a stale session
+    if (!mLastActualDurationSent.has_value() ||
+        (systemTime() - mLastActualReportTimestamp) > kStaleTimeout.count()) {
+        return true;
+    }
+
+    if (!mActualDuration.has_value()) {
+        return false;
+    }
+
+    // duration of most recent timing
+    const double mostRecentActualDuration = static_cast<double>(*mActualDuration);
+    // duration of the last timing actually reported to the powerhal
+    const double lastReportedActualDuration = static_cast<double>(*mLastActualDurationSent);
+
+    // report if the change in duration from then to now exceeds the threshold
+    return abs(1.0 - mostRecentActualDuration / lastReportedActualDuration) >=
+            kAllowedActualDeviationPercent;
+}
+
+void AidlPowerHalWrapper::sendActualWorkDuration(int64_t actualDurationNanos,
+                                                 nsecs_t timeStampNanos) {
+    ATRACE_CALL();
+
+    if (actualDurationNanos < 0 || !isPowerHintSessionRunning()) {
+        ALOGV("Failed to send actual work duration, skipping");
+        return;
+    }
+
+    WorkDuration duration;
+    duration.durationNanos = actualDurationNanos;
+    mActualDuration = actualDurationNanos;
+
+    // normalize the sent values to a pre-set target
+    if (sNormalizeTarget) {
+        duration.durationNanos += mLastTargetDurationSent - mTargetDuration;
+    }
+    duration.timeStampNanos = timeStampNanos;
+    mPowerHintQueue.push_back(duration);
+
+    nsecs_t targetNsec = mTargetDuration;
+    nsecs_t durationNsec = actualDurationNanos;
+
+    if (sTraceHintSessionData) {
+        ATRACE_INT64("Measured duration", durationNsec);
+        ATRACE_INT64("Target error term", targetNsec - durationNsec);
+    }
+
+    ALOGV("Sending actual work duration of: %" PRId64 " on target: %" PRId64
+          " with error: %" PRId64,
+          durationNsec, targetNsec, targetNsec - durationNsec);
+
+    // This rate limiter queues similar duration reports to the powerhal into
+    // batches to avoid excessive binder calls. The criteria to send a given batch
+    // are outlined in shouldReportActualDurationsNow()
+    if (shouldReportActualDurationsNow()) {
+        ALOGV("Sending hint update batch");
+        mLastActualReportTimestamp = systemTime();
+        auto ret = mPowerHintSession->reportActualWorkDuration(mPowerHintQueue);
+        if (!ret.isOk()) {
+            ALOGW("Failed to report actual work durations with error: %s",
+                  ret.exceptionMessage().c_str());
+            mShouldReconnectHal = true;
+        }
+        mPowerHintQueue.clear();
+        // we save the non-normalized value here to detect % changes
+        mLastActualDurationSent = actualDurationNanos;
+    }
+}
+
+bool AidlPowerHalWrapper::shouldReconnectHAL() {
+    return mShouldReconnectHal;
+}
+
+std::vector<int32_t> AidlPowerHalWrapper::getPowerHintSessionThreadIds() {
+    return mPowerHintThreadIds;
+}
+
+std::optional<int64_t> AidlPowerHalWrapper::getTargetWorkDuration() {
+    return mTargetDuration;
+}
+
 const bool AidlPowerHalWrapper::sTraceHintSessionData =
         base::GetBoolProperty(std::string("debug.sf.trace_hint_sessions"), false);
 
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index 0db56aa..3f47ffd 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -22,6 +22,7 @@
 
 #include <utils/Mutex.h>
 
+#include <android/hardware/power/IPower.h>
 #include <ui/DisplayIdentification.h>
 #include "../Scheduler/OneShotTimer.h"
 
@@ -118,6 +119,69 @@
     scheduler::OneShotTimer mScreenUpdateTimer;
 };
 
+class AidlPowerHalWrapper : public PowerAdvisor::HalWrapper {
+public:
+    explicit AidlPowerHalWrapper(sp<hardware::power::IPower> powerHal);
+    ~AidlPowerHalWrapper() override;
+
+    static std::unique_ptr<HalWrapper> connect();
+
+    bool setExpensiveRendering(bool enabled) override;
+    bool notifyDisplayUpdateImminent() override;
+    bool supportsPowerHintSession() override;
+    bool isPowerHintSessionRunning() override;
+    void restartPowerHintSession() override;
+    void setPowerHintSessionThreadIds(const std::vector<int32_t>& threadIds) override;
+    bool startPowerHintSession() override;
+    void setTargetWorkDuration(int64_t targetDurationNanos) override;
+    void sendActualWorkDuration(int64_t actualDurationNanos, nsecs_t timeStampNanos) override;
+    bool shouldReconnectHAL() override;
+    std::vector<int32_t> getPowerHintSessionThreadIds() override;
+    std::optional<int64_t> getTargetWorkDuration() override;
+
+private:
+    bool checkPowerHintSessionSupported();
+    void closePowerHintSession();
+    bool shouldReportActualDurationsNow();
+    bool shouldSetTargetDuration(int64_t targetDurationNanos);
+
+    const sp<hardware::power::IPower> mPowerHal = nullptr;
+    bool mHasExpensiveRendering = false;
+    bool mHasDisplayUpdateImminent = false;
+    // Used to indicate an error state and need for reconstruction
+    bool mShouldReconnectHal = false;
+    // This is not thread safe, but is currently protected by mPowerHalMutex so it needs no lock
+    sp<hardware::power::IPowerHintSession> mPowerHintSession = nullptr;
+    // Queue of actual durations saved to report
+    std::vector<hardware::power::WorkDuration> mPowerHintQueue;
+    // The latest un-normalized values we have received for target and actual
+    int64_t mTargetDuration = kDefaultTarget.count();
+    std::optional<int64_t> mActualDuration;
+    // The list of thread ids, stored so we can restart the session from this class if needed
+    std::vector<int32_t> mPowerHintThreadIds;
+    bool mSupportsPowerHint;
+    // Keep track of the last messages sent for rate limiter change detection
+    std::optional<int64_t> mLastActualDurationSent;
+    // timestamp of the last report we sent, used to avoid stale sessions
+    int64_t mLastActualReportTimestamp = 0;
+    int64_t mLastTargetDurationSent = kDefaultTarget.count();
+    // Whether to normalize all the actual values as error terms relative to a constant target
+    // This saves a binder call by not setting the target, and should not affect the pid values
+    static const bool sNormalizeTarget;
+    // Whether we should emit ATRACE_INT data for hint sessions
+    static const bool sTraceHintSessionData;
+
+    // Max percent the actual duration can vary without causing a report (eg: 0.1 = 10%)
+    static constexpr double kAllowedActualDeviationPercent = 0.1;
+    // Max percent the target duration can vary without causing a report (eg: 0.05 = 5%)
+    static constexpr double kAllowedTargetDeviationPercent = 0.05;
+    // Target used for init and normalization, the actual value does not really matter
+    static constexpr const std::chrono::nanoseconds kDefaultTarget = 50ms;
+    // Amount of time after the last message was sent before the session goes stale
+    // actually 100ms but we use 80 here to ideally avoid going stale
+    static constexpr const std::chrono::nanoseconds kStaleTimeout = 80ms;
+};
+
 } // namespace impl
 } // namespace Hwc2
 } // namespace android
