Merge "Revert "Updates encoding/decoding of optional metadata"" into tm-dev
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index 659efd8..bfdf667 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -80,22 +80,33 @@
 
 } // namespace
 
-PowerAdvisor::PowerAdvisor(SurfaceFlinger& flinger)
-      : mFlinger(flinger),
-        mUseScreenUpdateTimer(getUpdateTimeout() > 0),
-        mScreenUpdateTimer(
-                "UpdateImminentTimer", OneShotTimer::Interval(getUpdateTimeout()),
-                /* resetCallback */ [this] { mSendUpdateImminent.store(false); },
-                /* timeoutCallback */
-                [this] {
-                    mSendUpdateImminent.store(true);
-                    mFlinger.disableExpensiveRendering();
-                }) {}
+PowerAdvisor::PowerAdvisor(SurfaceFlinger& flinger) : mFlinger(flinger) {
+    if (getUpdateTimeout()) {
+        mScreenUpdateTimer.emplace("UpdateImminentTimer",
+                                   OneShotTimer::Interval(getUpdateTimeout()),
+                                   /* resetCallback */ nullptr,
+                                   /* timeoutCallback */
+                                   [this] {
+                                       const nsecs_t timeSinceLastUpdate =
+                                               systemTime() - mLastScreenUpdatedTime.load();
+                                       if (timeSinceLastUpdate < getUpdateTimeout()) {
+                                           // We may try to disable expensive rendering and allow
+                                           // for sending DISPLAY_UPDATE_IMMINENT hints too early if
+                                           // we idled very shortly after updating the screen, so
+                                           // make sure we wait enough time.
+                                           std::this_thread::sleep_for(std::chrono::nanoseconds(
+                                                   getUpdateTimeout() - timeSinceLastUpdate));
+                                       }
+                                       mSendUpdateImminent.store(true);
+                                       mFlinger.disableExpensiveRendering();
+                                   });
+    }
+}
 
 void PowerAdvisor::init() {
     // Defer starting the screen update timer until SurfaceFlinger finishes construction.
-    if (mUseScreenUpdateTimer) {
-        mScreenUpdateTimer.start();
+    if (mScreenUpdateTimer) {
+        mScreenUpdateTimer->start();
     }
 }
 
@@ -135,7 +146,7 @@
         return;
     }
 
-    if (mSendUpdateImminent.load()) {
+    if (mSendUpdateImminent.exchange(false)) {
         std::lock_guard lock(mPowerHalMutex);
         HalWrapper* const halWrapper = getPowerHal();
         if (halWrapper == nullptr) {
@@ -147,10 +158,18 @@
             mReconnectPowerHal = true;
             return;
         }
+
+        if (mScreenUpdateTimer) {
+            mScreenUpdateTimer->reset();
+        } else {
+            // If we don't have a screen update timer, then we don't throttle power hal calls so
+            // flip this bit back to allow for calling into power hal again.
+            mSendUpdateImminent.store(true);
+        }
     }
 
-    if (mUseScreenUpdateTimer) {
-        mScreenUpdateTimer.reset();
+    if (mScreenUpdateTimer) {
+        mLastScreenUpdatedTime.store(systemTime());
     }
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index 61bb32b..7c10e19 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -114,9 +114,9 @@
     bool mNotifiedExpensiveRendering = false;
 
     SurfaceFlinger& mFlinger;
-    const bool mUseScreenUpdateTimer;
     std::atomic_bool mSendUpdateImminent = true;
-    scheduler::OneShotTimer mScreenUpdateTimer;
+    std::atomic<nsecs_t> mLastScreenUpdatedTime = 0;
+    std::optional<scheduler::OneShotTimer> mScreenUpdateTimer;
 };
 
 class AidlPowerHalWrapper : public PowerAdvisor::HalWrapper {