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