1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 #include <test_header.h>
18 
19 #include "hgm_core.h"
20 #include "hgm_frame_rate_manager.h"
21 #include "hgm_config_callback_manager.h"
22 #include "hgm_idle_detector.h"
23 
24 using namespace testing;
25 using namespace testing::ext;
26 
27 namespace OHOS {
28 namespace Rosen {
29 namespace {
30     int32_t width = 720;
31     int32_t height = 1080;
32     int32_t phyWidth = 685;
33     int32_t phyHeight = 1218;
34     ScreenSize screenSize = {width, height, phyWidth, phyHeight};
35     const std::string otherSurface = "Other_SF";
36     const std::string settingStrategyName = "99";
37     constexpr uint64_t  currTime = 200000000;
38     constexpr uint64_t  lastTime = 100000000;
39     constexpr pid_t appPid = 0;
40     constexpr uint32_t touchCount = 1;
41     constexpr uint32_t delay_60Ms = 60;
42     constexpr uint32_t delay_110Ms = 110;
43 }
44 class HgmFrameRateMgrTest : public testing::Test {
45 public:
46     static void SetUpTestCase();
47     static void TearDownTestCase();
48     void SetUp();
49     void TearDown();
50     void InitHgmFrameRateManager(HgmFrameRateManager &frameRateMgr);
51 };
52 
SetUpTestCase()53 void HgmFrameRateMgrTest::SetUpTestCase() {}
TearDownTestCase()54 void HgmFrameRateMgrTest::TearDownTestCase() {}
SetUp()55 void HgmFrameRateMgrTest::SetUp() {}
TearDown()56 void HgmFrameRateMgrTest::TearDown() {}
57 
58 /**
59  * @tc.name: MergeRangeByPriority
60  * @tc.desc: Verify the result of MergeRangeByPriority function
61  * @tc.type: FUNC
62  * @tc.require:
63  */
64 HWTEST_F(HgmFrameRateMgrTest, MergeRangeByPriority, Function | SmallTest | Level1)
65 {
66     VoteRange voteRange0 = { OLED_40_HZ, OLED_120_HZ };
67     VoteRange voteRange1 = { OLED_30_HZ, OLED_40_HZ };
68     VoteRange voteRange2 = { OLED_60_HZ, OLED_90_HZ };
69     VoteRange voteRange3 = { OLED_120_HZ, OLED_144_HZ };
70     VoteRange voteRange4 = { OLED_30_HZ, OLED_144_HZ };
71     VoteRange voteRangeRes;
72 
73     voteRangeRes = voteRange0;
74     HgmFrameRateManager::MergeRangeByPriority(voteRangeRes, voteRange1);
75     ASSERT_EQ(voteRangeRes.first, OledRefreshRate::OLED_40_HZ);
76     ASSERT_EQ(voteRangeRes.second, OledRefreshRate::OLED_40_HZ);
77 
78     voteRangeRes = voteRange0;
79     HgmFrameRateManager::MergeRangeByPriority(voteRangeRes, voteRange2);
80     ASSERT_EQ(voteRangeRes.first, OledRefreshRate::OLED_60_HZ);
81     ASSERT_EQ(voteRangeRes.second, OledRefreshRate::OLED_90_HZ);
82 
83     voteRangeRes = voteRange0;
84     HgmFrameRateManager::MergeRangeByPriority(voteRangeRes, voteRange3);
85     ASSERT_EQ(voteRangeRes.first, OledRefreshRate::OLED_120_HZ);
86     ASSERT_EQ(voteRangeRes.second, OledRefreshRate::OLED_120_HZ);
87 
88     voteRangeRes = voteRange0;
89     HgmFrameRateManager::MergeRangeByPriority(voteRangeRes, voteRange4);
90     ASSERT_EQ(voteRangeRes.first, OledRefreshRate::OLED_40_HZ);
91     ASSERT_EQ(voteRangeRes.second, OledRefreshRate::OLED_120_HZ);
92 }
93 
InitHgmFrameRateManager(HgmFrameRateManager & frameRateMgr)94 void HgmFrameRateMgrTest::InitHgmFrameRateManager(HgmFrameRateManager &frameRateMgr)
95 {
96     int64_t offset = 0;
97     auto vsyncGenerator = CreateVSyncGenerator();
98     sptr<Rosen::VSyncController> rsController = new VSyncController(vsyncGenerator, offset);
99     sptr<Rosen::VSyncController> appController = new VSyncController(vsyncGenerator, offset);
100     frameRateMgr.Init(rsController, appController, vsyncGenerator);
101 
102     auto strategyConfigs = frameRateMgr.multiAppStrategy_.GetStrategyConfigs();
103     auto screenSetting = frameRateMgr.multiAppStrategy_.GetScreenSetting();
104     strategyConfigs[settingStrategyName] = { .min = OLED_NULL_HZ, .max = OLED_120_HZ, .down = OLED_144_HZ,
105         .dynamicMode = DynamicModeType::TOUCH_ENABLED, .isFactor = true };
106     screenSetting.strategy = settingStrategyName;
107     frameRateMgr.multiAppStrategy_.SetStrategyConfigs(strategyConfigs);
108     frameRateMgr.multiAppStrategy_.SetScreenSetting(screenSetting);
109 }
110 
111 /**
112  * @tc.name: HgmSetTouchUpFPS001
113  * @tc.desc: Verify the result of HgmSetTouchUpFPS001 function
114  * @tc.type: FUNC
115  * @tc.require:
116  */
117 HWTEST_F(HgmFrameRateMgrTest, HgmSetTouchUpFPS001, Function | SmallTest | Level1)
118 {
119     HgmFrameRateManager frameRateMgr;
120     InitHgmFrameRateManager(frameRateMgr);
121     PolicyConfigData::StrategyConfig strategyConfig;
122     PART("CaseDescription") {
123         STEP("1. init") {
124             frameRateMgr.idleDetector_.SetAppSupportedState(true);
125             frameRateMgr.UpdateSurfaceTime(otherSurface, lastTime, appPid);
126         }
127         STEP("2. handle touch up event") {
128             frameRateMgr.HandleTouchEvent(appPid, TouchStatus::TOUCH_DOWN, touchCount);
129             frameRateMgr.HandleTouchEvent(appPid, TouchStatus::TOUCH_UP, touchCount);
130             std::this_thread::sleep_for(std::chrono::milliseconds(delay_110Ms));
131             frameRateMgr.UpdateGuaranteedPlanVote(currTime);
132             std::this_thread::sleep_for(std::chrono::milliseconds(delay_60Ms));
133             if (frameRateMgr.multiAppStrategy_.GetVoteRes(strategyConfig) != EXEC_SUCCESS) {
134                 return; // xml is empty, return
135             }
136             ASSERT_EQ(strategyConfig.min, OLED_120_HZ);
137             ASSERT_EQ(strategyConfig.max, OLED_120_HZ);
138 
139             std::vector<std::pair<std::string, int32_t>> appBufferList;
140             appBufferList.push_back(std::make_pair(otherSurface, OLED_90_HZ));
141             frameRateMgr.idleDetector_.UpdateAppBufferList(appBufferList);
142             frameRateMgr.HandleTouchEvent(appPid, TouchStatus::TOUCH_DOWN, touchCount);
143             frameRateMgr.HandleTouchEvent(appPid, TouchStatus::TOUCH_UP, touchCount);
144             std::this_thread::sleep_for(std::chrono::milliseconds(delay_110Ms));
145             frameRateMgr.UpdateGuaranteedPlanVote(currTime);
146             std::this_thread::sleep_for(std::chrono::milliseconds(delay_60Ms));
147             frameRateMgr.multiAppStrategy_.GetVoteRes(strategyConfig);
148             ASSERT_EQ(strategyConfig.min, OLED_90_HZ);
149             ASSERT_EQ(strategyConfig.max, OLED_90_HZ);
150 
151             appBufferList.clear();
152             appBufferList.push_back(std::make_pair(otherSurface, OLED_120_HZ));
153             frameRateMgr.idleDetector_.ClearAppBufferList();
154             frameRateMgr.idleDetector_.UpdateAppBufferList(appBufferList);
155             frameRateMgr.HandleTouchEvent(appPid, TouchStatus::TOUCH_DOWN, touchCount);
156             frameRateMgr.HandleTouchEvent(appPid, TouchStatus::TOUCH_UP, touchCount);
157             std::this_thread::sleep_for(std::chrono::milliseconds(delay_110Ms));
158             frameRateMgr.UpdateGuaranteedPlanVote(currTime);
159             std::this_thread::sleep_for(std::chrono::milliseconds(delay_60Ms));
160             frameRateMgr.multiAppStrategy_.GetVoteRes(strategyConfig);
161             ASSERT_EQ(strategyConfig.min, OLED_120_HZ);
162             ASSERT_EQ(strategyConfig.max, OLED_120_HZ);
163         }
164     }
165     frameRateMgr.touchManager_.ChangeState(TouchState::IDLE_STATE);
166     sleep(1); // wait for handler task finished
167 }
168 
169 /**
170  * @tc.name: HgmSetTouchUpFPS002
171  * @tc.desc: Verify the result of HgmSetTouchUpFPS002 function
172  * @tc.type: FUNC
173  * @tc.require:
174  */
175 HWTEST_F(HgmFrameRateMgrTest, HgmSetTouchUpFPS002, Function | SmallTest | Level1)
176 {
177     HgmFrameRateManager frameRateMgr;
178     InitHgmFrameRateManager(frameRateMgr);
179     PolicyConfigData::StrategyConfig strategyConfig;
180     PART("CaseDescription") {
181         STEP("1. init") {
182             frameRateMgr.idleDetector_.SetAppSupportedState(true);
183             frameRateMgr.UpdateSurfaceTime(otherSurface, lastTime, appPid);
184         }
185         STEP("2. handle touch up event") {
186             std::vector<std::string> appBufferBlackList = { otherSurface };
187             frameRateMgr.idleDetector_.UpdateAppBufferBlackList(appBufferBlackList);
188             frameRateMgr.HandleTouchEvent(appPid, TouchStatus::TOUCH_DOWN, touchCount);
189             std::this_thread::sleep_for(std::chrono::milliseconds(delay_60Ms));
190             frameRateMgr.HandleTouchEvent(appPid, TouchStatus::TOUCH_UP, touchCount);
191             std::this_thread::sleep_for(std::chrono::milliseconds(delay_110Ms));
192             frameRateMgr.UpdateGuaranteedPlanVote(currTime);
193             ASSERT_EQ(frameRateMgr.idleDetector_.ThirdFrameNeedHighRefresh(), false);
194             std::this_thread::sleep_for(std::chrono::milliseconds(delay_60Ms));
195             ASSERT_EQ(frameRateMgr.touchManager_.GetState(), TouchState::IDLE_STATE);
196         }
197     }
198     frameRateMgr.touchManager_.ChangeState(TouchState::IDLE_STATE);
199     sleep(1); // wait for handler task finished
200 }
201 
202 /**
203  * @tc.name: MultiThread001
204  * @tc.desc: Verify the result of MultiThread001 function
205  * @tc.type: FUNC
206  * @tc.require:
207  */
208 HWTEST_F(HgmFrameRateMgrTest, MultiThread001, Function | SmallTest | Level1)
209 {
210     int64_t offset = 0;
211     int64_t touchCnt = 1;
212     int32_t testThreadNum = 100;
213     std::string pkg0 = "com.pkg.other:0:-1";
214     std::string pkg1 = "com.ss.hm.ugc.aweme:1001:10067";
215     std::string pkg2 = "com.wedobest.fivechess.harm:1002:10110";
216 
217     HgmFrameRateManager frameRateMgr;
218     auto vsyncGenerator = CreateVSyncGenerator();
219     sptr<Rosen::VSyncController> rsController = new VSyncController(vsyncGenerator, offset);
220     sptr<Rosen::VSyncController> appController = new VSyncController(vsyncGenerator, offset);
221     frameRateMgr.Init(rsController, appController, vsyncGenerator);
222 
223     std::vector<std::thread> testThreads;
224 
225     for (int i = 0; i < testThreadNum; i++) {
226         // HandleLightFactorStatus
__anon743f33730202() 227         testThreads.push_back(std::thread([&] () { frameRateMgr.HandleLightFactorStatus(i, true); }));
__anon743f33730302() 228         testThreads.push_back(std::thread([&] () { frameRateMgr.HandleLightFactorStatus(i, false); }));
229 
230         // HandlePackageEvent
__anon743f33730402() 231         testThreads.push_back(std::thread([&] () { frameRateMgr.HandlePackageEvent(i, {pkg0}); }));
__anon743f33730502() 232         testThreads.push_back(std::thread([&] () { frameRateMgr.HandlePackageEvent(i, {pkg1}); }));
__anon743f33730602() 233         testThreads.push_back(std::thread([&] () { frameRateMgr.HandlePackageEvent(i, {pkg2}); }));
__anon743f33730702() 234         testThreads.push_back(std::thread([&] () { frameRateMgr.HandlePackageEvent(i, {pkg0, pkg1}); }));
235 
236         // HandleRefreshRateEvent
__anon743f33730802() 237         testThreads.push_back(std::thread([&] () { frameRateMgr.HandleRefreshRateEvent(i, {}); }));
238 
239         // HandleTouchEvent
240         // param 1: touchCnt
__anon743f33730902() 241         testThreads.push_back(std::thread([&] () { frameRateMgr.HandleTouchEvent(i, TouchStatus::TOUCH_DOWN, 1); }));
__anon743f33730a02() 242         testThreads.push_back(std::thread([&] () { frameRateMgr.HandleTouchEvent(i, TouchStatus::TOUCH_UP, 1); }));
243 
244         // HandleRefreshRateMode
245         // param -1、0、1、2、3:refresh rate mode
__anon743f33730b02() 246         testThreads.push_back(std::thread([&] () { frameRateMgr.HandleRefreshRateMode(-1); }));
__anon743f33730c02() 247         testThreads.push_back(std::thread([&] () { frameRateMgr.HandleRefreshRateMode(0); }));
__anon743f33730d02() 248         testThreads.push_back(std::thread([&] () { frameRateMgr.HandleRefreshRateMode(1); }));
__anon743f33730e02() 249         testThreads.push_back(std::thread([&] () { frameRateMgr.HandleRefreshRateMode(2); }));
__anon743f33730f02() 250         testThreads.push_back(std::thread([&] () { frameRateMgr.HandleRefreshRateMode(3); }));
251 
252         // HandleScreenPowerStatus
__anon743f33731002() 253         testThreads.push_back(std::thread([&] () {
254             frameRateMgr.HandleScreenPowerStatus(i, ScreenPowerStatus::POWER_STATUS_ON);
255         }));
__anon743f33731102() 256         testThreads.push_back(std::thread([&] () {
257             frameRateMgr.HandleScreenPowerStatus(i, ScreenPowerStatus::POWER_STATUS_OFF);
258         }));
259     }
260     for (auto &testThread : testThreads) {
261         if (testThread.joinable()) {
262             testThread.join();
263         }
264     }
265     sleep(1); // wait for handler task finished
266 }
267 
268 /**
269  * @tc.name: HgmOneShotTimerTest
270  * @tc.desc: Verify the result of HgmOneShotTimerTest
271  * @tc.type: FUNC
272  * @tc.require: I7DMS1
273  */
274 HWTEST_F(HgmFrameRateMgrTest, HgmOneShotTimerTest, Function | SmallTest | Level2)
275 {
276     std::unique_ptr<HgmFrameRateManager> mgr = std::make_unique<HgmFrameRateManager>();
277     ScreenId id = 1;
278     int32_t interval = 200; // 200ms means waiting time
279 
280     PART("CaseDescription") {
281         STEP("1. set force update callback") {
__anon743f33731202(bool idleTimerExpired, bool forceUpdate) 282             mgr->SetForceUpdateCallback([](bool idleTimerExpired, bool forceUpdate) {});
283         }
284         STEP("2. insert and start screenTimer") {
285             mgr->StartScreenTimer(id, interval, nullptr, nullptr);
286             auto timer = mgr->GetScreenTimer(id);
287             STEP_ASSERT_NE(timer, nullptr);
288         }
289         STEP("3. reset screenTimer") {
290             mgr->ResetScreenTimer(id);
291             auto timer = mgr->GetScreenTimer(id);
292             STEP_ASSERT_NE(timer, nullptr);
293         }
294     }
295 }
296 
297 /**
298  * @tc.name: HgmOneShotTimerTest001
299  * @tc.desc: Verify the result of HgmOneShotTimerTest001
300  * @tc.type: FUNC
301  * @tc.require: I7DMS1
302  */
303 HWTEST_F(HgmFrameRateMgrTest, HgmOneShotTimerTest001, Function | SmallTest | Level2)
304 {
305     int32_t interval = 200; // 200ms means waiting time
306     int32_t testThreadNum = 100;
307 
308     auto timer = HgmOneShotTimer("timer", std::chrono::milliseconds(interval), nullptr, nullptr);
309     std::vector<std::thread> testThreads;
310     for (int i = 0; i < testThreadNum; i++) {
__anon743f33731302() 311         testThreads.push_back(std::thread([&timer] () { return timer.Start(); }));
__anon743f33731402() 312         testThreads.push_back(std::thread([&timer] () { return timer.Reset(); }));
__anon743f33731502() 313         testThreads.push_back(std::thread([&timer] () { return timer.Stop(); }));
314     }
315     for (auto &testThread : testThreads) {
316         if (testThread.joinable()) {
317             testThread.join();
318         }
319     }
320     sleep(2); // wait for handler task finished
321 }
322 
323 } // namespace Rosen
324 } // namespace OHOS