|  | /* | 
|  | * 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 <renderengine/mock/FakeExternalTexture.h> | 
|  |  | 
|  | #include "FrontEnd/LayerHierarchy.h" | 
|  | #include "FrontEnd/LayerLifecycleManager.h" | 
|  | #include "FrontEnd/LayerSnapshotBuilder.h" | 
|  | #include "Layer.h" | 
|  | #include "LayerHierarchyTest.h" | 
|  | #include "ui/GraphicTypes.h" | 
|  |  | 
|  | #define UPDATE_AND_VERIFY(BUILDER, ...)                                    \ | 
|  | ({                                                                     \ | 
|  | SCOPED_TRACE("");                                                  \ | 
|  | updateAndVerify((BUILDER), /*displayChanges=*/false, __VA_ARGS__); \ | 
|  | }) | 
|  |  | 
|  | #define UPDATE_AND_VERIFY_WITH_DISPLAY_CHANGES(BUILDER, ...)              \ | 
|  | ({                                                                    \ | 
|  | SCOPED_TRACE("");                                                 \ | 
|  | updateAndVerify((BUILDER), /*displayChanges=*/true, __VA_ARGS__); \ | 
|  | }) | 
|  |  | 
|  | namespace android::surfaceflinger::frontend { | 
|  |  | 
|  | using ftl::Flags; | 
|  | using namespace ftl::flag_operators; | 
|  |  | 
|  | // To run test: | 
|  | /** | 
|  | mp :libsurfaceflinger_unittest && adb sync; adb shell \ | 
|  | /data/nativetest/libsurfaceflinger_unittest/libsurfaceflinger_unittest \ | 
|  | --gtest_filter="LayerSnapshotTest.*" --gtest_brief=1 | 
|  | */ | 
|  |  | 
|  | class LayerSnapshotTest : public LayerHierarchyTestBase { | 
|  | protected: | 
|  | LayerSnapshotTest() : LayerHierarchyTestBase() { | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | } | 
|  |  | 
|  | void createRootLayer(uint32_t id) override { | 
|  | LayerHierarchyTestBase::createRootLayer(id); | 
|  | setColor(id); | 
|  | } | 
|  |  | 
|  | void createLayer(uint32_t id, uint32_t parentId) override { | 
|  | LayerHierarchyTestBase::createLayer(id, parentId); | 
|  | setColor(parentId); | 
|  | } | 
|  |  | 
|  | void mirrorLayer(uint32_t id, uint32_t parent, uint32_t layerToMirror) override { | 
|  | LayerHierarchyTestBase::mirrorLayer(id, parent, layerToMirror); | 
|  | setColor(id); | 
|  | } | 
|  |  | 
|  | void update(LayerSnapshotBuilder& actualBuilder, LayerSnapshotBuilder::Args& args) { | 
|  | if (mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy)) { | 
|  | mHierarchyBuilder.update(mLifecycleManager.getLayers(), | 
|  | mLifecycleManager.getDestroyedLayers()); | 
|  | } | 
|  | args.root = mHierarchyBuilder.getHierarchy(); | 
|  | actualBuilder.update(args); | 
|  | } | 
|  |  | 
|  | void updateAndVerify(LayerSnapshotBuilder& actualBuilder, bool hasDisplayChanges, | 
|  | const std::vector<uint32_t> expectedVisibleLayerIdsInZOrder) { | 
|  | LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(), | 
|  | .layerLifecycleManager = mLifecycleManager, | 
|  | .includeMetadata = false, | 
|  | .displays = mFrontEndDisplayInfos, | 
|  | .displayChanges = hasDisplayChanges, | 
|  | .globalShadowSettings = globalShadowSettings, | 
|  | .supportsBlur = true, | 
|  | .supportedLayerGenericMetadata = {}, | 
|  | .genericLayerMetadataKeyMap = {}}; | 
|  | update(actualBuilder, args); | 
|  |  | 
|  | // rebuild layer snapshots from scratch and verify that it matches the updated state. | 
|  | LayerSnapshotBuilder expectedBuilder(args); | 
|  | mLifecycleManager.commitChanges(); | 
|  | ASSERT_TRUE(expectedBuilder.getSnapshots().size() > 0); | 
|  | ASSERT_TRUE(actualBuilder.getSnapshots().size() > 0); | 
|  |  | 
|  | std::vector<uint32_t> actualVisibleLayerIdsInZOrder; | 
|  | actualBuilder.forEachVisibleSnapshot( | 
|  | [&actualVisibleLayerIdsInZOrder](const LayerSnapshot& snapshot) { | 
|  | actualVisibleLayerIdsInZOrder.push_back(snapshot.path.id); | 
|  | }); | 
|  | EXPECT_EQ(expectedVisibleLayerIdsInZOrder, actualVisibleLayerIdsInZOrder); | 
|  | } | 
|  |  | 
|  | LayerSnapshot* getSnapshot(uint32_t layerId) { return mSnapshotBuilder.getSnapshot(layerId); } | 
|  | LayerSnapshot* getSnapshot(const LayerHierarchy::TraversalPath path) { | 
|  | return mSnapshotBuilder.getSnapshot(path); | 
|  | } | 
|  |  | 
|  | LayerHierarchyBuilder mHierarchyBuilder{{}}; | 
|  | LayerSnapshotBuilder mSnapshotBuilder; | 
|  | DisplayInfos mFrontEndDisplayInfos; | 
|  | renderengine::ShadowSettings globalShadowSettings; | 
|  | static const std::vector<uint32_t> STARTING_ZORDER; | 
|  | }; | 
|  | const std::vector<uint32_t> LayerSnapshotTest::STARTING_ZORDER = {1,   11,   111, 12, 121, | 
|  | 122, 1221, 13,  2}; | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, buildSnapshot) { | 
|  | LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(), | 
|  | .layerLifecycleManager = mLifecycleManager, | 
|  | .includeMetadata = false, | 
|  | .displays = mFrontEndDisplayInfos, | 
|  | .globalShadowSettings = globalShadowSettings, | 
|  | .supportedLayerGenericMetadata = {}, | 
|  | .genericLayerMetadataKeyMap = {}}; | 
|  | LayerSnapshotBuilder builder(args); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, updateSnapshot) { | 
|  | LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(), | 
|  | .layerLifecycleManager = mLifecycleManager, | 
|  | .includeMetadata = false, | 
|  | .displays = mFrontEndDisplayInfos, | 
|  | .globalShadowSettings = globalShadowSettings, | 
|  | .supportedLayerGenericMetadata = {}, | 
|  | .genericLayerMetadataKeyMap = {} | 
|  |  | 
|  | }; | 
|  |  | 
|  | LayerSnapshotBuilder builder; | 
|  | builder.update(args); | 
|  | } | 
|  |  | 
|  | // update using parent snapshot data | 
|  | TEST_F(LayerSnapshotTest, croppedByParent) { | 
|  | /// MAKE ALL LAYERS VISIBLE BY DEFAULT | 
|  | DisplayInfo info; | 
|  | info.info.logicalHeight = 100; | 
|  | info.info.logicalWidth = 200; | 
|  | mFrontEndDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(1), info); | 
|  | Rect layerCrop(0, 0, 10, 20); | 
|  | setCrop(11, layerCrop); | 
|  | EXPECT_TRUE(mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Geometry)); | 
|  | UPDATE_AND_VERIFY_WITH_DISPLAY_CHANGES(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot(11)->geomCrop, layerCrop); | 
|  | EXPECT_EQ(getSnapshot(111)->geomLayerBounds, layerCrop.toFloatRect()); | 
|  | float maxHeight = static_cast<float>(info.info.logicalHeight * 10); | 
|  | float maxWidth = static_cast<float>(info.info.logicalWidth * 10); | 
|  |  | 
|  | FloatRect maxDisplaySize(-maxWidth, -maxHeight, maxWidth, maxHeight); | 
|  | EXPECT_EQ(getSnapshot(1)->geomLayerBounds, maxDisplaySize); | 
|  | } | 
|  |  | 
|  | // visibility tests | 
|  | TEST_F(LayerSnapshotTest, newLayerHiddenByPolicy) { | 
|  | createLayer(112, 11); | 
|  | hideLayer(112); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  |  | 
|  | showLayer(112); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 11, 111, 112, 12, 121, 122, 1221, 13, 2}); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, hiddenByParent) { | 
|  | hideLayer(11); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 13, 2}); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, reparentShowsChild) { | 
|  | hideLayer(11); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 13, 2}); | 
|  |  | 
|  | showLayer(11); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, reparentHidesChild) { | 
|  | hideLayer(11); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 13, 2}); | 
|  |  | 
|  | reparentLayer(121, 11); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 122, 1221, 13, 2}); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, unHidingUpdatesSnapshot) { | 
|  | hideLayer(11); | 
|  | Rect crop(1, 2, 3, 4); | 
|  | setCrop(111, crop); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 13, 2}); | 
|  |  | 
|  | showLayer(11); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot(111)->geomLayerBounds, crop.toFloatRect()); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, childBehindParentCanBeHiddenByParent) { | 
|  | setZ(111, -1); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 111, 11, 12, 121, 122, 1221, 13, 2}); | 
|  |  | 
|  | hideLayer(11); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 13, 2}); | 
|  | } | 
|  |  | 
|  | // relative tests | 
|  | TEST_F(LayerSnapshotTest, RelativeParentCanHideChild) { | 
|  | reparentRelativeLayer(13, 11); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 11, 13, 111, 12, 121, 122, 1221, 2}); | 
|  |  | 
|  | hideLayer(11); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 2}); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, ReparentingToHiddenRelativeParentHidesChild) { | 
|  | hideLayer(11); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 13, 2}); | 
|  | reparentRelativeLayer(13, 11); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 12, 121, 122, 1221, 2}); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, AlphaInheritedByChildren) { | 
|  | setAlpha(1, 0.5); | 
|  | setAlpha(122, 0.5); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot(1)->alpha, 0.5f); | 
|  | EXPECT_EQ(getSnapshot(12)->alpha, 0.5f); | 
|  | EXPECT_EQ(getSnapshot(1221)->alpha, 0.25f); | 
|  | } | 
|  |  | 
|  | // Change states | 
|  | TEST_F(LayerSnapshotTest, UpdateClearsPreviousChangeStates) { | 
|  | setCrop(1, Rect(1, 2, 3, 4)); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_TRUE(getSnapshot(1)->changes.test(RequestedLayerState::Changes::Geometry)); | 
|  | EXPECT_TRUE(getSnapshot(11)->changes.test(RequestedLayerState::Changes::Geometry)); | 
|  | setCrop(2, Rect(1, 2, 3, 4)); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_TRUE(getSnapshot(2)->changes.test(RequestedLayerState::Changes::Geometry)); | 
|  | EXPECT_FALSE(getSnapshot(1)->changes.test(RequestedLayerState::Changes::Geometry)); | 
|  | EXPECT_FALSE(getSnapshot(11)->changes.test(RequestedLayerState::Changes::Geometry)); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, FastPathClearsPreviousChangeStates) { | 
|  | setColor(11, {1._hf, 0._hf, 0._hf}); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot(11)->changes, RequestedLayerState::Changes::Content); | 
|  | EXPECT_EQ(getSnapshot(11)->clientChanges, layer_state_t::eColorChanged); | 
|  | EXPECT_EQ(getSnapshot(1)->changes.get(), 0u); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot(11)->changes.get(), 0u); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, FastPathSetsChangeFlagToContent) { | 
|  | setColor(1, {1._hf, 0._hf, 0._hf}); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot(1)->changes, RequestedLayerState::Changes::Content); | 
|  | EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eColorChanged); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, GameMode) { | 
|  | std::vector<TransactionState> transactions; | 
|  | transactions.emplace_back(); | 
|  | transactions.back().states.push_back({}); | 
|  | transactions.back().states.front().state.what = layer_state_t::eMetadataChanged; | 
|  | transactions.back().states.front().state.metadata = LayerMetadata(); | 
|  | transactions.back().states.front().state.metadata.setInt32(METADATA_GAME_MODE, 42); | 
|  | transactions.back().states.front().layerId = 1; | 
|  | transactions.back().states.front().state.layerId = static_cast<int32_t>(1); | 
|  | mLifecycleManager.applyTransactions(transactions); | 
|  | EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::GameMode); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eMetadataChanged); | 
|  | EXPECT_EQ(static_cast<int32_t>(getSnapshot(1)->gameMode), 42); | 
|  | EXPECT_EQ(static_cast<int32_t>(getSnapshot(11)->gameMode), 42); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, NoLayerVoteForParentWithChildVotes) { | 
|  | // ROOT | 
|  | // ├── 1 | 
|  | // │   ├── 11 (frame rate set) | 
|  | // │   │   └── 111 | 
|  | // │   ├── 12 | 
|  | // │   │   ├── 121 | 
|  | // │   │   └── 122 | 
|  | // │   │       └── 1221 | 
|  | // │   └── 13 | 
|  | // └── 2 | 
|  |  | 
|  | std::vector<TransactionState> transactions; | 
|  | transactions.emplace_back(); | 
|  | transactions.back().states.push_back({}); | 
|  | transactions.back().states.front().state.what = layer_state_t::eFrameRateChanged; | 
|  | transactions.back().states.front().state.frameRate = 90.0; | 
|  | transactions.back().states.front().state.frameRateCompatibility = | 
|  | ANATIVEWINDOW_FRAME_RATE_EXACT; | 
|  | transactions.back().states.front().state.changeFrameRateStrategy = | 
|  | ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS; | 
|  | transactions.back().states.front().layerId = 11; | 
|  | mLifecycleManager.applyTransactions(transactions); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  |  | 
|  | EXPECT_EQ(getSnapshot(11)->frameRate.vote.rate.getIntValue(), 90); | 
|  | EXPECT_EQ(getSnapshot(11)->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Exact); | 
|  | EXPECT_EQ(getSnapshot(111)->frameRate.vote.rate.getIntValue(), 90); | 
|  | EXPECT_EQ(getSnapshot(111)->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Exact); | 
|  | EXPECT_EQ(getSnapshot(1)->frameRate.vote.rate.getIntValue(), 0); | 
|  | EXPECT_EQ(getSnapshot(1)->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::NoVote); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, CanCropTouchableRegion) { | 
|  | // ROOT | 
|  | // ├── 1 | 
|  | // │   ├── 11 | 
|  | // │   │   └── 111 (touchregion set to touch but cropped by layer 13) | 
|  | // │   ├── 12 | 
|  | // │   │   ├── 121 | 
|  | // │   │   └── 122 | 
|  | // │   │       └── 1221 | 
|  | // │   └── 13 (crop set to touchCrop) | 
|  | // └── 2 | 
|  |  | 
|  | Rect touchCrop{300, 300, 400, 500}; | 
|  | setCrop(13, touchCrop); | 
|  | Region touch{Rect{0, 0, 1000, 1000}}; | 
|  | setTouchableRegionCrop(111, touch, /*touchCropId=*/13, /*replaceTouchableRegionWithCrop=*/true); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot({.id = 111})->inputInfo.touchableRegion.bounds(), touchCrop); | 
|  |  | 
|  | Rect modifiedTouchCrop{100, 300, 400, 700}; | 
|  | setCrop(13, modifiedTouchCrop); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot({.id = 111})->inputInfo.touchableRegion.bounds(), modifiedTouchCrop); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, blurUpdatesWhenAlphaChanges) { | 
|  | int blurRadius = 42; | 
|  | setBackgroundBlurRadius(1221, static_cast<uint32_t>(blurRadius)); | 
|  |  | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot({.id = 1221})->backgroundBlurRadius, blurRadius); | 
|  |  | 
|  | blurRadius = 21; | 
|  | setBackgroundBlurRadius(1221, static_cast<uint32_t>(blurRadius)); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot({.id = 1221})->backgroundBlurRadius, blurRadius); | 
|  |  | 
|  | static constexpr float alpha = 0.5; | 
|  | setAlpha(12, alpha); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot({.id = 1221})->backgroundBlurRadius, | 
|  | static_cast<int>(static_cast<float>(blurRadius) * alpha)); | 
|  | } | 
|  |  | 
|  | // Display Mirroring Tests | 
|  | // tree with 3 levels of children | 
|  | // ROOT (DISPLAY 0) | 
|  | // ├── 1 | 
|  | // │   ├── 11 | 
|  | // │   │   └── 111 | 
|  | // │   ├── 12 (has skip screenshot flag) | 
|  | // │   │   ├── 121 | 
|  | // │   │   └── 122 | 
|  | // │   │       └── 1221 | 
|  | // │   └── 13 | 
|  | // └── 2 | 
|  | // ROOT (DISPLAY 1) | 
|  | // └── 3 (mirrors display 0) | 
|  | TEST_F(LayerSnapshotTest, displayMirrorRespectsLayerSkipScreenshotFlag) { | 
|  | setFlags(12, layer_state_t::eLayerSkipScreenshot, layer_state_t::eLayerSkipScreenshot); | 
|  | createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0)); | 
|  | setLayerStack(3, 1); | 
|  |  | 
|  | std::vector<uint32_t> expected = {1, 11, 111, 12, 121, 122, 1221, 13, 2, 3, 1, 11, 111, 13, 2}; | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, expected); | 
|  | } | 
|  |  | 
|  | // ROOT (DISPLAY 0) | 
|  | // ├── 1 | 
|  | // │   ├── 11 | 
|  | // │   │   └── 111 | 
|  | // │   └── 13 | 
|  | // └── 2 | 
|  | // ROOT (DISPLAY 3) | 
|  | // └── 3 (mirrors display 0) | 
|  | TEST_F(LayerSnapshotTest, mirrorLayerGetsCorrectLayerStack) { | 
|  | reparentLayer(12, UNASSIGNED_LAYER_ID); | 
|  | createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0)); | 
|  | setLayerStack(3, 3); | 
|  | createDisplayMirrorLayer(4, ui::LayerStack::fromValue(0)); | 
|  | setLayerStack(4, 4); | 
|  |  | 
|  | std::vector<uint32_t> expected = {1,  11, 111, 13, 2,  3,   1,  11, 111, | 
|  | 13, 2,  4,   1,  11, 111, 13, 2}; | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, expected); | 
|  | EXPECT_EQ(getSnapshot({.id = 111, .mirrorRootIds = 3u})->outputFilter.layerStack.id, 3u); | 
|  | EXPECT_EQ(getSnapshot({.id = 111, .mirrorRootIds = 4u})->outputFilter.layerStack.id, 4u); | 
|  | } | 
|  |  | 
|  | // ROOT (DISPLAY 0) | 
|  | // ├── 1 (crop 50x50) | 
|  | // │   ├── 11 | 
|  | // │   │   └── 111 | 
|  | // │   └── 13 | 
|  | // └── 2 | 
|  | // ROOT (DISPLAY 3) | 
|  | // └── 3 (mirrors display 0) (crop 100x100) | 
|  | TEST_F(LayerSnapshotTest, mirrorLayerTouchIsCroppedByMirrorRoot) { | 
|  | reparentLayer(12, UNASSIGNED_LAYER_ID); | 
|  | createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0)); | 
|  | setLayerStack(3, 3); | 
|  | setCrop(1, Rect{50, 50}); | 
|  | setCrop(3, Rect{100, 100}); | 
|  | setCrop(111, Rect{200, 200}); | 
|  | Region touch{Rect{0, 0, 1000, 1000}}; | 
|  | setTouchableRegion(111, touch); | 
|  | std::vector<uint32_t> expected = {1, 11, 111, 13, 2, 3, 1, 11, 111, 13, 2}; | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, expected); | 
|  | EXPECT_TRUE(getSnapshot({.id = 111})->inputInfo.touchableRegion.hasSameRects(touch)); | 
|  | Region touchCroppedByMirrorRoot{Rect{0, 0, 50, 50}}; | 
|  | EXPECT_TRUE(getSnapshot({.id = 111, .mirrorRootIds = 3u}) | 
|  | ->inputInfo.touchableRegion.hasSameRects(touchCroppedByMirrorRoot)); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, canRemoveDisplayMirror) { | 
|  | setFlags(12, layer_state_t::eLayerSkipScreenshot, layer_state_t::eLayerSkipScreenshot); | 
|  | createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0)); | 
|  | setLayerStack(3, 1); | 
|  | std::vector<uint32_t> expected = {1, 11, 111, 12, 121, 122, 1221, 13, 2, 3, 1, 11, 111, 13, 2}; | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, expected); | 
|  | destroyLayerHandle(3); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, cleanUpUnreachableSnapshotsAfterMirroring) { | 
|  | size_t startingNumSnapshots = mSnapshotBuilder.getSnapshots().size(); | 
|  | createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0)); | 
|  | setLayerStack(3, 1); | 
|  | std::vector<uint32_t> expected = {1, 11, 111, 12, 121, 122, 1221, 13, 2, 3, | 
|  | 1, 11, 111, 12, 121, 122, 1221, 13, 2}; | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, expected); | 
|  | destroyLayerHandle(3); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  |  | 
|  | EXPECT_EQ(startingNumSnapshots, mSnapshotBuilder.getSnapshots().size()); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, canMirrorDisplayWithMirrors) { | 
|  | reparentLayer(12, UNASSIGNED_LAYER_ID); | 
|  | 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); | 
|  |  | 
|  | createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0)); | 
|  | setLayerStack(3, 3); | 
|  | expected = {1, 11, 111, 13, 14, 11, 111, 2, 3, 1, 11, 111, 13, 14, 11, 111, 2}; | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, expected); | 
|  | EXPECT_EQ(getSnapshot({.id = 11, .mirrorRootIds = 14u})->outputFilter.layerStack.id, 0u); | 
|  | EXPECT_EQ(getSnapshot({.id = 11, .mirrorRootIds = 3u})->outputFilter.layerStack.id, 3u); | 
|  | EXPECT_EQ(getSnapshot({.id = 11, .mirrorRootIds = 3u, 14u})->outputFilter.layerStack.id, 3u); | 
|  | } | 
|  |  | 
|  | // Rel z doesn't create duplicate snapshots but this is for completeness | 
|  | TEST_F(LayerSnapshotTest, cleanUpUnreachableSnapshotsAfterRelZ) { | 
|  | size_t startingNumSnapshots = mSnapshotBuilder.getSnapshots().size(); | 
|  | reparentRelativeLayer(13, 11); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, {1, 11, 13, 111, 12, 121, 122, 1221, 2}); | 
|  | setZ(13, 0); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  |  | 
|  | EXPECT_EQ(startingNumSnapshots, mSnapshotBuilder.getSnapshots().size()); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, cleanUpUnreachableSnapshotsAfterLayerDestruction) { | 
|  | size_t startingNumSnapshots = mSnapshotBuilder.getSnapshots().size(); | 
|  | destroyLayerHandle(2); | 
|  | destroyLayerHandle(122); | 
|  |  | 
|  | std::vector<uint32_t> expected = {1, 11, 111, 12, 121, 122, 1221, 13}; | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, expected); | 
|  |  | 
|  | EXPECT_LE(startingNumSnapshots - 2, mSnapshotBuilder.getSnapshots().size()); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, snashotContainsMetadataFromLayerCreationArgs) { | 
|  | LayerCreationArgs args(std::make_optional<uint32_t>(200)); | 
|  | args.name = "testlayer"; | 
|  | args.addToRoot = true; | 
|  | args.metadata.setInt32(42, 24); | 
|  |  | 
|  | std::vector<std::unique_ptr<RequestedLayerState>> layers; | 
|  | layers.emplace_back(std::make_unique<RequestedLayerState>(args)); | 
|  | EXPECT_TRUE(layers.back()->metadata.has(42)); | 
|  | EXPECT_EQ(layers.back()->metadata.getInt32(42, 0), 24); | 
|  | mLifecycleManager.addLayers(std::move(layers)); | 
|  |  | 
|  | std::vector<uint32_t> expected = STARTING_ZORDER; | 
|  | expected.push_back(200); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, expected); | 
|  |  | 
|  | EXPECT_TRUE(mSnapshotBuilder.getSnapshot(200)->layerMetadata.has(42)); | 
|  | EXPECT_EQ(mSnapshotBuilder.getSnapshot(200)->layerMetadata.getInt32(42, 0), 24); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, frameRateSelectionPriorityPassedToChildLayers) { | 
|  | setFrameRateSelectionPriority(11, 1); | 
|  |  | 
|  | setFrameRateSelectionPriority(12, 2); | 
|  |  | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot({.id = 1})->frameRateSelectionPriority, Layer::PRIORITY_UNSET); | 
|  | EXPECT_EQ(getSnapshot({.id = 11})->frameRateSelectionPriority, 1); | 
|  | EXPECT_EQ(getSnapshot({.id = 12})->frameRateSelectionPriority, 2); | 
|  | EXPECT_EQ(getSnapshot({.id = 122})->frameRateSelectionPriority, 2); | 
|  | EXPECT_EQ(getSnapshot({.id = 1221})->frameRateSelectionPriority, 2); | 
|  |  | 
|  | // reparent and verify the child gets the new parent's framerate selection priority | 
|  | reparentLayer(122, 11); | 
|  |  | 
|  | std::vector<uint32_t> expected = {1, 11, 111, 122, 1221, 12, 121, 13, 2}; | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, expected); | 
|  | EXPECT_EQ(getSnapshot({.id = 1})->frameRateSelectionPriority, Layer::PRIORITY_UNSET); | 
|  | EXPECT_EQ(getSnapshot({.id = 11})->frameRateSelectionPriority, 1); | 
|  | EXPECT_EQ(getSnapshot({.id = 12})->frameRateSelectionPriority, 2); | 
|  | EXPECT_EQ(getSnapshot({.id = 122})->frameRateSelectionPriority, 1); | 
|  | EXPECT_EQ(getSnapshot({.id = 1221})->frameRateSelectionPriority, 1); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, framerate) { | 
|  | setFrameRate(11, 244.f, 0, 0); | 
|  |  | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | // verify parent is gets no vote | 
|  | EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::NoVote); | 
|  | EXPECT_TRUE(getSnapshot({.id = 1})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  |  | 
|  | // verify layer and children get the requested votes | 
|  | EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.rate.getValue(), 244.f); | 
|  | EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  | EXPECT_TRUE(getSnapshot({.id = 11})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  |  | 
|  | EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.rate.getValue(), 244.f); | 
|  | EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  | EXPECT_TRUE(getSnapshot({.id = 111})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  |  | 
|  | // reparent and verify the child gets the new parent's framerate | 
|  | reparentLayer(122, 11); | 
|  |  | 
|  | std::vector<uint32_t> expected = {1, 11, 111, 122, 1221, 12, 121, 13, 2}; | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, expected); | 
|  | // verify parent is gets no vote | 
|  | EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::NoVote); | 
|  |  | 
|  | // verify layer and children get the requested votes | 
|  | EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.rate.getValue(), 244.f); | 
|  | EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  |  | 
|  | EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.rate.getValue(), 244.f); | 
|  | EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  |  | 
|  | EXPECT_TRUE(getSnapshot({.id = 122})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.rate.getValue(), 244.f); | 
|  | EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  | EXPECT_TRUE(getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  |  | 
|  | // reparent and verify the new parent gets no vote | 
|  | reparentLayer(11, 2); | 
|  | expected = {1, 12, 121, 13, 2, 11, 111, 122, 1221}; | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, expected); | 
|  |  | 
|  | // verify old parent has invalid framerate (default) | 
|  | EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  | EXPECT_TRUE(getSnapshot({.id = 1})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  |  | 
|  | // verify new parent get no vote | 
|  | EXPECT_FALSE(getSnapshot({.id = 2})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 2})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::NoVote); | 
|  | EXPECT_TRUE(getSnapshot({.id = 2})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  |  | 
|  | // verify layer and children get the requested votes (unchanged) | 
|  | EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.rate.getValue(), 244.f); | 
|  | EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  |  | 
|  | EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.rate.getValue(), 244.f); | 
|  | EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  |  | 
|  | EXPECT_TRUE(getSnapshot({.id = 122})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.rate.getValue(), 244.f); | 
|  | EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, translateDataspace) { | 
|  | setDataspace(1, ui::Dataspace::UNKNOWN); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot({.id = 1})->dataspace, ui::Dataspace::V0_SRGB); | 
|  | } | 
|  |  | 
|  | // This test is similar to "frameRate" test case but checks that the setFrameRateCategory API | 
|  | // interaction also works correctly with the setFrameRate API within SF frontend. | 
|  | TEST_F(LayerSnapshotTest, frameRateWithCategory) { | 
|  | // ROOT | 
|  | // ├── 1 | 
|  | // │   ├── 11 (frame rate set to 244.f) | 
|  | // │   │   └── 111 | 
|  | // │   ├── 12 | 
|  | // │   │   ├── 121 | 
|  | // │   │   └── 122 (frame rate category set to Normal) | 
|  | // │   │       └── 1221 | 
|  | // │   └── 13 | 
|  | // └── 2 | 
|  | setFrameRate(11, 244.f, 0, 0); | 
|  | setFrameRateCategory(122, 3 /* Normal */); | 
|  |  | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | // verify parent 1 gets no vote | 
|  | EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::NoVote); | 
|  | EXPECT_TRUE(getSnapshot({.id = 1})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  |  | 
|  | // verify layer 11 and children 111 get the requested votes | 
|  | EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.rate.getValue(), 244.f); | 
|  | EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  | EXPECT_TRUE(getSnapshot({.id = 11})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  |  | 
|  | EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.rate.getValue(), 244.f); | 
|  | EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  | EXPECT_TRUE(getSnapshot({.id = 111})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  |  | 
|  | // verify parent 12 gets no vote | 
|  | EXPECT_FALSE(getSnapshot({.id = 12})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 12})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::NoVote); | 
|  | EXPECT_TRUE(getSnapshot({.id = 12})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  |  | 
|  | // verify layer 122 and children 1221 get the requested votes | 
|  | EXPECT_FALSE(getSnapshot({.id = 122})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_TRUE(getSnapshot({.id = 122})->frameRate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  | EXPECT_EQ(getSnapshot({.id = 122})->frameRate.category, FrameRateCategory::Normal); | 
|  | EXPECT_TRUE(getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  | EXPECT_TRUE( | 
|  | getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::AffectsChildren)); | 
|  |  | 
|  | EXPECT_FALSE(getSnapshot({.id = 1221})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_TRUE(getSnapshot({.id = 1221})->frameRate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  | EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.category, FrameRateCategory::Normal); | 
|  | EXPECT_TRUE(getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  | EXPECT_TRUE( | 
|  | getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::AffectsChildren)); | 
|  |  | 
|  | // reparent and verify the child does NOT get the new parent's framerate because it already has | 
|  | // the frame rate category specified. | 
|  | // ROOT | 
|  | //  ├─1 | 
|  | //  │  ├─11 (frame rate set to 244.f) | 
|  | //  │  │  ├─111 | 
|  | //  │  │  └─122 (frame rate category set to Normal) | 
|  | //  │  │     └─1221 | 
|  | //  │  ├─12 | 
|  | //  │  │  └─121 | 
|  | //  │  └─13 | 
|  | //  └─2 | 
|  | reparentLayer(122, 11); | 
|  |  | 
|  | std::vector<uint32_t> expected = {1, 11, 111, 122, 1221, 12, 121, 13, 2}; | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, expected); | 
|  | // verify parent is gets no vote | 
|  | EXPECT_FALSE(getSnapshot({.id = 1})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 1})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::NoVote); | 
|  |  | 
|  | // verify layer 11 and children 111 get the requested votes | 
|  | EXPECT_TRUE(getSnapshot({.id = 11})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.rate.getValue(), 244.f); | 
|  | EXPECT_EQ(getSnapshot({.id = 11})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  |  | 
|  | EXPECT_TRUE(getSnapshot({.id = 111})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.rate.getValue(), 244.f); | 
|  | EXPECT_EQ(getSnapshot({.id = 111})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  |  | 
|  | // verify layer 122 and children 1221 get the requested category vote (unchanged from | 
|  | // reparenting) | 
|  | EXPECT_FALSE(getSnapshot({.id = 122})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_TRUE(getSnapshot({.id = 122})->frameRate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 122})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  | EXPECT_EQ(getSnapshot({.id = 122})->frameRate.category, FrameRateCategory::Normal); | 
|  | EXPECT_TRUE(getSnapshot({.id = 122})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  |  | 
|  | EXPECT_FALSE(getSnapshot({.id = 1221})->frameRate.vote.rate.isValid()); | 
|  | EXPECT_TRUE(getSnapshot({.id = 1221})->frameRate.isValid()); | 
|  | EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.vote.type, | 
|  | scheduler::LayerInfo::FrameRateCompatibility::Default); | 
|  | EXPECT_EQ(getSnapshot({.id = 1221})->frameRate.category, FrameRateCategory::Normal); | 
|  | EXPECT_TRUE(getSnapshot({.id = 1221})->changes.test(RequestedLayerState::Changes::FrameRate)); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, skipRoundCornersWhenProtected) { | 
|  | setRoundedCorners(1, 42.f); | 
|  | setRoundedCorners(2, 42.f); | 
|  | setCrop(1, Rect{1000, 1000}); | 
|  | setCrop(2, Rect{1000, 1000}); | 
|  |  | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_TRUE(getSnapshot({.id = 1})->roundedCorner.hasRoundedCorners()); | 
|  | EXPECT_EQ(getSnapshot({.id = 1})->roundedCorner.radius.x, 42.f); | 
|  | EXPECT_TRUE(getSnapshot({.id = 2})->roundedCorner.hasRoundedCorners()); | 
|  |  | 
|  | // add a buffer with the protected bit, check rounded corners are not set when | 
|  | // skipRoundCornersWhenProtected == true | 
|  | setBuffer(1, | 
|  | std::make_shared< | 
|  | renderengine::mock::FakeExternalTexture>(1U /*width*/, 1U /*height*/, | 
|  | 1ULL /* bufferId */, | 
|  | HAL_PIXEL_FORMAT_RGBA_8888, | 
|  | GRALLOC_USAGE_PROTECTED /*usage*/)); | 
|  |  | 
|  | LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(), | 
|  | .layerLifecycleManager = mLifecycleManager, | 
|  | .includeMetadata = false, | 
|  | .displays = mFrontEndDisplayInfos, | 
|  | .displayChanges = false, | 
|  | .globalShadowSettings = globalShadowSettings, | 
|  | .supportsBlur = true, | 
|  | .supportedLayerGenericMetadata = {}, | 
|  | .genericLayerMetadataKeyMap = {}, | 
|  | .skipRoundCornersWhenProtected = true}; | 
|  | update(mSnapshotBuilder, args); | 
|  | EXPECT_FALSE(getSnapshot({.id = 1})->roundedCorner.hasRoundedCorners()); | 
|  | // layer 2 doesn't have a buffer and should be unaffected | 
|  | EXPECT_TRUE(getSnapshot({.id = 2})->roundedCorner.hasRoundedCorners()); | 
|  |  | 
|  | // remove protected bit, check rounded corners are set | 
|  | setBuffer(1, | 
|  | std::make_shared<renderengine::mock::FakeExternalTexture>(1U /*width*/, 1U /*height*/, | 
|  | 2ULL /* bufferId */, | 
|  | HAL_PIXEL_FORMAT_RGBA_8888, | 
|  | 0 /*usage*/)); | 
|  | update(mSnapshotBuilder, args); | 
|  | EXPECT_TRUE(getSnapshot({.id = 1})->roundedCorner.hasRoundedCorners()); | 
|  | EXPECT_EQ(getSnapshot({.id = 1})->roundedCorner.radius.x, 42.f); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, setRefreshRateIndicatorCompositionType) { | 
|  | setFlags(1, layer_state_t::eLayerIsRefreshRateIndicator, | 
|  | layer_state_t::eLayerIsRefreshRateIndicator); | 
|  | setBuffer(1, | 
|  | std::make_shared<renderengine::mock::FakeExternalTexture>(1U /*width*/, 1U /*height*/, | 
|  | 42ULL /* bufferId */, | 
|  | HAL_PIXEL_FORMAT_RGBA_8888, | 
|  | 0 /*usage*/)); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot({.id = 1})->compositionType, | 
|  | aidl::android::hardware::graphics::composer3::Composition::REFRESH_RATE_INDICATOR); | 
|  | } | 
|  |  | 
|  | TEST_F(LayerSnapshotTest, setBufferCrop) { | 
|  | // validate no buffer but has crop | 
|  | Rect crop = Rect(0, 0, 50, 50); | 
|  | setBufferCrop(1, crop); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot(1)->geomContentCrop, crop); | 
|  |  | 
|  | setBuffer(1, | 
|  | std::make_shared<renderengine::mock::FakeExternalTexture>(100U /*width*/, | 
|  | 100U /*height*/, | 
|  | 42ULL /* bufferId */, | 
|  | HAL_PIXEL_FORMAT_RGBA_8888, | 
|  | 0 /*usage*/)); | 
|  | // validate a buffer crop within the buffer bounds | 
|  | setBufferCrop(1, crop); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot(1)->geomContentCrop, crop); | 
|  |  | 
|  | // validate a buffer crop outside the buffer bounds | 
|  | crop = Rect(0, 0, 150, 150); | 
|  | setBufferCrop(1, crop); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot(1)->geomContentCrop, Rect(0, 0, 100, 100)); | 
|  |  | 
|  | // validate no buffer crop | 
|  | setBufferCrop(1, Rect()); | 
|  | UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); | 
|  | EXPECT_EQ(getSnapshot(1)->geomContentCrop, Rect(0, 0, 100, 100)); | 
|  | } | 
|  | } // namespace android::surfaceflinger::frontend |