1 /*
2  * Copyright 2020 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 <scheduler/Fps.h>
21 
22 #include "DisplayTransactionTestHelpers.h"
23 #include "FpsOps.h"
24 
25 namespace android {
26 namespace {
27 
28 class CreateDisplayTest : public DisplayTransactionTest {
29 public:
createDisplayWithRequestedRefreshRate(const std::string & name,uint64_t displayId,float pacesetterDisplayRefreshRate,float requestedRefreshRate,float expectedAdjustedRefreshRate)30     void createDisplayWithRequestedRefreshRate(const std::string& name, uint64_t displayId,
31                                                float pacesetterDisplayRefreshRate,
32                                                float requestedRefreshRate,
33                                                float expectedAdjustedRefreshRate) {
34         // --------------------------------------------------------------------
35         // Call Expectations
36 
37         // --------------------------------------------------------------------
38         // Invocation
39 
40         sp<IBinder> displayToken = mFlinger.createVirtualDisplay(name, false, requestedRefreshRate);
41 
42         // --------------------------------------------------------------------
43         // Postconditions
44 
45         // The display should have been added to the current state
46         ASSERT_TRUE(hasCurrentDisplayState(displayToken));
47         const auto& display = getCurrentDisplayState(displayToken);
48         EXPECT_TRUE(display.isVirtual());
49         EXPECT_EQ(display.requestedRefreshRate, Fps::fromValue(requestedRefreshRate));
50         EXPECT_EQ(name.c_str(), display.displayName);
51 
52         std::optional<VirtualDisplayId> vid =
53                 DisplayId::fromValue<VirtualDisplayId>(displayId | DisplayId::FLAG_VIRTUAL);
54         ASSERT_TRUE(vid.has_value());
55 
56         sp<DisplayDevice> device =
57                 mFlinger.createVirtualDisplayDevice(displayToken, *vid, requestedRefreshRate);
58         EXPECT_TRUE(device->isVirtual());
59         device->adjustRefreshRate(Fps::fromValue(pacesetterDisplayRefreshRate));
60         // verifying desired value
61         EXPECT_EQ(device->getAdjustedRefreshRate(), Fps::fromValue(expectedAdjustedRefreshRate));
62         // verifying rounding up
63         if (requestedRefreshRate < pacesetterDisplayRefreshRate) {
64             EXPECT_GE(device->getAdjustedRefreshRate(), Fps::fromValue(requestedRefreshRate));
65         } else {
66             EXPECT_EQ(device->getAdjustedRefreshRate(),
67                       Fps::fromValue(pacesetterDisplayRefreshRate));
68         }
69 
70         // --------------------------------------------------------------------
71         // Cleanup conditions
72     }
73 };
74 
TEST_F(CreateDisplayTest,createDisplaySetsCurrentStateForNonsecureDisplay)75 TEST_F(CreateDisplayTest, createDisplaySetsCurrentStateForNonsecureDisplay) {
76     static const std::string name("virtual.test");
77 
78     // --------------------------------------------------------------------
79     // Call Expectations
80 
81     // --------------------------------------------------------------------
82     // Invocation
83 
84     sp<IBinder> displayToken = mFlinger.createVirtualDisplay(name, false);
85 
86     // --------------------------------------------------------------------
87     // Postconditions
88 
89     // The display should have been added to the current state
90     ASSERT_TRUE(hasCurrentDisplayState(displayToken));
91     const auto& display = getCurrentDisplayState(displayToken);
92     EXPECT_TRUE(display.isVirtual());
93     EXPECT_FALSE(display.isSecure);
94     EXPECT_EQ(name.c_str(), display.displayName);
95 
96     // --------------------------------------------------------------------
97     // Cleanup conditions
98 
99     // Creating the display commits a display transaction.
100     EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
101 }
102 
TEST_F(CreateDisplayTest,createDisplaySetsCurrentStateForSecureDisplay)103 TEST_F(CreateDisplayTest, createDisplaySetsCurrentStateForSecureDisplay) {
104     static const std::string kDisplayName("virtual.test");
105 
106     // --------------------------------------------------------------------
107     // Call Expectations
108 
109     // --------------------------------------------------------------------
110     // Invocation
111     int64_t oldId = IPCThreadState::self()->clearCallingIdentity();
112     // Set the calling identity to graphics so captureDisplay with secure is allowed.
113     IPCThreadState::self()->restoreCallingIdentity(static_cast<int64_t>(AID_GRAPHICS) << 32 |
114                                                    AID_GRAPHICS);
115     sp<IBinder> displayToken = mFlinger.createVirtualDisplay(kDisplayName, true);
116     IPCThreadState::self()->restoreCallingIdentity(oldId);
117 
118     // --------------------------------------------------------------------
119     // Postconditions
120 
121     // The display should have been added to the current state
122     ASSERT_TRUE(hasCurrentDisplayState(displayToken));
123     const auto& display = getCurrentDisplayState(displayToken);
124     EXPECT_TRUE(display.isVirtual());
125     EXPECT_TRUE(display.isSecure);
126     EXPECT_EQ(kDisplayName.c_str(), display.displayName);
127 
128     // --------------------------------------------------------------------
129     // Cleanup conditions
130 
131     // Creating the display commits a display transaction.
132     EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
133 }
134 
TEST_F(CreateDisplayTest,createDisplaySetsCurrentStateForUniqueId)135 TEST_F(CreateDisplayTest, createDisplaySetsCurrentStateForUniqueId) {
136     static const std::string kDisplayName("virtual.test");
137     static const std::string kUniqueId = "virtual:package:id";
138 
139     // --------------------------------------------------------------------
140     // Call Expectations
141 
142     // --------------------------------------------------------------------
143     // Invocation
144 
145     sp<IBinder> displayToken = mFlinger.createVirtualDisplay(kDisplayName, false, kUniqueId);
146 
147     // --------------------------------------------------------------------
148     // Postconditions
149 
150     // The display should have been added to the current state
151     ASSERT_TRUE(hasCurrentDisplayState(displayToken));
152     const auto& display = getCurrentDisplayState(displayToken);
153     EXPECT_TRUE(display.isVirtual());
154     EXPECT_FALSE(display.isSecure);
155     EXPECT_EQ(display.uniqueId, "virtual:package:id");
156     EXPECT_EQ(kDisplayName.c_str(), display.displayName);
157 
158     // --------------------------------------------------------------------
159     // Cleanup conditions
160 
161     // Creating the display commits a display transaction.
162     EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
163 }
164 
165 // Requesting 0 tells SF not to do anything, i.e., default to refresh as physical displays
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRate0)166 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRate0) {
167     static const std::string kDisplayName("virtual.test");
168     constexpr uint64_t kDisplayId = 123ull;
169     constexpr float kPacesetterDisplayRefreshRate = 60.f;
170     constexpr float kRequestedRefreshRate = 0.f;
171     constexpr float kExpectedAdjustedRefreshRate = 0.f;
172     createDisplayWithRequestedRefreshRate(kDisplayName, kDisplayId, kPacesetterDisplayRefreshRate,
173                                           kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
174 }
175 
176 // Requesting negative refresh rate, will be ignored, same as requesting 0
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRateNegative)177 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRateNegative) {
178     static const std::string kDisplayName("virtual.test");
179     constexpr uint64_t kDisplayId = 123ull;
180     constexpr float kPacesetterDisplayRefreshRate = 60.f;
181     constexpr float kRequestedRefreshRate = -60.f;
182     constexpr float kExpectedAdjustedRefreshRate = 0.f;
183     createDisplayWithRequestedRefreshRate(kDisplayName, kDisplayId, kPacesetterDisplayRefreshRate,
184                                           kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
185 }
186 
187 // Requesting a higher refresh rate than the pacesetter
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRateHigh)188 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRateHigh) {
189     static const std::string kDisplayName("virtual.test");
190     constexpr uint64_t kDisplayId = 123ull;
191     constexpr float kPacesetterDisplayRefreshRate = 60.f;
192     constexpr float kRequestedRefreshRate = 90.f;
193     constexpr float kExpectedAdjustedRefreshRate = 60.f;
194     createDisplayWithRequestedRefreshRate(kDisplayName, kDisplayId, kPacesetterDisplayRefreshRate,
195                                           kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
196 }
197 
198 // Requesting the same refresh rate as the pacesetter
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRateSame)199 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRateSame) {
200     static const std::string kDisplayName("virtual.test");
201     constexpr uint64_t kDisplayId = 123ull;
202     constexpr float kPacesetterDisplayRefreshRate = 60.f;
203     constexpr float kRequestedRefreshRate = 60.f;
204     constexpr float kExpectedAdjustedRefreshRate = 60.f;
205     createDisplayWithRequestedRefreshRate(kDisplayName, kDisplayId, kPacesetterDisplayRefreshRate,
206                                           kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
207 }
208 
209 // Requesting a divisor (30) of the pacesetter (60) should be honored
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRateDivisor)210 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRateDivisor) {
211     static const std::string kDisplayName("virtual.test");
212     constexpr uint64_t kDisplayId = 123ull;
213     constexpr float kPacesetterDisplayRefreshRate = 60.f;
214     constexpr float kRequestedRefreshRate = 30.f;
215     constexpr float kExpectedAdjustedRefreshRate = 30.f;
216     createDisplayWithRequestedRefreshRate(kDisplayName, kDisplayId, kPacesetterDisplayRefreshRate,
217                                           kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
218 }
219 
220 // Requesting a non divisor (45) of the pacesetter (120) should round up to a divisor (60)
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRateNoneDivisor)221 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRateNoneDivisor) {
222     static const std::string kDisplayName("virtual.test");
223     constexpr uint64_t kDisplayId = 123ull;
224     constexpr float kPacesetterDisplayRefreshRate = 120.f;
225     constexpr float kRequestedRefreshRate = 45.f;
226     constexpr float kExpectedAdjustedRefreshRate = 60.f;
227     createDisplayWithRequestedRefreshRate(kDisplayName, kDisplayId, kPacesetterDisplayRefreshRate,
228                                           kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
229 }
230 
231 // Requesting a non divisor (75) of the pacesetter (120) should round up to pacesetter (120)
TEST_F(CreateDisplayTest,createDisplayWithRequestedRefreshRateNoneDivisorMax)232 TEST_F(CreateDisplayTest, createDisplayWithRequestedRefreshRateNoneDivisorMax) {
233     static const std::string kDisplayName("virtual.test");
234     constexpr uint64_t kDisplayId = 123ull;
235     constexpr float kPacesetterDisplayRefreshRate = 120.f;
236     constexpr float kRequestedRefreshRate = 75.f;
237     constexpr float kExpectedAdjustedRefreshRate = 120.f;
238     createDisplayWithRequestedRefreshRate(kDisplayName, kDisplayId, kPacesetterDisplayRefreshRate,
239                                           kRequestedRefreshRate, kExpectedAdjustedRefreshRate);
240 }
241 
242 } // namespace
243 } // namespace android
244