1 /*
2  * Copyright 2021 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 #undef LOG_TAG
18 #define LOG_TAG "LibSurfaceFlingerUnittests"
19 
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 #include <gui/LayerMetadata.h>
23 #include <gui/SurfaceComposerClient.h>
24 #include <log/log.h>
25 
26 #include "TestableSurfaceFlinger.h"
27 #include "mock/DisplayHardware/MockComposer.h"
28 #include "mock/MockEventThread.h"
29 #include "mock/MockVsyncController.h"
30 
31 namespace android {
32 
33 using testing::_;
34 using testing::Mock;
35 using testing::Return;
36 using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
37 
38 class GameModeTest : public testing::Test {
39 public:
GameModeTest()40     GameModeTest() {
41         const ::testing::TestInfo* const test_info =
42                 ::testing::UnitTest::GetInstance()->current_test_info();
43         ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
44         setupScheduler();
45         setupComposer();
46     }
47 
~GameModeTest()48     ~GameModeTest() {
49         const ::testing::TestInfo* const test_info =
50                 ::testing::UnitTest::GetInstance()->current_test_info();
51         ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
52     }
53 
createBufferStateLayer()54     sp<BufferStateLayer> createBufferStateLayer() {
55         sp<Client> client;
56         LayerCreationArgs args(mFlinger.flinger(), client, "buffer-state-layer", 100, 100, 0,
57                                LayerMetadata());
58         return new BufferStateLayer(args);
59     }
60 
setupScheduler()61     void setupScheduler() {
62         auto eventThread = std::make_unique<mock::EventThread>();
63         auto sfEventThread = std::make_unique<mock::EventThread>();
64 
65         EXPECT_CALL(*eventThread, registerDisplayEventConnection(_));
66         EXPECT_CALL(*eventThread, createEventConnection(_, _))
67                 .WillOnce(Return(new EventThreadConnection(eventThread.get(), /*callingUid=*/0,
68                                                            ResyncCallback())));
69 
70         EXPECT_CALL(*sfEventThread, registerDisplayEventConnection(_));
71         EXPECT_CALL(*sfEventThread, createEventConnection(_, _))
72                 .WillOnce(Return(new EventThreadConnection(sfEventThread.get(), /*callingUid=*/0,
73                                                            ResyncCallback())));
74 
75         auto vsyncController = std::make_unique<mock::VsyncController>();
76         auto vsyncTracker = std::make_unique<mock::VSyncTracker>();
77 
78         EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
79         EXPECT_CALL(*vsyncTracker, currentPeriod())
80                 .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD));
81         EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
82         mFlinger.setupScheduler(std::move(vsyncController), std::move(vsyncTracker),
83                                 std::move(eventThread), std::move(sfEventThread));
84     }
85 
setupComposer()86     void setupComposer() {
87         mComposer = new Hwc2::mock::Composer();
88         mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
89 
90         Mock::VerifyAndClear(mComposer);
91     }
92 
93     // Mocks the behavior of applying a transaction from WMShell
setGameModeMetadata(sp<Layer> layer,int gameMode)94     void setGameModeMetadata(sp<Layer> layer, int gameMode) {
95         mLayerMetadata.setInt32(METADATA_GAME_MODE, gameMode);
96         layer->setMetadata(mLayerMetadata);
97         layer->setGameModeForTree(gameMode);
98     }
99 
100     TestableSurfaceFlinger mFlinger;
101     Hwc2::mock::Composer* mComposer = nullptr;
102     client_cache_t mClientCache;
103     LayerMetadata mLayerMetadata;
104 };
105 
TEST_F(GameModeTest,SetGameModeSetsForAllCurrentChildren)106 TEST_F(GameModeTest, SetGameModeSetsForAllCurrentChildren) {
107     sp<BufferStateLayer> rootLayer = createBufferStateLayer();
108     sp<BufferStateLayer> childLayer1 = createBufferStateLayer();
109     sp<BufferStateLayer> childLayer2 = createBufferStateLayer();
110     rootLayer->addChild(childLayer1);
111     rootLayer->addChild(childLayer2);
112     rootLayer->setGameModeForTree(/*gameMode*/ 2);
113 
114     EXPECT_EQ(rootLayer->getGameMode(), 2);
115     EXPECT_EQ(childLayer1->getGameMode(), 2);
116     EXPECT_EQ(childLayer2->getGameMode(), 2);
117 }
118 
TEST_F(GameModeTest,AddChildAppliesGameModeFromParent)119 TEST_F(GameModeTest, AddChildAppliesGameModeFromParent) {
120     sp<BufferStateLayer> rootLayer = createBufferStateLayer();
121     sp<BufferStateLayer> childLayer = createBufferStateLayer();
122     rootLayer->setGameModeForTree(/*gameMode*/ 2);
123     rootLayer->addChild(childLayer);
124 
125     EXPECT_EQ(rootLayer->getGameMode(), 2);
126     EXPECT_EQ(childLayer->getGameMode(), 2);
127 }
128 
TEST_F(GameModeTest,RemoveChildResetsGameMode)129 TEST_F(GameModeTest, RemoveChildResetsGameMode) {
130     sp<BufferStateLayer> rootLayer = createBufferStateLayer();
131     sp<BufferStateLayer> childLayer = createBufferStateLayer();
132     rootLayer->setGameModeForTree(/*gameMode*/ 2);
133     rootLayer->addChild(childLayer);
134 
135     EXPECT_EQ(rootLayer->getGameMode(), 2);
136     EXPECT_EQ(childLayer->getGameMode(), 2);
137 
138     rootLayer->removeChild(childLayer);
139     EXPECT_EQ(childLayer->getGameMode(), 0);
140 }
141 
TEST_F(GameModeTest,ReparentingDoesNotOverrideMetadata)142 TEST_F(GameModeTest, ReparentingDoesNotOverrideMetadata) {
143     sp<BufferStateLayer> rootLayer = createBufferStateLayer();
144     sp<BufferStateLayer> childLayer1 = createBufferStateLayer();
145     sp<BufferStateLayer> childLayer2 = createBufferStateLayer();
146     rootLayer->setGameModeForTree(/*gameMode*/ 1);
147     rootLayer->addChild(childLayer1);
148 
149     setGameModeMetadata(childLayer2, /*gameMode*/ 2);
150     rootLayer->addChild(childLayer2);
151 
152     EXPECT_EQ(rootLayer->getGameMode(), 1);
153     EXPECT_EQ(childLayer1->getGameMode(), 1);
154     EXPECT_EQ(childLayer2->getGameMode(), 2);
155 
156     rootLayer->removeChild(childLayer2);
157     EXPECT_EQ(childLayer2->getGameMode(), 2);
158 }
159 } // namespace android