Add a re-parent function to re-parent a specific child.

This is similar to reparentChildren, but the reparentChild will
only re-parent a specific child to the new parent and not all
children.

Test: Added test in Transaction_test for reparentChild.

Change-Id: I4275e0d5f1d5601b489956753c78a56d1a5d4c1c
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index e92565f..c406f74 100755
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2625,6 +2625,44 @@
     return true;
 }
 
+bool Layer::reparentChild(const sp<IBinder>& newParentHandle, const sp<IBinder>& childHandle) {
+    if (newParentHandle == nullptr || childHandle == nullptr) {
+        return false;
+    }
+
+    auto handle = static_cast<Handle*>(newParentHandle.get());
+    sp<Layer> newParent = handle->owner.promote();
+    if (newParent == nullptr) {
+        ALOGE("Unable to promote Layer handle");
+        return false;
+    }
+
+    handle = static_cast<Handle*>(childHandle.get());
+    sp<Layer> child = handle->owner.promote();
+    if (child == nullptr) {
+        ALOGE("Unable to promote child Layer handle");
+        return false;
+    }
+
+    if (mCurrentChildren.indexOf(child) < 0) {
+        ALOGE("Child layer is not child of current layer");
+        return false;
+    }
+
+    sp<Client> parentClient(mClientRef.promote());
+    sp<Client> childClient(child->mClientRef.promote());
+    sp<Client> newParentClient(newParent->mClientRef.promote());
+
+    if (parentClient != childClient || childClient != newParentClient) {
+        ALOGE("Current layer, child layer, and new parent layer must have the same client");
+        return false;
+    }
+
+    newParent->addChild(child);
+    mCurrentChildren.remove(child);
+    return true;
+}
+
 bool Layer::detachChildren() {
     traverseInZOrder(LayerVector::StateSet::Drawing, [this](Layer* child) {
         if (child == this) {