1 /*
2 * Copyright 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19
20 #include <android/gui/ActivePicture.h>
21 #include <android/gui/IActivePictureListener.h>
22 #include <compositionengine/mock/CompositionEngine.h>
23 #include <mock/DisplayHardware/MockComposer.h>
24 #include <mock/MockLayer.h>
25 #include <renderengine/mock/RenderEngine.h>
26
27 #include "ActivePictureUpdater.h"
28 #include "LayerFE.h"
29 #include "TestableSurfaceFlinger.h"
30
31 namespace android {
32
33 using android::compositionengine::LayerFECompositionState;
34 using android::gui::ActivePicture;
35 using android::gui::IActivePictureListener;
36 using android::mock::MockLayer;
37 using surfaceflinger::frontend::LayerSnapshot;
38 using testing::_;
39 using testing::NiceMock;
40 using testing::Return;
41
42 class TestableLayerFE : public LayerFE {
43 public:
TestableLayerFE()44 TestableLayerFE() : LayerFE("TestableLayerFE"), snapshot(*(new LayerSnapshot)) {
45 mSnapshot = std::unique_ptr<LayerSnapshot>(&snapshot);
46 }
47
48 LayerSnapshot& snapshot;
49 };
50
51 class ActivePictureUpdaterTest : public testing::Test {
52 protected:
flinger()53 SurfaceFlinger* flinger() {
54 if (!mFlingerSetup) {
55 mFlinger.setupMockScheduler();
56 mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
57 mFlinger.setupRenderEngine(std::make_unique<renderengine::mock::RenderEngine>());
58 mFlingerSetup = true;
59 }
60 return mFlinger.flinger();
61 }
62
63 private:
64 TestableSurfaceFlinger mFlinger;
65 bool mFlingerSetup = false;
66 };
67
68 // Hack to workaround initializer lists not working for parcelables because parcelables inherit from
69 // Parcelable, which has a virtual destructor.
UnorderedElementsAre(std::initializer_list<std::tuple<int32_t,int32_t,int64_t>> tuples)70 auto UnorderedElementsAre(std::initializer_list<std::tuple<int32_t, int32_t, int64_t>> tuples) {
71 std::vector<ActivePicture> activePictures;
72 for (auto tuple : tuples) {
73 ActivePicture ap;
74 ap.layerId = std::get<0>(tuple);
75 ap.ownerUid = std::get<1>(tuple);
76 ap.pictureProfileId = std::get<2>(tuple);
77 activePictures.push_back(ap);
78 }
79 return testing::UnorderedElementsAreArray(activePictures);
80 }
81
82 // Parcelables don't define this for matchers, which is unfortunate
PrintTo(const ActivePicture & activePicture,std::ostream * os)83 void PrintTo(const ActivePicture& activePicture, std::ostream* os) {
84 *os << activePicture.toString();
85 }
86
TEST_F(ActivePictureUpdaterTest,notCalledWithNoProfile)87 TEST_F(ActivePictureUpdaterTest, notCalledWithNoProfile) {
88 sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100);
89 TestableLayerFE layerFE;
90 EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
91
92 ActivePictureUpdater updater;
93 {
94 layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE;
95 updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
96
97 ASSERT_FALSE(updater.updateAndHasChanged());
98 }
99 }
100
TEST_F(ActivePictureUpdaterTest,calledWhenLayerStartsUsingProfile)101 TEST_F(ActivePictureUpdaterTest, calledWhenLayerStartsUsingProfile) {
102 sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100);
103 TestableLayerFE layerFE;
104 EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
105
106 ActivePictureUpdater updater;
107 {
108 layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE;
109 updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
110
111 ASSERT_FALSE(updater.updateAndHasChanged());
112 }
113 {
114 layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
115 layerFE.onPictureProfileCommitted();
116 updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
117
118 ASSERT_TRUE(updater.updateAndHasChanged());
119 EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}}));
120 }
121 }
122
TEST_F(ActivePictureUpdaterTest,notCalledWhenLayerContinuesUsingProfile)123 TEST_F(ActivePictureUpdaterTest, notCalledWhenLayerContinuesUsingProfile) {
124 sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100);
125 TestableLayerFE layerFE;
126 EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
127
128 ActivePictureUpdater updater;
129 {
130 layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
131 layerFE.onPictureProfileCommitted();
132 updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
133
134 ASSERT_TRUE(updater.updateAndHasChanged());
135 EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}}));
136 }
137 {
138 layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
139 layerFE.onPictureProfileCommitted();
140 updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
141
142 ASSERT_FALSE(updater.updateAndHasChanged());
143 }
144 }
145
TEST_F(ActivePictureUpdaterTest,calledWhenLayerStopsUsingProfile)146 TEST_F(ActivePictureUpdaterTest, calledWhenLayerStopsUsingProfile) {
147 sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100);
148 TestableLayerFE layerFE;
149 EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
150
151 ActivePictureUpdater updater;
152 {
153 layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
154 layerFE.onPictureProfileCommitted();
155 updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
156
157 ASSERT_TRUE(updater.updateAndHasChanged());
158 EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}}));
159 }
160 {
161 layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE;
162 updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
163
164 ASSERT_TRUE(updater.updateAndHasChanged());
165 EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({}));
166 }
167 }
168
TEST_F(ActivePictureUpdaterTest,calledWhenLayerChangesProfile)169 TEST_F(ActivePictureUpdaterTest, calledWhenLayerChangesProfile) {
170 sp<NiceMock<MockLayer>> layer = sp<NiceMock<MockLayer>>::make(flinger(), 100);
171 TestableLayerFE layerFE;
172 EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
173
174 ActivePictureUpdater updater;
175 {
176 layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
177 layerFE.onPictureProfileCommitted();
178 updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
179
180 ASSERT_TRUE(updater.updateAndHasChanged());
181 EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}}));
182 }
183 {
184 layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(2);
185 layerFE.onPictureProfileCommitted();
186 updater.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
187
188 ASSERT_TRUE(updater.updateAndHasChanged());
189 EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 2}}));
190 }
191 }
192
TEST_F(ActivePictureUpdaterTest,notCalledWhenUncommittedLayerChangesProfile)193 TEST_F(ActivePictureUpdaterTest, notCalledWhenUncommittedLayerChangesProfile) {
194 sp<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100);
195 TestableLayerFE layerFE1;
196 EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
197
198 sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::make(flinger(), 200);
199 TestableLayerFE layerFE2;
200 EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(20)));
201
202 ActivePictureUpdater updater;
203 {
204 layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
205 layerFE1.onPictureProfileCommitted();
206 updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
207
208 layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1);
209 updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
210
211 ASSERT_TRUE(updater.updateAndHasChanged());
212 EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}}));
213 }
214 {
215 layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
216 layerFE1.onPictureProfileCommitted();
217 updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
218
219 layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2);
220 updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
221
222 ASSERT_FALSE(updater.updateAndHasChanged());
223 }
224 }
225
TEST_F(ActivePictureUpdaterTest,calledWhenDifferentLayerUsesSameProfile)226 TEST_F(ActivePictureUpdaterTest, calledWhenDifferentLayerUsesSameProfile) {
227 sp<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100);
228 TestableLayerFE layerFE1;
229 EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
230
231 sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::make(flinger(), 200);
232 TestableLayerFE layerFE2;
233 EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(20)));
234
235 ActivePictureUpdater updater;
236 {
237 layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
238 layerFE1.onPictureProfileCommitted();
239 updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
240
241 layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2);
242 layerFE2.onPictureProfileCommitted();
243 updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
244
245 ASSERT_TRUE(updater.updateAndHasChanged());
246 EXPECT_THAT(updater.getActivePictures(),
247 UnorderedElementsAre({{100, 10, 1}, {200, 20, 2}}));
248 }
249 {
250 layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(2);
251 layerFE1.onPictureProfileCommitted();
252 updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
253
254 layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1);
255 layerFE2.onPictureProfileCommitted();
256 updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
257
258 ASSERT_TRUE(updater.updateAndHasChanged());
259 EXPECT_THAT(updater.getActivePictures(),
260 UnorderedElementsAre({{100, 10, 2}, {200, 20, 1}}));
261 }
262 }
263
TEST_F(ActivePictureUpdaterTest,calledWhenSameUidUsesSameProfile)264 TEST_F(ActivePictureUpdaterTest, calledWhenSameUidUsesSameProfile) {
265 sp<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100);
266 TestableLayerFE layerFE1;
267 EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
268
269 sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::make(flinger(), 200);
270 TestableLayerFE layerFE2;
271 EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
272
273 ActivePictureUpdater updater;
274 {
275 layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
276 layerFE1.onPictureProfileCommitted();
277 updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
278
279 layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2);
280 layerFE2.onPictureProfileCommitted();
281 updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
282
283 ASSERT_TRUE(updater.updateAndHasChanged());
284 EXPECT_THAT(updater.getActivePictures(),
285 UnorderedElementsAre({{100, 10, 1}, {200, 10, 2}}));
286 }
287 {
288 layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(2);
289 layerFE1.onPictureProfileCommitted();
290 updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
291
292 layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1);
293 layerFE2.onPictureProfileCommitted();
294 updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
295
296 ASSERT_TRUE(updater.updateAndHasChanged());
297 EXPECT_THAT(updater.getActivePictures(),
298 UnorderedElementsAre({{100, 10, 2}, {200, 10, 1}}));
299 }
300 }
301
TEST_F(ActivePictureUpdaterTest,calledWhenNewLayerUsesSameProfile)302 TEST_F(ActivePictureUpdaterTest, calledWhenNewLayerUsesSameProfile) {
303 sp<NiceMock<MockLayer>> layer1 = sp<NiceMock<MockLayer>>::make(flinger(), 100);
304 TestableLayerFE layerFE1;
305 EXPECT_CALL(*layer1, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
306
307 ActivePictureUpdater updater;
308 {
309 layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
310 layerFE1.onPictureProfileCommitted();
311 updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
312
313 ASSERT_TRUE(updater.updateAndHasChanged());
314 EXPECT_THAT(updater.getActivePictures(), UnorderedElementsAre({{100, 10, 1}}));
315 }
316
317 sp<NiceMock<MockLayer>> layer2 = sp<NiceMock<MockLayer>>::make(flinger(), 200);
318 TestableLayerFE layerFE2;
319 EXPECT_CALL(*layer2, getOwnerUid()).WillRepeatedly(Return(uid_t(10)));
320
321 {
322 layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
323 layerFE1.onPictureProfileCommitted();
324 updater.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
325
326 layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1);
327 layerFE2.onPictureProfileCommitted();
328 updater.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
329
330 ASSERT_TRUE(updater.updateAndHasChanged());
331 EXPECT_THAT(updater.getActivePictures(),
332 UnorderedElementsAre({{100, 10, 1}, {200, 10, 1}}));
333 }
334 }
335
336 } // namespace android
337