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
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index be88b11..cabde22 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -3293,10 +3293,17 @@
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 8c19bbb..da47ee2 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -607,8 +607,14 @@
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 0ce0c0a..0f66c8b 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -298,7 +298,9 @@
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 76362ff..3185778 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -1016,7 +1016,11 @@
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 0319408..4e6fa66 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::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 @@
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 95a698b..cb319a5 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 @@
// 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 3f3d2c6..0f8d38f 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -199,7 +199,7 @@
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 1498fff..2147a85 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 @@
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 @@
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 @@
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::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 @@
return binderStatusFromStatusT(status);
}
-binder::Status SurfaceComposerAIDL::setActivePictureListener(
+binder::Status SurfaceComposerAIDL::addActivePictureListener(
const sp<gui::IActivePictureListener>& listener) {
status_t status = checkObservePictureProfilesPermission();
if (status == OK) {
- mFlinger->setActivePictureListener(listener);
+ mFlinger->addActivePictureListener(listener);
+ }
+ return binderStatusFromStatusT(status);
+}
+
+binder::Status SurfaceComposerAIDL::removeActivePictureListener(
+ const sp<gui::IActivePictureListener>& listener) {
+ status_t status = checkObservePictureProfilesPermission();
+ if (status == OK) {
+ mFlinger->removeActivePictureListener(listener);
}
return binderStatusFromStatusT(status);
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b16ea08..0ae236f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -667,7 +667,9 @@
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 @@
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 @@
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 ff9a456..7d9004a 100644
--- a/services/surfaceflinger/tests/unittests/ActivePictureTrackerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/ActivePictureTrackerTest.cpp
@@ -38,6 +38,8 @@
using testing::_;
using testing::NiceMock;
using testing::Return;
+using testing::SizeIs;
+using testing::StrictMock;
class TestableLayerFE : public LayerFE {
public:
@@ -48,8 +50,20 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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);
}
}