• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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