1 /*
2 * Copyright (c) 2022-2024 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 "ffrt.h"
24 #include "app_startup_scene_rec.h"
25 #include "supervisor.h"
26
27 #undef LOG_TAG
28 #define LOG_TAG "RmsAppStateObserver"
29
30 namespace OHOS {
31 namespace ResourceSchedule {
OnForegroundApplicationChanged(const AppStateData & appStateData)32 void RmsApplicationStateObserver::OnForegroundApplicationChanged(const AppStateData &appStateData)
33 {
34 if (!ValidateAppStateData(appStateData)) {
35 CGS_LOGE("%{public}s : validate app state data failed!", __func__);
36 return;
37 }
38 nlohmann::json payload;
39 payload["pid"] = std::to_string(appStateData.pid);
40 payload["uid"] = std::to_string(appStateData.uid);
41 payload["bundleName"] = appStateData.bundleName;
42 ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_APP_STATE_CHANGE, appStateData.state, payload);
43 }
44
OnAbilityStateChanged(const AbilityStateData & abilityStateData)45 void RmsApplicationStateObserver::OnAbilityStateChanged(const AbilityStateData &abilityStateData)
46 {
47 if (!ValidateAbilityStateData(abilityStateData)) {
48 CGS_LOGE("%{public}s : validate ability state data failed!", __func__);
49 return;
50 }
51 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
52 std::string bundleName = abilityStateData.bundleName;
53 int32_t abilityState = abilityStateData.abilityState;
54 if (cgHandler) {
55 auto uid = abilityStateData.uid;
56 auto pid = abilityStateData.pid;
57 auto abilityName = abilityStateData.abilityName;
58 auto token = reinterpret_cast<uintptr_t>(abilityStateData.token.GetRefPtr());
59 auto abilityType = abilityStateData.abilityType;
60
61 cgHandler->PostTask([cgHandler, uid, pid, bundleName, abilityName, token, abilityState, abilityType] {
62 cgHandler->HandleAbilityStateChanged(uid, pid, bundleName, abilityName,
63 token, abilityState, abilityType);
64 });
65 }
66
67 nlohmann::json payload;
68 std::string uid = std::to_string(abilityStateData.uid);
69 payload["pid"] = std::to_string(abilityStateData.pid);
70 payload["uid"] = uid;
71 payload["bundleName"] = bundleName;
72 ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_ABILITY_STATE_CHANGE,
73 abilityState, payload);
74 ffrt::submit([abilityState, uid, bundleName, this]() {
75 AppStartupSceneRec::GetInstance().RecordIsContinuousStartup(
76 abilityState, uid, bundleName);
77 });
78 }
79
OnExtensionStateChanged(const AbilityStateData & abilityStateData)80 void RmsApplicationStateObserver::OnExtensionStateChanged(const AbilityStateData &abilityStateData)
81 {
82 if (!ValidateAbilityStateData(abilityStateData)) {
83 CGS_LOGE("%{public}s : validate extension state data failed!", __func__);
84 return;
85 }
86 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
87 if (cgHandler) {
88 auto uid = abilityStateData.uid;
89 auto pid = abilityStateData.pid;
90 auto bundleName = abilityStateData.bundleName;
91 auto abilityName = abilityStateData.abilityName;
92 auto token = reinterpret_cast<uintptr_t>(abilityStateData.token.GetRefPtr());
93 auto abilityState = abilityStateData.abilityState;
94 auto abilityType = abilityStateData.abilityType;
95
96 cgHandler->PostTask([cgHandler, uid, pid, bundleName, abilityName, token, abilityState, abilityType] {
97 cgHandler->HandleExtensionStateChanged(uid, pid, bundleName, abilityName,
98 token, abilityState, abilityType);
99 });
100 }
101
102 nlohmann::json payload;
103 payload["pid"] = std::to_string(abilityStateData.pid);
104 payload["uid"] = std::to_string(abilityStateData.uid);
105 payload["bundleName"] = abilityStateData.bundleName;
106 ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_EXTENSION_STATE_CHANGE,
107 abilityStateData.abilityState, payload);
108 }
109
MarshallingProcessData(const ProcessData & processData,nlohmann::json & payload)110 void RmsApplicationStateObserver::MarshallingProcessData(const ProcessData &processData, nlohmann::json &payload)
111 {
112 payload["pid"] = std::to_string(processData.pid);
113 payload["uid"] = std::to_string(processData.uid);
114 payload["processType"] = std::to_string(static_cast<int32_t>(processData.processType));
115 payload["renderUid"] = std::to_string(processData.renderUid);
116 payload["bundleName"] = processData.bundleName;
117 payload["state"] = std::to_string(static_cast<uint32_t>(processData.state));
118 payload["extensionType"] = std::to_string(static_cast<uint32_t>(processData.extensionType));
119 payload["isKeepAlive"] = std::to_string(processData.isKeepAlive);
120 payload["isTestMode"] = std::to_string(processData.isTestMode);
121 payload["processName"] = processData.processName;
122 payload["exitReason"] = std::to_string(processData.exitReason);
123 payload["hostPid"] = std::to_string(processData.hostPid);
124 }
125
OnProcessCreated(const ProcessData & processData)126 void RmsApplicationStateObserver::OnProcessCreated(const ProcessData &processData)
127 {
128 if (!ValidateProcessData(processData)) {
129 CGS_LOGE("%{public}s : validate process data failed!", __func__);
130 return;
131 }
132 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
133 if (cgHandler) {
134 auto uid = processData.uid;
135 auto pid = processData.pid;
136 auto hostPid = processData.hostPid;
137 auto bundleName = processData.bundleName;
138 auto processType = static_cast<int32_t>(processData.processType);
139 auto extensionType = static_cast<int32_t>(processData.extensionType);
140 cgHandler->PostTask([cgHandler, uid, pid, hostPid, processType, bundleName, extensionType] {
141 cgHandler->HandleProcessCreated(uid, pid, hostPid, processType, bundleName, extensionType);
142 });
143 }
144
145 nlohmann::json payload;
146 MarshallingProcessData(processData, payload);
147 ResSchedUtils::GetInstance().ReportDataInProcess(
148 ResType::RES_TYPE_PROCESS_STATE_CHANGE, ResType::ProcessStatus::PROCESS_CREATED, payload);
149 }
150
OnProcessDied(const ProcessData & processData)151 void RmsApplicationStateObserver::OnProcessDied(const ProcessData &processData)
152 {
153 if (!ValidateProcessData(processData)) {
154 CGS_LOGE("%{public}s : validate process data failed!", __func__);
155 return;
156 }
157 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
158 if (cgHandler) {
159 auto uid = processData.uid;
160 auto pid = processData.pid;
161 auto bundleName = processData.bundleName;
162
163 cgHandler->PostTask([cgHandler, uid, pid, bundleName] {
164 cgHandler->HandleProcessDied(uid, pid, bundleName);
165 });
166 }
167
168 nlohmann::json payload;
169 MarshallingProcessData(processData, payload);
170 ResSchedUtils::GetInstance().ReportDataInProcess(
171 ResType::RES_TYPE_PROCESS_STATE_CHANGE, ResType::ProcessStatus::PROCESS_DIED, payload);
172 }
173
OnApplicationStateChanged(const AppStateData & appStateData)174 void RmsApplicationStateObserver::OnApplicationStateChanged(const AppStateData &appStateData)
175 {
176 if (!ValidateAppStateData(appStateData)) {
177 CGS_LOGE("%{public}s : validate app state data failed!", __func__);
178 return;
179 }
180
181 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
182 if (cgHandler) {
183 auto uid = appStateData.uid;
184 auto pid = appStateData.pid;
185 auto bundleName = appStateData.bundleName;
186 auto state = appStateData.state;
187
188 cgHandler->PostTask([cgHandler, uid, pid, bundleName, state] {
189 cgHandler->HandleApplicationStateChanged(uid, pid, bundleName, state);
190 });
191 }
192
193 nlohmann::json payload;
194 payload["pid"] = std::to_string(appStateData.pid);
195 payload["uid"] = std::to_string(appStateData.uid);
196 payload["bundleName"] = appStateData.bundleName;
197 payload["extensionType"] = std::to_string(static_cast<uint32_t>(appStateData.extensionType));
198 ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_APP_STATE_CHANGE, appStateData.state, payload);
199 ResSchedUtils::GetInstance().ReportAppStateInProcess(appStateData.state, appStateData.pid);
200 }
201
MarshallingAppStateData(const AppStateData & appStateData,nlohmann::json & payload)202 void RmsApplicationStateObserver::MarshallingAppStateData(const AppStateData &appStateData, nlohmann::json &payload)
203 {
204 payload["pid"] = appStateData.pid;
205 payload["uid"] = appStateData.uid;
206 payload["bundleName"] = appStateData.bundleName;
207 payload["state"] = static_cast<uint32_t>(appStateData.state);
208 payload["extensionType"] = static_cast<uint32_t>(appStateData.extensionType);
209 payload["isFocused"] = static_cast<bool>(appStateData.isFocused);
210 }
211
OnAppStateChanged(const AppStateData & appStateData)212 void RmsApplicationStateObserver::OnAppStateChanged(const AppStateData &appStateData)
213 {
214 if (!ValidateAppStateData(appStateData)) {
215 CGS_LOGE("%{public}s : validate app state data failed!", __func__);
216 return;
217 }
218
219 nlohmann::json payload;
220 MarshallingAppStateData(appStateData, payload);
221 ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_ON_APP_STATE_CHANGED, appStateData.state,
222 payload);
223 ResSchedUtils::GetInstance().ReportAppStateInProcess(appStateData.state, appStateData.pid);
224 }
225
OnAppCacheStateChanged(const AppStateData & appStateData)226 void RmsApplicationStateObserver::OnAppCacheStateChanged(const AppStateData &appStateData)
227 {
228 if (!ValidateAppStateData(appStateData)) {
229 CGS_LOGE("%{public}s : validate app state data failed!", __func__);
230 return;
231 }
232
233 nlohmann::json payload;
234 MarshallingAppStateData(appStateData, payload);
235 const int RES_TYPE_EXT_ON_APP_CACHED_STATE_CHANGED = 10008;
236 payload["extType"] = std::to_string(RES_TYPE_EXT_ON_APP_CACHED_STATE_CHANGED);
237 ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_KEY_PERF_SCENE, appStateData.state, payload);
238 }
239
OnProcessStateChanged(const ProcessData & processData)240 void RmsApplicationStateObserver::OnProcessStateChanged(const ProcessData &processData)
241 {
242 if (!ValidateProcessData(processData)) {
243 CGS_LOGE("%{public}s : validate process data failed!", __func__);
244 return;
245 }
246 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
247 if (cgHandler) {
248 auto uid = processData.uid;
249 auto pid = processData.pid;
250 auto bundleName = processData.bundleName;
251 auto state = static_cast<int32_t>(processData.state);
252
253 cgHandler->PostTask([cgHandler, uid, pid, bundleName, state] {
254 cgHandler->HandleProcessStateChanged(uid, pid, bundleName, state);
255 });
256 }
257
258 nlohmann::json payload;
259 MarshallingProcessData(processData, payload);
260 ResSchedUtils::GetInstance().ReportDataInProcess(
261 ResType::RES_TYPE_PROCESS_STATE_CHANGE, static_cast<int32_t>(processData.state), payload);
262 }
263
OnAppStopped(const AppStateData & appStateData)264 void RmsApplicationStateObserver::OnAppStopped(const AppStateData &appStateData)
265 {
266 if (!ValidateAppStateData(appStateData)) {
267 CGS_LOGE("%{public}s : validate app state data failed!", __func__);
268 return;
269 }
270
271 auto cgHandler = SchedController::GetInstance().GetCgroupEventHandler();
272 if (cgHandler) {
273 auto uid = appStateData.uid;
274 auto bundleName = appStateData.bundleName;
275
276 cgHandler->PostTask([cgHandler, uid, bundleName] {
277 cgHandler->HandleOnAppStopped(uid, bundleName);
278 });
279 }
280
281 nlohmann::json payload;
282 MarshallingAppStateData(appStateData, payload);
283 ResSchedUtils::GetInstance().ReportDataInProcess(ResType::RES_TYPE_APP_STOPPED, appStateData.state, payload);
284 }
285 } // namespace ResourceSchedule
286 } // namespace OHOS
287