Adding setColor, setColorAlpha, and setColorDataspace to
BufferStateLayer

Bug: 122326454
Test: atest CtsViewTestCases:android.view.cts.ASurfaceControlTests
Change-Id: If426541757a58d0fc63d744270bbae1b022f105a
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 2132f59..83b9585 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -20,6 +20,7 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #include "BufferStateLayer.h"
+#include "ColorLayer.h"
 
 #include "TimeStats/TimeStats.h"
 
@@ -302,6 +303,48 @@
     return true;
 }
 
+bool BufferStateLayer::setColor(const half3& color) {
+    // create color layer if one does not yet exist
+    if (!mCurrentState.bgColorLayer) {
+        uint32_t flags = ISurfaceComposerClient::eFXSurfaceColor;
+        const String8& name = mName + "BackgroundColorLayer";
+        mCurrentState.bgColorLayer =
+                new ColorLayer(LayerCreationArgs(mFlinger.get(), nullptr, name, 0, 0, flags));
+
+        // add to child list
+        addChild(mCurrentState.bgColorLayer);
+        mFlinger->mLayersAdded = true;
+        // set up SF to handle added color layer
+        if (isRemovedFromCurrentState()) {
+            mCurrentState.bgColorLayer->onRemovedFromCurrentState();
+        }
+        mFlinger->setTransactionFlags(eTransactionNeeded);
+    }
+
+    mCurrentState.bgColorLayer->setColor(color);
+    mCurrentState.bgColorLayer->setLayer(std::numeric_limits<int32_t>::min());
+
+    return true;
+}
+
+bool BufferStateLayer::setColorAlpha(float alpha) {
+    if (!mCurrentState.bgColorLayer) {
+        ALOGE("Attempting to set color alpha on a buffer state layer with no background color");
+        return false;
+    }
+    mCurrentState.bgColorLayer->setAlpha(alpha);
+    return true;
+}
+
+bool BufferStateLayer::setColorDataspace(ui::Dataspace dataspace) {
+    if (!mCurrentState.bgColorLayer) {
+        ALOGE("Attempting to set color dataspace on a buffer state layer with no background color");
+        return false;
+    }
+    mCurrentState.bgColorLayer->setDataspace(dataspace);
+    return true;
+}
+
 Rect BufferStateLayer::getBufferSize(const State& s) const {
     // for buffer state layers we use the display frame size as the buffer size.
     if (getActiveWidth(s) < UINT32_MAX && getActiveHeight(s) < UINT32_MAX) {
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 3f891d3..64d6a85 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -82,6 +82,9 @@
     }
     bool setCrop_legacy(const Rect& /*crop*/, bool /*immediate*/) override { return false; }
     bool setOverrideScalingMode(int32_t /*overrideScalingMode*/) override { return false; }
+    bool setColor(const half3& color) override;
+    bool setColorAlpha(float alpha) override;
+    bool setColorDataspace(ui::Dataspace dataspace) override;
     void deferTransactionUntil_legacy(const sp<IBinder>& /*barrierHandle*/,
                                       uint64_t /*frameNumber*/) override {}
     void deferTransactionUntil_legacy(const sp<Layer>& /*barrierLayer*/,
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index d30961a..b3979e2 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -201,6 +201,10 @@
         mat4 colorTransform;
         bool hasColorTransform;
 
+        // pointer to background color layer that, if set, appears below the buffer state layer
+        // and the buffer state layer's children.  Z order will be set to
+        // INT_MIN
+        sp<Layer> bgColorLayer;
         ui::Dataspace colorDataspace; // The dataspace of the background color layer
 
         // The deque of callback handles for this frame. The back of the deque contains the most
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 72c75bb..56d3bd4 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -1330,6 +1330,92 @@
     getScreenCapture()->expectColor(Rect(16, 16, 48, 48), Color::RED);
 }
 
+TEST_P(LayerRenderTypeTransactionTest, SetColorAlpha_Color_NoEffect) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(
+            layer = createLayer("test", 0, 0, ISurfaceComposerClient::eFXSurfaceColor));
+
+    half3 color;
+    color.r = 1.0f;
+    color.g = 0.0f;
+    color.b = 0.0f;
+    Transaction()
+            .setCrop_legacy(layer, Rect(0, 0, 32, 32))
+            .setAlpha(layer, 1.0f)
+            .setColor(layer, color)
+            .setColorAlpha(layer, 0.5f)
+            .apply();
+
+    screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
+}
+
+TEST_P(LayerRenderTypeTransactionTest, SetColorAlpha_BufferQueue_NoEffect) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
+    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
+
+    Transaction().setAlpha(layer, 1.0f).setColorAlpha(layer, 0.5f).apply();
+
+    screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
+}
+
+TEST_P(LayerRenderTypeTransactionTest, SetColorAlpha_BufferState_ColorLayer) {
+    sp<SurfaceControl> bgLayer;
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(bgLayer = createLayer("test bg", 32, 32));
+    ASSERT_NO_FATAL_FAILURE(
+            layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
+
+    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bgLayer, Color::RED, 32, 32));
+
+    // create color layer
+    half3 color;
+    color.r = 0.0f;
+    color.g = 1.0f;
+    color.b = 0.0f;
+    Transaction().setFrame(layer, Rect(0, 0, 32, 32)).setColor(layer, color).apply();
+
+    {
+        SCOPED_TRACE("before alpha");
+        auto shot = screenshot();
+        shot->expectColor(Rect(0, 0, 32, 32), Color::GREEN);
+        shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
+    }
+
+    // apply alpha
+    Transaction().setAlpha(layer, 0.0f).apply();
+    {
+        SCOPED_TRACE("set alpha");
+        auto shot = screenshot();
+        shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
+        shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
+    }
+}
+
+TEST_P(LayerRenderTypeTransactionTest, SetColorAlpha_BufferState_NoColorLayer) {
+    sp<SurfaceControl> bgLayer;
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(bgLayer = createLayer("test bg", 32, 32));
+    ASSERT_NO_FATAL_FAILURE(
+            layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
+
+    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bgLayer, Color::RED, 32, 32));
+
+    {
+        SCOPED_TRACE("before alpha");
+        screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
+    }
+
+    // setting alpha without creating color layer should have no effect
+    Transaction().setFrame(layer, Rect(0, 0, 32, 32)).setAlpha(layer, 0.5f).apply();
+    {
+        SCOPED_TRACE("alpha");
+        auto shot = screenshot();
+        shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
+        shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
+    }
+}
+
 void LayerRenderTypeTransactionTest::setAlphaBasicHelper(uint32_t layerType) {
     sp<SurfaceControl> layer1;
     sp<SurfaceControl> layer2;
@@ -1481,6 +1567,77 @@
     }
 }
 
