• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "cgroup_event_handler.h"
17 #include <cinttypes>
18 #include "ability_info.h"
19 #include "app_mgr_constants.h"
20 #include "cgroup_adjuster.h"
21 #include "cgroup_sched_log.h"
22 #include "hisysevent.h"
23 #include "ressched_utils.h"
24 #include "res_type.h"
25 #include "sched_controller.h"
26 #include "sched_policy.h"
27 #include "system_ability_definition.h"
28 #ifdef POWER_MANAGER_ENABLE
29 #include "power_mgr_client.h"
30 #endif
31 
32 #undef LOG_TAG
33 #define LOG_TAG "CgroupEventHandler"
34 
35 namespace OHOS {
36 namespace ResourceSchedule {
37 namespace {
38     constexpr uint32_t EVENT_ID_REG_APP_STATE_OBSERVER = 1;
39     constexpr uint32_t EVENT_ID_REG_BGTASK_OBSERVER = 2;
40     constexpr uint32_t DELAYED_RETRY_REGISTER_DURATION = 100;
41     constexpr uint32_t MAX_RETRY_TIMES = 100;
42     constexpr uint32_t MAX_SPAN_SERIAL = 99;
43     const std::string MMI_SERVICE_NAME = "mmi_service";
44 }
45 
46 using OHOS::AppExecFwk::ApplicationState;
47 using OHOS::AppExecFwk::AbilityState;
48 using OHOS::AppExecFwk::AbilityType;
49 using OHOS::AppExecFwk::ExtensionState;
50 using OHOS::AppExecFwk::ProcessType;
51 
CgroupEventHandler(const std::string & queueName)52 CgroupEventHandler::CgroupEventHandler(const std::string &queueName)
53 {
54     cgroupEventQueue_ = std::make_shared<ffrt::queue>(queueName.c_str(),
55         ffrt::queue_attr().qos(ffrt::qos_user_interactive));
56     if (!cgroupEventQueue_) {
57         CGS_LOGE("%{public}s : create cgroupEventQueue_ failed", __func__);
58     }
59 }
60 
~CgroupEventHandler()61 CgroupEventHandler::~CgroupEventHandler()
62 {
63     supervisor_ = nullptr;
64     cgroupEventQueue_ = nullptr;
65     delayTaskMap_.clear();
66 }
67 
ProcessEvent(uint32_t eventId,int64_t eventParam)68 void CgroupEventHandler::ProcessEvent(uint32_t eventId, int64_t eventParam)
69 {
70     CGS_LOGD("%{public}s : eventId:%{public}d param:%{public}" PRIu64,
71         __func__, eventId, eventParam);
72 }
73 
SetSupervisor(std::shared_ptr<Supervisor> supervisor)74 void CgroupEventHandler::SetSupervisor(std::shared_ptr<Supervisor> supervisor)
75 {
76     supervisor_ = supervisor;
77 }
78 
HandleAbilityAdded(int32_t saId,const std::string & deviceId)79 void CgroupEventHandler::HandleAbilityAdded(int32_t saId, const std::string& deviceId)
80 {
81     switch (saId) {
82         case APP_MGR_SERVICE_ID:
83             if (supervisor_ != nullptr) {
84                 supervisor_->InitSuperVisorContent();
85             }
86             break;
87 #ifdef POWER_MANAGER_ENABLE
88         case POWER_MANAGER_SERVICE_ID:
89             SchedController::GetInstance().GetRunningLockState();
90             break;
91 #endif
92         default:
93             break;
94     }
95 }
96 
HandleAbilityRemoved(int32_t saId,const std::string & deviceId)97 void CgroupEventHandler::HandleAbilityRemoved(int32_t saId, const std::string& deviceId)
98 {
99     CGS_LOGD("%{public}s : saId:%{public}d", __func__, saId);
100 }
101 
HandleApplicationStateChanged(uint32_t resType,int64_t value,const nlohmann::json & payload)102 void CgroupEventHandler::HandleApplicationStateChanged(uint32_t resType, int64_t value, const nlohmann::json& payload)
103 {
104     if (!supervisor_) {
105         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
106         return;
107     }
108 
109     int32_t uid = 0;
110     int32_t pid = 0;
111     std::string bundleName;
112     int32_t state = 0;
113 
114     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload) ||
115         !ParseString(bundleName, "bundleName", payload) || !ParseValue(state, "state", payload)) {
116         CGS_LOGD("%{public}s: param error", __func__);
117         return;
118     }
119 
120     CGS_LOGD("%{public}s : %{public}d, %{public}s, %{public}d", __func__, uid, bundleName.c_str(), state);
121     ChronoScope cs("HandleApplicationStateChanged");
122     if (state == (int32_t)(ApplicationState::APP_STATE_TERMINATED)) {
123         return;
124     }
125     std::shared_ptr<Application> app = supervisor_->GetAppRecordNonNull(uid);
126     app->SetName(bundleName);
127     app->state_ = state;
128 }
129 
HandleProcessStateChanged(uint32_t resType,int64_t value,const nlohmann::json & payload)130 void CgroupEventHandler::HandleProcessStateChanged(uint32_t resType, int64_t value, const nlohmann::json& payload)
131 {
132     int32_t uid = 0;
133     int32_t pid = 0;
134     std::string bundleName;
135     int32_t state = 0;
136     if (!ParseValue(uid, "uid", payload) ||
137         !ParseValue(pid, "pid", payload) ||
138         !ParseString(bundleName, "bundleName", payload) ||
139         !ParseValue(state, "state", payload)) {
140         CGS_LOGE("%{public}s: param error", __func__);
141         return;
142     }
143     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}s, %{public}d", __func__, uid,
144         pid, bundleName.c_str(), state);
145     ChronoScope cs("HandleProcessStateChanged");
146     std::shared_ptr<Application> app = supervisor_->GetAppRecordNonNull(uid);
147     std::shared_ptr<ProcessRecord> procRecord = app->GetProcessRecordNonNull(pid);
148     procRecord->processState_ = state;
149     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
150         AdjustSource::ADJS_PROCESS_STATE);
151 }
152 
HandleUIExtensionAbilityStateChange(uint32_t resType,int64_t value,const nlohmann::json & payload)153 void CgroupEventHandler::HandleUIExtensionAbilityStateChange(uint32_t resType, int64_t value,
154     const nlohmann::json& payload)
155 {
156     int32_t extensionAbilityType = 0;
157     int32_t uiExtensionState = 0;
158     if (!ParseValue(extensionAbilityType, "extensionAbilityType", payload) ||
159         !ParseValue(uiExtensionState, "uiExtensionState", payload)) {
160         CGS_LOGD("%{public}s : this type of event is not dealt with here", __func__);
161         return;
162     }
163 
164     nlohmann::json payloadChange = payload;
165     payloadChange["extensionState"] = std::to_string(uiExtensionState);
166     HandleExtensionStateChanged(resType, value, payloadChange);
167 }
168 
HandleAbilityStateChanged(uint32_t resType,int64_t value,const nlohmann::json & payload)169 void CgroupEventHandler::HandleAbilityStateChanged(uint32_t resType, int64_t value, const nlohmann::json& payload)
170 {
171     if (!supervisor_) {
172         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
173         return;
174     }
175 
176     int32_t uid = 0;
177     int32_t pid = 0;
178     std::string bundleName;
179     std::string abilityName;
180     int32_t recordId = 0;
181     int32_t abilityState = 0;
182     int32_t abilityType = 0;
183     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload) ||
184         !ParseString(bundleName, "bundleName", payload) || !ParseString(abilityName, "abilityName", payload) ||
185         !ParseValue(recordId, "recordId", payload) ||
186         !ParseValue(abilityState, "abilityState", payload) || !ParseValue(abilityType, "abilityType", payload)) {
187         CGS_LOGE("%{public}s: param error", __func__);
188         return;
189     }
190 
191     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}s, %{public}s, %{public}d, %{public}d, %{public}d",
192         __func__, uid, pid, bundleName.c_str(), abilityName.c_str(), recordId, abilityState, abilityType);
193     if (abilityType == (int32_t)AbilityType::EXTENSION) {
194         HandleUIExtensionAbilityStateChange(resType, value, payload);
195         return;
196     }
197     ChronoScope cs("HandleAbilityStateChanged");
198     if (abilityState == (int32_t)(AbilityState::ABILITY_STATE_TERMINATED)) {
199         auto app = supervisor_->GetAppRecord(uid);
200         if (app) {
201             auto procRecord = app->GetProcessRecord(pid);
202             if (procRecord) {
203                 procRecord->RemoveAbilityByRecordId(recordId);
204                 CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
205                     AdjustSource::ADJS_ABILITY_STATE);
206             }
207         }
208         return;
209     }
210     auto app = supervisor_->GetAppRecordNonNull(uid);
211     app->SetName(bundleName);
212     auto procRecord = app->GetProcessRecordNonNull(pid);
213     auto abiInfo = procRecord->GetAbilityInfoNonNull(recordId);
214     abiInfo->name_ = abilityName;
215     abiInfo->state_ = abilityState;
216     abiInfo->type_ = abilityType;
217     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
218         AdjustSource::ADJS_ABILITY_STATE);
219 }
220 
HandleExtensionStateChanged(uint32_t resType,int64_t value,const nlohmann::json & payload)221 void CgroupEventHandler::HandleExtensionStateChanged(uint32_t resType, int64_t value, const nlohmann::json& payload)
222 {
223     if (!supervisor_) {
224         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
225         return;
226     }
227 
228     int32_t uid = 0;
229     int32_t pid = 0;
230     std::string bundleName;
231     std::string abilityName;
232     int32_t recordId = 0;
233     int32_t extensionState = 0;
234     int32_t abilityType = 0;
235     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload) ||
236         !ParseString(bundleName, "bundleName", payload) || !ParseString(abilityName, "abilityName", payload) ||
237         !ParseValue(recordId, "recordId", payload) ||
238         !ParseValue(extensionState, "extensionState", payload) || !ParseValue(abilityType, "abilityType", payload)) {
239         CGS_LOGE("%{public}s: param error", __func__);
240         return;
241     }
242 
243     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}s, %{public}s, %{public}d, %{public}d, %{public}d",
244         __func__, uid, pid, bundleName.c_str(), abilityName.c_str(), recordId, extensionState, abilityType);
245     ChronoScope cs("HandleExtensionStateChanged");
246     if (extensionState == (int32_t)(ExtensionState::EXTENSION_STATE_TERMINATED)) {
247         auto app = supervisor_->GetAppRecord(uid);
248         if (app) {
249             auto procRecord = app->GetProcessRecord(pid);
250             if (procRecord) {
251                 procRecord->RemoveAbilityByRecordId(recordId);
252                 CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
253                     AdjustSource::ADJS_EXTENSION_STATE);
254             }
255         }
256         return;
257     }
258     auto app = supervisor_->GetAppRecordNonNull(uid);
259     app->SetName(bundleName);
260     auto procRecord = app->GetProcessRecordNonNull(pid);
261     auto abiInfo = procRecord->GetAbilityInfoNonNull(recordId);
262     abiInfo->name_ = abilityName;
263     abiInfo->estate_ = extensionState;
264     abiInfo->type_ = abilityType;
265     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
266         AdjustSource::ADJS_EXTENSION_STATE);
267 }
268 
HandleProcessStateChangedEx(uint32_t resType,int64_t value,const nlohmann::json & payload)269 void CgroupEventHandler::HandleProcessStateChangedEx(uint32_t resType, int64_t value, const nlohmann::json& payload)
270 {
271     if (!supervisor_) {
272         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
273         return;
274     }
275     if (value == ResType::ProcessStatus::PROCESS_CREATED) {
276         HandleProcessCreated(resType, value, payload);
277     } else if (value == ResType::ProcessStatus::PROCESS_DIED) {
278         HandleProcessDied(resType, value, payload);
279     } else {
280         HandleProcessStateChanged(resType, value, payload);
281     }
282 }
283 
HandleProcessCreated(uint32_t resType,int64_t value,const nlohmann::json & payload)284 void CgroupEventHandler::HandleProcessCreated(uint32_t resType, int64_t value, const nlohmann::json& payload)
285 {
286     int32_t uid = 0;
287     int32_t pid = 0;
288     int32_t hostPid = 0;
289     std::string bundleName;
290     int32_t extensionType = 0;
291     int32_t processType = 0;
292     int32_t isPreloadModule = 0;
293     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload) ||
294         !ParseString(bundleName, "bundleName", payload) || !ParseValue(hostPid, "hostPid", payload) ||
295         !ParseValue(extensionType, "extensionType", payload) || !ParseValue(processType, "processType", payload) ||
296         !ParseValue(isPreloadModule, "isPreloadModule", payload)) {
297         CGS_LOGE("%{public}s: param error", __func__);
298         return;
299     }
300     CGS_LOGI("%{public}s : %{public}d, %{public}d, %{public}d, %{public}d, %{public}s, %{public}d",
301         __func__, uid, pid, hostPid, processType, bundleName.c_str(),
302         extensionType);
303     ChronoScope cs("HandleProcessCreated");
304     std::shared_ptr<Application> app = supervisor_->GetAppRecordNonNull(uid);
305     std::shared_ptr<ProcessRecord> procRecord = app->GetProcessRecordNonNull(pid);
306     app->SetName(bundleName);
307     std::string processName;
308     if (ParseString(processName, "processName", payload)) {
309         procRecord->SetName(processName);
310     } else {
311         CGS_LOGE("%{public}s: param error,not have processName", __func__);
312     }
313     procRecord->processType_ = processType;
314     switch (processType) {
315         case static_cast<int32_t>(ProcessType::RENDER):
316         case static_cast<int32_t>(ProcessType::CHILD):
317         case static_cast<int32_t>(ProcessType::GPU):
318             procRecord->hostPid_ = hostPid;
319             app->AddHostProcess(hostPid);
320             break;
321         case static_cast<int32_t>(ProcessType::EXTENSION):
322             procRecord->extensionType_ = extensionType;
323             break;
324         default:
325             break;
326     }
327     AdjustSource policy = (isPreloadModule != 0) ? AdjustSource::ADJS_APP_PRELOAD : AdjustSource::ADJS_PROCESS_CREATE;
328     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()), policy);
329 }
330 
HandleProcessDied(uint32_t resType,int64_t value,const nlohmann::json & payload)331 void CgroupEventHandler::HandleProcessDied(uint32_t resType, int64_t value, const nlohmann::json& payload)
332 {
333     int32_t uid = 0;
334     int32_t pid = 0;
335     std::string bundleName;
336     if (!ParseValue(uid, "uid", payload) ||
337         !ParseValue(pid, "pid", payload) ||
338         !ParseString(bundleName, "bundleName", payload)) {
339         return;
340     }
341     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}s", __func__, uid, pid, bundleName.c_str());
342     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
343     if (!app) {
344         CGS_LOGE("%{public}s : application %{public}s not exist!", __func__, bundleName.c_str());
345         return;
346     }
347     std::shared_ptr<ProcessRecord> procRecord = app->GetProcessRecord(pid);
348     if (procRecord) {
349         ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
350             ResType::RES_TYPE_PROCESS_STATE_CHANGE, ResType::ProcessStatus::PROCESS_DIED);
351     }
352     app->RemoveProcessRecord(pid);
353     // if all processes died, remove current app
354     if (app->GetPidsMap().size() == 0) {
355         supervisor_->RemoveApplication(uid);
356     }
357 }
358 
HandleTransientTaskStatus(uint32_t resType,int64_t value,const nlohmann::json & payload)359 void CgroupEventHandler::HandleTransientTaskStatus(uint32_t resType, int64_t value, const nlohmann::json& payload)
360 {
361     int32_t uid = 0;
362     int32_t pid = 0;
363     std::string bundleName;
364     if (!ParseValue(uid, "uid", payload) ||
365         !ParseValue(pid, "pid", payload) ||
366         !ParseString(bundleName, "bundleName", payload)) {
367         CGS_LOGE("%{public}s: param error", __func__);
368         return;
369     }
370 
371     if (value == ResType::TransientTaskStatus::TRANSIENT_TASK_START) {
372         HandleTransientTaskStart(uid, pid, bundleName);
373     } else if (value == ResType::TransientTaskStatus::TRANSIENT_TASK_END) {
374         HandleTransientTaskEnd(uid, pid, bundleName);
375     }
376 }
377 
HandleTransientTaskStart(uid_t uid,pid_t pid,const std::string & packageName)378 void CgroupEventHandler::HandleTransientTaskStart(uid_t uid, pid_t pid, const std::string& packageName)
379 {
380     if (!supervisor_) {
381         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
382         return;
383     }
384     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}s", __func__, uid, pid, packageName.c_str());
385     auto app = supervisor_->GetAppRecordNonNull(uid);
386     app->SetName(packageName);
387     auto procRecord = app->GetProcessRecord(pid);
388     if (!procRecord) {
389         return;
390     }
391     procRecord->runningTransientTask_ = true;
392 }
393 
HandleTransientTaskEnd(uid_t uid,pid_t pid,const std::string & packageName)394 void CgroupEventHandler::HandleTransientTaskEnd(uid_t uid, pid_t pid, const std::string& packageName)
395 {
396     if (!supervisor_) {
397         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
398         return;
399     }
400     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}s", __func__, uid, pid, packageName.c_str());
401     auto app = supervisor_->GetAppRecordNonNull(uid);
402     app->SetName(packageName);
403     auto procRecord = app->GetProcessRecord(pid);
404     if (!procRecord) {
405         return;
406     }
407     procRecord->runningTransientTask_ = false;
408 }
409 
HandleContinuousTaskStatus(uint32_t resType,int64_t value,const nlohmann::json & payload)410 void CgroupEventHandler::HandleContinuousTaskStatus(uint32_t resType, int64_t value, const nlohmann::json& payload)
411 {
412     int32_t uid = 0;
413     int32_t pid = 0;
414     int32_t abilityId = 0;
415     if (!ParseValue(uid, "uid", payload) ||
416         !ParseValue(pid, "pid", payload) ||
417         !ParseValue(abilityId, "abilityId", payload)) {
418         CGS_LOGE("%{public}s: param error", __func__);
419         return;
420     }
421 
422     if (value == ResType::ContinuousTaskStatus::CONTINUOUS_TASK_START ||
423         value == ResType::ContinuousTaskStatus::CONTINUOUS_TASK_UPDATE) {
424         std::vector<uint32_t> typeIds;
425         if (payload.contains("typeIds") && payload["typeIds"].is_array()) {
426             typeIds = payload["typeIds"].get<std::vector<uint32_t>>();
427         }
428         HandleContinuousTaskUpdate(uid, pid, typeIds, abilityId);
429     } else if (value == ResType::ContinuousTaskStatus::CONTINUOUS_TASK_END) {
430         HandleContinuousTaskCancel(uid, pid, abilityId);
431     }
432 }
433 
HandleContinuousTaskUpdate(uid_t uid,pid_t pid,const std::vector<uint32_t> & typeIds,int32_t abilityId)434 void CgroupEventHandler::HandleContinuousTaskUpdate(uid_t uid, pid_t pid,
435     const std::vector<uint32_t>& typeIds, int32_t abilityId)
436 {
437     if (!supervisor_) {
438         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
439         return;
440     }
441     ChronoScope cs("HandleContinuousTaskUpdate");
442     auto app = supervisor_->GetAppRecordNonNull(uid);
443     auto procRecord = app->GetProcessRecordNonNull(pid);
444     procRecord->continuousTaskFlag_ = 0;
445     procRecord->abilityIdAndContinuousTaskFlagMap_[abilityId] = typeIds;
446     for (const auto& typeId : typeIds) {
447         CGS_LOGI("%{public}s : %{public}d, %{public}d, %{public}d, abilityId %{public}d,",
448             __func__, uid, pid, typeId, abilityId);
449     }
450     for (const auto& ablityIdAndcontinuousTaskFlag : procRecord->abilityIdAndContinuousTaskFlagMap_) {
451         for (const auto& typeId : ablityIdAndcontinuousTaskFlag.second) {
452             procRecord->continuousTaskFlag_ |= (1U << typeId);
453         }
454     }
455     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
456         AdjustSource::ADJS_CONTINUOUS_BEGIN);
457 }
458 
HandleContinuousTaskCancel(uid_t uid,pid_t pid,int32_t abilityId)459 void CgroupEventHandler::HandleContinuousTaskCancel(uid_t uid, pid_t pid, int32_t abilityId)
460 {
461     if (!supervisor_) {
462         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
463         return;
464     }
465     CGS_LOGI("%{public}s : %{public}d, %{public}d, %{public}d", __func__, uid, pid, abilityId);
466     ChronoScope cs("HandleContinuousTaskCancel");
467     auto app = supervisor_->GetAppRecordNonNull(uid);
468     auto procRecord = app->GetProcessRecord(pid);
469     if (!procRecord) {
470         return;
471     }
472     procRecord->abilityIdAndContinuousTaskFlagMap_.erase(abilityId);
473     procRecord->continuousTaskFlag_ = 0;
474     for (const auto& ablityIdAndcontinuousTaskFlag : procRecord->abilityIdAndContinuousTaskFlagMap_) {
475         for (const auto& typeId : ablityIdAndcontinuousTaskFlag.second) {
476             procRecord->continuousTaskFlag_ |= (1U << typeId);
477         }
478     }
479     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
480         AdjustSource::ADJS_CONTINUOUS_END);
481 }
482 
HandleFocusStateChange(uint32_t resType,int64_t value,const nlohmann::json & payload)483 void CgroupEventHandler::HandleFocusStateChange(uint32_t resType, int64_t value, const nlohmann::json& payload)
484 {
485     if (!supervisor_) {
486         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
487         return;
488     }
489     int32_t windowId = 0;
490     int32_t windowType = 0;
491     int64_t displayId = 0;
492     int32_t pid = 0;
493     int32_t uid = 0;
494 
495     if (!ParseValue(pid, "pid", payload) || !ParseValue(uid, "uid", payload) ||
496         !ParseValue(windowId, "windowId", payload) || !ParseValue(windowType, "windowType", payload) ||
497         !ParseLongValue(displayId, "displayId", payload)) {
498         CGS_LOGE("%{public}s: param error", __func__);
499         return;
500     }
501 
502     if (value == ResType::WindowFocusStatus::WINDOW_FOCUS) {
503         HandleFocusedWindow(windowId, windowType, displayId, pid, uid);
504     } else if (value == ResType::WindowFocusStatus::WINDOW_UNFOCUS) {
505         HandleUnfocusedWindow(windowId, windowType, displayId, pid, uid);
506     }
507 }
508 
HandleFocusedWindow(uint32_t windowId,uint32_t windowType,uint64_t displayId,int32_t pid,int32_t uid)509 void CgroupEventHandler::HandleFocusedWindow(uint32_t windowId, uint32_t windowType,
510     uint64_t displayId, int32_t pid, int32_t uid)
511 {
512     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}" PRIu64 ", %{public}d, %{public}d",
513         __func__, windowId, windowType, displayId, pid, uid);
514     std::shared_ptr<Application> app = nullptr;
515     std::shared_ptr<ProcessRecord> procRecord = nullptr;
516     {
517         ChronoScope cs("HandleFocusedWindow");
518         app = supervisor_->GetAppRecordNonNull(uid);
519         procRecord = app->GetProcessRecordNonNull(pid);
520         auto win = procRecord->GetWindowInfoNonNull(windowId);
521         procRecord->linkedWindowId_ = (int32_t)(windowId);
522         win->windowType_ = (int32_t)(windowType);
523         win->isFocused_ = true;
524         win->displayId_ = displayId;
525 
526         app->focusedProcess_ = procRecord;
527         auto lastFocusApp = supervisor_->focusedApp_;
528         supervisor_->focusedApp_ = app;
529         CgroupAdjuster::GetInstance().AdjustAllProcessGroup(*(app.get()), AdjustSource::ADJS_FOCUSED_WINDOW);
530         ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()), ResType::RES_TYPE_WINDOW_FOCUS,
531             ResType::WindowFocusStatus::WINDOW_FOCUS);
532     }
533     if (app->GetName().empty()) {
534         app->SetName(SchedController::GetInstance().GetBundleNameByUid(uid));
535     }
536 }
537 
HandleUnfocusedWindow(uint32_t windowId,uint32_t windowType,uint64_t displayId,int32_t pid,int32_t uid)538 void CgroupEventHandler::HandleUnfocusedWindow(uint32_t windowId, uint32_t windowType,
539     uint64_t displayId, int32_t pid, int32_t uid)
540 {
541     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}" PRIu64 ", %{public}d, %{public}d",
542         __func__, windowId, windowType, displayId, pid, uid);
543     std::shared_ptr<Application> app = nullptr;
544     std::shared_ptr<ProcessRecord> procRecord = nullptr;
545     {
546         ChronoScope cs("HandleUnfocusedWindow");
547         app = supervisor_->GetAppRecord(uid);
548         procRecord = app ? app->GetProcessRecord(pid) : nullptr;
549         if (!app || !procRecord) {
550             return;
551         }
552         auto win = procRecord->GetWindowInfoNonNull(windowId);
553         win->windowType_ = (int32_t)(windowType);
554         win->isFocused_ = false;
555         win->displayId_ = displayId;
556 
557         if (app->focusedProcess_ == procRecord) {
558             app->focusedProcess_ = nullptr;
559         }
560         CgroupAdjuster::GetInstance().AdjustAllProcessGroup(*(app.get()), AdjustSource::ADJS_UNFOCUSED_WINDOW);
561         ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()), ResType::RES_TYPE_WINDOW_FOCUS,
562             ResType::WindowFocusStatus::WINDOW_UNFOCUS);
563     }
564     if (app->GetName().empty()) {
565         app->SetName(SchedController::GetInstance().GetBundleNameByUid(uid));
566     }
567 }
568 
HandleWindowVisibilityChanged(uint32_t resType,int64_t value,const nlohmann::json & payload)569 void CgroupEventHandler::HandleWindowVisibilityChanged(uint32_t resType, int64_t value, const nlohmann::json& payload)
570 {
571     if (!supervisor_) {
572         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
573         return;
574     }
575 
576     int32_t windowId = 0;
577     int32_t windowType = 0;
578     int32_t pid = 0;
579     int32_t uid = 0;
580 
581     if (!ParseValue(pid, "pid", payload) || !ParseValue(uid, "uid", payload) ||
582         !ParseValue(windowId, "windowId", payload) || !ParseValue(windowType, "windowType", payload)) {
583         CGS_LOGE("%{public}s: param error", __func__);
584         return;
585     }
586 
587     bool isVisible = (bool)value;
588     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}d, %{public}d, %{public}d", __func__, windowId,
589         isVisible, (int32_t)windowType, pid, uid);
590 
591     std::shared_ptr<Application> app = nullptr;
592     std::shared_ptr<ProcessRecord> procRecord = nullptr;
593     if (isVisible) {
594         app = supervisor_->GetAppRecordNonNull(uid);
595         procRecord = app->GetProcessRecordNonNull(pid);
596     } else {
597         app = supervisor_->GetAppRecord(uid);
598         if (app) {
599             procRecord = app->GetProcessRecord(pid);
600         }
601     }
602     if (!procRecord) {
603         return;
604     }
605     auto windowInfo = procRecord->GetWindowInfoNonNull(windowId);
606     bool visibleStatusNotChanged = windowInfo->isVisible_ == isVisible;
607     windowInfo->isVisible_ = isVisible;
608     windowInfo->windowType_ = (int32_t)windowType;
609 
610     if (visibleStatusNotChanged) {
611         return;
612     }
613     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
614         AdjustSource::ADJS_WINDOW_VISIBILITY_CHANGED);
615 }
616 
HandleDrawingContentChangeWindow(uint32_t resType,int64_t value,const nlohmann::json & payload)617 void CgroupEventHandler::HandleDrawingContentChangeWindow(uint32_t resType, int64_t value,
618     const nlohmann::json& payload)
619 {
620     if (!supervisor_) {
621         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
622         return;
623     }
624 
625     int32_t windowId = 0;
626     int32_t windowType = 0;
627     int32_t pid = 0;
628     int32_t uid = 0;
629     bool drawingContentState = (bool)value;
630 
631     if (!ParseValue(pid, "pid", payload) || !ParseValue(uid, "uid", payload) ||
632         !ParseValue(windowId, "windowId", payload) || !ParseValue(windowType, "windowType", payload)) {
633         CGS_LOGE("%{public}s: param error", __func__);
634         return;
635     }
636 
637     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}d, %{public}d, %{public}d", __func__, windowId,
638         drawingContentState, (int32_t)windowType, pid, uid);
639 
640     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
641     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
642     if (!app || !procRecord) {
643         return;
644     }
645     procRecord->processDrawingState_ = drawingContentState;
646     auto windowInfo = procRecord->GetWindowInfoNonNull(windowId);
647     if (!windowInfo) {
648         CGS_LOGE("%{public}s : windowInfo nullptr!", __func__);
649         return;
650     }
651     windowInfo->drawingContentState_ = drawingContentState;
652     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
653         ResType::RES_TYPE_WINDOW_DRAWING_CONTENT_CHANGE,
654         drawingContentState ? ResType::WindowDrawingStatus::Drawing : ResType::WindowDrawingStatus::NotDrawing);
655 }
656 
HandleReportMMIProcess(uint32_t resType,int64_t value,const nlohmann::json & payload)657 void CgroupEventHandler::HandleReportMMIProcess(uint32_t resType, int64_t value, const nlohmann::json& payload)
658 {
659     int32_t uid = 0;
660     int32_t pid = 0;
661     int32_t mmi_service;
662 
663     if (!supervisor_) {
664         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
665         return;
666     }
667 
668     if (!ParsePayload(uid, pid, mmi_service, value, payload)) {
669         return;
670     }
671 
672     CGS_LOGD("%{public}s : %{public}u, %{public}d, %{public}d, %{public}d",
673         __func__, resType, uid, pid, mmi_service);
674     if (uid <= 0 || pid <= 0 || mmi_service <= 0) {
675         return;
676     }
677 
678     auto app = supervisor_->GetAppRecordNonNull(uid);
679     app->SetName(MMI_SERVICE_NAME);
680     auto procRecord = app->GetProcessRecordNonNull(mmi_service);
681     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
682         AdjustSource::ADJS_REPORT_MMI_SERVICE_THREAD);
683 }
684 
HandleReportRenderThread(uint32_t resType,int64_t value,const nlohmann::json & payload)685 void CgroupEventHandler::HandleReportRenderThread(uint32_t resType, int64_t value, const nlohmann::json& payload)
686 {
687     int32_t uid = 0;
688     int32_t pid = 0;
689     int32_t render = 0;
690 
691     if (!supervisor_) {
692         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
693         return;
694     }
695 
696     if (!ParsePayload(uid, pid, render, value, payload)) {
697         return;
698     }
699 
700     CGS_LOGD("%{public}s : %{public}u, %{public}d, %{public}d, %{public}d",
701         __func__, resType, uid, pid, render);
702     if (uid <= 0 || pid <= 0 || render <= 0) {
703         return;
704     }
705 
706     auto app = supervisor_->GetAppRecordNonNull(uid);
707     auto procRecord = app->GetProcessRecordNonNull(pid);
708     procRecord->renderTid_ = render;
709     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
710         AdjustSource::ADJS_REPORT_RENDER_THREAD);
711 }
712 
HandleReportKeyThread(uint32_t resType,int64_t value,const nlohmann::json & payload)713 void CgroupEventHandler::HandleReportKeyThread(uint32_t resType, int64_t value, const nlohmann::json& payload)
714 {
715     int32_t uid = 0;
716     int32_t pid = 0;
717     int32_t keyTid = 0;
718     int32_t role = 0;
719 
720     std::shared_ptr<Application> app = nullptr;
721     std::shared_ptr<ProcessRecord> procRecord = nullptr;
722     if (!GetProcInfoByPayload(uid, pid, app, procRecord, payload)) {
723         return;
724     }
725 
726     if (!ParseValue(keyTid, "tid", payload) || !ParseValue(role, "role", payload)) {
727         return;
728     }
729 
730     if (!ResSchedUtils::GetInstance().CheckTidIsInPid(pid, keyTid)) {
731         return;
732     }
733 
734     if (value == ResType::ReportChangeStatus::CREATE) {
735         procRecord->keyThreadRoleMap_.emplace(keyTid, role);
736         procRecord->isReload_ = false;
737     } else {
738         procRecord->keyThreadRoleMap_.erase(keyTid);
739     }
740 
741     CGS_LOGI("%{public}s : appName: %{public}s, uid: %{public}d, pid: %{public}d, keyTid: %{public}d",
742         __func__, app->GetName().c_str(), uid, pid, keyTid);
743 
744     // if role of thread is important display, adjust it
745     auto hostProcRecord = app->GetProcessRecord(procRecord->hostPid_);
746     if (!hostProcRecord) {
747         return;
748     }
749     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(hostProcRecord.get()),
750         AdjustSource::ADJS_REPORT_IMPORTANT_DISPLAY_THREAD);
751 }
752 
HandleReportWindowState(uint32_t resType,int64_t value,const nlohmann::json & payload)753 void CgroupEventHandler::HandleReportWindowState(uint32_t resType, int64_t value, const nlohmann::json& payload)
754 {
755     int32_t uid = 0;
756     int32_t pid = 0;
757     int32_t windowId = -1;
758     int32_t state = 0;
759     int32_t nowSerialNum = -1;
760 
761     std::shared_ptr<Application> app = nullptr;
762     std::shared_ptr<ProcessRecord> procRecord = nullptr;
763     if (!GetProcInfoByPayload(uid, pid, app, procRecord, payload)) {
764         return;
765     }
766 
767     if (!ParseValue(windowId, "windowId", payload) || !ParseValue(state, "state", payload) ||
768         !ParseValue(nowSerialNum, "serialNum", payload)) {
769         CGS_LOGW("%{public}s : param is not valid or not exist", __func__);
770         return;
771     }
772     CGS_LOGI("%{public}s : render process name: %{public}s, uid: %{public}d, pid: %{public}d, state: %{public}d",
773         __func__, app->GetName().c_str(), uid, pid, state);
774     if (nowSerialNum <= procRecord->serialNum_ &&
775         (procRecord->serialNum_ - nowSerialNum <= static_cast<int32_t>(MAX_SPAN_SERIAL))) {
776         return;
777     }
778     procRecord->serialNum_ = nowSerialNum;
779 
780     if (state == ResType::WindowStates::ACTIVE) {
781         procRecord->linkedWindowId_ = windowId;
782         procRecord->isActive_ = true;
783     } else {
784         procRecord->linkedWindowId_ = -1;
785         procRecord->isActive_ = false;
786     }
787     auto hostProcRecord = app->GetProcessRecord(procRecord->hostPid_);
788     if (!hostProcRecord) {
789         return;
790     }
791     CGS_LOGI("%{public}s : pid: %{public}d, winId: %{public}d, isActive_: %{public}d",
792         __func__, pid, procRecord->linkedWindowId_, procRecord->isActive_);
793     UpdateActivepWebRenderInfo(uid, pid, windowId, state, hostProcRecord);
794     if (CheckVisibilityForRenderProcess(*(procRecord.get()), *hostProcRecord)) {
795         CGS_LOGW("%{public}s : bundle name: %{public}s, uid: %{public}d, pid: %{public}d, winId: %{public}d" \
796             "is not visible but active", __func__, app->GetName().c_str(), uid, pid, procRecord->linkedWindowId_);
797     }
798     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(hostProcRecord.get()),
799         AdjustSource::ADJS_REPORT_WINDOW_STATE_CHANGED);
800     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
801         ResType::RES_TYPE_REPORT_WINDOW_STATE, state);
802 }
803 
UpdateActivepWebRenderInfo(int32_t uid,int32_t pid,int32_t windowId,int32_t state,const std::shared_ptr<ProcessRecord> & proc)804 void CgroupEventHandler::UpdateActivepWebRenderInfo(int32_t uid, int32_t pid, int32_t windowId, int32_t state,
805     const std::shared_ptr<ProcessRecord>& proc)
806 {
807     if (state != ResType::WindowStates::ACTIVE) {
808         return;
809     }
810     auto win = proc->GetWindowInfoNonNull(windowId);
811     win->topWebviewRenderUid_ = (uint32_t)(uid);
812 }
813 
HandleReportAudioState(uint32_t resType,int64_t value,const nlohmann::json & payload)814 void CgroupEventHandler::HandleReportAudioState(uint32_t resType, int64_t value, const nlohmann::json& payload)
815 {
816     int32_t uid = 0;
817     int32_t pid = 0;
818 
819     if (!supervisor_) {
820         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
821         return;
822     }
823 
824     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
825         CGS_LOGE("%{public}s : payload does not contain uid or pid", __func__);
826         return;
827     }
828     if (uid <= 0 || pid <= 0) {
829         CGS_LOGE("%{public}s : uid or pid is less than 0", __func__);
830         return;
831     }
832 
833     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
834     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
835     if (!app || !procRecord) {
836         return;
837     }
838 
839     procRecord->audioPlayingState_ = static_cast<int32_t>(value);
840     CGS_LOGI("%{public}s :Appname:%{public}s, uid:%{public}d, pid:%{public}d, state:%{public}d",
841         __func__, app->GetName().c_str(), uid, pid, procRecord->audioPlayingState_);
842 
843     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
844         AdjustSource::ADJS_REPORT_AUDIO_STATE_CHANGED);
845     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
846         resType, static_cast<int32_t>(value));
847 }
848 
HandleReportWebviewAudioState(uint32_t resType,int64_t value,const nlohmann::json & payload)849 void CgroupEventHandler::HandleReportWebviewAudioState(uint32_t resType, int64_t value, const nlohmann::json& payload)
850 {
851     int32_t uid = 0;
852     int32_t pid = 0;
853 
854     if (!supervisor_) {
855         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
856         return;
857     }
858 
859     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
860         return;
861     }
862     if (uid <= 0 || pid <= 0) {
863         CGS_LOGW("%{public}s : uid or pid invalid, uid: %{public}d, pid: %{public}d!",
864             __func__, uid, pid);
865         return;
866     }
867 
868     std::shared_ptr<Application> app = supervisor_->GetAppRecordNonNull(uid);
869     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
870     if (!app || !procRecord) {
871         CGS_LOGW("%{public}s : proc record is not exist, uid: %{public}d, pid: %{public}d",
872             __func__, uid, pid);
873         return;
874     }
875 
876     procRecord->audioPlayingState_ = static_cast<int32_t>(value);
877     CGS_LOGI("%{public}s : audio process name: %{public}s, uid: %{public}d, pid: %{public}d, state: %{public}d",
878         __func__, app->GetName().c_str(), uid, pid, procRecord->audioPlayingState_);
879 
880     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
881         AdjustSource::ADJS_REPORT_WEBVIEW_AUDIO_STATE_CHANGED);
882     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
883         resType, static_cast<int32_t>(value));
884 }
885 
HandleReportRunningLockEvent(uint32_t resType,int64_t value,const nlohmann::json & payload)886 void CgroupEventHandler::HandleReportRunningLockEvent(uint32_t resType, int64_t value, const nlohmann::json& payload)
887 {
888     int32_t uid = 0;
889     int32_t pid = 0;
890     uint32_t type = 0;
891     int32_t state = -1;
892 
893     if (!supervisor_) {
894         CGS_LOGE("%{public}s : supervisor nullptr.", __func__);
895         return;
896     }
897 
898     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
899         return;
900     }
901     if (uid <= 0 || pid <= 0) {
902         return;
903     }
904     if (payload.contains("type") && payload.at("type").is_string()) {
905         type = static_cast<uint32_t>(atoi(payload["type"].get<std::string>().c_str()));
906     }
907     state = static_cast<int32_t>(value);
908     CGS_LOGI("report running lock event, uid:%{public}d, pid:%{public}d, lockType:%{public}d, state:%{public}d",
909         uid, pid, type, state);
910 #ifdef POWER_MANAGER_ENABLE
911     if (type == static_cast<uint32_t>(PowerMgr::RunningLockType::RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL)) {
912         return;
913     }
914     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
915     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
916     if (!app || !procRecord) {
917         return;
918     }
919     procRecord->runningLockState_[type] = (state == ResType::RunninglockState::RUNNINGLOCK_STATE_ENABLE);
920     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()), resType, state);
921 #endif
922 }
923 
HandleReportBluetoothConnectState(uint32_t resType,int64_t value,const nlohmann::json & payload)924 void CgroupEventHandler::HandleReportBluetoothConnectState(
925     uint32_t resType, int64_t value, const nlohmann::json& payload)
926 {
927     int32_t uid = 0;
928     int32_t pid = 0;
929 
930     if (!supervisor_) {
931         CGS_LOGE("%{public}s : supervisor nullptr.", __func__);
932         return;
933     }
934 
935     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
936         CGS_LOGE("%{public}s : payload does not contain uid or pid", __func__);
937         return;
938     }
939     if (uid <= 0 || pid <= 0) {
940         CGS_LOGE("%{public}s : uid or pid is less than 0", __func__);
941         return;
942     }
943     CGS_LOGD("report bluetooth connect state, uid:%{public}d, pid:%{public}d, value:%{public}lld",
944         uid, pid, (long long)value);
945     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
946     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
947     if (!app || !procRecord) {
948         return;
949     }
950     procRecord->bluetoothState_ = static_cast<int32_t>(value);
951     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
952         resType, static_cast<int32_t>(value));
953 }
954 
HandleMmiInputState(uint32_t resType,int64_t value,const nlohmann::json & payload)955 void CgroupEventHandler::HandleMmiInputState(uint32_t resType, int64_t value, const nlohmann::json& payload)
956 {
957     int32_t uid = 0;
958     int32_t pid = 0;
959 
960     if (!supervisor_) {
961         CGS_LOGE("%{public}s : supervisor nullptr.", __func__);
962         return;
963     }
964 
965     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
966         CGS_LOGE("%{public}s : payload does not contain uid or pid", __func__);
967         return;
968     }
969     if (uid <= 0 || pid <= 0) {
970         CGS_LOGE("%{public}s : uid or pid is less than 0", __func__);
971         return;
972     }
973     CGS_LOGD("report mmi input state, uid:%{public}d, pid:%{public}d, value:%{public}lld",
974         uid, pid, (long long)value);
975     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
976     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
977     if (!app || !procRecord) {
978         return;
979     }
980 
981     if (payload.contains("syncStatus") && payload.at("syncStatus").is_string()) {
982         procRecord->mmiStatus_ = atoi(payload["syncStatus"].get<std::string>().c_str());
983     }
984     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
985         resType, static_cast<int32_t>(value));
986 }
987 
HandleReportHisysEvent(uint32_t resType,int64_t value,const nlohmann::json & payload)988 void CgroupEventHandler::HandleReportHisysEvent(uint32_t resType, int64_t value, const nlohmann::json& payload)
989 {
990     int32_t uid = 0;
991     int32_t pid = 0;
992 
993     if (!supervisor_) {
994         CGS_LOGE("%{public}s : supervisor nullptr.", __func__);
995         return;
996     }
997 
998     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
999         return;
1000     }
1001     if (uid <= 0 || pid <= 0) {
1002         return;
1003     }
1004     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
1005     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
1006     if (!app || !procRecord) {
1007         return;
1008     }
1009 
1010     switch (resType) {
1011         case ResType::RES_TYPE_REPORT_CAMERA_STATE: {
1012             procRecord->cameraState_ = static_cast<int32_t>(value);
1013             break;
1014         }
1015         case ResType::RES_TYPE_WIFI_CONNECT_STATE_CHANGE: {
1016             procRecord->wifiState_ = static_cast<int32_t>(value);
1017             break;
1018         }
1019         default: {
1020             break;
1021         }
1022     }
1023     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
1024         resType, static_cast<int32_t>(value));
1025 }
1026 
HandleReportScreenCaptureEvent(uint32_t resType,int64_t value,const nlohmann::json & payload)1027 void CgroupEventHandler::HandleReportScreenCaptureEvent(uint32_t resType, int64_t value, const nlohmann::json& payload)
1028 {
1029     int32_t uid = 0;
1030     int32_t pid = 0;
1031 
1032     if (!supervisor_) {
1033         CGS_LOGE("%{public}s : supervisor nullptr.", __func__);
1034         return;
1035     }
1036 
1037     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
1038         CGS_LOGE("%{public}s : payload does not contain uid or pid", __func__);
1039         return;
1040     }
1041     if (uid <= 0 || pid <= 0) {
1042         CGS_LOGE("%{public}s : uid or pid is less than 0", __func__);
1043         return;
1044     }
1045     CGS_LOGD("report Screen capture, uid:%{public}d, pid:%{public}d, value:%{public}lld",
1046         uid, pid, (long long)value);
1047     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
1048     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
1049     if (!app || !procRecord) {
1050         return;
1051     }
1052 
1053     procRecord->screenCaptureState_ = (value == ResType::ScreenCaptureStatus::START_SCREEN_CAPTURE);
1054     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
1055         AdjustSource::ADJS_REPORT_SCREEN_CAPTURE);
1056 
1057     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
1058         resType, static_cast<int32_t>(value));
1059 }
1060 
HandleReportAvCodecEvent(uint32_t resType,int64_t value,const nlohmann::json & payload)1061 void CgroupEventHandler::HandleReportAvCodecEvent(uint32_t resType, int64_t value, const nlohmann::json& payload)
1062 {
1063     int32_t uid = 0;
1064     int32_t pid = 0;
1065     int32_t instanceId = -1;
1066     int32_t state = -1;
1067 
1068     if (!supervisor_) {
1069         CGS_LOGE("%{public}s : supervisor nullptr.", __func__);
1070         return;
1071     }
1072 
1073     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
1074         return;
1075     }
1076     if (uid <= 0 || pid <= 0) {
1077         return;
1078     }
1079     if (!ParseValue(instanceId, "instanceId", payload)) {
1080         return;
1081     }
1082     if (instanceId < 0) {
1083         return;
1084     }
1085     state = static_cast<int32_t>(value);
1086     CGS_LOGI("report av_codec event, uid:%{public}d, pid:%{public}d, instanceId:%{public}d, state:%{public}d",
1087         uid, pid, instanceId, state);
1088     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
1089     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
1090     if (!app || !procRecord) {
1091         return;
1092     }
1093     procRecord->avCodecState_[instanceId] = (state == ResType::AvCodecState::CODEC_START_INFO);
1094     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()), resType, state);
1095 }
1096 
HandleSceneBoardState(uint32_t resType,int64_t value,const nlohmann::json & payload)1097 void CgroupEventHandler::HandleSceneBoardState(uint32_t resType, int64_t value, const nlohmann::json& payload)
1098 {
1099     int32_t sceneBoardPid = 0;
1100     int32_t sceneBoardUid = 0;
1101     if (!supervisor_) {
1102         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
1103         return;
1104     }
1105 
1106     if (!ParseValue(sceneBoardPid, "pid", payload) || !ParseValue(sceneBoardUid, "uid", payload)) {
1107         return;
1108     }
1109     if (sceneBoardPid <= 0) {
1110         return;
1111     }
1112     supervisor_->sceneBoardUid_ = sceneBoardUid;
1113     supervisor_->sceneBoardPid_ = sceneBoardPid;
1114     CGS_LOGI("%{public}s:pid[%{public}d],uid[%{public}d]", __func__, sceneBoardPid, sceneBoardUid);
1115 }
1116 
CheckVisibilityForRenderProcess(ProcessRecord & pr,ProcessRecord & mainProc)1117 bool CgroupEventHandler::CheckVisibilityForRenderProcess(ProcessRecord &pr, ProcessRecord &mainProc)
1118 {
1119     return (pr.processType_ == ProcRecordType::RENDER) && pr.isActive_ &&
1120         !mainProc.GetWindowInfoNonNull(pr.linkedWindowId_)->isVisible_;
1121 }
1122 
HandleWebviewScreenCapture(uint32_t resType,int64_t value,const nlohmann::json & payload)1123 void CgroupEventHandler::HandleWebviewScreenCapture(uint32_t resType, int64_t value, const nlohmann::json& payload)
1124 {
1125     int32_t uid = 0;
1126     int32_t pid = 0;
1127     std::shared_ptr<Application> app = nullptr;
1128     std::shared_ptr<ProcessRecord> procRecord = nullptr;
1129 
1130     if (!GetProcInfoByPayload(uid, pid, app, procRecord, payload)) {
1131         return;
1132     }
1133 
1134     procRecord->screenCaptureState_= (value == ResType::WebScreenCapture::WEB_SCREEN_CAPTURE_START);
1135     CGS_LOGI("%{public}s : screen capture process: %{public}s, uid: %{public}d, pid: %{public}d, state: %{public}d",
1136         __func__, app->GetName().c_str(), uid, pid, procRecord->screenCaptureState_);
1137 
1138     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
1139         AdjustSource::ADJS_REPORT_WEBVIEW_SCREEN_CAPTURE);
1140     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()), resType,
1141         procRecord->screenCaptureState_);
1142 }
1143 
ReportAbilityStatus(uint32_t resType,int64_t value,const nlohmann::json & payload)1144 void CgroupEventHandler::ReportAbilityStatus(uint32_t resType, int64_t value, const nlohmann::json& payload)
1145 {
1146     int32_t saId = -1;
1147     if (payload.contains("saId") && payload.at("saId").is_number_integer()) {
1148         saId = payload["saId"].get<int32_t>();
1149     }
1150     std::string deviceId = "";
1151     if (payload.contains("deviceId") && payload.at("deviceId").is_string()) {
1152         deviceId = payload["deviceId"].get<std::string>();
1153     }
1154     CGS_LOGD("%{public}s saId: %{public}d, status: %{public}lld", __func__, saId, (long long)value);
1155     PostTask([saId, deviceId, value, this] {
1156         if (value > 0) {
1157             HandleAbilityAdded(saId, deviceId);
1158         } else {
1159             HandleAbilityRemoved(saId, deviceId);
1160         }
1161     });
1162 }
1163 
UpdateMmiStatus(uint32_t resType,int64_t value,const nlohmann::json & payload)1164 void CgroupEventHandler::UpdateMmiStatus(uint32_t resType, int64_t value, const nlohmann::json& payload)
1165 {
1166     if (supervisor_ == nullptr) {
1167         return;
1168     }
1169     if (!payload.contains("pid") || !payload.at("pid").is_number_integer()) {
1170         return;
1171     }
1172     if (!payload.contains("uid") || !payload.at("uid").is_number_integer()) {
1173         return;
1174     }
1175     if (!payload.contains("status") || !payload.at("status").is_number_integer()) {
1176         return;
1177     }
1178     int32_t pid = payload["pid"].get<int32_t>();
1179     int32_t uid = payload["uid"].get<int32_t>();
1180     int32_t status = payload["status"].get<int32_t>();
1181     auto app = supervisor_->GetAppRecord(uid);
1182     auto procRecord = app ? app->GetProcessRecord(pid) : nullptr;
1183     if (procRecord) {
1184         procRecord->mmiStatus_ = status;
1185     }
1186 }
1187 
HandleEmptyPayloadForCosmicCubeState(uint32_t resType,int64_t value)1188 void CgroupEventHandler::HandleEmptyPayloadForCosmicCubeState(uint32_t resType, int64_t value)
1189 {
1190     bool isNeedRecover = resType == ResType::RES_TYPE_COSMIC_CUBE_STATE_CHANGE &&
1191         value == ResType::CosmicCubeState::APPLICATION_ABOUT_TO_RECOVER;
1192     if (!isNeedRecover) {
1193         return;
1194     }
1195     std::map <int32_t, std::shared_ptr<Application>> uidMap = supervisor_->GetUidsMap();
1196     for (auto it = uidMap.begin(); it != uidMap.end(); it++) {
1197         int32_t uid = it->first;
1198         std::shared_ptr <Application> app = it->second;
1199         if (!app->isCosmicCubeStateHide_) {
1200             continue;
1201         }
1202         app->isCosmicCubeStateHide_ = false;
1203         std::map <pid_t, std::shared_ptr<ProcessRecord>> pidMap = app->GetPidsMap();
1204         for (auto pidIt = pidMap.begin(); pidIt != pidMap.end(); pidIt++) {
1205             int32_t pid = pidIt->first;
1206             std::shared_ptr <ProcessRecord> procRecord = pidIt->second;
1207             if (procRecord->processType_ == ProcRecordType::NORMAL) {
1208                 CGS_LOGI("%{public}s, uid:%{public}d pid:%{public}d recover", __func__, uid, pid);
1209                 CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
1210                     AdjustSource::ADJS_PROCESS_STATE);
1211             }
1212         }
1213     }
1214 }
1215 
HandleReportCosmicCubeState(uint32_t resType,int64_t value,const nlohmann::json & payload)1216 void CgroupEventHandler::HandleReportCosmicCubeState(uint32_t resType, int64_t value, const nlohmann::json &payload)
1217 {
1218     if (supervisor_ == nullptr) {
1219         return;
1220     }
1221     int32_t uid = 0;
1222     int32_t pid = 0;
1223     if (!ParsePayload(uid, pid, payload)) {
1224         CGS_LOGW("%{public}s : uid or pid invalid, uid:%{public}d, pid:%{public}d, value:%{public}lld",
1225             __func__, uid, pid, (long long)value);
1226         HandleEmptyPayloadForCosmicCubeState(resType, value);
1227         return;
1228     }
1229     std::shared_ptr <Application> app = supervisor_->GetAppRecord(uid);
1230     std::shared_ptr <ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
1231     if (!app || !procRecord) {
1232         CGS_LOGW("%{public}s : app or proc record is not exist, uid:%{public}d, pid:%{public}d!", __func__, uid, pid);
1233         return;
1234     }
1235     app->isCosmicCubeStateHide_ = (value == ResType::CosmicCubeState::APPLICATION_ABOUT_TO_HIDE);
1236     if (procRecord->processType_ == ProcRecordType::NORMAL) {
1237         CGS_LOGI("%{public}s uid:%{public}d, pid:%{public}d, value:%{public}lld", __func__, uid, pid, (long long)value);
1238         CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
1239             AdjustSource::ADJS_PROCESS_STATE);
1240     }
1241 }
1242 
HandleReportWebviewVideoState(uint32_t resType,int64_t value,const nlohmann::json & payload)1243 void CgroupEventHandler::HandleReportWebviewVideoState(uint32_t resType, int64_t value, const nlohmann::json& payload)
1244 {
1245     int32_t uid = 0;
1246     int32_t pid = 0;
1247     std::shared_ptr<Application> app = nullptr;
1248     std::shared_ptr<ProcessRecord> procRecord = nullptr;
1249 
1250     if (!GetProcInfoByPayload(uid, pid, app, procRecord, payload)) {
1251         return;
1252     }
1253 
1254     procRecord->videoState_ = (value == ResType::WebVideoState::WEB_VIDEO_PLAYING_START);
1255     CGS_LOGI("%{public}s : video process name: %{public}s, uid: %{public}d, pid: %{public}d, state: %{public}d",
1256         __func__, app->GetName().c_str(), uid, pid, procRecord->videoState_);
1257 
1258     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()), resType,
1259         procRecord->videoState_);
1260 }
1261 
HandleOnAppStopped(uint32_t resType,int64_t value,const nlohmann::json & payload)1262 void CgroupEventHandler::HandleOnAppStopped(uint32_t resType, int64_t value, const nlohmann::json& payload)
1263 {
1264     if (!payload.contains("uid") || !payload.at("uid").is_number_integer()) {
1265         CGS_LOGE("%{public}s : uid invalid!", __func__);
1266         return;
1267     }
1268     int32_t uid = payload["uid"].get<int32_t>();
1269     if (!payload.contains("bundleName") || !payload.at("bundleName").is_string()) {
1270         CGS_LOGE("%{public}s : bundleName invalid!", __func__);
1271         return;
1272     }
1273     std::string bundleName = payload["bundleName"].get<std::string>();
1274 
1275     if (!supervisor_) {
1276         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
1277         return;
1278     }
1279     CGS_LOGI("%{public}s : %{public}d, %{public}s", __func__, uid, bundleName.c_str());
1280     supervisor_->RemoveApplication(uid);
1281 }
1282 
GetProcInfoByPayload(int32_t & uid,int32_t & pid,std::shared_ptr<Application> & app,std::shared_ptr<ProcessRecord> & procRecord,const nlohmann::json & payload)1283 bool CgroupEventHandler::GetProcInfoByPayload(int32_t &uid, int32_t &pid, std::shared_ptr<Application>& app,
1284     std::shared_ptr<ProcessRecord>& procRecord, const nlohmann::json& payload)
1285 {
1286     if (!supervisor_) {
1287         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
1288         return false;
1289     }
1290 
1291     if (!ParsePayload(uid, pid, payload)) {
1292         CGS_LOGW("%{public}s : uid or pid invalid, uid: %{public}d, pid: %{public}d!",
1293             __func__, uid, pid);
1294         return false;
1295     }
1296     app = supervisor_->GetAppRecord(uid);
1297     if (app) {
1298         procRecord = app->GetProcessRecordNonNull(pid);
1299     }
1300     if (!app || !procRecord) {
1301         CGS_LOGW("%{public}s : app record or proc record is not exist, uid: %{public}d, pid: %{public}d!",
1302             __func__, uid, pid);
1303         return false;
1304     }
1305     return true;
1306 }
1307 
ParsePayload(int32_t & uid,int32_t & pid,const nlohmann::json & payload)1308 bool CgroupEventHandler::ParsePayload(int32_t& uid, int32_t& pid, const nlohmann::json& payload)
1309 {
1310     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
1311         return false;
1312     }
1313     if (uid <= 0 || pid <= 0) {
1314         return false;
1315     }
1316     return true;
1317 }
1318 
ParsePayload(int32_t & uid,int32_t & pid,int32_t & tid,int64_t value,const nlohmann::json & payload)1319 bool CgroupEventHandler::ParsePayload(int32_t& uid, int32_t& pid, int32_t& tid,
1320     int64_t value, const nlohmann::json& payload)
1321 {
1322     if (payload.contains("uid") && payload.at("uid").is_string()) {
1323         uid = atoi(payload["uid"].get<std::string>().c_str());
1324     }
1325 
1326     if (payload.contains("pid") && payload.at("pid").is_string()) {
1327         pid = atoi(payload["pid"].get<std::string>().c_str());
1328     }
1329     tid = static_cast<int32_t>(value);
1330     return true;
1331 }
1332 
ParseString(std::string & value,const char * name,const nlohmann::json & payload)1333 bool CgroupEventHandler::ParseString(std::string& value, const char* name,
1334     const nlohmann::json& payload)
1335 {
1336     if (payload.contains(name) && payload.at(name).is_string()) {
1337         value = payload[name].get<std::string>();
1338         return true;
1339     }
1340     return false;
1341 }
1342 
ParseValue(int32_t & value,const char * name,const nlohmann::json & payload)1343 bool CgroupEventHandler::ParseValue(int32_t& value, const char* name,
1344     const nlohmann::json& payload)
1345 {
1346     if (payload.contains(name) && payload.at(name).is_string()) {
1347         value = atoi(payload[name].get<std::string>().c_str());
1348         return true;
1349     }
1350     return false;
1351 }
1352 
ParseLongValue(int64_t & value,const char * name,const nlohmann::json & payload)1353 bool CgroupEventHandler::ParseLongValue(int64_t& value, const char* name,
1354     const nlohmann::json& payload)
1355 {
1356     if (payload.contains(name) && payload.at(name).is_string()) {
1357         value = atoll(payload[name].get<std::string>().c_str());
1358         return true;
1359     }
1360     return false;
1361 }
1362 
PostTask(const std::function<void ()> task)1363 void CgroupEventHandler::PostTask(const std::function<void()> task)
1364 {
1365     if (!cgroupEventQueue_) {
1366         CGS_LOGE("%{public}s : cgroupEventQueue_ nullptr", __func__);
1367         return;
1368     }
1369     cgroupEventQueue_->submit([task, this] {
1370         task();
1371     });
1372 }
1373 
PostTask(const std::function<void ()> task,const std::string & taskName,const int32_t delayTime)1374 void CgroupEventHandler::PostTask(const std::function<void()> task, const std::string &taskName,
1375     const int32_t delayTime)
1376 {
1377     std::lock_guard<ffrt::mutex> autoLock(delayTaskMapMutex_);
1378     if (!cgroupEventQueue_) {
1379         CGS_LOGE("%{public}s : cgroupEventQueue_ nullptr", __func__);
1380         return;
1381     }
1382     delayTaskMap_[taskName] = cgroupEventQueue_->submit_h([task, this] {
1383         task();
1384     }, ffrt::task_attr().delay(delayTime * ffrtSwitch_));
1385 }
1386 
PostTaskAndWait(const std::function<void ()> task)1387 void CgroupEventHandler::PostTaskAndWait(const std::function<void()> task)
1388 {
1389     if (!cgroupEventQueue_) {
1390         CGS_LOGE("%{public}s : cgroupEventQueue_ nullptr", __func__);
1391         return;
1392     }
1393     ffrt::task_handle handle = cgroupEventQueue_->submit_h(task);
1394     cgroupEventQueue_->wait(handle);
1395 }
1396 
RemoveTask(const std::string & taskName)1397 void CgroupEventHandler::RemoveTask(const std::string &taskName)
1398 {
1399     std::lock_guard<ffrt::mutex> autoLock(delayTaskMapMutex_);
1400     for (auto iter = delayTaskMap_.begin(); iter != delayTaskMap_.end(); iter++) {
1401         if (iter->first == taskName && iter->second != nullptr) {
1402             cgroupEventQueue_->cancel(iter->second);
1403             delayTaskMap_.erase(iter);
1404             return;
1405         }
1406     }
1407 }
1408 } // namespace ResourceSchedule
1409 } // namespace OHOS
1410