1 /*
2 * Copyright 2019 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 "SchedulerUnittests"
19
20 #include <gmock/gmock.h>
21 #include <log/log.h>
22 #include <thread>
23
24 #include "Scheduler/RefreshRateStats.h"
25 #include "mock/MockTimeStats.h"
26
27 using namespace std::chrono_literals;
28 using android::hardware::graphics::composer::hal::PowerMode;
29 using testing::_;
30 using testing::AtLeast;
31
32 namespace android::scheduler {
33
34 class RefreshRateStatsTest : public testing::Test {
35 protected:
36 RefreshRateStatsTest();
37 ~RefreshRateStatsTest();
38
resetStats(Fps fps)39 void resetStats(Fps fps) {
40 mRefreshRateStats = std::make_unique<RefreshRateStats>(mTimeStats, fps, PowerMode::OFF);
41 }
42
43 mock::TimeStats mTimeStats;
44 std::unique_ptr<RefreshRateStats> mRefreshRateStats;
45 };
46
RefreshRateStatsTest()47 RefreshRateStatsTest::RefreshRateStatsTest() {
48 const ::testing::TestInfo* const test_info =
49 ::testing::UnitTest::GetInstance()->current_test_info();
50 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
51 }
52
~RefreshRateStatsTest()53 RefreshRateStatsTest::~RefreshRateStatsTest() {
54 const ::testing::TestInfo* const test_info =
55 ::testing::UnitTest::GetInstance()->current_test_info();
56 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
57 }
58
59 namespace {
60
TEST_F(RefreshRateStatsTest,oneMode)61 TEST_F(RefreshRateStatsTest, oneMode) {
62 resetStats(90_Hz);
63
64 EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
65 EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
66
67 auto times = mRefreshRateStats->getTotalTimes();
68 ASSERT_TRUE(times.contains("ScreenOff"));
69 EXPECT_EQ(1u, times.size());
70
71 // Screen is off by default.
72 std::chrono::milliseconds screenOff = times.get("ScreenOff")->get();
73 std::this_thread::sleep_for(std::chrono::milliseconds(2));
74 times = mRefreshRateStats->getTotalTimes();
75
76 EXPECT_LT(screenOff, times.get("ScreenOff")->get());
77 EXPECT_FALSE(times.contains("90.00 Hz"));
78
79 mRefreshRateStats->setRefreshRate(90_Hz);
80 mRefreshRateStats->setPowerMode(PowerMode::ON);
81 screenOff = mRefreshRateStats->getTotalTimes().get("ScreenOff")->get();
82 std::this_thread::sleep_for(std::chrono::milliseconds(2));
83 times = mRefreshRateStats->getTotalTimes();
84
85 EXPECT_EQ(screenOff, times.get("ScreenOff")->get());
86 ASSERT_TRUE(times.contains("90.00 Hz"));
87 EXPECT_LT(0ms, times.get("90.00 Hz")->get());
88
89 mRefreshRateStats->setPowerMode(PowerMode::DOZE);
90 const auto ninety = mRefreshRateStats->getTotalTimes().get("90.00 Hz")->get();
91 std::this_thread::sleep_for(std::chrono::milliseconds(2));
92 times = mRefreshRateStats->getTotalTimes();
93
94 EXPECT_LT(screenOff, times.get("ScreenOff")->get());
95 EXPECT_EQ(ninety, times.get("90.00 Hz")->get());
96
97 mRefreshRateStats->setRefreshRate(90_Hz);
98 screenOff = mRefreshRateStats->getTotalTimes().get("ScreenOff")->get();
99 std::this_thread::sleep_for(std::chrono::milliseconds(2));
100 times = mRefreshRateStats->getTotalTimes();
101
102 // Stats are not updated while the screen is off.
103 EXPECT_LT(screenOff, times.get("ScreenOff")->get());
104 EXPECT_EQ(ninety, times.get("90.00 Hz")->get());
105 }
106
TEST_F(RefreshRateStatsTest,twoModes)107 TEST_F(RefreshRateStatsTest, twoModes) {
108 resetStats(90_Hz);
109
110 EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
111 EXPECT_CALL(mTimeStats, recordRefreshRate(60, _)).Times(AtLeast(1));
112 EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
113
114 auto times = mRefreshRateStats->getTotalTimes();
115 ASSERT_TRUE(times.contains("ScreenOff"));
116 EXPECT_EQ(1u, times.size());
117
118 // Screen is off by default.
119 std::chrono::milliseconds screenOff = times.get("ScreenOff")->get();
120 std::this_thread::sleep_for(std::chrono::milliseconds(2));
121 times = mRefreshRateStats->getTotalTimes();
122
123 EXPECT_LT(screenOff, times.get("ScreenOff")->get());
124 EXPECT_FALSE(times.contains("60.00 Hz"));
125 EXPECT_FALSE(times.contains("90.00 Hz"));
126
127 mRefreshRateStats->setRefreshRate(90_Hz);
128 mRefreshRateStats->setPowerMode(PowerMode::ON);
129 screenOff = mRefreshRateStats->getTotalTimes().get("ScreenOff")->get();
130 std::this_thread::sleep_for(std::chrono::milliseconds(2));
131 times = mRefreshRateStats->getTotalTimes();
132
133 EXPECT_EQ(screenOff, times.get("ScreenOff")->get());
134 ASSERT_TRUE(times.contains("90.00 Hz"));
135 EXPECT_LT(0ms, times.get("90.00 Hz")->get());
136
137 mRefreshRateStats->setRefreshRate(60_Hz);
138 auto ninety = mRefreshRateStats->getTotalTimes().get("90.00 Hz")->get();
139 std::this_thread::sleep_for(std::chrono::milliseconds(2));
140 times = mRefreshRateStats->getTotalTimes();
141
142 EXPECT_EQ(screenOff, times.get("ScreenOff")->get());
143 EXPECT_EQ(ninety, times.get("90.00 Hz")->get());
144 ASSERT_TRUE(times.contains("60.00 Hz"));
145 EXPECT_LT(0ms, times.get("60.00 Hz")->get());
146
147 mRefreshRateStats->setRefreshRate(90_Hz);
148 auto sixty = mRefreshRateStats->getTotalTimes().get("60.00 Hz")->get();
149 std::this_thread::sleep_for(std::chrono::milliseconds(2));
150 times = mRefreshRateStats->getTotalTimes();
151
152 EXPECT_EQ(screenOff, times.get("ScreenOff")->get());
153 EXPECT_LT(ninety, times.get("90.00 Hz")->get());
154 EXPECT_EQ(sixty, times.get("60.00 Hz")->get());
155
156 mRefreshRateStats->setRefreshRate(60_Hz);
157 ninety = mRefreshRateStats->getTotalTimes().get("90.00 Hz")->get();
158 std::this_thread::sleep_for(std::chrono::milliseconds(2));
159 times = mRefreshRateStats->getTotalTimes();
160
161 EXPECT_EQ(screenOff, times.get("ScreenOff")->get());
162 EXPECT_EQ(ninety, times.get("90.00 Hz")->get());
163 EXPECT_LT(sixty, times.get("60.00 Hz")->get());
164
165 // Stats are not updated while the screen is off.
166 mRefreshRateStats->setPowerMode(PowerMode::DOZE);
167 mRefreshRateStats->setRefreshRate(90_Hz);
168 sixty = mRefreshRateStats->getTotalTimes().get("60.00 Hz")->get();
169 std::this_thread::sleep_for(std::chrono::milliseconds(2));
170 times = mRefreshRateStats->getTotalTimes();
171
172 EXPECT_LT(screenOff, times.get("ScreenOff")->get());
173 EXPECT_EQ(ninety, times.get("90.00 Hz")->get());
174 EXPECT_EQ(sixty, times.get("60.00 Hz")->get());
175
176 mRefreshRateStats->setRefreshRate(60_Hz);
177 screenOff = mRefreshRateStats->getTotalTimes().get("ScreenOff")->get();
178 std::this_thread::sleep_for(std::chrono::milliseconds(2));
179 times = mRefreshRateStats->getTotalTimes();
180
181 EXPECT_LT(screenOff, times.get("ScreenOff")->get());
182 EXPECT_EQ(ninety, times.get("90.00 Hz")->get());
183 EXPECT_EQ(sixty, times.get("60.00 Hz")->get());
184 }
185
186 } // namespace
187 } // namespace android::scheduler
188