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