• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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