diff --git a/frameworks/ability_lite/BUILD.gn b/frameworks/ability_lite/BUILD.gn index 27e57ff233571daa94b4039f327367d3e1e6f740..37489a99a022d3a7ab2bbffc343c85faffb64f9e 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 0480e92666b9b654c1c19363b83466f7e04a6438..0188c51d48bda1e919a4ca7dd7ad5c1dade8461c 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 782026e92c236b123591af91d7ffff783215276f..859b2df666c55f24ef88949a7ed0c8b2e3229f0f 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 = nullptr); - 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,8 @@ public: int GetState() const; + char *bundleName_ = nullptr; + private: int abilityState_ = 0; }; diff --git a/services/abilitymgr_lite/BUILD.gn b/services/abilitymgr_lite/BUILD.gn index bf48124783d6fa35b7b3b9c81d69088632f56f9d..47f555d451c5f5d6be92df716fa02f24c8566037 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 51dd35400bd773a8189fdbf80990e44aca41eac2..a163a26ca3c17a99efc6fac928f68d49a0aca1a1 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,12 @@ 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 = false); bool CheckResponse(const char *bundleName); @@ -89,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); @@ -103,7 +111,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 499d5762c1705fee411a079ff4e03c8b601440cb..d475de381484618e2bc3764178e6e8689311ee67 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 98091f3c904b4d7f9c2361bdce7486e7af7609f1..aa806c97d3f970b4b8d35c3ff181ae2977d9a12b 100644 --- a/services/abilitymgr_lite/include/slite/ability_thread.h +++ b/services/abilitymgr_lite/include/slite/ability_thread.h @@ -21,8 +21,13 @@ #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 +45,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 +52,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 f4b3bcf473c23f12786d15c96c18a3c179d4c139..c0e203ad1591f0d50dcc21817cf659b3df3fde18 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 edb6cc916091c8089a8c3ca17c4ec6a908d44b44..3a1e107087a0169bc9ad47ef8fc32b4c02e56fd9 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 3f93f185b9d262bc7d28c69f99c5b9a2e471a213..d68fdf92c2af146f31b1708eeaecbd73c4eec2a6 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 11f21121110076ad40b51c4ddb05bb581d4509fb..766f62e29a5ac525c2d83b05090e2c136a6704f3 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 c777d6bca1b8ffc4df0bd24bbba937c15bfaa883..177ec7c0c8273bfa82296427d07b1c4bedeaaf30 100644 --- a/services/abilitymgr_lite/src/slite/ability_record_manager.cpp +++ b/services/abilitymgr_lite/src/slite/ability_record_manager.cpp @@ -43,7 +43,6 @@ 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; @@ -61,6 +60,8 @@ void AbilityRecordManager::StartLauncher() if (launcherRecord != nullptr) { return; } + +#ifndef _MINI_MULTI_TASKS_ auto record = new AbilityRecord(); record->SetAppName(LAUNCHER_BUNDLE_NAME); record->token = LAUNCHER_TOKEN; @@ -70,6 +71,40 @@ void AbilityRecordManager::StartLauncher() 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) +{ + 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 (IsLauncher(bundleName) || 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,6 +257,7 @@ 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; @@ -261,6 +299,34 @@ 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); +#else + if (topRecord == nullptr) { + if (!IsLauncher(info->bundleName)) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "first ability should be launcher."); + return PARAM_NULL_ERROR; + } + // start launcher when boot + return PreCheckStartAbility(info->bundleName, info->path, info->data, info->dataLength, info->isNative); + } + + if (!CheckResponse(info->bundleName)) { + return PARAM_CHECK_ERROR; + } + + // 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, info->isNative); +#endif } int32_t AbilityRecordManager::TerminateAbility(uint16_t token) @@ -272,6 +338,7 @@ 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) { @@ -289,6 +356,39 @@ int32_t AbilityRecordManager::TerminateAbility(uint16_t token) 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; + } + // 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; + } + // 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 + pendingToken_ = newTopRecord->token; + return SendMsgToJsOrNativeAbility(topRecord, SLITE_STATE_BACKGROUND); +#endif } int32_t AbilityRecordManager::ForceStopBundle(uint16_t token) @@ -309,9 +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; } @@ -341,8 +448,9 @@ 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) { +#ifndef _MINI_MULTI_TASKS_ if (path == nullptr) { HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility path is null."); return PARAM_NULL_ERROR; @@ -374,6 +482,47 @@ int32_t AbilityRecordManager::PreCheckStartAbility( delete record; return CREATE_APPTASK_ERROR; } +#else + 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_STOP) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility current state active."); + } 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; + } + } else { + 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); + } + + 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; + } +#endif return ERR_OK; } @@ -398,13 +547,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,6 +568,7 @@ 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) { @@ -429,7 +581,11 @@ int32_t AbilityRecordManager::CreateAppTask(AbilityRecord *record) } 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() @@ -438,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) @@ -448,15 +608,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 +617,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 +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) { @@ -502,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; @@ -516,6 +687,7 @@ 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) { @@ -544,12 +716,31 @@ void AbilityRecordManager::OnBackgroundDone(uint16_t token) } return; } +#else + if (abilityList_.Get(token) == nullptr) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "token is not found"); + return; + } + SetAbilityState(token, SCHEDULE_BACKGROUND); + + 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); + } + } + + (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); @@ -583,6 +774,46 @@ void AbilityRecordManager::OnDestroyDone(uint16_t token) (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"); + return; + } + // 1. ability is terminated and pop out ability stack + if (onDestroyRecord->isTerminated) { + APP_EVENT(MT_ACE_APP_STOP); + DeleteRecordInfo(token); + } else { + // 2. ability is transferred to SCHEDULE_STOP state and still keep in the ability stack + DeleteAbilityThread(onDestroyRecord); + SetAbilityState(token, SCHEDULE_STOP); + } + + // start pending token + 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; + auto topRecord = abilityStack_.GetTopAbility(); + if (topRecord == nullptr) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "record stack is empty"); + return; + } + StartAbility(topRecord); + } + pendingToken_ = 0; + } else { + // start launcher + auto launcherRecord = abilityStack_.GetTopAbility(); + StartAbility(launcherRecord); + } +#endif } int32_t AbilityRecordManager::SchedulerLifecycle(uint64_t token, int32_t state) @@ -591,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) @@ -689,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; diff --git a/services/abilitymgr_lite/src/slite/ability_stack.cpp b/services/abilitymgr_lite/src/slite/ability_stack.cpp index 56648df0226cdf60a8b821db732f1e042fe83743..b475e948e6b49a0e4c5c553e142e72e9fee15a9d 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 60540bea8830b03fcc390c9e5692e926d4ccacfa..1ebcddaed5b1972e82e8ef281c672664f7deca9d 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 839a5585ed17cf36a8b624b36ac413f62b1a4bc6..7eefedba3492f150ca8967bae09353c4a827cfdf 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 1d5572b461df1b426886b1252ec5a2c5fe9c3335..c4158d4df110960c9ff882d6e43a7176f358b637 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.uwStackSize = TASK_STACK_SIZE; + stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC) (NativeAbilityThread::NativeAppTaskHandler); + stTskInitParam.uwStackSize = NATIVE_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