+TEST_P(LayerRenderTypeTransactionTest, SetBackgroundColor_BufferState_NoPriorColor) {
+    sp<SurfaceControl> bufferQueueLayer;
+    sp<SurfaceControl> bufferStateLayer;
+    ASSERT_NO_FATAL_FAILURE(bufferQueueLayer = createLayer("test bg", 32, 32));
+    ASSERT_NO_FATAL_FAILURE(
+            bufferStateLayer =
+                    createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
+
+    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferQueueLayer, Color::RED, 32, 32));
+
+    {
+        SCOPED_TRACE("default color");
+        screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
+    }
+
+    half3 color;
+    color.r = 0.0f;
+    color.g = 1.0f;
+    color.b = 0.0f;
+    Transaction()
+            .setFrame(bufferStateLayer, Rect(0, 0, 32, 32))
+            .setLayer(bufferStateLayer, mLayerZBase + 1)
+            .setColor(bufferStateLayer, color)
+            .apply();
+
+    {
+        SCOPED_TRACE("set color");
+        auto shot = screenshot();
+        shot->expectColor(Rect(0, 0, 32, 32), Color::GREEN);
+        shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
+    }
+}
+
+TEST_P(LayerRenderTypeTransactionTest, SetBackgroundColor_BufferState_PriorColor) {
+    sp<SurfaceControl> bufferQueueLayer;
+    sp<SurfaceControl> bufferStateLayer;
+    ASSERT_NO_FATAL_FAILURE(bufferQueueLayer = createLayer("test bg", 32, 32));
+    ASSERT_NO_FATAL_FAILURE(
+            bufferStateLayer =
+                    createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
+
+    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferQueueLayer, Color::RED, 32, 32));
+
+    half3 color;
+    color.r = 0.0f;
+    color.g = 1.0f;
+    color.b = 0.0f;
+    Transaction()
+            .setFrame(bufferStateLayer, Rect(0, 0, 32, 32))
+            .setLayer(bufferStateLayer, mLayerZBase + 1)
+            .setColor(bufferStateLayer, color)
+            .apply();
+    {
+        SCOPED_TRACE("default color");
+        auto shot = screenshot();
+        shot->expectColor(Rect(0, 0, 32, 32), Color::GREEN);
+        shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
+    }
+
+    color.r = 0.0f;
+    color.g = 0.0f;
+    color.b = 1.0f;
+    Transaction().setColor(bufferStateLayer, color).apply();
+    {
+        SCOPED_TRACE("new color");
+        auto shot = screenshot();
+        shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE);
+        shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
+    }
+}
+
 TEST_P(LayerRenderTypeTransactionTest, SetColorClamped) {
     sp<SurfaceControl> colorLayer;
     ASSERT_NO_FATAL_FAILURE(colorLayer =
@@ -2334,6 +2491,71 @@
     shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
 }
 
+TEST_P(LayerRenderTypeTransactionTest, SetColorDataspace_ColorLayer_NoEffect) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(
+            layer = createLayer("test", 0, 0, ISurfaceComposerClient::eFXSurfaceColor));
+    half3 color;
+    color.r = 1.0f;
+    color.g = 0.0f;
+    color.b = 0.0f;
+    Transaction()
+            .setCrop_legacy(layer, Rect(0, 0, 32, 32))
+            .setColor(layer, color)
+            .setDataspace(layer, ui::Dataspace::UNKNOWN)
+            .setColorDataspace(layer, ui::Dataspace::BT2020_ITU)
+            .apply();
+
+    screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
+}
+
+TEST_P(LayerRenderTypeTransactionTest, SetColorDataspace_BufferQueue_NoEffect) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
+    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
+
+    Transaction()
+            .setDataspace(layer, ui::Dataspace::UNKNOWN)
+            .setColorDataspace(layer, ui::Dataspace::BT2020_ITU)
+            .apply();
+
+    screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
+}
+
+TEST_P(LayerRenderTypeTransactionTest, SetColorDataspace_BufferState_ColorLayer) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(
+            layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
+
+    half3 color;
+    color.r = 1.0f;
+    color.g = 0.0f;
+    color.b = 0.0f;
+    Transaction()
+            .setFrame(layer, Rect(0, 0, 32, 32))
+            .setColor(layer, color)
+            .setColorDataspace(layer, ui::Dataspace::BT2020_ITU)
+            .apply();
+    auto shot = screenshot();
+    shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
+    shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
+}
+
+TEST_P(LayerRenderTypeTransactionTest, SetColorDataspace_BufferState_NoColorLayer) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(
+            layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
+    ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+
+    Transaction()
+            .setFrame(layer, Rect(0, 0, 32, 32))
+            .setDataspace(layer, ui::Dataspace::UNKNOWN)
+            .setColorDataspace(layer, ui::Dataspace::DCI_P3)
+            .apply();
+
+    screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
+}
+
 TEST_P(LayerRenderTypeTransactionTest, SetDataspaceBasic_BufferState) {
     sp<SurfaceControl> layer;
     ASSERT_NO_FATAL_FAILURE(