Merge "Apply display translation to blurred result" into rvc-dev
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 1911119..9ba4819 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -169,6 +169,7 @@
 #define OTA_METADATA_DIR "/metadata/ota"
 #define SNAPSHOTCTL_LOG_DIR "/data/misc/snapshotctl_log"
 #define LINKERCONFIG_DIR "/linkerconfig"
+#define PACKAGE_DEX_USE_LIST "/data/system/package-dex-usage.list"
 
 // TODO(narayan): Since this information has to be kept in sync
 // with tombstoned, we should just put it in a common header.
@@ -1612,6 +1613,7 @@
     if (!PropertiesHelper::IsUserBuild()) {
         ds.AddDir(PROFILE_DATA_DIR_CUR, true);
         ds.AddDir(PROFILE_DATA_DIR_REF, true);
+        ds.AddZipEntry(ZIP_ROOT_DIR + PACKAGE_DEX_USE_LIST, PACKAGE_DEX_USE_LIST);
     }
     ds.AddDir(PREREBOOT_DATA_DIR, false);
     add_mountinfo();
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index 55400c7..5baec2f 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -59,7 +59,6 @@
     ],
 
     shared_libs: [
-        "libhardware",
         "libcutils",
         "liblog",
         "libutils",
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index bf487c4..d929cc3 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -306,6 +306,10 @@
 // ----------------------------------------------------------------------------
 
 Region& Region::orSelf(const Rect& r) {
+    if (isEmpty()) {
+        set(r);
+        return *this;
+    }
     return operationSelf(r, op_or);
 }
 Region& Region::xorSelf(const Rect& r) {
@@ -326,6 +330,10 @@
 // ----------------------------------------------------------------------------
 
 Region& Region::orSelf(const Region& rhs) {
+    if (isEmpty()) {
+        *this = rhs;
+        return *this;
+    }
     return operationSelf(rhs, op_or);
 }
 Region& Region::xorSelf(const Region& rhs) {
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 19b8a58..3997134 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -75,7 +75,6 @@
         "bionic_libc_platform_headers",
         "gl_headers",
         "libsystem_headers",
-        "libhardware_headers",
         "libnativebase_headers",
     ],
     export_header_lib_headers: ["gl_headers"],
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 0581708..d5d57d7 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -16,8 +16,6 @@
 
 #include <stdlib.h>
 
-#include <hardware/gralloc.h>
-
 #include <EGL/egl.h>
 
 #include <cutils/properties.h>
diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp
index 1b75b20..c976c60 100644
--- a/opengl/libs/EGL/egl_platform_entries.cpp
+++ b/opengl/libs/EGL/egl_platform_entries.cpp
@@ -23,8 +23,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <hardware/gralloc1.h>
-
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <EGL/eglext_angle.h>
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 56d6567..baf2f2b 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -1986,18 +1986,49 @@
     return true;
 }
 
+/**
+ * Indicate whether one window handle should be considered as obscuring
+ * another window handle. We only check a few preconditions. Actually
+ * checking the bounds is left to the caller.
+ */
+static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
+                            const sp<InputWindowHandle>& otherHandle) {
+    // Compare by token so cloned layers aren't counted
+    if (haveSameToken(windowHandle, otherHandle)) {
+        return false;
+    }
+    auto info = windowHandle->getInfo();
+    auto otherInfo = otherHandle->getInfo();
+    if (!otherInfo->visible) {
+        return false;
+    } else if (info->ownerPid == otherInfo->ownerPid && otherHandle->getToken() == nullptr) {
+      // In general, if ownerPid is the same we don't want to generate occlusion
+      // events. This line is now necessary since we are including all Surfaces
+      // in occlusion calculation, so if we didn't check PID like this SurfaceView
+      // would occlude their parents. On the other hand before we started including
+      // all surfaces in occlusion calculation and had this line, we would count
+      // windows with an input channel from the same PID as occluding, and so we
+      // preserve this behavior with the getToken() == null check.
+        return false;
+    } else if (otherInfo->isTrustedOverlay()) {
+        return false;
+    } else if (otherInfo->displayId != info->displayId) {
+        return false;
+    }
+    return true;
+}
+
 bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
                                                     int32_t x, int32_t y) const {
     int32_t displayId = windowHandle->getInfo()->displayId;
     const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
     for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
-        if (otherHandle == windowHandle) {
-            break;
+        if (windowHandle == otherHandle) {
+            break; // All future windows are below us. Exit early.
         }
-
         const InputWindowInfo* otherInfo = otherHandle->getInfo();
-        if (otherInfo->displayId == displayId && otherInfo->visible &&
-            !otherInfo->isTrustedOverlay() && otherInfo->frameContainsPoint(x, y)) {
+          if (canBeObscuredBy(windowHandle, otherHandle) &&
+            otherInfo->frameContainsPoint(x, y)) {
             return true;
         }
     }
@@ -2009,13 +2040,13 @@
     const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
     const InputWindowInfo* windowInfo = windowHandle->getInfo();
     for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
-        if (otherHandle == windowHandle) {
-            break;
+        if (windowHandle == otherHandle) {
+            break; // All future windows are below us. Exit early.
         }
 
         const InputWindowInfo* otherInfo = otherHandle->getInfo();
-        if (otherInfo->displayId == displayId && otherInfo->visible &&
-            !otherInfo->isTrustedOverlay() && otherInfo->overlaps(windowInfo)) {
+        if (canBeObscuredBy(windowHandle, otherHandle) &&
+            otherInfo->overlaps(windowInfo)) {
             return true;
         }
     }
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 27266b7..75a4fec 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -74,7 +74,7 @@
     MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(DisplayId, bool, uint8_t, uint64_t));
     MOCK_METHOD4(getDisplayedContentSample,
                  status_t(DisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
-    MOCK_METHOD2(setDisplayBrightness, status_t(DisplayId, float));
+    MOCK_METHOD2(setDisplayBrightness, std::future<status_t>(DisplayId, float));
     MOCK_METHOD2(getDisplayBrightnessSupport, status_t(DisplayId, bool*));
 
     MOCK_METHOD2(onHotplug,
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index d6dbd57..0ea3340 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -25,7 +25,6 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #include "HWC2.h"
-#include "ComposerHal.h"
 
 #include <ui/Fence.h>
 #include <ui/FloatRect.h>
@@ -38,6 +37,9 @@
 #include <iterator>
 #include <set>
 
+#include "../Promise.h"
+#include "ComposerHal.h"
+
 namespace android {
 
 using android::Fence;
@@ -640,12 +642,14 @@
     return error;
 }
 
-Error Display::setDisplayBrightness(float brightness) const {
-    const auto intError = mComposer.setDisplayBrightness(mId, brightness);
-    return static_cast<Error>(intError);
+std::future<Error> Display::setDisplayBrightness(float brightness) {
+    return promise::defer([composer = &mComposer, id = mId, brightness] {
+        const auto intError = composer->setDisplayBrightness(id, brightness);
+        return static_cast<Error>(intError);
+    });
 }
 
-Error Display::setAutoLowLatencyMode(bool on) const {
+Error Display::setAutoLowLatencyMode(bool on) {
     auto intError = mComposer.setAutoLowLatencyMode(mId, on);
     return static_cast<Error>(intError);
 }
@@ -659,7 +663,7 @@
     return static_cast<Error>(intError);
 }
 
-Error Display::setContentType(ContentType contentType) const {
+Error Display::setContentType(ContentType contentType) {
     auto intError = mComposer.setContentType(mId, contentType);
     return static_cast<Error>(intError);
 }
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index af31df8..f4c7fdd 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -27,6 +27,7 @@
 #include <utils/Timers.h>
 
 #include <functional>
+#include <future>
 #include <string>
 #include <unordered_map>
 #include <unordered_set>
@@ -221,18 +222,18 @@
     [[clang::warn_unused_result]] virtual hal::Error presentOrValidate(
             uint32_t* outNumTypes, uint32_t* outNumRequests,
             android::sp<android::Fence>* outPresentFence, uint32_t* state) = 0;
-    [[clang::warn_unused_result]] virtual hal::Error setDisplayBrightness(
-            float brightness) const = 0;
+    [[clang::warn_unused_result]] virtual std::future<hal::Error> setDisplayBrightness(
+            float brightness) = 0;
     [[clang::warn_unused_result]] virtual hal::Error getDisplayVsyncPeriod(
             nsecs_t* outVsyncPeriod) const = 0;
     [[clang::warn_unused_result]] virtual hal::Error setActiveConfigWithConstraints(
             const std::shared_ptr<const HWC2::Display::Config>& config,
             const hal::VsyncPeriodChangeConstraints& constraints,
             hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
-    [[clang::warn_unused_result]] virtual hal::Error setAutoLowLatencyMode(bool on) const = 0;
+    [[clang::warn_unused_result]] virtual hal::Error setAutoLowLatencyMode(bool on) = 0;
     [[clang::warn_unused_result]] virtual hal::Error getSupportedContentTypes(
             std::vector<hal::ContentType>*) const = 0;
-    [[clang::warn_unused_result]] virtual hal::Error setContentType(hal::ContentType) const = 0;
+    [[clang::warn_unused_result]] virtual hal::Error setContentType(hal::ContentType) = 0;
 };
 
 namespace impl {
@@ -294,16 +295,16 @@
     hal::Error presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
                                  android::sp<android::Fence>* outPresentFence,
                                  uint32_t* state) override;
-    hal::Error setDisplayBrightness(float brightness) const override;
+    std::future<hal::Error> setDisplayBrightness(float brightness) override;
     hal::Error getDisplayVsyncPeriod(nsecs_t* outVsyncPeriod) const override;
     hal::Error setActiveConfigWithConstraints(
             const std::shared_ptr<const HWC2::Display::Config>& config,
             const hal::VsyncPeriodChangeConstraints& constraints,
             hal::VsyncPeriodChangeTimeline* outTimeline) override;
-    hal::Error setAutoLowLatencyMode(bool on) const override;
+    hal::Error setAutoLowLatencyMode(bool on) override;
     hal::Error getSupportedContentTypes(
             std::vector<hal::ContentType>* outSupportedContentTypes) const override;
-    hal::Error setContentType(hal::ContentType contentType) const override;
+    hal::Error setContentType(hal::ContentType) override;
     // Other Display methods
     hal::HWDisplayId getId() const override { return mId; }
     bool isConnected() const override { return mIsConnected; }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 4344a8d..038cec4 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -36,6 +36,7 @@
 #include <utils/Trace.h>
 
 #include "../Layer.h" // needed only for debugging
+#include "../Promise.h"
 #include "../SurfaceFlinger.h"
 #include "ComposerHal.h"
 #include "HWC2.h"
@@ -794,17 +795,21 @@
     return NO_ERROR;
 }
 
-status_t HWComposer::setDisplayBrightness(DisplayId displayId, float brightness) {
-    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
-    const auto error = mDisplayData[displayId].hwcDisplay->setDisplayBrightness(brightness);
-    if (error == hal::Error::UNSUPPORTED) {
-        RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
-    }
-    if (error == hal::Error::BAD_PARAMETER) {
-        RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
-    }
-    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
-    return NO_ERROR;
+std::future<status_t> HWComposer::setDisplayBrightness(DisplayId displayId, float brightness) {
+    RETURN_IF_INVALID_DISPLAY(displayId, promise::yield<status_t>(BAD_INDEX));
+    auto& display = mDisplayData[displayId].hwcDisplay;
+
+    return promise::chain(display->setDisplayBrightness(brightness))
+            .then([displayId](hal::Error error) -> status_t {
+                if (error == hal::Error::UNSUPPORTED) {
+                    RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+                }
+                if (error == hal::Error::BAD_PARAMETER) {
+                    RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
+                }
+                RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
+                return NO_ERROR;
+            });
 }
 
 bool HWComposer::isUsingVrComposer() const {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index cfa2193..b7e9f3a 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -18,6 +18,7 @@
 #define ANDROID_SF_HWCOMPOSER_H
 
 #include <cstdint>
+#include <future>
 #include <memory>
 #include <mutex>
 #include <optional>
@@ -163,7 +164,7 @@
                                                DisplayedFrameStats* outStats) = 0;
 
     // Sets the brightness of a display.
-    virtual status_t setDisplayBrightness(DisplayId displayId, float brightness) = 0;
+    virtual std::future<status_t> setDisplayBrightness(DisplayId displayId, float brightness) = 0;
 
     // Events handling ---------------------------------------------------------
 
@@ -305,7 +306,7 @@
                                               uint8_t componentMask, uint64_t maxFrames) override;
     status_t getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames, uint64_t timestamp,
                                        DisplayedFrameStats* outStats) override;
-    status_t setDisplayBrightness(DisplayId displayId, float brightness) override;
+    std::future<status_t> setDisplayBrightness(DisplayId displayId, float brightness) override;
 
     // Events handling ---------------------------------------------------------
 
diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
index d9aaa05..fe2e406 100644
--- a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
+++ b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
@@ -60,6 +60,12 @@
 PhaseOffsets::PhaseOffsets(const scheduler::RefreshRateConfigs& refreshRateConfigs)
       : PhaseOffsets(getRefreshRatesFromConfigs(refreshRateConfigs),
                      refreshRateConfigs.getCurrentRefreshRate().getFps(),
+                     sysprop::vsync_event_phase_offset_ns(1000000),
+                     sysprop::vsync_sf_event_phase_offset_ns(1000000),
+                     getProperty("debug.sf.early_phase_offset_ns"),
+                     getProperty("debug.sf.early_gl_phase_offset_ns"),
+                     getProperty("debug.sf.early_app_phase_offset_ns"),
+                     getProperty("debug.sf.early_gl_app_phase_offset_ns"),
                      // Below defines the threshold when an offset is considered to be negative,
                      // i.e. targeting for the N+2 vsync instead of N+1. This means that: For offset
                      // < threshold, SF wake up (vsync_duration - offset) before HW vsync. For
@@ -69,8 +75,18 @@
                              .value_or(std::numeric_limits<nsecs_t>::max())) {}
 
 PhaseOffsets::PhaseOffsets(const std::vector<float>& refreshRates, float currentFps,
-                           nsecs_t thresholdForNextVsync)
-      : mThresholdForNextVsync(thresholdForNextVsync),
+                           nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs,
+                           std::optional<nsecs_t> earlySfOffsetNs,
+                           std::optional<nsecs_t> earlyGlSfOffsetNs,
+                           std::optional<nsecs_t> earlyAppOffsetNs,
+                           std::optional<nsecs_t> earlyGlAppOffsetNs, nsecs_t thresholdForNextVsync)
+      : mVSyncPhaseOffsetNs(vsyncPhaseOffsetNs),
+        mSfVSyncPhaseOffsetNs(sfVSyncPhaseOffsetNs),
+        mEarlySfOffsetNs(earlySfOffsetNs),
+        mEarlyGlSfOffsetNs(earlyGlSfOffsetNs),
+        mEarlyAppOffsetNs(earlyAppOffsetNs),
+        mEarlyGlAppOffsetNs(earlyGlAppOffsetNs),
+        mThresholdForNextVsync(thresholdForNextVsync),
         mOffsets(initializeOffsets(refreshRates)),
         mRefreshRateFps(currentFps) {}
 
@@ -106,35 +122,27 @@
 }
 
 PhaseOffsets::Offsets PhaseOffsets::getDefaultOffsets(nsecs_t vsyncDuration) const {
-    const int64_t vsyncPhaseOffsetNs = sysprop::vsync_event_phase_offset_ns(1000000);
-    const int64_t sfVsyncPhaseOffsetNs = sysprop::vsync_sf_event_phase_offset_ns(1000000);
-
-    const auto earlySfOffsetNs = getProperty("debug.sf.early_phase_offset_ns");
-    const auto earlyGlSfOffsetNs = getProperty("debug.sf.early_gl_phase_offset_ns");
-    const auto earlyAppOffsetNs = getProperty("debug.sf.early_app_phase_offset_ns");
-    const auto earlyGlAppOffsetNs = getProperty("debug.sf.early_gl_app_phase_offset_ns");
-
     return {
             {
-                    earlySfOffsetNs.value_or(sfVsyncPhaseOffsetNs) < mThresholdForNextVsync
-                            ? earlySfOffsetNs.value_or(sfVsyncPhaseOffsetNs)
-                            : earlySfOffsetNs.value_or(sfVsyncPhaseOffsetNs) - vsyncDuration,
+                    mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
+                            ? mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs)
+                            : mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - vsyncDuration,
 
-                    earlyAppOffsetNs.value_or(vsyncPhaseOffsetNs),
+                    mEarlyAppOffsetNs.value_or(mVSyncPhaseOffsetNs),
             },
             {
-                    earlyGlSfOffsetNs.value_or(sfVsyncPhaseOffsetNs) < mThresholdForNextVsync
-                            ? earlyGlSfOffsetNs.value_or(sfVsyncPhaseOffsetNs)
-                            : earlyGlSfOffsetNs.value_or(sfVsyncPhaseOffsetNs) - vsyncDuration,
+                    mEarlyGlSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
+                            ? mEarlyGlSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs)
+                            : mEarlyGlSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - vsyncDuration,
 
-                    earlyGlAppOffsetNs.value_or(vsyncPhaseOffsetNs),
+                    mEarlyGlAppOffsetNs.value_or(mVSyncPhaseOffsetNs),
             },
             {
-                    sfVsyncPhaseOffsetNs < mThresholdForNextVsync
-                            ? sfVsyncPhaseOffsetNs
-                            : sfVsyncPhaseOffsetNs - vsyncDuration,
+                    mSfVSyncPhaseOffsetNs < mThresholdForNextVsync
+                            ? mSfVSyncPhaseOffsetNs
+                            : mSfVSyncPhaseOffsetNs - vsyncDuration,
 
-                    vsyncPhaseOffsetNs,
+                    mVSyncPhaseOffsetNs,
             },
     };
 }
diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.h b/services/surfaceflinger/Scheduler/PhaseOffsets.h
index fa8011d..9ec6d56 100644
--- a/services/surfaceflinger/Scheduler/PhaseOffsets.h
+++ b/services/surfaceflinger/Scheduler/PhaseOffsets.h
@@ -69,6 +69,9 @@
 protected:
     // Used for unit tests
     PhaseOffsets(const std::vector<float>& refreshRates, float currentFps,
+                 nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs,
+                 std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGlSfOffsetNs,
+                 std::optional<nsecs_t> earlyAppOffsetNs, std::optional<nsecs_t> earlyGlAppOffsetNs,
                  nsecs_t thresholdForNextVsync);
     std::unordered_map<float, Offsets> initializeOffsets(
             const std::vector<float>& refreshRates) const;
@@ -76,6 +79,12 @@
     Offsets getHighFpsOffsets(nsecs_t vsyncPeriod) const;
     Offsets getPhaseOffsets(float fps, nsecs_t vsyncPeriod) const;
 
+    const nsecs_t mVSyncPhaseOffsetNs;
+    const nsecs_t mSfVSyncPhaseOffsetNs;
+    const std::optional<nsecs_t> mEarlySfOffsetNs;
+    const std::optional<nsecs_t> mEarlyGlSfOffsetNs;
+    const std::optional<nsecs_t> mEarlyAppOffsetNs;
+    const std::optional<nsecs_t> mEarlyGlAppOffsetNs;
     const nsecs_t mThresholdForNextVsync;
     const std::unordered_map<float, Offsets> mOffsets;
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2943499..79ea97b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -108,6 +108,7 @@
 #include "LayerVector.h"
 #include "MonitoredProducer.h"
 #include "NativeWindowSurface.h"
+#include "Promise.h"
 #include "RefreshRateOverlay.h"
 #include "RegionSamplingThread.h"
 #include "Scheduler/DispSync.h"
@@ -1491,14 +1492,15 @@
         return BAD_VALUE;
     }
 
