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 }