1 /*
2  * Copyright (c) 2020 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 "ability_record_manager.h"
17 #include "aafwk_event_error_id.h"
18 #include "aafwk_event_error_code.h"
19 #include "ability_errors.h"
20 #include "ability_inner_message.h"
21 #include "ability_lock_guard.h"
22 #include "ability_record.h"
23 #include "ability_record_observer_manager.h"
24 #include "ability_service_interface.h"
25 #include "ability_thread_loader.h"
26 #include "abilityms_log.h"
27 #include "ability_manager_inner.h"
28 #include "bms_helper.h"
29 #include "bundle_manager.h"
30 #include "cmsis_os.h"
31 #ifdef OHOS_DMS_ENABLED
32 #include "dmsfwk_interface.h"
33 #endif
34 #include "js_ability_thread.h"
35 #include "los_task.h"
36 #ifdef OHOS_DMS_ENABLED
37 #include "samgr_lite.h"
38 #endif
39 #include "slite_ability.h"
40 #include "utils.h"
41 #include "want.h"
42 
43 using namespace OHOS::ACELite;
44 
45 namespace OHOS {
46 namespace AbilitySlite {
47 constexpr int32_t QUEUE_LENGTH = 32;
48 constexpr int32_t APP_TASK_PRI = 25;
49 
50 AbilityRecordManager::AbilityRecordManager() = default;
51 
~AbilityRecordManager()52 AbilityRecordManager::~AbilityRecordManager()
53 {
54     DeleteRecordInfo(LAUNCHER_TOKEN);
55 }
56 
StartLauncher()57 void AbilityRecordManager::StartLauncher()
58 {
59     AbilityRecord *launcherRecord = abilityList_.Get(LAUNCHER_TOKEN);
60     if (launcherRecord != nullptr) {
61         return;
62     }
63 
64 #ifndef _MINI_MULTI_TASKS_
65     auto record = new AbilityRecord();
66     record->SetAppName(LAUNCHER_BUNDLE_NAME);
67     record->token = LAUNCHER_TOKEN;
68     record->isNativeApp = true;
69     record->state = SCHEDULE_FOREGROUND;
70     record->taskId = LOS_CurTaskIDGet();
71     abilityList_.Add(record);
72     (void)ScheduleLifecycleInner(record, SLITE_STATE_FOREGROUND);
73 #else // define _MINI_MULTI_TASKS_
74     Want *want = static_cast<Want *>(AdapterMalloc(sizeof(Want)));
75     if (want == nullptr) {
76         return;
77     }
78     want->data = nullptr;
79     want->dataLength = 0;
80     want->element = nullptr;
81     want->appPath = nullptr;
82     want->actions = nullptr;
83     want->entities = nullptr;
84     ElementName elementName = {};
85     SetElementBundleName(&elementName, BMSHelper::GetInstance().GetStartupBundleName());
86     SetWantElement(want, elementName);
87     ClearElement(&elementName);
88     StartAbility(want);
89     ClearWant(want);
90     AdapterFree(want);
91 #endif
92 }
93 
StartAbility(const AbilityRecord * record)94 int32_t AbilityRecordManager::StartAbility(const AbilityRecord *record)
95 {
96     if (record == nullptr) {
97         return PARAM_NULL_ERROR;
98     }
99     Want *want = static_cast<Want *>(AdapterMalloc(sizeof(Want)));
100     if (want == nullptr) {
101         return PARAM_NULL_ERROR;
102     }
103     want->data = nullptr;
104     want->dataLength = 0;
105     want->element = nullptr;
106     want->appPath = nullptr;
107     want->actions = nullptr;
108     want->entities = nullptr;
109     ElementName elementName = {};
110     if (record != nullptr) {
111         want->data = Utils::Memdup(record->abilityData->wantData, record->abilityData->wantDataSize);
112         want->dataLength = record->abilityData->wantDataSize;
113         want->appPath = Utils::Strdup(record->appPath);
114         SetElementBundleName(&elementName, record->appName);
115     }
116     SetWantElement(want, elementName);
117     ClearElement(&elementName);
118 
119     auto ret = StartAbility(want);
120     ClearWant(want);
121     if (ret != ERR_OK) {
122         HILOG_ERROR(HILOG_MODULE_AAFWK, "start ability failed [%{public}d]", ret);
123     }
124     AdapterFree(want);
125     return ret;
126 }
127 
IsLauncher(const char * bundleName)128 bool AbilityRecordManager::IsLauncher(const char *bundleName)
129 {
130     size_t len = strlen(bundleName);
131     const char* suffix = ".launcher";
132     size_t suffixLen = strlen(suffix);
133     if (len < suffixLen) {
134         return false;
135     }
136     return (strcmp(bundleName + len - suffixLen, suffix) == 0);
137 }
138 
StartRemoteAbility(const Want * want)139 int32_t AbilityRecordManager::StartRemoteAbility(const Want *want)
140 {
141 #ifdef OHOS_DMS_ENABLED
142     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(DISTRIBUTED_SCHEDULE_SERVICE, DMSLITE_FEATURE);
143     if (iUnknown == nullptr) {
144         HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to get distributed schedule service.");
145         return EC_INVALID;
146     }
147     DmsProxy *dmsInterface = nullptr;
148     int32_t retVal = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **) &dmsInterface);
149     if (retVal != EC_SUCCESS) {
150         HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to get DMS interface retVal: [%{public}d]", retVal);
151         return EC_INVALID;
152     }
153     AbilityRecord *record = abilityList_.GetByTaskId(curTask_);
154     if (record == nullptr) {
155         HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to get record by taskId.");
156         return PARAM_NULL_ERROR;
157     }
158     const char *callerBundleName = record->GetAppName();
159     if (callerBundleName == nullptr) {
160         HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to get callerBundleName.");
161         return PARAM_NULL_ERROR;
162     }
163 
164     CallerInfo callerInfo = {
165         .uid = 0,
166         .bundleName = OHOS::Utils::Strdup(callerBundleName)
167     };
168     retVal = dmsInterface->StartRemoteAbility(want, &callerInfo, nullptr);
169 
170     HILOG_INFO(HILOG_MODULE_AAFWK, "StartRemoteAbility retVal: [%{public}d]", retVal);
171     AdapterFree(callerInfo.bundleName);
172     return retVal;
173 #else
174     return PARAM_NULL_ERROR;
175 #endif
176 }
177 
StartAbility(const Want * want)178 int32_t AbilityRecordManager::StartAbility(const Want *want)
179 {
180     if (isAppScheduling_) {
181         return AddAbilityOperation(START_ABILITY, want, 0);
182     }
183     isAppScheduling_ = true;
184     if (want == nullptr || want->element == nullptr) {
185         isAppScheduling_ = false;
186         HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service wanted element is null");
187         return PARAM_NULL_ERROR;
188     }
189     char *bundleName = want->element->bundleName;
190     if (bundleName == nullptr) {
191         isAppScheduling_ = false;
192         HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service wanted bundleName is null");
193         return PARAM_NULL_ERROR;
194     }
195 
196 #ifdef OHOS_DMS_ENABLED
197     if (want->element->deviceId != nullptr && *(want->element->deviceId) != '\0') {
198         // deviceId is set
199         isAppScheduling_ = false;
200         return StartRemoteAbility(want);
201     }
202 #endif
203 
204 #ifdef _MINI_MULTI_TASKS_
205     AbilityRecord *abilityRecord = abilityList_.Get(bundleName);
206     if (abilityRecord != nullptr) {
207         auto topRecord = abilityList_.GetTopAbility();
208         if (topRecord == abilityRecord) {
209             isAppScheduling_ = false;
210             return ERR_OK;
211         }
212         if ((abilityRecord->isNativeApp == false) && !CheckResponse(bundleName)) {
213             HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service CheckResponse Failed.");
214             isAppScheduling_ = false;
215             return PARAM_CHECK_ERROR;
216         }
217         abilityRecord->SetWantData(want->data, want->dataLength);
218         if (want->mission != UINT32_MAX) {
219             abilityRecord->mission = want->mission;
220         }
221         abilityList_.MoveToTop(abilityRecord->token);
222         if (NeedToBeTerminated(topRecord->appName)) {
223             topRecord->isTerminated = true;
224         }
225         return SendMsgToAbilityThread(SLITE_STATE_BACKGROUND, topRecord);
226     }
227 #endif
228 
229     auto *info = static_cast<AbilitySvcInfo *>(AdapterMalloc(sizeof(AbilitySvcInfo)));
230     if (info == nullptr) {
231         isAppScheduling_ = false;
232         HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service AbilitySvcInfo is null");
233         return PARAM_NULL_ERROR;
234     }
235     uint8_t queryRet = BMSHelper::GetInstance().QueryAbilitySvcInfo(want, info);
236     if (queryRet != ERR_OK) {
237         isAppScheduling_ = false;
238         HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability BMS Helper return abilitySvcInfo failed");
239         AdapterFree(info);
240         return PARAM_CHECK_ERROR;
241     }
242 
243     info->data = OHOS::Utils::Memdup(want->data, want->dataLength);
244     info->dataLength = want->dataLength;
245     info->mission = want->mission;
246     auto ret = StartAbility(info);
247     BMSHelper::GetInstance().ClearAbilitySvcInfo(info);
248     AdapterFree(info->data);
249     AdapterFree(info);
250     return ret;
251 }
252 
253 #ifndef _MINI_MULTI_TASKS_
UpdateRecord(AbilitySvcInfo * info)254 void AbilityRecordManager::UpdateRecord(AbilitySvcInfo *info)
255 {
256     if (info == nullptr) {
257         return;
258     }
259     AbilityRecord *record = abilityList_.Get(info->bundleName);
260     if (record == nullptr) {
261         return;
262     }
263     if (record->token != LAUNCHER_TOKEN) {
264         return;
265     }
266     record->SetWantData(info->data, info->dataLength);
267 }
268 #endif // _MINI_MULTI_TASKS_
269 
StartAbility(AbilitySvcInfo * info)270 int32_t AbilityRecordManager::StartAbility(AbilitySvcInfo *info)
271 {
272     if ((info == nullptr) || (info->bundleName == nullptr) || (strlen(info->bundleName) == 0)) {
273         isAppScheduling_ = false;
274         return PARAM_NULL_ERROR;
275     }
276     HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility");
277 
278     auto topRecord = abilityList_.GetTopAbility();
279 #ifndef _MINI_MULTI_TASKS_
280     if ((topRecord == nullptr) || (topRecord->appName == nullptr)) {
281         isAppScheduling_ = false;
282         HILOG_ERROR(HILOG_MODULE_AAFWK, "StartAbility top null.");
283         return PARAM_NULL_ERROR;
284     }
285     uint16_t topToken = topRecord->token;
286     //  start launcher
287     if (IsLauncher(info->bundleName)) {
288         UpdateRecord(info);
289         if (topToken != LAUNCHER_TOKEN && topRecord->state != SCHEDULE_BACKGROUND) {
290             HILOG_INFO(HILOG_MODULE_AAFWK, "Change Js app to background.");
291             (void)ScheduleLifecycleInner(topRecord, SLITE_STATE_BACKGROUND);
292         } else {
293             (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND);
294         }
295         return ERR_OK;
296     }
297 
298     if ((info->isNativeApp == false) && !CheckResponse(info->bundleName)) {
299         isAppScheduling_ = false;
300         return PARAM_CHECK_ERROR;
301     }
302 
303     // start js app
304     if (topRecord->state != SCHEDULE_STOP && topRecord->token != LAUNCHER_TOKEN) {
305         // start app is top
306         if (strcmp(info->bundleName, topRecord->appName) == 0) {
307             if (topRecord->state == SCHEDULE_BACKGROUND) {
308                 HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility Resume app when background.");
309                 (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND);
310                 return ERR_OK;
311             }
312             HILOG_INFO(HILOG_MODULE_AAFWK, "Js app already started or starting.");
313         } else {
314             // js to js
315             HILOG_INFO(HILOG_MODULE_AAFWK, "Terminate pre js app when js to js");
316             TerminateAbility(topRecord->token);
317             pendingToken_ = GenerateToken();
318         }
319     }
320 
321     // application has not been launched and then to check priority and permission.
322     info->isNativeApp = false;
323     return PreCheckStartAbility(*info);
324 #else
325     if (topRecord == nullptr) {
326         if (strcmp(info->bundleName, BMSHelper::GetInstance().GetStartupBundleName()) != 0) {
327             HILOG_ERROR(HILOG_MODULE_AAFWK, "first ability should be launcher.");
328             return PARAM_CHECK_ERROR;
329         }
330         // start launcher when boot
331         return PreCheckStartAbility(*info);
332     }
333 
334     if ((info->isNativeApp == false) && !CheckResponse(info->bundleName)) {
335         return PARAM_CHECK_ERROR;
336     }
337 
338     // the topAbility needs to be transferred to background
339     // start topAbility
340     if (strcmp(info->bundleName, topRecord->appName) == 0) {
341         if (topRecord->state == SCHEDULE_STOP) {
342             CreateAppTask(const_cast<AbilityRecord *>(topRecord));
343         } else {
344             isAppScheduling_ = false;
345         }
346         return ERR_OK;
347     }
348     if (NeedToBeTerminated(topRecord->appName)) {
349         topRecord->isTerminated = true;
350     }
351     (void) SendMsgToAbilityThread(SLITE_STATE_BACKGROUND, topRecord);
352     pendingToken_ = GenerateToken();
353 
354     // application has not been launched and then to check priority and permission.
355     return PreCheckStartAbility(*info);
356 #endif
357 }
358 
TerminateAbility(uint16_t token)359 int32_t AbilityRecordManager::TerminateAbility(uint16_t token)
360 {
361     if (isAppScheduling_) {
362         return AddAbilityOperation(TERMINATE_ABILITY, nullptr, token);
363     }
364     isAppScheduling_ = true;
365     return TerminateAbility(token, nullptr);
366 }
367 
TerminateMission(uint32_t mission)368 int32_t AbilityRecordManager::TerminateMission(uint32_t mission)
369 {
370     if (isAppScheduling_) {
371         return AddAbilityOperation(TERMINATE_MISSION, nullptr, mission);
372     }
373 
374     AbilityRecord *topRecord = const_cast<AbilityRecord *>(abilityList_.GetTopAbility());
375     if (topRecord == nullptr) {
376         APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_NO_ABILITY_RUNNING);
377         return PARAM_NULL_ERROR;
378     }
379 
380     List<uint32_t> list;
381     abilityList_.GetAbilityList(mission, list);
382     for (auto node = list.Begin(); node != list.End(); node = node->next_) {
383         uint16_t token = static_cast<uint32_t>(node->value_);
384         if (token != topRecord->token) {
385             TerminateAbility(token);
386         }
387     }
388 
389     return ERR_OK;
390 }
391 
TerminateAbility(uint16_t token,const Want * want)392 int32_t AbilityRecordManager::TerminateAbility(uint16_t token, const Want* want)
393 {
394     HILOG_INFO(HILOG_MODULE_AAFWK, "TerminateAbility [%{public}u]", token);
395     AbilityRecord *topRecord = const_cast<AbilityRecord *>(abilityList_.GetTopAbility());
396     if (topRecord == nullptr) {
397         isAppScheduling_ = false;
398         APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_NO_ABILITY_RUNNING);
399         return PARAM_NULL_ERROR;
400     }
401     uint16_t topToken = topRecord->token;
402 #ifndef _MINI_MULTI_TASKS_
403     if (token == LAUNCHER_TOKEN) {
404         // if js is in background, the launcher goes back to background and js goes to active
405         isAppScheduling_ = false;
406         if (topToken != token && topRecord->state == SCHEDULE_BACKGROUND) {
407             HILOG_INFO(HILOG_MODULE_AAFWK, "Resume Js app [%{public}u]", topToken);
408             return SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND);
409         }
410         return ERR_OK;
411     }
412 
413     if (token != topToken) {
414         isAppScheduling_ = false;
415         APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_UNKNOWN_ABILITY_TOKEN);
416         DeleteRecordInfo(token);
417         return -1;
418     }
419     topRecord->isTerminated = true;
420     // TerminateAbility top js
421     return ScheduleLifecycleInner(topRecord, SLITE_STATE_BACKGROUND);
422 #else
423     // 1. only launcher in the ability stack
424     if (abilityList_.Size() == 1 && AbilityList::IsPermanentAbility(*topRecord)) {
425         isAppScheduling_ = false;
426         return ERR_OK;
427     }
428     // 2. terminate non-top ability
429     if (token != topToken) {
430         AbilityRecord* abilityRecord = abilityList_.Get(token);
431         if ((abilityRecord == nullptr) || (AbilityList::IsPermanentAbility(*abilityRecord))) {
432             isAppScheduling_ = false;
433             return PARAM_CHECK_ERROR;
434         }
435         APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_UNKNOWN_ABILITY_TOKEN);
436         DeleteRecordInfo(token);
437         isAppScheduling_ = false;
438         return ERR_OK;
439     }
440     // 3. terminate top ability
441     abilityList_.PopAbility();
442     AbilityRecord *newTopRecord = const_cast<AbilityRecord *>(abilityList_.GetTopAbility());
443     if (newTopRecord == nullptr) {
444         isAppScheduling_ = false;
445         APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_NO_ABILITY_RUNNING);
446         return PARAM_NULL_ERROR;
447     }
448 
449     if (!AbilityList::IsPermanentAbility(*topRecord)) {
450         topRecord->isTerminated = true;
451         abilityList_.Add(topRecord);
452     } else {
453         // launcher will not pop ability stack
454         abilityList_.PopAbility();
455         abilityList_.Add(topRecord);
456         abilityList_.Add(newTopRecord);
457     }
458     if (want != nullptr) {
459         if (newTopRecord->abilityData != nullptr) {
460             AdapterFree(newTopRecord->abilityData->wantData);
461         }
462         if (want->data != nullptr) {
463             newTopRecord->SetWantData(want->data, want->dataLength);
464         }
465         HILOG_INFO(HILOG_MODULE_AAFWK, "Terminate ability with want, dataLength is %{public}u", want->dataLength);
466     } else {
467         HILOG_INFO(HILOG_MODULE_AAFWK, "Terminate ability with no want");
468     }
469 
470     // TerminateAbility top js
471     pendingToken_ = newTopRecord->token;
472     return SendMsgToAbilityThread(SLITE_STATE_BACKGROUND, topRecord);
473 #endif
474 }
475 
ForceStopBundle(uint16_t token)476 int32_t AbilityRecordManager::ForceStopBundle(uint16_t token)
477 {
478     HILOG_INFO(HILOG_MODULE_AAFWK, "ForceStopBundle [%{public}u]", token);
479     if (isAppScheduling_) {
480         return AddAbilityOperation(TERMINATE_APP, nullptr, token);
481     }
482     isAppScheduling_ = true;
483 
484 #ifndef _MINI_MULTI_TASKS_
485     if (token == LAUNCHER_TOKEN) {
486         HILOG_INFO(HILOG_MODULE_AAFWK, "Launcher does not support force stop.");
487         isAppScheduling_ = false;
488         return ERR_OK;
489     }
490 
491     // free js mem and delete the record
492     if (ForceStopBundleInner(token) != ERR_OK) {
493         return PARAM_CHECK_ERROR;
494     }
495 
496     // active the launcher
497     AbilityRecord *launcherRecord = abilityList_.Get(LAUNCHER_TOKEN);
498     if (launcherRecord == nullptr) {
499         return PARAM_NULL_ERROR;
500     }
501     if (launcherRecord->state != SCHEDULE_FOREGROUND) {
502         return SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND);
503     }
504 #else
505     AbilityRecord* topRecord = abilityList_.GetTopAbility();
506     if (topRecord->token != token) {
507         return TerminateAbility(token, nullptr);
508     }
509 
510     HILOG_INFO(HILOG_MODULE_AAFWK, "force stop top ability.");
511     topRecord->isTerminated = true;
512     OnDestroyDone(token);
513 #endif
514     return ERR_OK;
515 }
516 
TerminateAll(const char * excludedBundleName)517 int32_t AbilityRecordManager::TerminateAll(const char *excludedBundleName)
518 {
519     if (isAppScheduling_) {
520         Want want;
521         if (excludedBundleName == nullptr) {
522             want.data = nullptr;
523             want.dataLength = 0;
524         } else {
525             want.data = reinterpret_cast<void *>(const_cast<char *>(excludedBundleName));
526             want.dataLength = strlen(excludedBundleName) + 1;
527         }
528         want.element = nullptr;
529         want.appPath = nullptr;
530         return AddAbilityOperation(TERMINATE_ALL, &want, 0);
531     }
532     isAppScheduling_ = true;
533     int32_t ret = abilityList_.PopAllAbility(excludedBundleName);
534     isAppScheduling_ = false;
535     return ret;
536 }
537 
ForceStop(const Want * want)538 int32_t AbilityRecordManager::ForceStop(const Want *want)
539 {
540     if (isAppScheduling_) {
541         return AddAbilityOperation(TERMINATE_APP_BY_BUNDLENAME, want, 0);
542     }
543     isAppScheduling_ = true;
544     if (want == nullptr
545         || want->element == nullptr
546         || want->element->bundleName == nullptr) {
547         isAppScheduling_ = false;
548         return PARAM_NULL_ERROR;
549     }
550 
551 #ifndef _MINI_MULTI_TASKS_
552     // stop Launcher
553     if (IsLauncher(want->element->bundleName)) {
554         return TerminateAbility(0, nullptr);
555     }
556 #endif
557     // stop app
558     AbilityRecord *terminateRecord = abilityList_.Get(want->element->bundleName);
559     if (terminateRecord == nullptr) {
560         isAppScheduling_ = false;
561         HILOG_ERROR(HILOG_MODULE_AAFWK, "ForceStop, The specified ability is not found.");
562         return PARAM_CHECK_ERROR;
563     }
564     HILOG_INFO(HILOG_MODULE_AAFWK, "ForceStop [%{public}u]", terminateRecord->token);
565     return TerminateAbility(terminateRecord->token, want);
566 }
567 
ForceStopBundleInner(uint16_t token)568 int32_t AbilityRecordManager::ForceStopBundleInner(uint16_t token)
569 {
570     return ERR_OK;
571 }
572 
PreCheckStartAbility(const AbilitySvcInfo & info)573 int32_t AbilityRecordManager::PreCheckStartAbility(const AbilitySvcInfo &info)
574 {
575 #ifndef _MINI_MULTI_TASKS_
576     if (info.path == nullptr) {
577         HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility path is null.");
578         return PARAM_NULL_ERROR;
579     }
580     auto curRecord = abilityList_.Get(info.bundleName);
581     if (curRecord != nullptr) {
582         if (curRecord->state == SCHEDULE_FOREGROUND) {
583             HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility current state active.");
584         } else if (curRecord->state == SCHEDULE_BACKGROUND) {
585             SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND);
586         }
587         return ERR_OK;
588     }
589     auto record = new AbilityRecord();
590     record->SetAppName(info.bundleName);
591     record->SetAppPath(info.path);
592     record->SetWantData(info.data, info.dataLength);
593     record->isNativeApp = BMSHelper::GetInstance().IsNativeApp(info.bundleName);
594     record->state = SCHEDULE_STOP;
595     if (pendingToken_ != 0) {
596         record->token = pendingToken_;
597         pendingRecord = record;
598     } else {
599         record->token = GenerateToken();
600         abilityList_.Add(record);
601     }
602     if (pendingToken_ == 0 && CreateAppTask(record) != ERR_OK) {
603         HILOG_ERROR(HILOG_MODULE_AAFWK, "CheckResponse CreateAppTask fail");
604         abilityList_.Erase(record->token);
605         delete record;
606         return CREATE_APPTASK_ERROR;
607     }
608 #else
609     if ((info.path == nullptr) && !(info.isNativeApp)) {
610         HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility path is null.");
611         return PARAM_NULL_ERROR;
612     }
613     auto curRecord = abilityList_.Get(info.bundleName);
614     AbilityRecord *record = nullptr;
615     if (curRecord != nullptr) {
616         if (curRecord->state != SCHEDULE_STOP) {
617             HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility current state active.");
618         } else {
619             // update ability stack and move the ability to the top of ability stack
620             abilityList_.MoveToTop(curRecord->token);
621             pendingToken_ = curRecord->token;
622             return ERR_OK;
623         }
624     } else {
625         record = new AbilityRecord();
626         if (pendingToken_ != 0) {
627             record->token = pendingToken_;
628         } else {
629             record->token = GenerateToken();
630         }
631         record->SetAppName(info.bundleName);
632         record->SetAppPath(info.path);
633         record->SetWantData(info.data, info.dataLength);
634         record->state = SCHEDULE_STOP;
635         record->isNativeApp = info.isNativeApp;
636         record->mission = info.mission;
637         if (record->mission == UINT32_MAX) {
638             record->mission = GenerateMission();
639         }
640         abilityList_.Add(record);
641     }
642 
643     if (pendingToken_ == 0 && CreateAppTask(record) != ERR_OK) {
644         HILOG_ERROR(HILOG_MODULE_AAFWK, "CheckResponse CreateAppTask fail");
645         abilityList_.Erase(record->token);
646         delete record;
647         return CREATE_APPTASK_ERROR;
648     }
649 #endif
650     return ERR_OK;
651 }
652 
CheckResponse(const char * bundleName)653 bool AbilityRecordManager::CheckResponse(const char *bundleName)
654 {
655     StartCheckFunc callBackFunc = GetAbilityCallback();
656     if (callBackFunc == nullptr) {
657         HILOG_ERROR(HILOG_MODULE_AAFWK, "calling ability callback failed: null");
658         return true;
659     }
660     int32_t ret = (*callBackFunc)(bundleName);
661     if (ret != ERR_OK) {
662         HILOG_ERROR(HILOG_MODULE_AAFWK, "calling ability callback failed: check");
663         return false;
664     }
665     return true;
666 }
667 
CreateAppTask(AbilityRecord * record)668 int32_t AbilityRecordManager::CreateAppTask(AbilityRecord *record)
669 {
670     if ((record == nullptr) || (record->appName == nullptr)) {
671         HILOG_ERROR(HILOG_MODULE_AAFWK, "CreateAppTask fail: null");
672         return PARAM_NULL_ERROR;
673     }
674 
675     if (record->isNativeApp) {
676         record->abilityThread =
677             AbilityThreadLoader::GetInstance().CreateAbilityThread(AbilityThreadCreatorType::NATIVE_CREATOR);
678     } else {
679         record->abilityThread =
680             AbilityThreadLoader::GetInstance().CreateAbilityThread(AbilityThreadCreatorType::JS_CREATOR);
681     }
682 
683     if (record->abilityThread == nullptr) {
684         return MEMORY_MALLOC_ERROR;
685     }
686     int32_t ret = record->abilityThread->InitAbilityThread(record);
687     if (ret != ERR_OK) {
688         delete record->abilityThread;
689         record->abilityThread = nullptr;
690         return ret;
691     }
692     record->taskId = record->abilityThread->GetAppTaskId();
693     record->jsAppQueueId = record->abilityThread->GetMessageQueueId();
694     record->state = SCHEDULE_STOP;
695 
696 #ifndef _MINI_MULTI_TASKS_
697     APP_EVENT(MT_ACE_APP_START);
698     abilityList_.Add(record);
699     if (nativeAbility_ != nullptr) {
700         if (SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND) != 0) {
701             APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_LAUNCHER_EXIT_FAILED);
702             HILOG_INFO(HILOG_MODULE_AAFWK, "CreateAppTask Fail to hide launcher");
703             return SCHEDULER_LIFECYCLE_ERROR;
704         }
705     } else {
706         SchedulerLifecycle(record->token, SLITE_STATE_INITIAL);
707     }
708 #else
709     APP_EVENT(MT_ACE_APP_START);
710     SchedulerLifecycle(record->token, SLITE_STATE_INITIAL);
711 #endif
712     return ERR_OK;
713 }
714 
GenerateToken()715 uint16_t AbilityRecordManager::GenerateToken()
716 {
717     static uint16_t token = LAUNCHER_TOKEN;
718     if (token == UINT16_MAX - 1) {
719         token = LAUNCHER_TOKEN;
720     }
721 
722 #ifndef _MINI_MULTI_TASKS_
723     return ++token;
724 #else
725     return token++;
726 #endif
727 }
728 
GenerateMission()729 uint32_t AbilityRecordManager::GenerateMission()
730 {
731     static uint32_t mission = 0;
732     if (mission == UINT32_MAX) {
733         mission = 0;
734     }
735     return mission++;
736 }
737 
DeleteRecordInfo(uint16_t token)738 void AbilityRecordManager::DeleteRecordInfo(uint16_t token)
739 {
740     AbilityRecord *record = abilityList_.Get(token);
741     if (record == nullptr) {
742         return;
743     }
744     DeleteAbilityThread(record);
745     // record app info event when stop app
746     RecordAbiityInfoEvt(record->GetAppName());
747     abilityList_.Erase(token);
748     AbilityRecordObserverManager::GetInstance().NotifyAbilityRecordCleanup(record->appName);
749     delete record;
750 }
751 
DeleteAbilityThread(AbilityRecord * record)752 void AbilityRecordManager::DeleteAbilityThread(AbilityRecord *record)
753 {
754     if (record->abilityThread != nullptr) {
755         record->abilityThread->ReleaseAbilityThread();
756         delete record->abilityThread;
757         record->abilityThread = nullptr;
758     }
759     // free all JS native memory after exiting it
760     // CleanTaskMem(taskId)
761 }
762 
OnCreateDone(uint16_t token)763 void AbilityRecordManager::OnCreateDone(uint16_t token)
764 {
765     SetAbilityStateAndNotify(token, SCHEDULE_INITED);
766     SchedulerLifecycle(token, SLITE_STATE_FOREGROUND);
767 }
768 
OnForegroundDone(uint16_t token)769 void AbilityRecordManager::OnForegroundDone(uint16_t token)
770 {
771     HILOG_INFO(HILOG_MODULE_AAFWK, "OnForegroundDone [%{public}u]", token);
772     SetAbilityStateAndNotify(token, SCHEDULE_FOREGROUND);
773     auto topRecord = const_cast<AbilityRecord *>(abilityList_.GetTopAbility());
774     if (topRecord == nullptr) {
775         return;
776     }
777     HILOG_INFO(HILOG_MODULE_AAFWK, "The number of tasks in the stack is %{public}u.", abilityList_.Size());
778 
779 #ifndef _MINI_MULTI_TASKS_
780     // the launcher foreground
781     if (token == LAUNCHER_TOKEN) {
782         if (nativeAbility_ == nullptr || nativeAbility_->GetState() != SLITE_STATE_FOREGROUND) {
783             HILOG_ERROR(HILOG_MODULE_AAFWK, "native ability is in wrong state : %{public}d",
784                 nativeAbility_->GetState());
785             return;
786         }
787         if (topRecord->token != LAUNCHER_TOKEN) {
788             int abilityState = SLITE_STATE_UNINITIALIZED;
789             if (topRecord->state == SCHEDULE_FOREGROUND) {
790                 HILOG_ERROR(HILOG_MODULE_AAFWK,
791                     "js is in foreground state, native state is %{public}d", abilityState);
792                 OnDestroyDone(topRecord->token);
793                 return;
794             }
795             if (topRecord->state != SCHEDULE_BACKGROUND) {
796                 APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_LAUNCHER_EXIT_FAILED);
797                 HILOG_ERROR(HILOG_MODULE_AAFWK,
798                     "Active launcher js bg fail, native state is %{public}d", abilityState);
799                 DeleteRecordInfo(topRecord->token);
800             } else if (topRecord->isTerminated) {
801                 (void)ScheduleLifecycleInner(topRecord, SLITE_STATE_UNINITIALIZED);
802             }
803         }
804         return;
805     }
806 #endif // _MINI_MULTI_TASKS_
807 
808     // the js app active
809     if (topRecord->token == token) {
810         APP_EVENT(MT_ACE_APP_ACTIVE);
811     }
812 }
813 
OnBackgroundDone(uint16_t token)814 void AbilityRecordManager::OnBackgroundDone(uint16_t token)
815 {
816     HILOG_INFO(HILOG_MODULE_AAFWK, "OnBackgroundDone [%{public}u]", token);
817     SetAbilityStateAndNotify(token, SCHEDULE_BACKGROUND);
818 
819 #ifndef _MINI_MULTI_TASKS_
820     const AbilityRecord *topRecord = abilityList_.GetTopAbility();
821     if (topRecord == nullptr) {
822         return;
823     }
824     // the js background
825     if (token != LAUNCHER_TOKEN) {
826         if (topRecord->token == token) {
827             APP_EVENT(MT_ACE_APP_BACKGROUND);
828             (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND);
829         }
830         return;
831     }
832     // the launcher background
833     if (topRecord->token != LAUNCHER_TOKEN) {
834         if (topRecord->state == SCHEDULE_STOP) {
835             (void)ScheduleLifecycleInner(topRecord, SLITE_STATE_INITIAL);
836         } else {
837             (void)ScheduleLifecycleInner(topRecord, SLITE_STATE_FOREGROUND);
838         }
839         if (GetCleanAbilityDataFlag()) {
840             HILOG_INFO(HILOG_MODULE_AAFWK, "OnBackgroundDone clean launcher record data");
841             AbilityRecord *record = abilityList_.Get(token);
842             record->SetWantData(nullptr, 0);
843             SetCleanAbilityDataFlag(false);
844         }
845         return;
846     }
847 #else
848     AbilityRecord *record = abilityList_.Get(token);
849     if (record == nullptr) {
850         HILOG_ERROR(HILOG_MODULE_AAFWK, "token is not found");
851         return;
852     }
853 
854     if ((!record->isTerminated) && (record->abilitySavedData == nullptr)) {
855         record->abilitySavedData = new AbilitySavedData();
856     }
857     if (record->abilitySavedData != nullptr) {
858         record->abilitySavedData->Reset();
859     }
860 
861     SendMsgToAbilityThread(SLITE_STATE_UNINITIALIZED, record);
862 #endif
863 }
864 
OnDestroyDone(uint16_t token)865 void AbilityRecordManager::OnDestroyDone(uint16_t token)
866 {
867     HILOG_INFO(HILOG_MODULE_AAFWK, "OnDestroyDone [%{public}u]", token);
868     SetAbilityStateAndNotify(token, SCHEDULE_STOP);
869 #ifndef _MINI_MULTI_TASKS_
870     // the launcher destroy
871     if (token == LAUNCHER_TOKEN) {
872         return;
873     }
874     auto topRecord = abilityList_.GetTopAbility();
875     if ((topRecord == nullptr) || (topRecord->token != token)) {
876         DeleteRecordInfo(token);
877         return;
878     }
879     APP_EVENT(MT_ACE_APP_STOP);
880     DeleteRecordInfo(token);
881 
882     // no pending token
883     if (pendingToken_ == 0) {
884         (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND);
885         return;
886     }
887 
888     // start pending token
889     auto record = pendingRecord;
890     if (record == nullptr) {
891         return;
892     }
893     if (CreateAppTask(record) != ERR_OK) {
894         delete record;
895         pendingRecord = nullptr;
896         (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND);
897     }
898     pendingToken_ = 0;
899     pendingRecord = nullptr;
900 #else
901     auto onDestroyRecord = abilityList_.Get(token);
902     if (onDestroyRecord == nullptr) {
903         HILOG_ERROR(HILOG_MODULE_AAFWK, "token is not found");
904         return;
905     }
906     // 1. ability is terminated and pop out ability stack
907     if (onDestroyRecord->isTerminated) {
908         APP_EVENT(MT_ACE_APP_STOP);
909         DeleteRecordInfo(token);
910     } else {
911         // 2. ability is transferred to SCHEDULE_STOP state and still keep in the ability stack
912         DeleteAbilityThread(onDestroyRecord);
913     }
914 
915     // start pending token
916     if (pendingToken_ != 0) {
917         auto record = abilityList_.Get(pendingToken_);
918         if (record == nullptr) {
919             return;
920         }
921         if (CreateAppTask(record) != ERR_OK) {
922             abilityList_.Erase(pendingToken_);
923             delete record;
924             auto topRecord = abilityList_.GetTopAbility();
925             if (topRecord == nullptr) {
926                 HILOG_ERROR(HILOG_MODULE_AAFWK, "record stack is empty");
927                 return;
928             }
929             isAppScheduling_ = false;
930             StartAbility(topRecord);
931         }
932         pendingToken_ = 0;
933     } else {
934         // start top ability
935         auto topAbilityRecord = abilityList_.GetTopAbility();
936         if (pendingToken_ == 0 && CreateAppTask(topAbilityRecord) != ERR_OK) {
937             abilityList_.Erase(topAbilityRecord->token);
938             delete topAbilityRecord;
939             isAppScheduling_ = false;
940         }
941     }
942 #endif
943 }
944 
SchedulerLifecycle(uint64_t token,int32_t state)945 int32_t AbilityRecordManager::SchedulerLifecycle(uint64_t token, int32_t state)
946 {
947     AbilityRecord *record = abilityList_.Get(token);
948     if (record == nullptr) {
949         return PARAM_NULL_ERROR;
950     }
951 
952 #ifndef _MINI_MULTI_TASKS_
953     return ScheduleLifecycleInner(record, state);
954 #else
955     return SendMsgToAbilityThread(state, record);
956 #endif
957 }
958 
SetAbilityStateAndNotify(uint64_t token,int32_t state)959 void AbilityRecordManager::SetAbilityStateAndNotify(uint64_t token, int32_t state)
960 {
961     AbilityRecord *record = abilityList_.Get(token);
962     if (record == nullptr) {
963         return;
964     }
965     record->state = state;
966     AbilityRecordObserverManager::GetInstance().NotifyAbilityRecordStateChanged(
967         AbilityRecordStateData(record->appName, static_cast<AbilityRecordState>(state)));
968 }
969 
970 #ifndef _MINI_MULTI_TASKS_
ScheduleLifecycleInner(const AbilityRecord * record,int32_t state)971 int32_t AbilityRecordManager::ScheduleLifecycleInner(const AbilityRecord *record, int32_t state)
972 {
973     if (record == nullptr) {
974         return PARAM_NULL_ERROR;
975     }
976     // dispatch js life cycle
977     if (record->token != LAUNCHER_TOKEN) {
978         (void) SendMsgToAbilityThread(state, record);
979         return ERR_OK;
980     }
981     // dispatch native life cycle
982     if (nativeAbility_ == nullptr) {
983         return PARAM_NULL_ERROR;
984     }
985     // malloc want memory and release after use
986     Want *info = static_cast<Want *>(AdapterMalloc(sizeof(Want)));
987     if (info == nullptr) {
988         return MEMORY_MALLOC_ERROR;
989     }
990     info->element = nullptr;
991     info->data = nullptr;
992     info->dataLength = 0;
993     info->appPath = nullptr;
994     info->actions = nullptr;
995     info->entities = nullptr;
996 
997     ElementName elementName = {};
998     SetElementBundleName(&elementName, LAUNCHER_BUNDLE_NAME);
999     SetWantElement(info, elementName);
1000     ClearElement(&elementName);
1001     if (record->abilityData != nullptr) {
1002         SetWantData(info, record->abilityData->wantData, record->abilityData->wantDataSize);
1003     } else {
1004         SetWantData(info, nullptr, 0);
1005     }
1006     SchedulerAbilityLifecycle(nativeAbility_, *info, state);
1007     ClearWant(info);
1008     AdapterFree(info);
1009     return ERR_OK;
1010 }
1011 #endif
1012 
SchedulerAbilityLifecycle(SliteAbility * ability,const Want & want,int32_t state)1013 void AbilityRecordManager::SchedulerAbilityLifecycle(SliteAbility *ability, const Want &want, int32_t state)
1014 {
1015     if (ability == nullptr) {
1016         return;
1017     }
1018     switch (state) {
1019         case SLITE_STATE_FOREGROUND: {
1020             ability->OnForeground(want);
1021             break;
1022         }
1023         case SLITE_STATE_BACKGROUND: {
1024             ability->OnBackground();
1025             break;
1026         }
1027         default: {
1028             break;
1029         }
1030     }
1031     return;
1032 }
1033 
SchedulerLifecycleDone(uint64_t token,int32_t state)1034 int32_t AbilityRecordManager::SchedulerLifecycleDone(uint64_t token, int32_t state)
1035 {
1036     switch (state) {
1037         case SLITE_STATE_INITIAL: {
1038             OnCreateDone(token);
1039             break;
1040         }
1041         case SLITE_STATE_FOREGROUND: {
1042             OnForegroundDone(token);
1043             isAppScheduling_ = false;
1044             RunOperation();
1045             break;
1046         }
1047         case SLITE_STATE_BACKGROUND: {
1048             OnBackgroundDone(token);
1049             break;
1050         }
1051         case SLITE_STATE_UNINITIALIZED: {
1052             OnDestroyDone(token);
1053             break;
1054         }
1055         default: {
1056             break;
1057         }
1058     }
1059     return ERR_OK;
1060 }
1061 
SendMsgToAbilityThread(int32_t state,const AbilityRecord * record)1062 int32_t AbilityRecordManager::SendMsgToAbilityThread(int32_t state, const AbilityRecord *record)
1063 {
1064     if (record == nullptr || record->abilityThread == nullptr) {
1065         return PARAM_NULL_ERROR;
1066     }
1067 
1068     SliteAbilityInnerMsg innerMsg;
1069     switch (state) {
1070         case SLITE_STATE_INITIAL:
1071             innerMsg.msgId = SliteAbilityMsgId::CREATE;
1072             innerMsg.want = CreateWant(record);
1073             if (!record->isTerminated) {
1074                 innerMsg.abilitySavedData = record->abilitySavedData;
1075             }
1076             break;
1077         case SLITE_STATE_FOREGROUND:
1078             innerMsg.msgId = SliteAbilityMsgId::FOREGROUND;
1079             innerMsg.want = CreateWant(record);
1080             break;
1081         case SLITE_STATE_BACKGROUND:
1082             innerMsg.msgId = SliteAbilityMsgId::BACKGROUND;
1083             break;
1084         case SLITE_STATE_UNINITIALIZED:
1085             innerMsg.msgId = SliteAbilityMsgId::DESTROY;
1086             if (!record->isTerminated) {
1087                 innerMsg.abilitySavedData = record->abilitySavedData;
1088             }
1089             break;
1090         default:
1091             innerMsg.msgId = (SliteAbilityMsgId)state;
1092             break;
1093     }
1094     innerMsg.abilityThread = record->abilityThread;
1095     return record->abilityThread->SendScheduleMsgToAbilityThread(innerMsg);
1096 }
1097 
CreateWant(const AbilityRecord * record)1098 Want *AbilityRecordManager::CreateWant(const AbilityRecord *record)
1099 {
1100     Want *want = static_cast<Want *>(AdapterMalloc(sizeof(Want)));
1101     want->element = nullptr;
1102     want->data = nullptr;
1103     want->dataLength = 0;
1104     want->appPath = OHOS::Utils::Strdup(record->appPath);
1105     want->mission = record->mission;
1106     want->actions = nullptr;
1107     want->entities = nullptr;
1108     ElementName elementName = {};
1109     SetElementBundleName(&elementName, record->appName);
1110     SetWantElement(want, elementName);
1111     if (record->abilityData != nullptr) {
1112         SetWantData(want, record->abilityData->wantData, record->abilityData->wantDataSize);
1113     }
1114     ClearElement(&elementName);
1115     return want;
1116 }
1117 
NeedToBeTerminated(const char * bundleName)1118 bool AbilityRecordManager::NeedToBeTerminated(const char *bundleName)
1119 {
1120     return BMSHelper::GetInstance().IsTemporaryBundleName(bundleName);
1121 }
1122 
GetTopAbility()1123 ElementName *AbilityRecordManager::GetTopAbility()
1124 {
1125     auto topRecord = const_cast<AbilityRecord *>(abilityList_.GetTopAbility());
1126     if (topRecord == nullptr) {
1127         return nullptr;
1128     }
1129     ElementName *element = reinterpret_cast<ElementName *>(AdapterMalloc(sizeof(ElementName)));
1130     if (element == nullptr || memset_s(element, sizeof(ElementName), 0, sizeof(ElementName)) != EOK) {
1131         AdapterFree(element);
1132         return nullptr;
1133     }
1134 
1135     // case js active or background when launcher not active
1136     if (topRecord->state == SCHEDULE_FOREGROUND || topRecord->state == SCHEDULE_BACKGROUND) {
1137         SetElementBundleName(element, topRecord->appName);
1138     }
1139     return element;
1140 }
1141 
GetMissionInfos(uint32_t maxNum) const1142 MissionInfoList *AbilityRecordManager::GetMissionInfos(uint32_t maxNum) const
1143 {
1144     return abilityList_.GetMissionInfos(maxNum);
1145 }
1146 
setNativeAbility(const SliteAbility * ability)1147 void AbilityRecordManager::setNativeAbility(const SliteAbility *ability)
1148 {
1149     nativeAbility_ = const_cast<SliteAbility *>(ability);
1150 }
1151 
AddAbilityRecordObserver(AbilityRecordObserver * observer)1152 int32_t AbilityRecordManager::AddAbilityRecordObserver(AbilityRecordObserver *observer)
1153 {
1154     AbilityRecordObserverManager::GetInstance().AddObserver(observer);
1155     return ERR_OK;
1156 }
1157 
RemoveAbilityRecordObserver(AbilityRecordObserver * observer)1158 int32_t AbilityRecordManager::RemoveAbilityRecordObserver(AbilityRecordObserver *observer)
1159 {
1160     AbilityRecordObserverManager::GetInstance().RemoveObserver(observer);
1161     return ERR_OK;
1162 }
1163 
CopyWant(const Want * want)1164 Want *AbilityRecordManager::CopyWant(const Want *want)
1165 {
1166     if (want == nullptr) {
1167         HILOG_ERROR(HILOG_MODULE_AAFWK, "want is nullptr");
1168         return nullptr;
1169     }
1170     Want *copiedWant = static_cast<Want *>(AdapterMalloc(sizeof(Want)));
1171     copiedWant->element = nullptr;
1172     copiedWant->data = OHOS::Utils::Memdup(want->data, want->dataLength);
1173     copiedWant->dataLength = want->dataLength;
1174     copiedWant->appPath = OHOS::Utils::Strdup(want->appPath);
1175     copiedWant->actions = nullptr;
1176     copiedWant->entities = nullptr;
1177     if (want->element != nullptr) {
1178         ElementName elementName = {};
1179         SetElementBundleName(&elementName, want->element->bundleName);
1180         SetWantElement(copiedWant, elementName);
1181         ClearElement(&elementName);
1182     }
1183     return copiedWant;
1184 }
1185 
AddAbilityOperation(uint16_t msgId,const Want * want,uint64_t token)1186 int32_t AbilityRecordManager::AddAbilityOperation(uint16_t msgId, const Want *want, uint64_t token)
1187 {
1188     AbilityOperation *operation = static_cast<AbilityOperation *>(AdapterMalloc(sizeof(AbilityOperation)));
1189     if (operation == nullptr || memset_s(operation, sizeof(AbilityOperation), 0, sizeof(AbilityOperation)) != EOK) {
1190         AdapterFree(operation);
1191         HILOG_ERROR(HILOG_MODULE_AAFWK, "AddAbilityOperation failed");
1192         return PARAM_NULL_ERROR;
1193     }
1194     operation->msgId = msgId;
1195     operation->want = CopyWant(want);
1196     operation->token = token;
1197     abilityOperation_.PushBack(operation);
1198     return ERR_OK;
1199 }
1200 
RunOperation()1201 int32_t AbilityRecordManager::RunOperation()
1202 {
1203     if (abilityOperation_.Size() == 0) {
1204         isAppScheduling_ = false;
1205         return ERR_OK;
1206     }
1207 
1208     if (isAppScheduling_) {
1209         return ERR_OK;
1210     }
1211 
1212     AbilityOperation *operation = abilityOperation_.Front();
1213     abilityOperation_.PopFront();
1214     if (operation == nullptr) {
1215         return PARAM_NULL_ERROR;
1216     }
1217     int32_t ret = ERR_OK;
1218     switch (operation->msgId) {
1219         case START_ABILITY: {
1220             ret = StartAbility(operation->want);
1221             break;
1222         }
1223         case TERMINATE_ABILITY: {
1224             ret = TerminateAbility(static_cast<uint16_t>(operation->token));
1225             break;
1226         }
1227         case TERMINATE_APP: {
1228             ret = ForceStopBundle(static_cast<uint16_t>(operation->token));
1229             break;
1230         }
1231         case TERMINATE_MISSION: {
1232             ret = TerminateMission(static_cast<uint32_t>(operation->token));
1233             break;
1234         }
1235         case TERMINATE_APP_BY_BUNDLENAME: {
1236             ret = ForceStop(operation->want);
1237             break;
1238         }
1239         case TERMINATE_ALL: {
1240             ret = TerminateAll(reinterpret_cast<char *>(operation->want->data));
1241             break;
1242         }
1243         default: {
1244             break;
1245         }
1246     }
1247     ClearWant(operation->want);
1248     AdapterFree(operation->want);
1249     AdapterFree(operation);
1250     if (ret != ERR_OK) {
1251         HILOG_ERROR(HILOG_MODULE_AAFWK, "RunOperation failed due to error : [%{public}d]", ret);
1252         isAppScheduling_ = false;
1253         return RunOperation();
1254     }
1255 
1256     if (!isAppScheduling_) {
1257         return RunOperation();
1258     }
1259 
1260     return ret;
1261 }
1262 
SetIsAppScheduling(bool runState)1263 void AbilityRecordManager::SetIsAppScheduling(bool runState)
1264 {
1265     isAppScheduling_ = runState;
1266 }
1267 
GetIsAppScheduling()1268 bool AbilityRecordManager::GetIsAppScheduling()
1269 {
1270     return isAppScheduling_;
1271 }
1272 } // namespace AbilitySlite
1273 } // namespace OHOS
1274 
1275 extern "C" {
InstallNativeAbility(const AbilityInfo * abilityInfo,const OHOS::AbilitySlite::SliteAbility * ability)1276 int InstallNativeAbility(const AbilityInfo *abilityInfo, const OHOS::AbilitySlite::SliteAbility *ability)
1277 {
1278     OHOS::AbilitySlite::AbilityRecordManager::GetInstance().setNativeAbility(ability);
1279     return ERR_OK;
1280 }
1281 
GetTopAbility()1282 ElementName *GetTopAbility()
1283 {
1284     return OHOS::AbilitySlite::AbilityRecordManager::GetInstance().GetTopAbility();
1285 }
1286 }
1287