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