-    return schedule([=]() -> status_t {
+    return promise::chain(schedule([=] {
                if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
                    return getHwComposer().setDisplayBrightness(*displayId, brightness);
                } else {
                    ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
-                   return NAME_NOT_FOUND;
+                   return promise::yield<status_t>(NAME_NOT_FOUND);
                }
-           })
+           }))
+            .then([](std::future<status_t> task) { return task; })
             .get();
 }
 
@@ -1782,11 +1784,10 @@
         return false;
     }
 
-    if (graceTimeMs > 0 && fence->getStatus() == Fence::Status::Unsignaled) {
-        fence->wait(graceTimeMs);
-    }
-
-    return (fence->getStatus() == Fence::Status::Unsignaled);
+    const status_t status = fence->wait(graceTimeMs);
+    // This is the same as Fence::Status::Unsignaled, but it saves a getStatus() call,
+    // which calls wait(0) again internally
+    return status == -ETIME;
 }
 
 nsecs_t SurfaceFlinger::previousFramePresentTime() NO_THREAD_SAFETY_ANALYSIS {
@@ -1812,184 +1813,188 @@
     ATRACE_CALL();
     switch (what) {
         case MessageQueue::INVALIDATE: {
-            const nsecs_t frameStart = systemTime();
-            // calculate the expected present time once and use the cached
-            // value throughout this frame to make sure all layers are
-            // seeing this same value.
-            const nsecs_t lastExpectedPresentTime = mExpectedPresentTime.load();
-            mExpectedPresentTime = expectedVSyncTime;
-
-            // When Backpressure propagation is enabled we want to give a small grace period
-            // for the present fence to fire instead of just giving up on this frame to handle cases
-            // where present fence is just about to get signaled.
-            const int graceTimeForPresentFenceMs =
-                    (mPropagateBackpressure &&
-                     (mPropagateBackpressureClientComposition || !mHadClientComposition))
-                    ? 1
-                    : 0;
-
-            // Pending frames may trigger backpressure propagation.
-            const TracedOrdinal<bool> framePending = {"PrevFramePending",
-                                                      previousFramePending(
-                                                              graceTimeForPresentFenceMs)};
-
-            // Frame missed counts for metrics tracking.
-            // A frame is missed if the prior frame is still pending. If no longer pending,
-            // then we still count the frame as missed if the predicted present time
-            // was further in the past than when the fence actually fired.
-
-            // Add some slop to correct for drift. This should generally be
-            // smaller than a typical frame duration, but should not be so small
-            // that it reports reasonable drift as a missed frame.
-            DisplayStatInfo stats;
-            mScheduler->getDisplayStatInfo(&stats);
-            const nsecs_t frameMissedSlop = stats.vsyncPeriod / 2;
-            const nsecs_t previousPresentTime = previousFramePresentTime();
-            const TracedOrdinal<bool> frameMissed =
-                    {"PrevFrameMissed",
-                     framePending ||
-                             (previousPresentTime >= 0 &&
-                              (lastExpectedPresentTime < previousPresentTime - frameMissedSlop))};
-            const TracedOrdinal<bool> hwcFrameMissed = {"PrevHwcFrameMissed",
-                                                        mHadDeviceComposition && frameMissed};
-            const TracedOrdinal<bool> gpuFrameMissed = {"PrevGpuFrameMissed",
-                                                        mHadClientComposition && frameMissed};
-
-            if (frameMissed) {
-                mFrameMissedCount++;
-                mTimeStats->incrementMissedFrames();
-                if (mMissedFrameJankCount == 0) {
-                    mMissedFrameJankStart = systemTime();
-                }
-                mMissedFrameJankCount++;
-            }
-
-            if (hwcFrameMissed) {
-                mHwcFrameMissedCount++;
-            }
-
-            if (gpuFrameMissed) {
-                mGpuFrameMissedCount++;
-            }
-
-            // If we are in the middle of a config change and the fence hasn't
-            // fired yet just wait for the next invalidate
-            if (mSetActiveConfigPending) {
-                if (framePending) {
-                    mEventQueue->invalidate();
-                    break;
-                }
-
-                // We received the present fence from the HWC, so we assume it successfully updated
-                // the config, hence we update SF.
-                mSetActiveConfigPending = false;
-                setActiveConfigInternal();
-            }
-
-            if (framePending && mPropagateBackpressure) {
-                if ((hwcFrameMissed && !gpuFrameMissed) ||
-                    mPropagateBackpressureClientComposition) {
-                    signalLayerUpdate();
-                    break;
-                }
-            }
-
-            // Our jank window is always at least 100ms since we missed a
-            // frame...
-            static constexpr nsecs_t kMinJankyDuration =
-                    std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count();
-            // ...but if it's larger than 1s then we missed the trace cutoff.
-            static constexpr nsecs_t kMaxJankyDuration =
-                    std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
-            // If we're in a user build then don't push any atoms
-            if (!mIsUserBuild && mMissedFrameJankCount > 0) {
-                const auto displayDevice = getDefaultDisplayDeviceLocked();
-                // Only report jank when the display is on, as displays in DOZE
-                // power mode may operate at a different frame rate than is
-                // reported in their config, which causes noticeable (but less
-                // severe) jank.
-                if (displayDevice && displayDevice->getPowerMode() == hal::PowerMode::ON) {
-                    const nsecs_t currentTime = systemTime();
-                    const nsecs_t jankDuration = currentTime - mMissedFrameJankStart;
-                    if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) {
-                        ATRACE_NAME("Jank detected");
-                        ALOGD("Detected janky event. Missed frames: %d", mMissedFrameJankCount);
-                        const int32_t jankyDurationMillis = jankDuration / (1000 * 1000);
-                        android::util::stats_write(android::util::DISPLAY_JANK_REPORTED,
-                                                   jankyDurationMillis, mMissedFrameJankCount);
-                    }
-
-                    // We either reported a jank event or we missed the trace
-                    // window, so clear counters here.
-                    if (jankDuration > kMinJankyDuration) {
-                        mMissedFrameJankCount = 0;
-                        mMissedFrameJankStart = 0;
-                    }
-                }
-            }
-
-            // Now that we're going to make it to the handleMessageTransaction()
-            // call below it's safe to call updateVrFlinger(), which will
-            // potentially trigger a display handoff.
-            updateVrFlinger();
-
-            if (mTracingEnabledChanged) {
-                mTracingEnabled = mTracing.isEnabled();
-                mTracingEnabledChanged = false;
-            }
-
-            bool refreshNeeded;
-            {
-                ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
-
-                refreshNeeded = handleMessageTransaction();
-                refreshNeeded |= handleMessageInvalidate();
-                if (mTracingEnabled) {
-                    mAddCompositionStateToTrace =
-                            mTracing.flagIsSetLocked(SurfaceTracing::TRACE_COMPOSITION);
-                    if (mVisibleRegionsDirty && !mAddCompositionStateToTrace) {
-                        mTracing.notifyLocked("visibleRegionsDirty");
-                    }
-                }
-            }
-
-            // Layers need to get updated (in the previous line) before we can use them for
-            // choosing the refresh rate.
-            // Hold mStateLock as chooseRefreshRateForContent promotes wp<Layer> to sp<Layer>
-            // and may eventually call to ~Layer() if it holds the last reference
-            {
-                Mutex::Autolock _l(mStateLock);
-                mScheduler->chooseRefreshRateForContent();
-            }
-
-            performSetActiveConfig();
-
-            updateCursorAsync();
-            updateInputFlinger();
-
-            refreshNeeded |= mRepaintEverything;
-            if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) {
-                // Signal a refresh if a transaction modified the window state,
-                // a new buffer was latched, or if HWC has requested a full
-                // repaint
-                if (mFrameStartTime <= 0) {
-                    // We should only use the time of the first invalidate
-                    // message that signals a refresh as the beginning of the
-                    // frame. Otherwise the real frame time will be
-                    // underestimated.
-                    mFrameStartTime = frameStart;
-                }
-                signalRefresh();
-            }
+            onMessageInvalidate(expectedVSyncTime);
             break;
         }
         case MessageQueue::REFRESH: {
-            handleMessageRefresh();
+            onMessageRefresh();
             break;
         }
     }
 }
 
