Fix crash when reparenting layer to itself.

Currently this creates unbounded recursion and a SurfaceFlinger
crash.

Bug: 123283486
Test: Transaction_test.cpp
Change-Id: Ieae19cb3a7724de2ddb95a895328dd5b4a8d8782
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index e108d1e..f181220 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1623,19 +1623,26 @@
         return false;
     }
 
+    sp<Layer> newParent;
+    if (newParentHandle != nullptr) {
+        auto handle = static_cast<Handle*>(newParentHandle.get());
+        newParent = handle->owner.promote();
+        if (newParent == nullptr) {
+            ALOGE("Unable to promote Layer handle");
+            return false;
+        }
+        if (newParent == this) {
+            ALOGE("Invalid attempt to reparent Layer (%s) to itself", getName().c_str());
+            return false;
+        }
+    }
+
     sp<Layer> parent = getParent();
     if (parent != nullptr) {
         parent->removeChild(this);
     }
 
     if (newParentHandle != nullptr) {
-        auto handle = static_cast<Handle*>(newParentHandle.get());
-        sp<Layer> newParent = handle->owner.promote();
-        if (newParent == nullptr) {
-            ALOGE("Unable to promote Layer handle");
-            return false;
-        }
-
         newParent->addChild(this);
         if (!newParent->isRemovedFromCurrentState()) {
             addToCurrentState();
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index b95c0ec..396fc55 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -2460,6 +2460,23 @@
     ASSERT_EQ(NO_ERROR, mClient->uncacheBuffer(bufferId));
 }
 
+TEST_F(LayerTransactionTest, ReparentToSelf) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
+    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
+    Transaction().reparent(layer, layer->getHandle()).apply();
+
+    {
+        // We expect the transaction to be silently dropped, but for SurfaceFlinger
+        // to still be functioning.
+        SCOPED_TRACE("after reparent to self");
+        const Rect rect(0, 0, 32, 32);
+        auto shot = screenshot();
+        shot->expectColor(rect, Color::RED);
+        shot->expectBorder(rect, Color::BLACK);
+    }
+}
+
 class ColorTransformHelper {
 public:
     static void DegammaColorSingle(half& s) {