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