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 "app_state_observer.h"
17
18 #include "sched_controller.h"
19 #include "cgroup_event_handler.h"
20 #include "cgroup_sched_log.h"
21 #include "ressched_utils.h"
22 #include "res_type.h"
23 #include "supervisor.h"
24
25 namespace OHOS {
26 namespace ResourceSchedule {
27 namespace {
28 constexpr HiviewDFX::HiLogLabel LOG_LABEL = {LOG_CORE, LOG_TAG_DOMAIN_ID_RMS, "RmsAppStateObserver"};
29 }
30
OnForegroundApplicationChanged(const AppStateData & appStateData)31 void RmsApplicationStateObserver::OnForegroundApplicationChanged(const AppStateData &appStateData)
32 {
33 if (!ValidateAppStateData(appStateData)) {
34 CGS_LOGE("%{public}s : validate app state data failed!", __func__);
35 return;
36 }
37 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
38 if (cgHandler) {
39 auto uid = appStateData.uid;
40 auto bundleName = appStateData.bundleName;
41 auto state = appStateData.state;
42 auto pid = appStateData.pid;
43
44 cgHandler->PostTask([cgHandler, uid, pid, bundleName, state] {
45 cgHandler->HandleForegroundApplicationChanged(uid, pid, bundleName, state);
46 });
47 }
48
49 nlohmann::json payload;
50 payload["pid"] = std::to_string(appStateData.pid);
51 payload["uid"] = std::to_string(appStateData.uid);
52 payload["bundleName"] = appStateData.bundleName;
53 ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_APP_STATE_CHANGE, appStateData.state, payload);
54 }
55
OnAbilityStateChanged(const AbilityStateData & abilityStateData)56 void RmsApplicationStateObserver::OnAbilityStateChanged(const AbilityStateData &abilityStateData)
57 {
58 if (!ValidateAbilityStateData(abilityStateData)) {
59 CGS_LOGE("%{public}s : validate ability state data failed!", __func__);
60 return;
61 }
62 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
63 if (cgHandler) {
64 auto uid = abilityStateData.uid;
65 auto pid = abilityStateData.pid;
66 auto bundleName = abilityStateData.bundleName;
67 auto abilityName = abilityStateData.abilityName;
68 auto token = reinterpret_cast<uintptr_t>(abilityStateData.token.GetRefPtr());
69 auto abilityState = abilityStateData.abilityState;
70 auto abilityType = abilityStateData.abilityType;
71
72 cgHandler->PostTask([cgHandler, uid, pid, bundleName, abilityName, token, abilityState, abilityType] {
73 cgHandler->HandleAbilityStateChanged(uid, pid, bundleName, abilityName,
74 token, abilityState, abilityType);
75 });
76 }
77
78 nlohmann::json payload;
79 payload["pid"] = std::to_string(abilityStateData.pid);
80 payload["uid"] = std::to_string(abilityStateData.uid);
81 payload["bundleName"] = abilityStateData.bundleName;
82 ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_ABILITY_STATE_CHANGE,
83 abilityStateData.abilityState, payload);
84 }
85
OnExtensionStateChanged(const AbilityStateData & abilityStateData)86 void RmsApplicationStateObserver::OnExtensionStateChanged(const AbilityStateData &abilityStateData)
87 {
88 if (!ValidateAbilityStateData(abilityStateData)) {
89 CGS_LOGE("%{public}s : validate extension state data failed!", __func__);
90 return;
91 }
92 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
93 if (cgHandler) {
94 auto uid = abilityStateData.uid;
95 auto pid = abilityStateData.pid;
96 auto bundleName = abilityStateData.bundleName;
97 auto abilityName = abilityStateData.abilityName;
98 auto token = reinterpret_cast<uintptr_t>(abilityStateData.token.GetRefPtr());
99 auto abilityState = abilityStateData.abilityState;
100 auto abilityType = abilityStateData.abilityType;
101
102 cgHandler->PostTask([cgHandler, uid, pid, bundleName, abilityName, token, abilityState, abilityType] {
103 cgHandler->HandleExtensionStateChanged(uid, pid, bundleName, abilityName,
104 token, abilityState, abilityType);
105 });
106 }
107
108 nlohmann::json payload;
109 payload["pid"] = std::to_string(abilityStateData.pid);
110 payload["uid"] = std::to_string(abilityStateData.uid);
111 payload["bundleName"] = abilityStateData.bundleName;
112 ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_EXTENSION_STATE_CHANGE,
113 abilityStateData.abilityState, payload);
114 }
115
OnProcessCreated(const ProcessData & processData)116 void RmsApplicationStateObserver::OnProcessCreated(const ProcessData &processData)
117 {
118 if (!ValidateProcessData(processData)) {
119 CGS_LOGE("%{public}s : validate process data failed!", __func__);
120 return;
121 }
122 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
123 if (cgHandler) {
124 auto uid = processData.uid;
125 auto pid = processData.pid;
126 auto bundleName = processData.bundleName;
127 auto processType = static_cast<int32_t>(processData.processType);
128
129 cgHandler->PostTask([cgHandler, uid, pid, processType, bundleName] {
130 cgHandler->HandleProcessCreated(uid, pid, processType, bundleName);
131 });
132 }
133
134 nlohmann::json payload;
135 payload["pid"] = std::to_string(processData.pid);
136 payload["uid"] = std::to_string(processData.uid);
137 payload["processType"] = std::to_string(static_cast<int32_t>(processData.processType));
138 payload["renderUid"] = std::to_string(processData.renderUid);
139 payload["bundleName"] = processData.bundleName;
140 ResSchedUtils::GetInstance().ReportDataInProcess(
141 ResType::RES_TYPE_PROCESS_STATE_CHANGE, ResType::ProcessStatus::PROCESS_CREATED, payload);
142 }
143
OnProcessDied(const ProcessData & processData)144 void RmsApplicationStateObserver::OnProcessDied(const ProcessData &processData)
145 {
146 if (!ValidateProcessData(processData)) {
147 CGS_LOGE("%{public}s : validate process data failed!", __func__);
148 return;
149 }
150 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
151 if (cgHandler) {
152 auto uid = processData.uid;
153 auto pid = processData.pid;
154 auto bundleName = processData.bundleName;
155
156 cgHandler->PostTask([cgHandler, uid, pid, bundleName] {
157 cgHandler->HandleProcessDied(uid, pid, bundleName);
158 });
159 }
160
161 nlohmann::json payload;
162 payload["pid"] = std::to_string(processData.pid);
163 payload["uid"] = std::to_string(processData.uid);
164 payload["bundleName"] = processData.bundleName;
165 ResSchedUtils::GetInstance().ReportDataInProcess(
166 ResType::RES_TYPE_PROCESS_STATE_CHANGE, ResType::ProcessStatus::PROCESS_DIED, payload);
167 }
168
OnApplicationStateChanged(const AppStateData & appStateData)169 void RmsApplicationStateObserver::OnApplicationStateChanged(const AppStateData &appStateData)
170 {
171 if (!ValidateAppStateData(appStateData)) {
172 CGS_LOGE("%{public}s : validate app state data failed!", __func__);
173 return;
174 }
175
176 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
177 if (cgHandler) {
178 auto uid = appStateData.uid;
179 auto pid = appStateData.pid;
180 auto bundleName = appStateData.bundleName;
181 auto state = appStateData.state;
182
183 cgHandler->PostTask([cgHandler, uid, pid, bundleName, state] {
184 cgHandler->HandleApplicationStateChanged(uid, pid, bundleName, state);
185 });
186 }
187
188 nlohmann::json payload;
189 payload["pid"] = std::to_string(appStateData.pid);
190 payload["uid"] = std::to_string(appStateData.uid);
191 payload["bundleName"] = appStateData.bundleName;
192 ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_APP_STATE_CHANGE, appStateData.state, payload);
193 }
194 } // namespace ResourceSchedule
195 } // namespace OHOS
196