740 lines
33 KiB
C++
740 lines
33 KiB
C++
|
|
/*
|
||
|
|
* Copyright 2022 The Android Open Source Project
|
||
|
|
*
|
||
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
* you may not use this file except in compliance with the License.
|
||
|
|
* You may obtain a copy of the License at
|
||
|
|
*
|
||
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
*
|
||
|
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
* See the License for the specific language governing permissions and
|
||
|
|
* limitations under the License.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include <gmock/gmock.h>
|
||
|
|
#include <gtest/gtest.h>
|
||
|
|
|
||
|
|
#include "FrontEnd/LayerHierarchy.h"
|
||
|
|
#include "FrontEnd/LayerLifecycleManager.h"
|
||
|
|
#include "LayerHierarchyTest.h"
|
||
|
|
|
||
|
|
#define UPDATE_AND_VERIFY(HIERARCHY) \
|
||
|
|
({ \
|
||
|
|
SCOPED_TRACE(""); \
|
||
|
|
updateAndVerify((HIERARCHY)); \
|
||
|
|
})
|
||
|
|
|
||
|
|
namespace android::surfaceflinger::frontend {
|
||
|
|
|
||
|
|
// To run test:
|
||
|
|
/**
|
||
|
|
mp :libsurfaceflinger_unittest && adb sync; adb shell \
|
||
|
|
/data/nativetest/libsurfaceflinger_unittest/libsurfaceflinger_unittest \
|
||
|
|
--gtest_filter="LayerHierarchyTest.*" --gtest_repeat=100 \
|
||
|
|
--gtest_shuffle \
|
||
|
|
--gtest_brief=1
|
||
|
|
*/
|
||
|
|
|
||
|
|
class LayerHierarchyTest : public LayerHierarchyTestBase {
|
||
|
|
protected:
|
||
|
|
LayerHierarchyTest() : LayerHierarchyTestBase() { mLifecycleManager.commitChanges(); }
|
||
|
|
};
|
||
|
|
|
||
|
|
// reparenting tests
|
||
|
|
TEST_F(LayerHierarchyTest, addLayer) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
|
||
|
|
createRootLayer(3);
|
||
|
|
createLayer(112, 11);
|
||
|
|
createLayer(12211, 1221);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
expectedTraversalPath = {1, 11, 111, 112, 12, 121, 122, 1221, 12211, 13, 2, 3};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, reparentLayer) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentLayer(2, 11);
|
||
|
|
reparentLayer(111, 12);
|
||
|
|
reparentLayer(1221, 1);
|
||
|
|
reparentLayer(1221, 13);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 2, 12, 111, 121, 122, 13, 1221};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, reparentLayerToNull) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
|
||
|
|
reparentLayer(2, UNASSIGNED_LAYER_ID);
|
||
|
|
reparentLayer(11, UNASSIGNED_LAYER_ID);
|
||
|
|
reparentLayer(1221, 13);
|
||
|
|
reparentLayer(1221, UNASSIGNED_LAYER_ID);
|
||
|
|
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 12, 121, 122, 13};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {2, 11, 111, 1221};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, reparentLayerToNullAndDestroyHandles) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentLayer(2, UNASSIGNED_LAYER_ID);
|
||
|
|
reparentLayer(11, UNASSIGNED_LAYER_ID);
|
||
|
|
reparentLayer(1221, UNASSIGNED_LAYER_ID);
|
||
|
|
|
||
|
|
destroyLayerHandle(2);
|
||
|
|
destroyLayerHandle(11);
|
||
|
|
destroyLayerHandle(1221);
|
||
|
|
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 12, 121, 122, 13};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {111};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, destroyHandleThenDestroyParentLayer) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
destroyLayerHandle(111);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
// handle is destroyed but layer is kept alive and reachable by parent
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
|
||
|
|
// destroy parent layer and the child gets destroyed
|
||
|
|
reparentLayer(11, UNASSIGNED_LAYER_ID);
|
||
|
|
destroyLayerHandle(11);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
expectedTraversalPath = {1, 12, 121, 122, 1221, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, layerSurvivesTemporaryReparentToNull) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentLayer(11, UNASSIGNED_LAYER_ID);
|
||
|
|
reparentLayer(11, 1);
|
||
|
|
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
// offscreen tests
|
||
|
|
TEST_F(LayerHierarchyTest, layerMovesOnscreen) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
|
||
|
|
reparentLayer(11, UNASSIGNED_LAYER_ID);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
reparentLayer(11, 1);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, addLayerToOffscreenParent) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
|
||
|
|
reparentLayer(11, UNASSIGNED_LAYER_ID);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
createLayer(112, 11);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 12, 121, 122, 1221, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {11, 111, 112};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
// rel-z tests
|
||
|
|
TEST_F(LayerHierarchyTest, setRelativeParent) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentRelativeLayer(11, 2);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2, 11, 111};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {1, 12, 121, 122, 1221, 13, 2, 11, 111};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, reparentFromRelativeParentWithSetLayer) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentRelativeLayer(11, 2);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
// This calls setLayer
|
||
|
|
removeRelativeZ(11);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, reparentToRelativeParent) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentRelativeLayer(11, 2);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
reparentLayer(11, 2);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 12, 121, 122, 1221, 13, 2, 11, 111};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, setParentAsRelativeParent) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentLayer(11, 2);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
reparentRelativeLayer(11, 2);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 12, 121, 122, 1221, 13, 2, 11, 111};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, relativeChildMovesOffscreenIsNotTraversable) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentRelativeLayer(11, 2);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
reparentLayer(2, UNASSIGNED_LAYER_ID);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {1, 12, 121, 122, 1221, 13};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {2, 11, 111};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, reparentRelativeLayer) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentRelativeLayer(11, 2);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2, 11, 111};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {1, 12, 121, 122, 1221, 13, 2, 11, 111};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
|
||
|
|
reparentLayer(11, 1);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2, 11, 111};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {1, 12, 121, 122, 1221, 13, 2, 11, 111};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
|
||
|
|
setZ(11, 0);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
// mirror tests
|
||
|
|
TEST_F(LayerHierarchyTest, canTraverseMirrorLayer) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
|
||
|
|
mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 11);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122,
|
||
|
|
1221, 13, 14, 11, 111, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, canMirrorOffscreenLayer) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
|
||
|
|
reparentLayer(11, UNASSIGNED_LAYER_ID);
|
||
|
|
mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 11);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 12, 121, 122, 1221, 13, 14, 11, 111, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {11, 111};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, newChildLayerIsUpdatedInMirrorHierarchy) {
|
||
|
|
mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 11);
|
||
|
|
mLifecycleManager.commitChanges();
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
|
||
|
|
createLayer(1111, 111);
|
||
|
|
createLayer(112, 11);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 1111, 112, 12, 121, 122,
|
||
|
|
1221, 13, 14, 11, 111, 1111, 112, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
// mirror & relatives tests
|
||
|
|
TEST_F(LayerHierarchyTest, mirrorWithRelativeOutsideMirrorHierarchy) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentRelativeLayer(111, 12);
|
||
|
|
mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 11);
|
||
|
|
|
||
|
|
// ROOT
|
||
|
|
// ├── 1
|
||
|
|
// │ ├── 11
|
||
|
|
// │ │ └── 111
|
||
|
|
// │ ├── 12
|
||
|
|
// │ │ ├── 121
|
||
|
|
// │ │ ├── 122
|
||
|
|
// │ │ │ └── 1221
|
||
|
|
// │ │ └ - 111 (relative)
|
||
|
|
// │ ├── 13
|
||
|
|
// │ └── 14
|
||
|
|
// │ └ * 11 (mirroring)
|
||
|
|
// └── 2
|
||
|
|
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 111, 121, 122,
|
||
|
|
1221, 13, 14, 11, 111, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
// 111 is not reachable in the mirror
|
||
|
|
expectedTraversalPath = {1, 11, 12, 111, 121, 122, 1221, 13, 14, 11, 2};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, mirrorWithRelativeInsideMirrorHierarchy) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentRelativeLayer(1221, 12);
|
||
|
|
mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 12);
|
||
|
|
|
||
|
|
// ROOT
|
||
|
|
// ├── 1
|
||
|
|
// │ ├── 11
|
||
|
|
// │ │ └── 111
|
||
|
|
// │ ├── 12
|
||
|
|
// │ │ ├── 121
|
||
|
|
// │ │ ├── 122
|
||
|
|
// │ │ │ └── 1221
|
||
|
|
// │ │ └ - 1221 (relative)
|
||
|
|
// │ ├── 13
|
||
|
|
// │ └── 14
|
||
|
|
// │ └ * 12 (mirroring)
|
||
|
|
// └── 2
|
||
|
|
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 1221,
|
||
|
|
13, 14, 12, 121, 122, 1221, 1221, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
// relative layer 1221 is traversable in the mirrored hierarchy as well
|
||
|
|
expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 14, 12, 121, 122, 1221, 2};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, childMovesOffscreenWhenRelativeParentDies) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
|
||
|
|
reparentRelativeLayer(11, 2);
|
||
|
|
reparentLayer(2, UNASSIGNED_LAYER_ID);
|
||
|
|
destroyLayerHandle(2);
|
||
|
|
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {1, 12, 121, 122, 1221, 13};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {11, 111};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
|
||
|
|
// remove relative parent so layer becomes onscreen again
|
||
|
|
removeRelativeZ(11);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, offscreenLayerCannotBeRelativeToOnscreenLayer) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentRelativeLayer(1221, 2);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
// verify relz path
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2, 1221};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {1, 11, 111, 12, 121, 122, 13, 2, 1221};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
|
||
|
|
// offscreen layer cannot be reached as a relative child
|
||
|
|
reparentLayer(12, UNASSIGNED_LAYER_ID);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
expectedTraversalPath = {1, 11, 111, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {12, 121, 122, 1221};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
|
||
|
|
// layer when onscreen can be reached as a relative child again
|
||
|
|
reparentLayer(12, 1);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2, 1221};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {1, 11, 111, 12, 121, 122, 13, 2, 1221};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, backgroundLayersAreBehindParentLayer) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
|
||
|
|
updateBackgroundColor(1, 0.5);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
auto hierarchy = hierarchyBuilder.getPartialHierarchy(1, /*childrenOnly=*/true);
|
||
|
|
auto bgLayerId = hierarchy.mChildren.front().first->getLayer()->id;
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, bgLayerId, 11, 111, 12,
|
||
|
|
121, 122, 1221, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {bgLayerId, 1, 11, 111, 12, 121, 122, 1221, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
// cycle tests
|
||
|
|
TEST_F(LayerHierarchyTest, ParentBecomesTheChild) {
|
||
|
|
// remove default hierarchy
|
||
|
|
mLifecycleManager = LayerLifecycleManager();
|
||
|
|
createRootLayer(1);
|
||
|
|
createLayer(11, 1);
|
||
|
|
reparentLayer(1, 11);
|
||
|
|
mLifecycleManager.commitChanges();
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, RelativeLoops) {
|
||
|
|
// remove default hierarchy
|
||
|
|
mLifecycleManager = LayerLifecycleManager();
|
||
|
|
createRootLayer(1);
|
||
|
|
createRootLayer(2);
|
||
|
|
createLayer(11, 1);
|
||
|
|
reparentRelativeLayer(11, 2);
|
||
|
|
reparentRelativeLayer(2, 11);
|
||
|
|
mLifecycleManager.commitChanges();
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
|
||
|
|
// fix loop
|
||
|
|
uint32_t invalidRelativeRoot;
|
||
|
|
bool hasRelZLoop = hierarchyBuilder.getHierarchy().hasRelZLoop(invalidRelativeRoot);
|
||
|
|
EXPECT_TRUE(hasRelZLoop);
|
||
|
|
mLifecycleManager.fixRelativeZLoop(invalidRelativeRoot);
|
||
|
|
hierarchyBuilder.update(mLifecycleManager.getLayers(), mLifecycleManager.getDestroyedLayers());
|
||
|
|
EXPECT_EQ(invalidRelativeRoot, 11u);
|
||
|
|
EXPECT_FALSE(hierarchyBuilder.getHierarchy().hasRelZLoop(invalidRelativeRoot));
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 2, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {1};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {11, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, IndirectRelativeLoops) {
|
||
|
|
// remove default hierarchy
|
||
|
|
mLifecycleManager = LayerLifecycleManager();
|
||
|
|
createRootLayer(1);
|
||
|
|
createRootLayer(2);
|
||
|
|
createLayer(11, 1);
|
||
|
|
createLayer(111, 11);
|
||
|
|
createLayer(21, 2);
|
||
|
|
createLayer(22, 2);
|
||
|
|
createLayer(221, 22);
|
||
|
|
reparentRelativeLayer(22, 111);
|
||
|
|
reparentRelativeLayer(11, 221);
|
||
|
|
mLifecycleManager.commitChanges();
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
|
||
|
|
// fix loop
|
||
|
|
uint32_t invalidRelativeRoot;
|
||
|
|
bool hasRelZLoop = hierarchyBuilder.getHierarchy().hasRelZLoop(invalidRelativeRoot);
|
||
|
|
EXPECT_TRUE(hasRelZLoop);
|
||
|
|
mLifecycleManager.fixRelativeZLoop(invalidRelativeRoot);
|
||
|
|
hierarchyBuilder.update(mLifecycleManager.getLayers(), mLifecycleManager.getDestroyedLayers());
|
||
|
|
EXPECT_FALSE(hierarchyBuilder.getHierarchy().hasRelZLoop(invalidRelativeRoot));
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 22, 221, 2, 21, 22, 221};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {1, 2, 21};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {11, 111, 22, 221};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, ReparentRootLayerToNull) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
reparentLayer(1, UNASSIGNED_LAYER_ID);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, AddRemoveLayerInSameTransaction) {
|
||
|
|
// remove default hierarchy
|
||
|
|
mLifecycleManager = LayerLifecycleManager();
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
createRootLayer(1);
|
||
|
|
destroyLayerHandle(1);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
// traversal path test
|
||
|
|
TEST_F(LayerHierarchyTest, traversalPathId) {
|
||
|
|
setZ(122, -1);
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
auto checkTraversalPathIdVisitor =
|
||
|
|
[](const LayerHierarchy& hierarchy,
|
||
|
|
const LayerHierarchy::TraversalPath& traversalPath) -> bool {
|
||
|
|
EXPECT_EQ(hierarchy.getLayer()->id, traversalPath.id);
|
||
|
|
return true;
|
||
|
|
};
|
||
|
|
hierarchyBuilder.getHierarchy().traverse(checkTraversalPathIdVisitor);
|
||
|
|
hierarchyBuilder.getHierarchy().traverseInZOrder(checkTraversalPathIdVisitor);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, zorderRespectsLayerSequenceId) {
|
||
|
|
// remove default hierarchy
|
||
|
|
mLifecycleManager = LayerLifecycleManager();
|
||
|
|
createRootLayer(1);
|
||
|
|
createRootLayer(2);
|
||
|
|
createRootLayer(4);
|
||
|
|
createRootLayer(5);
|
||
|
|
createLayer(11, 1);
|
||
|
|
createLayer(51, 5);
|
||
|
|
createLayer(53, 5);
|
||
|
|
|
||
|
|
mLifecycleManager.commitChanges();
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 2, 4, 5, 51, 53};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
|
||
|
|
// A new layer is added with a smaller sequence id. Make sure its sorted correctly. While
|
||
|
|
// sequence ids are always incremented, this scenario can happen when a layer is reparented.
|
||
|
|
createRootLayer(3);
|
||
|
|
createLayer(52, 5);
|
||
|
|
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
expectedTraversalPath = {1, 11, 2, 3, 4, 5, 51, 52, 53};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, zorderRespectsLayerZ) {
|
||
|
|
// remove default hierarchy
|
||
|
|
mLifecycleManager = LayerLifecycleManager();
|
||
|
|
createRootLayer(1);
|
||
|
|
createLayer(11, 1);
|
||
|
|
createLayer(12, 1);
|
||
|
|
createLayer(13, 1);
|
||
|
|
setZ(11, -1);
|
||
|
|
setZ(12, 2);
|
||
|
|
setZ(13, 1);
|
||
|
|
|
||
|
|
mLifecycleManager.commitChanges();
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {1, 11, 13, 12};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
|
||
|
|
expectedTraversalPath = {11, 1, 13, 12};
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, zorderRespectsLayerStack) {
|
||
|
|
// remove default hierarchy
|
||
|
|
mLifecycleManager = LayerLifecycleManager();
|
||
|
|
createRootLayer(1);
|
||
|
|
createRootLayer(2);
|
||
|
|
createLayer(11, 1);
|
||
|
|
createLayer(21, 2);
|
||
|
|
setLayerStack(1, 20);
|
||
|
|
setLayerStack(2, 10);
|
||
|
|
|
||
|
|
mLifecycleManager.commitChanges();
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
std::vector<uint32_t> expectedTraversalPath = {2, 21, 1, 11};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
|
||
|
|
expectedTraversalPath = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expectedTraversalPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, canMirrorDisplay) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
setFlags(12, layer_state_t::eLayerSkipScreenshot, layer_state_t::eLayerSkipScreenshot);
|
||
|
|
createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0));
|
||
|
|
setLayerStack(3, 1);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expected = {1, 11, 111, 12, 121, 122, 1221, 13, 2, 3,
|
||
|
|
1, 11, 111, 12, 121, 122, 1221, 13, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expected);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expected);
|
||
|
|
expected = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expected);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, mirrorNonExistingDisplay) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
setFlags(12, layer_state_t::eLayerSkipScreenshot, layer_state_t::eLayerSkipScreenshot);
|
||
|
|
createDisplayMirrorLayer(3, ui::LayerStack::fromValue(5));
|
||
|
|
setLayerStack(3, 1);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expected = {1, 11, 111, 12, 121, 122, 1221, 13, 2, 3};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expected);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expected);
|
||
|
|
expected = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expected);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, newRootLayerIsMirrored) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
setFlags(12, layer_state_t::eLayerSkipScreenshot, layer_state_t::eLayerSkipScreenshot);
|
||
|
|
createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0));
|
||
|
|
setLayerStack(3, 1);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
createRootLayer(4);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expected = {1, 11, 111, 12, 121, 122, 1221, 13, 2, 4, 3,
|
||
|
|
1, 11, 111, 12, 121, 122, 1221, 13, 2, 4};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expected);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expected);
|
||
|
|
expected = {};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expected);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(LayerHierarchyTest, removedRootLayerIsNoLongerMirrored) {
|
||
|
|
LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
|
||
|
|
setFlags(12, layer_state_t::eLayerSkipScreenshot, layer_state_t::eLayerSkipScreenshot);
|
||
|
|
createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0));
|
||
|
|
setLayerStack(3, 1);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
reparentLayer(1, UNASSIGNED_LAYER_ID);
|
||
|
|
destroyLayerHandle(1);
|
||
|
|
UPDATE_AND_VERIFY(hierarchyBuilder);
|
||
|
|
|
||
|
|
std::vector<uint32_t> expected = {2, 3, 2};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expected);
|
||
|
|
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expected);
|
||
|
|
expected = {11, 111, 12, 121, 122, 1221, 13};
|
||
|
|
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getOffscreenHierarchy()), expected);
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace android::surfaceflinger::frontend
|