Merge changes from topic "multiple-picture-listeners" into main
* changes:
Add additional ActivePictureTracker test coverage and rename tests
Support multiple active picture listeners
Rename of ActivePictureUpdater to ActivePictureTracker
diff --git a/METADATA b/METADATA
index d97975c..86892cd 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,3 @@
-third_party {
+ third_party {
license_type: NOTICE
}
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
new file mode 100644
index 0000000..4e6fa66
--- /dev/null
+++ b/services/surfaceflinger/ActivePictureTracker.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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 "ActivePictureTracker.h"
+
+#include <algorithm>
+
+#include "Layer.h"
+#include "LayerFE.h"
+
+namespace android {
+
+using gui::ActivePicture;
+using gui::IActivePictureListener;
+
+void ActivePictureTracker::onLayerComposed(const Layer& layer, const LayerFE& layerFE,
+ const CompositionResult& result) {
+ if (result.wasPictureProfileCommitted) {
+ gui::ActivePicture picture;
+ picture.layerId = int32_t(layer.sequence);
+ picture.ownerUid = int32_t(layer.getOwnerUid());
+ // TODO(b/337330263): Why does LayerFE coming from SF have a null composition state?
+ if (layerFE.getCompositionState()) {
+ picture.pictureProfileId = layerFE.getCompositionState()->pictureProfileHandle.getId();
+ } else {
+ picture.pictureProfileId = result.pictureProfileHandle.getId();
+ }
+ mNewActivePictures.push_back(picture);
+ }
+}
+
+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 ActivePicture& lhs, const ActivePicture& rhs) -> int {
+ if (lhs.layerId == rhs.layerId) {
+ return lhs.pictureProfileId < rhs.pictureProfileId;
+ }
+ return lhs.layerId < rhs.layerId;
+ };
+ std::sort(mNewActivePictures.begin(), mNewActivePictures.end(), compare);
+ if (std::equal(mNewActivePictures.begin(), mNewActivePictures.end(),
+ mOldActivePictures.begin())) {
+ hasChanged = false;
+ }
+ }
+ std::swap(mOldActivePictures, mNewActivePictures);
+ mNewActivePictures.resize(0);
+ return hasChanged;
+}
+
+const std::vector<ActivePicture>& ActivePictureTracker::getActivePictures() const {
+ return mOldActivePictures;
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/ActivePictureUpdater.h b/services/surfaceflinger/ActivePictureTracker.h
similarity index 76%
rename from services/surfaceflinger/ActivePictureUpdater.h
rename to services/surfaceflinger/ActivePictureTracker.h
index 20779bb..cb319a5 100644
--- a/services/surfaceflinger/ActivePictureUpdater.h
+++ b/services/surfaceflinger/ActivePictureTracker.h
@@ -19,6 +19,7 @@
#include <vector>
#include <android/gui/ActivePicture.h>
+#include <android/gui/IActivePictureListener.h>
namespace android {
@@ -27,21 +28,28 @@
struct CompositionResult;
// Keeps track of active pictures - layers that are undergoing picture processing.
-class ActivePictureUpdater {
+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/ActivePictureUpdater.cpp b/services/surfaceflinger/ActivePictureUpdater.cpp
deleted file mode 100644
index 210e948..0000000
--- a/services/surfaceflinger/ActivePictureUpdater.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 "ActivePictureUpdater.h"
-
-#include <algorithm>
-
-#include "Layer.h"
-#include "LayerFE.h"
-
-namespace android {
-
-void ActivePictureUpdater::onLayerComposed(const Layer& layer, const LayerFE& layerFE,
- const CompositionResult& result) {
- if (result.wasPictureProfileCommitted) {
- gui::ActivePicture picture;
- picture.layerId = int32_t(layer.sequence);
- picture.ownerUid = int32_t(layer.getOwnerUid());
- // TODO(b/337330263): Why does LayerFE coming from SF have a null composition state?
- if (layerFE.getCompositionState()) {
- picture.pictureProfileId = layerFE.getCompositionState()->pictureProfileHandle.getId();
- } else {
- picture.pictureProfileId = result.pictureProfileHandle.getId();
- }
- mNewActivePictures.push_back(picture);
- }
-}
-
-bool ActivePictureUpdater::updateAndHasChanged() {
- bool hasChanged = true;
- if (mNewActivePictures.size() == mOldActivePictures.size()) {
- auto compare = [](const gui::ActivePicture& lhs, const gui::ActivePicture& rhs) -> int {
- if (lhs.layerId == rhs.layerId) {
- return lhs.pictureProfileId < rhs.pictureProfileId;
- }
- return lhs.layerId < rhs.layerId;
- };
- std::sort(mNewActivePictures.begin(), mNewActivePictures.end(), compare);
- if (std::equal(mNewActivePictures.begin(), mNewActivePictures.end(),
- mOldActivePictures.begin())) {
- hasChanged = false;
- }
- }
- std::swap(mOldActivePictures, mNewActivePictures);
- mNewActivePictures.resize(0);
- return hasChanged;
-}
-
-const std::vector<gui::ActivePicture>& ActivePictureUpdater::getActivePictures() const {
- return mOldActivePictures;
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 7b90363..71c779e 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -198,7 +198,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 0de2673..220133d 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 "ActivePictureUpdater.h"
#include "BackgroundExecutor.h"
#include "Client.h"
#include "ClientCache.h"
@@ -2952,7 +2951,7 @@
layer->setWasClientComposed(compositionResult.lastClientCompositionFence);
}
if (com_android_graphics_libgui_flags_apply_picture_profiles()) {
- mActivePictureUpdater.onLayerComposed(*layer, *layerFE, compositionResult);
+ mActivePictureTracker.onLayerComposed(*layer, *layerFE, compositionResult);
}
}
@@ -3264,8 +3263,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) {
@@ -3287,9 +3286,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) {
@@ -3353,14 +3351,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 (mActivePictureUpdater.updateAndHasChanged() || haveNewActivePictureListener) {
- if (activePictureListener) {
- activePictureListener->onActivePicturesChanged(
- mActivePictureUpdater.getActivePictures());
- }
- }
+ // Track, update and notify changes to active pictures - layers that are undergoing
+ // picture processing
+ mActivePictureTracker.updateAndNotifyListeners(activePictureListenersToAdd,
+ activePictureListenersToRemove);
}
mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
@@ -8226,12 +8220,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(
@@ -9184,11 +9186,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 05a511e..c85c084 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -69,7 +69,7 @@
#include <ui/FenceResult.h>
#include <common/FlagManager.h>
-#include "ActivePictureUpdater.h"
+#include "ActivePictureTracker.h"
#include "BackgroundExecutor.h"
#include "Display/DisplayModeController.h"
#include "Display/PhysicalDisplay.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;
@@ -1407,9 +1409,9 @@
std::unordered_map<DisplayId, sp<HdrLayerInfoReporter>> mHdrLayerInfoListeners
GUARDED_BY(mStateLock);
- sp<gui::IActivePictureListener> mActivePictureListener GUARDED_BY(mStateLock);
- bool mHaveNewActivePictureListener GUARDED_BY(mStateLock);
- ActivePictureUpdater mActivePictureUpdater GUARDED_BY(kMainThreadContext);
+ ActivePictureTracker mActivePictureTracker GUARDED_BY(kMainThreadContext);
+ ActivePictureTracker::Listeners mActivePictureListenersToAdd GUARDED_BY(mStateLock);
+ ActivePictureTracker::Listeners mActivePictureListenersToRemove GUARDED_BY(mStateLock);
std::atomic<ui::Transform::RotationFlags> mActiveDisplayTransformHint;
@@ -1646,8 +1648,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
new file mode 100644
index 0000000..8011309
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/ActivePictureTrackerTest.cpp
@@ -0,0 +1,482 @@
+/*
+ * 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 <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <android/gui/ActivePicture.h>
+#include <android/gui/IActivePictureListener.h>
+#include <compositionengine/mock/CompositionEngine.h>
+#include <mock/DisplayHardware/MockComposer.h>
+#include <mock/MockLayer.h>
+#include <renderengine/mock/RenderEngine.h>
+
+#include "ActivePictureTracker.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;
+using testing::SizeIs;
+using testing::StrictMock;
+
+class TestableLayerFE : public LayerFE {
+public:
+ TestableLayerFE() : LayerFE("TestableLayerFE"), snapshot(*(new LayerSnapshot)) {
+ mSnapshot = std::unique_ptr<LayerSnapshot>(&snapshot);
+ }
+
+ 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();
+ mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
+ mFlinger.setupRenderEngine(std::make_unique<renderengine::mock::RenderEngine>());
+ mFlingerSetup = true;
+ }
+ 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) {
+ std::vector<ActivePicture> 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(ActivePictureTrackerTest, whenListenerAdded_called) {
+ ActivePictureTracker tracker;
+ auto listener = createMockListener();
+ EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1);
+ tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
+}
+
+TEST_F(ActivePictureTrackerTest, whenListenerAdded_withListenerAlreadyAdded_notCalled) {
+ ActivePictureTracker tracker;
+ auto listener = createMockListener();
+ {
+ EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1);
+ tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
+ }
+ {
+ EXPECT_CALL(*listener, onActivePicturesChanged(_)).Times(0);
+ tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
+ }
+}
+
+TEST_F(ActivePictureTrackerTest, whenListenerAdded_withUncommittedProfile_calledWithNone) {
+ auto layer = createMockLayer(100, 10);
+ TestableLayerFE layerFE;
+
+ ActivePictureTracker tracker;
+ {
+ layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
+ 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, whenListenerAdded_withCommittedProfile_calledWithActivePicture) {
+ auto layer = createMockLayer(100, 10);
+ TestableLayerFE layerFE;
+
+ ActivePictureTracker tracker;
+ {
+ layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
+
+ auto listener = createMockListener();
+ EXPECT_CALL(*listener, onActivePicturesChanged(_))
+ .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) {
+ EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}}));
+ return binder::Status::ok();
+ });
+ tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
+ }
+}
+
+TEST_F(ActivePictureTrackerTest, whenProfileAdded_calledWithActivePicture) {
+ auto layer = createMockLayer(100, 10);
+ TestableLayerFE layerFE;
+
+ ActivePictureTracker tracker;
+ auto listener = createMockListener();
+ {
+ tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
+
+ 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());
+
+ 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, whenContinuesUsingProfile_notCalled) {
+ auto layer = createMockLayer(100, 10);
+ TestableLayerFE layerFE;
+
+ ActivePictureTracker tracker;
+ auto listener = createMockListener();
+ {
+ layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
+
+ 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());
+
+ EXPECT_CALL(*listener, onActivePicturesChanged(_)).Times(0);
+ tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS);
+ }
+}
+
+TEST_F(ActivePictureTrackerTest, whenProfileIsRemoved_calledWithNoActivePictures) {
+ auto layer = createMockLayer(100, 10);
+ TestableLayerFE layerFE;
+
+ ActivePictureTracker tracker;
+ auto listener = createMockListener();
+ {
+ layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
+
+ EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1);
+ tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
+ }
+ {
+ layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE;
+ tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
+
+ EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1);
+ tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS);
+ }
+}
+
+TEST_F(ActivePictureTrackerTest, whenProfileIsNotCommitted_calledWithNoActivePictures) {
+ auto layer = createMockLayer(100, 10);
+ TestableLayerFE layerFE;
+
+ ActivePictureTracker tracker;
+ auto listener = createMockListener();
+ {
+ layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
+
+ EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1);
+ tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
+ }
+ {
+ layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
+
+ EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1);
+ tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS);
+ }
+}
+
+TEST_F(ActivePictureTrackerTest, whenProfileChanges_calledWithDifferentProfile) {
+ auto layer = createMockLayer(100, 10);
+ TestableLayerFE layerFE;
+
+ ActivePictureTracker tracker;
+ auto listener = createMockListener();
+ {
+ layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
+
+ 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());
+
+ 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, whenMultipleCommittedProfiles_calledWithMultipleActivePictures) {
+ auto layer1 = createMockLayer(100, 10);
+ TestableLayerFE layerFE1;
+
+ auto layer2 = createMockLayer(200, 20);
+ TestableLayerFE layerFE2;
+
+ ActivePictureTracker tracker;
+ auto listener = createMockListener();
+ {
+ layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE1.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
+
+ layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2);
+ layerFE2.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
+
+ EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(2)))
+ .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);
+ }
+}
+
+TEST_F(ActivePictureTrackerTest, whenNonCommittedProfileChanges_notCalled) {
+ auto layer1 = createMockLayer(100, 10);
+ TestableLayerFE layerFE1;
+
+ auto layer2 = createMockLayer(200, 20);
+ TestableLayerFE layerFE2;
+
+ ActivePictureTracker tracker;
+ auto listener = createMockListener();
+ {
+ layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE1.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
+
+ layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
+
+ EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1);
+ tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
+ }
+ {
+ layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE1.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
+
+ layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2);
+ tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
+
+ EXPECT_CALL(*listener, onActivePicturesChanged(_)).Times(0);
+ tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
+ }
+}
+
+TEST_F(ActivePictureTrackerTest, whenDifferentLayerUsesSameProfile_called) {
+ auto layer1 = createMockLayer(100, 10);
+ TestableLayerFE layerFE1;
+
+ auto layer2 = createMockLayer(200, 20);
+ TestableLayerFE layerFE2;
+
+ ActivePictureTracker tracker;
+ auto listener = createMockListener();
+ {
+ layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE1.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
+
+ layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2);
+ layerFE2.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
+
+ 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);
+ layerFE1.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
+
+ layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE2.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
+
+ 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, whenSameUidDifferentLayerUsesSameProfile_called) {
+ auto layer1 = createMockLayer(100, 10);
+ TestableLayerFE layerFE1;
+
+ auto layer2 = createMockLayer(200, 10);
+ TestableLayerFE layerFE2;
+
+ ActivePictureTracker tracker;
+ auto listener = createMockListener();
+ {
+ layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE1.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
+
+ layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2);
+ layerFE2.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
+
+ 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);
+ layerFE1.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
+
+ layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE2.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
+
+ 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, whenNewLayerUsesSameProfile_called) {
+ auto layer1 = createMockLayer(100, 10);
+ TestableLayerFE layerFE1;
+
+ ActivePictureTracker tracker;
+ auto listener = createMockListener();
+ {
+ layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE1.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
+
+ EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1);
+ tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
+ }
+
+ auto layer2 = createMockLayer(200, 10);
+ TestableLayerFE layerFE2;
+ {
+ layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE1.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
+
+ layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1);
+ layerFE2.onPictureProfileCommitted();
+ tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
+
+ 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);
+ }
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/ActivePictureUpdaterTest.cpp b/services/surfaceflinger/tests/unittests/ActivePictureUpdaterTest.cpp
deleted file mode 100644
index b926d2f..0000000
--- a/services/surfaceflinger/tests/unittests/ActivePictureUpdaterTest.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * 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 <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <android/gui/ActivePicture.h>
-#include <android/gui/IActivePictureListener.h>
-#include <compositionengine/mock/CompositionEngine.h>
-#include <mock/DisplayHardware/MockComposer.h>
-#include <mock/MockLayer.h>
-#include <renderengine/mock/RenderEngine.h>
-
-#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<LayerSnapshot>(&snapshot);
- }
-
- LayerSnapshot& snapshot;
-};
-
-class ActivePictureUpdaterTest : public testing::Test {
-protected:
- SurfaceFlinger* flinger() {
- if (!mFlingerSetup) {
- mFlinger.setupMockScheduler();
- mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
- mFlinger.setupRenderEngine(std::make_unique<renderengine::mock::RenderEngine>());
- 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<std::tuple<int32_t, int32_t, int64_t>> tuples) {
- std::vector<ActivePicture> 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<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::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<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::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<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::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<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::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<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::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<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100);
- TestableLayerFE layerFE1;
- EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
-
- sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::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<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100);
- TestableLayerFE layerFE1;
- EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
-
- sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::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<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100);
- TestableLayerFE layerFE1;
- EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
-
- sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::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<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::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<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::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