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