• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_multi_app_strategy.h"
17 
18 #include <functional>
19 #include <limits>
20 
21 #include "common/rs_common_hook.h"
22 #include "hgm_config_callback_manager.h"
23 #include "hgm_core.h"
24 #include "hgm_energy_consumption_policy.h"
25 #include "hgm_frame_rate_manager.h"
26 #include "rs_trace.h"
27 #include "xml_parser.h"
28 
29 namespace OHOS {
30 namespace Rosen {
31 namespace {
32     static PolicyConfigData::ScreenSetting defaultScreenSetting;
33     static PolicyConfigData::StrategyConfigMap defaultStrategyConfigMap;
34     static PolicyConfigData::StrategyConfigMap defaultAppStrategyConfigMap;
35     static PolicyConfigData::StrategyConfigMap defaultAppStrategyConfigPreMap;
36     static std::vector<std::string> defaultAppBufferList;
37     const std::string NULL_STRATEGY_CONFIG_NAME = "null";
38     using AppStrategyConfigHandleFunc = std::function<void(const std::string&, PolicyConfigData::StrategyConfig&)>;
39     const std::unordered_map<std::string, AppStrategyConfigHandleFunc> APP_STRATEGY_CONFIG_HANDLE_MAP = {
__anonb9071f4a0202() 40         {"min", [](const std::string& value, PolicyConfigData::StrategyConfig& appStrategyConfig) {
41             appStrategyConfig.min = XMLParser::IsNumber(value) ? std::stoi(value) : appStrategyConfig.min; }},
__anonb9071f4a0302() 42         {"max", [](const std::string& value, PolicyConfigData::StrategyConfig& appStrategyConfig) {
43             appStrategyConfig.max = XMLParser::IsNumber(value) ? std::stoi(value) : appStrategyConfig.max;  }},
__anonb9071f4a0402() 44         {"dynamicMode", [](const std::string& value, PolicyConfigData::StrategyConfig& appStrategyConfig) {
45             appStrategyConfig.dynamicMode = XMLParser::IsNumber(value) ?
46                 static_cast<DynamicModeType>(std::stoi(value)) : appStrategyConfig.dynamicMode; }},
__anonb9071f4a0502() 47         {"isFactor", [](const std::string& value, PolicyConfigData::StrategyConfig& appStrategyConfig) {
48             appStrategyConfig.isFactor = value == "1"; }},
__anonb9071f4a0602() 49         {"drawMin", [](const std::string& value, PolicyConfigData::StrategyConfig& appStrategyConfig) {
50             appStrategyConfig.drawMin = XMLParser::IsNumber(value) ? std::stoi(value) : 0; }},
__anonb9071f4a0702() 51         {"drawMax", [](const std::string& value, PolicyConfigData::StrategyConfig& appStrategyConfig) {
52             appStrategyConfig.drawMax = XMLParser::IsNumber(value) ? std::stoi(value) : 0; }},
__anonb9071f4a0802() 53         {"down", [](const std::string& value, PolicyConfigData::StrategyConfig& appStrategyConfig) {
54             appStrategyConfig.drawMax = XMLParser::IsNumber(value) ? std::stoi(value) : appStrategyConfig.max; }},
55     };
56 }
57 
HgmMultiAppStrategy()58 HgmMultiAppStrategy::HgmMultiAppStrategy()
59     : screenSettingCache_(defaultScreenSetting), strategyConfigMapCache_(defaultStrategyConfigMap),
60     appStrategyConfigMapCache_(defaultAppStrategyConfigMap),
61     appStrategyConfigMapPreCache_(defaultAppStrategyConfigPreMap), appBufferListCache_(defaultAppBufferList)
62 {
63 }
64 
HandlePkgsEvent(const std::vector<std::string> & pkgs)65 HgmErrCode HgmMultiAppStrategy::HandlePkgsEvent(const std::vector<std::string>& pkgs)
66 {
67     RS_TRACE_FUNC();
68     // update pkgs
69     if (pkgs_ == pkgs) {
70         return HGM_ERROR;
71     }
72     pkgs_ = pkgs;
73     // update pid of pkg
74     for (auto &it : foregroundPidAppMap_) {
75         backgroundPid_.Put(it.first);
76     }
77     foregroundPidAppMap_.clear();
78     pidAppTypeMap_.clear();
79     CheckPackageInConfigList(pkgs_);
80     for (auto &param : pkgs_) {
81         RS_TRACE_NAME_FMT("pkg update:%s", param.c_str());
82         HGM_LOGI("pkg update:%{public}s", param.c_str());
83         auto [pkgName, pid, appType] = AnalyzePkgParam(param);
84         pidAppTypeMap_[pkgName] = { pid, appType };
85         if (pid > DEFAULT_PID) {
86             foregroundPidAppMap_[pid] = { appType, pkgName };
87             backgroundPid_.Erase(pid);
88         }
89     }
90     if (auto configCallbackManager = HgmConfigCallbackManager::GetInstance(); configCallbackManager != nullptr) {
91         configCallbackManager->SyncHgmConfigChangeCallback(foregroundPidAppMap_);
92     }
93 
94     if (!pkgs_.empty()) {
95         touchInfo_.pkgName = std::get<0>(AnalyzePkgParam(pkgs_.front()));
96     }
97     touchInfo_.upExpectFps = OLED_NULL_HZ;
98     CalcVote();
99 
100     return EXEC_SUCCESS;
101 }
102 
HandleTouchInfo(const TouchInfo & touchInfo)103 void HgmMultiAppStrategy::HandleTouchInfo(const TouchInfo& touchInfo)
104 {
105     RS_TRACE_NAME_FMT("[HandleTouchInfo] pkgName:%s, touchState:%d, upExpectFps:%d",
106         touchInfo.pkgName.c_str(), touchInfo.touchState, touchInfo.upExpectFps);
107     HGM_LOGD("touch info update, pkgName:%{public}s, touchState:%{public}d, upExpectFps:%{public}d",
108         touchInfo.pkgName.c_str(), touchInfo.touchState, touchInfo.upExpectFps);
109     touchInfo_ = { touchInfo.pkgName, touchInfo.touchState, touchInfo.upExpectFps };
110     if (touchInfo.pkgName == "" && !pkgs_.empty()) {
111         auto [focusPkgName, pid, appType] = AnalyzePkgParam(pkgs_.front());
112         touchInfo_.pkgName = focusPkgName;
113         HGM_LOGD("auto change touch pkgName to focusPkgName:%{public}s", focusPkgName.c_str());
114     }
115     CalcVote();
116 }
117 
HandleLightFactorStatus(int32_t state)118 void HgmMultiAppStrategy::HandleLightFactorStatus(int32_t state)
119 {
120     RS_TRACE_NAME_FMT("[HandleLightFactorStatus] state: %d", state);
121     if (lightFactorStatus_.load() == state) {
122         return;
123     }
124     lightFactorStatus_.store(state);
125     CalcVote();
126 }
127 
SetScreenType(bool isLtpo)128 void HgmMultiAppStrategy::SetScreenType(bool isLtpo)
129 {
130     isLtpo_ = isLtpo;
131 }
132 
HandleLowAmbientStatus(bool isEffect)133 void HgmMultiAppStrategy::HandleLowAmbientStatus(bool isEffect)
134 {
135     RS_TRACE_NAME_FMT("[HandleLowAmbientStatus] isEffect: %d", isEffect);
136     if (lowAmbientStatus_ == isEffect) {
137         return;
138     }
139     lowAmbientStatus_ = isEffect;
140 }
141 
CalcVote()142 void HgmMultiAppStrategy::CalcVote()
143 {
144     RS_TRACE_FUNC();
145     HgmTaskHandleThread::Instance().DetectMultiThreadingCalls();
146     voteRes_ = { HGM_ERROR, {
147         .min = OLED_NULL_HZ, .max = OLED_120_HZ, .dynamicMode = DynamicModeType::TOUCH_ENABLED,
148         .idleFps = OLED_60_HZ, .isFactor = false, .drawMin = OLED_NULL_HZ,
149         .drawMax = OLED_120_HZ, .down = OLED_120_HZ,
150     }};
151     uniqueTouchInfo_ = std::make_unique<TouchInfo>(touchInfo_);
152 
153     if (pkgs_.size() <= 1) {
154         FollowFocus();
155     } else {
156         switch (screenSettingCache_.multiAppStrategyType) {
157             case MultiAppStrategyType::USE_MAX:
158                 UseMax();
159                 break;
160             case MultiAppStrategyType::FOLLOW_FOCUS:
161                 FollowFocus();
162                 break;
163             case MultiAppStrategyType::USE_STRATEGY_NUM:
164                 UseStrategyNum();
165                 break;
166             default:
167                 UseMax();
168                 break;
169         }
170     }
171 
172     if (voteRes_.first != EXEC_SUCCESS) {
173         // using setting mode when fail to calc vote
174         if (GetAppStrategyConfig("", voteRes_.second) == EXEC_SUCCESS) {
175             OnLightFactor(voteRes_.second);
176         }
177     }
178 
179     UpdateStrategyByTouch(voteRes_.second, "", true);
180     uniqueTouchInfo_ = nullptr;
181 
182     OnStrategyChange();
183 }
184 
GetVoteRes(PolicyConfigData::StrategyConfig & strategyRes) const185 HgmErrCode HgmMultiAppStrategy::GetVoteRes(PolicyConfigData::StrategyConfig& strategyRes) const
186 {
187     strategyRes = voteRes_.second;
188     return voteRes_.first;
189 }
190 
CheckPidValid(pid_t pid,bool onlyCheckForegroundApp)191 bool HgmMultiAppStrategy::CheckPidValid(pid_t pid, bool onlyCheckForegroundApp)
192 {
193     auto configData = HgmCore::Instance().GetPolicyConfigData();
194     if ((configData != nullptr && !configData->safeVoteEnabled) || disableSafeVote_) {
195         // disable safe vote
196         return true;
197     }
198     if (onlyCheckForegroundApp) {
199         return foregroundPidAppMap_.find(pid) != foregroundPidAppMap_.end();
200     }
201     return !backgroundPid_.Existed(pid);
202 }
203 
GetGameNodeName(const std::string & pkgName)204 std::string HgmMultiAppStrategy::GetGameNodeName(const std::string& pkgName)
205 {
206     auto &appNodeMap = screenSettingCache_.gameAppNodeList;
207     if (appNodeMap.find(pkgName) != appNodeMap.end()) {
208         return appNodeMap.at(pkgName);
209     }
210     return "";
211 }
212 
GetAppStrategyConfigName(const std::string & pkgName)213 std::string HgmMultiAppStrategy::GetAppStrategyConfigName(const std::string& pkgName)
214 {
215     auto &appConfigMap = screenSettingCache_.appList;
216     if (appConfigMap.find(pkgName) != appConfigMap.end()) {
217         return appConfigMap.at(pkgName);
218     }
219     if (pidAppTypeMap_.find(pkgName) != pidAppTypeMap_.end()) {
220         auto &appType = pidAppTypeMap_.at(pkgName).second;
221         auto &appTypes = screenSettingCache_.appTypes;
222         if (appTypes.find(appType) != appTypes.end()) {
223             return appTypes.at(appType);
224         }
225     }
226 
227     return screenSettingCache_.strategy;
228 }
229 
GetFocusAppStrategyConfig(PolicyConfigData::StrategyConfig & strategyRes)230 HgmErrCode HgmMultiAppStrategy::GetFocusAppStrategyConfig(PolicyConfigData::StrategyConfig& strategyRes)
231 {
232     auto [pkgName, pid, appType] = AnalyzePkgParam(pkgs_.empty() ? "" : pkgs_.front());
233     return GetAppStrategyConfig(pkgName, strategyRes);
234 }
235 
CleanApp(pid_t pid)236 void HgmMultiAppStrategy::CleanApp(pid_t pid)
237 {
238     foregroundPidAppMap_.erase(pid);
239     backgroundPid_.Erase(pid);
240 }
241 
UpdateXmlConfigCache()242 void HgmMultiAppStrategy::UpdateXmlConfigCache()
243 {
244     auto &hgmCore = HgmCore::Instance();
245     auto frameRateMgr = hgmCore.GetFrameRateMgr();
246 
247     auto configData = hgmCore.GetPolicyConfigData();
248     if (configData == nullptr || frameRateMgr == nullptr) {
249         HGM_LOGD("configData or frameRateMgr is null");
250         return;
251     }
252 
253     // udpate strategyConfigMapCache_
254     strategyConfigMapCache_ = configData->strategyConfigs_;
255     appBufferListCache_ = configData->appBufferList_;
256 
257     // update screenSettingCache_
258     auto curScreenStrategyId = frameRateMgr->GetCurScreenStrategyId();
259     if (configData->screenConfigs_.find(curScreenStrategyId) == configData->screenConfigs_.end()) {
260         HGM_LOGD("curScreenStrategyId not existed: %{public}s", curScreenStrategyId.c_str());
261         return;
262     }
263     auto &screenConfig = configData->screenConfigs_[curScreenStrategyId];
264 
265     auto curRefreshRateMode = std::to_string(frameRateMgr->GetCurRefreshRateMode());
266     if (screenConfig.find(curRefreshRateMode) == screenConfig.end()) {
267         HGM_LOGD("curRefreshRateMode not existed: %{public}s", curRefreshRateMode.c_str());
268         return;
269     }
270 
271     screenSettingCache_ = screenConfig[curRefreshRateMode];
272     appStrategyConfigMapCache_.clear();
273     appStrategyConfigMapPreCache_.clear();
274 }
275 
GetStrategyConfig(const std::string & strategyName,PolicyConfigData::StrategyConfig & strategyRes)276 HgmErrCode HgmMultiAppStrategy::GetStrategyConfig(
277     const std::string& strategyName, PolicyConfigData::StrategyConfig& strategyRes)
278 {
279     if (strategyConfigMapCache_.find(strategyName) != strategyConfigMapCache_.end()) {
280         strategyRes = strategyConfigMapCache_.at(strategyName);
281         return EXEC_SUCCESS;
282     }
283     return HGM_ERROR;
284 }
285 
GetAppStrategyConfig(const std::string & pkgName,PolicyConfigData::StrategyConfig & strategyRes)286 HgmErrCode HgmMultiAppStrategy::GetAppStrategyConfig(
287     const std::string& pkgName, PolicyConfigData::StrategyConfig& strategyRes)
288 {
289     if (appStrategyConfigMapCache_.find(pkgName) != appStrategyConfigMapCache_.end()) {
290         strategyRes = appStrategyConfigMapCache_.at(pkgName);
291         return EXEC_SUCCESS;
292     }
293     return GetStrategyConfig(GetAppStrategyConfigName(pkgName), strategyRes);
294 }
295 
UseStrategyNum()296 void HgmMultiAppStrategy::UseStrategyNum()
297 {
298     auto &strategyName = screenSettingCache_.multiAppStrategyName;
299     RS_TRACE_NAME_FMT("[UseStrategyNum] strategyName:%s", strategyName.c_str());
300     if (strategyConfigMapCache_.find(strategyName) != strategyConfigMapCache_.end()) {
301         voteRes_.first = EXEC_SUCCESS;
302         voteRes_.second = strategyConfigMapCache_.at(strategyName);
303         OnLightFactor(voteRes_.second);
304         UpdateStrategyByTouch(voteRes_.second, touchInfo_.pkgName);
305     }
306 }
307 
FollowFocus()308 void HgmMultiAppStrategy::FollowFocus()
309 {
310     RS_TRACE_FUNC();
311     auto [pkgName, pid, appType] = AnalyzePkgParam(pkgs_.empty() ? "" : pkgs_.front());
312     if (voteRes_.first = GetAppStrategyConfig(pkgName, voteRes_.second); voteRes_.first == EXEC_SUCCESS) {
313         OnLightFactor(voteRes_.second);
314         UpdateStrategyByTouch(voteRes_.second, pkgName);
315     } else {
316         HGM_LOGD("[xml] not find pkg cfg: %{public}s", pkgName.c_str());
317     }
318 }
319 
UseMax()320 void HgmMultiAppStrategy::UseMax()
321 {
322     RS_TRACE_FUNC();
323     PolicyConfigData::StrategyConfig pkgStrategyConfig;
324     for (const auto &param : pkgs_) {
325         auto [pkgName, pid, appType] = AnalyzePkgParam(param);
326         if (GetAppStrategyConfig(pkgName, pkgStrategyConfig) != EXEC_SUCCESS) {
327             continue;
328         }
329         auto isVoteSuccess = voteRes_.first;
330         OnLightFactor(pkgStrategyConfig);
331         UpdateStrategyByTouch(pkgStrategyConfig, pkgName);
332         HGM_LOGD("app %{public}s res: [%{public}d, %{public}d]",
333             pkgName.c_str(), voteRes_.second.min, voteRes_.second.max);
334         if (isVoteSuccess != EXEC_SUCCESS) {
335             voteRes_.first = EXEC_SUCCESS;
336             voteRes_.second = pkgStrategyConfig;
337             continue;
338         }
339         auto &strategyRes = voteRes_.second;
340         strategyRes.min = strategyRes.min > pkgStrategyConfig.min ? strategyRes.min : pkgStrategyConfig.min;
341         strategyRes.max = strategyRes.max > pkgStrategyConfig.max ? strategyRes.max : pkgStrategyConfig.max;
342     }
343 }
344 
AnalyzePkgParam(const std::string & param)345 std::tuple<std::string, pid_t, int32_t> HgmMultiAppStrategy::AnalyzePkgParam(const std::string& param)
346 {
347     std::string pkgName = param;
348     pid_t pid = DEFAULT_PID;
349     int32_t appType = DEFAULT_APP_TYPE;
350 
351     auto index = param.find(":");
352     if (index == std::string::npos) {
353         return { pkgName, pid, appType };
354     }
355 
356     // split by : index
357     pkgName = param.substr(0, index);
358     auto pidAppType = param.substr(index + 1, param.size());
359     index = pidAppType.find(":");
360     if (index == std::string::npos) {
361         if (XMLParser::IsNumber(pidAppType)) {
362             pid = static_cast<pid_t>(std::stoi(pidAppType));
363         }
364         return { pkgName, pid, appType };
365     }
366 
367     // split by : index
368     auto pidStr = pidAppType.substr(0, index);
369     if (XMLParser::IsNumber(pidStr)) {
370         pid = static_cast<pid_t>(std::stoi(pidStr));
371     }
372 
373     auto appTypeStr = pidAppType.substr(index + 1, pidAppType.size());
374     if (XMLParser::IsNumber(appTypeStr)) {
375         appType = std::stoi(appTypeStr);
376     }
377 
378     return { pkgName, pid, appType };
379 }
380 
OnLightFactor(PolicyConfigData::StrategyConfig & strategyRes) const381 void HgmMultiAppStrategy::OnLightFactor(PolicyConfigData::StrategyConfig& strategyRes) const
382 {
383     HGM_LOGD("lightFactorStatus:%{public}d, isFactor:%{public}u, lowAmbientStatus:%{public}u",
384         lightFactorStatus_.load(), strategyRes.isFactor, lowAmbientStatus_);
385     if (!isLtpo_ && lowAmbientStatus_ && lightFactorStatus_.load() == LightFactorStatus::LOW_LEVEL) {
386         strategyRes.min = strategyRes.max;
387         return;
388     }
389     if (lightFactorStatus_.load() == LightFactorStatus::NORMAL_LOW && strategyRes.isFactor && !lowAmbientStatus_) {
390         RS_TRACE_NAME_FMT("OnLightFactor, strategy change: min -> max");
391         strategyRes.min = strategyRes.max;
392     }
393 }
394 
UpdateStrategyByTouch(PolicyConfigData::StrategyConfig & strategy,const std::string & pkgName,bool forceUpdate)395 void HgmMultiAppStrategy::UpdateStrategyByTouch(
396     PolicyConfigData::StrategyConfig& strategy, const std::string& pkgName, bool forceUpdate)
397 {
398     auto frameRateMgr = HgmCore::Instance().GetFrameRateMgr();
399     if (uniqueTouchInfo_ == nullptr || frameRateMgr == nullptr) {
400         return;
401     }
402 
403     if (uniqueTouchInfo_->touchState == TouchState::DOWN_STATE &&
404         (!HgmCore::Instance().GetEnableDynamicMode() || strategy.dynamicMode == DynamicModeType::TOUCH_DISENABLED)) {
405         return;
406     }
407 
408     if (uniqueTouchInfo_->touchState == TouchState::IDLE_STATE) {
409         uniqueTouchInfo_ = nullptr;
410         frameRateMgr->HandleRefreshRateEvent(DEFAULT_PID, {"VOTER_TOUCH", false});
411         return;
412     }
413 
414     auto voteTouchFunc = [this, frameRateMgr] (const PolicyConfigData::StrategyConfig& strategy) {
415         auto touchInfo = std::move(uniqueTouchInfo_);
416         if (touchInfo->touchState == TouchState::DOWN_STATE) {
417             RS_TRACE_NAME_FMT("[UpdateStrategyByTouch] pkgName:%s, state:%d, downFps:%d",
418                 touchInfo->pkgName.c_str(), touchInfo->touchState, strategy.down);
419             frameRateMgr->HandleRefreshRateEvent(DEFAULT_PID, {"VOTER_TOUCH", true, strategy.down, strategy.down});
420         } else if (touchInfo->touchState == TouchState::UP_STATE && touchInfo->upExpectFps > 0) {
421             RS_TRACE_NAME_FMT("[UpdateStrategyByTouch] pkgName:%s, state:%d, upExpectFps:%d",
422                 touchInfo->pkgName.c_str(), touchInfo->touchState, touchInfo->upExpectFps);
423             frameRateMgr->HandleRefreshRateEvent(DEFAULT_PID,
424                 {"VOTER_TOUCH", true, touchInfo->upExpectFps, touchInfo->upExpectFps});
425         }
426     };
427 
428     if (forceUpdate) {
429         // click pkg which not config
430         HGM_LOGD("force update touch info");
431         PolicyConfigData::StrategyConfig settingStrategy;
432         if (GetAppStrategyConfig("", settingStrategy) != EXEC_SUCCESS ||
433             settingStrategy.dynamicMode == DynamicModeType::TOUCH_DISENABLED) {
434             return;
435         }
436         voteTouchFunc(settingStrategy);
437     } else {
438         if (uniqueTouchInfo_->touchState == TouchState::DOWN_STATE && pkgName != uniqueTouchInfo_->pkgName) {
439             return;
440         }
441         voteTouchFunc(strategy);
442     }
443 }
444 
OnStrategyChange()445 void HgmMultiAppStrategy::OnStrategyChange()
446 {
447     HGM_LOGD("multi app strategy change: [%{public}d, %{public}d]", voteRes_.second.min, voteRes_.second.max);
448     for (const auto &callback : strategyChangeCallbacks_) {
449         if (callback != nullptr) {
450             callback(voteRes_.second);
451         }
452     }
453 }
454 
455 // use in temporary scheme to check package name
CheckPackageInConfigList(const std::vector<std::string> & pkgs)456 void HgmMultiAppStrategy::CheckPackageInConfigList(const std::vector<std::string>& pkgs)
457 {
458     auto& rsCommonHook = RsCommonHook::Instance();
459     auto& hgmCore = HgmCore::Instance();
460     auto configData = hgmCore.GetPolicyConfigData();
461     if (configData == nullptr) {
462         return;
463     }
464     rsCommonHook.SetVideoSurfaceFlag(false);
465     rsCommonHook.SetHardwareEnabledByHwcnodeBelowSelfInAppFlag(false);
466     rsCommonHook.SetHardwareEnabledByBackgroundAlphaFlag(false);
467     rsCommonHook.SetIsWhiteListForSolidColorLayerFlag(false);
468     std::unordered_map<std::string, std::string>& videoConfigFromHgm = configData->sourceTuningConfig_;
469     std::unordered_map<std::string, std::string>& solidLayerConfigFromHgm = configData->solidLayerConfig_;
470     std::unordered_map<std::string, std::string>& hwcVideoConfigFromHgm = configData->hwcSourceTuningConfig_;
471     std::unordered_map<std::string, std::string>& hwcSolidLayerConfigFromHgm = configData->hwcSolidLayerConfig_;
472     HgmEnergyConsumptionPolicy::Instance().SetCurrentPkgName(pkgs);
473     if (pkgs.size() > 1) {
474         return;
475     }
476     for (auto &param: pkgs) {
477         std::string pkgNameForCheck = param.substr(0, param.find(':'));
478         // 1 means crop source tuning
479         auto videoIter = videoConfigFromHgm.find(pkgNameForCheck);
480         auto hwcVideoIter = hwcVideoConfigFromHgm.find(pkgNameForCheck);
481         if ((videoIter != videoConfigFromHgm.end() && videoIter->second == "1") ||
482             (hwcVideoIter != hwcVideoConfigFromHgm.end() && hwcVideoIter->second == "1")) {
483             rsCommonHook.SetVideoSurfaceFlag(true);
484         // 2 means skip hardware disabled by hwc node and background alpha
485         } else if ((videoIter != videoConfigFromHgm.end() && videoIter->second == "2") ||
486                    (hwcVideoIter != hwcVideoConfigFromHgm.end() && hwcVideoIter->second == "2")) {
487             rsCommonHook.SetHardwareEnabledByHwcnodeBelowSelfInAppFlag(true);
488             rsCommonHook.SetHardwareEnabledByBackgroundAlphaFlag(true);
489         }
490         // 1 means enable dss by solid color layer
491         auto iter = solidLayerConfigFromHgm.find(pkgNameForCheck);
492         auto hwcIter = hwcSolidLayerConfigFromHgm.find(pkgNameForCheck);
493         if ((iter != solidLayerConfigFromHgm.end() && iter->second == "1") ||
494             (hwcIter != hwcSolidLayerConfigFromHgm.end() && hwcIter->second == "1")) {
495             rsCommonHook.SetIsWhiteListForSolidColorLayerFlag(true);
496         }
497     }
498 }
499 
HandleAppBufferStrategy(const std::string & configName,const std::string & configValue,PolicyConfigData::StrategyConfig & appStrategyConfig)500 void HgmMultiAppStrategy::HandleAppBufferStrategy(const std::string& configName, const std::string& configValue,
501     PolicyConfigData::StrategyConfig& appStrategyConfig)
502 {
503     auto it = find(appBufferListCache_.begin(), appBufferListCache_.end(), configName);
504     if (it == appBufferListCache_.end()) {
505         return;
506     }
507     if (!XMLParser::IsNumber(configValue)) {
508         return;
509     }
510     appStrategyConfig.bufferFpsMap[configName] = std::stoi(configValue);
511 }
512 
SetAppStrategyConfig(const std::string & pkgName,const std::vector<std::pair<std::string,std::string>> & newConfig)513 void HgmMultiAppStrategy::SetAppStrategyConfig(
514     const std::string& pkgName, const std::vector<std::pair<std::string, std::string>>& newConfig)
515 {
516     if (pkgName.empty()) {
517         HGM_LOGI("pkgName is empty, clear all config");
518         appStrategyConfigMapPreCache_.clear();
519         appStrategyConfigMapChanged_ = true;
520         return;
521     }
522 
523     if (newConfig.empty()) {
524         HGM_LOGI("newConfig is empty, clear %{public}s config", pkgName.c_str());
525         appStrategyConfigMapPreCache_.erase(pkgName);
526         appStrategyConfigMapChanged_ = true;
527         return;
528     }
529 
530     PolicyConfigData::StrategyConfig appStrategyConfig;
531     if (GetAppStrategyConfig(pkgName, appStrategyConfig) != EXEC_SUCCESS) {
532         HGM_LOGE("not found  %{public}s strategy config", pkgName.c_str());
533         return;
534     }
535     for (const auto& [configName, configValue] : newConfig) {
536         HGM_LOGD("handle %{public}s config %{public}s = %{public}s",
537             pkgName.c_str(), configName.c_str(), configValue.c_str());
538         if (APP_STRATEGY_CONFIG_HANDLE_MAP.find(configName) != APP_STRATEGY_CONFIG_HANDLE_MAP.end()) {
539             APP_STRATEGY_CONFIG_HANDLE_MAP.at(configName)(configValue, appStrategyConfig);
540         } else {
541             HandleAppBufferStrategy(configName, configValue, appStrategyConfig);
542         }
543     }
544     appStrategyConfigMapPreCache_[pkgName] = appStrategyConfig;
545     appStrategyConfigMapChanged_ = true;
546 }
547 
UpdateAppStrategyConfigCache()548 void HgmMultiAppStrategy::UpdateAppStrategyConfigCache()
549 {
550     if (appStrategyConfigMapChanged_) {
551         HGM_LOGI("UpdateAppStrategyConfigCache on power touch idle");
552         appStrategyConfigMapCache_ = appStrategyConfigMapPreCache_;
553         appStrategyConfigMapChanged_ = false;
554     }
555 }
556 
557 } // namespace Rosen
558 } // namespace OHOS