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 "app_startup_scene_rec.h"
19 #include "res_sched_log.h"
20 #include "res_sched_mgr.h"
21 #include "res_type.h"
22 #include "ui_extension_utils.h"
23
24 #undef LOG_TAG
25 #define LOG_TAG "RmsAppStateObserver"
26
27 namespace OHOS {
28 namespace ResourceSchedule {
29
30 std::unordered_map<int32_t, int32_t> RmsApplicationStateObserver::extensionStateToAbilityState_ = {
31 {static_cast<int32_t>(AppExecFwk::ExtensionState::EXTENSION_STATE_CREATE),
32 static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_CREATE)},
33 {static_cast<int32_t>(AppExecFwk::ExtensionState::EXTENSION_STATE_READY),
34 static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_READY)},
35 {static_cast<int32_t>(AppExecFwk::ExtensionState::EXTENSION_STATE_CONNECTED),
36 static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_CONNECTED)},
37 {static_cast<int32_t>(AppExecFwk::ExtensionState::EXTENSION_STATE_DISCONNECTED),
38 static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_DISCONNECTED)},
39 {static_cast<int32_t>(AppExecFwk::ExtensionState::EXTENSION_STATE_TERMINATED),
40 static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_TERMINATED)},
41 {static_cast<int32_t>(AppExecFwk::ExtensionState::EXTENSION_STATE_FOREGROUND),
42 static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_FOREGROUND)},
43 {static_cast<int32_t>(AppExecFwk::ExtensionState::EXTENSION_STATE_BACKGROUND),
44 static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_BACKGROUND)},
45 };
46
OnForegroundApplicationChanged(const AppStateData & appStateData)47 void RmsApplicationStateObserver::OnForegroundApplicationChanged(const AppStateData &appStateData)
48 {
49 if (!ValidateAppStateData(appStateData)) {
50 RESSCHED_LOGE("%{public}s : validate app state data failed!", __func__);
51 return;
52 }
53 nlohmann::json payload;
54 payload["pid"] = std::to_string(appStateData.pid);
55 payload["uid"] = std::to_string(appStateData.uid);
56 payload["bundleName"] = appStateData.bundleName;
57 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_APP_STATE_CHANGE, appStateData.state, payload);
58 }
59
OnAbilityStateChanged(const AbilityStateData & abilityStateData)60 void RmsApplicationStateObserver::OnAbilityStateChanged(const AbilityStateData &abilityStateData)
61 {
62 if (!ValidateAbilityStateData(abilityStateData)) {
63 RESSCHED_LOGE("%{public}s : validate ability state data failed!", __func__);
64 return;
65 }
66
67 if (abilityStateData.isInnerNotify) {
68 RESSCHED_LOGD("%{public}s : Redundancy report dont need care!", __func__);
69 return;
70 }
71
72 int32_t abilityState = abilityStateData.abilityState;
73 nlohmann::json payload;
74
75 // if is uiExtension state changed, need to change extensionState to abilityState and write payload.
76 if (IsUIExtensionAbilityStateChanged(abilityStateData)) {
77 if (extensionStateToAbilityState_.find(abilityState) != extensionStateToAbilityState_.end()) {
78 abilityState = extensionStateToAbilityState_.at(abilityState);
79 payload["extensionAbilityType"] = std::to_string(abilityStateData.extensionAbilityType);
80 payload["processType"] = std::to_string(abilityStateData.processType);
81 payload["uiExtensionState"] = std::to_string(abilityStateData.abilityState);
82 } else {
83 RESSCHED_LOGE("%{public}s : abilityState trans to extensionState failed", __func__);
84 }
85 }
86
87 std::string uid = std::to_string(abilityStateData.uid);
88 std::string bundleName = abilityStateData.bundleName;
89
90 payload["pid"] = std::to_string(abilityStateData.pid);
91 payload["uid"] = uid;
92 payload["bundleName"] = bundleName;
93 payload["abilityName"] = abilityStateData.abilityName;
94 payload["recordId"] = std::to_string(abilityStateData.abilityRecordId);
95 payload["abilityType"] = std::to_string(abilityStateData.abilityType);
96 payload["abilityState"] = std::to_string(abilityState);
97
98 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_ABILITY_STATE_CHANGE,
99 abilityState, payload);
100 if (AppStartupSceneRec::GetInstance().IsAppStartUp(abilityState)) {
101 ffrt::submit([uid, bundleName]() {
102 AppStartupSceneRec::GetInstance().RecordIsContinuousStartup(uid, bundleName);
103 });
104 }
105 }
106
OnExtensionStateChanged(const AbilityStateData & abilityStateData)107 void RmsApplicationStateObserver::OnExtensionStateChanged(const AbilityStateData &abilityStateData)
108 {
109 if (!ValidateAbilityStateData(abilityStateData)) {
110 RESSCHED_LOGE("%{public}s : validate extension state data failed!", __func__);
111 return;
112 }
113
114 // if current is uiExtension, goto onAbilityStateChanged and report
115 if (IsUIExtensionAbilityStateChanged(abilityStateData)) {
116 RESSCHED_LOGD("UIExtensionAbility Changed, extensionType: %{public}d, bundleName: %{public}s,"
117 " abilityRecordId: %{public}d, abilityState: %{public}d, processType: %{public}d",
118 abilityStateData.extensionAbilityType, abilityStateData.bundleName.c_str(),
119 abilityStateData.abilityRecordId, abilityStateData.abilityState, abilityStateData.processType);
120 OnAbilityStateChanged(abilityStateData);
121 return;
122 }
123
124 nlohmann::json payload;
125 payload["pid"] = std::to_string(abilityStateData.pid);
126 payload["uid"] = std::to_string(abilityStateData.uid);
127 payload["bundleName"] = abilityStateData.bundleName;
128 payload["abilityName"] = abilityStateData.abilityName;
129 payload["recordId"] = std::to_string(abilityStateData.abilityRecordId);
130 payload["extensionState"] = std::to_string(abilityStateData.abilityState);
131 payload["abilityType"] = std::to_string(abilityStateData.abilityType);
132 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_EXTENSION_STATE_CHANGE,
133 abilityStateData.abilityState, payload);
134 }
135
IsUIExtensionAbilityStateChanged(const AbilityStateData & abilityStateData)136 bool RmsApplicationStateObserver::IsUIExtensionAbilityStateChanged(const AbilityStateData &abilityStateData)
137 {
138 if (!ValidateUIExtensionAbilityStateData(abilityStateData)) {
139 RESSCHED_LOGD("%{public}s : Validate UIExtensionAbility state data failed!", __func__);
140 return false;
141 }
142 if (extensionStateToAbilityState_.find(abilityStateData.abilityState) == extensionStateToAbilityState_.end()) {
143 RESSCHED_LOGD("%{public}s : Validate UIExtensionAbility data out of bound!", __func__);
144 return false;
145 }
146
147 // trans int32_t to ExtensionAbilityType and check whether it is an UiExtensionAbility or an Extension
148 AppExecFwk::ExtensionAbilityType extType =
149 static_cast<AppExecFwk::ExtensionAbilityType>(abilityStateData.extensionAbilityType);
150 if (!AAFwk::UIExtensionUtils::IsUIExtension(extType)) {
151 RESSCHED_LOGD("%{public}s : Current is not a UIExtensionAbility!", __func__);
152 return false;
153 }
154
155 return true;
156 }
157
MarshallingProcessData(const ProcessData & processData,nlohmann::json & payload)158 void RmsApplicationStateObserver::MarshallingProcessData(const ProcessData &processData, nlohmann::json &payload)
159 {
160 payload["pid"] = std::to_string(processData.pid);
161 payload["uid"] = std::to_string(processData.uid);
162 payload["processType"] = std::to_string(static_cast<int32_t>(processData.processType));
163 payload["renderUid"] = std::to_string(processData.renderUid);
164 payload["bundleName"] = processData.bundleName;
165 payload["state"] = std::to_string(static_cast<uint32_t>(processData.state));
166 payload["extensionType"] = std::to_string(static_cast<uint32_t>(processData.extensionType));
167 payload["isKeepAlive"] = std::to_string(processData.isKeepAlive);
168 payload["isTestMode"] = std::to_string(processData.isTestMode);
169 payload["processName"] = processData.processName;
170 payload["hostPid"] = std::to_string(processData.hostPid);
171 payload["callerPid"] = std::to_string(processData.callerPid);
172 payload["callerUid"] = std::to_string(processData.callerUid);
173 payload["killReason"] = processData.killReason;
174 payload["isPreloadModule"] = std::to_string(processData.isPreloadModule);
175 }
176
OnProcessCreated(const ProcessData & processData)177 void RmsApplicationStateObserver::OnProcessCreated(const ProcessData &processData)
178 {
179 if (!ValidateProcessData(processData)) {
180 RESSCHED_LOGE("%{public}s : validate process data failed!", __func__);
181 return;
182 }
183
184 nlohmann::json payload;
185 MarshallingProcessData(processData, payload);
186 ResSchedMgr::GetInstance().ReportData(
187 ResType::RES_TYPE_PROCESS_STATE_CHANGE, ResType::ProcessStatus::PROCESS_CREATED, payload);
188 }
189
OnProcessDied(const ProcessData & processData)190 void RmsApplicationStateObserver::OnProcessDied(const ProcessData &processData)
191 {
192 if (!ValidateProcessData(processData)) {
193 RESSCHED_LOGE("%{public}s : validate process data failed!", __func__);
194 return;
195 }
196
197 nlohmann::json payload;
198 MarshallingProcessData(processData, payload);
199 ResSchedMgr::GetInstance().ReportData(
200 ResType::RES_TYPE_PROCESS_STATE_CHANGE, ResType::ProcessStatus::PROCESS_DIED, payload);
201 ResSchedMgr::GetInstance().ReportProcessStateInProcess((int32_t)ResType::ProcessStatus::PROCESS_DIED,
202 (int32_t)processData.pid);
203 }
204
OnApplicationStateChanged(const AppStateData & appStateData)205 void RmsApplicationStateObserver::OnApplicationStateChanged(const AppStateData &appStateData)
206 {
207 if (!ValidateAppStateData(appStateData)) {
208 RESSCHED_LOGE("%{public}s : validate app state data failed!", __func__);
209 return;
210 }
211
212 nlohmann::json payload;
213 payload["pid"] = std::to_string(appStateData.pid);
214 payload["uid"] = std::to_string(appStateData.uid);
215 payload["bundleName"] = appStateData.bundleName;
216 payload["extensionType"] = std::to_string(static_cast<uint32_t>(appStateData.extensionType));
217 payload["isPreload"] = std::to_string(appStateData.isPreloadModule);
218 payload["state"] = std::to_string(appStateData.state);
219 payload["callerBundleName"] = appStateData.callerBundleName;
220 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_APP_STATE_CHANGE, appStateData.state,
221 payload);
222 ResSchedMgr::GetInstance().ReportAppStateInProcess(appStateData.state, appStateData.pid);
223 }
224
MarshallingAppStateData(const AppStateData & appStateData,nlohmann::json & payload)225 void RmsApplicationStateObserver::MarshallingAppStateData(const AppStateData &appStateData, nlohmann::json &payload)
226 {
227 payload["pid"] = appStateData.pid;
228 payload["uid"] = appStateData.uid;
229 payload["bundleName"] = appStateData.bundleName;
230 payload["state"] = static_cast<uint32_t>(appStateData.state);
231 payload["extensionType"] = static_cast<uint32_t>(appStateData.extensionType);
232 payload["isFocused"] = static_cast<bool>(appStateData.isFocused);
233 }
234
OnAppStateChanged(const AppStateData & appStateData)235 void RmsApplicationStateObserver::OnAppStateChanged(const AppStateData &appStateData)
236 {
237 if (!ValidateAppStateData(appStateData)) {
238 RESSCHED_LOGE("%{public}s : validate app state data failed!", __func__);
239 return;
240 }
241
242 nlohmann::json payload;
243 MarshallingAppStateData(appStateData, payload);
244 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_ON_APP_STATE_CHANGED, appStateData.state,
245 payload);
246 ResSchedMgr::GetInstance().ReportAppStateInProcess(appStateData.state, appStateData.pid);
247 }
248
OnAppCacheStateChanged(const AppStateData & appStateData)249 void RmsApplicationStateObserver::OnAppCacheStateChanged(const AppStateData &appStateData)
250 {
251 if (!ValidateAppStateData(appStateData)) {
252 RESSCHED_LOGE("%{public}s : validate app state data failed!", __func__);
253 return;
254 }
255
256 nlohmann::json payload;
257 MarshallingAppStateData(appStateData, payload);
258 const int RES_TYPE_EXT_ON_APP_CACHED_STATE_CHANGED = 10008;
259 payload["extType"] = std::to_string(RES_TYPE_EXT_ON_APP_CACHED_STATE_CHANGED);
260 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_KEY_PERF_SCENE, appStateData.state, payload);
261 }
262
MarshallingPreForegroundData(const PreloadProcessData & data,nlohmann::json & payload)263 void RmsApplicationStateObserver::MarshallingPreForegroundData(const PreloadProcessData &data, nlohmann::json &payload)
264 {
265 payload["isPreForeground"] = data.isPreForeground;
266 payload["pid"] = data.pid;
267 payload["uid"] = data.uid;
268 payload["bundleName"] = data.bundleName;
269 }
270
OnProcessPreForegroundChanged(const PreloadProcessData & data)271 void RmsApplicationStateObserver::OnProcessPreForegroundChanged(const PreloadProcessData &data)
272 {
273 if (data.uid <= 0 || data.pid <= 0) {
274 RESSCHED_LOGE("%{public}s: invalid data %{public}d_%{public}d", __func__, data.uid, data.pid);
275 return;
276 }
277
278 nlohmann::json payload;
279 MarshallingPreForegroundData(data, payload);
280 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_PROCESS_PRE_FOREGROUND_CHANGE, 0, payload);
281 }
282
OnProcessStateChanged(const ProcessData & processData)283 void RmsApplicationStateObserver::OnProcessStateChanged(const ProcessData &processData)
284 {
285 if (!ValidateProcessData(processData)) {
286 RESSCHED_LOGE("%{public}s : validate process data failed!", __func__);
287 return;
288 }
289
290 nlohmann::json payload;
291 MarshallingProcessData(processData, payload);
292 ResSchedMgr::GetInstance().ReportData(
293 ResType::RES_TYPE_PROCESS_STATE_CHANGE, static_cast<int32_t>(processData.state), payload);
294 ResSchedMgr::GetInstance().ReportProcessStateInProcess((int32_t)processData.state, (int32_t)processData.pid);
295 }
296
OnAppStopped(const AppStateData & appStateData)297 void RmsApplicationStateObserver::OnAppStopped(const AppStateData &appStateData)
298 {
299 if (!ValidateAppStateData(appStateData)) {
300 RESSCHED_LOGE("%{public}s : validate app state data failed!", __func__);
301 return;
302 }
303
304 nlohmann::json payload;
305 MarshallingAppStateData(appStateData, payload);
306 ResSchedMgr::GetInstance().ReportData(ResType::RES_TYPE_APP_STOPPED, appStateData.state, payload);
307 }
308 } // namespace ResourceSchedule
309 } // namespace OHOS
310