1 /*
2  * Copyright (c) 2024 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 "hgm_energy_consumption_policy.h"
17 
18 #include <functional>
19 
20 #include "hgm_core.h"
21 #include "hgm_log.h"
22 #include "rs_trace.h"
23 #include "xml_parser.h"
24 
25 #include "common/rs_common_def.h"
26 #include "common/rs_common_hook.h"
27 
28 namespace OHOS::Rosen {
29 static const std::string IS_ANIMATION_ENERGY_ASSURANCE_ENABLE = "animation_energy_assurance_enable";
30 static const std::string ANIMATION_IDLE_FPS = "animation_idle_fps";
31 static const std::string ANIMATION_IDLE_DURATION = "animation_idle_duration";
32 static const std::unordered_map<std::string, int32_t> UI_RATE_TYPE_NAME_MAP = {
33     {"ui_animation", UI_ANIMATION_FRAME_RATE_TYPE },
34     {"display_sync", DISPLAY_SYNC_FRAME_RATE_TYPE },
35     {"ace_component", ACE_COMPONENT_FRAME_RATE_TYPE },
36     {"display_soloist", DISPLAY_SOLOIST_FRAME_RATE_TYPE },
37 };
38 constexpr int DEFAULT_ENERGY_ASSURANCE_IDLE_FPS = 60;
39 constexpr int DEFAULT_ANIMATION_IDLE_DURATION = 2000;
40 
HgmEnergyConsumptionPolicy()41 HgmEnergyConsumptionPolicy::HgmEnergyConsumptionPolicy()
42 {
43     RsCommonHook::Instance().RegisterStartNewAnimationListener(
44         std::bind(&HgmEnergyConsumptionPolicy::StartNewAnimation, this));
45 }
46 
Instance()47 HgmEnergyConsumptionPolicy& HgmEnergyConsumptionPolicy::Instance()
48 {
49     static HgmEnergyConsumptionPolicy hlpp;
50     return hlpp;
51 }
52 
ConverStrToInt(int & targetNum,std::string sourceStr,int defaultValue)53 void HgmEnergyConsumptionPolicy::ConverStrToInt(int& targetNum, std::string sourceStr, int defaultValue)
54 {
55     if (!XMLParser::IsNumber(sourceStr)) {
56         targetNum = defaultValue;
57         return;
58     }
59     targetNum = std::stoi(sourceStr.c_str());
60 }
61 
SetEnergyConsumptionConfig(std::unordered_map<std::string,std::string> animationPowerConfig)62 void HgmEnergyConsumptionPolicy::SetEnergyConsumptionConfig(
63     std::unordered_map<std::string, std::string> animationPowerConfig)
64 {
65     std::lock_guard<std::recursive_mutex> lock(mutex_);
66     if (animationPowerConfig.count(IS_ANIMATION_ENERGY_ASSURANCE_ENABLE) == 0) {
67         isAnimationEnergyAssuranceEnable_ = false;
68     } else {
69         isAnimationEnergyAssuranceEnable_ =
70             animationPowerConfig[IS_ANIMATION_ENERGY_ASSURANCE_ENABLE] == "true" ? true : false;
71     }
72     if (!isAnimationEnergyAssuranceEnable_) {
73         HGM_LOGD("HgmEnergyConsumptionPolicy::SetEnergyConsumptionConfig isAnimationLtpoPowerEnable is false");
74         return;
75     }
76 
77     if (animationPowerConfig.count(ANIMATION_IDLE_FPS) == 0) {
78         animationIdleFps_ = DEFAULT_ENERGY_ASSURANCE_IDLE_FPS;
79     } else {
80         ConverStrToInt(animationIdleFps_, animationPowerConfig[ANIMATION_IDLE_FPS], DEFAULT_ENERGY_ASSURANCE_IDLE_FPS);
81     }
82 
83     if (animationPowerConfig.count(ANIMATION_IDLE_DURATION) == 0) {
84         animationIdleDuration_ = DEFAULT_ANIMATION_IDLE_DURATION;
85     } else {
86         ConverStrToInt(
87             animationIdleDuration_, animationPowerConfig[ANIMATION_IDLE_DURATION], DEFAULT_ANIMATION_IDLE_DURATION);
88     }
89     HGM_LOGD("HgmEnergyConsumptionPolicy::SetEnergyConsumptionConfig update config success");
90 }
91 
SetUiEnergyConsumptionConfig(std::unordered_map<std::string,std::string> uiPowerConfig)92 void HgmEnergyConsumptionPolicy::SetUiEnergyConsumptionConfig(
93     std::unordered_map<std::string, std::string> uiPowerConfig)
94 {
95     std::lock_guard<std::recursive_mutex> lock(mutex_);
96     uiEnergyAssuranceMap_.clear();
97     for (auto config : uiPowerConfig) {
98         std::string rateTypeName = config.first;
99         auto it = UI_RATE_TYPE_NAME_MAP.find(rateTypeName);
100         if (it == UI_RATE_TYPE_NAME_MAP.end()) {
101             HGM_LOGD("HgmEnergyConsumptionPolicy::SetUiEnergyConsumptionConfig the rateType is invalid");
102             continue;
103         }
104         int idleFps = 60;
105         ConverStrToInt(idleFps, config.second, DEFAULT_ENERGY_ASSURANCE_IDLE_FPS);
106         uiEnergyAssuranceMap_[it->second] = std::make_pair(true, idleFps);
107     }
108 }
109 
SetAnimationEnergyConsumptionAssuranceMode(bool isEnergyConsumptionAssuranceMode)110 void HgmEnergyConsumptionPolicy::SetAnimationEnergyConsumptionAssuranceMode(bool isEnergyConsumptionAssuranceMode)
111 {
112     std::lock_guard<std::recursive_mutex> lock(mutex_);
113     if (!isAnimationEnergyAssuranceEnable_ ||
114         isAnimationEnergyConsumptionAssuranceMode_ == isEnergyConsumptionAssuranceMode) {
115         return;
116     }
117     isAnimationEnergyConsumptionAssuranceMode_ = isEnergyConsumptionAssuranceMode;
118     firstAnimationTimestamp_ = HgmCore::Instance().GetCurrentTimestamp() / NS_PER_MS;
119     lastAnimationTimestamp_ = firstAnimationTimestamp_;
120 }
121 
SetUiEnergyConsumptionAssuranceMode(bool isEnergyConsumptionAssuranceMode)122 void HgmEnergyConsumptionPolicy::SetUiEnergyConsumptionAssuranceMode(bool isEnergyConsumptionAssuranceMode)
123 {
124     std::lock_guard<std::recursive_mutex> lock(mutex_);
125     isUiEnergyConsumptionAssuranceMode_ = isEnergyConsumptionAssuranceMode;
126 }
127 
StatisticAnimationTime(uint64_t timestamp)128 void HgmEnergyConsumptionPolicy::StatisticAnimationTime(uint64_t timestamp)
129 {
130     std::lock_guard<std::recursive_mutex> lock(mutex_);
131     if (!isAnimationEnergyAssuranceEnable_ || !isAnimationEnergyConsumptionAssuranceMode_) {
132         return;
133     }
134     lastAnimationTimestamp_ = timestamp;
135 }
136 
StartNewAnimation()137 void HgmEnergyConsumptionPolicy::StartNewAnimation()
138 {
139     std::lock_guard<std::recursive_mutex> lock(mutex_);
140     if (!isAnimationEnergyAssuranceEnable_ || !isAnimationEnergyConsumptionAssuranceMode_) {
141         return;
142     }
143     firstAnimationTimestamp_ = HgmCore::Instance().GetCurrentTimestamp() / NS_PER_MS;
144     lastAnimationTimestamp_ = firstAnimationTimestamp_;
145 }
146 
GetAnimationIdleFps(FrameRateRange & rsRange)147 void HgmEnergyConsumptionPolicy::GetAnimationIdleFps(FrameRateRange& rsRange)
148 {
149     std::lock_guard<std::recursive_mutex> lock(mutex_);
150     if (!isAnimationEnergyAssuranceEnable_ || !isAnimationEnergyConsumptionAssuranceMode_) {
151         return;
152     }
153     if (lastAnimationTimestamp_ > firstAnimationTimestamp_ &&
154         (lastAnimationTimestamp_ - firstAnimationTimestamp_) < static_cast<uint64_t>(animationIdleDuration_)) {
155         return;
156     }
157     SetEnergyConsumptionRateRange(rsRange, animationIdleFps_);
158 }
159 
GetUiIdleFps(FrameRateRange & rsRange)160 void HgmEnergyConsumptionPolicy::GetUiIdleFps(FrameRateRange& rsRange)
161 {
162     std::lock_guard<std::recursive_mutex> lock(mutex_);
163     if (!isUiEnergyConsumptionAssuranceMode_) {
164         return;
165     }
166     auto it = uiEnergyAssuranceMap_.find(rsRange.type_);
167     if (it == uiEnergyAssuranceMap_.end()) {
168         HGM_LOGD("HgmEnergyConsumptionPolicy::GetUiIdleFps the rateType = %{public}d is invalid", rsRange.type_);
169         return;
170     }
171     bool isEnergyAssuranceEnable = it->second.first;
172     int idleFps = it->second.second;
173     if (isEnergyAssuranceEnable) {
174         SetEnergyConsumptionRateRange(rsRange, idleFps);
175     }
176 }
177 
SetEnergyConsumptionRateRange(FrameRateRange & rsRange,int idleFps)178 void HgmEnergyConsumptionPolicy::SetEnergyConsumptionRateRange(FrameRateRange& rsRange, int idleFps)
179 {
180     RS_TRACE_NAME_FMT("SetEnergyConsumptionRateRange rateType:%s, maxFps:%d", rsRange.GetExtInfo().c_str(), idleFps);
181     rsRange.max_ = std::min(rsRange.max_, idleFps);
182     rsRange.min_ = std::min(rsRange.min_, idleFps);
183     rsRange.preferred_ = std::min(rsRange.preferred_, idleFps);
184 }
185 } // namespace OHOS::Rosen