Merge "Re-parent invoked on child instead of on parent."
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 573f685..3418a49 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -46,7 +46,6 @@
output.writeStrongBinder(IInterface::asBinder(barrierGbp));
output.writeStrongBinder(relativeLayerHandle);
output.writeStrongBinder(parentHandleForChild);
- output.writeStrongBinder(childHandle);
output.write(transparentRegion);
return NO_ERROR;
}
@@ -80,7 +79,6 @@
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 b0ae7e0..be7b1d2 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -176,9 +176,8 @@
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 reparent(const sp<SurfaceComposerClient>& client,
+ const sp<IBinder>& id, const sp<IBinder>& newParentHandle);
status_t detachChildren(const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id);
status_t setOverrideScalingMode(const sp<SurfaceComposerClient>& client,
@@ -496,18 +495,16 @@
return NO_ERROR;
}
-status_t Composer::reparentChild(const sp<SurfaceComposerClient>& client,
+status_t Composer::reparent(const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id,
- const sp<IBinder>& newParentHandle,
- const sp<IBinder>& childHandle) {
+ const sp<IBinder>& newParentHandle) {
Mutex::Autolock lock(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s) {
return BAD_INDEX;
}
- s->what |= layer_state_t::eReparentChild;
+ s->what |= layer_state_t::eReparent;
s->parentHandleForChild = newParentHandle;
- s->childHandle = childHandle;
return NO_ERROR;
}
@@ -849,9 +846,9 @@
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::reparent(const sp<IBinder>& id,
+ const sp<IBinder>& newParentHandle) {
+ return getComposer().reparent(this, id, newParentHandle);
}
status_t SurfaceComposerClient::detachChildren(const sp<IBinder>& id) {
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index b9c5ef9..d801d12 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -191,11 +191,10 @@
return mClient->reparentChildren(mHandle, newParentHandle);
}
-status_t SurfaceControl::reparentChild(const sp<IBinder>& newParentHandle,
- const sp<IBinder>& childHandle) {
+status_t SurfaceControl::reparent(const sp<IBinder>& newParentHandle) {
status_t err = validate();
if (err < 0) return err;
- return mClient->reparentChild(mHandle, newParentHandle, childHandle);
+ return mClient->reparent(mHandle, newParentHandle);
}
status_t SurfaceControl::detachChildren() {
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 6e2cb83..cf2ff5b 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -161,8 +161,7 @@
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 reparent(const sp<IBinder>& id, const sp<IBinder>& newParentHandle);
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 d8b67ef..b506e00 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -124,11 +124,10 @@
// 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.
+ // Reparents the current layer to the new parent handle. The new parent must not be null.
// 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);
+ // only re-parent a specific child.
+ status_t reparent(const sp<IBinder>& newParentHandle);
// Detaches all child surfaces (and their children recursively)
// from their SurfaceControl.
diff --git a/libs/gui/include/private/gui/LayerState.h b/libs/gui/include/private/gui/LayerState.h
index 4f73e04..4ff2e5e 100644
--- a/libs/gui/include/private/gui/LayerState.h
+++ b/libs/gui/include/private/gui/LayerState.h
@@ -60,7 +60,7 @@
eReparentChildren = 0x00002000,
eDetachChildren = 0x00004000,
eRelativeLayerChanged = 0x00008000,
- eReparentChild = 0x00010000
+ eReparent = 0x00010000
};
layer_state_t()
@@ -109,7 +109,6 @@
sp<IBinder> relativeLayerHandle;
sp<IBinder> parentHandleForChild;
- sp<IBinder> childHandle;
// non POD must be last. see write/read
Region transparentRegion;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 9435a18..fd30e16 100755
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2625,8 +2625,8 @@
return true;
}
-bool Layer::reparentChild(const sp<IBinder>& newParentHandle, const sp<IBinder>& childHandle) {
- if (newParentHandle == nullptr || childHandle == nullptr) {
+bool Layer::reparent(const sp<IBinder>& newParentHandle) {
+ if (newParentHandle == nullptr) {
return false;
}
@@ -2637,29 +2637,19 @@
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;
+ sp<Layer> parent = getParent();
+ if (parent != nullptr) {
+ parent->removeChild(this);
}
+ newParent->addChild(this);
- 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> client(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;
+ if (client != newParentClient) {
+ client->setParentLayer(newParent);
}
- newParent->addChild(child);
- mCurrentChildren.remove(child);
return true;
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f94833b..e7ece45 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -241,7 +241,7 @@
bool setOverrideScalingMode(int32_t overrideScalingMode);
void setInfo(uint32_t type, uint32_t appId);
bool reparentChildren(const sp<IBinder>& layer);
- bool reparentChild(const sp<IBinder>& newParentHandle, const sp<IBinder>& childHandle);
+ bool reparent(const sp<IBinder>& newParentHandle);
bool detachChildren();
// If we have received a new buffer this frame, we will pass its surface
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index cae4dea..6ee14fe 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3121,10 +3121,8 @@
// We don't trigger a traversal here because if no other state is
// changed, we don't want this to cause any more work
}
- // Always re-parent the children that explicitly requested to get
- // re-parented before the general re-parent of all children.
- if (what & layer_state_t::eReparentChild) {
- if (layer->reparentChild(s.parentHandleForChild, s.childHandle)) {
+ if (what & layer_state_t::eReparent) {
+ if (layer->reparent(s.parentHandleForChild)) {
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 3b4db05..b1c8c0a 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -2681,10 +2681,8 @@
// We don't trigger a traversal here because if no other state is
// changed, we don't want this to cause any more work
}
- // Always re-parent the children that explicitly requested to get
- // re-parented before the general re-parent of all children.
- if (what & layer_state_t::eReparentChild) {
- if (layer->reparentChild(s.parentHandleForChild, s.childHandle)) {
+ if (what & layer_state_t::eReparent) {
+ if (layer->reparent(s.parentHandleForChild)) {
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index dea6503..2119492 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -1169,7 +1169,7 @@
fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
}
-TEST_F(ChildLayerTest, ReparentChild) {
+TEST_F(ChildLayerTest, Reparent) {
SurfaceComposerClient::openGlobalTransaction();
mChild->show();
mChild->setPosition(10, 10);
@@ -1185,7 +1185,7 @@
// And 10 more pixels we should be back to the foreground surface
mCapture->expectFGColor(84, 84);
}
- mFGSurfaceControl->reparentChild(mBGSurfaceControl->getHandle(), mChild->getHandle());
+ mChild->reparent(mBGSurfaceControl->getHandle());
{
ScreenCapture::captureScreen(&mCapture);
mCapture->expectFGColor(64, 64);
@@ -1198,6 +1198,69 @@
}
}
+TEST_F(ChildLayerTest, ReparentToNoParent) {
+ SurfaceComposerClient::openGlobalTransaction();
+ mChild->show();
+ mChild->setPosition(10, 10);
+ mFGSurfaceControl->setPosition(64, 64);
+ SurfaceComposerClient::closeGlobalTransaction(true);
+
+ {
+ ScreenCapture::captureScreen(&mCapture);
+ // Top left of foreground must now be visible
+ mCapture->expectFGColor(64, 64);
+ // But 10 pixels in we should see the child surface
+ mCapture->expectChildColor(74, 74);
+ // And 10 more pixels we should be back to the foreground surface
+ mCapture->expectFGColor(84, 84);
+ }
+ mChild->reparent(nullptr);
+ {
+ ScreenCapture::captureScreen(&mCapture);
+ // Nothing should have changed.
+ mCapture->expectFGColor(64, 64);
+ mCapture->expectChildColor(74, 74);
+ mCapture->expectFGColor(84, 84);
+ }
+}
+
+TEST_F(ChildLayerTest, ReparentFromNoParent) {
+ sp<SurfaceControl> newSurface = mComposerClient->createSurface(
+ String8("New Surface"), 10, 10, PIXEL_FORMAT_RGBA_8888, 0);
+ ASSERT_TRUE(newSurface != NULL);
+ ASSERT_TRUE(newSurface->isValid());
+
+ fillSurfaceRGBA8(newSurface, 63, 195, 63);
+ SurfaceComposerClient::openGlobalTransaction();
+ mChild->hide();
+ newSurface->show();
+ newSurface->setPosition(10, 10);
+ newSurface->setLayer(INT32_MAX-2);
+ mFGSurfaceControl->setPosition(64, 64);
+ SurfaceComposerClient::closeGlobalTransaction(true);
+
+ {
+ ScreenCapture::captureScreen(&mCapture);
+ // Top left of foreground must now be visible
+ mCapture->expectFGColor(64, 64);
+ // At 10, 10 we should see the new surface
+ mCapture->checkPixel(10, 10, 63, 195, 63);
+ }
+
+ SurfaceComposerClient::openGlobalTransaction();
+ newSurface->reparent(mFGSurfaceControl->getHandle());
+ SurfaceComposerClient::closeGlobalTransaction(true);
+
+ {
+ ScreenCapture::captureScreen(&mCapture);
+ // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
+ // mFGSurface, putting it at 74, 74.
+ mCapture->expectFGColor(64, 64);
+ mCapture->checkPixel(74, 74, 63, 195, 63);
+ mCapture->expectFGColor(84, 84);
+ }
+}
+
TEST_F(ChildLayerTest, NestedChildren) {
sp<SurfaceControl> grandchild = mComposerClient->createSurface(
String8("Grandchild surface"),