diff options
author | 2024-12-06 08:07:16 -0700 | |
---|---|---|
committer | 2024-12-06 10:33:23 -0700 | |
commit | f1cfbf6417bef270f83e6cae3f1c0d5d0082ad1e (patch) | |
tree | cd2f480c41235cf796334dbf55c4a4d5303685a4 | |
parent | e8334907786ff4ac63d3ba9cccc12c4dbd8f501e (diff) |
Support multiple active picture listeners
Bug: 337330263
Test: atest SurfaceControlPictureProfileTest
Test: atest ActivePictureTrackerTest
Flag: com.android.graphics.libgui.flags.apply_picture_profiles
Change-Id: If030b3f6177b6bd641ed7953b10a37319c9e537a
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 11 | ||||
-rw-r--r-- | libs/gui/aidl/android/gui/ISurfaceComposer.aidl | 10 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 4 | ||||
-rw-r--r-- | libs/gui/tests/Surface_test.cpp | 6 | ||||
-rw-r--r-- | services/surfaceflinger/ActivePictureTracker.cpp | 44 | ||||
-rw-r--r-- | services/surfaceflinger/ActivePictureTracker.h | 10 | ||||
-rw-r--r-- | services/surfaceflinger/Android.bp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 55 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 12 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/ActivePictureTrackerTest.cpp | 185 |
10 files changed, 238 insertions, 101 deletions
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index be88b11b9c..cabde22c6d 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -3293,10 +3293,17 @@ status_t SurfaceComposerClient::removeHdrLayerInfoListener( return statusTFromBinderStatus(status); } -status_t SurfaceComposerClient::setActivePictureListener( +status_t SurfaceComposerClient::addActivePictureListener( const sp<gui::IActivePictureListener>& listener) { binder::Status status = - ComposerServiceAIDL::getComposerService()->setActivePictureListener(listener); + ComposerServiceAIDL::getComposerService()->addActivePictureListener(listener); + return statusTFromBinderStatus(status); +} + +status_t SurfaceComposerClient::removeActivePictureListener( + const sp<gui::IActivePictureListener>& listener) { + binder::Status status = + ComposerServiceAIDL::getComposerService()->removeActivePictureListener(listener); return statusTFromBinderStatus(status); } diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl index 8c19bbbba9..da47ee27ba 100644 --- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl +++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl @@ -607,8 +607,14 @@ interface ISurfaceComposer { oneway void removeJankListener(int layerId, IJankListener listener, long afterVsync); /** - * Sets the listener used to monitor visible content that is being processed with picture + * Adds a listener used to monitor visible content that is being processed with picture * profiles. */ - oneway void setActivePictureListener(IActivePictureListener listener); + oneway void addActivePictureListener(IActivePictureListener listener); + + /** + * Removes a listener used to monitor visible content that is being processed with picture + * profiles. + */ + oneway void removeActivePictureListener(IActivePictureListener listener); } diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 0ce0c0a9c3..0f66c8b492 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -298,7 +298,9 @@ public: static status_t removeHdrLayerInfoListener(const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener); - static status_t setActivePictureListener(const sp<gui::IActivePictureListener>& listener); + static status_t addActivePictureListener(const sp<gui::IActivePictureListener>& listener); + + static status_t removeActivePictureListener(const sp<gui::IActivePictureListener>& listener); /* * Sends a power boost to the composer. This function is asynchronous. diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 76362ff272..3185778acf 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -1016,7 +1016,11 @@ public: return binder::Status::ok(); } - binder::Status setActivePictureListener(const sp<gui::IActivePictureListener>&) { + binder::Status addActivePictureListener(const sp<gui::IActivePictureListener>&) { + return binder::Status::ok(); + } + + binder::Status removeActivePictureListener(const sp<gui::IActivePictureListener>&) { return binder::Status::ok(); } diff --git a/services/surfaceflinger/ActivePictureTracker.cpp b/services/surfaceflinger/ActivePictureTracker.cpp index 031940841e..4e6fa66ed8 100644 --- a/services/surfaceflinger/ActivePictureTracker.cpp +++ b/services/surfaceflinger/ActivePictureTracker.cpp @@ -23,6 +23,9 @@ namespace android { +using gui::ActivePicture; +using gui::IActivePictureListener; + void ActivePictureTracker::onLayerComposed(const Layer& layer, const LayerFE& layerFE, const CompositionResult& result) { if (result.wasPictureProfileCommitted) { @@ -39,10 +42,47 @@ void ActivePictureTracker::onLayerComposed(const Layer& layer, const LayerFE& la } } +void ActivePictureTracker::updateAndNotifyListeners(const Listeners& listenersToAdd, + const Listeners& listenersToRemove) { + Listeners newListeners = updateListeners(listenersToAdd, listenersToRemove); + if (updateAndHasChanged()) { + for (auto listener : mListeners) { + listener->onActivePicturesChanged(getActivePictures()); + } + } else { + for (auto listener : newListeners) { + listener->onActivePicturesChanged(getActivePictures()); + } + } +} + +ActivePictureTracker::Listeners ActivePictureTracker::updateListeners( + const Listeners& listenersToAdd, const Listeners& listenersToRemove) { + Listeners newListeners; + for (auto listener : listenersToRemove) { + std::erase_if(mListeners, [listener](const sp<IActivePictureListener>& otherListener) { + return IInterface::asBinder(listener) == IInterface::asBinder(otherListener); + }); + } + for (auto listener : listenersToAdd) { + if (std::find_if(mListeners.begin(), mListeners.end(), + [listener](const sp<IActivePictureListener>& otherListener) { + return IInterface::asBinder(listener) == + IInterface::asBinder(otherListener); + }) == mListeners.end()) { + newListeners.push_back(listener); + } + } + for (auto listener : newListeners) { + mListeners.push_back(listener); + } + return newListeners; +} + bool ActivePictureTracker::updateAndHasChanged() { bool hasChanged = true; if (mNewActivePictures.size() == mOldActivePictures.size()) { - auto compare = [](const gui::ActivePicture& lhs, const gui::ActivePicture& rhs) -> int { + auto compare = [](const ActivePicture& lhs, const ActivePicture& rhs) -> int { if (lhs.layerId == rhs.layerId) { return lhs.pictureProfileId < rhs.pictureProfileId; } @@ -59,7 +99,7 @@ bool ActivePictureTracker::updateAndHasChanged() { return hasChanged; } -const std::vector<gui::ActivePicture>& ActivePictureTracker::getActivePictures() const { +const std::vector<ActivePicture>& ActivePictureTracker::getActivePictures() const { return mOldActivePictures; } diff --git a/services/surfaceflinger/ActivePictureTracker.h b/services/surfaceflinger/ActivePictureTracker.h index 95a698ba7f..cb319a58be 100644 --- a/services/surfaceflinger/ActivePictureTracker.h +++ b/services/surfaceflinger/ActivePictureTracker.h @@ -19,6 +19,7 @@ #include <vector> #include <android/gui/ActivePicture.h> +#include <android/gui/IActivePictureListener.h> namespace android { @@ -29,19 +30,26 @@ struct CompositionResult; // Keeps track of active pictures - layers that are undergoing picture processing. class ActivePictureTracker { public: + typedef std::vector<sp<gui::IActivePictureListener>> Listeners; + // Called for each visible layer when SurfaceFlinger finishes composing. void onLayerComposed(const Layer& layer, const LayerFE& layerFE, const CompositionResult& result); // Update internals and return whether the set of active pictures have changed. - bool updateAndHasChanged(); + void updateAndNotifyListeners(const Listeners& activePictureListenersToAdd, + const Listeners& activePictureListenersToRemove); // The current set of active pictures. const std::vector<gui::ActivePicture>& getActivePictures() const; private: + Listeners updateListeners(const Listeners& listenersToAdd, const Listeners& listenersToRemove); + bool updateAndHasChanged(); + std::vector<gui::ActivePicture> mOldActivePictures; std::vector<gui::ActivePicture> mNewActivePictures; + Listeners mListeners; }; } // namespace android diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 3f3d2c6cc6..0f8d38fcfc 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -199,7 +199,7 @@ filegroup { name: "libsurfaceflinger_sources", srcs: [ ":libsurfaceflinger_backend_sources", - "ActivePictureUpdater.cpp", + "ActivePictureTracker.cpp", "BackgroundExecutor.cpp", "Client.cpp", "ClientCache.cpp", diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1498fffea4..2147a8515e 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -126,7 +126,6 @@ #include <gui/SchedulingPolicy.h> #include <gui/SyncScreenCaptureListener.h> #include <ui/DisplayIdentification.h> -#include "ActivePictureTracker.h" #include "BackgroundExecutor.h" #include "Client.h" #include "ClientCache.h" @@ -3223,8 +3222,8 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, std::vector<std::pair<std::shared_ptr<compositionengine::Display>, sp<HdrLayerInfoReporter>>> hdrInfoListeners; bool haveNewHdrInfoListeners = false; - sp<gui::IActivePictureListener> activePictureListener; - bool haveNewActivePictureListener = false; + ActivePictureTracker::Listeners activePictureListenersToAdd; + ActivePictureTracker::Listeners activePictureListenersToRemove; { Mutex::Autolock lock(mStateLock); if (mFpsReporter) { @@ -3246,9 +3245,8 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, haveNewHdrInfoListeners = mAddingHDRLayerInfoListener; // grab this with state lock mAddingHDRLayerInfoListener = false; - activePictureListener = mActivePictureListener; - haveNewActivePictureListener = mHaveNewActivePictureListener; - mHaveNewActivePictureListener = false; + std::swap(activePictureListenersToAdd, mActivePictureListenersToAdd); + std::swap(activePictureListenersToRemove, mActivePictureListenersToRemove); } if (haveNewHdrInfoListeners || mHdrLayerInfoChanged) { @@ -3312,14 +3310,10 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, mHdrLayerInfoChanged = false; if (com_android_graphics_libgui_flags_apply_picture_profiles()) { - // Track, update and notify changes to active pictures - layers that are undergoing picture - // processing - if (mActivePictureTracker.updateAndHasChanged() || haveNewActivePictureListener) { - if (activePictureListener) { - activePictureListener->onActivePicturesChanged( - mActivePictureTracker.getActivePictures()); - } - } + // Track, update and notify changes to active pictures - layers that are undergoing + // picture processing + mActivePictureTracker.updateAndNotifyListeners(activePictureListenersToAdd, + activePictureListenersToRemove); } mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */); @@ -8171,12 +8165,20 @@ void SurfaceFlinger::updateHdcpLevels(hal::HWDisplayId hwcDisplayId, int32_t con })); } -void SurfaceFlinger::setActivePictureListener(const sp<gui::IActivePictureListener>& listener) { - if (com_android_graphics_libgui_flags_apply_picture_profiles()) { - Mutex::Autolock lock(mStateLock); - mActivePictureListener = listener; - mHaveNewActivePictureListener = listener != nullptr; - } +void SurfaceFlinger::addActivePictureListener(const sp<gui::IActivePictureListener>& listener) { + Mutex::Autolock lock(mStateLock); + std::erase_if(mActivePictureListenersToRemove, [listener](const auto& otherListener) { + return IInterface::asBinder(listener) == IInterface::asBinder(otherListener); + }); + mActivePictureListenersToAdd.push_back(listener); +} + +void SurfaceFlinger::removeActivePictureListener(const sp<gui::IActivePictureListener>& listener) { + Mutex::Autolock lock(mStateLock); + std::erase_if(mActivePictureListenersToAdd, [listener](const auto& otherListener) { + return IInterface::asBinder(listener) == IInterface::asBinder(otherListener); + }); + mActivePictureListenersToRemove.push_back(listener); } std::shared_ptr<renderengine::ExternalTexture> SurfaceFlinger::getExternalTextureFromBufferData( @@ -9129,11 +9131,20 @@ binder::Status SurfaceComposerAIDL::removeHdrLayerInfoListener( return binderStatusFromStatusT(status); } -binder::Status SurfaceComposerAIDL::setActivePictureListener( +binder::Status SurfaceComposerAIDL::addActivePictureListener( + const sp<gui::IActivePictureListener>& listener) { + status_t status = checkObservePictureProfilesPermission(); + if (status == OK) { + mFlinger->addActivePictureListener(listener); + } + return binderStatusFromStatusT(status); +} + +binder::Status SurfaceComposerAIDL::removeActivePictureListener( const sp<gui::IActivePictureListener>& listener) { status_t status = checkObservePictureProfilesPermission(); if (status == OK) { - mFlinger->setActivePictureListener(listener); + mFlinger->removeActivePictureListener(listener); } return binderStatusFromStatusT(status); } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index b16ea082a9..0ae236ff0c 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -667,7 +667,9 @@ private: void updateHdcpLevels(hal::HWDisplayId hwcDisplayId, int32_t connectedLevel, int32_t maxLevel); - void setActivePictureListener(const sp<gui::IActivePictureListener>& listener); + void addActivePictureListener(const sp<gui::IActivePictureListener>& listener); + + void removeActivePictureListener(const sp<gui::IActivePictureListener>& listener); // IBinder::DeathRecipient overrides: void binderDied(const wp<IBinder>& who) override; @@ -1402,9 +1404,9 @@ private: std::unordered_map<DisplayId, sp<HdrLayerInfoReporter>> mHdrLayerInfoListeners GUARDED_BY(mStateLock); - sp<gui::IActivePictureListener> mActivePictureListener GUARDED_BY(mStateLock); - bool mHaveNewActivePictureListener GUARDED_BY(mStateLock); ActivePictureTracker mActivePictureTracker GUARDED_BY(kMainThreadContext); + ActivePictureTracker::Listeners mActivePictureListenersToAdd GUARDED_BY(mStateLock); + ActivePictureTracker::Listeners mActivePictureListenersToRemove GUARDED_BY(mStateLock); std::atomic<ui::Transform::RotationFlags> mActiveDisplayTransformHint; @@ -1641,8 +1643,8 @@ public: binder::Status flushJankData(int32_t layerId) override; binder::Status removeJankListener(int32_t layerId, const sp<gui::IJankListener>& listener, int64_t afterVsync) override; - binder::Status setActivePictureListener(const sp<gui::IActivePictureListener>& listener); - binder::Status clearActivePictureListener(); + binder::Status addActivePictureListener(const sp<gui::IActivePictureListener>& listener); + binder::Status removeActivePictureListener(const sp<gui::IActivePictureListener>& listener); private: static const constexpr bool kUsePermissionCache = true; diff --git a/services/surfaceflinger/tests/unittests/ActivePictureTrackerTest.cpp b/services/surfaceflinger/tests/unittests/ActivePictureTrackerTest.cpp index ff9a4562bf..7d9004aee8 100644 --- a/services/surfaceflinger/tests/unittests/ActivePictureTrackerTest.cpp +++ b/services/surfaceflinger/tests/unittests/ActivePictureTrackerTest.cpp @@ -38,6 +38,8 @@ using surfaceflinger::frontend::LayerSnapshot; using testing::_; using testing::NiceMock; using testing::Return; +using testing::SizeIs; +using testing::StrictMock; class TestableLayerFE : public LayerFE { public: @@ -48,8 +50,20 @@ public: LayerSnapshot& snapshot; }; +class MockActivePictureListener : public gui::BnActivePictureListener { +public: + operator ActivePictureTracker::Listeners const() { + return {sp<IActivePictureListener>::fromExisting(this)}; + } + + MOCK_METHOD(binder::Status, onActivePicturesChanged, (const std::vector<ActivePicture>&), + (override)); +}; + class ActivePictureTrackerTest : public testing::Test { protected: + const static ActivePictureTracker::Listeners NO_LISTENERS; + SurfaceFlinger* flinger() { if (!mFlingerSetup) { mFlinger.setupMockScheduler(); @@ -60,11 +74,26 @@ protected: return mFlinger.flinger(); } + sp<NiceMock<MockLayer>> createMockLayer(int layerId, int ownerUid) { + auto layer = sp<NiceMock<MockLayer>>::make(flinger(), layerId); + EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(ownerUid))); + return layer; + } + + sp<StrictMock<MockActivePictureListener>> createMockListener() { + return sp<StrictMock<MockActivePictureListener>>::make(); + } + + ActivePictureTracker::Listeners mListenersToAdd; + ActivePictureTracker::Listeners mListenersToRemove; + private: TestableSurfaceFlinger mFlinger; bool mFlingerSetup = false; }; +const ActivePictureTracker::Listeners ActivePictureTrackerTest::NO_LISTENERS; + // Hack to workaround initializer lists not working for parcelables because parcelables inherit from // Parcelable, which has a virtual destructor. auto UnorderedElementsAre(std::initializer_list<std::tuple<int32_t, int32_t, int64_t>> tuples) { @@ -85,121 +114,137 @@ void PrintTo(const ActivePicture& activePicture, std::ostream* os) { } TEST_F(ActivePictureTrackerTest, notCalledWithNoProfile) { - sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100); + auto layer = createMockLayer(100, 10); TestableLayerFE layerFE; - EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureTracker tracker; { - layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE; + layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - ASSERT_FALSE(tracker.updateAndHasChanged()); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); + } + { + auto listener = createMockListener(); + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); } } TEST_F(ActivePictureTrackerTest, calledWhenLayerStartsUsingProfile) { - sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100); + auto layer = createMockLayer(100, 10); TestableLayerFE layerFE; - EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureTracker tracker; + auto listener = createMockListener(); { - layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE; tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - ASSERT_FALSE(tracker.updateAndHasChanged()); + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); } { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE.onPictureProfileCommitted(); tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); } } TEST_F(ActivePictureTrackerTest, notCalledWhenLayerContinuesUsingProfile) { - sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100); + auto layer = createMockLayer(100, 10); TestableLayerFE layerFE; - EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureTracker tracker; + auto listener = createMockListener(); { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE.onPictureProfileCommitted(); tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); } { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE.onPictureProfileCommitted(); tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - ASSERT_FALSE(tracker.updateAndHasChanged()); + EXPECT_CALL(*listener, onActivePicturesChanged(_)).Times(0); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); } } TEST_F(ActivePictureTrackerTest, calledWhenLayerStopsUsingProfile) { - sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100); + auto layer = createMockLayer(100, 10); TestableLayerFE layerFE; - EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureTracker tracker; + auto listener = createMockListener(); { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE.onPictureProfileCommitted(); tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); } { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE; tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), UnorderedElementsAre({})); + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); } } TEST_F(ActivePictureTrackerTest, calledWhenLayerChangesProfile) { - sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100); + auto layer = createMockLayer(100, 10); TestableLayerFE layerFE; - EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureTracker tracker; + auto listener = createMockListener(); { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE.onPictureProfileCommitted(); tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); } { layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(2); layerFE.onPictureProfileCommitted(); tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), UnorderedElementsAre({{100, 10, 2}})); + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 2}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); } } TEST_F(ActivePictureTrackerTest, notCalledWhenUncommittedLayerChangesProfile) { - sp<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100); + auto layer1 = createMockLayer(100, 10); TestableLayerFE layerFE1; - EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::make(flinger(), 200); + auto layer2 = createMockLayer(200, 20); TestableLayerFE layerFE2; - EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(20))); ActivePictureTracker tracker; + auto listener = createMockListener(); { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE1.onPictureProfileCommitted(); @@ -208,8 +253,8 @@ TEST_F(ActivePictureTrackerTest, notCalledWhenUncommittedLayerChangesProfile) { layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1); tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); } { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); @@ -219,20 +264,20 @@ TEST_F(ActivePictureTrackerTest, notCalledWhenUncommittedLayerChangesProfile) { layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2); tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - ASSERT_FALSE(tracker.updateAndHasChanged()); + EXPECT_CALL(*listener, onActivePicturesChanged(_)).Times(0); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); } } TEST_F(ActivePictureTrackerTest, calledWhenDifferentLayerUsesSameProfile) { - sp<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100); + auto layer1 = createMockLayer(100, 10); TestableLayerFE layerFE1; - EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::make(flinger(), 200); + auto layer2 = createMockLayer(200, 20); TestableLayerFE layerFE2; - EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(20))); ActivePictureTracker tracker; + auto listener = createMockListener(); { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE1.onPictureProfileCommitted(); @@ -242,9 +287,12 @@ TEST_F(ActivePictureTrackerTest, calledWhenDifferentLayerUsesSameProfile) { layerFE2.onPictureProfileCommitted(); tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), - UnorderedElementsAre({{100, 10, 1}, {200, 20, 2}})); + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}, {200, 20, 2}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); } { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(2); @@ -255,22 +303,24 @@ TEST_F(ActivePictureTrackerTest, calledWhenDifferentLayerUsesSameProfile) { layerFE2.onPictureProfileCommitted(); tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), - UnorderedElementsAre({{100, 10, 2}, {200, 20, 1}})); + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 2}, {200, 20, 1}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); } } TEST_F(ActivePictureTrackerTest, calledWhenSameUidUsesSameProfile) { - sp<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100); + auto layer1 = createMockLayer(100, 10); TestableLayerFE layerFE1; - EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::make(flinger(), 200); + auto layer2 = createMockLayer(200, 10); TestableLayerFE layerFE2; - EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureTracker tracker; + auto listener = createMockListener(); { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE1.onPictureProfileCommitted(); @@ -280,9 +330,12 @@ TEST_F(ActivePictureTrackerTest, calledWhenSameUidUsesSameProfile) { layerFE2.onPictureProfileCommitted(); tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), - UnorderedElementsAre({{100, 10, 1}, {200, 10, 2}})); + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}, {200, 10, 2}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); } { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(2); @@ -293,31 +346,32 @@ TEST_F(ActivePictureTrackerTest, calledWhenSameUidUsesSameProfile) { layerFE2.onPictureProfileCommitted(); tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), - UnorderedElementsAre({{100, 10, 2}, {200, 10, 1}})); + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 2}, {200, 10, 1}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); } } TEST_F(ActivePictureTrackerTest, calledWhenNewLayerUsesSameProfile) { - sp<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100); + auto layer1 = createMockLayer(100, 10); TestableLayerFE layerFE1; - EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); ActivePictureTracker tracker; + auto listener = createMockListener(); { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE1.onPictureProfileCommitted(); tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), UnorderedElementsAre({{100, 10, 1}})); + EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1); + tracker.updateAndNotifyListeners(*listener, NO_LISTENERS); } - sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::make(flinger(), 200); + auto layer2 = createMockLayer(200, 10); TestableLayerFE layerFE2; - EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(10))); - { layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1); layerFE1.onPictureProfileCommitted(); @@ -327,9 +381,12 @@ TEST_F(ActivePictureTrackerTest, calledWhenNewLayerUsesSameProfile) { layerFE2.onPictureProfileCommitted(); tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult()); - ASSERT_TRUE(tracker.updateAndHasChanged()); - EXPECT_THAT(tracker.getActivePictures(), - UnorderedElementsAre({{100, 10, 1}, {200, 10, 1}})); + EXPECT_CALL(*listener, onActivePicturesChanged(_)) + .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) { + EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}, {200, 10, 1}})); + return binder::Status::ok(); + }); + tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS); } } |