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