• 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_service.h"
17 
18 #include "ability_errors.h"
19 #include "ability_list.h"
20 #include "ability_message_id.h"
21 #include "ability_mgr_service.h"
22 #include "ability_mgr_slite_feature.h"
23 #include "ability_record.h"
24 #include "ability_stack.h"
25 #include "ability_state.h"
26 #include "abilityms_log.h"
27 #include "ability_manager_inner.h"
28 #include "bundle_manager.h"
29 #include "cmsis_os.h"
30 #include "js_app_host.h"
31 #include "los_task.h"
32 #include "slite_ability.h"
33 #include "utils.h"
34 #include "want.h"
35 
36 using namespace OHOS::ACELite;
37 
38 namespace OHOS {
39 constexpr char LAUNCHER_BUNDLE_NAME[] = "com.huawei.launcher";
40 constexpr uint16_t LAUNCHER_TOKEN = 0;
41 constexpr int32_t QUEUE_LENGTH = 32;
42 constexpr int32_t SIZE_COEFFICIENT = 12;
43 constexpr int32_t TASK_STACK_SIZE = 0x400 * SIZE_COEFFICIENT;
44 constexpr int32_t APP_TASK_PRI = 25;
45 
46 AbilityService::LifecycleFuncStr AbilityService::lifecycleFuncList_[] = {
47     {STATE_UNINITIALIZED, &AbilityService::OnDestroyDone},
48     {STATE_INITIAL, nullptr},
49     {STATE_INACTIVE, nullptr},
50     {STATE_ACTIVE, &AbilityService::OnActiveDone},
51     {STATE_BACKGROUND, &AbilityService::OnBackgroundDone},
52 };
53 
AbilityService()54 AbilityService::AbilityService()
55 {
56 }
57 
~AbilityService()58 AbilityService::~AbilityService()
59 {
60     DeleteRecordInfo(LAUNCHER_TOKEN);
61 }
62 
StartLauncher()63 void AbilityService::StartLauncher()
64 {
65     auto record = new AbilityRecord();
66     record->SetAppName(LAUNCHER_BUNDLE_NAME);
67     record->SetToken(LAUNCHER_TOKEN);
68     record->SetState(SCHEDULE_ACTIVE);
69     abilityList_.Add(record);
70     abilityStack_.PushAbility(record);
71     (void) SchedulerLifecycleInner(record, STATE_ACTIVE);
72 }
73 
CleanWant()74 void AbilityService::CleanWant()
75 {
76     ClearWant(want_);
77     AdapterFree(want_);
78 }
79 
IsValidAbility(AbilityInfo * abilityInfo)80 bool AbilityService::IsValidAbility(AbilityInfo *abilityInfo)
81 {
82     if (abilityInfo == nullptr) {
83         return false;
84     }
85     if (abilityInfo->bundleName == nullptr || abilityInfo->srcPath == nullptr) {
86         return false;
87     }
88     if (strlen(abilityInfo->bundleName) == 0 || strlen(abilityInfo->srcPath) == 0) {
89         return false;
90     }
91     return true;
92 }
93 
StartAbility(const Want * want)94 int32_t AbilityService::StartAbility(const Want *want)
95 {
96     if (want == nullptr || want->element == nullptr) {
97         HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service wanted element is null");
98         return PARAM_NULL_ERROR;
99     }
100     char *bundleName = want->element->bundleName;
101     if (bundleName == nullptr) {
102         HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service wanted bundleName is null");
103         return PARAM_NULL_ERROR;
104     }
105 
106     AbilitySvcInfo *info =
107         static_cast<OHOS::AbilitySvcInfo *>(AdapterMalloc(sizeof(AbilitySvcInfo)));
108     if (info == nullptr) {
109         HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service AbilitySvcInfo is null");
110         return PARAM_NULL_ERROR;
111     }
112 
113     if (strcmp(bundleName, LAUNCHER_BUNDLE_NAME) == 0) {
114         // Launcher
115         info->bundleName = Utils::Strdup(bundleName);
116         info->path = nullptr;
117     } else {
118         // JS APP
119         AbilityInfo abilityInfo = { nullptr, nullptr };
120         QueryAbilityInfo(want, &abilityInfo);
121         if (!IsValidAbility(&abilityInfo)) {
122             APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_UNKNOWN_BUNDLE_INFO);
123             ClearAbilityInfo(&abilityInfo);
124             AdapterFree(info);
125             HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service returned bundleInfo is not valid");
126             return PARAM_NULL_ERROR;
127         }
128         info->bundleName = OHOS::Utils::Strdup(abilityInfo.bundleName);
129         info->path = OHOS::Utils::Strdup(abilityInfo.srcPath);
130         ClearAbilityInfo(&abilityInfo);
131     }
132 
133     info->data = OHOS::Utils::Memdup(want->data, want->dataLength);
134     info->dataLength = want->dataLength;
135     auto ret = StartAbility(info);
136     AdapterFree(info->bundleName);
137     AdapterFree(info->path);
138     AdapterFree(info->data);
139     AdapterFree(info);
140     return ERR_OK;
141 }
142 
UpdataRecord(AbilitySvcInfo * info)143 void AbilityService::UpdataRecord(AbilitySvcInfo *info)
144 {
145     if (info == nullptr) {
146         return;
147     }
148     AbilityRecord *record = abilityList_.Get(info->bundleName);
149     if (record == nullptr) {
150         return;
151     }
152     if (record->GetToken() != LAUNCHER_TOKEN) {
153         return;
154     }
155     record->SetAppData(info->data, info->dataLength);
156 }
157 
StartAbility(AbilitySvcInfo * info)158 int32_t AbilityService::StartAbility(AbilitySvcInfo *info)
159 {
160     if ((info == nullptr) || (info->bundleName == nullptr) || (strlen(info->bundleName) == 0)) {
161         return PARAM_NULL_ERROR;
162     }
163     HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility");
164 
165     auto topRecord = abilityStack_.GetTopAbility();
166     if ((topRecord == nullptr) || (topRecord->GetAppName() == nullptr)) {
167         HILOG_ERROR(HILOG_MODULE_AAFWK, "StartAbility top null.");
168         return PARAM_NULL_ERROR;
169     }
170     uint16_t topToken = topRecord->GetToken();
171     //  start launcher
172     if (strcmp(info->bundleName, LAUNCHER_BUNDLE_NAME) == 0) {
173         UpdataRecord(info);
174         if (topToken != LAUNCHER_TOKEN && topRecord->GetState() != SCHEDULE_BACKGROUND) {
175             HILOG_INFO(HILOG_MODULE_AAFWK, "Change Js app to background.");
176             (void) SchedulerLifecycleInner(topRecord, STATE_BACKGROUND);
177         } else {
178             (void) SchedulerLifecycle(LAUNCHER_TOKEN, STATE_ACTIVE);
179         }
180         return ERR_OK;
181     }
182 
183     if (!CheckResponse(info->bundleName)) {
184         return PARAM_CHECK_ERROR;
185     }
186 
187     // start js app
188     if (topRecord->IsAttached() && topRecord->GetToken() != LAUNCHER_TOKEN) {
189         // start app is top
190         if (strcmp(info->bundleName, topRecord->GetAppName()) == 0) {
191             if (topRecord->GetState() == SCHEDULE_BACKGROUND) {
192                 HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility Resume app when background.");
193                 (void) SchedulerLifecycle(LAUNCHER_TOKEN, STATE_BACKGROUND);
194                 return ERR_OK;
195             }
196             HILOG_INFO(HILOG_MODULE_AAFWK, "Js app already started or starting.");
197         } else {
198             // js to js
199             HILOG_INFO(HILOG_MODULE_AAFWK, "Terminate pre js app when js to js");
200             TerminateAbility(topRecord->GetToken());
201             pendingToken_ = GenerateToken();
202         }
203     }
204 
205     // application has not been launched and then to check priority and permission.
206     return PreCheckStartAbility(info->bundleName, info->path, info->data, info->dataLength);
207 }
208 
TerminateAbility(uint16_t token)209 int32_t AbilityService::TerminateAbility(uint16_t token)
210 {
211     HILOG_INFO(HILOG_MODULE_AAFWK, "TerminateAbility [%u]", token);
212     AbilityRecord *topRecord = const_cast<AbilityRecord *>(abilityStack_.GetTopAbility());
213     if (topRecord == nullptr) {
214         APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_NO_ABILITY_RUNNING);
215         return PARAM_NULL_ERROR;
216     }
217     uint16_t topToken = topRecord->GetToken();
218     // TODO CHECK terminate token
219     if (token == LAUNCHER_TOKEN) {
220         // if js is in background, the launcher goes back to background and js goes to active
221         if (topToken != token && topRecord->GetState() == SCHEDULE_BACKGROUND) {
222             HILOG_INFO(HILOG_MODULE_AAFWK, "Resume Js app [%u]", topToken);
223             return SchedulerLifecycle(LAUNCHER_TOKEN, STATE_BACKGROUND);
224         }
225         return ERR_OK;
226     }
227 
228     if (token != topToken) {
229         APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_UNKNOWN_ABILITY_TOKEN);
230         DeleteRecordInfo(token);
231         return -1;
232     }
233     topRecord->SetTerminated(true);
234     // TerminateAbility top js
235     return SchedulerLifecycleInner(topRecord, STATE_BACKGROUND);
236 }
237 
ForceStopBundle(uint16_t token)238 int32_t AbilityService::ForceStopBundle(uint16_t token)
239 {
240     HILOG_INFO(HILOG_MODULE_AAFWK, "ForceStopBundle [%u]", token);
241     if (token == LAUNCHER_TOKEN) {
242         HILOG_INFO(HILOG_MODULE_AAFWK, "Launcher does not support force stop.");
243         return ERR_OK;
244     }
245 
246     // free js mem and delete the record
247     AbilityRecord *record = abilityList_.Get(token);
248     if (ForceStopBundleInner(token) != ERR_OK) {
249         return PARAM_CHECK_ERROR;
250     }
251 
252     // active the launcher
253     AbilityRecord *launcherRecord = abilityList_.Get(LAUNCHER_TOKEN);
254     if (launcherRecord == nullptr) {
255         return PARAM_NULL_ERROR;
256     }
257     if (launcherRecord->GetState() != SCHEDULE_ACTIVE) {
258         return SchedulerLifecycle(LAUNCHER_TOKEN, STATE_ACTIVE);
259     }
260     return ERR_OK;
261 }
262 
ForceStop(char * bundlename)263 int32_t AbilityService::ForceStop(char* bundlename)
264 {
265     //stop Launcher
266     if (strcmp(bundlename, LAUNCHER_BUNDLE_NAME) == 0) {
267         return TerminateAbility(0);
268     }
269 
270     //stop js app
271     if (strcmp(abilityStack_.GetTopAbility()->GetAppName(), bundlename) == 0) {
272         AbilityRecord *topRecord = const_cast<AbilityRecord *>(abilityStack_.GetTopAbility());
273         HILOG_INFO(HILOG_MODULE_AAFWK, "ForceStop [%u]", topRecord->GetToken());
274         return TerminateAbility(topRecord->GetToken());
275     }
276 
277     return PARAM_CHECK_ERROR;
278 }
279 
ForceStopBundleInner(uint16_t token)280 int32_t AbilityService::ForceStopBundleInner(uint16_t token)
281 {
282     // free js mem and delete the record
283     AbilityRecord *record = abilityList_.Get(token);
284     if (record == nullptr) {
285         return PARAM_NULL_ERROR;
286     }
287     auto jsAppHost = const_cast<JsAppHost *>(record->GetJsAppHost());
288     if (jsAppHost != nullptr) {
289         // free js mem
290         jsAppHost->ForceDestroy();
291     }
292     DeleteRecordInfo(token);
293     return ERR_OK;
294 }
295 
PreCheckStartAbility(const char * bundleName,const char * path,const void * data,uint16_t dataLength)296 int32_t AbilityService::PreCheckStartAbility(
297     const char *bundleName, const char *path, const void *data, uint16_t dataLength)
298 {
299     if (path == nullptr) {
300         HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility path is null.");
301         return PARAM_NULL_ERROR;
302     }
303     auto curRecord = abilityList_.Get(bundleName);
304     if (curRecord != nullptr) {
305         if (curRecord->GetState() == SCHEDULE_ACTIVE) {
306             HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility current state active.");
307         } else if (curRecord->GetState() == SCHEDULE_BACKGROUND) {
308             SchedulerLifecycle(LAUNCHER_TOKEN, STATE_BACKGROUND);
309         }
310         return ERR_OK;
311     }
312     auto record = new AbilityRecord();
313     if (pendingToken_ != 0) {
314         record->SetToken(pendingToken_);
315     } else {
316         record->SetToken(GenerateToken());
317     }
318     record->SetAppName(bundleName);
319     record->SetAppPath(path);
320     record->SetAppData(data, dataLength);
321     record->SetState(SCHEDULE_STOP);
322     abilityList_.Add(record);
323     if (pendingToken_ == 0 && CreateAppTask(record) != ERR_OK) {
324         HILOG_ERROR(HILOG_MODULE_AAFWK, "CheckResponse CreateAppTask fail");
325         abilityList_.Erase(record->GetToken());
326         delete record;
327         return CREATE_APPTASK_ERROR;
328     }
329     return ERR_OK;
330 }
331 
CheckResponse(const char * bundleName)332 bool AbilityService::CheckResponse(const char *bundleName)
333 {
334     StartCheckFunc callBackFunc = getAbilityCallback();
335     if (callBackFunc == nullptr) {
336         HILOG_ERROR(HILOG_MODULE_AAFWK, "calling ability callback failed: null");
337         return true;
338     }
339     int32_t ret = (*callBackFunc)(bundleName);
340     if (ret != ERR_OK) {
341         HILOG_ERROR(HILOG_MODULE_AAFWK, "calling ability callback failed: check");
342         return false;
343     }
344     return true;
345 }
346 
CreateAppTask(AbilityRecord * record)347 int32_t AbilityService::CreateAppTask(AbilityRecord *record)
348 {
349     if ((record == nullptr) || (record->GetAppName() == nullptr)) {
350         HILOG_ERROR(HILOG_MODULE_AAFWK, "CreateAppTask fail: null");
351         return PARAM_NULL_ERROR;
352     }
353 
354     HILOG_INFO(HILOG_MODULE_AAFWK, "CreateAppTask.");
355     LOS_TaskLock();
356     TSK_INIT_PARAM_S stTskInitParam;
357     stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)(JsAppHost::JsAppTaskHandler);
358     stTskInitParam.uwStackSize = TASK_STACK_SIZE;
359     stTskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST - APP_TASK_PRI;
360     stTskInitParam.pcName = const_cast<char *>("AppTask");
361     stTskInitParam.uwResved = 0;
362     auto jsAppHost = new JsAppHost();
363     stTskInitParam.uwArg = reinterpret_cast<UINT32>((uintptr_t)jsAppHost);
364     UINT32 appTaskId = 0;
365     UINT32 ret = LOS_TaskCreate(&appTaskId, &stTskInitParam);
366     if (ret != LOS_OK) {
367         HILOG_ERROR(HILOG_MODULE_AAFWK, "CreateAppTask fail: ret = %d", ret);
368         APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_CREATE_TSAK_FAILED);
369         delete jsAppHost;
370         LOS_TaskUnlock();
371         return CREATE_APPTASK_ERROR;
372     }
373     osMessageQueueId_t jsAppQueueId = osMessageQueueNew(QUEUE_LENGTH, sizeof(AbilityInnerMsg), nullptr);
374     jsAppHost->SetMessageQueueId(jsAppQueueId);
375     LOS_TaskUnlock();
376 
377     record->SetTaskId(appTaskId);
378     record->SetMessageQueueId(jsAppQueueId);
379     record->SetJsAppHost(jsAppHost);
380 
381     // LoadPermissions(record->GetAppName(), appTaskId)
382     record->SetState(SCHEDULE_INACTIVE);
383     abilityStack_.PushAbility(record);
384     APP_EVENT(MT_ACE_APP_START);
385     if (SchedulerLifecycle(LAUNCHER_TOKEN, STATE_BACKGROUND) != 0) {
386         APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_LAUNCHER_EXIT_FAILED);
387         HILOG_INFO(HILOG_MODULE_AAFWK, "CreateAppTask Fail to hide launcher");
388         abilityStack_.PopAbility();
389         return SCHEDULER_LIFECYCLE_ERROR;
390     }
391     return ERR_OK;
392 }
393 
GenerateToken()394 uint16_t AbilityService::GenerateToken()
395 {
396     static uint16_t token = LAUNCHER_TOKEN;
397     if (token == UINT16_MAX - 1) {
398         token = LAUNCHER_TOKEN;
399     }
400     return ++token;
401 }
402 
DeleteRecordInfo(uint16_t token)403 void AbilityService::DeleteRecordInfo(uint16_t token)
404 {
405     AbilityRecord *record = abilityList_.Get(token);
406     if (record == nullptr) {
407         return;
408     }
409     if (token != LAUNCHER_TOKEN) {
410         if (record->IsAttached()) {
411             UINT32 taskId = record->GetTaskId();
412             // UnLoadPermissions(taskId)
413             LOS_TaskDelete(taskId);
414             osMessageQueueId_t jsAppQueueId = record->GetMessageQueueId();
415             osMessageQueueDelete(jsAppQueueId);
416             auto jsAppHost = const_cast<JsAppHost *>(record->GetJsAppHost());
417             delete jsAppHost;
418             // free all JS native memory after exiting it
419             // CleanTaskMem(taskId)
420         }
421         // record app info event when stop app
422         RecordAbiityInfoEvt(record->GetAppName());
423     }
424     abilityList_.Erase(token);
425     delete record;
426 }
427 
OnActiveDone(uint16_t token)428 void AbilityService::OnActiveDone(uint16_t token)
429 {
430     HILOG_INFO(HILOG_MODULE_AAFWK, "OnActiveDone [%u]", token);
431     SetAbilityState(token, SCHEDULE_ACTIVE);
432     auto topRecord = const_cast<AbilityRecord *>(abilityStack_.GetTopAbility());
433     if (topRecord == nullptr) {
434         return;
435     }
436 
437     // the launcher active
438     if (token == LAUNCHER_TOKEN) {
439         if (topRecord->GetToken() != LAUNCHER_TOKEN) {
440             if (topRecord->GetState() != SCHEDULE_BACKGROUND) {
441                 APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_LAUNCHER_EXIT_FAILED);
442                 HILOG_ERROR(HILOG_MODULE_AAFWK, "Active launcher js bg fail");
443                 abilityStack_.PopAbility();
444                 DeleteRecordInfo(topRecord->GetToken());
445             } else if (topRecord->IsTerminated()) {
446                 (void) SchedulerLifecycleInner(topRecord, STATE_UNINITIALIZED);
447             }
448         }
449         return;
450     }
451     // the js app active
452     if (topRecord->GetToken() == token) {
453         APP_EVENT(MT_ACE_APP_ACTIVE);
454     }
455 }
456 
OnBackgroundDone(uint16_t token)457 void AbilityService::OnBackgroundDone(uint16_t token)
458 {
459     HILOG_INFO(HILOG_MODULE_AAFWK, "OnBackgroundDone [%u]", token);
460     SetAbilityState(token, SCHEDULE_BACKGROUND);
461     auto topRecord = const_cast<AbilityRecord *>(abilityStack_.GetTopAbility());
462     if (topRecord == nullptr) {
463         return;
464     }
465     // the js background
466     if (token != LAUNCHER_TOKEN) {
467         if (topRecord->GetToken() == token) {
468             APP_EVENT(MT_ACE_APP_BACKGROUND);
469             (void) SchedulerLifecycle(LAUNCHER_TOKEN, STATE_ACTIVE);
470         }
471         return;
472     }
473     // the launcher background
474     if (topRecord->GetToken() != LAUNCHER_TOKEN) {
475         (void) SchedulerLifecycleInner(topRecord, STATE_ACTIVE);
476         if (getCleanAbilityDataFlag()) {
477             HILOG_INFO(HILOG_MODULE_AAFWK, "OnBackgroundDone clean launcher record data");
478             AbilityRecord *record = abilityList_.Get(token);
479             record->SetAppData(nullptr, 0);
480             setCleanAbilityDataFlag(false);
481         }
482         return;
483     }
484     HILOG_WARN(HILOG_MODULE_AAFWK, "Js app exit, but has no js app.");
485 }
486 
OnDestroyDone(uint16_t token)487 void AbilityService::OnDestroyDone(uint16_t token)
488 {
489     HILOG_INFO(HILOG_MODULE_AAFWK, "OnDestroyDone [%u]", token);
490     // the launcher destroy
491     if (token == LAUNCHER_TOKEN) {
492         SetAbilityState(token, SCHEDULE_STOP);
493         return;
494     }
495     auto topRecord = abilityStack_.GetTopAbility();
496     if ((topRecord == nullptr) || (topRecord->GetToken() != token)) {
497         SetAbilityState(token, SCHEDULE_STOP);
498         DeleteRecordInfo(token);
499         return;
500     }
501     APP_EVENT(MT_ACE_APP_STOP);
502     abilityStack_.PopAbility();
503     DeleteRecordInfo(token);
504     SetAbilityState(token, SCHEDULE_STOP);
505 
506     // no pending token
507     if (pendingToken_ == 0) {
508         (void) SchedulerLifecycle(LAUNCHER_TOKEN, STATE_ACTIVE);
509         return;
510     }
511 
512     // start pending token
513     auto record = abilityList_.Get(pendingToken_);
514     if (CreateAppTask(record) != ERR_OK) {
515         abilityList_.Erase(pendingToken_);
516         delete record;
517         (void) SchedulerLifecycle(LAUNCHER_TOKEN, STATE_ACTIVE);
518     }
519     pendingToken_ = 0;
520 }
521 
SchedulerLifecycle(uint64_t token,int32_t state)522 int32_t AbilityService::SchedulerLifecycle(uint64_t token, int32_t state)
523 {
524     AbilityRecord *record = abilityList_.Get(token);
525     if (record == nullptr) {
526         return PARAM_NULL_ERROR;
527     }
528     return SchedulerLifecycleInner(record, state);
529 }
530 
SetAbilityState(uint64_t token,int32_t state)531 void AbilityService::SetAbilityState(uint64_t token, int32_t state)
532 {
533     AbilityRecord *record = abilityList_.Get(token);
534     if (record == nullptr) {
535         return;
536     }
537     record->SetState((AbilityState) state);
538 }
539 
SchedulerLifecycleInner(const AbilityRecord * record,int32_t state)540 int32_t AbilityService::SchedulerLifecycleInner(const AbilityRecord *record, int32_t state)
541 {
542     if (record == nullptr) {
543         return PARAM_NULL_ERROR;
544     }
545     // dispatch js life cycle
546     if (record->GetToken() != LAUNCHER_TOKEN) {
547         (void) SendMsgToJsAbility(state, record);
548         return ERR_OK;
549     }
550     // dispatch native life cycle
551     if (nativeAbility_ == nullptr) {
552         return PARAM_NULL_ERROR;
553     }
554     // malloc want memory and release after use
555     Want *info = static_cast<Want *>(AdapterMalloc(sizeof(Want)));
556     if (info == nullptr) {
557         return MEMORY_MALLOC_ERROR;
558     }
559     info->element = nullptr;
560     info->data = nullptr;
561     info->dataLength = 0;
562 
563     ElementName elementName = {};
564     SetElementBundleName(&elementName, LAUNCHER_BUNDLE_NAME);
565     SetWantElement(info, elementName);
566     ClearElement(&elementName);
567     SetWantData(info, record->GetAppData(), record->GetDataLength());
568     SchedulerAbilityLifecycle(nativeAbility_, *info, state);
569     ClearWant(info);
570     return ERR_OK;
571 }
572 
SchedulerAbilityLifecycle(SliteAbility * ability,const Want & want,int32_t state)573 void AbilityService::SchedulerAbilityLifecycle(SliteAbility *ability, const Want &want, int32_t state)
574 {
575     if (ability == nullptr) {
576         return;
577     }
578     switch (state) {
579         case STATE_ACTIVE: {
580             ability->OnActive(want);
581             break;
582         }
583         case STATE_BACKGROUND: {
584             ability->OnBackground();
585             break;
586         }
587         default: {
588             break;
589         }
590     }
591     return;
592 }
593 
SchedulerLifecycleDone(uint64_t token,int32_t state)594 int32_t AbilityService::SchedulerLifecycleDone(uint64_t token, int32_t state)
595 {
596     for (auto temp : lifecycleFuncList_) {
597         if (state == temp.state && temp.func_ptr != nullptr) {
598             (this->*temp.func_ptr)(token);
599         }
600     }
601     return ERR_OK;
602 }
603 
SendMsgToJsAbility(int32_t state,const AbilityRecord * record)604 bool AbilityService::SendMsgToJsAbility(int32_t state, const AbilityRecord *record)
605 {
606     if (record == nullptr) {
607         return false;
608     }
609 
610     AbilityInnerMsg innerMsg;
611     if (state == STATE_ACTIVE) {
612         innerMsg.msgId = ACTIVE;
613     } else if (state == STATE_BACKGROUND) {
614         innerMsg.msgId = BACKGROUND;
615     } else if (state == STATE_UNINITIALIZED) {
616         innerMsg.msgId = DESTORY;
617     } else {
618         innerMsg.msgId = (AbilityMsgId) state;
619     }
620     innerMsg.bundleName = record->GetAppName();
621     innerMsg.token = record->GetToken();
622     innerMsg.path = record->GetAppPath();
623     innerMsg.data = const_cast<void *>(record->GetAppData());
624     innerMsg.dataLength = record->GetDataLength();
625     osMessageQueueId_t appQueueId = record->GetMessageQueueId();
626     osStatus_t ret = osMessageQueuePut(appQueueId, static_cast<void *>(&innerMsg), 0, 0);
627     return ret == osOK;
628 }
629 
GetTopAbility()630 ElementName *AbilityService::GetTopAbility()
631 {
632     auto topRecord = const_cast<AbilityRecord *>(abilityStack_.GetTopAbility());
633     AbilityRecord *launcherRecord = abilityList_.Get(LAUNCHER_TOKEN);
634     if (topRecord == nullptr || launcherRecord == nullptr) {
635         return nullptr;
636     }
637     ElementName *element = reinterpret_cast<ElementName *>(AdapterMalloc(sizeof(ElementName)));
638     if (element == nullptr || memset_s(element, sizeof(ElementName), 0, sizeof(ElementName)) != EOK) {
639         AdapterFree(element);
640         return nullptr;
641     }
642     if (topRecord->GetToken() == LAUNCHER_TOKEN || launcherRecord->GetState() == SCHEDULE_ACTIVE) {
643         SetElementBundleName(element, LAUNCHER_BUNDLE_NAME);
644         return element;
645     }
646 
647     // case js active or background when launcher not active
648     if (topRecord->GetState() == SCHEDULE_ACTIVE || topRecord->GetState() == SCHEDULE_BACKGROUND) {
649         SetElementBundleName(element, topRecord->GetAppName());
650     }
651     return element;
652 }
653 
setNativeAbility(const SliteAbility * ability)654 void AbilityService::setNativeAbility(const SliteAbility *ability)
655 {
656     nativeAbility_ = const_cast<SliteAbility *>(ability);
657 }
658 } // namespace OHOS
659 
660 extern "C" {
InstallNativeAbility(const AbilityInfo * abilityInfo,const OHOS::SliteAbility * ability)661 int InstallNativeAbility(const AbilityInfo *abilityInfo, const OHOS::SliteAbility *ability)
662 {
663     OHOS::AbilityService::GetInstance().setNativeAbility(ability);
664     return ERR_OK;
665 }
666 
GetTopAbility()667 ElementName *GetTopAbility()
668 {
669     return OHOS::AbilityService::GetInstance().GetTopAbility();
670 }
671 }