/* * Copyright 2024 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 #include #include #include #include #include #include #include #include "ActivePictureUpdater.h" #include "LayerFE.h" #include "TestableSurfaceFlinger.h" namespace android { using android::compositionengine::LayerFECompositionState; using android::gui::ActivePicture; using android::gui::IActivePictureListener; using android::mock::MockLayer; using surfaceflinger::frontend::LayerSnapshot; using testing::_; using testing::NiceMock; using testing::Return; class TestableLayerFE : public LayerFE { public: TestableLayerFE() : LayerFE("TestableLayerFE"), snapshot(*(new LayerSnapshot)) { mSnapshot = std::unique_ptr(&snapshot); } LayerSnapshot& snapshot; }; class ActivePictureUpdaterTest : public testing::Test { protected: SurfaceFlinger* flinger() { if (!mFlingerSetup) { mFlinger.setupMockScheduler(); mFlinger.setupComposer(std::make_unique()); mFlinger.setupRenderEngine(std::make_unique()); mFlingerSetup = true; } return mFlinger.flinger(); } private: TestableSurfaceFlinger mFlinger; bool mFlingerSetup = false; }; // Hack to workaround initializer lists not working for parcelables because parcelables inherit from // Parcelable, which has a virtual destructor. auto UnorderedElementsAre(std::initializer_list> tuples) { std::vector activePictures; for (auto tuple : tuples) { ActivePicture ap; ap.layerId = std::get<0>(tuple); ap.ownerUid = std::get<1>(tuple); ap.pictureProfileId = std::get<2>(tuple); activePictures.push_back(ap); } return testing::UnorderedElementsAreArray(activePictures); } // Parcelables don't define this for matchers, which is unfortunate void PrintTo(const ActivePicture& activePicture, std::ostream* os) { *os << activePicture.toString(); } TEST_F(ActivePictureUpdaterTest, notCalledWithNoProfile) { sp> layer = sp>::make(flinger(), 100); TestableLayerFE layerFE; EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureUpdater updater; { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE; updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); ASSERT_FALSE(updater.updateAndHasChanged()); } } TEST_F(ActivePictureUpdaterTest, calledWhenLayerStartsUsingProfile) { sp> layer = sp>::make(flinger(), 100); TestableLayerFE layerFE; EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureUpdater updater; { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE; updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); ASSERT_FALSE(updater.updateAndHasChanged()); } { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE.onPictureProfileCommitted(); updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); } } TEST_F(ActivePictureUpdaterTest, notCalledWhenLayerContinuesUsingProfile) { sp> layer = sp>::make(flinger(), 100); TestableLayerFE layerFE; EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureUpdater updater; { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE.onPictureProfileCommitted(); updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); } { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE.onPictureProfileCommitted(); updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); ASSERT_FALSE(updater.updateAndHasChanged()); } } TEST_F(ActivePictureUpdaterTest, calledWhenLayerStopsUsingProfile) { sp> layer = sp>::make(flinger(), 100); TestableLayerFE layerFE; EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureUpdater updater; { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE.onPictureProfileCommitted(); updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); } { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE; updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({})); } } TEST_F(ActivePictureUpdaterTest, calledWhenLayerChangesProfile) { sp> layer = sp>::make(flinger(), 100); TestableLayerFE layerFE; EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureUpdater updater; { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE.onPictureProfileCommitted(); updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); } { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(2); layerFE.onPictureProfileCommitted(); updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 2}})); } } TEST_F(ActivePictureUpdaterTest, notCalledWhenUncommittedLayerChangesProfile) { sp> layer1 = sp>::make(flinger(), 100); TestableLayerFE layerFE1; EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); sp> layer2 = sp>::make(flinger(), 200); TestableLayerFE layerFE2; EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(20))); ActivePictureUpdater updater; { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE1.onPictureProfileCommitted(); updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); } { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE1.onPictureProfileCommitted(); updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2); updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); ASSERT_FALSE(updater.updateAndHasChanged()); } } TEST_F(ActivePictureUpdaterTest, calledWhenDifferentLayerUsesSameProfile) { sp> layer1 = sp>::make(flinger(), 100); TestableLayerFE layerFE1; EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); sp> layer2 = sp>::make(flinger(), 200); TestableLayerFE layerFE2; EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(20))); ActivePictureUpdater updater; { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE1.onPictureProfileCommitted(); updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2); layerFE2.onPictureProfileCommitted(); updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}, {200, 20, 2}})); } { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(2); layerFE1.onPictureProfileCommitted(); updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE2.onPictureProfileCommitted(); updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 2}, {200, 20, 1}})); } } TEST_F(ActivePictureUpdaterTest, calledWhenSameUidUsesSameProfile) { sp> layer1 = sp>::make(flinger(), 100); TestableLayerFE layerFE1; EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); sp> layer2 = sp>::make(flinger(), 200); TestableLayerFE layerFE2; EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureUpdater updater; { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE1.onPictureProfileCommitted(); updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2); layerFE2.onPictureProfileCommitted(); updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}, {200, 10, 2}})); } { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(2); layerFE1.onPictureProfileCommitted(); updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE2.onPictureProfileCommitted(); updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 2}, {200, 10, 1}})); } } TEST_F(ActivePictureUpdaterTest, calledWhenNewLayerUsesSameProfile) { sp> layer1 = sp>::make(flinger(), 100); TestableLayerFE layerFE1; EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureUpdater updater; { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE1.onPictureProfileCommitted(); updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); } sp> layer2 = sp>::make(flinger(), 200); TestableLayerFE layerFE2; EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE1.onPictureProfileCommitted(); updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE2.onPictureProfileCommitted(); updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); ASSERT_TRUE(updater.updateAndHasChanged()); EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}, {200, 10, 1}})); } } } // namespace android