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/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 9b06e63..573f685 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -45,6 +45,8 @@
     output.writeInt32(overrideScalingMode);
     output.writeStrongBinder(IInterface::asBinder(barrierGbp));
     output.writeStrongBinder(relativeLayerHandle);
+    output.writeStrongBinder(parentHandleForChild);
+    output.writeStrongBinder(childHandle);
     output.write(transparentRegion);
     return NO_ERROR;
 }
@@ -77,6 +79,8 @@
     barrierGbp =
         interface_cast<IGraphicBufferProducer>(input.readStrongBinder());
     relativeLayerHandle = input.readStrongBinder();
+    parentHandleForChild = input.readStrongBinder();
+    childHandle = input.readStrongBinder();
     input.read(transparentRegion);
     return NO_ERROR;
 }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 7ae2672..b0ae7e0 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -176,6 +176,9 @@
     status_t reparentChildren(const sp<SurfaceComposerClient>& client,
             const sp<IBinder>& id,
             const sp<IBinder>& newParentHandle);
+    status_t reparentChild(const sp<SurfaceComposerClient>& client,
+            const sp<IBinder>& id, const sp<IBinder>& newParentHandle,
+            const sp<IBinder>& childHandle);
     status_t detachChildren(const sp<SurfaceComposerClient>& client,
             const sp<IBinder>& id);
     status_t setOverrideScalingMode(const sp<SurfaceComposerClient>& client,
@@ -493,6 +496,21 @@
     return NO_ERROR;
 }
 
+status_t Composer::reparentChild(const sp<SurfaceComposerClient>& client,
+        const sp<IBinder>& id,
+        const sp<IBinder>& newParentHandle,
+        const sp<IBinder>& childHandle) {
+    Mutex::Autolock lock(mLock);
+    layer_state_t* s = getLayerStateLocked(client, id);
+    if (!s) {
+        return BAD_INDEX;
+    }
+    s->what |= layer_state_t::eReparentChild;
+    s->parentHandleForChild = newParentHandle;
+    s->childHandle = childHandle;
+    return NO_ERROR;
+}
+
 status_t Composer::detachChildren(
         const sp<SurfaceComposerClient>& client,
         const sp<IBinder>& id) {
@@ -831,6 +849,11 @@
     return getComposer().reparentChildren(this, id, newParentHandle);
 }
 
+status_t SurfaceComposerClient::reparentChild(const sp<IBinder>& id,
+        const sp<IBinder>& newParentHandle, const sp<IBinder>& childHandle) {
+    return getComposer().reparentChild(this, id, newParentHandle, childHandle);
+}
+
 status_t SurfaceComposerClient::detachChildren(const sp<IBinder>& id) {
     return getComposer().detachChildren(this, id);
 }
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 58bd273..b9c5ef9 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -191,6 +191,13 @@
     return mClient->reparentChildren(mHandle, newParentHandle);
 }
 
+status_t SurfaceControl::reparentChild(const sp<IBinder>& newParentHandle,
+        const sp<IBinder>& childHandle) {
+    status_t err = validate();
+    if (err < 0) return err;
+    return mClient->reparentChild(mHandle, newParentHandle, childHandle);
+}
+
 status_t SurfaceControl::detachChildren() {
     status_t err = validate();
     if (err < 0) return err;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 145c059..6e2cb83 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -161,6 +161,8 @@
             const sp<Surface>& handle, uint64_t frameNumber);
     status_t    reparentChildren(const sp<IBinder>& id,
             const sp<IBinder>& newParentHandle);
+    status_t    reparentChild(const sp<IBinder>& id, const sp<IBinder>& newParentHandle,
+            const sp<IBinder>& childHandle);
     status_t    detachChildren(const sp<IBinder>& id);
     status_t    setOverrideScalingMode(const sp<IBinder>& id,
             int32_t overrideScalingMode);
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index c15209d..d8b67ef 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -124,6 +124,12 @@
     // Reparents all children of this layer to the new parent handle.
     status_t reparentChildren(const sp<IBinder>& newParentHandle);
 
+    // Reparents a specified child from this layer to the new parent handle.
+    // The child, parent, and new parent must all have the same client.
+    // This can be used instead of reparentChildren if the caller wants to
+    // only re-parent specific children.
+    status_t reparentChild(const sp<IBinder>& newParentHandle, const sp<IBinder>& childHandle);
+
     // Detaches all child surfaces (and their children recursively)
     // from their SurfaceControl.
     // The child SurfaceControl's will not throw exceptions or return errors,
diff --git a/libs/gui/include/private/gui/LayerState.h b/libs/gui/include/private/gui/LayerState.h
index 307c764..4f73e04 100644
--- a/libs/gui/include/private/gui/LayerState.h
+++ b/libs/gui/include/private/gui/LayerState.h
@@ -59,7 +59,8 @@
         eGeometryAppliesWithResize  = 0x00001000,
         eReparentChildren           = 0x00002000,
         eDetachChildren             = 0x00004000,
-        eRelativeLayerChanged       = 0x00008000
+        eRelativeLayerChanged       = 0x00008000,
+        eReparentChild              = 0x00010000
     };
 
     layer_state_t()
@@ -107,6 +108,9 @@
 
             sp<IBinder>     relativeLayerHandle;
 
+            sp<IBinder>     parentHandleForChild;
+            sp<IBinder>     childHandle;
+
             // non POD must be last. see write/read
             Region          transparentRegion;
 };