SurfaceFlinger: Emit callbacks for non-buffer layer transactions

Ensure we emit callbacks if the transaction contains only non-buffer
layer state changes.

Test: atest SurfaceFlinger_test
Fixes: 205183085
Change-Id: I56bf0dcaff4312628fe2cd1d0b93db520518ec54
diff --git a/services/surfaceflinger/tests/LayerCallback_test.cpp b/services/surfaceflinger/tests/LayerCallback_test.cpp
index 91a5b52..7beba15 100644
--- a/services/surfaceflinger/tests/LayerCallback_test.cpp
+++ b/services/surfaceflinger/tests/LayerCallback_test.cpp
@@ -1067,7 +1067,7 @@
 }
 
 // b202394221
-TEST_F(LayerCallbackTest, DISABLED_NonBufferLayerStateChanges) {
+TEST_F(LayerCallbackTest, NonBufferLayerStateChanges) {
     sp<SurfaceControl> layer;
     ASSERT_NO_FATAL_FAILURE(layer = createColorLayer("ColorLayer", Color::RED));
 
@@ -1085,4 +1085,47 @@
     EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
 }
 
+class TimedCallbackHelper {
+public:
+    static void function(void* callbackContext, nsecs_t, const sp<Fence>&,
+                         const std::vector<SurfaceControlStats>&) {
+        if (!callbackContext) {
+            ALOGE("failed to get callback context");
+        }
+        TimedCallbackHelper* helper = static_cast<TimedCallbackHelper*>(callbackContext);
+        std::lock_guard lock(helper->mMutex);
+        helper->mInvokedTime = systemTime();
+        helper->mCv.notify_all();
+    }
+
+    void waitForCallback() {
+        std::unique_lock lock(mMutex);
+        ASSERT_TRUE(mCv.wait_for(lock, std::chrono::seconds(3), [&] { return mInvokedTime != -1; }))
+                << "did not receive callback";
+    }
+    void* getContext() { return static_cast<void*>(this); }
+
+    std::mutex mMutex;
+    std::condition_variable mCv;
+    nsecs_t mInvokedTime = -1;
+};
+
+TEST_F(LayerCallbackTest, EmptyTransactionCallbackOrder) {
+    TimedCallbackHelper onCommitCallback;
+    TimedCallbackHelper onCompleteCallback;
+
+    // Add transaction callback before on commit callback
+    Transaction()
+            .addTransactionCompletedCallback(onCompleteCallback.function,
+                                             onCompleteCallback.getContext())
+            .addTransactionCommittedCallback(onCommitCallback.function,
+                                             onCommitCallback.getContext())
+            .apply();
+
+    EXPECT_NO_FATAL_FAILURE(onCompleteCallback.waitForCallback());
+    EXPECT_NO_FATAL_FAILURE(onCommitCallback.waitForCallback());
+    // verify we get the oncomplete at the same time or after the oncommit callback.
+    EXPECT_GE(onCompleteCallback.mInvokedTime, onCommitCallback.mInvokedTime);
+}
+
 } // namespace android