From a6a31adf100fc853b2f1cf5fcac98b4621846432 Mon Sep 17 00:00:00 2001 From: s00494828 Date: Fri, 21 Apr 2023 14:09:21 +0800 Subject: [PATCH 1/4] native app schedule Signed-off-by: s00494828 --- frameworks/ability_lite/BUILD.gn | 1 + .../ability_lite/src/slite/slite_ability.cpp | 11 + .../kits/ability_lite/slite/slite_ability.h | 5 +- .../include/slite/ability_record_manager.h | 11 +- .../include/slite/ability_stack.h | 2 + .../include/slite/ability_thread.h | 21 +- .../include/slite/dummy_js_ability.h | 2 +- .../include/slite/js_ability_thread.h | 2 + .../include/slite/native_ability_thread.h | 3 + .../src/slite/ability_mgr_service_slite.cpp | 6 +- .../src/slite/ability_record_manager.cpp | 493 ++++++++++-------- .../src/slite/ability_stack.cpp | 5 + .../src/slite/ability_thread.cpp | 77 +-- .../src/slite/js_ability_thread.cpp | 59 ++- .../src/slite/native_ability_thread.cpp | 94 +++- 15 files changed, 496 insertions(+), 296 deletions(-) diff --git a/frameworks/ability_lite/BUILD.gn b/frameworks/ability_lite/BUILD.gn index 27e57ff..37489a9 100644 --- a/frameworks/ability_lite/BUILD.gn +++ b/frameworks/ability_lite/BUILD.gn @@ -56,6 +56,7 @@ lite_library("ability") { "${aafwk_lite_path}/interfaces/inner_api/abilitymgr_lite/slite", "${aafwk_lite_path}/interfaces/kits/ability_lite", "${appexecfwk_lite_path}/utils/bundle_lite", + "//commonlibrary/utils_lite/memory/include", "//foundation/systemabilitymgr/samgr_lite/interfaces/kits/registry", "//foundation/systemabilitymgr/samgr_lite/interfaces/kits/samgr", ] diff --git a/frameworks/ability_lite/src/slite/slite_ability.cpp b/frameworks/ability_lite/src/slite/slite_ability.cpp index 0480e92..0188c51 100755 --- a/frameworks/ability_lite/src/slite/slite_ability.cpp +++ b/frameworks/ability_lite/src/slite/slite_ability.cpp @@ -16,9 +16,20 @@ #include "slite_ability.h" #include "slite_ability_state.h" #include "abilityms_slite_client.h" +#include "utils.h" namespace OHOS { namespace AbilitySlite { +SliteAbility::SliteAbility(const char *bundleName) +{ + bundleName_= OHOS::Utils::Strdup(bundleName); +} + +SliteAbility::~SliteAbility() +{ + AdapterFree(bundleName_); +} + void SliteAbility::OnCreate(const Want &want) { abilityState_ = SLITE_STATE_INITIAL; diff --git a/interfaces/kits/ability_lite/slite/slite_ability.h b/interfaces/kits/ability_lite/slite/slite_ability.h index 782026e..386142a 100755 --- a/interfaces/kits/ability_lite/slite/slite_ability.h +++ b/interfaces/kits/ability_lite/slite/slite_ability.h @@ -36,9 +36,9 @@ namespace AbilitySlite { */ class SliteAbility : public LiteContext { public: - SliteAbility() = default; + SliteAbility(const char *bundleName); - virtual ~SliteAbility() = default; + virtual ~SliteAbility(); /** * @brief Called when this ability is created. You must override this function if you want to perform some @@ -80,6 +80,7 @@ public: int GetState() const; + char *bundleName_ = nullptr; private: int abilityState_ = 0; }; diff --git a/services/abilitymgr_lite/include/slite/ability_record_manager.h b/services/abilitymgr_lite/include/slite/ability_record_manager.h index 51dd354..28fad19 100644 --- a/services/abilitymgr_lite/include/slite/ability_record_manager.h +++ b/services/abilitymgr_lite/include/slite/ability_record_manager.h @@ -35,6 +35,7 @@ struct AbilitySvcInfo { char *path; void *data; uint16_t dataLength; + bool isNative = false; }; class AbilityRecordManager : public NoCopyable { @@ -68,6 +69,8 @@ public: void setNativeAbility(const SliteAbility *ability); + int SetNativeApplications(const char **nativeApplications, int32_t size); + void StartLauncher(); uint32_t curTask_ = 0; @@ -79,9 +82,11 @@ private: int32_t StartAbility(AbilitySvcInfo *info); + int32_t StartAbility(const AbilityRecord *record); + int32_t StartRemoteAbility(const Want *want); - int32_t PreCheckStartAbility(const char *bundleName, const char *path, const void *data, uint16_t dataLength); + int32_t PreCheckStartAbility(const char *bundleName, const char *path, const void *data, uint16_t dataLength, bool isNative); bool CheckResponse(const char *bundleName); @@ -103,7 +108,9 @@ private: void DeleteRecordInfo(uint16_t token); - bool SendMsgToJsAbility(int32_t msgId, const AbilityRecord *record); + void DeleteAbilityThread(AbilityRecord *record); + + bool SendMsgToJsOrNativeAbility(const AbilityRecord *record, int32_t msgId); void SetAbilityState(uint64_t token, int32_t state); diff --git a/services/abilitymgr_lite/include/slite/ability_stack.h b/services/abilitymgr_lite/include/slite/ability_stack.h index 499d576..d475de3 100755 --- a/services/abilitymgr_lite/include/slite/ability_stack.h +++ b/services/abilitymgr_lite/include/slite/ability_stack.h @@ -36,6 +36,8 @@ public: void Erase(AbilityRecord *record); + uint32_t Size() const; + private: List abilityStack_ {}; }; diff --git a/services/abilitymgr_lite/include/slite/ability_thread.h b/services/abilitymgr_lite/include/slite/ability_thread.h index 98091f3..f0a2a92 100644 --- a/services/abilitymgr_lite/include/slite/ability_thread.h +++ b/services/abilitymgr_lite/include/slite/ability_thread.h @@ -21,8 +21,12 @@ #include "los_task.h" #include "slite_ability.h" +extern "C" void LP_TaskBegin(); +extern "C" void LP_TaskEnd(); + namespace OHOS { namespace AbilitySlite { +constexpr char LAUNCHER_BUNDLE_NAME[] = "com.ohos.launcher"; class AbilityRecord; enum class AbilityThreadState : int8_t { ABILITY_THREAD_UNINITIALIZED, @@ -40,16 +44,6 @@ public: virtual int32_t ReleaseAbilityThread() = 0; - static void AppTaskHandler(UINT32 uwArg); - - osMessageQueueId_t messageQueueId_ = nullptr; - UINT32 appTaskId_ = 0; - -protected: - AbilityThreadState state_ = AbilityThreadState::ABILITY_THREAD_UNINITIALIZED; - SliteAbility *ability_ = nullptr; - -private: int32_t HandleCreate(const Want *want); int32_t HandleForeground(const Want *want); @@ -57,6 +51,13 @@ private: int32_t HandleBackground(); int32_t HandleDestroy(); + + osMessageQueueId_t messageQueueId_ = nullptr; + UINT32 appTaskId_ = 0; + SliteAbility *ability_ = nullptr; + +protected: + AbilityThreadState state_ = AbilityThreadState::ABILITY_THREAD_UNINITIALIZED; }; } // namespace AbilitySlite } // namespace OHOS diff --git a/services/abilitymgr_lite/include/slite/dummy_js_ability.h b/services/abilitymgr_lite/include/slite/dummy_js_ability.h index f4b3bcf..c0e203a 100644 --- a/services/abilitymgr_lite/include/slite/dummy_js_ability.h +++ b/services/abilitymgr_lite/include/slite/dummy_js_ability.h @@ -23,7 +23,7 @@ namespace OHOS { namespace AbilitySlite { class DummyJsAbility : public SliteAbility { public: - DummyJsAbility() = default; + DummyJsAbility(const char *bundleName) : SliteAbility(bundleName) {} ~DummyJsAbility() override = default; diff --git a/services/abilitymgr_lite/include/slite/js_ability_thread.h b/services/abilitymgr_lite/include/slite/js_ability_thread.h index edb6cc9..3a1e107 100644 --- a/services/abilitymgr_lite/include/slite/js_ability_thread.h +++ b/services/abilitymgr_lite/include/slite/js_ability_thread.h @@ -31,6 +31,8 @@ public: int32_t InitAbilityThread(const AbilityRecord *abilityRecord) override; int32_t ReleaseAbilityThread() override; + + static void AppTaskHandler(UINT32 uwArg); }; } // namespace AbilitySlite } // namespace OHOS diff --git a/services/abilitymgr_lite/include/slite/native_ability_thread.h b/services/abilitymgr_lite/include/slite/native_ability_thread.h index 3f93f18..d68fdf9 100644 --- a/services/abilitymgr_lite/include/slite/native_ability_thread.h +++ b/services/abilitymgr_lite/include/slite/native_ability_thread.h @@ -30,8 +30,11 @@ public: int32_t ReleaseAbilityThread() override; + static void NativeAppTaskHandler(UINT32 uwArg); + static osMessageQueueId_t nativeQueueId; static UINT32 nativeTaskId; + static SliteAbility *LauncherAbility_; }; } } diff --git a/services/abilitymgr_lite/src/slite/ability_mgr_service_slite.cpp b/services/abilitymgr_lite/src/slite/ability_mgr_service_slite.cpp index 11f2112..766f62e 100755 --- a/services/abilitymgr_lite/src/slite/ability_mgr_service_slite.cpp +++ b/services/abilitymgr_lite/src/slite/ability_mgr_service_slite.cpp @@ -28,7 +28,8 @@ #include "ohos_init.h" #include "samgr_lite.h" #include "slite_ability_loader.h" -#include "slite_ace_ability.h" +//#include "slite_ace_ability.h" +#include "dummy_js_ability.h" #include "want.h" namespace OHOS { @@ -239,7 +240,8 @@ void AbilityMgrServiceSlite::InitAbilityThreadLoad() static SliteAbility *createJsAbility(const char *bundleName) { - SliteAbility *jsAbility = new DummyJsAbility(); + //SliteAbility *jsAbility = new ACELite::SliteAceAbility(); + SliteAbility *jsAbility = new DummyJsAbility(bundleName); return jsAbility; } diff --git a/services/abilitymgr_lite/src/slite/ability_record_manager.cpp b/services/abilitymgr_lite/src/slite/ability_record_manager.cpp index c777d6b..29ec13e 100644 --- a/services/abilitymgr_lite/src/slite/ability_record_manager.cpp +++ b/services/abilitymgr_lite/src/slite/ability_record_manager.cpp @@ -43,10 +43,10 @@ using namespace OHOS::ACELite; namespace OHOS { namespace AbilitySlite { -constexpr char LAUNCHER_BUNDLE_NAME[] = "com.ohos.launcher"; constexpr uint16_t LAUNCHER_TOKEN = 0; constexpr int32_t QUEUE_LENGTH = 32; constexpr int32_t APP_TASK_PRI = 25; +constexpr int32_t MAX_NATIVE_APP_SIZE = 200; // this size might be changed AbilityRecordManager::AbilityRecordManager() = default; @@ -57,19 +57,54 @@ AbilityRecordManager::~AbilityRecordManager() void AbilityRecordManager::StartLauncher() { + // AbilityRecord *launcherRecord = abilityList_.Get(LAUNCHER_TOKEN); + // if (launcherRecord != nullptr) { + // return; + // } + // auto record = new AbilityRecord(); + // record->SetAppName(LAUNCHER_BUNDLE_NAME); + // record->token = LAUNCHER_TOKEN; + // record->isNativeApp = true; + // record->state = SCHEDULE_FOREGROUND; + // record->taskId = LOS_CurTaskIDGet(); + // abilityList_.Add(record); + // abilityStack_.PushAbility(record); + // (void) SchedulerLifecycleInner(record, SLITE_STATE_FOREGROUND); AbilityRecord *launcherRecord = abilityList_.Get(LAUNCHER_TOKEN); if (launcherRecord != nullptr) { return; } - auto record = new AbilityRecord(); - record->SetAppName(LAUNCHER_BUNDLE_NAME); - record->token = LAUNCHER_TOKEN; - record->isNativeApp = true; - record->state = SCHEDULE_FOREGROUND; - record->taskId = LOS_CurTaskIDGet(); - abilityList_.Add(record); - abilityStack_.PushAbility(record); - (void) SchedulerLifecycleInner(record, SLITE_STATE_FOREGROUND); + StartAbility(launcherRecord); +} + +int32_t AbilityRecordManager::StartAbility(const AbilityRecord *record) +{ + Want *want = static_cast(AdapterMalloc(sizeof(Want))); + if (want == nullptr) { + return PARAM_NULL_ERROR; + } + want->data = nullptr; + want->dataLength = 0; + want->element = nullptr; + want->appPath = nullptr; + ElementName elementName = {}; + if (record != nullptr) { + want->data = Utils::Memdup(record->abilityData->wantData, record->abilityData->wantDataSize); + want->dataLength = record->abilityData->wantDataSize; + want->appPath = Utils::Strdup(record->appPath); + SetElementBundleName(&elementName, record->appName); + } else { + SetElementBundleName(&elementName, LAUNCHER_BUNDLE_NAME); + } + SetWantElement(want, elementName); + ClearElement(&elementName); + + auto ret = StartAbility(want); + ClearWant(want); + if (ret != ERR_OK) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "start ability failed [%{public}d]", ret); + } + return ret; } bool AbilityRecordManager::IsValidAbility(AbilityInfo *abilityInfo) @@ -161,16 +196,17 @@ int32_t AbilityRecordManager::StartAbility(const Want *want) return PARAM_NULL_ERROR; } - if (IsLauncher(bundleName)) { - // Launcher + if (BMSHelper::GetInstance().IsNativeApp(bundleName)) { + // Launcher or other Native App info->bundleName = Utils::Strdup(bundleName); info->path = nullptr; + info->isNative = true; } else { // JS APP #if ((defined OHOS_APPEXECFWK_BMS_BUNDLEMANAGER) || (defined APP_PLATFORM_WATCHGT)) AbilityInfo abilityInfo = { nullptr, nullptr }; QueryAbilityInfo(want, &abilityInfo); - if (!(BMSHelper::GetInstance().IsNativeApp(bundleName) || IsValidAbility(&abilityInfo))) { + if (!IsValidAbility(&abilityInfo)) { APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_UNKNOWN_BUNDLE_INFO); ClearAbilityInfo(&abilityInfo); AdapterFree(info); @@ -179,6 +215,7 @@ int32_t AbilityRecordManager::StartAbility(const Want *want) } info->bundleName = OHOS::Utils::Strdup(abilityInfo.bundleName); info->path = OHOS::Utils::Strdup(abilityInfo.srcPath); + info->isNative = false; ClearAbilityInfo(&abilityInfo); #else info->bundleName = Utils::Strdup(bundleName); @@ -220,47 +257,80 @@ int32_t AbilityRecordManager::StartAbility(AbilitySvcInfo *info) HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility"); auto topRecord = abilityStack_.GetTopAbility(); - if ((topRecord == nullptr) || (topRecord->appName == nullptr)) { - HILOG_ERROR(HILOG_MODULE_AAFWK, "StartAbility top null."); - return PARAM_NULL_ERROR; - } - uint16_t topToken = topRecord->token; - // start launcher - if (IsLauncher(info->bundleName)) { - UpdateRecord(info); - if (topToken != LAUNCHER_TOKEN && topRecord->state != SCHEDULE_BACKGROUND) { - HILOG_INFO(HILOG_MODULE_AAFWK, "Change Js app to background."); - (void) SchedulerLifecycleInner(topRecord, SLITE_STATE_BACKGROUND); - } else { - (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + + // if ((topRecord == nullptr) && (strcmp(info->bundleName, LAUNCHER_BUNDLE_NAME) != 0)) { + // HILOG_ERROR(HILOG_MODULE_AAFWK, "first ability should be launcher."); + // return PARAM_NULL_ERROR; + // } + + // // start launcher + // if (IsLauncher(info->bundleName)) { + // if (topRecord == nullptr) { + // return PreCheckStartAbility(info->bundleName, info->path, info->data, info->dataLength, info->isNative); + // } + // uint16_t topToken = topRecord->token; + // UpdateRecord(info); + // if (topToken != LAUNCHER_TOKEN && topRecord->state != SCHEDULE_BACKGROUND) { + // HILOG_INFO(HILOG_MODULE_AAFWK, "Change Js app to background."); + // // 1. topRecord is js ability and transfer to background + // // 2. launcher transfer to foreground + // (void) SendMsgToJsOrNativeAbility(topRecord, SLITE_STATE_BACKGROUND); + // } else { + // // 1. topRecord is launcher and transfer to foreground directly + // (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + // } + // return ERR_OK; + // } + + // if (!CheckResponse(info->bundleName)) { + // return PARAM_CHECK_ERROR; + // } + + // // start js app + // if (topRecord->state != SCHEDULE_STOP && topRecord->token != LAUNCHER_TOKEN) { + // // start app is top + // if (strcmp(info->bundleName, topRecord->appName) == 0) { + // if (topRecord->state == SCHEDULE_BACKGROUND) { + // HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility Resume app when background."); + // (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND); + // return ERR_OK; + // } + // HILOG_INFO(HILOG_MODULE_AAFWK, "Js app already started or starting."); + // } else { + // // js to js + // HILOG_INFO(HILOG_MODULE_AAFWK, "Terminate pre js app when js to js"); + // TerminateAbility(topRecord->token); + // pendingToken_ = GenerateToken(); + // } + // } + + + if (topRecord == nullptr) { + if (!IsLauncher(info->bundleName)) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "first ability should be launcher."); + return PARAM_NULL_ERROR; } - return ERR_OK; + // start launcher when boot + return PreCheckStartAbility(info->bundleName, info->path, info->data, info->dataLength, info->isNative); } if (!CheckResponse(info->bundleName)) { return PARAM_CHECK_ERROR; } - // start js app - if (topRecord->state != SCHEDULE_STOP && topRecord->token != LAUNCHER_TOKEN) { - // start app is top - if (strcmp(info->bundleName, topRecord->appName) == 0) { - if (topRecord->state == SCHEDULE_BACKGROUND) { - HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility Resume app when background."); - (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND); - return ERR_OK; - } - HILOG_INFO(HILOG_MODULE_AAFWK, "Js app already started or starting."); - } else { - // js to js - HILOG_INFO(HILOG_MODULE_AAFWK, "Terminate pre js app when js to js"); - TerminateAbility(topRecord->token); - pendingToken_ = GenerateToken(); + // the topAbility needs to be transferred to background + // start topAbility + if (strcmp(info->bundleName, topRecord->appName) == 0) { + if (topRecord->state == SCHEDULE_STOP) { + CreateAppTask(const_cast(topRecord)); } + return ERR_OK; } + (void) SendMsgToJsOrNativeAbility(topRecord, SLITE_STATE_BACKGROUND); + pendingToken_ = GenerateToken(); // application has not been launched and then to check priority and permission. - return PreCheckStartAbility(info->bundleName, info->path, info->data, info->dataLength); + return PreCheckStartAbility(info->bundleName, info->path, info->data, info->dataLength, info->isNative); } int32_t AbilityRecordManager::TerminateAbility(uint16_t token) @@ -272,23 +342,38 @@ int32_t AbilityRecordManager::TerminateAbility(uint16_t token) return PARAM_NULL_ERROR; } uint16_t topToken = topRecord->token; - if (token == LAUNCHER_TOKEN) { - // if js is in background, the launcher goes back to background and js goes to active - if (topToken != token && topRecord->state == SCHEDULE_BACKGROUND) { - HILOG_INFO(HILOG_MODULE_AAFWK, "Resume Js app [%{public}u]", topToken); - return SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND); - } + + // 1. only launcher in the ability stack + if (abilityStack_.Size() == 1 && topToken == LAUNCHER_TOKEN) { return ERR_OK; } - + // 2. terminate non-top ability if (token != topToken) { APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_UNKNOWN_ABILITY_TOKEN); DeleteRecordInfo(token); return -1; } - topRecord->isTerminated = true; + // 3. terminate top ability + abilityStack_.PopAbility(); + AbilityRecord *newTopRecord = const_cast(abilityStack_.GetTopAbility()); + if (newTopRecord == nullptr) { + APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_NO_ABILITY_RUNNING); + return PARAM_NULL_ERROR; + } + + if (token != LAUNCHER_TOKEN) { + topRecord->isTerminated = true; + abilityStack_.PushAbility(topRecord); + } else { + // launcher will not pop ability stack + abilityStack_.PopAbility(); + abilityStack_.PushAbility(topRecord); + abilityStack_.PushAbility(newTopRecord); + } + // TerminateAbility top js - return SchedulerLifecycleInner(topRecord, SLITE_STATE_BACKGROUND); + pendingToken_ = newTopRecord->token; + return SendMsgToJsOrNativeAbility(topRecord, SLITE_STATE_BACKGROUND); } int32_t AbilityRecordManager::ForceStopBundle(uint16_t token) @@ -309,8 +394,9 @@ int32_t AbilityRecordManager::ForceStopBundle(uint16_t token) if (launcherRecord == nullptr) { return PARAM_NULL_ERROR; } - if (launcherRecord->state != SCHEDULE_FOREGROUND) { - return SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + if (launcherRecord->state == SCHEDULE_STOP) { + //return SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + return StartAbility(launcherRecord); } return ERR_OK; } @@ -341,36 +427,44 @@ int32_t AbilityRecordManager::ForceStopBundleInner(uint16_t token) } int32_t AbilityRecordManager::PreCheckStartAbility( - const char *bundleName, const char *path, const void *data, uint16_t dataLength) + const char *bundleName, const char *path, const void *data, uint16_t dataLength, bool isNative) { - if (path == nullptr) { + if ((path == nullptr) && !isNative) { HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility path is null."); return PARAM_NULL_ERROR; } auto curRecord = abilityList_.Get(bundleName); + AbilityRecord *record = nullptr; if (curRecord != nullptr) { - if (curRecord->state == SCHEDULE_FOREGROUND) { + if (curRecord->state != SCHEDULE_STOP) { HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility current state active."); - } else if (curRecord->state == SCHEDULE_BACKGROUND) { - SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND); + } else { + // update ability stack and move the ability to the top of ability stack + abilityStack_.Erase(curRecord); + abilityStack_.PushAbility(curRecord); + pendingToken_ = curRecord->token; + return ERR_OK; } - return ERR_OK; - } - auto record = new AbilityRecord(); - if (pendingToken_ != 0) { - record->token = pendingToken_; } else { - record->token = GenerateToken(); + record = new AbilityRecord(); + if (pendingToken_ != 0) { + record->token = pendingToken_; + } else { + record->token = GenerateToken(); + } + record->SetAppName(bundleName); + record->SetAppPath(path); + record->SetWantData(data, dataLength); + record->state = SCHEDULE_STOP; + record->isNativeApp = isNative; + abilityList_.Add(record); + abilityStack_.PushAbility(record); } - record->SetAppName(bundleName); - record->SetAppPath(path); - record->SetWantData(data, dataLength); - record->isNativeApp = BMSHelper::GetInstance().IsNativeApp(bundleName); - record->state = SCHEDULE_STOP; - abilityList_.Add(record); + if (pendingToken_ == 0 && CreateAppTask(record) != ERR_OK) { HILOG_ERROR(HILOG_MODULE_AAFWK, "CheckResponse CreateAppTask fail"); abilityList_.Erase(record->token); + abilityStack_.Erase(record); delete record; return CREATE_APPTASK_ERROR; } @@ -398,13 +492,15 @@ int32_t AbilityRecordManager::CreateAppTask(AbilityRecord *record) HILOG_ERROR(HILOG_MODULE_AAFWK, "CreateAppTask fail: null"); return PARAM_NULL_ERROR; } + if (record->isNativeApp) { - record->abilityThread = AbilityThreadLoader::GetInstance().CreateAbilityThread( - AbilityThreadCreatorType::NATIVE_CREATOR); + record->abilityThread = + AbilityThreadLoader::GetInstance().CreateAbilityThread(AbilityThreadCreatorType::NATIVE_CREATOR); } else { - record->abilityThread = AbilityThreadLoader::GetInstance().CreateAbilityThread( - AbilityThreadCreatorType::JS_CREATOR); + record->abilityThread = + AbilityThreadLoader::GetInstance().CreateAbilityThread(AbilityThreadCreatorType::JS_CREATOR); } + if (record->abilityThread == nullptr) { return MEMORY_MALLOC_ERROR; } @@ -417,18 +513,8 @@ int32_t AbilityRecordManager::CreateAppTask(AbilityRecord *record) record->taskId = record->abilityThread->appTaskId_; record->jsAppQueueId = record->abilityThread->messageQueueId_; record->state = SCHEDULE_STOP; - abilityStack_.PushAbility(record); APP_EVENT(MT_ACE_APP_START); - if (nativeAbility_ != nullptr) { - if (SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND) != 0) { - APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_LAUNCHER_EXIT_FAILED); - HILOG_INFO(HILOG_MODULE_AAFWK, "CreateAppTask Fail to hide launcher"); - abilityStack_.PopAbility(); - return SCHEDULER_LIFECYCLE_ERROR; - } - } else { - SchedulerLifecycle(record->token, SLITE_STATE_INITIAL); - } + SchedulerLifecycle(record->token, SLITE_STATE_INITIAL); return ERR_OK; } @@ -438,7 +524,7 @@ uint16_t AbilityRecordManager::GenerateToken() if (token == UINT16_MAX - 1) { token = LAUNCHER_TOKEN; } - return ++token; + return token++; } void AbilityRecordManager::DeleteRecordInfo(uint16_t token) @@ -448,15 +534,7 @@ void AbilityRecordManager::DeleteRecordInfo(uint16_t token) return; } if (token != LAUNCHER_TOKEN) { - if (record->state != SCHEDULE_STOP) { - if (record->abilityThread != nullptr) { - record->abilityThread->ReleaseAbilityThread(); - delete record->abilityThread; - record->abilityThread = nullptr; - } - // free all JS native memory after exiting it - // CleanTaskMem(taskId) - } + DeleteAbilityThread(record); // record app info event when stop app RecordAbiityInfoEvt(record->GetAppName()); } @@ -465,6 +543,19 @@ void AbilityRecordManager::DeleteRecordInfo(uint16_t token) delete record; } +void AbilityRecordManager::DeleteAbilityThread(AbilityRecord *record) +{ + if (record->state != SCHEDULE_STOP) { + if (record->abilityThread != nullptr) { + record->abilityThread->ReleaseAbilityThread(); + delete record->abilityThread; + record->abilityThread = nullptr; + } + // free all JS native memory after exiting it + // CleanTaskMem(taskId) + } +} + void AbilityRecordManager::OnCreateDone(uint16_t token) { SetAbilityState(token, SCHEDULE_INITED); @@ -482,11 +573,6 @@ void AbilityRecordManager::OnForegroundDone(uint16_t token) // the launcher foreground if (token == LAUNCHER_TOKEN) { - if (nativeAbility_ == nullptr || nativeAbility_->GetState() != SLITE_STATE_FOREGROUND) { - HILOG_ERROR(HILOG_MODULE_AAFWK, "native ability is in wrong state : %{public}d", - nativeAbility_->GetState()); - return; - } if (topRecord->token != LAUNCHER_TOKEN) { int abilityState = SLITE_STATE_UNINITIALIZED; if (topRecord->state == SCHEDULE_FOREGROUND) { @@ -502,7 +588,7 @@ void AbilityRecordManager::OnForegroundDone(uint16_t token) abilityStack_.PopAbility(); DeleteRecordInfo(topRecord->token); } else if (topRecord->isTerminated) { - (void) SchedulerLifecycleInner(topRecord, SLITE_STATE_UNINITIALIZED); + (void) SendMsgToJsOrNativeAbility(topRecord, SLITE_STATE_UNINITIALIZED); } } return; @@ -516,34 +602,50 @@ void AbilityRecordManager::OnForegroundDone(uint16_t token) void AbilityRecordManager::OnBackgroundDone(uint16_t token) { HILOG_INFO(HILOG_MODULE_AAFWK, "OnBackgroundDone [%{public}u]", token); - SetAbilityState(token, SCHEDULE_BACKGROUND); - auto topRecord = const_cast(abilityStack_.GetTopAbility()); - if (topRecord == nullptr) { + if (abilityList_.Get(token) == nullptr) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "token is not found"); return; } - // the js background - if (token != LAUNCHER_TOKEN) { - if (topRecord->token == token) { - APP_EVENT(MT_ACE_APP_BACKGROUND); - (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); - } - return; - } - // the launcher background - if (topRecord->token != LAUNCHER_TOKEN) { - if (topRecord->state == SCHEDULE_STOP) { - (void) SchedulerLifecycleInner(topRecord, SLITE_STATE_INITIAL); - } else { - (void) SchedulerLifecycleInner(topRecord, SLITE_STATE_FOREGROUND); - } + SetAbilityState(token, SCHEDULE_BACKGROUND); + // auto topRecord = const_cast(abilityStack_.GetTopAbility()); + // if (topRecord == nullptr) { + // return; + // } + // // the js background + // if (token != LAUNCHER_TOKEN) { + // if (topRecord->token == token) { + // APP_EVENT(MT_ACE_APP_BACKGROUND); + // (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + // } + // return; + // } + // // the launcher background + // if (topRecord->token != LAUNCHER_TOKEN) { + // if (topRecord->state == SCHEDULE_STOP) { + // (void) SendMsgToJsOrNativeAbility(topRecord, SLITE_STATE_INITIAL); + // } else { + // (void) SendMsgToJsOrNativeAbility(topRecord, SLITE_STATE_FOREGROUND); + // } + // if (GetCleanAbilityDataFlag()) { + // HILOG_INFO(HILOG_MODULE_AAFWK, "OnBackgroundDone clean launcher record data"); + // AbilityRecord *record = abilityList_.Get(token); + // record->SetWantData(nullptr, 0); + // SetCleanAbilityDataFlag(false); + // } + // return; + // } + + if (token == LAUNCHER_TOKEN) { if (GetCleanAbilityDataFlag()) { HILOG_INFO(HILOG_MODULE_AAFWK, "OnBackgroundDone clean launcher record data"); AbilityRecord *record = abilityList_.Get(token); record->SetWantData(nullptr, 0); SetCleanAbilityDataFlag(false); } - return; } + + (void) SchedulerLifecycle(token, SLITE_STATE_UNINITIALIZED); + HILOG_WARN(HILOG_MODULE_AAFWK, "Js app exit, but has no js app."); } @@ -551,38 +653,68 @@ void AbilityRecordManager::OnDestroyDone(uint16_t token) { HILOG_INFO(HILOG_MODULE_AAFWK, "OnDestroyDone [%{public}u]", token); // the launcher destroy - if (token == LAUNCHER_TOKEN) { - SetAbilityState(token, SCHEDULE_STOP); + // if (token == LAUNCHER_TOKEN) { + // SetAbilityState(token, SCHEDULE_STOP); + // return; + // } + // auto topRecord = abilityStack_.GetTopAbility(); + // if ((topRecord == nullptr) || (topRecord->token != token)) { + // SetAbilityState(token, SCHEDULE_STOP); + // DeleteRecordInfo(token); + // return; + // } + // APP_EVENT(MT_ACE_APP_STOP); + // abilityStack_.PopAbility(); + // DeleteRecordInfo(token); + // SetAbilityState(token, SCHEDULE_STOP); + + auto onDestroyRecord = abilityList_.Get(token); + if (onDestroyRecord == nullptr) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "token is not found"); return; } - auto topRecord = abilityStack_.GetTopAbility(); - if ((topRecord == nullptr) || (topRecord->token != token)) { - SetAbilityState(token, SCHEDULE_STOP); + // 1. ability is terminated and pop out ability stack + if (onDestroyRecord->isTerminated) { + APP_EVENT(MT_ACE_APP_STOP); DeleteRecordInfo(token); - return; - } - APP_EVENT(MT_ACE_APP_STOP); - abilityStack_.PopAbility(); - DeleteRecordInfo(token); - SetAbilityState(token, SCHEDULE_STOP); - - // no pending token - if (pendingToken_ == 0) { - (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); - return; + } else { + // 2. ability is transferred to SCHEDULE_STOP state and still keep in the ability stack + DeleteAbilityThread(onDestroyRecord); + SetAbilityState(token, SCHEDULE_STOP); } + // AbilityRecord *topRecord = abilityStack_.GetTopAbility(); + // if (topRecord == nullptr) { + // HILOG_ERROR(HILOG_MODULE_AAFWK, "ability stack is empty"); + // return; + // } + // // no pending token + // if (pendingToken_ == 0) { + // if (topRecord->state == SCHEDULE_STOP) { + // (void) SchedulerLifecycle(topRecord->token, SLITE_STATE_INITIAL); + // return; + // } + // HILOG_ERROR(HILOG_MODULE_AAFWK, "state of top ability is invalid"); + // return; + // } // start pending token - auto record = abilityList_.Get(pendingToken_); - if (record == nullptr) { - return; - } - if (CreateAppTask(record) != ERR_OK) { - abilityList_.Erase(pendingToken_); - delete record; - (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + if (pendingToken_ != 0) { + auto record = abilityList_.Get(pendingToken_); + if (record == nullptr) { + return; + } + if (CreateAppTask(record) != ERR_OK) { + abilityList_.Erase(pendingToken_); + abilityStack_.Erase(record); + delete record; + //(void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + } + pendingToken_ = 0; + } else { + // start launcher + auto launcherRecord = abilityStack_.GetTopAbility(); + StartAbility(launcherRecord); } - pendingToken_ = 0; } int32_t AbilityRecordManager::SchedulerLifecycle(uint64_t token, int32_t state) @@ -591,7 +723,7 @@ int32_t AbilityRecordManager::SchedulerLifecycle(uint64_t token, int32_t state) if (record == nullptr) { return PARAM_NULL_ERROR; } - return SchedulerLifecycleInner(record, state); + return SendMsgToJsOrNativeAbility(record, state); } void AbilityRecordManager::SetAbilityState(uint64_t token, int32_t state) @@ -603,66 +735,6 @@ void AbilityRecordManager::SetAbilityState(uint64_t token, int32_t state) record->state = state; } -int32_t AbilityRecordManager::SchedulerLifecycleInner(const AbilityRecord *record, int32_t state) -{ - if (record == nullptr) { - return PARAM_NULL_ERROR; - } - // dispatch js life cycle - if (record->token != LAUNCHER_TOKEN) { - (void) SendMsgToJsAbility(state, record); - return ERR_OK; - } - // dispatch native life cycle - if (nativeAbility_ == nullptr) { - return PARAM_NULL_ERROR; - } - // malloc want memory and release after use - Want *info = static_cast(AdapterMalloc(sizeof(Want))); - if (info == nullptr) { - return MEMORY_MALLOC_ERROR; - } - info->element = nullptr; - info->data = nullptr; - info->dataLength = 0; - info->appPath = nullptr; - - ElementName elementName = {}; - SetElementBundleName(&elementName, LAUNCHER_BUNDLE_NAME); - SetWantElement(info, elementName); - ClearElement(&elementName); - if (record->abilityData != nullptr) { - SetWantData(info, record->abilityData->wantData, record->abilityData->wantDataSize); - } else { - SetWantData(info, nullptr, 0); - } - SchedulerAbilityLifecycle(nativeAbility_, *info, state); - ClearWant(info); - AdapterFree(info); - return ERR_OK; -} - -void AbilityRecordManager::SchedulerAbilityLifecycle(SliteAbility *ability, const Want &want, int32_t state) -{ - if (ability == nullptr) { - return; - } - switch (state) { - case SLITE_STATE_FOREGROUND: { - ability->OnForeground(want); - break; - } - case SLITE_STATE_BACKGROUND: { - ability->OnBackground(); - break; - } - default: { - break; - } - } - return; -} - int32_t AbilityRecordManager::SchedulerLifecycleDone(uint64_t token, int32_t state) { switch (state) { @@ -689,7 +761,7 @@ int32_t AbilityRecordManager::SchedulerLifecycleDone(uint64_t token, int32_t sta return ERR_OK; } -bool AbilityRecordManager::SendMsgToJsAbility(int32_t state, const AbilityRecord *record) +bool AbilityRecordManager::SendMsgToJsOrNativeAbility(const AbilityRecord *record, int32_t state) { if (record == nullptr) { return false; @@ -733,6 +805,11 @@ Want *AbilityRecordManager::CreateWant(const AbilityRecord *record) SetElementBundleName(&elementName, record->appName); SetWantElement(want, elementName); ClearElement(&elementName); + if (record->abilityData != nullptr) { + SetWantData(want, record->abilityData->wantData, record->abilityData->wantDataSize); + } else { + SetWantData(want, nullptr, 0); + } return want; } diff --git a/services/abilitymgr_lite/src/slite/ability_stack.cpp b/services/abilitymgr_lite/src/slite/ability_stack.cpp index 56648df..b475e94 100644 --- a/services/abilitymgr_lite/src/slite/ability_stack.cpp +++ b/services/abilitymgr_lite/src/slite/ability_stack.cpp @@ -54,5 +54,10 @@ void AbilityStack::Erase(AbilityRecord *record) node = node->next_; } } + +uint32_t AbilityStack::Size() const +{ + return abilityStack_.Size(); +} } // namespace AbilitySlite } // namespace OHOS \ No newline at end of file diff --git a/services/abilitymgr_lite/src/slite/ability_thread.cpp b/services/abilitymgr_lite/src/slite/ability_thread.cpp index 60540be..1ebcdda 100644 --- a/services/abilitymgr_lite/src/slite/ability_thread.cpp +++ b/services/abilitymgr_lite/src/slite/ability_thread.cpp @@ -15,16 +15,16 @@ #include "ability_thread.h" +#include + #include "ability_errors.h" #include "ability_manager_inner.h" +#include "bms_helper.h" #include "slite_ability_state.h" #include "los_task.h" #include "ability_inner_message.h" #include "adapter.h" -extern "C" void LP_TaskBegin(); -extern "C" void LP_TaskEnd(); - namespace OHOS { namespace AbilitySlite { @@ -32,65 +32,22 @@ AbilityThread::AbilityThread() = default; AbilityThread::~AbilityThread() { - delete ability_; - ability_ = nullptr; - if (messageQueueId_ != nullptr) { - osMessageQueueDelete(messageQueueId_); - } - messageQueueId_ = nullptr; -} - -void AbilityThread::AppTaskHandler(UINT32 uwArg) -{ - auto messageQueueId = reinterpret_cast(uwArg); - if (messageQueueId == nullptr) { - return; - } - AbilityThread *defaultAbilityThread = nullptr; - - for (;;) { - SliteAbilityInnerMsg innerMsg; - uint8_t prio = 0; - osStatus_t ret = osMessageQueueGet(messageQueueId, &innerMsg, &prio, osWaitForever); - if (ret != osOK) { - return; - } - AbilityThread *abilityThread = innerMsg.abilityThread; - if (abilityThread == nullptr) { - if (defaultAbilityThread == nullptr) { - continue; + if (ability_ != nullptr && ability_->bundleName_ != nullptr) { + if (!BMSHelper::GetInstance().IsNativeApp(ability_->bundleName_)) { + // js ability thread deconstruction + delete ability_; + ability_ = nullptr; + if (messageQueueId_ != nullptr) { + osMessageQueueDelete(messageQueueId_); + } + messageQueueId_ = nullptr; + } else { + // native ability thread deconstruction + if (strcmp(ability_->bundleName_, LAUNCHER_BUNDLE_NAME) != 0) { + delete ability_; + ability_ = nullptr; } - abilityThread = defaultAbilityThread; - } - LP_TaskBegin(); - switch (innerMsg.msgId) { - case SliteAbilityMsgId::CREATE: - defaultAbilityThread = abilityThread; - abilityThread->HandleCreate(innerMsg.want); - ClearWant(innerMsg.want); - AdapterFree(innerMsg.want); - innerMsg.want = nullptr; - break; - case SliteAbilityMsgId::FOREGROUND: - abilityThread->HandleForeground(innerMsg.want); - ClearWant(innerMsg.want); - AdapterFree(innerMsg.want); - innerMsg.want = nullptr; - break; - case SliteAbilityMsgId::BACKGROUND: - abilityThread->HandleBackground(); - break; - case SliteAbilityMsgId::DESTROY: - abilityThread->HandleDestroy(); - LP_TaskEnd(); - return; // here exit the loop, and abort all messages afterwards - default: - if (abilityThread->ability_ != nullptr) { - abilityThread->ability_->HandleExtraMessage(innerMsg); - } - break; } - LP_TaskEnd(); } } diff --git a/services/abilitymgr_lite/src/slite/js_ability_thread.cpp b/services/abilitymgr_lite/src/slite/js_ability_thread.cpp index 839a558..7eefedb 100644 --- a/services/abilitymgr_lite/src/slite/js_ability_thread.cpp +++ b/services/abilitymgr_lite/src/slite/js_ability_thread.cpp @@ -19,6 +19,7 @@ #include "ability_errors.h" #include "ability_inner_message.h" #include "ability_manager_inner.h" +#include "adapter.h" #include "dummy_js_ability.h" #include "js_ability.h" #include "js_async_work.h" @@ -58,7 +59,7 @@ int32_t JsAbilityThread::InitAbilityThread(const AbilityRecord *abilityRecord) TSK_INIT_PARAM_S stTskInitParam = { nullptr }; LOS_TaskLock(); - stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC) (AbilityThread::AppTaskHandler); + stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC) (JsAbilityThread::AppTaskHandler); stTskInitParam.uwStackSize = TASK_STACK_SIZE; stTskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST - APP_TASK_PRI; stTskInitParam.pcName = g_jsAppTask; @@ -96,9 +97,61 @@ int32_t JsAbilityThread::ReleaseAbilityThread() appTaskId_ = 0; osMessageQueueDelete(messageQueueId_); messageQueueId_ = nullptr; - delete ability_; - ability_ = nullptr; return ERR_OK; } + +void JsAbilityThread::AppTaskHandler(UINT32 uwArg) +{ + auto messageQueueId = reinterpret_cast(uwArg); + if (messageQueueId == nullptr) { + return; + } + AbilityThread *defaultAbilityThread = nullptr; + + for (;;) { + SliteAbilityInnerMsg innerMsg; + uint8_t prio = 0; + osStatus_t ret = osMessageQueueGet(messageQueueId, &innerMsg, &prio, osWaitForever); + if (ret != osOK) { + return; + } + AbilityThread *abilityThread = innerMsg.abilityThread; + if (abilityThread == nullptr) { + if (defaultAbilityThread == nullptr) { + continue; + } + abilityThread = defaultAbilityThread; + } + LP_TaskBegin(); + switch (innerMsg.msgId) { + case SliteAbilityMsgId::CREATE: + defaultAbilityThread = abilityThread; + abilityThread->HandleCreate(innerMsg.want); + ClearWant(innerMsg.want); + AdapterFree(innerMsg.want); + innerMsg.want = nullptr; + break; + case SliteAbilityMsgId::FOREGROUND: + abilityThread->HandleForeground(innerMsg.want); + ClearWant(innerMsg.want); + AdapterFree(innerMsg.want); + innerMsg.want = nullptr; + break; + case SliteAbilityMsgId::BACKGROUND: + abilityThread->HandleBackground(); + break; + case SliteAbilityMsgId::DESTROY: + abilityThread->HandleDestroy(); + LP_TaskEnd(); + return; // here exit the loop, and abort all messages afterwards + default: + if (abilityThread->ability_ != nullptr) { + abilityThread->ability_->HandleExtraMessage(innerMsg); + } + break; + } + LP_TaskEnd(); + } +} } // namespace AbilitySlite } // namespace OHOS diff --git a/services/abilitymgr_lite/src/slite/native_ability_thread.cpp b/services/abilitymgr_lite/src/slite/native_ability_thread.cpp index 1d5572b..d8b927b 100644 --- a/services/abilitymgr_lite/src/slite/native_ability_thread.cpp +++ b/services/abilitymgr_lite/src/slite/native_ability_thread.cpp @@ -15,12 +15,15 @@ #include "native_ability_thread.h" +#include + #include "aafwk_event_error_id.h" #include "aafwk_event_error_code.h" #include "ability_manager_inner.h" #include "ability_errors.h" #include "ability_inner_message.h" #include "ability_record_manager.h" +#include "adapter.h" #include "slite_ability_state.h" #include "ability_thread.h" #include "abilityms_log.h" @@ -29,12 +32,13 @@ namespace OHOS { namespace AbilitySlite { - +static char NATIVE_APP_TASK[] = "NativeAppTask"; constexpr int32_t APP_TASK_PRI = 25; constexpr int32_t QUEUE_LENGTH = 32; osMessageQueueId_t NativeAbilityThread::nativeQueueId = nullptr; UINT32 NativeAbilityThread::nativeTaskId = 0; +SliteAbility *NativeAbilityThread::LauncherAbility_ = nullptr; NativeAbilityThread::NativeAbilityThread() = default; @@ -68,10 +72,10 @@ int32_t NativeAbilityThread::InitAbilityThread(const AbilityRecord *abilityRecor if (nativeTaskId == 0) { TSK_INIT_PARAM_S stTskInitParam = { 0 }; LOS_TaskLock(); - stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC) (AbilityThread::AppTaskHandler); + stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC) (NativeAbilityThread::NativeAppTaskHandler); stTskInitParam.uwStackSize = TASK_STACK_SIZE; stTskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST - APP_TASK_PRI; - stTskInitParam.pcName = const_cast("AppTask"); + stTskInitParam.pcName = NATIVE_APP_TASK; stTskInitParam.uwResved = 0; stTskInitParam.uwArg = reinterpret_cast((uintptr_t) messageQueueId_); uint32_t ret = LOS_TaskCreate(&nativeTaskId, &stTskInitParam); @@ -83,10 +87,25 @@ int32_t NativeAbilityThread::InitAbilityThread(const AbilityRecord *abilityRecor } } appTaskId_ = nativeTaskId; - state_ = AbilityThreadState::ABILITY_THREAD_INITIALIZED; - ability_ = SliteAbilityLoader::GetInstance().CreateAbility(SliteAbilityType::NATIVE_ABILITY, - abilityRecord->appName); + if (LauncherAbility_ != nullptr) { + if (LauncherAbility_->bundleName_ == nullptr) { + return PARAM_NULL_ERROR; + } + if (strcmp(LauncherAbility_->bundleName_, abilityRecord->appName) != 0) { + ability_ = SliteAbilityLoader::GetInstance().CreateAbility(SliteAbilityType::NATIVE_ABILITY, + abilityRecord->appName); + } else { + ability_ = LauncherAbility_; + } + } else { + if (strcmp(abilityRecord->appName, LAUNCHER_BUNDLE_NAME) == 0) { + LauncherAbility_ = SliteAbilityLoader::GetInstance().CreateAbility(SliteAbilityType::NATIVE_ABILITY, + abilityRecord->appName); + } + ability_ = LauncherAbility_; + } + if (ability_ == nullptr) { HILOG_INFO(HILOG_MODULE_AAFWK, "NativeAbility create fail"); return MEMORY_MALLOC_ERROR; @@ -103,9 +122,68 @@ int32_t NativeAbilityThread::ReleaseAbilityThread() HILOG_ERROR(HILOG_MODULE_AAFWK, "NativeAbilityThread release fail, the AbilityThread is not inited"); return PARAM_CHECK_ERROR; } - delete ability_; - ability_ = nullptr; + if (ability_->bundleName_ == nullptr) { + return PARAM_NULL_ERROR; + } + + if (strcmp(ability_->bundleName_, LAUNCHER_BUNDLE_NAME) != 0) { + delete ability_; + ability_ = nullptr; + } return ERR_OK; } + +void NativeAbilityThread::NativeAppTaskHandler(UINT32 uwArg) +{ + auto messageQueueId = reinterpret_cast(uwArg); + if (messageQueueId == nullptr) { + return; + } + AbilityThread *defaultAbilityThread = nullptr; + + for (;;) { + SliteAbilityInnerMsg innerMsg; + uint8_t prio = 0; + osStatus_t ret = osMessageQueueGet(messageQueueId, &innerMsg, &prio, osWaitForever); + if (ret != osOK) { + return; + } + AbilityThread *abilityThread = innerMsg.abilityThread; + if (abilityThread == nullptr) { + if (defaultAbilityThread == nullptr) { + continue; + } + abilityThread = defaultAbilityThread; + } + LP_TaskBegin(); + switch (innerMsg.msgId) { + case SliteAbilityMsgId::CREATE: + defaultAbilityThread = abilityThread; + abilityThread->HandleCreate(innerMsg.want); + ClearWant(innerMsg.want); + AdapterFree(innerMsg.want); + innerMsg.want = nullptr; + break; + case SliteAbilityMsgId::FOREGROUND: + abilityThread->HandleForeground(innerMsg.want); + ClearWant(innerMsg.want); + AdapterFree(innerMsg.want); + innerMsg.want = nullptr; + break; + case SliteAbilityMsgId::BACKGROUND: + abilityThread->HandleBackground(); + break; + case SliteAbilityMsgId::DESTROY: + abilityThread->HandleDestroy(); + break; // this task will be kept alive + default: + if (abilityThread->ability_ != nullptr) { + abilityThread->ability_->HandleExtraMessage(innerMsg); + } + break; + } + LP_TaskEnd(); + } +} } // namespace AbilitySlite } // namespace OHOS -- Gitee From 995e8f6276ef5b95fcc42288cb657b1bb2213424 Mon Sep 17 00:00:00 2001 From: s00494828 Date: Fri, 21 Apr 2023 14:19:15 +0800 Subject: [PATCH 2/4] remove redundant code Signed-off-by: s00494828 --- .../kits/ability_lite/slite/slite_ability.h | 1 + .../include/slite/ability_thread.h | 1 + .../src/slite/ability_record_manager.cpp | 118 ------------------ 3 files changed, 2 insertions(+), 118 deletions(-) diff --git a/interfaces/kits/ability_lite/slite/slite_ability.h b/interfaces/kits/ability_lite/slite/slite_ability.h index 386142a..3482a60 100755 --- a/interfaces/kits/ability_lite/slite/slite_ability.h +++ b/interfaces/kits/ability_lite/slite/slite_ability.h @@ -81,6 +81,7 @@ public: int GetState() const; char *bundleName_ = nullptr; + private: int abilityState_ = 0; }; diff --git a/services/abilitymgr_lite/include/slite/ability_thread.h b/services/abilitymgr_lite/include/slite/ability_thread.h index f0a2a92..aa806c9 100644 --- a/services/abilitymgr_lite/include/slite/ability_thread.h +++ b/services/abilitymgr_lite/include/slite/ability_thread.h @@ -27,6 +27,7 @@ extern "C" void LP_TaskEnd(); namespace OHOS { namespace AbilitySlite { constexpr char LAUNCHER_BUNDLE_NAME[] = "com.ohos.launcher"; + class AbilityRecord; enum class AbilityThreadState : int8_t { ABILITY_THREAD_UNINITIALIZED, diff --git a/services/abilitymgr_lite/src/slite/ability_record_manager.cpp b/services/abilitymgr_lite/src/slite/ability_record_manager.cpp index 29ec13e..561196f 100644 --- a/services/abilitymgr_lite/src/slite/ability_record_manager.cpp +++ b/services/abilitymgr_lite/src/slite/ability_record_manager.cpp @@ -46,7 +46,6 @@ namespace AbilitySlite { constexpr uint16_t LAUNCHER_TOKEN = 0; constexpr int32_t QUEUE_LENGTH = 32; constexpr int32_t APP_TASK_PRI = 25; -constexpr int32_t MAX_NATIVE_APP_SIZE = 200; // this size might be changed AbilityRecordManager::AbilityRecordManager() = default; @@ -57,19 +56,6 @@ AbilityRecordManager::~AbilityRecordManager() void AbilityRecordManager::StartLauncher() { - // AbilityRecord *launcherRecord = abilityList_.Get(LAUNCHER_TOKEN); - // if (launcherRecord != nullptr) { - // return; - // } - // auto record = new AbilityRecord(); - // record->SetAppName(LAUNCHER_BUNDLE_NAME); - // record->token = LAUNCHER_TOKEN; - // record->isNativeApp = true; - // record->state = SCHEDULE_FOREGROUND; - // record->taskId = LOS_CurTaskIDGet(); - // abilityList_.Add(record); - // abilityStack_.PushAbility(record); - // (void) SchedulerLifecycleInner(record, SLITE_STATE_FOREGROUND); AbilityRecord *launcherRecord = abilityList_.Get(LAUNCHER_TOKEN); if (launcherRecord != nullptr) { return; @@ -257,54 +243,6 @@ int32_t AbilityRecordManager::StartAbility(AbilitySvcInfo *info) HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility"); auto topRecord = abilityStack_.GetTopAbility(); - - // if ((topRecord == nullptr) && (strcmp(info->bundleName, LAUNCHER_BUNDLE_NAME) != 0)) { - // HILOG_ERROR(HILOG_MODULE_AAFWK, "first ability should be launcher."); - // return PARAM_NULL_ERROR; - // } - - // // start launcher - // if (IsLauncher(info->bundleName)) { - // if (topRecord == nullptr) { - // return PreCheckStartAbility(info->bundleName, info->path, info->data, info->dataLength, info->isNative); - // } - // uint16_t topToken = topRecord->token; - // UpdateRecord(info); - // if (topToken != LAUNCHER_TOKEN && topRecord->state != SCHEDULE_BACKGROUND) { - // HILOG_INFO(HILOG_MODULE_AAFWK, "Change Js app to background."); - // // 1. topRecord is js ability and transfer to background - // // 2. launcher transfer to foreground - // (void) SendMsgToJsOrNativeAbility(topRecord, SLITE_STATE_BACKGROUND); - // } else { - // // 1. topRecord is launcher and transfer to foreground directly - // (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); - // } - // return ERR_OK; - // } - - // if (!CheckResponse(info->bundleName)) { - // return PARAM_CHECK_ERROR; - // } - - // // start js app - // if (topRecord->state != SCHEDULE_STOP && topRecord->token != LAUNCHER_TOKEN) { - // // start app is top - // if (strcmp(info->bundleName, topRecord->appName) == 0) { - // if (topRecord->state == SCHEDULE_BACKGROUND) { - // HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility Resume app when background."); - // (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND); - // return ERR_OK; - // } - // HILOG_INFO(HILOG_MODULE_AAFWK, "Js app already started or starting."); - // } else { - // // js to js - // HILOG_INFO(HILOG_MODULE_AAFWK, "Terminate pre js app when js to js"); - // TerminateAbility(topRecord->token); - // pendingToken_ = GenerateToken(); - // } - // } - - if (topRecord == nullptr) { if (!IsLauncher(info->bundleName)) { HILOG_ERROR(HILOG_MODULE_AAFWK, "first ability should be launcher."); @@ -607,33 +545,6 @@ void AbilityRecordManager::OnBackgroundDone(uint16_t token) return; } SetAbilityState(token, SCHEDULE_BACKGROUND); - // auto topRecord = const_cast(abilityStack_.GetTopAbility()); - // if (topRecord == nullptr) { - // return; - // } - // // the js background - // if (token != LAUNCHER_TOKEN) { - // if (topRecord->token == token) { - // APP_EVENT(MT_ACE_APP_BACKGROUND); - // (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); - // } - // return; - // } - // // the launcher background - // if (topRecord->token != LAUNCHER_TOKEN) { - // if (topRecord->state == SCHEDULE_STOP) { - // (void) SendMsgToJsOrNativeAbility(topRecord, SLITE_STATE_INITIAL); - // } else { - // (void) SendMsgToJsOrNativeAbility(topRecord, SLITE_STATE_FOREGROUND); - // } - // if (GetCleanAbilityDataFlag()) { - // HILOG_INFO(HILOG_MODULE_AAFWK, "OnBackgroundDone clean launcher record data"); - // AbilityRecord *record = abilityList_.Get(token); - // record->SetWantData(nullptr, 0); - // SetCleanAbilityDataFlag(false); - // } - // return; - // } if (token == LAUNCHER_TOKEN) { if (GetCleanAbilityDataFlag()) { @@ -652,21 +563,6 @@ void AbilityRecordManager::OnBackgroundDone(uint16_t token) void AbilityRecordManager::OnDestroyDone(uint16_t token) { HILOG_INFO(HILOG_MODULE_AAFWK, "OnDestroyDone [%{public}u]", token); - // the launcher destroy - // if (token == LAUNCHER_TOKEN) { - // SetAbilityState(token, SCHEDULE_STOP); - // return; - // } - // auto topRecord = abilityStack_.GetTopAbility(); - // if ((topRecord == nullptr) || (topRecord->token != token)) { - // SetAbilityState(token, SCHEDULE_STOP); - // DeleteRecordInfo(token); - // return; - // } - // APP_EVENT(MT_ACE_APP_STOP); - // abilityStack_.PopAbility(); - // DeleteRecordInfo(token); - // SetAbilityState(token, SCHEDULE_STOP); auto onDestroyRecord = abilityList_.Get(token); if (onDestroyRecord == nullptr) { @@ -682,20 +578,6 @@ void AbilityRecordManager::OnDestroyDone(uint16_t token) DeleteAbilityThread(onDestroyRecord); SetAbilityState(token, SCHEDULE_STOP); } - // AbilityRecord *topRecord = abilityStack_.GetTopAbility(); - // if (topRecord == nullptr) { - // HILOG_ERROR(HILOG_MODULE_AAFWK, "ability stack is empty"); - // return; - // } - // // no pending token - // if (pendingToken_ == 0) { - // if (topRecord->state == SCHEDULE_STOP) { - // (void) SchedulerLifecycle(topRecord->token, SLITE_STATE_INITIAL); - // return; - // } - // HILOG_ERROR(HILOG_MODULE_AAFWK, "state of top ability is invalid"); - // return; - // } // start pending token if (pendingToken_ != 0) { -- Gitee From 6b206beb1c2f0e7e45d870aa78d4ce10810d26ce Mon Sep 17 00:00:00 2001 From: s00494828 Date: Fri, 21 Apr 2023 18:39:21 +0800 Subject: [PATCH 3/4] fix problem Signed-off-by: s00494828 --- interfaces/kits/ability_lite/slite/slite_ability.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/kits/ability_lite/slite/slite_ability.h b/interfaces/kits/ability_lite/slite/slite_ability.h index 3482a60..859b2df 100755 --- a/interfaces/kits/ability_lite/slite/slite_ability.h +++ b/interfaces/kits/ability_lite/slite/slite_ability.h @@ -36,7 +36,7 @@ namespace AbilitySlite { */ class SliteAbility : public LiteContext { public: - SliteAbility(const char *bundleName); + SliteAbility(const char *bundleName = nullptr); virtual ~SliteAbility(); -- Gitee From c839cde22316c782b1a13225d9c92b3c396b3936 Mon Sep 17 00:00:00 2001 From: s00494828 Date: Sun, 23 Apr 2023 15:02:49 +0800 Subject: [PATCH 4/4] fix problem of creating task failed Signed-off-by: s00494828 --- services/abilitymgr_lite/BUILD.gn | 14 +- .../include/slite/ability_record_manager.h | 5 +- .../src/slite/ability_record_manager.cpp | 298 +++++++++++++++++- .../src/slite/native_ability_thread.cpp | 2 +- 4 files changed, 306 insertions(+), 13 deletions(-) diff --git a/services/abilitymgr_lite/BUILD.gn b/services/abilitymgr_lite/BUILD.gn index bf48124..47f555d 100644 --- a/services/abilitymgr_lite/BUILD.gn +++ b/services/abilitymgr_lite/BUILD.gn @@ -13,6 +13,10 @@ import("//build/lite/config/component/lite_component.gni") import("//build/lite/config/subsystem/aafwk/config.gni") +declare_args() { + enable_ohos_aafwk_multi_tasks_feature = false +} + lite_library("abilityms") { if (ohos_kernel_type == "liteos_m") { target_type = "static_library" @@ -39,8 +43,14 @@ lite_library("abilityms") { if (defined(config_ohos_aafwk_aafwk_lite_task_stack_size) && config_ohos_aafwk_aafwk_lite_task_stack_size > 0) { - defines += - [ "TASK_STACK_SIZE=$config_ohos_aafwk_aafwk_lite_task_stack_size" ] + defines += [ + "TASK_STACK_SIZE=$config_ohos_aafwk_aafwk_lite_task_stack_size", + "NATIVE_TASK_STACK_SIZE=$config_ohos_aafwk_ams_task_size" + ] + } + + if (enable_ohos_aafwk_multi_tasks_feature == true) { + defines += [ "_MINI_MULTI_TASKS_" ] } deps = [ diff --git a/services/abilitymgr_lite/include/slite/ability_record_manager.h b/services/abilitymgr_lite/include/slite/ability_record_manager.h index 28fad19..a163a26 100644 --- a/services/abilitymgr_lite/include/slite/ability_record_manager.h +++ b/services/abilitymgr_lite/include/slite/ability_record_manager.h @@ -86,7 +86,8 @@ private: int32_t StartRemoteAbility(const Want *want); - int32_t PreCheckStartAbility(const char *bundleName, const char *path, const void *data, uint16_t dataLength, bool isNative); + int32_t PreCheckStartAbility(const char *bundleName, const char *path, const void *data, uint16_t dataLength, + bool isNative = false); bool CheckResponse(const char *bundleName); @@ -94,6 +95,8 @@ private: int32_t SchedulerLifecycleInner(const AbilityRecord *record, int32_t state); + bool SendMsgToJsAbility(int32_t state, const AbilityRecord *record); + void SchedulerAbilityLifecycle(SliteAbility *ability, const Want &want, int32_t state); int32_t CreateAppTask(AbilityRecord *record); diff --git a/services/abilitymgr_lite/src/slite/ability_record_manager.cpp b/services/abilitymgr_lite/src/slite/ability_record_manager.cpp index 561196f..177ec7c 100644 --- a/services/abilitymgr_lite/src/slite/ability_record_manager.cpp +++ b/services/abilitymgr_lite/src/slite/ability_record_manager.cpp @@ -60,7 +60,21 @@ void AbilityRecordManager::StartLauncher() if (launcherRecord != nullptr) { return; } + +#ifndef _MINI_MULTI_TASKS_ + auto record = new AbilityRecord(); + record->SetAppName(LAUNCHER_BUNDLE_NAME); + record->token = LAUNCHER_TOKEN; + record->isNativeApp = true; + record->state = SCHEDULE_FOREGROUND; + record->taskId = LOS_CurTaskIDGet(); + abilityList_.Add(record); + abilityStack_.PushAbility(record); + (void) SchedulerLifecycleInner(record, SLITE_STATE_FOREGROUND); +#else // define _MINI_MULTI_TASKS_ StartAbility(launcherRecord); +#endif + } int32_t AbilityRecordManager::StartAbility(const AbilityRecord *record) @@ -182,7 +196,7 @@ int32_t AbilityRecordManager::StartAbility(const Want *want) return PARAM_NULL_ERROR; } - if (BMSHelper::GetInstance().IsNativeApp(bundleName)) { + if (IsLauncher(bundleName) || BMSHelper::GetInstance().IsNativeApp(bundleName)) { // Launcher or other Native App info->bundleName = Utils::Strdup(bundleName); info->path = nullptr; @@ -243,6 +257,49 @@ int32_t AbilityRecordManager::StartAbility(AbilitySvcInfo *info) HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility"); auto topRecord = abilityStack_.GetTopAbility(); +#ifndef _MINI_MULTI_TASKS_ + if ((topRecord == nullptr) || (topRecord->appName == nullptr)) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "StartAbility top null."); + return PARAM_NULL_ERROR; + } + uint16_t topToken = topRecord->token; + // start launcher + if (IsLauncher(info->bundleName)) { + UpdateRecord(info); + if (topToken != LAUNCHER_TOKEN && topRecord->state != SCHEDULE_BACKGROUND) { + HILOG_INFO(HILOG_MODULE_AAFWK, "Change Js app to background."); + (void) SchedulerLifecycleInner(topRecord, SLITE_STATE_BACKGROUND); + } else { + (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + } + return ERR_OK; + } + + if (!CheckResponse(info->bundleName)) { + return PARAM_CHECK_ERROR; + } + + // start js app + if (topRecord->state != SCHEDULE_STOP && topRecord->token != LAUNCHER_TOKEN) { + // start app is top + if (strcmp(info->bundleName, topRecord->appName) == 0) { + if (topRecord->state == SCHEDULE_BACKGROUND) { + HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility Resume app when background."); + (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND); + return ERR_OK; + } + HILOG_INFO(HILOG_MODULE_AAFWK, "Js app already started or starting."); + } else { + // js to js + HILOG_INFO(HILOG_MODULE_AAFWK, "Terminate pre js app when js to js"); + TerminateAbility(topRecord->token); + pendingToken_ = GenerateToken(); + } + } + + // application has not been launched and then to check priority and permission. + return PreCheckStartAbility(info->bundleName, info->path, info->data, info->dataLength); +#else if (topRecord == nullptr) { if (!IsLauncher(info->bundleName)) { HILOG_ERROR(HILOG_MODULE_AAFWK, "first ability should be launcher."); @@ -269,6 +326,7 @@ int32_t AbilityRecordManager::StartAbility(AbilitySvcInfo *info) // application has not been launched and then to check priority and permission. return PreCheckStartAbility(info->bundleName, info->path, info->data, info->dataLength, info->isNative); +#endif } int32_t AbilityRecordManager::TerminateAbility(uint16_t token) @@ -280,7 +338,25 @@ int32_t AbilityRecordManager::TerminateAbility(uint16_t token) return PARAM_NULL_ERROR; } uint16_t topToken = topRecord->token; +#ifndef _MINI_MULTI_TASKS_ + if (token == LAUNCHER_TOKEN) { + // if js is in background, the launcher goes back to background and js goes to active + if (topToken != token && topRecord->state == SCHEDULE_BACKGROUND) { + HILOG_INFO(HILOG_MODULE_AAFWK, "Resume Js app [%{public}u]", topToken); + return SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND); + } + return ERR_OK; + } + if (token != topToken) { + APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_UNKNOWN_ABILITY_TOKEN); + DeleteRecordInfo(token); + return -1; + } + topRecord->isTerminated = true; + // TerminateAbility top js + return SchedulerLifecycleInner(topRecord, SLITE_STATE_BACKGROUND); +#else // 1. only launcher in the ability stack if (abilityStack_.Size() == 1 && topToken == LAUNCHER_TOKEN) { return ERR_OK; @@ -312,6 +388,7 @@ int32_t AbilityRecordManager::TerminateAbility(uint16_t token) // TerminateAbility top js pendingToken_ = newTopRecord->token; return SendMsgToJsOrNativeAbility(topRecord, SLITE_STATE_BACKGROUND); +#endif } int32_t AbilityRecordManager::ForceStopBundle(uint16_t token) @@ -332,10 +409,16 @@ int32_t AbilityRecordManager::ForceStopBundle(uint16_t token) if (launcherRecord == nullptr) { return PARAM_NULL_ERROR; } +#ifndef _MINI_MULTI_TASKS_ + if (launcherRecord->state != SCHEDULE_FOREGROUND) { + return SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + } +#else if (launcherRecord->state == SCHEDULE_STOP) { //return SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); return StartAbility(launcherRecord); } +#endif return ERR_OK; } @@ -367,6 +450,39 @@ int32_t AbilityRecordManager::ForceStopBundleInner(uint16_t token) int32_t AbilityRecordManager::PreCheckStartAbility( const char *bundleName, const char *path, const void *data, uint16_t dataLength, bool isNative) { +#ifndef _MINI_MULTI_TASKS_ + if (path == nullptr) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility path is null."); + return PARAM_NULL_ERROR; + } + auto curRecord = abilityList_.Get(bundleName); + if (curRecord != nullptr) { + if (curRecord->state == SCHEDULE_FOREGROUND) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility current state active."); + } else if (curRecord->state == SCHEDULE_BACKGROUND) { + SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND); + } + return ERR_OK; + } + auto record = new AbilityRecord(); + if (pendingToken_ != 0) { + record->token = pendingToken_; + } else { + record->token = GenerateToken(); + } + record->SetAppName(bundleName); + record->SetAppPath(path); + record->SetWantData(data, dataLength); + record->isNativeApp = BMSHelper::GetInstance().IsNativeApp(bundleName); + record->state = SCHEDULE_STOP; + abilityList_.Add(record); + if (pendingToken_ == 0 && CreateAppTask(record) != ERR_OK) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "CheckResponse CreateAppTask fail"); + abilityList_.Erase(record->token); + delete record; + return CREATE_APPTASK_ERROR; + } +#else if ((path == nullptr) && !isNative) { HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility path is null."); return PARAM_NULL_ERROR; @@ -406,6 +522,7 @@ int32_t AbilityRecordManager::PreCheckStartAbility( delete record; return CREATE_APPTASK_ERROR; } +#endif return ERR_OK; } @@ -451,9 +568,24 @@ int32_t AbilityRecordManager::CreateAppTask(AbilityRecord *record) record->taskId = record->abilityThread->appTaskId_; record->jsAppQueueId = record->abilityThread->messageQueueId_; record->state = SCHEDULE_STOP; +#ifndef _MINI_MULTI_TASKS_ + abilityStack_.PushAbility(record); + APP_EVENT(MT_ACE_APP_START); + if (nativeAbility_ != nullptr) { + if (SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_BACKGROUND) != 0) { + APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_LAUNCHER_EXIT_FAILED); + HILOG_INFO(HILOG_MODULE_AAFWK, "CreateAppTask Fail to hide launcher"); + abilityStack_.PopAbility(); + return SCHEDULER_LIFECYCLE_ERROR; + } + } else { + SchedulerLifecycle(record->token, SLITE_STATE_INITIAL); + } +#else APP_EVENT(MT_ACE_APP_START); SchedulerLifecycle(record->token, SLITE_STATE_INITIAL); return ERR_OK; +#endif } uint16_t AbilityRecordManager::GenerateToken() @@ -462,7 +594,11 @@ uint16_t AbilityRecordManager::GenerateToken() if (token == UINT16_MAX - 1) { token = LAUNCHER_TOKEN; } +#ifndef _MINI_MULTI_TASKS_ + return ++token; +#else return token++; +#endif } void AbilityRecordManager::DeleteRecordInfo(uint16_t token) @@ -511,6 +647,13 @@ void AbilityRecordManager::OnForegroundDone(uint16_t token) // the launcher foreground if (token == LAUNCHER_TOKEN) { +#ifndef _MINI_MULTI_TASKS_ + if (nativeAbility_ == nullptr || nativeAbility_->GetState() != SLITE_STATE_FOREGROUND) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "native ability is in wrong state : %{public}d", + nativeAbility_->GetState()); + return; + } +#endif if (topRecord->token != LAUNCHER_TOKEN) { int abilityState = SLITE_STATE_UNINITIALIZED; if (topRecord->state == SCHEDULE_FOREGROUND) { @@ -526,7 +669,11 @@ void AbilityRecordManager::OnForegroundDone(uint16_t token) abilityStack_.PopAbility(); DeleteRecordInfo(topRecord->token); } else if (topRecord->isTerminated) { +#ifndef _MINI_MULTI_TASKS_ + (void) SchedulerLifecycleInner(topRecord, SLITE_STATE_UNINITIALIZED); +#else (void) SendMsgToJsOrNativeAbility(topRecord, SLITE_STATE_UNINITIALIZED); +#endif } } return; @@ -540,6 +687,36 @@ void AbilityRecordManager::OnForegroundDone(uint16_t token) void AbilityRecordManager::OnBackgroundDone(uint16_t token) { HILOG_INFO(HILOG_MODULE_AAFWK, "OnBackgroundDone [%{public}u]", token); +#ifndef _MINI_MULTI_TASKS_ + SetAbilityState(token, SCHEDULE_BACKGROUND); + auto topRecord = const_cast(abilityStack_.GetTopAbility()); + if (topRecord == nullptr) { + return; + } + // the js background + if (token != LAUNCHER_TOKEN) { + if (topRecord->token == token) { + APP_EVENT(MT_ACE_APP_BACKGROUND); + (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + } + return; + } + // the launcher background + if (topRecord->token != LAUNCHER_TOKEN) { + if (topRecord->state == SCHEDULE_STOP) { + (void) SchedulerLifecycleInner(topRecord, SLITE_STATE_INITIAL); + } else { + (void) SchedulerLifecycleInner(topRecord, SLITE_STATE_FOREGROUND); + } + if (GetCleanAbilityDataFlag()) { + HILOG_INFO(HILOG_MODULE_AAFWK, "OnBackgroundDone clean launcher record data"); + AbilityRecord *record = abilityList_.Get(token); + record->SetWantData(nullptr, 0); + SetCleanAbilityDataFlag(false); + } + return; + } +#else if (abilityList_.Get(token) == nullptr) { HILOG_ERROR(HILOG_MODULE_AAFWK, "token is not found"); return; @@ -556,14 +733,48 @@ void AbilityRecordManager::OnBackgroundDone(uint16_t token) } (void) SchedulerLifecycle(token, SLITE_STATE_UNINITIALIZED); - +#endif HILOG_WARN(HILOG_MODULE_AAFWK, "Js app exit, but has no js app."); } void AbilityRecordManager::OnDestroyDone(uint16_t token) { - HILOG_INFO(HILOG_MODULE_AAFWK, "OnDestroyDone [%{public}u]", token); + HILOG_INFO(HILOG_MODULE_AAFWK, "OnDestroyDone [%{public}u]", token); +#ifndef _MINI_MULTI_TASKS_ + // the launcher destroy + if (token == LAUNCHER_TOKEN) { + SetAbilityState(token, SCHEDULE_STOP); + return; + } + auto topRecord = abilityStack_.GetTopAbility(); + if ((topRecord == nullptr) || (topRecord->token != token)) { + SetAbilityState(token, SCHEDULE_STOP); + DeleteRecordInfo(token); + return; + } + APP_EVENT(MT_ACE_APP_STOP); + abilityStack_.PopAbility(); + DeleteRecordInfo(token); + SetAbilityState(token, SCHEDULE_STOP); + + // no pending token + if (pendingToken_ == 0) { + (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + return; + } + // start pending token + auto record = abilityList_.Get(pendingToken_); + if (record == nullptr) { + return; + } + if (CreateAppTask(record) != ERR_OK) { + abilityList_.Erase(pendingToken_); + delete record; + (void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + } + pendingToken_ = 0; +#else auto onDestroyRecord = abilityList_.Get(token); if (onDestroyRecord == nullptr) { HILOG_ERROR(HILOG_MODULE_AAFWK, "token is not found"); @@ -589,7 +800,12 @@ void AbilityRecordManager::OnDestroyDone(uint16_t token) abilityList_.Erase(pendingToken_); abilityStack_.Erase(record); delete record; - //(void) SchedulerLifecycle(LAUNCHER_TOKEN, SLITE_STATE_FOREGROUND); + auto topRecord = abilityStack_.GetTopAbility(); + if (topRecord == nullptr) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "record stack is empty"); + return; + } + StartAbility(topRecord); } pendingToken_ = 0; } else { @@ -597,6 +813,7 @@ void AbilityRecordManager::OnDestroyDone(uint16_t token) auto launcherRecord = abilityStack_.GetTopAbility(); StartAbility(launcherRecord); } +#endif } int32_t AbilityRecordManager::SchedulerLifecycle(uint64_t token, int32_t state) @@ -605,7 +822,11 @@ int32_t AbilityRecordManager::SchedulerLifecycle(uint64_t token, int32_t state) if (record == nullptr) { return PARAM_NULL_ERROR; } +#ifndef _MINI_MULTI_TASKS_ + return SchedulerLifecycleInner(record, state); +#else return SendMsgToJsOrNativeAbility(record, state); +#endif } void AbilityRecordManager::SetAbilityState(uint64_t token, int32_t state) @@ -617,6 +838,66 @@ void AbilityRecordManager::SetAbilityState(uint64_t token, int32_t state) record->state = state; } +int32_t AbilityRecordManager::SchedulerLifecycleInner(const AbilityRecord *record, int32_t state) +{ + if (record == nullptr) { + return PARAM_NULL_ERROR; + } + // dispatch js life cycle + if (record->token != LAUNCHER_TOKEN) { + (void) SendMsgToJsAbility(state, record); + return ERR_OK; + } + // dispatch native life cycle + if (nativeAbility_ == nullptr) { + return PARAM_NULL_ERROR; + } + // malloc want memory and release after use + Want *info = static_cast(AdapterMalloc(sizeof(Want))); + if (info == nullptr) { + return MEMORY_MALLOC_ERROR; + } + info->element = nullptr; + info->data = nullptr; + info->dataLength = 0; + info->appPath = nullptr; + + ElementName elementName = {}; + SetElementBundleName(&elementName, LAUNCHER_BUNDLE_NAME); + SetWantElement(info, elementName); + ClearElement(&elementName); + if (record->abilityData != nullptr) { + SetWantData(info, record->abilityData->wantData, record->abilityData->wantDataSize); + } else { + SetWantData(info, nullptr, 0); + } + SchedulerAbilityLifecycle(nativeAbility_, *info, state); + ClearWant(info); + AdapterFree(info); + return ERR_OK; +} + +void AbilityRecordManager::SchedulerAbilityLifecycle(SliteAbility *ability, const Want &want, int32_t state) +{ + if (ability == nullptr) { + return; + } + switch (state) { + case SLITE_STATE_FOREGROUND: { + ability->OnForeground(want); + break; + } + case SLITE_STATE_BACKGROUND: { + ability->OnBackground(); + break; + } + default: { + break; + } + } + return; +} + int32_t AbilityRecordManager::SchedulerLifecycleDone(uint64_t token, int32_t state) { switch (state) { @@ -643,7 +924,11 @@ int32_t AbilityRecordManager::SchedulerLifecycleDone(uint64_t token, int32_t sta return ERR_OK; } +#ifndef _MINI_MULTI_TASKS_ +bool AbilityRecordManager::SendMsgToJsAbility(int32_t state, const AbilityRecord *record) +#else bool AbilityRecordManager::SendMsgToJsOrNativeAbility(const AbilityRecord *record, int32_t state) +#endif { if (record == nullptr) { return false; @@ -687,11 +972,6 @@ Want *AbilityRecordManager::CreateWant(const AbilityRecord *record) SetElementBundleName(&elementName, record->appName); SetWantElement(want, elementName); ClearElement(&elementName); - if (record->abilityData != nullptr) { - SetWantData(want, record->abilityData->wantData, record->abilityData->wantDataSize); - } else { - SetWantData(want, nullptr, 0); - } return want; } diff --git a/services/abilitymgr_lite/src/slite/native_ability_thread.cpp b/services/abilitymgr_lite/src/slite/native_ability_thread.cpp index d8b927b..c4158d4 100644 --- a/services/abilitymgr_lite/src/slite/native_ability_thread.cpp +++ b/services/abilitymgr_lite/src/slite/native_ability_thread.cpp @@ -73,7 +73,7 @@ int32_t NativeAbilityThread::InitAbilityThread(const AbilityRecord *abilityRecor TSK_INIT_PARAM_S stTskInitParam = { 0 }; LOS_TaskLock(); stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC) (NativeAbilityThread::NativeAppTaskHandler); - stTskInitParam.uwStackSize = TASK_STACK_SIZE; + stTskInitParam.uwStackSize = NATIVE_TASK_STACK_SIZE; stTskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST - APP_TASK_PRI; stTskInitParam.pcName = NATIVE_APP_TASK; stTskInitParam.uwResved = 0; -- Gitee