Ignore local transforms when mirroring a partial hierarchy

When mirroring a partial hierarchy remove the local transform
on the mirrored root.  This is necessary because we are placing
the mirrored root under a new parent layer and its original
position relative to the old parent is no longer relevant. This
fixes offsets when mirroring a freeform window.

Flag: com.android.graphics.surfaceflinger.flags.detached_mirror
Fixes: 337845753
Test: atest libsurfaceflinger_unittest
Change-Id: I0453026217f62868a4f6d1362cdc8187baf3f9b0
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
index e8e7667..fd15eef 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -155,6 +155,17 @@
         mLifecycleManager.applyTransactions(transactions);
     }
 
+    void setPosition(uint32_t id, float x, float y) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+        transactions.back().states.front().state.what = layer_state_t::ePositionChanged;
+        transactions.back().states.front().state.x = x;
+        transactions.back().states.front().state.y = y;
+        transactions.back().states.front().layerId = id;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
     virtual void mirrorLayer(uint32_t id, uint32_t parentId, uint32_t layerIdToMirror) {
         std::vector<std::unique_ptr<RequestedLayerState>> layers;
         layers.emplace_back(std::make_unique<RequestedLayerState>(
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index ae9a89c..7c6cff0 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -1302,4 +1302,33 @@
     EXPECT_EQ(getSnapshot(1221)->inputInfo.canOccludePresentation, true);
 }
 
+TEST_F(LayerSnapshotTest, mirroredHierarchyIgnoresLocalTransform) {
+    SET_FLAG_FOR_TEST(flags::detached_mirror, true);
+    reparentLayer(12, UNASSIGNED_LAYER_ID);
+    setPosition(11, 2, 20);
+    setPosition(111, 20, 200);
+    mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 11);
+    std::vector<uint32_t> expected = {1, 11, 111, 13, 14, 11, 111, 2};
+    UPDATE_AND_VERIFY(mSnapshotBuilder, expected);
+
+    // mirror root has no position set
+    EXPECT_EQ(getSnapshot({.id = 11, .mirrorRootIds = 14u})->localTransform.tx(), 0);
+    EXPECT_EQ(getSnapshot({.id = 11, .mirrorRootIds = 14u})->localTransform.ty(), 0);
+    // original root still has a position
+    EXPECT_EQ(getSnapshot({.id = 11})->localTransform.tx(), 2);
+    EXPECT_EQ(getSnapshot({.id = 11})->localTransform.ty(), 20);
+
+    // mirror child still has the correct position
+    EXPECT_EQ(getSnapshot({.id = 111, .mirrorRootIds = 14u})->localTransform.tx(), 20);
+    EXPECT_EQ(getSnapshot({.id = 111, .mirrorRootIds = 14u})->localTransform.ty(), 200);
+    EXPECT_EQ(getSnapshot({.id = 111, .mirrorRootIds = 14u})->geomLayerTransform.tx(), 20);
+    EXPECT_EQ(getSnapshot({.id = 111, .mirrorRootIds = 14u})->geomLayerTransform.ty(), 200);
+
+    // original child still has the correct position including its parent's position
+    EXPECT_EQ(getSnapshot({.id = 111})->localTransform.tx(), 20);
+    EXPECT_EQ(getSnapshot({.id = 111})->localTransform.ty(), 200);
+    EXPECT_EQ(getSnapshot({.id = 111})->geomLayerTransform.tx(), 22);
+    EXPECT_EQ(getSnapshot({.id = 111})->geomLayerTransform.ty(), 220);
+}
+
 } // namespace android::surfaceflinger::frontend