Merge changes I91a4be00,I07f4d4ab

* changes:
  SurfaceFlinger: Add ChildColorLayerTest with zero alpha
  SurfaceFlinger: Correct DetachChildren case in SFFakeHwc_test
diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
index 9b31985..070bd51 100644
--- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
+++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
@@ -1095,7 +1095,7 @@
     EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
 }
 
-TEST_F(ChildLayerTest, DetachChildren) {
+TEST_F(ChildLayerTest, DetachChildrenSameClient) {
     {
         TransactionScope ts(*sFakeComposer);
         ts.show(mChild);
@@ -1111,14 +1111,59 @@
 
     {
         TransactionScope ts(*sFakeComposer);
+        ts.setPosition(mFGSurfaceControl, 0, 0);
         ts.detachChildren(mFGSurfaceControl);
     }
 
     {
         TransactionScope ts(*sFakeComposer);
+        ts.setPosition(mFGSurfaceControl, 64, 64);
         ts.hide(mChild);
     }
 
+    std::vector<RenderState> refFrame(2);
+    refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
+    refFrame[FG_LAYER] = mBaseFrame[FG_LAYER];
+
+    EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
+}
+
+TEST_F(ChildLayerTest, DetachChildrenDifferentClient) {
+    sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient;
+    sp<SurfaceControl> childNewClient =
+            newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10,
+                                             PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
+    ASSERT_TRUE(childNewClient != nullptr);
+    ASSERT_TRUE(childNewClient->isValid());
+    fillSurfaceRGBA8(childNewClient, LIGHT_GRAY);
+
+    {
+        TransactionScope ts(*sFakeComposer);
+        ts.hide(mChild);
+        ts.show(childNewClient);
+        ts.setPosition(childNewClient, 10, 10);
+        ts.setPosition(mFGSurfaceControl, 64, 64);
+    }
+
+    auto referenceFrame = mBaseFrame;
+    referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64};
+    referenceFrame[CHILD_LAYER].mDisplayFrame =
+            hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10};
+    EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
+
+    {
+        TransactionScope ts(*sFakeComposer);
+        ts.detachChildren(mFGSurfaceControl);
+        ts.setPosition(mFGSurfaceControl, 0, 0);
+    }
+
+    {
+        TransactionScope ts(*sFakeComposer);
+        ts.setPosition(mFGSurfaceControl, 64, 64);
+        ts.setPosition(childNewClient, 0, 0);
+        ts.hide(childNewClient);
+    }
+
     // Nothing should have changed. The child control becomes a no-op
     // zombie on detach. See comments for detachChildren in the
     // SurfaceControl.h file.
@@ -1217,6 +1262,81 @@
     sFakeComposer->runVSyncAndWait();
 }
 
+class ChildColorLayerTest : public ChildLayerTest {
+protected:
+    void SetUp() override {
+        TransactionTest::SetUp();
+        mChild = mComposerClient->createSurface(String8("Child surface"), 10, 10,
+                                                PIXEL_FORMAT_RGBA_8888,
+                                                ISurfaceComposerClient::eFXSurfaceColor,
+                                                mFGSurfaceControl.get());
+        {
+            TransactionScope ts(*sFakeComposer);
+            ts.setColor(mChild,
+                        {LIGHT_GRAY.r / 255.0f, LIGHT_GRAY.g / 255.0f, LIGHT_GRAY.b / 255.0f});
+        }
+
+        sFakeComposer->runVSyncAndWait();
+        mBaseFrame.push_back(makeSimpleRect(64, 64, 64 + 10, 64 + 10));
+        mBaseFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.0f, 0.0f, 0.0f, 0.0f};
+        mBaseFrame[CHILD_LAYER].mSwapCount = 0;
+        ASSERT_EQ(2, sFakeComposer->getFrameCount());
+        ASSERT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
+    }
+};
+
+TEST_F(ChildColorLayerTest, LayerAlpha) {
+    {
+        TransactionScope ts(*sFakeComposer);
+        ts.show(mChild);
+        ts.setPosition(mChild, 0, 0);
+        ts.setPosition(mFGSurfaceControl, 0, 0);
+        ts.setAlpha(mChild, 0.5);
+    }
+
+    auto referenceFrame = mBaseFrame;
+    referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
+    referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
+    referenceFrame[CHILD_LAYER].mPlaneAlpha = 0.5f;
+    EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
+
+    {
+        TransactionScope ts(*sFakeComposer);
+        ts.setAlpha(mFGSurfaceControl, 0.5);
+    }
+
+    auto referenceFrame2 = referenceFrame;
+    referenceFrame2[FG_LAYER].mPlaneAlpha = 0.5f;
+    referenceFrame2[CHILD_LAYER].mPlaneAlpha = 0.25f;
+    EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
+}
+
+TEST_F(ChildColorLayerTest, LayerZeroAlpha) {
+    {
+        TransactionScope ts(*sFakeComposer);
+        ts.show(mChild);
+        ts.setPosition(mChild, 0, 0);
+        ts.setPosition(mFGSurfaceControl, 0, 0);
+        ts.setAlpha(mChild, 0.5);
+    }
+
+    auto referenceFrame = mBaseFrame;
+    referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
+    referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
+    referenceFrame[CHILD_LAYER].mPlaneAlpha = 0.5f;
+    EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
+
+    {
+        TransactionScope ts(*sFakeComposer);
+        ts.setAlpha(mFGSurfaceControl, 0.0f);
+    }
+
+    std::vector<RenderState> refFrame(1);
+    refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
+
+    EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
+}
+
 class LatchingTest : public TransactionTest {
 protected:
     void lockAndFillFGBuffer() { fillSurfaceRGBA8(mFGSurfaceControl, RED, false); }