• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ActivePictureTracker.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 using testing::SizeIs;
42 using testing::StrictMock;
43 
44 class TestableLayerFE : public LayerFE {
45 public:
TestableLayerFE()46     TestableLayerFE() : LayerFE("TestableLayerFE"), snapshot(*(new LayerSnapshot)) {
47         mSnapshot = std::unique_ptr<LayerSnapshot>(&snapshot);
48     }
49 
50     LayerSnapshot& snapshot;
51 };
52 
53 class MockActivePictureListener : public gui::BnActivePictureListener {
54 public:
operator ActivePictureTracker::Listeners const()55     operator ActivePictureTracker::Listeners const() {
56         return {sp<IActivePictureListener>::fromExisting(this)};
57     }
58 
59     MOCK_METHOD(binder::Status, onActivePicturesChanged, (const std::vector<ActivePicture>&),
60                 (override));
61 };
62 
63 class ActivePictureTrackerTest : public testing::Test {
64 protected:
65     const static ActivePictureTracker::Listeners NO_LISTENERS;
66 
flinger()67     SurfaceFlinger* flinger() {
68         if (!mFlingerSetup) {
69             mFlinger.setupMockScheduler();
70             mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
71             mFlinger.setupRenderEngine(std::make_unique<renderengine::mock::RenderEngine>());
72             mFlingerSetup = true;
73         }
74         return mFlinger.flinger();
75     }
76 
createMockLayer(int layerId,int ownerUid)77     sp<NiceMock<MockLayer>> createMockLayer(int layerId, int ownerUid) {
78         auto layer = sp<NiceMock<MockLayer>>::make(flinger(), layerId);
79         EXPECT_CALL(*layer, getOwnerUid()).WillRepeatedly(Return(uid_t(ownerUid)));
80         return layer;
81     }
82 
createMockListener()83     sp<StrictMock<MockActivePictureListener>> createMockListener() {
84         return sp<StrictMock<MockActivePictureListener>>::make();
85     }
86 
87     ActivePictureTracker::Listeners mListenersToAdd;
88     ActivePictureTracker::Listeners mListenersToRemove;
89 
90 private:
91     TestableSurfaceFlinger mFlinger;
92     bool mFlingerSetup = false;
93 };
94 
95 const ActivePictureTracker::Listeners ActivePictureTrackerTest::NO_LISTENERS;
96 
97 // Hack to workaround initializer lists not working for parcelables because parcelables inherit from
98 // Parcelable, which has a virtual destructor.
UnorderedElementsAre(std::initializer_list<std::tuple<int32_t,int32_t,int64_t>> tuples)99 auto UnorderedElementsAre(std::initializer_list<std::tuple<int32_t, int32_t, int64_t>> tuples) {
100     std::vector<ActivePicture> activePictures;
101     for (auto tuple : tuples) {
102         ActivePicture ap;
103         ap.layerId = std::get<0>(tuple);
104         ap.ownerUid = std::get<1>(tuple);
105         ap.pictureProfileId = std::get<2>(tuple);
106         activePictures.push_back(ap);
107     }
108     return testing::UnorderedElementsAreArray(activePictures);
109 }
110 
111 // Parcelables don't define this for matchers, which is unfortunate
PrintTo(const ActivePicture & activePicture,std::ostream * os)112 void PrintTo(const ActivePicture& activePicture, std::ostream* os) {
113     *os << activePicture.toString();
114 }
115 
TEST_F(ActivePictureTrackerTest,whenListenerAdded_called)116 TEST_F(ActivePictureTrackerTest, whenListenerAdded_called) {
117     ActivePictureTracker tracker;
118     auto listener = createMockListener();
119     EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1);
120     tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
121 }
122 
TEST_F(ActivePictureTrackerTest,whenListenerAdded_withListenerAlreadyAdded_notCalled)123 TEST_F(ActivePictureTrackerTest, whenListenerAdded_withListenerAlreadyAdded_notCalled) {
124     ActivePictureTracker tracker;
125     auto listener = createMockListener();
126     {
127         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1);
128         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
129     }
130     {
131         EXPECT_CALL(*listener, onActivePicturesChanged(_)).Times(0);
132         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
133     }
134 }
135 
TEST_F(ActivePictureTrackerTest,whenListenerAdded_withUncommittedProfile_calledWithNone)136 TEST_F(ActivePictureTrackerTest, whenListenerAdded_withUncommittedProfile_calledWithNone) {
137     auto layer = createMockLayer(100, 10);
138     TestableLayerFE layerFE;
139 
140     ActivePictureTracker tracker;
141     {
142         layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
143         tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
144         tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS);
145     }
146     {
147         auto listener = createMockListener();
148         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1);
149         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
150     }
151 }
152 
TEST_F(ActivePictureTrackerTest,whenListenerAdded_withCommittedProfile_calledWithActivePicture)153 TEST_F(ActivePictureTrackerTest, whenListenerAdded_withCommittedProfile_calledWithActivePicture) {
154     auto layer = createMockLayer(100, 10);
155     TestableLayerFE layerFE;
156 
157     ActivePictureTracker tracker;
158     {
159         layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
160         layerFE.onPictureProfileCommitted();
161         tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
162 
163         auto listener = createMockListener();
164         EXPECT_CALL(*listener, onActivePicturesChanged(_))
165                 .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) {
166                     EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}}));
167                     return binder::Status::ok();
168                 });
169         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
170     }
171 }
172 
TEST_F(ActivePictureTrackerTest,whenProfileAdded_calledWithActivePicture)173 TEST_F(ActivePictureTrackerTest, whenProfileAdded_calledWithActivePicture) {
174     auto layer = createMockLayer(100, 10);
175     TestableLayerFE layerFE;
176 
177     ActivePictureTracker tracker;
178     auto listener = createMockListener();
179     {
180         tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
181 
182         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1);
183         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
184     }
185     {
186         layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
187         layerFE.onPictureProfileCommitted();
188         tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
189 
190         EXPECT_CALL(*listener, onActivePicturesChanged(_))
191                 .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) {
192                     EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}}));
193                     return binder::Status::ok();
194                 });
195         tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS);
196     }
197 }
198 
TEST_F(ActivePictureTrackerTest,whenContinuesUsingProfile_notCalled)199 TEST_F(ActivePictureTrackerTest, whenContinuesUsingProfile_notCalled) {
200     auto layer = createMockLayer(100, 10);
201     TestableLayerFE layerFE;
202 
203     ActivePictureTracker tracker;
204     auto listener = createMockListener();
205     {
206         layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
207         layerFE.onPictureProfileCommitted();
208         tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
209 
210         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1);
211         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
212     }
213     {
214         layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
215         layerFE.onPictureProfileCommitted();
216         tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
217 
218         EXPECT_CALL(*listener, onActivePicturesChanged(_)).Times(0);
219         tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS);
220     }
221 }
222 
TEST_F(ActivePictureTrackerTest,whenProfileIsRemoved_calledWithNoActivePictures)223 TEST_F(ActivePictureTrackerTest, whenProfileIsRemoved_calledWithNoActivePictures) {
224     auto layer = createMockLayer(100, 10);
225     TestableLayerFE layerFE;
226 
227     ActivePictureTracker tracker;
228     auto listener = createMockListener();
229     {
230         layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
231         layerFE.onPictureProfileCommitted();
232         tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
233 
234         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1);
235         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
236     }
237     {
238         layerFE.snapshot.pictureProfileHandle = PictureProfileHandle::NONE;
239         tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
240 
241         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1);
242         tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS);
243     }
244 }
245 
TEST_F(ActivePictureTrackerTest,whenProfileIsNotCommitted_calledWithNoActivePictures)246 TEST_F(ActivePictureTrackerTest, whenProfileIsNotCommitted_calledWithNoActivePictures) {
247     auto layer = createMockLayer(100, 10);
248     TestableLayerFE layerFE;
249 
250     ActivePictureTracker tracker;
251     auto listener = createMockListener();
252     {
253         layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
254         layerFE.onPictureProfileCommitted();
255         tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
256 
257         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1);
258         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
259     }
260     {
261         layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
262         tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
263 
264         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(0))).Times(1);
265         tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS);
266     }
267 }
268 
TEST_F(ActivePictureTrackerTest,whenProfileChanges_calledWithDifferentProfile)269 TEST_F(ActivePictureTrackerTest, whenProfileChanges_calledWithDifferentProfile) {
270     auto layer = createMockLayer(100, 10);
271     TestableLayerFE layerFE;
272 
273     ActivePictureTracker tracker;
274     auto listener = createMockListener();
275     {
276         layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(1);
277         layerFE.onPictureProfileCommitted();
278         tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
279 
280         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1)))
281                 .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) {
282                     EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}}));
283                     return binder::Status::ok();
284                 });
285         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
286     }
287     {
288         layerFE.snapshot.pictureProfileHandle = PictureProfileHandle(2);
289         layerFE.onPictureProfileCommitted();
290         tracker.onLayerComposed(*layer, layerFE, layerFE.stealCompositionResult());
291 
292         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1)))
293                 .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) {
294                     EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 2}}));
295                     return binder::Status::ok();
296                 });
297         tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS);
298     }
299 }
300 
TEST_F(ActivePictureTrackerTest,whenMultipleCommittedProfiles_calledWithMultipleActivePictures)301 TEST_F(ActivePictureTrackerTest, whenMultipleCommittedProfiles_calledWithMultipleActivePictures) {
302     auto layer1 = createMockLayer(100, 10);
303     TestableLayerFE layerFE1;
304 
305     auto layer2 = createMockLayer(200, 20);
306     TestableLayerFE layerFE2;
307 
308     ActivePictureTracker tracker;
309     auto listener = createMockListener();
310     {
311         layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
312         layerFE1.onPictureProfileCommitted();
313         tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
314 
315         layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2);
316         layerFE2.onPictureProfileCommitted();
317         tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
318 
319         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(2)))
320                 .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) {
321                     EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}, {200, 20, 2}}));
322                     return binder::Status::ok();
323                 });
324         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
325     }
326 }
327 
TEST_F(ActivePictureTrackerTest,whenNonCommittedProfileChanges_notCalled)328 TEST_F(ActivePictureTrackerTest, whenNonCommittedProfileChanges_notCalled) {
329     auto layer1 = createMockLayer(100, 10);
330     TestableLayerFE layerFE1;
331 
332     auto layer2 = createMockLayer(200, 20);
333     TestableLayerFE layerFE2;
334 
335     ActivePictureTracker tracker;
336     auto listener = createMockListener();
337     {
338         layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
339         layerFE1.onPictureProfileCommitted();
340         tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
341 
342         layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1);
343         tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
344 
345         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1);
346         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
347     }
348     {
349         layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
350         layerFE1.onPictureProfileCommitted();
351         tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
352 
353         layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2);
354         tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
355 
356         EXPECT_CALL(*listener, onActivePicturesChanged(_)).Times(0);
357         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
358     }
359 }
360 
TEST_F(ActivePictureTrackerTest,whenDifferentLayerUsesSameProfile_called)361 TEST_F(ActivePictureTrackerTest, whenDifferentLayerUsesSameProfile_called) {
362     auto layer1 = createMockLayer(100, 10);
363     TestableLayerFE layerFE1;
364 
365     auto layer2 = createMockLayer(200, 20);
366     TestableLayerFE layerFE2;
367 
368     ActivePictureTracker tracker;
369     auto listener = createMockListener();
370     {
371         layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
372         layerFE1.onPictureProfileCommitted();
373         tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
374 
375         layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2);
376         layerFE2.onPictureProfileCommitted();
377         tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
378 
379         EXPECT_CALL(*listener, onActivePicturesChanged(_))
380                 .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) {
381                     EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}, {200, 20, 2}}));
382                     return binder::Status::ok();
383                 });
384         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
385     }
386     {
387         layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(2);
388         layerFE1.onPictureProfileCommitted();
389         tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
390 
391         layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1);
392         layerFE2.onPictureProfileCommitted();
393         tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
394 
395         EXPECT_CALL(*listener, onActivePicturesChanged(_))
396                 .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) {
397                     EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 2}, {200, 20, 1}}));
398                     return binder::Status::ok();
399                 });
400         tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS);
401     }
402 }
403 
TEST_F(ActivePictureTrackerTest,whenSameUidDifferentLayerUsesSameProfile_called)404 TEST_F(ActivePictureTrackerTest, whenSameUidDifferentLayerUsesSameProfile_called) {
405     auto layer1 = createMockLayer(100, 10);
406     TestableLayerFE layerFE1;
407 
408     auto layer2 = createMockLayer(200, 10);
409     TestableLayerFE layerFE2;
410 
411     ActivePictureTracker tracker;
412     auto listener = createMockListener();
413     {
414         layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
415         layerFE1.onPictureProfileCommitted();
416         tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
417 
418         layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(2);
419         layerFE2.onPictureProfileCommitted();
420         tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
421 
422         EXPECT_CALL(*listener, onActivePicturesChanged(_))
423                 .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) {
424                     EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}, {200, 10, 2}}));
425                     return binder::Status::ok();
426                 });
427         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
428     }
429     {
430         layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(2);
431         layerFE1.onPictureProfileCommitted();
432         tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
433 
434         layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1);
435         layerFE2.onPictureProfileCommitted();
436         tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
437 
438         EXPECT_CALL(*listener, onActivePicturesChanged(_))
439                 .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) {
440                     EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 2}, {200, 10, 1}}));
441                     return binder::Status::ok();
442                 });
443         tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS);
444     }
445 }
446 
TEST_F(ActivePictureTrackerTest,whenNewLayerUsesSameProfile_called)447 TEST_F(ActivePictureTrackerTest, whenNewLayerUsesSameProfile_called) {
448     auto layer1 = createMockLayer(100, 10);
449     TestableLayerFE layerFE1;
450 
451     ActivePictureTracker tracker;
452     auto listener = createMockListener();
453     {
454         layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
455         layerFE1.onPictureProfileCommitted();
456         tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
457 
458         EXPECT_CALL(*listener, onActivePicturesChanged(SizeIs(1))).Times(1);
459         tracker.updateAndNotifyListeners(*listener, NO_LISTENERS);
460     }
461 
462     auto layer2 = createMockLayer(200, 10);
463     TestableLayerFE layerFE2;
464     {
465         layerFE1.snapshot.pictureProfileHandle = PictureProfileHandle(1);
466         layerFE1.onPictureProfileCommitted();
467         tracker.onLayerComposed(*layer1, layerFE1, layerFE1.stealCompositionResult());
468 
469         layerFE2.snapshot.pictureProfileHandle = PictureProfileHandle(1);
470         layerFE2.onPictureProfileCommitted();
471         tracker.onLayerComposed(*layer2, layerFE2, layerFE2.stealCompositionResult());
472 
473         EXPECT_CALL(*listener, onActivePicturesChanged(_))
474                 .WillOnce([](const std::vector<gui::ActivePicture>& activePictures) {
475                     EXPECT_THAT(activePictures, UnorderedElementsAre({{100, 10, 1}, {200, 10, 1}}));
476                     return binder::Status::ok();
477                 });
478         tracker.updateAndNotifyListeners(NO_LISTENERS, NO_LISTENERS);
479     }
480 }
481 
482 } // namespace android
483