diff --git a/frameworks/abilitymgr_lite/include/abilityms_slite_client.h b/frameworks/abilitymgr_lite/include/abilityms_slite_client.h index b1feab900e503fe8b9b3cadcf111908693c45537..21e71ed83926c68790ad24e6768770fdd2708316 100755 --- a/frameworks/abilitymgr_lite/include/abilityms_slite_client.h +++ b/frameworks/abilitymgr_lite/include/abilityms_slite_client.h @@ -40,6 +40,10 @@ public: int SchedulerLifecycleDone(uint64_t token, int state) const; + int ForceStopBundle(uint64_t token) const; + + ElementName *GetTopAbility() const; + private: AbilityMsClient() = default; diff --git a/frameworks/abilitymgr_lite/src/slite/ability_manager_inner.cpp b/frameworks/abilitymgr_lite/src/slite/ability_manager_inner.cpp index 7d36ad1575e712b093db30b3319c3d1092b3ba8c..b5759c242cc4530a71f1d7f9d806eb58559b129a 100755 --- a/frameworks/abilitymgr_lite/src/slite/ability_manager_inner.cpp +++ b/frameworks/abilitymgr_lite/src/slite/ability_manager_inner.cpp @@ -27,4 +27,9 @@ int SchedulerLifecycleDone(uint64_t token, int state) { return OHOS::AbilityMsClient::GetInstance().SchedulerLifecycleDone(token, state); } + +int ForceStopBundle(uint64_t token) +{ + return OHOS::AbilityMsClient::GetInstance().ForceStopBundle(token); +} } diff --git a/frameworks/abilitymgr_lite/src/slite/abilityms_slite_client.cpp b/frameworks/abilitymgr_lite/src/slite/abilityms_slite_client.cpp index 0d6185457da016958ab8b61e5b81c4702af0c654..5852ee8b3e69577ff0424739e2b9585d0d10322a 100755 --- a/frameworks/abilitymgr_lite/src/slite/abilityms_slite_client.cpp +++ b/frameworks/abilitymgr_lite/src/slite/abilityms_slite_client.cpp @@ -112,4 +112,27 @@ int AbilityMsClient::SchedulerLifecycleDone(uint64_t token, int state) const }; return SAMGR_SendRequest(service->GetIdentity(), &request, nullptr); } + +int AbilityMsClient::ForceStopBundle(uint64_t token) const +{ + AbilityMgrService *service = AbilityMgrService::GetInstance(); + if (service == nullptr) { + return PARAM_CHECK_ERROR; + } + Request request = { + .msgId = TERMINATE_APP, + .data = nullptr, + .len = 0, + .msgValue = static_cast(token & 0xFFFF), + }; + return SAMGR_SendRequest(service->GetIdentity(), &request, nullptr); +} + +ElementName *AbilityMsClient::GetTopAbility() const +{ + if (!Initialize()) { + return nullptr; + } + return amsProxy_->GetTopAbility(); +} } // namespace OHOS diff --git a/interfaces/innerkits/abilitymgr_lite/ability_service_interface.h b/interfaces/innerkits/abilitymgr_lite/ability_service_interface.h index 70898616801a1e4d36962088b9dc89da87fdf81b..353da6d3e89701af30e41a82681dea4442464133 100755 --- a/interfaces/innerkits/abilitymgr_lite/ability_service_interface.h +++ b/interfaces/innerkits/abilitymgr_lite/ability_service_interface.h @@ -70,6 +70,8 @@ struct AmsSliteInterface { int32 (*StartAbility)(const Want *want); int32 (*TerminateAbility)(uint64_t token); int32 (*SchedulerLifecycleDone)(uint64_t token, int state); + int32 (*ForceStopBundle)(uint64_t token); + ElementName *(*GetTopAbility)(); }; #ifdef __cplusplus #if __cplusplus diff --git a/interfaces/innerkits/abilitymgr_lite/slite/ability_manager_inner.h b/interfaces/innerkits/abilitymgr_lite/slite/ability_manager_inner.h index 3b5241d4d2c819507ebe58438be4789b3580938d..37d9e88ce593fea15514c341b5b56e8e4ea548c7 100755 --- a/interfaces/innerkits/abilitymgr_lite/slite/ability_manager_inner.h +++ b/interfaces/innerkits/abilitymgr_lite/slite/ability_manager_inner.h @@ -18,6 +18,8 @@ #include "stdint.h" +#include "element_name.h" + #ifdef __cplusplus #if __cplusplus extern "C" { @@ -26,9 +28,37 @@ extern "C" { typedef int (*StartCheckFunc)(const char *bundleName); +/** + * @brief Register the check function for the ability starting. + * + * @param startChecktCallback Indicates the check function for the ability starting. + * @return Returns 0 if this function is successfully called; returns another value otherwise. + */ int RegAbilityCallback(StartCheckFunc startChecktCallback); +/** + * @brief Schedule the lifecycle of the ability. + * + * @param token Indicates the token of the ability. + * @param state Indicates the state of the lifecycle. + * @return Returns 0 if this function is successfully called; returns another value otherwise. + */ int SchedulerLifecycleDone(uint64_t token, int state); + +/** + * @brief Forcestop an ability based on the specified token information. + * + * @param token Indicates the token of the ability. + * @return Returns 0 if this function is successfully called; returns another value otherwise. + */ +int ForceStopBundle(uint64_t token); + +/** + * @brief Get the element name of the top ability. + * + * @return Returns the element name of the top ability. + */ +ElementName *GetTopAbility(); #ifdef __cplusplus #if __cplusplus } diff --git a/interfaces/kits/ability_lite/slite/ability_manager.h b/interfaces/kits/ability_lite/slite/ability_manager.h index aa26a67237f9e03427d63c0abfa7cd28d7e0886a..d997f9f02b1495eafe9d588b5e8660e176c9d08b 100755 --- a/interfaces/kits/ability_lite/slite/ability_manager.h +++ b/interfaces/kits/ability_lite/slite/ability_manager.h @@ -32,6 +32,12 @@ extern "C" { */ int StartAbility(const Want *want); +/** + * @brief Terminate an ability based on the specified token information. + * + * @param token Indicates the token of the ability. + * @return Returns 0 if this function is successfully called; returns another value otherwise. + */ int TerminateAbility(uint64_t token); #ifdef __cplusplus #if __cplusplus diff --git a/services/abilitymgr_lite/include/ability_mgr_slite_feature.h b/services/abilitymgr_lite/include/ability_mgr_slite_feature.h index 9a37fd15be27622330e38ea525a725b9c319d5ac..bc0b70a3d56ae4a0cdd7d0fa34f68e0765f9a56a 100755 --- a/services/abilitymgr_lite/include/ability_mgr_slite_feature.h +++ b/services/abilitymgr_lite/include/ability_mgr_slite_feature.h @@ -29,6 +29,8 @@ public: static int32 StartAbility(const Want *want); static int32 TerminateAbility(uint64_t token); static int32 SchedulerLifecycleDone(uint64_t token, int state); + static int32 ForceStopBundle(uint64_t token); + static ElementName *GetTopAbility(); static AbilityMgrSliteFeature *GetInstance() { diff --git a/services/abilitymgr_lite/include/ability_service.h b/services/abilitymgr_lite/include/ability_service.h index 02e9a34dd7a62a2d498469ef2025dfd97acde840..3ffbabfd27202061f6b6fc72e3d7ef9714983aff 100755 --- a/services/abilitymgr_lite/include/ability_service.h +++ b/services/abilitymgr_lite/include/ability_service.h @@ -45,7 +45,9 @@ public: ~AbilityService() override; int32_t StartAbility(const Want *want); int32_t TerminateAbility(uint16_t token); + int32_t ForceStopBundle(uint16_t token); int32_t SchedulerLifecycleDone(uint64_t token, int32_t state); + ElementName *GetTopAbility(); void setNativeAbility(const SliteAbility *ability); void StartLauncher(); void CleanWant(); @@ -68,6 +70,7 @@ private: bool SendMsgToJsAbility(int32_t msgId, const AbilityRecord *record); void SetAbilityState(uint64_t token, int32_t state); void UpdataRecord(AbilitySvcInfo *info); + int32_t ForceStopBundleInner(uint16_t token); uint16_t pendingToken_ { 0 }; AbilityList abilityList_ {}; diff --git a/services/abilitymgr_lite/src/ability_mgr_service.cpp b/services/abilitymgr_lite/src/ability_mgr_service.cpp index 08fd2ff7d620786b2f6934379e3787ef4ef51b81..385e19039fad8420d2ca153f2e1ff5cb252ad61d 100755 --- a/services/abilitymgr_lite/src/ability_mgr_service.cpp +++ b/services/abilitymgr_lite/src/ability_mgr_service.cpp @@ -86,8 +86,10 @@ BOOL AbilityMgrService::ServiceMessageHandle(Service *service, Request *request) int token = request->msgValue & 0xFF; int state = (request->msgValue >> BYTE_OFFSET) & 0xFF; ret = AbilityService::GetInstance().SchedulerLifecycleDone(token, state); - } else if (request->msgId == TERMINATE_ABILITY) { + } else if (request->msgId == TERMINATE_ABILITY) { ret = AbilityService::GetInstance().TerminateAbility(request->msgValue); + } else if (request->msgId == TERMINATE_APP) { + ret = AbilityService::GetInstance().ForceStopBundle(request->msgValue); } return ret == ERR_OK; #else diff --git a/services/abilitymgr_lite/src/ability_mgr_slite_feature.cpp b/services/abilitymgr_lite/src/ability_mgr_slite_feature.cpp index 12bff89acc794455d85c9886d35a4014495ee44a..a17006a1f647b604ff44915ead59582df608b2ca 100755 --- a/services/abilitymgr_lite/src/ability_mgr_slite_feature.cpp +++ b/services/abilitymgr_lite/src/ability_mgr_slite_feature.cpp @@ -33,6 +33,8 @@ AbilityMgrSliteFeatureImpl g_amsSliteImpl = { .StartAbility = AbilityMgrSliteFeature::StartAbility, .TerminateAbility = AbilityMgrSliteFeature::TerminateAbility, .SchedulerLifecycleDone = AbilityMgrSliteFeature::SchedulerLifecycleDone, + .ForceStopBundle = AbilityMgrSliteFeature::ForceStopBundle, + .GetTopAbility = AbilityMgrSliteFeature::GetTopAbility, DEFAULT_IUNKNOWN_ENTRY_END }; @@ -105,4 +107,15 @@ int32_t AbilityMgrSliteFeature::SchedulerLifecycleDone(uint64_t token, int state { return AbilityService::GetInstance().SchedulerLifecycleDone(token, state); } + +int32_t AbilityMgrSliteFeature::ForceStopBundle(uint64_t token) +{ + uint16_t slitToken = token & 0xFFFF; + return AbilityService::GetInstance().ForceStopBundle(slitToken); +} + +ElementName *AbilityMgrSliteFeature::GetTopAbility() +{ + return AbilityService::GetInstance().GetTopAbility(); +} } // namespace OHOS diff --git a/services/abilitymgr_lite/src/ability_service.cpp b/services/abilitymgr_lite/src/ability_service.cpp index 41cf6e978a3242d300051ce37efc23cec1b1c080..4cd2f32a59320703c94d8d427f3ff89e88b4bef2 100755 --- a/services/abilitymgr_lite/src/ability_service.cpp +++ b/services/abilitymgr_lite/src/ability_service.cpp @@ -42,8 +42,6 @@ constexpr int32_t SIZE_COEFFICIENT = 12; constexpr int32_t TASK_STACK_SIZE = 0x400 * SIZE_COEFFICIENT; constexpr int32_t APP_TASK_PRI = 25; SliteAbility *g_NativeAbility = nullptr; -AbilityMgrService *g_AbilityService = nullptr; -AbilityMgrSliteFeature *g_AbilityFeature = nullptr; AbilityService::AbilityService() { @@ -83,22 +81,19 @@ int32_t AbilityService::StartAbility(const Want *want) return PARAM_NULL_ERROR; } - // TODO Èç¹ûÒѾ­ÔÚǰ̨£¬ÔòÖ±½Ó·µ»Ø AbilitySvcInfo *info = static_cast(AdapterMalloc(sizeof(AbilitySvcInfo))); if (info == nullptr) { HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service AbilitySvcInfo is null"); return PARAM_NULL_ERROR; } - // TODO ³õʼ»¯info - // ×é×°infoÐÅÏ¢ - // Èç¹ûÊÇ×ÀÃæ if (strcmp(bundleName, LAUNCHER_BUNDLE_NAME) == 0) { + // Launcher info->bundleName = Utils::Strdup(bundleName); info->path = nullptr; } else { - // JSÓ¦Óà + // JS APP AbilityInfo abilityInfo = { nullptr, nullptr }; QueryAbilityInfo(want, &abilityInfo); if ((abilityInfo.bundleName == nullptr) || (strlen(abilityInfo.bundleName) == 0) || @@ -152,27 +147,25 @@ int32_t AbilityService::StartAbility(AbilitySvcInfo *info) return PARAM_NULL_ERROR; } uint16_t topToken = topRecord->GetToken(); - // Æô¶¯µÄÊÇ×ÀÃæ + // start launcher if (strcmp(info->bundleName, LAUNCHER_BUNDLE_NAME) == 0) { UpdataRecord(info); - // Top²»ÊÇ×ÀÃæ£¬¶øÊÇJSÓ¦ÓÃÇÒ²»ÔÚºǫ́ if (topToken != LAUNCHER_TOKEN && topRecord->GetState() != SCHEDULE_BACKGROUND) { HILOG_INFO(HILOG_MODULE_AAFWK, "Change Js app to background."); (void) SchedulerLifecycleInner(topRecord, STATE_BACKGROUND); } else { - // TODO ÕâÀïÊÇ·ñ»¹Í¨ÖªLauncher TOPÊÇ×ÀÃæ£¬»òÕßtop²»ÊÇ×ÀÃæ£¬jsÔÚºǫ́ (void) SchedulerLifecycle(LAUNCHER_TOKEN, STATE_ACTIVE); } return ERR_OK; } - // TODO CheckÊÇ·ñÔÊÐíÆô¶¯ + if (!CheckResponse(info->bundleName)) { - return -1; + return PARAM_CHECK_ERROR; } - // Æô¶¯jsÇÒTOPÊÇjsÓ¦Óã¬ÇÒÒѾ­´´½¨ÁËtask + // start js app if (topRecord->IsAttached() && topRecord->GetToken() != LAUNCHER_TOKEN) { - // ¸ú֮ǰÆðµÄÊÇͬһ¸öÓ¦Óà tocheck + // start app is top if (strcmp(info->bundleName, topRecord->GetAppName()) == 0) { if (topRecord->GetState() == SCHEDULE_BACKGROUND) { HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility Resume app when background."); @@ -181,7 +174,7 @@ int32_t AbilityService::StartAbility(AbilitySvcInfo *info) } HILOG_INFO(HILOG_MODULE_AAFWK, "Js app already started or starting."); } else { - // TODO ºÍ֮ǰµÄjsÓ¦Óò»ÊÇÒ»¸öÓ¦Óà JS2JS³¡¾°£¬ÐèÒªÏȰÑ֮ǰµÄJSÍ˳ö + // TODO ��֮ǰ��jsӦ�ò���һ��Ӧ�� JS2JS��������Ҫ�Ȱ�֮ǰ��JS�˳� return ERR_OK; } } @@ -199,9 +192,9 @@ int32_t AbilityService::TerminateAbility(uint16_t token) return PARAM_NULL_ERROR; } uint16_t topToken = topRecord->GetToken(); - // TODO CHECK terminate ×ÀÃæ,ÊÇ·ñÓиó¡¾°£¿ + // TODO CHECK terminate ����,�Ƿ��иó����� if (token == LAUNCHER_TOKEN) { - // Èç¹ûµ±Ç°jsÔÚºǫ́, Ôò×ÀÃæÍ˺ǫ́£¬js×ßµ½Ç°Ì¨ + // �����ǰjs�ں�̨, �������˺�̨��js�ߵ�ǰ̨ if (topToken != token && topRecord->GetState() == SCHEDULE_BACKGROUND) { HILOG_INFO(HILOG_MODULE_AAFWK, "Resume Js app [%u]", topToken); return SchedulerLifecycle(LAUNCHER_TOKEN, STATE_BACKGROUND); @@ -209,17 +202,58 @@ int32_t AbilityService::TerminateAbility(uint16_t token) return ERR_OK; } - // TODO CHECKÊÇ·ñÓиó¡¾° + // TODO CHECK�Ƿ��иó��� if (token != topToken) { APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_UNKNOWN_ABILITY_TOKEN); DeleteRecordInfo(token); return -1; } topRecord->SetTerminated(true); - // TerminateAbility TOPµÄjs + // TerminateAbility TOP��js return SchedulerLifecycleInner(topRecord, STATE_BACKGROUND); } +int32_t AbilityService::ForceStopBundle(uint16_t token) +{ + HILOG_INFO(HILOG_MODULE_AAFWK, "ForceStopBundle [%u]", token); + if (token == LAUNCHER_TOKEN) { + HILOG_INFO(HILOG_MODULE_AAFWK, "Launcher does not support force stop."); + return ERR_OK; + } + + // free js mem and delete the record + AbilityRecord *record = abilityList_.Get(token); + if (ForceStopBundleInner(token) != ERR_OK) { + return PARAM_CHECK_ERROR; + } + + // active the launcher + AbilityRecord *launcherRecord = abilityList_.Get(LAUNCHER_TOKEN); + if (launcherRecord == nullptr) { + return PARAM_NULL_ERROR; + } + if (launcherRecord->GetState() != SCHEDULE_ACTIVE) { + return SchedulerLifecycleInner(LAUNCHER_TOKEN, STATE_ACTIVE); + } + return ERR_OK; +} + +int32_t AbilityService::ForceStopBundleInner(uint16_t token) +{ + // free js mem and delete the record + AbilityRecord *record = abilityList_.Get(token); + if (record == nullptr) { + return PARAM_NULL_ERROR; + } + auto jsAppHost = const_cast(record->GetJsAppHost()); + if (jsAppHost != nullptr) { + // free js mem + jsAppHost->ForceDestroy(); + } + DeleteRecordInfo(token); + return ERR_OK; +} + int32_t AbilityService::PreCheckStartAbility( const char *bundleName, const char *path, const void *data, uint16_t dataLength) { @@ -229,11 +263,9 @@ int32_t AbilityService::PreCheckStartAbility( } auto curRecord = abilityList_.Get(bundleName); if (curRecord != nullptr) { - // µ±Ç°ÒѾ­ÊÇǰ̨£¬²»´¦Àí if (curRecord->GetState() == SCHEDULE_ACTIVE) { - HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility cur state active."); + HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility current state active."); } else if (curRecord->GetState() == SCHEDULE_BACKGROUND) { - // Æô¶¯µÄjsÔÚºǫ́£¬ÔòÏȽ«×ÀÃæ×ßµ½ºǫ́ SchedulerLifecycle(LAUNCHER_TOKEN, STATE_BACKGROUND); } return ERR_OK; @@ -245,7 +277,6 @@ int32_t AbilityService::PreCheckStartAbility( record->SetAppData(data, dataLength); record->SetState(SCHEDULE_STOP); abilityList_.Add(record); - // ´´½¨APP TASK if (CreateAppTask(record) != ERR_OK) { HILOG_ERROR(HILOG_MODULE_AAFWK, "CheckResponse CreateAppTask fail"); abilityList_.Erase(record->GetToken()); @@ -294,7 +325,6 @@ int32_t AbilityService::CreateAppTask(AbilityRecord *record) // LoadPermissions(record->GetAppName(), appTaskId) record->SetState(SCHEDULE_INACTIVE); - // TODO ÕâÀïÔÚSchedulerLifecycleÖ®ºó abilityStack_.PushAbility(record); APP_EVENT(MT_ACE_APP_START); if (SchedulerLifecycle(LAUNCHER_TOKEN, STATE_BACKGROUND) != 0) { @@ -348,8 +378,9 @@ void AbilityService::OnActiveDone(uint16_t token) if (topRecord == nullptr) { return; } + + // the launcher active if (token == LAUNCHER_TOKEN) { - // Èç¹ûÊÇ×ÀÃæ¼¤»î£¬µ«JSµÄ״̬²»Îªºǫ́£¬ÔòÍ˳öJS if (topRecord->GetToken() != LAUNCHER_TOKEN) { if (topRecord->GetState() != SCHEDULE_BACKGROUND) { APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_LAUNCHER_EXIT_FAILED); @@ -362,7 +393,7 @@ void AbilityService::OnActiveDone(uint16_t token) } return; } - // Èç¹ûÆô¶¯µÄÊÇjs + // the js app active if (topRecord->GetToken() == token) { APP_EVENT(MT_ACE_APP_ACTIVE); } @@ -376,7 +407,7 @@ void AbilityService::OnBackgroundDone(uint16_t token) if (topRecord == nullptr) { return; } - // JS×ßµ½ºǫ́£¬¼¤»îLAUNCHER + // the js background if (token != LAUNCHER_TOKEN) { if (topRecord->GetToken() == token) { APP_EVENT(MT_ACE_APP_BACKGROUND); @@ -385,19 +416,18 @@ void AbilityService::OnBackgroundDone(uint16_t token) } return; } - // launcher×ßµ½ºǫ́³¡¾° + // the launcher background if (topRecord->GetToken() != LAUNCHER_TOKEN) { (void) SchedulerLifecycleInner(topRecord, STATE_ACTIVE); - } else { - // TODO CHECKÕâ¸ö³¡¾°»¹ÓÐûÓÐ - HILOG_WARN(HILOG_MODULE_AAFWK, "Js app exit, but has no js app."); + return; } + HILOG_WARN(HILOG_MODULE_AAFWK, "Js app exit, but has no js app."); } void AbilityService::OnDestroyDone(uint16_t token) { HILOG_INFO(HILOG_MODULE_AAFWK, "OnDestroyDone [%u]", token); - // ×ÀÃæ²»»ádestroy + // the launcher destroy if (token == LAUNCHER_TOKEN) { SetAbilityState(token, SCHEDULE_STOP); return; @@ -413,13 +443,13 @@ void AbilityService::OnDestroyDone(uint16_t token) DeleteRecordInfo(token); SetAbilityState(token, SCHEDULE_STOP); - // ÎÞÆäËûJSÐèÒªÆô¶¯µÄ³¡¾°£¬Ö±½Ó¼¤»î×ÀÃæ + // no pending token if (pendingToken_ == 0) { (void) SchedulerLifecycle(LAUNCHER_TOKEN, STATE_ACTIVE); return; } - // JS2JS³¡¾° + // start pending token auto record = abilityList_.Get(pendingToken_); if (CreateAppTask(record) != ERR_OK) { abilityList_.Erase(pendingToken_); @@ -452,16 +482,16 @@ int32_t AbilityService::SchedulerLifecycleInner(const AbilityRecord *record, int if (record == nullptr) { return PARAM_NULL_ERROR; } - // ֪ͨ¶ÔÓ¦µÄability£¬×ßÏàÓ¦µÄÉúÃüÖÜÆÚ - if (record->GetToken() != LAUNCHER_TOKEN) { // jsÓ¦Óà + // dispatch js life cycle + if (record->GetToken() != LAUNCHER_TOKEN) { // jsӦ�� (void) SendMsgToJsAbility(state, record); return ERR_OK; } - // native Ó¦Ó㬻ñÈ¡nativeµÄability£¬µ÷ÓÃÏàÓ¦µÄÉúÃüÖÜÆÚ + // dispatch native life cycle if (g_NativeAbility == nullptr) { return PARAM_NULL_ERROR; } - // ÉêÇëwantÄڴ棬ÔÚ·þÎñ¶ËÓÃÍêÊÍ·Å + // ����want�ڴ棬�ڷ���������ͷ� Want *info = static_cast(AdapterMalloc(sizeof(Want))); if (info == nullptr) { return MEMORY_MALLOC_ERROR; @@ -512,7 +542,7 @@ int32_t AbilityService::SchedulerLifecycleDone(uint64_t token, int32_t state) OnBackgroundDone(token); break; } - case STATE_UNINITIALIZED: { // TODO DESTROYÈçºÎÌåÏÖ + case STATE_UNINITIALIZED: { OnDestroyDone(token); break; } @@ -549,10 +579,32 @@ bool AbilityService::SendMsgToJsAbility(int32_t state, const AbilityRecord *reco return ret == osOK; } +ElementName *AbilityService::GetTopAbility() +{ + auto topRecord = const_cast(abilityStack_.GetTopAbility()); + AbilityRecord *launcherRecord = abilityList_.Get(LAUNCHER_TOKEN); + if (topRecord == nullptr || launcherRecord == nullptr) { + return nullptr; + } + ElementName *element = reinterpret_cast(AdapterMalloc(sizeof(ElementName))); + if (element == nullptr || memset_s(element, sizeof(ElementName), 0, sizeof(ElementName)) != EOK) { + AdapterFree(element); + return nullptr; + } + if (topRecord->GetToken() == LAUNCHER_TOKEN || launcherRecord->GetState() == SCHEDULE_ACTIVE) { + SetElementBundleName(element, LAUNCHER_BUNDLE_NAME); + return element; + } + + // case js active or background when launcher not active + if (topRecord->GetState() == SCHEDULE_ACTIVE || topRecord->GetState() == SCHEDULE_BACKGROUND) { + SetElementBundleName(element, topRecord->GetAppName()); + } + return element; +} + void AbilityService::setNativeAbility(const SliteAbility *ability) { - g_AbilityFeature = AbilityMgrSliteFeature::GetInstance(); - g_AbilityService = AbilityMgrService::GetInstance(); g_NativeAbility = const_cast(ability); } } // namespace OHOS @@ -563,4 +615,9 @@ int InstallNativeAbility(const AbilityInfo *abilityInfo, const OHOS::SliteAbilit OHOS::AbilityService::GetInstance().setNativeAbility(ability); return ERR_OK; } + +ElementName *GetTopAbility() +{ + return OHOS::AbilityService::GetInstance().GetTopAbility(); +} } \ No newline at end of file