+void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) NO_THREAD_SAFETY_ANALYSIS {
+    ATRACE_CALL();
+
+    const nsecs_t frameStart = systemTime();
+    // calculate the expected present time once and use the cached
+    // value throughout this frame to make sure all layers are
+    // seeing this same value.
+    const nsecs_t lastExpectedPresentTime = mExpectedPresentTime.load();
+    mExpectedPresentTime = expectedVSyncTime;
+
+    // When Backpressure propagation is enabled we want to give a small grace period
+    // for the present fence to fire instead of just giving up on this frame to handle cases
+    // where present fence is just about to get signaled.
+    const int graceTimeForPresentFenceMs =
+            (mPropagateBackpressure &&
+             (mPropagateBackpressureClientComposition || !mHadClientComposition))
+            ? 1
+            : 0;
+
+    // Pending frames may trigger backpressure propagation.
+    const TracedOrdinal<bool> framePending = {"PrevFramePending",
+                                              previousFramePending(graceTimeForPresentFenceMs)};
+
+    // Frame missed counts for metrics tracking.
+    // A frame is missed if the prior frame is still pending. If no longer pending,
+    // then we still count the frame as missed if the predicted present time
+    // was further in the past than when the fence actually fired.
+
+    // Add some slop to correct for drift. This should generally be
+    // smaller than a typical frame duration, but should not be so small
+    // that it reports reasonable drift as a missed frame.
+    DisplayStatInfo stats;
+    mScheduler->getDisplayStatInfo(&stats);
+    const nsecs_t frameMissedSlop = stats.vsyncPeriod / 2;
+    const nsecs_t previousPresentTime = previousFramePresentTime();
+    const TracedOrdinal<bool> frameMissed = {"PrevFrameMissed",
+                                             framePending ||
+                                                     (previousPresentTime >= 0 &&
+                                                      (lastExpectedPresentTime <
+                                                       previousPresentTime - frameMissedSlop))};
+    const TracedOrdinal<bool> hwcFrameMissed = {"PrevHwcFrameMissed",
+                                                mHadDeviceComposition && frameMissed};
+    const TracedOrdinal<bool> gpuFrameMissed = {"PrevGpuFrameMissed",
+                                                mHadClientComposition && frameMissed};
+
+    if (frameMissed) {
+        mFrameMissedCount++;
+        mTimeStats->incrementMissedFrames();
+        if (mMissedFrameJankCount == 0) {
+            mMissedFrameJankStart = systemTime();
+        }
+        mMissedFrameJankCount++;
+    }
+
+    if (hwcFrameMissed) {
+        mHwcFrameMissedCount++;
+    }
+
+    if (gpuFrameMissed) {
+        mGpuFrameMissedCount++;
+    }
+
+    // If we are in the middle of a config change and the fence hasn't
+    // fired yet just wait for the next invalidate
+    if (mSetActiveConfigPending) {
+        if (framePending) {
+            mEventQueue->invalidate();
+            return;
+        }
+
+        // We received the present fence from the HWC, so we assume it successfully updated
+        // the config, hence we update SF.
+        mSetActiveConfigPending = false;
+        setActiveConfigInternal();
+    }
+
+    if (framePending && mPropagateBackpressure) {
+        if ((hwcFrameMissed && !gpuFrameMissed) || mPropagateBackpressureClientComposition) {
+            signalLayerUpdate();
+            return;
+        }
+    }
+
+    // Our jank window is always at least 100ms since we missed a
+    // frame...
+    static constexpr nsecs_t kMinJankyDuration =
+            std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count();
+    // ...but if it's larger than 1s then we missed the trace cutoff.
+    static constexpr nsecs_t kMaxJankyDuration =
+            std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
+    // If we're in a user build then don't push any atoms
+    if (!mIsUserBuild && mMissedFrameJankCount > 0) {
+        const auto displayDevice = getDefaultDisplayDeviceLocked();
+        // Only report jank when the display is on, as displays in DOZE
+        // power mode may operate at a different frame rate than is
+        // reported in their config, which causes noticeable (but less
+        // severe) jank.
+        if (displayDevice && displayDevice->getPowerMode() == hal::PowerMode::ON) {
+            const nsecs_t currentTime = systemTime();
+            const nsecs_t jankDuration = currentTime - mMissedFrameJankStart;
+            if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) {
+                ATRACE_NAME("Jank detected");
+                ALOGD("Detected janky event. Missed frames: %d", mMissedFrameJankCount);
+                const int32_t jankyDurationMillis = jankDuration / (1000 * 1000);
+                android::util::stats_write(android::util::DISPLAY_JANK_REPORTED,
+                                           jankyDurationMillis, mMissedFrameJankCount);
+            }
+
+            // We either reported a jank event or we missed the trace
+            // window, so clear counters here.
+            if (jankDuration > kMinJankyDuration) {
+                mMissedFrameJankCount = 0;
+                mMissedFrameJankStart = 0;
+            }
+        }
+    }
+
+    // Now that we're going to make it to the handleMessageTransaction()
+    // call below it's safe to call updateVrFlinger(), which will
+    // potentially trigger a display handoff.
+    updateVrFlinger();
+
+    if (mTracingEnabledChanged) {
+        mTracingEnabled = mTracing.isEnabled();
+        mTracingEnabledChanged = false;
+    }
+
+    bool refreshNeeded;
+    {
+        ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
+
+        refreshNeeded = handleMessageTransaction();
+        refreshNeeded |= handleMessageInvalidate();
+        if (mTracingEnabled) {
+            mAddCompositionStateToTrace =
+                    mTracing.flagIsSetLocked(SurfaceTracing::TRACE_COMPOSITION);
+            if (mVisibleRegionsDirty && !mAddCompositionStateToTrace) {
+                mTracing.notifyLocked("visibleRegionsDirty");
+            }
+        }
+    }
+
+    // Layers need to get updated (in the previous line) before we can use them for
+    // choosing the refresh rate.
+    // Hold mStateLock as chooseRefreshRateForContent promotes wp<Layer> to sp<Layer>
+    // and may eventually call to ~Layer() if it holds the last reference
+    {
+        Mutex::Autolock _l(mStateLock);
+        mScheduler->chooseRefreshRateForContent();
+    }
+
+    performSetActiveConfig();
+
+    updateCursorAsync();
+    updateInputFlinger();
+
+    refreshNeeded |= mRepaintEverything;
+    if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) {
+        // Signal a refresh if a transaction modified the window state,
+        // a new buffer was latched, or if HWC has requested a full
+        // repaint
+        if (mFrameStartTime <= 0) {
+            // We should only use the time of the first invalidate
+            // message that signals a refresh as the beginning of the
+            // frame. Otherwise the real frame time will be
+            // underestimated.
+            mFrameStartTime = frameStart;
+        }
+        signalRefresh();
+    }
+}
+
 bool SurfaceFlinger::handleMessageTransaction() {
     ATRACE_CALL();
     uint32_t transactionFlags = peekTransactionFlags();
@@ -2012,7 +2017,7 @@
     return runHandleTransaction;
 }
 
