• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "socperf.h"
17 
18 #include "parameters.h"
19 #include "socperf_trace.h"
20 #include "socperf_hitrace_chain.h"
21 
22 namespace OHOS {
23 namespace SOCPERF {
24 namespace {
25     const int64_t TIME_INTERVAL = 8;
26     const int32_t CANCEL_CMDID_PREFIX = 100000;
27     const std::string DEFAULT_MODE = "default";
28     const std::string SPLIT_COLON = ":";
29     const std::string ACTION_MODE_STRING = "actionmode";
30     const std::string WEAK_ACTION_STRING = "weakaction";
31     const int32_t DEVICEMODE_PARAM_NUMBER = 2;
32     const int32_t MODE_TYPE_INDEX = 0;
33     const int32_t MODE_NAME_INDEX = 1;
34     const int32_t CONFIG_MIN_SIZE = 1;
35     const int32_t INVALID_CMD_ID = -1;
36     const int32_t BATTERY_LIMIT_CMD_ID = -2;
37     const int32_t PERF_REQUEST_CMD_ID_EVENT_FLING           = 10008;
38     const int32_t PERF_REQUEST_CMD_ID_EVENT_TOUCH_DOWN      = 10010;
39     const int32_t PERF_REQUEST_CMD_ID_EVENT_TOUCH_UP        = 10040;
40     const int32_t PERF_REQUEST_CMD_ID_EVENT_DRAG            = 10092;
41 
42 }
SocPerf()43 SocPerf::SocPerf()
44 {
45 }
46 
~SocPerf()47 SocPerf::~SocPerf()
48 {
49     socperfThreadWrap_ = nullptr;
50 }
51 
Init()52 bool SocPerf::Init()
53 {
54     if (!socPerfConfig_.Init()) {
55         SOC_PERF_LOGE("Failed to init SocPerf config");
56         return false;
57     }
58 
59     if (!CreateThreadWraps()) {
60         SOC_PERF_LOGE("Failed to create threadwraps threads");
61         return false;
62     }
63     InitThreadWraps();
64     enabled_ = true;
65     CompleteEvent();
66     return true;
67 }
68 
CreateThreadWraps()69 bool SocPerf::CreateThreadWraps()
70 {
71     socperfThreadWrap_ = std::make_shared<SocPerfThreadWrap>();
72     if (!socperfThreadWrap_) {
73         SOC_PERF_LOGE("Failed to Create socPerfThreadWrap");
74         return false;
75     }
76     SOC_PERF_LOGD("Success to Create All threadWrap threads");
77     return true;
78 }
79 
InitThreadWraps()80 void SocPerf::InitThreadWraps()
81 {
82     socperfThreadWrap_->InitResourceNodeInfo();
83 }
84 
CompleteEvent()85 bool SocPerf::CompleteEvent()
86 {
87     std::unordered_map<int32_t, std::shared_ptr<Actions>>& perfActionsInfo =
88         socPerfConfig_.configPerfActionsInfo_[DEFAULT_CONFIG_MODE];
89     CopyEvent(PERF_REQUEST_CMD_ID_EVENT_TOUCH_DOWN, PERF_REQUEST_CMD_ID_EVENT_TOUCH_UP, perfActionsInfo);
90     CopyEvent(PERF_REQUEST_CMD_ID_EVENT_FLING, PERF_REQUEST_CMD_ID_EVENT_DRAG, perfActionsInfo);
91     return true;
92 }
93 
CopyEvent(const int32_t oldCmdId,const int32_t newCmdId,std::unordered_map<int32_t,std::shared_ptr<Actions>> & perfActionsInfo)94 void SocPerf::CopyEvent(const int32_t oldCmdId, const int32_t newCmdId,
95     std::unordered_map<int32_t, std::shared_ptr<Actions>>& perfActionsInfo)
96 {
97     if (perfActionsInfo.find(oldCmdId) == perfActionsInfo.end() ||
98         perfActionsInfo.find(newCmdId) != perfActionsInfo.end()) {
99         SOC_PERF_LOGE("Already have event %{public}d", newCmdId);
100         return;
101     }
102     std::shared_ptr<Actions> oldActions = perfActionsInfo[oldCmdId];
103     std::shared_ptr<Actions> newActions = std::make_shared<Actions>(newCmdId, oldActions->name);
104     newActions->id = newCmdId;
105     newActions->name = oldActions->name;
106     newActions->actionList = oldActions->actionList;
107     newActions->modeMap = oldActions->modeMap;
108     newActions->isLongTimePerf = oldActions->isLongTimePerf;
109     newActions->interaction = oldActions->interaction;
110     perfActionsInfo[newCmdId] = newActions;
111     socPerfConfig_.configPerfActionsInfo_[DEFAULT_CONFIG_MODE] = perfActionsInfo;
112     SOC_PERF_LOGI("Complete event %{public}d", oldCmdId);
113 }
114 
PerfRequest(int32_t cmdId,const std::string & msg)115 void SocPerf::PerfRequest(int32_t cmdId, const std::string& msg)
116 {
117     SocPerfHiTraceChain traceChain(__func__);
118     if (!enabled_ || !perfRequestEnable_) {
119         SOC_PERF_LOGD("SocPerf disabled!");
120         return;
121     }
122     if (!CheckTimeInterval(true, cmdId)) {
123         SOC_PERF_LOGD("cmdId %{public}d can not trigger, because time interval", cmdId);
124         return;
125     }
126 
127     int32_t matchCmdId = GetMatchCmdId(cmdId, false);
128     if (matchCmdId == INVALID_CMD_ID) {
129         SOC_PERF_LOGD("Invalid PerfRequest cmdId[%{public}d]", cmdId);
130         return;
131     }
132     SOC_PERF_LOGD("cmdId[%{public}d]matchCmdId[%{public}d]msg[%{public}s]", cmdId, matchCmdId, msg.c_str());
133 
134     std::string trace_str(__func__);
135     trace_str.append(",cmdId[").append(std::to_string(matchCmdId)).append("]");
136     trace_str.append(",msg[").append(msg).append("]");
137     StartTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_SOCPERF, trace_str.c_str());
138     DoFreqActions(GetActionsInfo(matchCmdId), EVENT_INVALID, ACTION_TYPE_PERF);
139     FinishTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_SOCPERF);
140     UpdateCmdIdCount(cmdId);
141 }
142 
PerfRequestEx(int32_t cmdId,bool onOffTag,const std::string & msg)143 void SocPerf::PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg)
144 {
145     SocPerfHiTraceChain traceChain(__func__);
146     if (!enabled_ || !perfRequestEnable_) {
147         SOC_PERF_LOGD("SocPerf disabled!");
148         return;
149     }
150     if (!CheckTimeInterval(onOffTag, cmdId)) {
151         SOC_PERF_LOGD("cmdId %{public}d can not trigger, because time interval", cmdId);
152         return;
153     }
154     int32_t matchCmdId = GetMatchCmdId(cmdId, true);
155     if (matchCmdId == INVALID_CMD_ID) {
156         SOC_PERF_LOGD("Invalid PerfRequestEx cmdId[%{public}d]", cmdId);
157         return;
158     }
159     SOC_PERF_LOGD("cmdId[%{public}d]matchCmdId[%{public}d]onOffTag[%{public}d]msg[%{public}s]",
160         cmdId, matchCmdId, onOffTag, msg.c_str());
161 
162     std::string trace_str(__func__);
163     trace_str.append(",cmdId[").append(std::to_string(matchCmdId)).append("]");
164     trace_str.append(",onOff[").append(std::to_string(onOffTag)).append("]");
165     trace_str.append(",msg[").append(msg).append("]");
166     StartTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_SOCPERF, trace_str.c_str());
167     DoFreqActions(GetActionsInfo(matchCmdId), onOffTag ? EVENT_ON : EVENT_OFF, ACTION_TYPE_PERF);
168     FinishTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_SOCPERF);
169     if (onOffTag) {
170         UpdateCmdIdCount(cmdId);
171     }
172 }
173 
PowerLimitBoost(bool onOffTag,const std::string & msg)174 void SocPerf::PowerLimitBoost(bool onOffTag, const std::string& msg)
175 {
176     SocPerfHiTraceChain traceChain(__func__);
177     if (!enabled_) {
178         SOC_PERF_LOGD("SocPerf disabled!");
179         return;
180     }
181     if (msg == "Low_battery_limit") {
182         batteryLimitStatus_ = onOffTag;
183     } else {
184         powerLimitStatus_ = onOffTag;
185     }
186     onOffTag = batteryLimitStatus_ || powerLimitStatus_;
187 
188     SOC_PERF_LOGI("onOffTag[%{public}d]msg[%{public}s]", onOffTag, msg.c_str());
189     std::string trace_str(__func__);
190     trace_str.append(",onOff[").append(std::to_string(onOffTag)).append("]");
191     trace_str.append(",msg[").append(msg).append("]");
192     StartTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_SOCPERF, trace_str.c_str());
193     socperfThreadWrap_->UpdatePowerLimitBoostFreq(onOffTag);
194     HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::RSS, "LIMIT_BOOST",
195                     OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
196                     "CLIENT_ID", ACTION_TYPE_POWER,
197                     "ON_OFF_TAG", onOffTag);
198     FinishTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_SOCPERF);
199 }
200 
ThermalLimitBoost(bool onOffTag,const std::string & msg)201 void SocPerf::ThermalLimitBoost(bool onOffTag, const std::string& msg)
202 {
203     SocPerfHiTraceChain traceChain(__func__);
204     if (!enabled_) {
205         SOC_PERF_LOGD("SocPerf disabled!");
206         return;
207     }
208     SOC_PERF_LOGI("onOffTag[%{public}d]msg[%{public}s]", onOffTag, msg.c_str());
209     std::string trace_str(__func__);
210     trace_str.append(",onOff[").append(std::to_string(onOffTag)).append("]");
211     trace_str.append(",msg[").append(msg).append("]");
212     StartTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_SOCPERF, trace_str.c_str());
213     socperfThreadWrap_->UpdateThermalLimitBoostFreq(onOffTag);
214     HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::RSS, "LIMIT_BOOST",
215                     OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
216                     "CLIENT_ID", ACTION_TYPE_THERMAL,
217                     "ON_OFF_TAG", onOffTag);
218     FinishTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_SOCPERF);
219 }
220 
SendLimitRequestEventOff(std::shared_ptr<SocPerfThreadWrap> threadWrap,int32_t clientId,int32_t resId,int32_t eventId)221 void SocPerf::SendLimitRequestEventOff(std::shared_ptr<SocPerfThreadWrap> threadWrap,
222     int32_t clientId, int32_t resId, int32_t eventId)
223 {
224     int32_t cmdId = -1;
225     int32_t newClientId = clientId;
226     if (newClientId == (int32_t)ACTION_TYPE_BATTERY) {
227         cmdId = BATTERY_LIMIT_CMD_ID;
228         newClientId = (int32_t)ACTION_TYPE_POWER;
229     }
230     auto iter = limitRequest_[clientId].find(resId);
231     if (iter != limitRequest_[clientId].end()
232         && limitRequest_[clientId][resId] != INVALID_VALUE) {
233         auto resAction = std::make_shared<ResAction>(
234             limitRequest_[clientId][resId], 0, newClientId, EVENT_OFF, cmdId, MAX_INT_VALUE);
235         threadWrap->UpdateLimitStatus(eventId, resAction, resId);
236         limitRequest_[clientId].erase(iter);
237     }
238 }
239 
SendLimitRequestEventOn(std::shared_ptr<SocPerfThreadWrap> threadWrap,int32_t clientId,int32_t resId,int64_t resValue,int32_t eventId)240 void SocPerf::SendLimitRequestEventOn(std::shared_ptr<SocPerfThreadWrap> threadWrap,
241     int32_t clientId, int32_t resId, int64_t resValue, int32_t eventId)
242 {
243     if (resValue != INVALID_VALUE && resValue != RESET_VALUE) {
244         int32_t cmdId = -1;
245         int32_t newClientId = clientId;
246         if (newClientId == (int32_t)ACTION_TYPE_BATTERY) {
247             cmdId = BATTERY_LIMIT_CMD_ID;
248             newClientId = (int32_t)ACTION_TYPE_POWER;
249         }
250         auto resAction = std::make_shared<ResAction>(resValue, 0, newClientId, EVENT_ON, cmdId, MAX_INT_VALUE);
251         threadWrap->UpdateLimitStatus(eventId, resAction, resId);
252         limitRequest_[clientId].insert(std::pair<int32_t, int32_t>(resId, resValue));
253     }
254 }
255 
SendLimitRequestEvent(int32_t clientId,int32_t resId,int64_t resValue)256 void SocPerf::SendLimitRequestEvent(int32_t clientId, int32_t resId, int64_t resValue)
257 {
258     int32_t eventId = 0;
259     int32_t realResId = 0;
260     int32_t levelResId = 0;
261     if (resId > RES_ID_ADDITION) {
262         realResId = resId - RES_ID_ADDITION;
263         levelResId = resId;
264         eventId = INNER_EVENT_ID_DO_FREQ_ACTION_LEVEL;
265         SOC_PERF_LOGI("SocPerf DO_FREQ_ACTION_LEVEL");
266     } else {
267         realResId = resId;
268         levelResId = resId + RES_ID_ADDITION;
269         eventId = INNER_EVENT_ID_DO_FREQ_ACTION;
270     }
271 
272     if (!socPerfConfig_.IsValidResId(realResId)) {
273         return;
274     }
275     std::lock_guard<std::mutex> lock(mutex_);
276     SendLimitRequestEventOff(socperfThreadWrap_, clientId, realResId, INNER_EVENT_ID_DO_FREQ_ACTION);
277     SendLimitRequestEventOff(socperfThreadWrap_, clientId, levelResId, INNER_EVENT_ID_DO_FREQ_ACTION_LEVEL);
278     SendLimitRequestEventOn(socperfThreadWrap_, clientId, resId, resValue, eventId);
279 }
280 
LimitRequest(int32_t clientId,const std::vector<int32_t> & tags,const std::vector<int64_t> & configs,const std::string & msg)281 void SocPerf::LimitRequest(int32_t clientId,
282     const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg)
283 {
284     SocPerfHiTraceChain traceChain(__func__);
285     if (!enabled_) {
286         SOC_PERF_LOGE("SocPerf disabled!");
287         return;
288     }
289     if (tags.size() != configs.size()) {
290         SOC_PERF_LOGE("tags'size and configs' size must be the same!");
291         return;
292     }
293     if (clientId <= (int32_t)ACTION_TYPE_PERF || clientId >= (int32_t)ACTION_TYPE_MAX) {
294         SOC_PERF_LOGE("clientId must be between ACTION_TYPE_PERF and ACTION_TYPE_MAX!");
295         return;
296     }
297     std::string trace_str(__func__);
298     trace_str.append(",clientId[").append(std::to_string(clientId)).append("]");
299     trace_str.append(",msg[").append(msg).append("]");
300     for (int32_t i = 0; i < (int32_t)tags.size(); i++) {
301         trace_str.append(",tags[").append(std::to_string(tags[i])).append("]");
302         trace_str.append(",configs[").append(std::to_string(configs[i])).append("]");
303         SendLimitRequestEvent(clientId, tags[i], configs[i]);
304     }
305     StartTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_SOCPERF, trace_str.c_str());
306     SOC_PERF_LOGI("socperf limit %{public}s", trace_str.c_str());
307     FinishTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_SOCPERF);
308 }
309 
SetRequestStatus(bool status,const std::string & msg)310 void SocPerf::SetRequestStatus(bool status, const std::string& msg)
311 {
312     SOC_PERF_LOGI("requestEnable is changed to %{public}d, the reason is %{public}s", status, msg.c_str());
313     perfRequestEnable_ = status;
314     /* disable socperf sever, we should clear all alive request to avoid high freq for long time */
315     if (!perfRequestEnable_) {
316         ClearAllAliveRequest();
317     }
318 }
319 
ClearAllAliveRequest()320 void SocPerf::ClearAllAliveRequest()
321 {
322     if (!enabled_) {
323         SOC_PERF_LOGE("SocPerf disabled!");
324         return;
325     }
326     socperfThreadWrap_->ClearAllAliveRequest();
327 }
328 
SetThermalLevel(int32_t level)329 void SocPerf::SetThermalLevel(int32_t level)
330 {
331     SocPerfHiTraceChain traceChain(__func__);
332     if (!enabled_) {
333         SOC_PERF_LOGE("SocPerf disabled!");
334         return;
335     }
336     std::string trace_str(__func__);
337     trace_str.append(",level[").append(std::to_string(level)).append("]");
338     StartTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_SOCPERF, trace_str.c_str());
339     SOC_PERF_LOGI("ThermalLevel:%{public}d", level);
340     FinishTraceEx(HITRACE_LEVEL_INFO, HITRACE_TAG_SOCPERF);
341     thermalLvl_ = level;
342     socperfThreadWrap_->thermalLvl_ = level;
343 }
344 
DoPerfRequestThremalLvl(int32_t cmdId,std::shared_ptr<Action> originAction,int32_t onOff,std::shared_ptr<ResActionItem> curItem,int64_t endTime)345 std::shared_ptr<ResActionItem> SocPerf::DoPerfRequestThremalLvl(int32_t cmdId, std::shared_ptr<Action> originAction,
346     int32_t onOff, std::shared_ptr<ResActionItem> curItem, int64_t endTime)
347 {
348     if (curItem == nullptr) {
349         return curItem;
350     }
351     std::shared_ptr<Actions> cmdConfig = GetActionsInfo(originAction->thermalCmdId_);
352     if (cmdConfig == nullptr) {
353         SOC_PERF_LOGE("cmd %{public}d is not exist", originAction->thermalCmdId_);
354         return curItem;
355     }
356 
357     // select the Nearest thermallevel action
358     std::shared_ptr<Action> action = nullptr;
359     for (auto iter = cmdConfig->actionList.begin(); iter != cmdConfig->actionList.end(); iter++) {
360         if ((*iter)->thermalLvl_ <= thermalLvl_) {
361             if (action == nullptr || action->thermalLvl_ <= (*iter)->thermalLvl_) {
362                 action = *iter;
363             }
364         }
365     }
366     if (action == nullptr) {
367         return curItem;
368     }
369 
370     for (int32_t i = 0; i < (int32_t)action->variable.size() - 1; i += RES_ID_AND_VALUE_PAIR) {
371         if (!socPerfConfig_.IsValidResId(action->variable[i])) {
372             continue;
373         }
374 
375         auto resActionItem = std::make_shared<ResActionItem>(action->variable[i]);
376         resActionItem->resAction = std::make_shared<ResAction>(action->variable[i + 1], originAction->duration,
377             ACTION_TYPE_PERFLVL, onOff, cmdId, endTime);
378         curItem->next = resActionItem;
379         curItem = curItem->next;
380     }
381     return curItem;
382 }
383 
DoFreqActions(std::shared_ptr<Actions> actions,int32_t onOff,int32_t actionType)384 void SocPerf::DoFreqActions(std::shared_ptr<Actions> actions, int32_t onOff, int32_t actionType)
385 {
386     std::shared_ptr<ResActionItem> header = nullptr;
387     std::shared_ptr<ResActionItem> curItem = nullptr;
388     auto now = std::chrono::system_clock::now();
389     int64_t curMs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
390     for (auto iter = actions->actionList.begin(); iter != actions->actionList.end(); iter++) {
391         std::shared_ptr<Action> action = *iter;
392         if (action->duration == 0 && onOff == EVENT_INVALID) {
393             continue;
394         }
395         int64_t endTime = action->duration == 0 ? MAX_INT_VALUE : curMs + action->duration;
396         for (int32_t i = 0; i < (int32_t)action->variable.size() - 1; i += RES_ID_AND_VALUE_PAIR) {
397             if (!socPerfConfig_.IsValidResId(action->variable[i])) {
398                 continue;
399             }
400 
401             auto resActionItem = std::make_shared<ResActionItem>(action->variable[i]);
402             resActionItem->resAction = std::make_shared<ResAction>(action->variable[i + 1], action->duration,
403                 actionType, onOff, actions->id, endTime);
404             if (actions->interaction == false) {
405                 resActionItem->resAction->interaction = false;
406             }
407             if (curItem) {
408                 curItem->next = resActionItem;
409             } else {
410                 header = resActionItem;
411             }
412             curItem = resActionItem;
413         }
414         if (action->thermalCmdId_ != INVALID_THERMAL_CMD_ID && thermalLvl_ >= socPerfConfig_.minThermalLvl_) {
415             curItem = DoPerfRequestThremalLvl(actions->id, action, onOff, curItem, endTime);
416         }
417     }
418     socperfThreadWrap_->DoFreqActionPack(header);
419     socperfThreadWrap_->PostDelayTask(header);
420 }
421 
RequestDeviceMode(const std::string & mode,bool status)422 void SocPerf::RequestDeviceMode(const std::string& mode, bool status)
423 {
424     if (!enabled_) {
425         SOC_PERF_LOGE("SocPerf disabled!");
426         return;
427     }
428     SOC_PERF_LOGD("device mode %{public}s status changed to %{public}d", mode.c_str(), status);
429 
430     if (mode.empty() || mode.length() > MAX_RES_MODE_LEN) {
431         return;
432     }
433 
434     std::vector<std::string> modeParamList = Split(mode, SPLIT_COLON);
435     if (modeParamList.size() != DEVICEMODE_PARAM_NUMBER) {
436         SOC_PERF_LOGE("device mode %{public}s format is wrong.", mode.c_str());
437         return;
438     }
439 
440     const std::string modeType = modeParamList[MODE_TYPE_INDEX];
441     const std::string modeName = modeParamList[MODE_NAME_INDEX];
442     if (modeType == ACTION_MODE_STRING && modeName == WEAK_ACTION_STRING) {
443         socperfThreadWrap_->SetWeakInteractionStatus(status);
444         return;
445     }
446     auto iter = socPerfConfig_.sceneResourceInfo_.find(modeType);
447     if (iter == socPerfConfig_.sceneResourceInfo_.end()) {
448         SOC_PERF_LOGD("No matching device mode found.");
449         return;
450     }
451 
452     const std::shared_ptr<SceneResNode> sceneResNode = iter->second;
453     const std::vector<std::shared_ptr<SceneItem>> items = sceneResNode->items;
454     const int32_t persistMode = sceneResNode->persistMode;
455 
456     const std::string modeStr = MatchDeviceMode(modeName, status, items);
457     if (persistMode == REPORT_TO_PERFSO && socPerfConfig_.scenarioFunc_) {
458         const std::string msgStr = modeType + ":" + modeStr;
459         SOC_PERF_LOGD("send deviceMode to PerfScenario : %{public}s", msgStr.c_str());
460         socPerfConfig_.scenarioFunc_(msgStr);
461     }
462 }
463 
MatchDeviceMode(const std::string & mode,bool status,const std::vector<std::shared_ptr<SceneItem>> & items)464 std::string SocPerf::MatchDeviceMode(const std::string& mode, bool status,
465     const std::vector<std::shared_ptr<SceneItem>>& items)
466 {
467     std::lock_guard<std::mutex> lock(mutexDeviceMode_);
468 
469     if (!status) {
470         recordDeviceMode_.erase(mode);
471         return DEFAULT_MODE;
472     }
473 
474     std::string itemName = DEFAULT_MODE;
475     for (const auto& iter : items) {
476         if (iter->name == mode) {
477             recordDeviceMode_.insert(mode);
478             if (iter->req == REPORT_TO_PERFSO) {
479                 itemName = mode;
480             }
481         } else {
482             recordDeviceMode_.erase(iter->name);
483         }
484     }
485     return itemName;
486 }
487 
MatchDeviceModeCmd(int32_t cmdId,bool isTagOnOff)488 int32_t SocPerf::MatchDeviceModeCmd(int32_t cmdId, bool isTagOnOff)
489 {
490     auto itrPerfActionsInfo = socPerfConfig_.configPerfActionsInfo_.find(DEFAULT_CONFIG_MODE);
491     if (itrPerfActionsInfo == socPerfConfig_.configPerfActionsInfo_.end()) {
492         return cmdId;
493     }
494 
495     auto itrActions = itrPerfActionsInfo->second.find(cmdId);
496     if (itrActions == itrPerfActionsInfo->second.end()) {
497         return cmdId;
498     }
499 
500     if (itrActions->second->modeMap.empty() || (isTagOnOff && itrActions->second->isLongTimePerf)) {
501         return cmdId;
502     }
503 
504     std::lock_guard<std::mutex> lock(mutexDeviceMode_);
505     if (recordDeviceMode_.empty()) {
506         return cmdId;
507     }
508 
509     for (const auto& iter : itrActions->second->modeMap) {
510         if (recordDeviceMode_.find(iter->mode) != recordDeviceMode_.end()) {
511             int32_t deviceCmdId = iter->cmdId;
512             auto itrDeviceCmdId = itrPerfActionsInfo->second.find(deviceCmdId);
513             if (itrDeviceCmdId == itrPerfActionsInfo->second.end()) {
514                 SOC_PERF_LOGW("Invaild actions cmdid %{public}d", deviceCmdId);
515                 return cmdId;
516             }
517             if (isTagOnOff && itrDeviceCmdId->second->isLongTimePerf) {
518                 SOC_PERF_LOGD("long time perf not match cmdId %{public}d", deviceCmdId);
519                 return cmdId;
520             }
521             return deviceCmdId;
522         }
523     }
524     return cmdId;
525 }
526 
UpdateCmdIdCount(int32_t cmdId)527 void SocPerf::UpdateCmdIdCount(int32_t cmdId)
528 {
529     std::lock_guard<std::mutex> lock(mutexBoostCmdCount_);
530     if (boostCmdCount_.find(cmdId) == boostCmdCount_.end()) {
531         boostCmdCount_[cmdId] = 0;
532     }
533     boostCmdCount_[cmdId]++;
534 }
535 
RequestCmdIdCount(const std::string & msg)536 std::string SocPerf::RequestCmdIdCount(const std::string &msg)
537 {
538     std::lock_guard<std::mutex> lock(mutexBoostCmdCount_);
539     std::stringstream ret;
540     for (const auto& pair : boostCmdCount_) {
541         if (ret.str().length() > 0) {
542             ret << ",";
543         }
544         ret << pair.first << ":" << pair.second;
545     }
546     return ret.str();
547 }
548 
GetDeviceMode()549 std::string SocPerf::GetDeviceMode()
550 {
551     if (recordDeviceMode_.empty()) {
552         return DEFAULT_CONFIG_MODE;
553     }
554     return *recordDeviceMode_.begin();
555 }
556 
GetMatchCmdId(int32_t cmdId,bool isTagOnOff)557 int32_t SocPerf::GetMatchCmdId(int32_t cmdId, bool isTagOnOff)
558 {
559     int32_t matchCmdId = INVALID_CMD_ID;
560     std::string matchMode = GetDeviceMode();
561     if ((socPerfConfig_.configPerfActionsInfo_.find(matchMode) ==
562         socPerfConfig_.configPerfActionsInfo_.end() ||
563         socPerfConfig_.configPerfActionsInfo_[matchMode].find(cmdId) ==
564         socPerfConfig_.configPerfActionsInfo_[matchMode].end()) &&
565         socPerfConfig_.configPerfActionsInfo_[DEFAULT_CONFIG_MODE].find(cmdId) ==
566         socPerfConfig_.configPerfActionsInfo_[DEFAULT_CONFIG_MODE].end()) {
567         return matchCmdId;
568     }
569     matchCmdId = cmdId;
570     if (socPerfConfig_.configPerfActionsInfo_.size() == CONFIG_MIN_SIZE &&
571         socPerfConfig_.configPerfActionsInfo_.find(DEFAULT_CONFIG_MODE) !=
572         socPerfConfig_.configPerfActionsInfo_.end()) {
573         matchCmdId = MatchDeviceModeCmd(cmdId, isTagOnOff);
574     }
575     return matchCmdId;
576 }
577 
GetActionsInfo(int32_t cmdId)578 std::shared_ptr<Actions> SocPerf::GetActionsInfo(int32_t cmdId)
579 {
580     std::string matchMode = GetDeviceMode();
581     if (socPerfConfig_.configPerfActionsInfo_.find(matchMode) !=
582         socPerfConfig_.configPerfActionsInfo_.end() &&
583         socPerfConfig_.configPerfActionsInfo_[matchMode].find(cmdId) !=
584         socPerfConfig_.configPerfActionsInfo_[matchMode].end()) {
585         return socPerfConfig_.configPerfActionsInfo_[matchMode][cmdId];
586     }
587     return socPerfConfig_.configPerfActionsInfo_[DEFAULT_CONFIG_MODE][cmdId];
588 }
589 
CheckTimeInterval(bool onOff,int32_t cmdId)590 bool SocPerf::CheckTimeInterval(bool onOff, int32_t cmdId)
591 {
592     std::lock_guard<std::mutex> lock(mutexBoostTime_);
593     auto now = std::chrono::system_clock::now();
594     uint64_t curMs = static_cast<uint64_t>(
595         std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count());
596     int32_t cancelCmdId = cmdId + CANCEL_CMDID_PREFIX;
597     int32_t recordCmdId = cmdId;
598     if (onOff) {
599         boostTime_[cancelCmdId] = 0;
600     }
601     if (!onOff) {
602         recordCmdId = cancelCmdId;
603     }
604     if (boostTime_.find(recordCmdId) == boostTime_.end()) {
605         boostTime_[recordCmdId] = curMs;
606         return true;
607     }
608     if (curMs - boostTime_[recordCmdId] > TIME_INTERVAL) {
609         boostTime_[recordCmdId] = curMs;
610         return true;
611     }
612     return false;
613 }
614 } // namespace SOCPERF
615 } // namespace OHOS
616