1/*
2 * Copyright (c) 2021-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_lifecycle_deal.h"
17
18#include "freeze_util.h"
19#include "hilog_tag_wrapper.h"
20#include "hitrace_meter.h"
21#include "time_util.h"
22#include "app_mgr_service_const.h"
23#include "app_mgr_service_dump_error_code.h"
24
25namespace OHOS {
26using AbilityRuntime::FreezeUtil;
27namespace AppExecFwk {
28AppLifeCycleDeal::AppLifeCycleDeal()
29{}
30
31AppLifeCycleDeal::~AppLifeCycleDeal()
32{
33    TAG_LOGD(AAFwkTag::APPMGR, "called");
34}
35
36void AppLifeCycleDeal::LaunchApplication(const AppLaunchData &launchData, const Configuration &config)
37{
38    HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
39    TAG_LOGD(AAFwkTag::APPMGR, "called");
40    auto appThread = GetApplicationClient();
41    if (appThread) {
42        appThread->ScheduleLaunchApplication(launchData, config);
43    }
44}
45
46void AppLifeCycleDeal::UpdateApplicationInfoInstalled(const ApplicationInfo &appInfo)
47{
48    auto appThread = GetApplicationClient();
49    if (!appThread) {
50        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
51        return;
52    }
53
54    appThread->ScheduleUpdateApplicationInfoInstalled(appInfo);
55}
56
57void AppLifeCycleDeal::AddAbilityStage(const HapModuleInfo &abilityStage)
58{
59    auto appThread = GetApplicationClient();
60    if (!appThread) {
61        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
62        return;
63    }
64
65    appThread->ScheduleAbilityStage(abilityStage);
66}
67
68void AppLifeCycleDeal::LaunchAbility(const std::shared_ptr<AbilityRunningRecord> &ability)
69{
70    auto appThread = GetApplicationClient();
71    if (appThread && ability) {
72        auto abilityInfo = ability->GetAbilityInfo();
73        if (abilityInfo == nullptr) {
74            TAG_LOGW(AAFwkTag::APPMGR, "null abilityInfo");
75            return;
76        }
77        if (abilityInfo->type == AbilityType::PAGE) {
78            FreezeUtil::LifecycleFlow flow = {ability->GetToken(), FreezeUtil::TimeoutState::LOAD};
79            std::string entry = "AppLifeCycleDeal::LaunchAbility; the LoadAbility lifecycle.";
80            FreezeUtil::GetInstance().AddLifecycleEvent(flow, entry);
81        }
82        TAG_LOGD(AAFwkTag::APPMGR, "Launch");
83        appThread->ScheduleLaunchAbility(*abilityInfo, ability->GetToken(),
84            ability->GetWant(), ability->GetAbilityRecordId());
85    } else {
86        TAG_LOGW(AAFwkTag::APPMGR, "null appThread or ability");
87    }
88}
89
90void AppLifeCycleDeal::ScheduleTerminate(bool isLastProcess)
91{
92    auto appThread = GetApplicationClient();
93    if (!appThread) {
94        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
95        return;
96    }
97
98    appThread->ScheduleTerminateApplication(isLastProcess);
99}
100
101bool AppLifeCycleDeal::ScheduleForegroundRunning()
102{
103    auto appThread = GetApplicationClient();
104    if (!appThread) {
105        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
106        return false;
107    }
108
109    HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
110    return appThread->ScheduleForegroundApplication();
111}
112
113void AppLifeCycleDeal::ScheduleBackgroundRunning()
114{
115    auto appThread = GetApplicationClient();
116    if (!appThread) {
117        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
118        return;
119    }
120
121    appThread->ScheduleBackgroundApplication();
122}
123
124void AppLifeCycleDeal::ScheduleTrimMemory(int32_t timeLevel)
125{
126    auto appThread = GetApplicationClient();
127    if (!appThread) {
128        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
129        return;
130    }
131
132    appThread->ScheduleShrinkMemory(timeLevel);
133}
134
135void AppLifeCycleDeal::ScheduleMemoryLevel(int32_t Level)
136{
137    auto appThread = GetApplicationClient();
138    if (!appThread) {
139        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
140        return;
141    }
142
143    appThread->ScheduleMemoryLevel(Level);
144}
145
146void AppLifeCycleDeal::ScheduleHeapMemory(const int32_t pid, OHOS::AppExecFwk::MallocInfo &mallocInfo)
147{
148    auto appThread = GetApplicationClient();
149    if (!appThread) {
150        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
151        return;
152    }
153
154    appThread->ScheduleHeapMemory(pid, mallocInfo);
155}
156
157void AppLifeCycleDeal::ScheduleJsHeapMemory(OHOS::AppExecFwk::JsHeapDumpInfo &info)
158{
159    auto appThread = GetApplicationClient();
160    if (!appThread) {
161        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
162        return;
163    }
164
165    appThread->ScheduleJsHeapMemory(info);
166}
167
168void AppLifeCycleDeal::LowMemoryWarning()
169{
170    auto appThread = GetApplicationClient();
171    if (!appThread) {
172        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
173        return;
174    }
175
176    appThread->ScheduleLowMemory();
177}
178
179void AppLifeCycleDeal::ScheduleCleanAbility(const sptr<IRemoteObject> &token, bool isCacheProcess)
180{
181    auto appThread = GetApplicationClient();
182    if (!appThread) {
183        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
184        return;
185    }
186    appThread->ScheduleCleanAbility(token, isCacheProcess);
187}
188
189void AppLifeCycleDeal::ScheduleProcessSecurityExit()
190{
191    auto appThread = GetApplicationClient();
192    if (!appThread) {
193        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
194        return;
195    }
196
197    appThread->ScheduleProcessSecurityExit();
198}
199
200void AppLifeCycleDeal::ScheduleClearPageStack()
201{
202    auto appThread = GetApplicationClient();
203    if (!appThread) {
204        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
205        return;
206    }
207
208    appThread->ScheduleClearPageStack();
209}
210
211void AppLifeCycleDeal::SetApplicationClient(const sptr<IAppScheduler> &thread)
212{
213    std::lock_guard guard(schedulerMutex_);
214    appThread_ = thread;
215}
216
217sptr<IAppScheduler> AppLifeCycleDeal::GetApplicationClient() const
218{
219    std::lock_guard guard(schedulerMutex_);
220    return appThread_;
221}
222
223void AppLifeCycleDeal::ScheduleAcceptWant(const AAFwk::Want &want, const std::string &moduleName)
224{
225    auto appThread = GetApplicationClient();
226    if (!appThread) {
227        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
228        return;
229    }
230
231    appThread->ScheduleAcceptWant(want, moduleName);
232}
233
234void AppLifeCycleDeal::ScheduleNewProcessRequest(const AAFwk::Want &want, const std::string &moduleName)
235{
236    auto appThread = GetApplicationClient();
237    if (!appThread) {
238        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
239        return;
240    }
241
242    appThread->ScheduleNewProcessRequest(want, moduleName);
243}
244
245int32_t AppLifeCycleDeal::UpdateConfiguration(const Configuration &config)
246{
247    HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
248    TAG_LOGD(AAFwkTag::APPMGR, "call");
249    auto appThread = GetApplicationClient();
250    if (!appThread) {
251        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
252        return ERR_INVALID_VALUE;
253    }
254    appThread->ScheduleConfigurationUpdated(config);
255    return ERR_OK;
256}
257
258int32_t AppLifeCycleDeal::NotifyLoadRepairPatch(const std::string &bundleName, const sptr<IQuickFixCallback> &callback,
259    const int32_t recordId)
260{
261    HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
262    TAG_LOGD(AAFwkTag::APPMGR, "call");
263    auto appThread = GetApplicationClient();
264    if (appThread == nullptr) {
265        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
266        return ERR_INVALID_VALUE;
267    }
268    return appThread->ScheduleNotifyLoadRepairPatch(bundleName, callback, recordId);
269}
270
271int32_t AppLifeCycleDeal::NotifyHotReloadPage(const sptr<IQuickFixCallback> &callback, const int32_t recordId)
272{
273    HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
274    TAG_LOGD(AAFwkTag::APPMGR, "call");
275    auto appThread = GetApplicationClient();
276    if (appThread == nullptr) {
277        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
278        return ERR_INVALID_VALUE;
279    }
280    return appThread->ScheduleNotifyHotReloadPage(callback, recordId);
281}
282
283int32_t AppLifeCycleDeal::NotifyUnLoadRepairPatch(const std::string &bundleName,
284    const sptr<IQuickFixCallback> &callback, const int32_t recordId)
285{
286    HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
287    TAG_LOGD(AAFwkTag::APPMGR, "called");
288    auto appThread = GetApplicationClient();
289    if (appThread == nullptr) {
290        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
291        return ERR_INVALID_VALUE;
292    }
293    return appThread->ScheduleNotifyUnLoadRepairPatch(bundleName, callback, recordId);
294}
295
296int32_t AppLifeCycleDeal::NotifyAppFault(const FaultData &faultData)
297{
298    TAG_LOGD(AAFwkTag::APPMGR, "called");
299    auto appThread = GetApplicationClient();
300    if (appThread == nullptr) {
301        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
302        return ERR_INVALID_VALUE;
303    }
304    return appThread->ScheduleNotifyAppFault(faultData);
305}
306
307int32_t AppLifeCycleDeal::ChangeAppGcState(int32_t state)
308{
309    TAG_LOGD(AAFwkTag::APPMGR, "called");
310    auto appThread = GetApplicationClient();
311    if (appThread == nullptr) {
312        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
313        return ERR_INVALID_VALUE;
314    }
315    return appThread->ScheduleChangeAppGcState(state);
316}
317
318int32_t AppLifeCycleDeal::AttachAppDebug()
319{
320    TAG_LOGD(AAFwkTag::APPMGR, "called");
321    auto appThread = GetApplicationClient();
322    if (appThread == nullptr) {
323        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
324        return ERR_INVALID_VALUE;
325    }
326    appThread->AttachAppDebug();
327    return ERR_OK;
328}
329
330int32_t AppLifeCycleDeal::DetachAppDebug()
331{
332    TAG_LOGD(AAFwkTag::APPMGR, "called");
333    auto appThread = GetApplicationClient();
334    if (appThread == nullptr) {
335        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
336        return ERR_INVALID_VALUE;
337    }
338    appThread->DetachAppDebug();
339    return ERR_OK;
340}
341
342int AppLifeCycleDeal::DumpIpcStart(std::string& result)
343{
344    TAG_LOGD(AAFwkTag::APPMGR, "called");
345    auto appThread = GetApplicationClient();
346    if (appThread == nullptr) {
347        result.append(MSG_DUMP_IPC_START_STAT, strlen(MSG_DUMP_IPC_START_STAT))
348            .append(MSG_DUMP_FAIL, strlen(MSG_DUMP_FAIL))
349            .append(MSG_DUMP_FAIL_REASON_INTERNAL, strlen(MSG_DUMP_FAIL_REASON_INTERNAL));
350        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
351        return DumpErrorCode::ERR_INTERNAL_ERROR;
352    }
353    return appThread->ScheduleDumpIpcStart(result);
354}
355
356int AppLifeCycleDeal::DumpIpcStop(std::string& result)
357{
358    TAG_LOGD(AAFwkTag::APPMGR, "called");
359    auto appThread = GetApplicationClient();
360    if (appThread == nullptr) {
361        result.append(MSG_DUMP_IPC_STOP_STAT, strlen(MSG_DUMP_IPC_STOP_STAT))
362            .append(MSG_DUMP_FAIL, strlen(MSG_DUMP_FAIL))
363            .append(MSG_DUMP_FAIL_REASON_INTERNAL, strlen(MSG_DUMP_FAIL_REASON_INTERNAL));
364        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
365        return DumpErrorCode::ERR_INTERNAL_ERROR;
366    }
367    return appThread->ScheduleDumpIpcStop(result);
368}
369
370int AppLifeCycleDeal::DumpIpcStat(std::string& result)
371{
372    TAG_LOGD(AAFwkTag::APPMGR, "called");
373    auto appThread = GetApplicationClient();
374    if (appThread == nullptr) {
375        result.append(MSG_DUMP_IPC_STAT, strlen(MSG_DUMP_IPC_STAT))
376            .append(MSG_DUMP_FAIL, strlen(MSG_DUMP_FAIL))
377            .append(MSG_DUMP_FAIL_REASON_INTERNAL, strlen(MSG_DUMP_FAIL_REASON_INTERNAL));
378        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
379        return DumpErrorCode::ERR_INTERNAL_ERROR;
380    }
381    return appThread->ScheduleDumpIpcStat(result);
382}
383
384void AppLifeCycleDeal::ScheduleCacheProcess()
385{
386    auto appThread = GetApplicationClient();
387    if (!appThread) {
388        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
389        return;
390    }
391
392    appThread->ScheduleCacheProcess();
393}
394
395int AppLifeCycleDeal::DumpFfrt(std::string& result)
396{
397    TAG_LOGD(AAFwkTag::APPMGR, "called");
398    auto appThread = GetApplicationClient();
399    if (appThread == nullptr) {
400        result.append(MSG_DUMP_FAIL, strlen(MSG_DUMP_FAIL))
401            .append(MSG_DUMP_FAIL_REASON_INTERNAL, strlen(MSG_DUMP_FAIL_REASON_INTERNAL));
402        TAG_LOGE(AAFwkTag::APPMGR, "null appThread");
403        return DumpErrorCode::ERR_INTERNAL_ERROR;
404    }
405    return appThread->ScheduleDumpFfrt(result);
406}
407}  // namespace AppExecFwk
408}  // namespace OHOS
409