1 /*
2  * Copyright (c) 2022-2023 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_common.h"
22 #include "cgroup_sched_log.h"
23 #include "hisysevent.h"
24 #include "ressched_utils.h"
25 #include "res_type.h"
26 #include "sched_controller.h"
27 #include "sched_policy.h"
28 #include "system_ability_definition.h"
29 #ifdef POWER_MANAGER_ENABLE
30 #include "power_mgr_client.h"
31 #endif
32 #include "window_manager_lite.h"
33 
34 #undef LOG_TAG
35 #define LOG_TAG "CgroupEventHandler"
36 
37 namespace OHOS {
38 namespace ResourceSchedule {
39 namespace {
40     constexpr uint32_t EVENT_ID_REG_APP_STATE_OBSERVER = 1;
41     constexpr uint32_t EVENT_ID_REG_BGTASK_OBSERVER = 2;
42     constexpr uint32_t DELAYED_RETRY_REGISTER_DURATION = 100;
43     constexpr uint32_t MAX_RETRY_TIMES = 100;
44     constexpr uint32_t MAX_SPAN_SERIAL = 99;
45 
46     const std::string MMI_SERVICE_NAME = "mmi_service";
47 }
48 
49 using OHOS::AppExecFwk::ApplicationState;
50 using OHOS::AppExecFwk::AbilityState;
51 using OHOS::AppExecFwk::AbilityType;
52 using OHOS::AppExecFwk::ExtensionState;
53 using OHOS::AppExecFwk::ProcessType;
54 
CgroupEventHandler(const std::string & queueName)55 CgroupEventHandler::CgroupEventHandler(const std::string &queueName)
56 {
57     cgroupEventQueue_ = std::make_shared<ffrt::queue>(queueName.c_str(),
58         ffrt::queue_attr().qos(ffrt::qos_user_interactive));
59     if (!cgroupEventQueue_) {
60         CGS_LOGE("%{public}s : create cgroupEventQueue_ failed", __func__);
61     }
62 }
63 
~CgroupEventHandler()64 CgroupEventHandler::~CgroupEventHandler()
65 {
66     supervisor_ = nullptr;
67     cgroupEventQueue_ = nullptr;
68     delayTaskMap_.clear();
69 }
70 
ProcessEvent(uint32_t eventId,int64_t eventParam)71 void CgroupEventHandler::ProcessEvent(uint32_t eventId, int64_t eventParam)
72 {
73     CGS_LOGD("%{public}s : eventId:%{public}d param:%{public}" PRIu64,
74         __func__, eventId, eventParam);
75     switch (eventId) {
76         case EVENT_ID_REG_APP_STATE_OBSERVER: {
77             int64_t retry = eventParam;
78             if (!SchedController::GetInstance().SubscribeAppState() &&
79                 retry < MAX_RETRY_TIMES) {
80                 eventId = EVENT_ID_REG_APP_STATE_OBSERVER;
81                 eventParam = retry + 1;
82                 this->PostTask(
83                     [this, eventId, eventParam] {
84                         this->ProcessEvent(eventId, eventParam);
85                     },
86                     std::to_string(eventId), DELAYED_RETRY_REGISTER_DURATION);
87                 if (retry + 1 == static_cast<int64_t>(MAX_RETRY_TIMES)) {
88                     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::RSS, "INIT_FAULT",
89                         HiviewDFX::HiSysEvent::EventType::FAULT,
90                         "COMPONENT_NAME", "MAIN",
91                         "ERR_TYPE", "register failure",
92                         "ERR_MSG", "Subscribe app status change observer failed.");
93                 }
94             }
95             break;
96         }
97         case EVENT_ID_REG_BGTASK_OBSERVER: {
98             int64_t retry = eventParam;
99             if (!SchedController::GetInstance().SubscribeBackgroundTask() &&
100                 retry < MAX_RETRY_TIMES) {
101                 eventId = EVENT_ID_REG_BGTASK_OBSERVER;
102                 eventParam = retry + 1;
103                 this->PostTask(
104                     [this, eventId, eventParam] {
105                         this->ProcessEvent(eventId, eventParam);
106                     },
107                     std::to_string(eventId), DELAYED_RETRY_REGISTER_DURATION);
108                 if (retry + 1 == static_cast<int64_t>(MAX_RETRY_TIMES)) {
109                     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::RSS, "INIT_FAULT",
110                         HiviewDFX::HiSysEvent::EventType::FAULT,
111                         "COMPONENT_NAME", "MAIN",
112                         "ERR_TYPE", "register failure",
113                         "ERR_MSG", "Subscribe background task observer failed.");
114                 }
115             }
116             break;
117         }
118         default:
119             break;
120     }
121 }
122 
SetSupervisor(std::shared_ptr<Supervisor> supervisor)123 void CgroupEventHandler::SetSupervisor(std::shared_ptr<Supervisor> supervisor)
124 {
125     supervisor_ = supervisor;
126 }
127 
HandleAbilityAdded(int32_t saId,const std::string & deviceId)128 void CgroupEventHandler::HandleAbilityAdded(int32_t saId, const std::string& deviceId)
129 {
130     switch (saId) {
131         case APP_MGR_SERVICE_ID:
132             this->RemoveTask(std::to_string(EVENT_ID_REG_APP_STATE_OBSERVER));
133             if (!SchedController::GetInstance().SubscribeAppState()) {
134                 uint32_t eventId = EVENT_ID_REG_APP_STATE_OBSERVER;
135                 int64_t eventParam = 0;
136                 this->PostTask(
137                     [this, eventId, eventParam] {
138                         this->ProcessEvent(eventId, eventParam);
139                     },
140                     std::to_string(eventId), DELAYED_RETRY_REGISTER_DURATION);
141             }
142             if (supervisor_ != nullptr) {
143                 supervisor_->InitSuperVisorContent();
144             }
145             break;
146         case WINDOW_MANAGER_SERVICE_ID:
147             SchedController::GetInstance().SubscribeWindowState();
148             break;
149         case BACKGROUND_TASK_MANAGER_SERVICE_ID:
150             this->RemoveTask(std::to_string(EVENT_ID_REG_BGTASK_OBSERVER));
151             if (!SchedController::GetInstance().SubscribeBackgroundTask()) {
152                 uint32_t eventId = EVENT_ID_REG_BGTASK_OBSERVER;
153                 int64_t eventParam = 0;
154                 this->PostTask(
155                     [this, eventId, eventParam] {
156                         this->ProcessEvent(eventId, eventParam);
157                     },
158                     std::to_string(eventId), DELAYED_RETRY_REGISTER_DURATION);
159             }
160             break;
161 #ifdef POWER_MANAGER_ENABLE
162         case POWER_MANAGER_SERVICE_ID:
163             SchedController::GetInstance().GetRunningLockState();
164             break;
165 #endif
166         default:
167             break;
168     }
169 }
170 
HandleAbilityRemoved(int32_t saId,const std::string & deviceId)171 void CgroupEventHandler::HandleAbilityRemoved(int32_t saId, const std::string& deviceId)
172 {
173     switch (saId) {
174         case APP_MGR_SERVICE_ID:
175             this->RemoveTask(std::to_string(EVENT_ID_REG_APP_STATE_OBSERVER));
176             SchedController::GetInstance().UnsubscribeAppState();
177             break;
178         case WINDOW_MANAGER_SERVICE_ID:
179             SchedController::GetInstance().UnsubscribeWindowState();
180             break;
181         case BACKGROUND_TASK_MANAGER_SERVICE_ID:
182             this->RemoveTask(std::to_string(EVENT_ID_REG_BGTASK_OBSERVER));
183             SchedController::GetInstance().UnsubscribeBackgroundTask();
184             break;
185         default:
186             break;
187     }
188 }
189 
HandleApplicationStateChanged(uid_t uid,pid_t pid,const std::string & bundleName,int32_t state)190 void CgroupEventHandler::HandleApplicationStateChanged(uid_t uid, pid_t pid,
191     const std::string& bundleName, int32_t state)
192 {
193     if (!supervisor_) {
194         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
195         return;
196     }
197     CGS_LOGD("%{public}s : %{public}d, %{public}s, %{public}d", __func__, uid, bundleName.c_str(), state);
198     ChronoScope cs("HandleApplicationStateChanged");
199     if (state == (int32_t)(ApplicationState::APP_STATE_TERMINATED)) {
200         return;
201     }
202     std::shared_ptr<Application> app = supervisor_->GetAppRecordNonNull(uid);
203     app->SetName(bundleName);
204     app->state_ = state;
205 }
206 
HandleOnAppStopped(uid_t uid,const std::string & bundleName)207 void CgroupEventHandler::HandleOnAppStopped(uid_t uid, const std::string& bundleName)
208 {
209     if (!supervisor_) {
210         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
211         return;
212     }
213     CGS_LOGI("%{public}s : %{public}d, %{public}s", __func__, uid, bundleName.c_str());
214     supervisor_->RemoveApplication(uid);
215 }
216 
HandleProcessStateChanged(uid_t uid,pid_t pid,const std::string & bundleName,int32_t state)217 void CgroupEventHandler::HandleProcessStateChanged(uid_t uid, pid_t pid,
218     const std::string& bundleName, int32_t state)
219 {
220     if (!supervisor_) {
221         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
222         return;
223     }
224     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}s, %{public}d", __func__, uid,
225         pid, bundleName.c_str(), state);
226     ChronoScope cs("HandleProcessStateChanged");
227     std::shared_ptr<Application> app = supervisor_->GetAppRecordNonNull(uid);
228     std::shared_ptr<ProcessRecord> procRecord = app->GetProcessRecordNonNull(pid);
229     procRecord->processState_ = state;
230     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
231         AdjustSource::ADJS_PROCESS_STATE);
232 }
233 
HandleAbilityStateChanged(uid_t uid,pid_t pid,const std::string & bundleName,const std::string & abilityName,uintptr_t token,int32_t abilityState,int32_t abilityType)234 void CgroupEventHandler::HandleAbilityStateChanged(uid_t uid, pid_t pid, const std::string& bundleName,
235     const std::string& abilityName, uintptr_t token, int32_t abilityState, int32_t abilityType)
236 {
237     if (!supervisor_) {
238         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
239         return;
240     }
241     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}s, %{public}s, %{public}d, %{public}d",
242         __func__, uid, pid, bundleName.c_str(), abilityName.c_str(), abilityState, abilityType);
243     if (abilityType == (int32_t)AbilityType::EXTENSION) {
244         CGS_LOGD("%{public}s : this type of event is not dealt with here", __func__);
245         return;
246     }
247     ChronoScope cs("HandleAbilityStateChanged");
248     if (abilityState == (int32_t)(AbilityState::ABILITY_STATE_TERMINATED)) {
249         auto app = supervisor_->GetAppRecord(uid);
250         if (app) {
251             auto procRecord = app->GetProcessRecord(pid);
252             if (procRecord) {
253                 procRecord->RemoveAbilityByToken(token);
254                 CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
255                     AdjustSource::ADJS_ABILITY_STATE);
256             }
257         }
258         return;
259     }
260     auto app = supervisor_->GetAppRecordNonNull(uid);
261     app->SetName(bundleName);
262     auto procRecord = app->GetProcessRecordNonNull(pid);
263     auto abiInfo = procRecord->GetAbilityInfoNonNull(token);
264     abiInfo->name_ = abilityName;
265     abiInfo->state_ = abilityState;
266     abiInfo->type_ = abilityType;
267     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
268         AdjustSource::ADJS_ABILITY_STATE);
269 }
270 
HandleExtensionStateChanged(uid_t uid,pid_t pid,const std::string & bundleName,const std::string & abilityName,uintptr_t token,int32_t extensionState,int32_t abilityType)271 void CgroupEventHandler::HandleExtensionStateChanged(uid_t uid, pid_t pid, const std::string& bundleName,
272     const std::string& abilityName, uintptr_t token, int32_t extensionState, int32_t abilityType)
273 {
274     if (!supervisor_) {
275         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
276         return;
277     }
278     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}s, %{public}s, %{public}d, %{public}d",
279         __func__, uid, pid, bundleName.c_str(), abilityName.c_str(), extensionState, abilityType);
280     ChronoScope cs("HandleExtensionStateChanged");
281     if (extensionState == (int32_t)(ExtensionState::EXTENSION_STATE_TERMINATED)) {
282         auto app = supervisor_->GetAppRecord(uid);
283         if (app) {
284             auto procRecord = app->GetProcessRecord(pid);
285             if (procRecord) {
286                 procRecord->RemoveAbilityByToken(token);
287                 CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
288                     AdjustSource::ADJS_EXTENSION_STATE);
289             }
290         }
291         return;
292     }
293     auto app = supervisor_->GetAppRecordNonNull(uid);
294     app->SetName(bundleName);
295     auto procRecord = app->GetProcessRecordNonNull(pid);
296     auto abiInfo = procRecord->GetAbilityInfoNonNull(token);
297     abiInfo->name_ = abilityName;
298     abiInfo->estate_ = extensionState;
299     abiInfo->type_ = abilityType;
300     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
301         AdjustSource::ADJS_EXTENSION_STATE);
302 }
303 
HandleProcessCreated(uid_t uid,pid_t pid,int32_t hostPid,int32_t processType,const std::string & bundleName,int32_t extensionType)304 void CgroupEventHandler::HandleProcessCreated(uid_t uid, pid_t pid, int32_t hostPid, int32_t processType,
305     const std::string& bundleName, int32_t extensionType)
306 {
307     if (!supervisor_) {
308         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
309         return;
310     }
311     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}d, %{public}d, %{public}s, %{public}d",
312         __func__, uid, pid, hostPid, processType, bundleName.c_str(), extensionType);
313     ChronoScope cs("HandleProcessCreated");
314     std::shared_ptr<Application> app = supervisor_->GetAppRecordNonNull(uid);
315     std::shared_ptr<ProcessRecord> procRecord = app->GetProcessRecordNonNull(pid);
316     app->SetName(bundleName);
317     switch (processType) {
318         case static_cast<int32_t>(ProcessType::RENDER):
319             procRecord->processType_ = ProcRecordType::RENDER;
320             procRecord->hostPid_ = hostPid;
321             app->AddHostProcess(hostPid);
322             break;
323         case static_cast<int32_t>(ProcessType::EXTENSION):
324             procRecord->processType_ = ProcRecordType::EXTENSION;
325             procRecord->extensionType_ = extensionType;
326             break;
327         case static_cast<int32_t>(ProcessType::GPU):
328             procRecord->processType_ = ProcRecordType::GPU;
329             procRecord->hostPid_ = hostPid;
330             app->AddHostProcess(hostPid);
331             break;
332         case static_cast<int32_t>(ProcessType::CHILD):
333             procRecord->processType_ = ProcRecordType::CHILD;
334             procRecord->hostPid_ = hostPid;
335             app->AddHostProcess(hostPid);
336             break;
337         default:
338             break;
339     }
340     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
341         AdjustSource::ADJS_PROCESS_CREATE);
342 }
343 
HandleProcessDied(uid_t uid,pid_t pid,const std::string & bundleName)344 void CgroupEventHandler::HandleProcessDied(uid_t uid, pid_t pid, const std::string& bundleName)
345 {
346     if (!supervisor_) {
347         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
348         return;
349     }
350     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}s", __func__, uid, pid, bundleName.c_str());
351     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
352     if (!app) {
353         CGS_LOGE("%{public}s : application %{public}s not exist!", __func__, bundleName.c_str());
354         return;
355     }
356     std::shared_ptr<ProcessRecord> procRecord = app->GetProcessRecord(pid);
357     if (procRecord) {
358         ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
359             ResType::RES_TYPE_PROCESS_STATE_CHANGE, ResType::ProcessStatus::PROCESS_DIED);
360     }
361     app->RemoveProcessRecord(pid);
362     // if all processes died, remove current app
363     if (app->GetPidsMap().size() == 0) {
364         supervisor_->RemoveApplication(uid);
365     }
366 }
367 
HandleTransientTaskStart(uid_t uid,pid_t pid,const std::string & packageName)368 void CgroupEventHandler::HandleTransientTaskStart(uid_t uid, pid_t pid, const std::string& packageName)
369 {
370     if (!supervisor_) {
371         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
372         return;
373     }
374     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}s", __func__, uid, pid, packageName.c_str());
375     auto app = supervisor_->GetAppRecordNonNull(uid);
376     app->SetName(packageName);
377     auto procRecord = app->GetProcessRecord(pid);
378     if (!procRecord) {
379         return;
380     }
381     procRecord->runningTransientTask_ = true;
382 }
383 
HandleTransientTaskEnd(uid_t uid,pid_t pid,const std::string & packageName)384 void CgroupEventHandler::HandleTransientTaskEnd(uid_t uid, pid_t pid, const std::string& packageName)
385 {
386     if (!supervisor_) {
387         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
388         return;
389     }
390     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}s", __func__, uid, pid, packageName.c_str());
391     auto app = supervisor_->GetAppRecordNonNull(uid);
392     app->SetName(packageName);
393     auto procRecord = app->GetProcessRecord(pid);
394     if (!procRecord) {
395         return;
396     }
397     procRecord->runningTransientTask_ = false;
398 }
399 
HandleContinuousTaskUpdate(uid_t uid,pid_t pid,const std::vector<uint32_t> & typeIds,int32_t abilityId)400 void CgroupEventHandler::HandleContinuousTaskUpdate(uid_t uid, pid_t pid,
401     const std::vector<uint32_t>& typeIds, int32_t abilityId)
402 {
403     if (!supervisor_) {
404         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
405         return;
406     }
407     ChronoScope cs("HandleContinuousTaskUpdate");
408     auto app = supervisor_->GetAppRecordNonNull(uid);
409     auto procRecord = app->GetProcessRecordNonNull(pid);
410     procRecord->continuousTaskFlag_ = 0;
411     procRecord->abilityIdAndContinuousTaskFlagMap_[abilityId] = typeIds;
412     for (const auto& typeId : typeIds) {
413         CGS_LOGI("%{public}s : %{public}d, %{public}d, %{public}d, abilityId %{public}d,",
414             __func__, uid, pid, typeId, abilityId);
415     }
416     for (const auto& ablityIdAndcontinuousTaskFlag : procRecord->abilityIdAndContinuousTaskFlagMap_) {
417         for (const auto& typeId : ablityIdAndcontinuousTaskFlag.second) {
418             procRecord->continuousTaskFlag_ |= (1U << typeId);
419         }
420     }
421     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
422         AdjustSource::ADJS_CONTINUOUS_BEGIN);
423 }
424 
HandleContinuousTaskCancel(uid_t uid,pid_t pid,int32_t typeId,int32_t abilityId)425 void CgroupEventHandler::HandleContinuousTaskCancel(uid_t uid, pid_t pid, int32_t typeId,
426     int32_t abilityId)
427 {
428     if (!supervisor_) {
429         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
430         return;
431     }
432     CGS_LOGI("%{public}s : %{public}d, %{public}d, %{public}d, %{public}d",
433         __func__, uid, pid, typeId, abilityId);
434     ChronoScope cs("HandleContinuousTaskCancel");
435     auto app = supervisor_->GetAppRecordNonNull(uid);
436     auto procRecord = app->GetProcessRecord(pid);
437     if (!procRecord) {
438         return;
439     }
440     procRecord->abilityIdAndContinuousTaskFlagMap_.erase(abilityId);
441     procRecord->continuousTaskFlag_ = 0;
442     for (const auto& ablityIdAndcontinuousTaskFlag : procRecord->abilityIdAndContinuousTaskFlagMap_) {
443         for (const auto& typeId : ablityIdAndcontinuousTaskFlag.second) {
444             procRecord->continuousTaskFlag_ |= (1U << typeId);
445         }
446     }
447     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
448         AdjustSource::ADJS_CONTINUOUS_END);
449 }
450 
HandleFocusedWindow(uint32_t windowId,uintptr_t abilityToken,WindowType windowType,uint64_t displayId,int32_t pid,int32_t uid)451 void CgroupEventHandler::HandleFocusedWindow(uint32_t windowId, uintptr_t abilityToken,
452     WindowType windowType, uint64_t displayId, int32_t pid, int32_t uid)
453 {
454     if (!supervisor_) {
455         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
456         return;
457     }
458     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}" PRIu64 ", %{public}d, %{public}d",
459         __func__, windowId, windowType, displayId, pid, uid);
460     if (!abilityToken) {
461         CGS_LOGW("%{public}s : abilityToken nullptr!", __func__);
462     }
463     std::shared_ptr<Application> app = nullptr;
464     std::shared_ptr<ProcessRecord> procRecord = nullptr;
465     {
466         ChronoScope cs("HandleFocusedWindow");
467         app = supervisor_->GetAppRecordNonNull(uid);
468         procRecord = app->GetProcessRecordNonNull(pid);
469         auto win = procRecord->GetWindowInfoNonNull(windowId);
470         auto abi = procRecord->GetAbilityInfo(abilityToken);
471         procRecord->linkedWindowId_ = (int32_t)(windowId);
472         win->windowType_ = (int32_t)(windowType);
473         win->isFocused_ = true;
474         win->displayId_ = displayId;
475         win->ability_ = abi;
476 
477         app->focusedProcess_ = procRecord;
478         auto lastFocusApp = supervisor_->focusedApp_;
479         if (lastFocusApp && lastFocusApp != app) {
480             lastFocusApp->focusedProcess_ = nullptr;
481             CgroupAdjuster::GetInstance().AdjustAllProcessGroup(*(lastFocusApp.get()),
482                 AdjustSource::ADJS_FOCUSED_WINDOW);
483         }
484         supervisor_->focusedApp_ = app;
485         CgroupAdjuster::GetInstance().AdjustAllProcessGroup(*(app.get()), AdjustSource::ADJS_FOCUSED_WINDOW);
486         ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()), ResType::RES_TYPE_WINDOW_FOCUS,
487             ResType::WindowFocusStatus::WINDOW_FOCUS);
488     }
489     if (app->GetName().empty()) {
490         app->SetName(SchedController::GetInstance().GetBundleNameByUid(uid));
491     }
492 }
493 
HandleUnfocusedWindow(uint32_t windowId,uintptr_t abilityToken,WindowType windowType,uint64_t displayId,int32_t pid,int32_t uid)494 void CgroupEventHandler::HandleUnfocusedWindow(uint32_t windowId, uintptr_t abilityToken,
495     WindowType windowType, uint64_t displayId, int32_t pid, int32_t uid)
496 {
497     if (!supervisor_) {
498         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
499         return;
500     }
501     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}" PRIu64 ", %{public}d, %{public}d",
502         __func__, windowId, windowType, displayId, pid, uid);
503     if (!abilityToken) {
504         CGS_LOGW("%{public}s : abilityToken nullptr!", __func__);
505     }
506     std::shared_ptr<Application> app = nullptr;
507     std::shared_ptr<ProcessRecord> procRecord = nullptr;
508     {
509         ChronoScope cs("HandleUnfocusedWindow");
510         app = supervisor_->GetAppRecord(uid);
511         procRecord = app ? app->GetProcessRecord(pid) : nullptr;
512         if (!app || !procRecord) {
513             return;
514         }
515         auto win = procRecord->GetWindowInfoNonNull(windowId);
516         auto abi = procRecord->GetAbilityInfo(abilityToken);
517         win->windowType_ = (int32_t)(windowType);
518         win->isFocused_ = false;
519         win->displayId_ = displayId;
520         win->ability_ = abi;
521 
522         if (app->focusedProcess_ == procRecord) {
523             app->focusedProcess_ = nullptr;
524         }
525         CgroupAdjuster::GetInstance().AdjustAllProcessGroup(*(app.get()), AdjustSource::ADJS_UNFOCUSED_WINDOW);
526         ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()), ResType::RES_TYPE_WINDOW_FOCUS,
527             ResType::WindowFocusStatus::WINDOW_UNFOCUS);
528     }
529     if (app->GetName().empty()) {
530         app->SetName(SchedController::GetInstance().GetBundleNameByUid(uid));
531     }
532 }
533 
HandleWindowVisibilityChanged(uint32_t windowId,uint32_t visibilityState,WindowType windowType,int32_t pid,int32_t uid)534 void CgroupEventHandler::HandleWindowVisibilityChanged(
535     uint32_t windowId, uint32_t visibilityState, WindowType windowType, int32_t pid, int32_t uid)
536 {
537     if (!supervisor_) {
538         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
539         return;
540     }
541     bool isVisible = visibilityState < Rosen::WindowVisibilityState::WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
542     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}d, %{public}d, %{public}d", __func__, windowId,
543         visibilityState, (int32_t)windowType, pid, uid);
544 
545     std::shared_ptr<Application> app = nullptr;
546     std::shared_ptr<ProcessRecord> procRecord = nullptr;
547     if (isVisible) {
548         app = supervisor_->GetAppRecordNonNull(uid);
549         procRecord = app->GetProcessRecordNonNull(pid);
550     } else {
551         app = supervisor_->GetAppRecord(uid);
552         if (app) {
553             procRecord = app->GetProcessRecord(pid);
554         }
555     }
556     if (!procRecord) {
557         return;
558     }
559     auto windowInfo = procRecord->GetWindowInfoNonNull(windowId);
560     bool visibleStatusNotChanged  = windowInfo->isVisible_ == isVisible;
561     windowInfo->visibilityState_ = visibilityState;
562     windowInfo->isVisible_ = isVisible;
563     windowInfo->windowType_ = (int32_t)windowType;
564 
565     if (visibleStatusNotChanged) {
566         return;
567     }
568     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
569         AdjustSource::ADJS_WINDOW_VISIBILITY_CHANGED);
570 }
571 
HandleDrawingContentChangeWindow(uint32_t windowId,WindowType windowType,bool drawingContentState,int32_t pid,int32_t uid)572 void CgroupEventHandler::HandleDrawingContentChangeWindow(
573     uint32_t windowId, WindowType windowType, bool drawingContentState, int32_t pid, int32_t uid)
574 {
575     if (!supervisor_) {
576         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
577         return;
578     }
579     CGS_LOGD("%{public}s : %{public}d, %{public}d, %{public}d, %{public}d, %{public}d", __func__, windowId,
580         drawingContentState, (int32_t)windowType, pid, uid);
581 
582     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
583     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
584     if (!app || !procRecord) {
585         return;
586     }
587     procRecord->processDrawingState_ = drawingContentState;
588     auto windowInfo = procRecord->GetWindowInfoNonNull(windowId);
589     if (!windowInfo) {
590         CGS_LOGE("%{public}s : windowInfo nullptr!", __func__);
591         return;
592     }
593     windowInfo->drawingContentState_ = drawingContentState;
594     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
595         ResType::RES_TYPE_WINDOW_DRAWING_CONTENT_CHANGE,
596         drawingContentState ? ResType::WindowDrawingStatus::Drawing : ResType::WindowDrawingStatus::NotDrawing);
597 }
598 
HandleReportMMIProcess(uint32_t resType,int64_t value,const nlohmann::json & payload)599 void CgroupEventHandler::HandleReportMMIProcess(uint32_t resType, int64_t value, const nlohmann::json& payload)
600 {
601     int32_t uid = 0;
602     int32_t pid = 0;
603     int32_t mmi_service;
604 
605     if (!supervisor_) {
606         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
607         return;
608     }
609 
610     if (!ParsePayload(uid, pid, mmi_service, value, payload)) {
611         return;
612     }
613 
614     CGS_LOGD("%{public}s : %{public}u, %{public}d, %{public}d, %{public}d",
615         __func__, resType, uid, pid, mmi_service);
616     if (uid <= 0 || pid <= 0 || mmi_service <= 0) {
617         return;
618     }
619 
620     auto app = supervisor_->GetAppRecordNonNull(uid);
621     app->SetName(MMI_SERVICE_NAME);
622     auto procRecord = app->GetProcessRecordNonNull(mmi_service);
623     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
624         AdjustSource::ADJS_REPORT_MMI_SERVICE_THREAD);
625 }
626 
HandleReportRenderThread(uint32_t resType,int64_t value,const nlohmann::json & payload)627 void CgroupEventHandler::HandleReportRenderThread(uint32_t resType, int64_t value, const nlohmann::json& payload)
628 {
629     int32_t uid = 0;
630     int32_t pid = 0;
631     int32_t render = 0;
632 
633     if (!supervisor_) {
634         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
635         return;
636     }
637 
638     if (!ParsePayload(uid, pid, render, value, payload)) {
639         return;
640     }
641 
642     CGS_LOGD("%{public}s : %{public}u, %{public}d, %{public}d, %{public}d",
643         __func__, resType, uid, pid, render);
644     if (uid <= 0 || pid <= 0 || render <= 0) {
645         return;
646     }
647 
648     auto app = supervisor_->GetAppRecordNonNull(uid);
649     auto procRecord = app->GetProcessRecordNonNull(pid);
650     procRecord->renderTid_ = render;
651     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
652         AdjustSource::ADJS_REPORT_RENDER_THREAD);
653 }
654 
HandleReportKeyThread(uint32_t resType,int64_t value,const nlohmann::json & payload)655 void CgroupEventHandler::HandleReportKeyThread(uint32_t resType, int64_t value, const nlohmann::json& payload)
656 {
657     int32_t uid = 0;
658     int32_t pid = 0;
659     int32_t keyTid = 0;
660     int32_t role = 0;
661 
662     std::shared_ptr<Application> app = nullptr;
663     std::shared_ptr<ProcessRecord> procRecord = nullptr;
664     if (!GetProcInfoByPayload(uid, pid, app, procRecord, payload)) {
665         return;
666     }
667 
668     if (!ParseValue(keyTid, "tid", payload) || !ParseValue(role, "role", payload)) {
669         return;
670     }
671 
672     if (!ResSchedUtils::GetInstance().CheckTidIsInPid(pid, keyTid)) {
673         return;
674     }
675 
676     if (value == ResType::ReportChangeStatus::CREATE) {
677         procRecord->keyThreadRoleMap_.emplace(keyTid, role);
678     } else {
679         procRecord->keyThreadRoleMap_.erase(keyTid);
680     }
681 
682     // if role of thread is important display, adjust it
683     auto hostProcRecord = app->GetProcessRecord(procRecord->hostPid_);
684     if (!hostProcRecord) {
685         return;
686     }
687     CGS_LOGI("%{public}s : appName: %{public}s, uid: %{public}d, pid: %{public}d, keyTid: %{public}d",
688         __func__, app->GetName().c_str(), uid, pid, keyTid);
689     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(hostProcRecord.get()),
690         AdjustSource::ADJS_REPORT_IMPORTANT_DISPLAY_THREAD);
691 }
692 
HandleReportWindowState(uint32_t resType,int64_t value,const nlohmann::json & payload)693 void CgroupEventHandler::HandleReportWindowState(uint32_t resType, int64_t value, const nlohmann::json& payload)
694 {
695     int32_t uid = 0;
696     int32_t pid = 0;
697     int32_t windowId = -1;
698     int32_t state = 0;
699     int32_t nowSerialNum = -1;
700 
701     std::shared_ptr<Application> app = nullptr;
702     std::shared_ptr<ProcessRecord> procRecord = nullptr;
703     if (!GetProcInfoByPayload(uid, pid, app, procRecord, payload)) {
704         return;
705     }
706 
707     if (!ParseValue(windowId, "windowId", payload) || !ParseValue(state, "state", payload) ||
708         !ParseValue(nowSerialNum, "serialNum", payload)) {
709         CGS_LOGW("%{public}s : param is not valid or not exist", __func__);
710         return;
711     }
712     CGS_LOGI("%{public}s : render process name: %{public}s, uid: %{public}d, pid: %{public}d, state: %{public}d",
713         __func__, app->GetName().c_str(), uid, pid, state);
714     if (nowSerialNum <= procRecord->serialNum_ &&
715         (procRecord->serialNum_ - nowSerialNum <= static_cast<int32_t>(MAX_SPAN_SERIAL))) {
716         return;
717     }
718     procRecord->serialNum_ = nowSerialNum;
719 
720     if (state == ResType::WindowStates::ACTIVE) {
721         procRecord->linkedWindowId_ = windowId;
722         procRecord->isActive_ = true;
723     } else {
724         procRecord->linkedWindowId_ = -1;
725         procRecord->isActive_ = false;
726     }
727     auto hostProcRecord = app->GetProcessRecord(procRecord->hostPid_);
728     if (!hostProcRecord) {
729         return;
730     }
731     CGS_LOGI("%{public}s : pid: %{public}d, winId: %{public}d, isActive_: %{public}d",
732         __func__, pid, procRecord->linkedWindowId_, procRecord->isActive_);
733     UpdateActivepWebRenderInfo(uid, pid, windowId, state, hostProcRecord);
734     if (CheckVisibilityForRenderProcess(*(procRecord.get()), *hostProcRecord)) {
735         CGS_LOGW("%{public}s : bundle name: %{public}s, uid: %{public}d, pid: %{public}d, winId: %{public}d" \
736             "is not visible but active", __func__, app->GetName().c_str(), uid, pid, procRecord->linkedWindowId_);
737     }
738     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(hostProcRecord.get()),
739         AdjustSource::ADJS_REPORT_WINDOW_STATE_CHANGED);
740     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
741         ResType::RES_TYPE_REPORT_WINDOW_STATE, state);
742 }
743 
UpdateActivepWebRenderInfo(int32_t uid,int32_t pid,int32_t windowId,int32_t state,const std::shared_ptr<ProcessRecord> & proc)744 void CgroupEventHandler::UpdateActivepWebRenderInfo(int32_t uid, int32_t pid, int32_t windowId, int32_t state,
745     const std::shared_ptr<ProcessRecord>& proc)
746 {
747     if (state != ResType::WindowStates::ACTIVE) {
748         return;
749     }
750     auto win = proc->GetWindowInfoNonNull(windowId);
751     win->topWebviewRenderUid_ = (uint32_t)(uid);
752 }
753 
HandleReportAudioState(uint32_t resType,int64_t value,const nlohmann::json & payload)754 void CgroupEventHandler::HandleReportAudioState(uint32_t resType, int64_t value, const nlohmann::json& payload)
755 {
756     int32_t uid = 0;
757     int32_t pid = 0;
758 
759     if (!supervisor_) {
760         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
761         return;
762     }
763 
764     if (payload.contains("uid") && payload.at("uid").is_number_integer()) {
765         uid = payload["uid"].get<std::int32_t>();
766     }
767     if (payload.contains("pid") && payload.at("pid").is_number_integer()) {
768         pid = payload["pid"].get<std::int32_t>();
769     }
770     if (uid <= 0 || pid <= 0) {
771         return;
772     }
773 
774     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
775     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
776     if (!app || !procRecord) {
777         return;
778     }
779     procRecord->audioPlayingState_ = static_cast<int32_t>(value);
780     CGS_LOGI("%{public}s : audio process name: %{public}s, uid: %{public}d, pid: %{public}d, state: %{public}d",
781         __func__, app->GetName().c_str(), uid, pid, procRecord->audioPlayingState_);
782 
783     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
784         AdjustSource::ADJS_REPORT_AUDIO_STATE_CHANGED);
785     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
786         resType, static_cast<int32_t>(value));
787 }
788 
HandleReportWebviewAudioState(uint32_t resType,int64_t value,const nlohmann::json & payload)789 void CgroupEventHandler::HandleReportWebviewAudioState(uint32_t resType, int64_t value, const nlohmann::json& payload)
790 {
791     int32_t uid = 0;
792     int32_t pid = 0;
793 
794     if (!supervisor_) {
795         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
796         return;
797     }
798 
799     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "clientPid", payload)) {
800         return;
801     }
802     if (uid <= 0 || pid <= 0) {
803         CGS_LOGW("%{public}s : uid or pid invalid, uid: %{public}d, pid: %{public}d!",
804             __func__, uid, pid);
805         return;
806     }
807 
808     std::shared_ptr<ProcessRecord> procRecord = supervisor_->FindProcessRecord(pid);
809     if (!procRecord) {
810         CGS_LOGW("%{public}s : proc record is not exist, uid: %{public}d, pid: %{public}d",
811             __func__, uid, pid);
812         return;
813     }
814 
815     std::shared_ptr<Application> app = supervisor_->GetAppRecordNonNull(procRecord->GetUid());
816     procRecord->audioPlayingState_ = static_cast<int32_t>(value);
817     CGS_LOGI("%{public}s : audio process name: %{public}s, uid: %{public}d, pid: %{public}d, state: %{public}d",
818         __func__, app->GetName().c_str(), uid, pid, procRecord->audioPlayingState_);
819 
820     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
821         AdjustSource::ADJS_REPORT_WEBVIEW_AUDIO_STATE_CHANGED);
822     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
823         resType, static_cast<int32_t>(value));
824 }
825 
HandleReportRunningLockEvent(uint32_t resType,int64_t value,const nlohmann::json & payload)826 void CgroupEventHandler::HandleReportRunningLockEvent(uint32_t resType, int64_t value, const nlohmann::json& payload)
827 {
828     int32_t uid = 0;
829     int32_t pid = 0;
830     uint32_t type = 0;
831     int32_t state = -1;
832 
833     if (!supervisor_) {
834         CGS_LOGE("%{public}s : supervisor nullptr.", __func__);
835         return;
836     }
837 
838     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
839         return;
840     }
841     if (uid <= 0 || pid <= 0) {
842         return;
843     }
844     if (payload.contains("type") && payload.at("type").is_string()) {
845         type = static_cast<uint32_t>(atoi(payload["type"].get<std::string>().c_str()));
846     }
847     state = static_cast<int32_t>(value);
848     CGS_LOGI("report running lock event, uid:%{public}d, pid:%{public}d, lockType:%{public}d, state:%{public}d",
849         uid, pid, type, state);
850 #ifdef POWER_MANAGER_ENABLE
851     if (type == static_cast<uint32_t>(PowerMgr::RunningLockType::RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL)) {
852         return;
853     }
854     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
855     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
856     if (!app || !procRecord) {
857         return;
858     }
859     procRecord->runningLockState_[type] = (state == ResType::RunninglockState::RUNNINGLOCK_STATE_ENABLE);
860     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()), resType, state);
861 #endif
862 }
863 
HandleReportHisysEvent(uint32_t resType,int64_t value,const nlohmann::json & payload)864 void CgroupEventHandler::HandleReportHisysEvent(uint32_t resType, int64_t value, const nlohmann::json& payload)
865 {
866     int32_t uid = 0;
867     int32_t pid = 0;
868 
869     if (!supervisor_) {
870         CGS_LOGE("%{public}s : supervisor nullptr.", __func__);
871         return;
872     }
873 
874     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
875         return;
876     }
877     if (uid <= 0 || pid <= 0) {
878         return;
879     }
880     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
881     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
882     if (!app || !procRecord) {
883         return;
884     }
885 
886     switch (resType) {
887         case ResType::RES_TYPE_REPORT_CAMERA_STATE: {
888             procRecord->cameraState_ = static_cast<int32_t>(value);
889             break;
890         }
891         case ResType::RES_TYPE_BLUETOOTH_A2DP_CONNECT_STATE_CHANGE: {
892             procRecord->bluetoothState_ = static_cast<int32_t>(value);
893             break;
894         }
895         case ResType::RES_TYPE_WIFI_CONNECT_STATE_CHANGE: {
896             procRecord->wifiState_ = static_cast<int32_t>(value);
897             break;
898         }
899         case ResType::RES_TYPE_MMI_INPUT_STATE: {
900             if (payload.contains("syncStatus") && payload.at("syncStatus").is_string()) {
901                 procRecord->mmiStatus_ = atoi(payload["syncStatus"].get<std::string>().c_str());
902             }
903             break;
904         }
905         default: {
906             break;
907         }
908     }
909     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
910         resType, static_cast<int32_t>(value));
911 }
912 
HandleReportScreenCaptureEvent(uint32_t resType,int64_t value,const nlohmann::json & payload)913 void CgroupEventHandler::HandleReportScreenCaptureEvent(uint32_t resType, int64_t value, const nlohmann::json& payload)
914 {
915     int32_t uid = 0;
916     int32_t pid = 0;
917 
918     if (!supervisor_) {
919         CGS_LOGE("%{public}s: supervisor nullptr.", __func__);
920         return;
921     }
922 
923     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
924         CGS_LOGE("%{public}s : payload does not contain uid or pid", __func__);
925         return;
926     }
927     if (uid <= 0 || pid <= 0) {
928         return;
929     }
930     CGS_LOGI("report screen capture event, uid:%{public}d, pid:%{public}d, value:%{public}d",
931         uid, pid, static_cast<int32_t>(value));
932     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
933     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
934     if (!app || !procRecord) {
935         return;
936     }
937     procRecord->screenCaptureState_ = (value == ResType::ScreenCaptureStatus::START_SCREEN_CAPTURE);
938     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
939         AdjustSource::ADJS_REPORT_SCREEN_CAPTURE);
940     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()),
941         resType, static_cast<int32_t>(value));
942 }
943 
HandleReportAvCodecEvent(uint32_t resType,int64_t value,const nlohmann::json & payload)944 void CgroupEventHandler::HandleReportAvCodecEvent(uint32_t resType, int64_t value, const nlohmann::json& payload)
945 {
946     int32_t uid = 0;
947     int32_t pid = 0;
948     int32_t instanceId = -1;
949     int32_t state = -1;
950 
951     if (!supervisor_) {
952         CGS_LOGE("%{public}s : supervisor nullptr.", __func__);
953         return;
954     }
955 
956     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
957         return;
958     }
959     if (uid <= 0 || pid <= 0) {
960         return;
961     }
962     if (!ParseValue(instanceId, "instanceId", payload)) {
963         return;
964     }
965     if (instanceId < 0) {
966         return;
967     }
968     state = static_cast<int32_t>(value);
969     CGS_LOGI("report av_codec event, uid:%{public}d, pid:%{public}d, instanceId:%{public}d, state:%{public}d",
970         uid, pid, instanceId, state);
971     std::shared_ptr<Application> app = supervisor_->GetAppRecord(uid);
972     std::shared_ptr<ProcessRecord> procRecord = app ? app->GetProcessRecord(pid) : nullptr;
973     if (!app || !procRecord) {
974         return;
975     }
976     procRecord->avCodecState_[instanceId] = (state == ResType::AvCodecState::CODEC_START_INFO);
977     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()), resType, state);
978 }
979 
HandleSceneBoardState(uint32_t resType,int64_t value,const nlohmann::json & payload)980 void CgroupEventHandler::HandleSceneBoardState(uint32_t resType, int64_t value, const nlohmann::json& payload)
981 {
982     int32_t sceneBoardPid = 0;
983     if (!supervisor_) {
984         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
985         return;
986     }
987 
988     if (!ParseValue(sceneBoardPid, "pid", payload)) {
989         return;
990     }
991     if (sceneBoardPid <= 0) {
992         return;
993     }
994 
995     supervisor_->sceneBoardPid_ = sceneBoardPid;
996     CGS_LOGI("%{public}s : set sceneboard pid: %{public}d", __func__, sceneBoardPid);
997 }
998 
CheckVisibilityForRenderProcess(ProcessRecord & pr,ProcessRecord & mainProc)999 bool CgroupEventHandler::CheckVisibilityForRenderProcess(ProcessRecord &pr, ProcessRecord &mainProc)
1000 {
1001     return (pr.processType_ == ProcRecordType::RENDER) && pr.isActive_ &&
1002          !mainProc.GetWindowInfoNonNull(pr.linkedWindowId_)->isVisible_;
1003 }
1004 
HandleWebviewScreenCapture(uint32_t resType,int64_t value,const nlohmann::json & payload)1005 void CgroupEventHandler::HandleWebviewScreenCapture(uint32_t resType, int64_t value, const nlohmann::json& payload)
1006 {
1007     int32_t uid = 0;
1008     int32_t pid = 0;
1009     std::shared_ptr<Application> app = nullptr;
1010     std::shared_ptr<ProcessRecord> procRecord = nullptr;
1011 
1012     if (!GetProcInfoByPayload(uid, pid, app, procRecord, payload)) {
1013         return;
1014     }
1015 
1016     procRecord->screenCaptureState_= (value == ResType::WebScreenCapture::WEB_SCREEN_CAPTURE_START);
1017     CGS_LOGI("%{public}s : screen capture process: %{public}s, uid: %{public}d, pid: %{public}d, state: %{public}d",
1018         __func__, app->GetName().c_str(), uid, pid, procRecord->screenCaptureState_);
1019 
1020     CgroupAdjuster::GetInstance().AdjustProcessGroup(*(app.get()), *(procRecord.get()),
1021         AdjustSource::ADJS_REPORT_WEBVIEW_SCREEN_CAPTURE);
1022     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()), resType,
1023         procRecord->screenCaptureState_);
1024 }
1025 
HandleReportWebviewVideoState(uint32_t resType,int64_t value,const nlohmann::json & payload)1026 void CgroupEventHandler::HandleReportWebviewVideoState(uint32_t resType, int64_t value, const nlohmann::json& payload)
1027 {
1028     int32_t uid = 0;
1029     int32_t pid = 0;
1030     std::shared_ptr<Application> app = nullptr;
1031     std::shared_ptr<ProcessRecord> procRecord = nullptr;
1032 
1033     if (!GetProcInfoByPayload(uid, pid, app, procRecord, payload)) {
1034         return;
1035     }
1036 
1037     procRecord->videoState_ = (value == ResType::WebVideoState::WEB_VIDEO_PLAYING_START);
1038     CGS_LOGI("%{public}s : video process name: %{public}s, uid: %{public}d, pid: %{public}d, state: %{public}d",
1039         __func__, app->GetName().c_str(), uid, pid, procRecord->videoState_);
1040 
1041     ResSchedUtils::GetInstance().ReportSysEvent(*(app.get()), *(procRecord.get()), resType,
1042         procRecord->videoState_);
1043 }
1044 
GetProcInfoByPayload(int32_t & uid,int32_t & pid,std::shared_ptr<Application> & app,std::shared_ptr<ProcessRecord> & procRecord,const nlohmann::json & payload)1045 bool CgroupEventHandler::GetProcInfoByPayload(int32_t &uid, int32_t &pid, std::shared_ptr<Application>& app,
1046     std::shared_ptr<ProcessRecord>& procRecord, const nlohmann::json& payload)
1047 {
1048     if (!supervisor_) {
1049         CGS_LOGE("%{public}s : supervisor nullptr!", __func__);
1050         return false;
1051     }
1052 
1053     if (!ParsePayload(uid, pid, payload)) {
1054         CGS_LOGW("%{public}s : uid or pid invalid, uid: %{public}d, pid: %{public}d!",
1055             __func__, uid, pid);
1056         return false;
1057     }
1058     app = supervisor_->GetAppRecord(uid);
1059     if (app) {
1060         procRecord = app->GetProcessRecordNonNull(pid);
1061     }
1062     if (!app || !procRecord) {
1063         CGS_LOGW("%{public}s : app record or proc record is not exist, uid: %{public}d, pid: %{public}d!",
1064             __func__, uid, pid);
1065         return false;
1066     }
1067     return true;
1068 }
1069 
ParsePayload(int32_t & uid,int32_t & pid,const nlohmann::json & payload)1070 bool CgroupEventHandler::ParsePayload(int32_t& uid, int32_t& pid, const nlohmann::json& payload)
1071 {
1072     if (!ParseValue(uid, "uid", payload) || !ParseValue(pid, "pid", payload)) {
1073         return false;
1074     }
1075     if (uid <= 0 || pid <= 0) {
1076         return false;
1077     }
1078     return true;
1079 }
1080 
ParsePayload(int32_t & uid,int32_t & pid,int32_t & tid,int64_t value,const nlohmann::json & payload)1081 bool CgroupEventHandler::ParsePayload(int32_t& uid, int32_t& pid, int32_t& tid,
1082     int64_t value, const nlohmann::json& payload)
1083 {
1084     if (payload.contains("uid") && payload.at("uid").is_string()) {
1085         uid = atoi(payload["uid"].get<std::string>().c_str());
1086     }
1087 
1088     if (payload.contains("pid") && payload.at("pid").is_string()) {
1089         pid = atoi(payload["pid"].get<std::string>().c_str());
1090     }
1091     tid = static_cast<int32_t>(value);
1092     return true;
1093 }
1094 
ParseValue(int32_t & value,const char * name,const nlohmann::json & payload)1095 bool CgroupEventHandler::ParseValue(int32_t& value, const char* name,
1096     const nlohmann::json& payload)
1097 {
1098     if (payload.contains(name) && payload.at(name).is_string()) {
1099         value = atoi(payload[name].get<std::string>().c_str());
1100         return true;
1101     }
1102     return false;
1103 }
1104 
PostTask(const std::function<void ()> task)1105 void CgroupEventHandler::PostTask(const std::function<void()> task)
1106 {
1107     if (!cgroupEventQueue_) {
1108         CGS_LOGE("%{public}s : cgroupEventQueue_ nullptr", __func__);
1109         return;
1110     }
1111     cgroupEventQueue_->submit([task, this] {
1112         task();
1113     });
1114 }
1115 
PostTask(const std::function<void ()> task,const std::string & taskName,const int32_t delayTime)1116 void CgroupEventHandler::PostTask(const std::function<void()> task, const std::string &taskName,
1117     const int32_t delayTime)
1118 {
1119     std::lock_guard<ffrt::mutex> autoLock(delayTaskMapMutex_);
1120     if (!cgroupEventQueue_) {
1121         CGS_LOGE("%{public}s : cgroupEventQueue_ nullptr", __func__);
1122         return;
1123     }
1124     delayTaskMap_[taskName] = cgroupEventQueue_->submit_h([task, this] {
1125         task();
1126     }, ffrt::task_attr().delay(delayTime * ffrtSwitch_));
1127 }
1128 
RemoveTask(const std::string & taskName)1129 void CgroupEventHandler::RemoveTask(const std::string &taskName)
1130 {
1131     std::lock_guard<ffrt::mutex> autoLock(delayTaskMapMutex_);
1132     for (auto iter = delayTaskMap_.begin(); iter != delayTaskMap_.end(); iter++) {
1133         if (iter->first == taskName && iter->second != nullptr) {
1134             cgroupEventQueue_->cancel(iter->second);
1135             delayTaskMap_.erase(iter);
1136             return;
1137         }
1138     }
1139 }
1140 } // namespace ResourceSchedule
1141 } // namespace OHOS
1142