-void SurfaceFlinger::handleMessageRefresh() {
+void SurfaceFlinger::onMessageRefresh() {
     ATRACE_CALL();
 
     mRefreshPending = false;
@@ -2110,7 +2115,6 @@
     }
 }
 
-
 bool SurfaceFlinger::handleMessageInvalidate() {
     ATRACE_CALL();
     bool refreshNeeded = handlePageFlip();
@@ -3416,18 +3420,26 @@
                                                   : Scheduler::TransactionStart::NORMAL;
         setTransactionFlags(transactionFlags, start);
 
-        // if this is a synchronous transaction, wait for it to take effect
-        // before returning.
-        if (flags & eSynchronous) {
-            mTransactionPending = true;
-        }
         if (flags & eAnimation) {
             mAnimTransactionPending = true;
         }
-        if (mPendingInputWindowCommands.syncInputWindows) {
+
+        // if this is a synchronous transaction, wait for it to take effect
+        // before returning.
+        const bool synchronous = flags & eSynchronous;
+        const bool syncInput = inputWindowCommands.syncInputWindows;
+        if (!synchronous && !syncInput) {
+            return;
+        }
+
+        if (synchronous) {
+            mTransactionPending = true;
+        }
+        if (syncInput) {
             mPendingSyncInputWindows = true;
         }
 
+
         // applyTransactionState can be called by either the main SF thread or by
         // another process through setTransactionState.  While a given process may wish
         // to wait on synchronous transactions, the main SF thread should never
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b65e4f6..294a52f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -580,14 +580,20 @@
             const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy)
             EXCLUDES(mStateLock);
 
+    // Handle the INVALIDATE message queue event, latching new buffers and applying
+    // incoming transactions
+    void onMessageInvalidate(nsecs_t expectedVSyncTime);
+
     // Returns whether the transaction actually modified any state
     bool handleMessageTransaction();
 
+    // Handle the REFRESH message queue event, sending the current frame down to RenderEngine and
+    // the Composer HAL for presentation
+    void onMessageRefresh();
+
     // Returns whether a new buffer has been latched (see handlePageFlip())
     bool handleMessageInvalidate();
 
-    void handleMessageRefresh();
-
     void handleTransaction(uint32_t transactionFlags);
     void handleTransactionLocked(uint32_t transactionFlags) REQUIRES(mStateLock);
 
diff --git a/services/surfaceflinger/TracedOrdinal.h b/services/surfaceflinger/TracedOrdinal.h
index c145a39..4e7f67d 100644
--- a/services/surfaceflinger/TracedOrdinal.h
+++ b/services/surfaceflinger/TracedOrdinal.h
@@ -16,10 +16,13 @@
 
 #pragma once
 #include <android-base/stringprintf.h>
+#include <cutils/compiler.h>
 #include <utils/Trace.h>
 #include <cmath>
 #include <string>
 
+namespace android {
+
 template <typename T>
 class TracedOrdinal {
 public:
@@ -27,9 +30,8 @@
                   "Type is not supported. Please test it with systrace before adding "
                   "it to the list.");
 
-    TracedOrdinal(const std::string& name, T initialValue)
-          : mName(name),
-            mNameNegative(android::base::StringPrintf("%sNegative", name.c_str())),
+    TracedOrdinal(std::string name, T initialValue)
+          : mName(std::move(name)),
             mHasGoneNegative(std::signbit(initialValue)),
             mData(initialValue) {
         trace();
@@ -46,6 +48,14 @@
 
 private:
     void trace() {
+        if (CC_LIKELY(!ATRACE_ENABLED())) {
+            return;
+        }
+
+        if (mNameNegative.empty()) {
+            mNameNegative = base::StringPrintf("%sNegative", mName.c_str());
+        }
+
         if (!std::signbit(mData)) {
             ATRACE_INT64(mName.c_str(), int64_t(mData));
             if (mHasGoneNegative) {
@@ -58,7 +68,9 @@
     }
 
     const std::string mName;
-    const std::string mNameNegative;
+    std::string mNameNegative;
     bool mHasGoneNegative;
     T mData;
 };
+
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/PhaseOffsetsTest.cpp b/services/surfaceflinger/tests/unittests/PhaseOffsetsTest.cpp
index ce5993a..0b74682 100644
--- a/services/surfaceflinger/tests/unittests/PhaseOffsetsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/PhaseOffsetsTest.cpp
@@ -145,7 +145,9 @@
 
 class TestablePhaseOffsets : public impl::PhaseOffsets {
 public:
-    TestablePhaseOffsets() : impl::PhaseOffsets({60.0f, 90.0f}, 60.0f, 10'000'000) {}
+    TestablePhaseOffsets()
+          : impl::PhaseOffsets({60.0f, 90.0f}, 60.0f, 1'000'000, 1'000'000, {}, {}, {}, {},
+                               10'000'000) {}
 };
 
 class PhaseOffsetsTest : public testing::Test {
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
index 67d3e1c..dade9fc 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
@@ -84,15 +84,15 @@
     MOCK_METHOD2(validate, hal::Error(uint32_t*, uint32_t*));
     MOCK_METHOD4(presentOrValidate,
                  hal::Error(uint32_t*, uint32_t*, android::sp<android::Fence>*, uint32_t*));
-    MOCK_CONST_METHOD1(setDisplayBrightness, hal::Error(float));
+    MOCK_METHOD1(setDisplayBrightness, std::future<hal::Error>(float));
     MOCK_CONST_METHOD1(getDisplayVsyncPeriod, hal::Error(nsecs_t*));
     MOCK_METHOD3(setActiveConfigWithConstraints,
                  hal::Error(const std::shared_ptr<const HWC2::Display::Config>&,
                             const hal::VsyncPeriodChangeConstraints&,
                             hal::VsyncPeriodChangeTimeline*));
-    MOCK_CONST_METHOD1(setAutoLowLatencyMode, hal::Error(bool on));
+    MOCK_METHOD1(setAutoLowLatencyMode, hal::Error(bool on));
     MOCK_CONST_METHOD1(getSupportedContentTypes, hal::Error(std::vector<hal::ContentType>*));
-    MOCK_CONST_METHOD1(setContentType, hal::Error(hal::ContentType));
+    MOCK_METHOD1(setContentType, hal::Error(hal::ContentType));
     MOCK_CONST_METHOD1(getConnectionType, hal::Error(android::DisplayConnectionType*));
     MOCK_CONST_METHOD0(isVsyncPeriodSwitchSupported, bool());
 };