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