From 5cf5a0edb37a565e2ffa434cec65cc64b39e7c64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E8=8F=B2=E5=A2=A8?= Date: Tue, 17 Jun 2025 19:06:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EStartAbilities?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 朱菲墨 --- .../service_extension_context.js | 5 + .../ui_extension_context.js | 5 + frameworks/native/ability/native/BUILD.gn | 1 + .../native/ability/native/ability_thread.cpp | 5 + .../native/ability/native/extension.cpp | 5 + .../native/extension_ability_thread.cpp | 30 ++ .../native/ability/native/extension_impl.cpp | 13 + .../native/js_service_extension_context.cpp | 97 +++++ .../native/js_start_abilities_observer.cpp | 112 ++++++ .../ability/native/service_extension.cpp | 11 + .../js_ui_extension_context.cpp | 96 +++++ .../ui_extension_context.cpp | 10 + .../service_extension_context.cpp | 17 + .../include/ability_manager_client.h | 11 + .../include/ability_manager_errors.h | 23 ++ .../include/ability_manager_interface.h | 14 + .../ability_manager_ipc_interface_code.h | 3 + .../include/ability_scheduler_interface.h | 7 +- .../native/ability/native/ability_thread.h | 2 + .../kits/native/ability/native/extension.h | 2 + .../ability/native/extension_ability_thread.h | 2 + .../native/ability/native/extension_impl.h | 2 + .../native/js_service_extension_context.h | 1 + .../native/js_start_abilities_observer.h | 108 ++++++ .../native/ability/native/service_extension.h | 2 + .../js_ui_extension_context.h | 4 + .../ui_extension_base/ui_extension_context.h | 2 + .../service_extension_context.h | 7 + .../include/ability_manager_proxy.h | 11 + .../include/ability_manager_service.h | 12 + .../abilitymgr/include/ability_manager_stub.h | 1 + services/abilitymgr/include/ability_record.h | 2 + .../include/ability_scheduler_proxy.h | 1 + .../include/ability_scheduler_stub.h | 1 + services/abilitymgr/include/lifecycle_deal.h | 2 + .../ui_ability_lifecycle_manager.h | 15 + .../abilitymgr/src/ability_manager_client.cpp | 17 + .../abilitymgr/src/ability_manager_proxy.cpp | 50 +++ .../src/ability_manager_service.cpp | 194 ++++++++++ .../abilitymgr/src/ability_manager_stub.cpp | 38 ++ services/abilitymgr/src/ability_record.cpp | 6 + .../src/ability_scheduler_proxy.cpp | 30 ++ .../abilitymgr/src/ability_scheduler_stub.cpp | 10 + services/abilitymgr/src/lifecycle_deal.cpp | 7 + .../ui_ability_lifecycle_manager.cpp | 342 +++++++++++++++++- 45 files changed, 1323 insertions(+), 13 deletions(-) create mode 100644 frameworks/native/ability/native/js_start_abilities_observer.cpp create mode 100644 interfaces/kits/native/ability/native/js_start_abilities_observer.h diff --git a/frameworks/js/napi/service_extension_context/service_extension_context.js b/frameworks/js/napi/service_extension_context/service_extension_context.js index c81ba0f5120..18f3293362a 100644 --- a/frameworks/js/napi/service_extension_context/service_extension_context.js +++ b/frameworks/js/napi/service_extension_context/service_extension_context.js @@ -79,6 +79,11 @@ class ServiceExtensionContext extends ExtensionContext { return this.__context_impl__.startServiceExtensionAbilityWithAccount(want, accountId, callback); } + startAbilities(wantList) { + hilog.sLogI(domainID, TAG, 'startAbilities'); + return this.__context_impl__.startAbilities(wantList); + } + stopServiceExtensionAbility(want, callback) { hilog.sLogI(domainID, TAG, 'stopServiceExtensionAbility'); return this.__context_impl__.stopServiceExtensionAbility(want, callback); diff --git a/frameworks/js/napi/ui_extension_context/ui_extension_context.js b/frameworks/js/napi/ui_extension_context/ui_extension_context.js index cae8c4be3b5..4ac2983d4fd 100755 --- a/frameworks/js/napi/ui_extension_context/ui_extension_context.js +++ b/frameworks/js/napi/ui_extension_context/ui_extension_context.js @@ -71,6 +71,11 @@ class UIExtensionContext extends ExtensionContext { return this.__context_impl__.startAbilityForResultAsCaller(want, options, callback); } + startAbilities(wantList) { + hilog.sLogI(domainID, TAG, 'startAbilities'); + return this.__context_impl__.startAbilities(wantList); + } + terminateSelfWithResult(abilityResult, callback) { hilog.sLogI(domainID, TAG, 'terminateSelfWithResult'); return this.__context_impl__.terminateSelfWithResult(abilityResult, callback); diff --git a/frameworks/native/ability/native/BUILD.gn b/frameworks/native/ability/native/BUILD.gn index fb693b45d7f..60e09cfca63 100644 --- a/frameworks/native/ability/native/BUILD.gn +++ b/frameworks/native/ability/native/BUILD.gn @@ -318,6 +318,7 @@ ohos_shared_library("abilitykit_native") { "${ability_runtime_native_path}/ability/native/free_install_observer_stub.cpp", "${ability_runtime_native_path}/ability/native/insight_intent_host_client.cpp", "${ability_runtime_native_path}/ability/native/js_free_install_observer.cpp", + "${ability_runtime_native_path}/ability/native/js_start_abilities_observer.cpp", "${ability_runtime_native_path}/ability/native/js_query_erms_observer.cpp", "${ability_runtime_native_path}/ability/native/new_ability_impl.cpp", "${ability_runtime_native_path}/ability/native/query_erms_observer_proxy.cpp", diff --git a/frameworks/native/ability/native/ability_thread.cpp b/frameworks/native/ability/native/ability_thread.cpp index 4832062a632..c0ddfa03fd5 100644 --- a/frameworks/native/ability/native/ability_thread.cpp +++ b/frameworks/native/ability/native/ability_thread.cpp @@ -301,5 +301,10 @@ void AbilityThread::ScheduleAbilityRequestSuccess(const std::string &requestId, { TAG_LOGD(AAFwkTag::ABILITY, "called"); } + +void AbilityThread::ScheduleAbilitiesRequestDone(const std::string &startTime, const int32_t resultCode) +{ + TAG_LOGD(AAFwkTag::ABILITY, "called"); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/native/ability/native/extension.cpp b/frameworks/native/ability/native/extension.cpp index 259c13cfeaa..ebc23df790c 100644 --- a/frameworks/native/ability/native/extension.cpp +++ b/frameworks/native/ability/native/extension.cpp @@ -152,6 +152,11 @@ void Extension::OnConfigurationUpdated(const AppExecFwk::Configuration &configur TAG_LOGD(AAFwkTag::EXT, "call"); } +void Extension::OnAbilitiesRequestResponse(const std::string &startTime, const int32_t resultCode) +{ + TAG_LOGD(AAFwkTag::EXT, "call"); +} + void Extension::OnMemoryLevel(int level) { TAG_LOGD(AAFwkTag::EXT, "call"); diff --git a/frameworks/native/ability/native/extension_ability_thread.cpp b/frameworks/native/ability/native/extension_ability_thread.cpp index 6a7633b3519..e542e51c2e8 100644 --- a/frameworks/native/ability/native/extension_ability_thread.cpp +++ b/frameworks/native/ability/native/extension_ability_thread.cpp @@ -573,6 +573,36 @@ void ExtensionAbilityThread::SendResult(int requestCode, int resultCode, const W TAG_LOGD(AAFwkTag::EXT, "End"); } +void ExtensionAbilityThread::ScheduleAbilitiesRequestDone(const std::string &startTime, + const int32_t resultCode) +{ + TAG_LOGD(AAFwkTag::EXT, "ScheduleAbilitiesRequestDone"); + if (abilityHandler_ == nullptr) { + TAG_LOGE(AAFwkTag::EXT, "null abilityHandler_"); + return; + } + + wptr weak = this; + auto task = [weak, startTime, resultCode]() { + auto abilityThread = weak.promote(); + if (abilityThread == nullptr) { + TAG_LOGE(AAFwkTag::EXT, "null abilityThread"); + return; + } + + if (abilityThread->extensionImpl_ == nullptr) { + TAG_LOGE(AAFwkTag::EXT, "null extensionImpl_"); + return; + } + abilityThread->extensionImpl_->ScheduleAbilitiesRequestDone(startTime, resultCode); + }; + bool ret = abilityHandler_->PostTask(task); + if (!ret) { + TAG_LOGE(AAFwkTag::EXT, "PostTask error"); + } + TAG_LOGD(AAFwkTag::EXT, "End"); +} + void ExtensionAbilityThread::NotifyMemoryLevel(int32_t level) { TAG_LOGD(AAFwkTag::EXT, "result: %{public}d", level); diff --git a/frameworks/native/ability/native/extension_impl.cpp b/frameworks/native/ability/native/extension_impl.cpp index ea559e946cd..88bb2909439 100644 --- a/frameworks/native/ability/native/extension_impl.cpp +++ b/frameworks/native/ability/native/extension_impl.cpp @@ -499,6 +499,19 @@ void ExtensionImpl::Background(const Want &want, sptr sessio lifecycleState_ = AAFwk::ABILITY_STATE_BACKGROUND_NEW; } +void ExtensionImpl::ScheduleAbilitiesRequestDone(const std::string &startTime, + const int32_t resultCode) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::EXT, "ScheduleAbilitiesRequestDone"); + if (extension_ == nullptr) { + TAG_LOGE(AAFwkTag::EXT, "null extension_"); + return; + } + + extension_->OnAbilitiesRequestResponse(startTime, resultCode); +} + void ExtensionImpl::ExtensionWindowLifeCycleImpl::AfterForeground() { TAG_LOGD(AAFwkTag::EXT, "called"); diff --git a/frameworks/native/ability/native/js_service_extension_context.cpp b/frameworks/native/ability/native/js_service_extension_context.cpp index 04584705793..1e2cfde1ab5 100644 --- a/frameworks/native/ability/native/js_service_extension_context.cpp +++ b/frameworks/native/ability/native/js_service_extension_context.cpp @@ -45,6 +45,7 @@ constexpr int32_t INDEX_ZERO = 0; constexpr int32_t INDEX_ONE = 1; constexpr int32_t INDEX_TWO = 2; constexpr int32_t INDEX_THREE = 3; +constexpr int32_t INDEX_FOUR = 4; constexpr int32_t ERROR_CODE_ONE = 1; constexpr int32_t ERROR_CODE_TWO = 2; constexpr size_t ARGC_ZERO = 0; @@ -127,6 +128,11 @@ public: GET_NAPI_INFO_AND_CALL(env, info, JsServiceExtensionContext, OnStartAbilityWithAccount); } + napi_value JsAbilityContext::StartAbilities(napi_env env, napi_callback_info info) + { + GET_NAPI_INFO_AND_CALL(env, info, JsServiceExtensionContext, OnStartAbilities); + } + static napi_value ConnectAbilityWithAccount(napi_env env, napi_callback_info info) { GET_NAPI_INFO_AND_CALL(env, info, JsServiceExtensionContext, OnConnectAbilityWithAccount); @@ -190,6 +196,7 @@ public: private: std::weak_ptr context_; sptr freeInstallObserver_ = nullptr; + sptr startAbilitiesObserver_ = nullptr; static void ClearFailedCallConnection( const std::weak_ptr& serviceContext, const std::shared_ptr &callback) { @@ -743,6 +750,95 @@ private: return true; } + napi_value OnStartAbilities(napi_env env, NapiCallbackInfo& info) + { + TAG_LOGI(AAFwkTag::SERVICE_EXT, "startAbilitiesLog call JsAbilityContext::OnStartAbilities"); + //入参不止一个 抛出错误 + if (info.argc != ARGC_ONE) { + TAG_LOGI(AAFwkTag::SERVICE_EXT, "startAbilitiesLog info.argc != ARGC_ONE"); + ThrowInvalidNumParametersError(env); + return CreateJsUndefined(env); + } + + AppExecFwk::ComplexArrayData jsWantList; + if (!AppExecFwk::UnwrapArrayComplexFromJS(env, info.argv[INDEX_ZERO], jsWantList)) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "startAbilitiesLog wantList not array."); + ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return CreateJsUndefined(env); + } + + size_t jsWantSize = jsWantList.objectList.size(); + if (jsWantSize < INDEX_ONE || jsWantSize > INDEX_FOUR) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "startAbilitiesLog wantList size not support"); + ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return CreateJsUndefined(env); + } + + std::vector wantList; + std::string startTime = std::to_string(std::chrono::duration_cast(std::chrono:: + system_clock::now().time_since_epoch()).count()); + for (uint32_t index = 0; index < jsWantSize; index++) { + AAFwk::Want curWant; + // 元素不是want或解析失败 抛出错误 + if (!OHOS::AppExecFwk::UnwrapWant(env, jsWantList.objectList[index], curWant)) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "startAbilitiesLog parse want failed"); + ThrowInvalidParamError(env, "Parse want failed, wantList members must be Want."); + return CreateJsUndefined(env); + } + InheritWindowMode(curWant); + curWant.SetParam(Want::PARAM_RESV_START_TIME, startTime); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "startAbilitiesLog ability:%{public}s", + curWant.GetElement().GetAbilityName().c_str()); + wantList.emplace_back(curWant); + } + TAG_LOGI(AAFwkTag::SERVICE_EXT, "startAbilitiesLog wantListLength: %{public}zu", wantList.size()); + + napi_value result = nullptr; + auto innerErrCode = std::make_shared(ERR_OK); + AddStartAbilitiesObserver(env, startTime, &result); + NapiAsyncTask::ExecuteCallback execute = [weak = context_, wantList, innerErrCode]() { + auto context = weak.lock(); + if (!context) { + TAG_LOGW(AAFwkTag::SERVICE_EXT, "null context"); + *innerErrCode = static_cast(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); + return; + } + *innerErrCode = context->StartAbilities(wantList); + TAG_LOGI(AAFwkTag::SERVICE_EXT, "startAbilities execute innerErrCode: %{public}d", *innerErrCode); + }; + + NapiAsyncTask::CompleteCallback complete = [innerErrCode, startTime, weak = context_ + observer = startAbilitiesObserver_](napi_env env, NapiAsyncTask& task, int32_t status) { + TAG_LOGI(AAFwkTag::SERVICE_EXT, "startAbilities complete innerErrCode: %{public}d", *innerErrCode); + // 收到此返回码,不resolve,等待specified回调 + if (*innerErrCode == START_ABILITIES_WAITTING_SPECIFIED_CODE) { + TAG_LOGI(AAFwkTag::SERVICE_EXT, "startAbilities waiting specified."); + return; + } + // 非此返回码,处理startAbilities完成 + if (observer != nullptr) { + TAG_LOGI(AAFwkTag::SERVICE_EXT, "startAbilities handle innerErrCode"); + observer->OnStartAbilitiesFinished(startTime, *innerErrCode); + return + } + TAG_LOGE(AAFwkTag::SERVICE_EXT, "startAbilitiesObserver nullptr"); + }; + + NapiAsyncTask::ScheduleHighQos("JsAbilityContext::OnStartAbilities", env, + CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), nullptr)); + + return result; + } + //ability_context.js --> js_ability_context.cpp --> ability_context_impl.cpp --> ability_manager_client --> ability_manager_proxy --> IPC --> ability_manager_stub --> ability_manager_service --> SCB + void AddStartAbilitiesObserver(napi_env env, std::string startTime, napi_value *result) + { + TAG_LOGD(AAFwkTag::SERVICE_EXT, "called AddStartAbilitiesObserver"); + if (startAbilitiesObserver_ == nullptr) { + startAbilitiesObserver_ = std::make_shared(env); + } + startAbilitiesObserver_->AddJsObserverObject(startTime, result); + } + bool CheckConnectAbilityWithAccountInputParam( napi_env env, NapiCallbackInfo& info, AAFwk::Want& want, int32_t& accountId, sptr& connection) const @@ -1404,6 +1500,7 @@ napi_value CreateJsServiceExtensionContext(napi_env env, std::shared_ptr jsObserver = this; + std::unique_ptr complete = std::make_unique + ([jsObserver, startTime, resultCode](napi_env env, NapiAsyncTask &task, int32_t status) { + sptr jsObserverSptr = jsObserver.promote(); + if (jsObserverSptr) { + jsObserverSptr->HandleOnStartAbilitiesFinished(startTime, resultCode); + } + }); + napi_ref callback = nullptr; + std::unique_ptr execute = nullptr; + NapiAsyncTask::Schedule("JsStartAbilitiesObserver::OnStartAbilitiesFinished", + env_, std::make_unique(callback, std::move(execute), std::move(complete))); +} + +void JsStartAbilitiesObserver::HandleOnStartAbilitiesFinished(const std::string &startTime, const int &resultCode) +{ + TAG_LOGD(AAFwkTag::FREE_INSTALL, "HandleOnStartAbilitiesFinished"); + // 为什么会是vector? + std::vector promises; + { + std::unique_lock lock(jsObserverObjectListLock_); + for (auto it = jsObserverObjectList_.begin(); it != jsObserverObjectList_.end();) { + if (it->startTime != startTime) { + it++; + continue; + } + if (it->deferred != nullptr) { + promises.emplace_back(it->deferred); + } + it = jsObserverObjectList_.erase(it); + } + } + + for (const napi_deferred& promise : promises) { + CallPromise(promise, resultCode); + FinishAsyncTrace(HITRACE_TAG_ABILITY_MANAGER, "StartAbilities", atoi(startTime.c_str())); + } +} + +void JsStartAbilitiesObserver::CallPromise(napi_deferred deferred, int32_t resultCode) +{ + if (deferred == nullptr) { + TAG_LOGE(AAFwkTag::FREE_INSTALL, "null deferred"); + return; + } + if (resultCode == ERR_OK) { + napi_value value = CreateJsUndefined(env_); + napi_resolve_deferred(env_, deferred, value); + } else { + napi_value error = CreateJsError(env_, GetJsErrorCodeByNativeError(resultCode)); + napi_reject_deferred(env_, deferred, error); + } +} + +void JsStartAbilitiesObserver::AddJsObserverObject(const std::string &startTime, napi_value* result) +{ + TAG_LOGD(AAFwkTag::FREE_INSTALL, "call AddJsObserverObject"); + { + std::unique_lock lock(jsObserverObjectListLock_); + for (auto it = jsObserverObjectList_.begin(); it != jsObserverObjectList_.end(); ++it) { + if (it->startTime == startTime) { + TAG_LOGW(AAFwkTag::FREE_INSTALL, "add jsObject"); + return; + } + } + } + + StartAsyncTrace(HITRACE_TAG_ABILITY_MANAGER, "StartStartAbilities", atoi(startTime.c_str())); + JsStartAbilitiesObserverObject object; + object.startTime = startTime; + napi_deferred deferred; + napi_create_promise(env_, &deferred, result); + object.deferred = deferred; + std::unique_lock lock(jsObserverObjectListLock_); + jsObserverObjectList_.emplace_back(object); +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/ability/native/service_extension.cpp b/frameworks/native/ability/native/service_extension.cpp index cbf2ad871c8..af59ce9b7a9 100644 --- a/frameworks/native/ability/native/service_extension.cpp +++ b/frameworks/native/ability/native/service_extension.cpp @@ -91,5 +91,16 @@ void ServiceExtension::OnConfigurationUpdated(const AppExecFwk::Configuration &c auto configUtils = std::make_shared(); configUtils->UpdateGlobalConfig(configuration, context->GetResourceManager()); } + +void ServiceExtension::OnAbilitiesRequestResponse(const std::string &startTime, const int32_t resultCode) +{ + Extension::OnAbilitiesRequestResponse(startTime, resultCode); + auto context = GetContext(); + if (context == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null context"); + return; + } + context->OnAbilitiesRequestResponse(startTime, resultCode); +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/ability/native/ui_extension_base/js_ui_extension_context.cpp b/frameworks/native/ability/native/ui_extension_base/js_ui_extension_context.cpp index 5a2e7fcbdb0..b7007ca5e03 100755 --- a/frameworks/native/ability/native/ui_extension_base/js_ui_extension_context.cpp +++ b/frameworks/native/ability/native/ui_extension_base/js_ui_extension_context.cpp @@ -51,6 +51,7 @@ constexpr int32_t INDEX_ZERO = 0; constexpr int32_t INDEX_ONE = 1; constexpr int32_t INDEX_TWO = 2; constexpr int32_t INDEX_THREE = 3; +constexpr int32_t INDEX_FOUR = 4; constexpr size_t ARGC_ZERO = 0; constexpr size_t ARGC_ONE = 1; constexpr size_t ARGC_TWO = 2; @@ -143,6 +144,11 @@ napi_value JsUIExtensionContext::StartAbilityForResultAsCaller(napi_env env, nap GET_NAPI_INFO_AND_CALL(env, info, JsUIExtensionContext, OnStartAbilityForResultAsCaller); } +napi_value JsUIExtensionContext::StartAbilities(napi_env env, napi_callback_info info) +{ + GET_NAPI_INFO_AND_CALL(env, info, JsUIExtensionContext, OnStartAbilities); +} + napi_value JsUIExtensionContext::TerminateSelfWithResult(napi_env env, napi_callback_info info) { GET_NAPI_INFO_AND_CALL(env, info, JsUIExtensionContext, OnTerminateSelfWithResult); @@ -563,6 +569,95 @@ napi_value JsUIExtensionContext::OnStartAbilityForResultAsCaller(napi_env env, N return result; } +napi_value JsUIExtensionContext::OnStartAbilities(napi_env env, NapiCallbackInfo& info) +{ + TAG_LOGI(AAFwkTag::UI_EXT, "startAbilitiesLog call JsAbilityContext::OnStartAbilities"); + //入参不止一个 抛出错误 + if (info.argc != ARGC_ONE) { + TAG_LOGI(AAFwkTag::UI_EXT, "startAbilitiesLog info.argc != ARGC_ONE"); + ThrowInvalidNumParametersError(env); + return CreateJsUndefined(env); + } + + AppExecFwk::ComplexArrayData jsWantList; + if (!AppExecFwk::UnwrapArrayComplexFromJS(env, info.argv[INDEX_ZERO], jsWantList)) { + TAG_LOGE(AAFwkTag::UI_EXT, "startAbilitiesLog wantList not array."); + ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return CreateJsUndefined(env); + } + + size_t jsWantSize = jsWantList.objectList.size(); + if (jsWantSize < INDEX_ONE || jsWantSize > INDEX_FOUR) { + TAG_LOGE(AAFwkTag::UI_EXT, "startAbilitiesLog wantList size not support"); + ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return CreateJsUndefined(env); + } + + std::vector wantList; + std::string startTime = std::to_string(std::chrono::duration_cast(std::chrono:: + system_clock::now().time_since_epoch()).count()); + for (uint32_t index = 0; index < jsWantSize; index++) { + AAFwk::Want curWant; + // 元素不是want或解析失败 抛出错误 + if (!OHOS::AppExecFwk::UnwrapWant(env, jsWantList.objectList[index], curWant)) { + TAG_LOGE(AAFwkTag::UI_EXT, "startAbilitiesLog parse want failed"); + ThrowInvalidParamError(env, "Parse want failed, wantList members must be Want."); + return CreateJsUndefined(env); + } + InheritWindowMode(curWant); + curWant.SetParam(Want::PARAM_RESV_START_TIME, startTime); + TAG_LOGD(AAFwkTag::UI_EXT, "startAbilitiesLog ability:%{public}s", + curWant.GetElement().GetAbilityName().c_str()); + wantList.emplace_back(curWant); + } + TAG_LOGI(AAFwkTag::UI_EXT, "startAbilitiesLog wantListLength: %{public}zu", wantList.size()); + + napi_value result = nullptr; + auto innerErrCode = std::make_shared(ERR_OK); + AddStartAbilitiesObserver(env, startTime, &result); + NapiAsyncTask::ExecuteCallback execute = [weak = context_, wantList, innerErrCode]() { + auto context = weak.lock(); + if (!context) { + TAG_LOGW(AAFwkTag::UI_EXT, "null context"); + *innerErrCode = static_cast(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); + return; + } + *innerErrCode = context->StartAbilities(wantList); + TAG_LOGI(AAFwkTag::UI_EXT, "startAbilities execute innerErrCode: %{public}d", *innerErrCode); + }; + + NapiAsyncTask::CompleteCallback complete = [innerErrCode, startTime, weak = context_ + observer = startAbilitiesObserver_](napi_env env, NapiAsyncTask& task, int32_t status) { + TAG_LOGI(AAFwkTag::UI_EXT, "startAbilities complete innerErrCode: %{public}d", *innerErrCode); + // 收到此返回码,不resolve,等待specified回调 + if (*innerErrCode == START_ABILITIES_WAITTING_SPECIFIED_CODE) { + TAG_LOGI(AAFwkTag::UI_EXT, "startAbilities waiting specified."); + return; + } + // 非此返回码,处理startAbilities完成 + if (observer != nullptr) { + TAG_LOGI(AAFwkTag::UI_EXT, "startAbilities handle innerErrCode"); + observer->OnStartAbilitiesFinished(startTime, *innerErrCode); + return + } + TAG_LOGE(AAFwkTag::UI_EXT, "startAbilitiesObserver nullptr"); + }; + + NapiAsyncTask::ScheduleHighQos("JsAbilityContext::OnStartAbilities", env, + CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), nullptr)); + + return result; +} +//ability_context.js --> js_ability_context.cpp --> ability_context_impl.cpp --> ability_manager_client --> ability_manager_proxy --> IPC --> ability_manager_stub --> ability_manager_service --> SCB +void JsUIExtensionContext::AddStartAbilitiesObserver(napi_env env, std::string startTime, napi_value *result) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "called AddStartAbilitiesObserver"); + if (startAbilitiesObserver_ == nullptr) { + startAbilitiesObserver_ = std::make_shared(env); + } + startAbilitiesObserver_->AddJsObserverObject(startTime, result); +} + napi_value JsUIExtensionContext::OnConnectAbility(napi_env env, NapiCallbackInfo& info) { TAG_LOGD(AAFwkTag::UI_EXT, "called"); @@ -1317,6 +1412,7 @@ napi_value JsUIExtensionContext::CreateJsUIExtensionContext(napi_env env, BindNativeFunction(env, objValue, "startAbilityForResult", moduleName, StartAbilityForResult); BindNativeFunction(env, objValue, "terminateSelfWithResult", moduleName, TerminateSelfWithResult); BindNativeFunction(env, objValue, "startAbilityForResultAsCaller", moduleName, StartAbilityForResultAsCaller); + BindNativeFunction(env, objValue, "startAbilities", moduleName, StartAbilities); BindNativeFunction(env, objValue, "connectServiceExtensionAbility", moduleName, ConnectAbility); BindNativeFunction(env, objValue, "disconnectServiceExtensionAbility", moduleName, DisconnectAbility); BindNativeFunction(env, objValue, "reportDrawnCompleted", moduleName, ReportDrawnCompleted); diff --git a/frameworks/native/ability/native/ui_extension_base/ui_extension_context.cpp b/frameworks/native/ability/native/ui_extension_base/ui_extension_context.cpp index 57510b29014..cd4815b5d8e 100755 --- a/frameworks/native/ability/native/ui_extension_base/ui_extension_context.cpp +++ b/frameworks/native/ability/native/ui_extension_base/ui_extension_context.cpp @@ -136,6 +136,16 @@ ErrCode UIExtensionContext::StartServiceExtensionAbility(const AAFwk::Want& want return ret; } +ErrCode UIExtensionContext::StartAbilities(const std::vector &wantList) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "StartAbilitiesLog call StartAbilities"); + ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbilities(wantList, token_); + if (err != ERR_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "StartAbilitiesLog ret=%{public}d", err); + } + return err; +} + ErrCode UIExtensionContext::StartAbilityForResult(const AAFwk::Want &want, int requestCode, RuntimeTask &&task) { TAG_LOGD(AAFwkTag::UI_EXT, "begin"); diff --git a/frameworks/native/appkit/ability_runtime/service_extension_context.cpp b/frameworks/native/appkit/ability_runtime/service_extension_context.cpp index fd9a99c5616..3ab593cf112 100644 --- a/frameworks/native/appkit/ability_runtime/service_extension_context.cpp +++ b/frameworks/native/appkit/ability_runtime/service_extension_context.cpp @@ -1,3 +1,4 @@ + /* * Copyright (c) 2022-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -154,6 +155,22 @@ ErrCode ServiceExtensionContext::StartAbilityWithAccount( return err; } +ErrCode ServiceExtensionContext::StartAbilities(const std::vector &wantList) +{ + TAG_LOGD(AAFwkTag::APPKIT, "StartAbilitiesLog call StartAbilities"); + ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbilities(wantList, token_); + if (err != ERR_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "StartAbilitiesLog ret=%{public}d", err); + } + return err; +} + +ErrCode ServiceExtensionContext::OnAbilitiesRequestResponse(const std::string &startTime, + const int32_t resultCode) +{ + +} + ErrCode ServiceExtensionContext::StartServiceExtensionAbility(const AAFwk::Want &want, int32_t accountId) const { TAG_LOGD(AAFwkTag::APPKIT, "begin"); diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_client.h b/interfaces/inner_api/ability_manager/include/ability_manager_client.h index 66f98e5bb10..ffe0bea7aec 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_client.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_client.h @@ -284,6 +284,17 @@ public: int requestCode = DEFAULT_INVAL_VALUE, int32_t userId = DEFAULT_INVAL_VALUE); + /** + * @brief start abilities simultaneously. + * + * @param wantList a list of want to start abilities. + * @param callerToken current caller ability token. + * @param userId, Designation User ID. + * @return Returns ERR_OK if success. + */ + ErrCode StartAbilities(const std::vector &wantList, + const sptr &callerToken, int32_t userId = DEFAULT_INVAL_VALUE); + /** * Start ui session ability with extension session info, send session info to ability manager service. * diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_errors.h b/interfaces/inner_api/ability_manager/include/ability_manager_errors.h index 87c485af117..17e5758311c 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_errors.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_errors.h @@ -1135,6 +1135,29 @@ enum NativeFreeInstallError { */ ERR_WRITE_SA_INTERCEPTOR_FAILED = 29360219, + /* + * Result(29360220) for write SIZE failed. + */ + ERR_WRITE_SIZE_FAILED = 29360220, + + ERR_WRITE_USER_ID_FAILED, + + START_ABILITIES_NOT_SUPPORT_DLP, + + START_ABILITIES_NOT_SUPPORT_START_PLUGIN, + + START_ABILITIES_NOT_SUPPORT_CREATE_APP_INSTANCE_KEY, + + START_ABILITIES_NOT_SUPPORT_OPERATE_REMOTE, + + START_ABILITIES_NOT_SUPPORT_CROSS_USER, + + START_ABILITIES_NOT_SUPPORT_IMPLICIT_START, + + START_ABILITIES_ONLY_SUPPORT_UI_ABILITY, + + START_ABILITIES_INTERCEPTOR_CHECK_FAILED, + /** * Undefine error code. */ diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h index ddaa51cff77..660e747b41e 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h @@ -304,6 +304,20 @@ public: return 0; } + /** + * @brief start abilities simultaneously. + * + * @param wantList a list of want to start abilities. + * @param callerToken current caller ability token. + * @param userId, Designation User ID. + * @return Returns ERR_OK if success. + */ + virtual ErrCode StartAbilities(const std::vector &wantList, + const sptr &callerToken, int32_t userId = DEFAULT_INVAL_VALUE) + { + return 0; + } + /** * Start ui session ability with extension session info, send session info to ability manager service. * diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h b/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h index 670fa535cf7..356300be809 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h @@ -416,6 +416,9 @@ enum class AbilityManagerInterfaceCode { // ipc id for close ui extension ability by scb CLOSE_UI_EXTENSION_ABILITY_BY_SCB = 1069, + // ipc id for start abilities + START_ABILITIES = 1070, + // ipc id for continue ability(1101) START_CONTINUATION = 1101, diff --git a/interfaces/inner_api/ability_manager/include/ability_scheduler_interface.h b/interfaces/inner_api/ability_manager/include/ability_scheduler_interface.h index a9365cf1c33..ebac47de0fe 100644 --- a/interfaces/inner_api/ability_manager/include/ability_scheduler_interface.h +++ b/interfaces/inner_api/ability_manager/include/ability_scheduler_interface.h @@ -312,6 +312,9 @@ public: virtual void ScheduleAbilityRequestSuccess(const std::string &requestId, const AppExecFwk::ElementName &element) = 0; + virtual void ScheduleAbilitiesRequestDone(const std::string &startTime, + const int32_t resultCode) = 0; + enum { // ipc id for scheduling ability to a state of life cycle SCHEDULE_ABILITY_TRANSACTION = 0, @@ -413,7 +416,9 @@ public: SCHEDULE_ABILITY_REQUEST_FAILURE, - SCHEDULE_ABILITY_REQUEST_SUCCESS + SCHEDULE_ABILITY_REQUEST_SUCCESS, + + SCHEDULE_ABILITIES_REQUEST_DONE, }; }; } // namespace AAFwk diff --git a/interfaces/kits/native/ability/native/ability_thread.h b/interfaces/kits/native/ability/native/ability_thread.h index 6dd0fe9cded..0f4382df071 100644 --- a/interfaces/kits/native/ability/native/ability_thread.h +++ b/interfaces/kits/native/ability/native/ability_thread.h @@ -364,6 +364,8 @@ public: void ScheduleAbilityRequestSuccess(const std::string &requestId, const AppExecFwk::ElementName &element) override; + void ScheduleAbilitiesRequestDone(const std::string &startTime, const int32_t resultCode) override; + sptr token_; std::shared_ptr abilityHandler_ = nullptr; std::shared_ptr runner_ = nullptr; diff --git a/interfaces/kits/native/ability/native/extension.h b/interfaces/kits/native/ability/native/extension.h index f1236563e4e..5d127134a98 100644 --- a/interfaces/kits/native/ability/native/extension.h +++ b/interfaces/kits/native/ability/native/extension.h @@ -191,6 +191,8 @@ public: virtual void OnConfigurationUpdated(const AppExecFwk::Configuration& configuration); + virtual void OnAbilitiesRequestResponse(const std::string &startTime, const int32_t resultCode); + /** * @brief Notify current memory level. * diff --git a/interfaces/kits/native/ability/native/extension_ability_thread.h b/interfaces/kits/native/ability/native/extension_ability_thread.h index b5eca2c8602..4f30e995d05 100644 --- a/interfaces/kits/native/ability/native/extension_ability_thread.h +++ b/interfaces/kits/native/ability/native/extension_ability_thread.h @@ -215,6 +215,8 @@ private: void HandleAttachInner(const std::shared_ptr &application, const std::shared_ptr &abilityRecord); + void ScheduleAbilitiesRequestDone(const std::string &startTime, const int32_t resultCode); + /** * @brief Handle the current command of Extension. * @param want The Want object to command to. diff --git a/interfaces/kits/native/ability/native/extension_impl.h b/interfaces/kits/native/ability/native/extension_impl.h index 28e0473a525..09bc20ac18e 100644 --- a/interfaces/kits/native/ability/native/extension_impl.h +++ b/interfaces/kits/native/ability/native/extension_impl.h @@ -202,6 +202,8 @@ protected: */ void Background(const Want &want, sptr sessionInfo); + void ScheduleAbilitiesRequestDone(const std::string &startTime, const int32_t resultCode); + private: inline bool UIExtensionAbilityExecuteInsightIntent(const Want &want); diff --git a/interfaces/kits/native/ability/native/js_service_extension_context.h b/interfaces/kits/native/ability/native/js_service_extension_context.h index 032db759051..31ffd34dc60 100644 --- a/interfaces/kits/native/ability/native/js_service_extension_context.h +++ b/interfaces/kits/native/ability/native/js_service_extension_context.h @@ -22,6 +22,7 @@ #include "service_extension_context.h" #include "event_handler.h" #include "js_free_install_observer.h" +#include "js_start_abilities_observer.h" #include "native_engine/native_engine.h" namespace OHOS { diff --git a/interfaces/kits/native/ability/native/js_start_abilities_observer.h b/interfaces/kits/native/ability/native/js_start_abilities_observer.h new file mode 100644 index 00000000000..f1d1de6ef5a --- /dev/null +++ b/interfaces/kits/native/ability/native/js_start_abilities_observer.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef OHOS_ABILITY_RUNTIME_JS_START_ABILITIES_OBSERVER_H + #define OHOS_ABILITY_RUNTIME_JS_START_ABILITIES_OBSERVER_H + + #include + #include + #include + + #include "native_engine/native_engine.h" + #include "js_runtime_utils.h" + + namespace OHOS { + namespace AbilityRuntime { + struct JsStartAbilitiesObserverObject { + std::string startTime; + int32_t resultCode; + napi_deferred deferred; + }; + + class JsStartAbilitiesObserver { + public: + /** + * JsStartAbilitiesObserver, constructor. + * + */ + explicit JsStartAbilitiesObserver(napi_env env); + + /** + * JsStartAbilitiesObserver, destructor. + * + */ + ~JsStartAbilitiesObserver(); + + /** + * OnInstallFinished, return free install result. + * + * @param bundleName Free install bundleName. + * @param abilityName Free install abilityName. + * @param startTime Free install start request time. + * @param resultCode The result of this free install. + */ + void OnInstallFinished(const std::string &bundleName, const std::string &abilityName, + const std::string &startTime, const int &resultCode) override; + + /** + * @brief Use for context to add an callback into the observer. + * + * @param bundleName The bundleName of want. + * @param abilityName The abilityName of want. + * @param startTime The startTime that want requested. + * @param jsObserverObject The js object instance. + * @param result the promise to return. + */ + void AddJsObserverObject(const std::string &bundleName, const std::string &abilityName, + const std::string &startTime, napi_value jsObserverObject, napi_value* result, bool isAbilityResult = false); + + private: + /** + * CallPromise, resolve promise. + * + * @param deferred The promise that is to be resolved. + * @param resultCode The result code of the promise. + */ + void CallPromise(napi_deferred deferred, int32_t resultCode); + + /** + * HandleOnInstallFinished, handle the event of free install upon finished. + * + * @param bundleName The bundle name of the app. + * @param abilityName The ability name of the app. + * @param startTime The start time. + * @param resultCode The result code. + */ + void HandleOnInstallFinished(const std::string &bundleName, const std::string &abilityName, + const std::string &startTime, const int &resultCode); + + /** + * AddJsObserverCommon, helper of AddJsObserverObject. + * + * @param object The free install observer object. + * @param jsObserverObject The js observer object. + * @param result The resultant object. + * @param isAbilityResult The flag of whether it is to return ability result. + */ + void AddJsObserverCommon(JsStartAbilitiesObserverObject &object, + napi_value jsObserverObject, napi_value* result, bool isAbilityResult); + napi_env env_; + std::mutex jsObserverObjectListLock_; + std::vector jsObserverObjectList_; + }; + } // namespace AbilityRuntime + } // namespace OHOS + + #endif // OHOS_ABILITY_RUNTIME_JS_START_ABILITIES_OBSERVER_H \ No newline at end of file diff --git a/interfaces/kits/native/ability/native/service_extension.h b/interfaces/kits/native/ability/native/service_extension.h index 81d50fababc..bd779de5b7c 100644 --- a/interfaces/kits/native/ability/native/service_extension.h +++ b/interfaces/kits/native/ability/native/service_extension.h @@ -82,6 +82,8 @@ public: */ void OnConfigurationUpdated(const AppExecFwk::Configuration &configuration) override; + void OnAbilitiesRequestResponse(const std::string &startTime, const int32_t resultCode) override; + private: static CreatorFunc creator_; }; diff --git a/interfaces/kits/native/ability/native/ui_extension_base/js_ui_extension_context.h b/interfaces/kits/native/ability/native/ui_extension_base/js_ui_extension_context.h index 8e74c60d1df..a7071faf073 100755 --- a/interfaces/kits/native/ability/native/ui_extension_base/js_ui_extension_context.h +++ b/interfaces/kits/native/ability/native/ui_extension_base/js_ui_extension_context.h @@ -20,6 +20,7 @@ #include "ui_extension_context.h" #include "js_free_install_observer.h" +#include "js_start_abilities_observer.h" #include "native_engine/native_engine.h" namespace OHOS { @@ -40,6 +41,7 @@ public: static napi_value CreateJsUIExtensionContext(napi_env env, std::shared_ptr context); static napi_value StartAbilityForResult(napi_env env, napi_callback_info info); static napi_value StartAbilityForResultAsCaller(napi_env env, napi_callback_info info); + static napi_value StartAbilities(napi_env env, napi_callback_info info); static napi_value ConnectAbility(napi_env env, napi_callback_info info); static napi_value DisconnectAbility(napi_env env, napi_callback_info info); static napi_value ReportDrawnCompleted(napi_env env, napi_callback_info info); @@ -60,6 +62,7 @@ protected: virtual napi_value OnTerminateSelfWithResult(napi_env env, NapiCallbackInfo& info); virtual napi_value OnStartAbilityForResult(napi_env env, NapiCallbackInfo& info); virtual napi_value OnStartAbilityForResultAsCaller(napi_env env, NapiCallbackInfo &info); + virtual napi_value OnStartAbilities(napi_env env, NapiCallbackInfo& info); virtual napi_value OnConnectAbility(napi_env env, NapiCallbackInfo& info); virtual napi_value OnDisconnectAbility(napi_env env, NapiCallbackInfo& info); virtual napi_value OnReportDrawnCompleted(napi_env env, NapiCallbackInfo& info); @@ -85,6 +88,7 @@ protected: std::weak_ptr context_; private: sptr freeInstallObserver_ = nullptr; + sptr startAbilitiesObserver_ = nullptr; friend class JsEmbeddableUIAbilityContext; bool CheckStartAbilityInputParam(napi_env env, NapiCallbackInfo& info, AAFwk::Want& want, diff --git a/interfaces/kits/native/ability/native/ui_extension_base/ui_extension_context.h b/interfaces/kits/native/ability/native/ui_extension_base/ui_extension_context.h index 8f82651f6d6..554204a16d3 100755 --- a/interfaces/kits/native/ability/native/ui_extension_base/ui_extension_context.h +++ b/interfaces/kits/native/ability/native/ui_extension_base/ui_extension_context.h @@ -98,6 +98,8 @@ public: */ ErrCode StartServiceExtensionAbility(const AAFwk::Want &want, int32_t accountId = -1); + ErrCode StartAbilities(const std::vector &wantList) const; + /** * Start other ability for result. * diff --git a/interfaces/kits/native/appkit/ability_runtime/service_extension_context.h b/interfaces/kits/native/appkit/ability_runtime/service_extension_context.h index 3baf1b6f15c..4057e691f90 100644 --- a/interfaces/kits/native/appkit/ability_runtime/service_extension_context.h +++ b/interfaces/kits/native/appkit/ability_runtime/service_extension_context.h @@ -27,6 +27,7 @@ namespace OHOS { namespace AbilityRuntime { +using OnAbilitiesResponseCallback = std::function; /** * @brief context supply for service * @@ -122,6 +123,12 @@ public: ErrCode StartAbilityWithAccount( const AAFwk::Want &want, int accountId, const AAFwk::StartOptions &startOptions) const; + + ErrCode StartAbilities(const std::vector &wantList) const; + + ErrCode OnAbilitiesRequestResponse(const std::string &startTime, const int32_t resultCode) const; + + ErrCode AddAbiltiesCallback(const std::string &startTime, OnAbilitiesResponseCallback callback) const; ErrCode StartServiceExtensionAbility(const AAFwk::Want &want, int32_t accountId = -1) const; diff --git a/services/abilitymgr/include/ability_manager_proxy.h b/services/abilitymgr/include/ability_manager_proxy.h index cf32223a837..d281f91ee22 100644 --- a/services/abilitymgr/include/ability_manager_proxy.h +++ b/services/abilitymgr/include/ability_manager_proxy.h @@ -216,6 +216,17 @@ public: int requestCode = DEFAULT_INVAL_VALUE, int32_t userId = DEFAULT_INVAL_VALUE) override; + /** + * @brief start abilities simultaneously. + * + * @param wantList a list of want to start abilities. + * @param callerToken current caller ability token. + * @param userId, Designation User ID. + * @return Returns ERR_OK if success. + */ + ErrCode StartAbilities(const std::vector &wantList, + const sptr &callerToken, int32_t userId = DEFAULT_INVAL_VALUE) override; + /** * Start ui session ability with extension session info, send session info to ability manager service. * diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index a418c07c4c4..95098dc2030 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -336,6 +336,18 @@ public: int requestCode = DEFAULT_INVAL_VALUE, int32_t userId = DEFAULT_INVAL_VALUE) override; + + /** + * @brief start abilities simultaneously. + * + * @param wantList a list of want to start abilities. + * @param callerToken current caller ability token. + * @param userId, Designation User ID. + * @return Returns ERR_OK if success. + */ + ErrCode StartAbilities(const std::vector &wantList, + const sptr &callerToken, int32_t userId = DEFAULT_INVAL_VALUE) override; + /** * Start ui session ability with extension session info, send session info to ability manager service. * diff --git a/services/abilitymgr/include/ability_manager_stub.h b/services/abilitymgr/include/ability_manager_stub.h index ec97fda26cd..461628464dc 100644 --- a/services/abilitymgr/include/ability_manager_stub.h +++ b/services/abilitymgr/include/ability_manager_stub.h @@ -295,6 +295,7 @@ private: int StartAbilityForResultAsCallerInner(MessageParcel &data, MessageParcel &reply); int StartAbilityForResultAsCallerForOptionsInner(MessageParcel &data, MessageParcel &reply); + int32_t StartAbilitiesInner(MessageParcel &data, MessageParcel &reply); int32_t StartAbilityOnlyUIAbilityInner(MessageParcel &data, MessageParcel &reply); diff --git a/services/abilitymgr/include/ability_record.h b/services/abilitymgr/include/ability_record.h index 4843aa5922c..a8fb1783b0e 100644 --- a/services/abilitymgr/include/ability_record.h +++ b/services/abilitymgr/include/ability_record.h @@ -1181,6 +1181,8 @@ public: void NotifyAbilityRequestSuccess(const std::string &requestId, const AppExecFwk::ElementName &element); + void NotifyAbilitiesRequestDone(const std::string &startTime, const int32_t resultCode); + void ScheduleCollaborate(const Want &want); bool IsHook () const diff --git a/services/abilitymgr/include/ability_scheduler_proxy.h b/services/abilitymgr/include/ability_scheduler_proxy.h index e25c6ac6597..21625a52500 100644 --- a/services/abilitymgr/include/ability_scheduler_proxy.h +++ b/services/abilitymgr/include/ability_scheduler_proxy.h @@ -338,6 +338,7 @@ public: void ScheduleAbilityRequestSuccess(const std::string &requestId, const AppExecFwk::ElementName &element) override; + void ScheduleAbilitiesRequestDone(const std::string &startTime, const int32_t resultCode) override; private: bool WriteInterfaceToken(MessageParcel &data); int32_t SendTransactCmd(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); diff --git a/services/abilitymgr/include/ability_scheduler_stub.h b/services/abilitymgr/include/ability_scheduler_stub.h index e85b2d94faa..96fa99c1984 100644 --- a/services/abilitymgr/include/ability_scheduler_stub.h +++ b/services/abilitymgr/include/ability_scheduler_stub.h @@ -82,6 +82,7 @@ private: int CollaborateDataInner(MessageParcel &data); int ScheduleAbilityRequestFailureInner(MessageParcel &data); int ScheduleAbilityRequestSuccessInner(MessageParcel &data); + int ScheduleAbilitiesRequestDoneInner(MessageParcel &data); }; /** diff --git a/services/abilitymgr/include/lifecycle_deal.h b/services/abilitymgr/include/lifecycle_deal.h index 85132710b30..964b8d45d02 100644 --- a/services/abilitymgr/include/lifecycle_deal.h +++ b/services/abilitymgr/include/lifecycle_deal.h @@ -90,6 +90,8 @@ public: const std::string &message); void NotifyAbilityRequestSuccess(const std::string &requestId, const AppExecFwk::ElementName &element); + void NotifyAbilitiesRequestDone(const std::string &startTime, const int32_t resultCode); + private: sptr GetScheduler(); sptr abilityScheduler_; // kit interface used to schedule ability life diff --git a/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h b/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h index c6711837da5..c1e28877c0c 100644 --- a/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h +++ b/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h @@ -46,6 +46,7 @@ struct SpecifiedRequest { SpecifiedProcessState specifiedProcessState = SpecifiedProcessState::STATE_NONE; int32_t requestId = 0; int32_t persistentId = 0; + int32_t requestListId = -1; uint32_t sceneFlag = 0; uint32_t callingTokenId = 0; AbilityRequest abilityRequest; @@ -53,6 +54,15 @@ struct SpecifiedRequest { SpecifiedRequest(int32_t requestId, AbilityRequest request) : requestId(requestId), abilityRequest(request) {} }; +// AbilitiesRequest 指包含多个ability的一个request +struct AbilitiesRequest { + std::vector waitingRequestIdList;//移除时机不能是specifiedR移除时,而是各个分支决定走入sceneSession时 + std::vector abilityRequestList; + std::vector> UnsortedSessionInfoList; + + AbilitiesRequest(std::vector abilityRequestList) : abilityRequestList(abilityRequestList) {} +}; + class UIAbilityLifecycleManager : public std::enable_shared_from_this { public: UIAbilityLifecycleManager() = default; @@ -164,6 +174,7 @@ public: void SetRootSceneSession(const sptr &rootSceneSession); int NotifySCBToStartUIAbility(AbilityRequest &abilityRequest); + int32_t NotifySCBToStartUIAbilities(std::vector &abilityRequestList); int NotifySCBToPreStartUIAbility(const AbilityRequest &abilityRequest, sptr &sessionInfo); @@ -443,6 +454,8 @@ private: sptr CreateSessionInfo(const AbilityRequest &abilityRequest) const; int NotifySCBPendingActivation(sptr &sessionInfo, const AbilityRequest &abilityRequest, std::string &errMsg); + int32_t BatchNotifySCBPendingActivation(std::vector> &sessionInfoList, + const std::vector &abilityRequestList, std::string &errMsg); bool IsHookModule(const AbilityRequest &abilityRequest) const; int ResolveAbility(const std::shared_ptr &targetAbility, const AbilityRequest &abilityRequest) const; std::vector> GetAbilityRecordsByNameInner(const AppExecFwk::ElementName &element); @@ -566,6 +579,8 @@ private: std::vector> prepareTerminateByPidRecords_; std::unordered_map> hookSpecifiedMap_; + ffrt::mutex startAbilitiesProcessLock_; + std::map>> abilitiesRequestMap_; std::mutex startingPidsMutex_; std::vector startingPids_; }; diff --git a/services/abilitymgr/src/ability_manager_client.cpp b/services/abilitymgr/src/ability_manager_client.cpp index 3b2389f6271..aec44da8dcf 100644 --- a/services/abilitymgr/src/ability_manager_client.cpp +++ b/services/abilitymgr/src/ability_manager_client.cpp @@ -261,6 +261,23 @@ ErrCode AbilityManagerClient::StartAbilityForResultAsCaller(const Want &want, co return abms->StartAbilityForResultAsCaller(want, startOptions, callerToken, requestCode, userId); } +ErrCode AbilityManagerClient::StartAbilities(const std::vector &wantList, + const sptr &callerToken, int32_t userId) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGI(AAFwkTag::ABILITYMGR, "call StartAbilities"); + for (const Want &item : wantList) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "StartAbilitiesLog want abilityName %{public}s", item.GetElement().GetAbilityName().c_str()); + } + TAG_LOGI(AAFwkTag::ABILITYMGR, "call StartAbilities"); + auto abms = GetAbilityManager(); + CHECK_POINTER_RETURN_NOT_CONNECTED(abms); + for (const Want &item : wantList) { + HandleDlpApp(const_cast(item)); + } + return abms->StartAbilities(wantList, callerToken, userId); +} + ErrCode AbilityManagerClient::StartAbilityByUIContentSession(const Want &want, const StartOptions &startOptions, sptr callerToken, sptr sessionInfo, int requestCode, int32_t userId) diff --git a/services/abilitymgr/src/ability_manager_proxy.cpp b/services/abilitymgr/src/ability_manager_proxy.cpp index a7aca2e9eff..2c8a73501bf 100644 --- a/services/abilitymgr/src/ability_manager_proxy.cpp +++ b/services/abilitymgr/src/ability_manager_proxy.cpp @@ -497,6 +497,56 @@ int AbilityManagerProxy::StartAbilityForResultAsCaller(const Want &want, const S return reply.ReadInt32(); } +ErrCode AbilityManagerProxy::StartAbilities(const std::vector &wantList, + const sptr &callerToken, int32_t userId) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (callerToken == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null callerToken"); + return INVALID_CALLER_TOKEN; + } + if (!WriteInterfaceToken(data)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write token fail"); + return ERR_WRITE_INTERFACE_TOKEN_FAILED; + } + + int32_t size = static_cast(wantList.size()); + int32_t threshold = 4; + if (size > threshold) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "vector too large"); + return ERR_NATIVE_IPC_PARCEL_FAILED; + } + if (!data.WriteInt32(size)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write size fail"); + return ERR_WRITE_SIZE_FAILED; + } + for (const Want &item : wantList) { + if (!data.WriteParcelable(&item)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write want fail"); + return ERR_WRITE_WANT; + } + } + + if (!data.WriteRemoteObject(callerToken)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write callerToken fail"); + return ERR_WRITE_CALLER_TOKEN_FAILED; + } + + if (!data.WriteInt32(userId)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write userId fail"); + return ERR_WRITE_USER_ID_FAILED; + } + + auto error = SendRequest(AbilityManagerInterfaceCode::START_ABILITIES, data, reply, option); + if (error != NO_ERROR) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "request error:%{public}d", error); + return error; + } + return reply.ReadInt32(); +} + int AbilityManagerProxy::CheckUISessionParams(MessageParcel &data, const sptr &callerToken, const sptr &sessionInfo, int32_t userId, int requestCode) { diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index a8e70944708..82ed862da7d 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -2167,6 +2167,200 @@ int AbilityManagerService::StartAbilityForOptionInner(const Want &want, const St return ret; } +ErrCode AbilityManagerService::StartAbilities(std::vector &wantList, + const sptr &callerToken, int32_t userId) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + XCOLLIE_TIMER_LESS(__PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::ABILITYMGR, "Call StartAbilities"); + std::vector abilityRequestList; + int32_t oriValidUserId = GetValidUserId(userId); + int32_t validUserId = oriValidUserId; + //before want + //callerToken 必须存在且有效 before want + if (callerToken == nullptr || !VerificationAllToken(callerToken)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities %{public}s verificationAllToken failed", __func__); + return ERR_INVALID_CALLER; + } + + for (Want &want : wantList) { + //func processWant + AbilityUtil::RemoveShowModeKey(const_cast(want)); + + //intent openlink do not RemoveInsightIntent action + if (!want.HasParameter(AppExecFwk::INSIGHT_INTENT_EXECUTE_OPENLINK_FLAG)) { + InsightIntentExecuteParam::RemoveInsightIntent(const_cast(want)); + } + +#ifdef SUPPORT_SCREEN + DmsUtil::GetInstance().UpdateFlagForCollaboration(want); +#endif + +#ifdef WITH_DLP //不支持 返回错误码 怎么判断是否触发了DLP handle == true? 是的,判断完后再判断DLP权限 + if (AbilityUtil::HandleDlpApp(const_cast(want))) { + //新增错误码 + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities not support Dlp"); + return START_ABILITIES_NOT_SUPPORT_DLP; + } + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "CHECK_DLP"); + if (!DlpUtils::OtherAppsAccessDlpCheck(callerToken, want) || + VerifyAccountPermission(userId) == CHECK_PERMISSION_FAILED || + !DlpUtils::DlpAccessOtherAppsCheck(callerToken, want)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities Dlp %{public}s: permission verification failed", __func__); + return CHECK_PERMISSION_FAILED; + } +#endif // WITH_DLP + + if (AbilityRuntime::StartupUtil::IsStartPlugin(want)) { + //新增错误码 + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities not support StartPlugin"); + return START_ABILITIES_NOT_SUPPORT_START_PLUGIN; + } + + AbilityUtil::RemoveWindowModeKey(const_cast(want)); + + //ERR_CREATE_INSTANCE_KEY_FAILED 创建新实例 不支持 返回错误码 需要在这里判断吗 判断key前置拦截 + if (want.GetBoolParam(Want::CREATE_APP_INSTANCE_KEY, false);) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities not support CREATE_APP_INSTANCE_KEY"); + return START_ABILITIES_NOT_SUPPORT_CREATE_APP_INSTANCE_KEY; + } + // AppIndex是否有值 没有->与caller不同包名设置为0,同包名设置为caller的index;有值->是否有效(最大最小范围) + // func StartAbilitiesProcessAppIndex + if (want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY)) { + auto appIndex = want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, -1); + if (appIndex < 0 || appIndex > AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities appCloneIndex exist and invalid"); + return ERR_APP_CLONE_INDEX_INVALID; + } + } + //action1 + SetTargetCloneIndexInSameBundle(want, callerToken);//不同包名 不处理;同包名 有预置的key不处理;同包名 没有预置的key -> 若caller的index有效,给want也设置相同值 + int32_t appIndex = 0 + if (!StartAbilityUtils::GetAppIndex(want, callerToken, appIndex)) { + return ERR_APP_CLONE_INDEX_INVALID; + } + // func StartAbilitiesProcessAppIndex end + + //action1 + auto checkRet = AbilityPermissionUtil::GetInstance().CheckMultiInstanceAndAppClone(const_cast(want), + validUserId, appIndex, callerToken); + if (checkRet != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities CheckMultiInstanceAndAppClone failed"); + return checkRet; + } + //action1 + StartAbilityInfoWrap threadLocalInfo(want, validUserId, appIndex, callerToken); + + //action1 不支持 返回错误码 zfm + if (CheckIfOperateRemote(want)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities not support StartRemoteAbility"); + return START_ABILITIES_NOT_SUPPORT_OPERATE_REMOTE; + }1 + + //action0 不支持 返回错误码 zfm 返回false说明不允许 + if (!JudgeMultiUserConcurrency(validUserId)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities multi-user non-concurrent unsatisfied"); + return START_ABILITIES_NOT_SUPPORT_CROSS_USER; + } + // 隐式启动 不支持 返回错误码 +#ifdef SUPPORT_SCREEN + if (ImplicitStartProcessor::IsImplicitStartAction(want)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities not support implicit start"); + return START_ABILITIES_NOT_SUPPORT_IMPLICIT_START; + } +#endif + AbilityRequest abilityRequest; + result = GenerateAbilityRequest(want, requestCode, abilityRequest, callerToken, validUserId); + auto abilityRecord = Token::GetAbilityRecordByToken(callerToken); + std::string callerBundleName = abilityRecord ? abilityRecord->GetAbilityInfo().bundleName : ""; + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "generate ability request local error"); + return result; + } + + TAG_LOGD(AAFwkTag::ABILITYMGR, "StartAbilities abilityRequest generated"); + UpdateCallerInfoUtil::GetInstance().UpdateCallerInfo(abilityRequest.want, callerToken); + + auto abilityInfo = abilityRequest.abilityInfo; + //仅支持UIAbility + if (abilityInfo.type != AbilityType::PAGE) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities only support UIAbility"); + return START_ABILITIES_ONLY_SUPPORT_UI_ABILITY; + } + //校验StaticCfg权限 + result = CheckStaticCfgPermission(abilityRequest, isStartAsCaller, + abilityRequest.want.GetIntParam(Want::PARAM_RESV_CALLER_TOKEN, 0), false, false, false); + if (result != AppExecFwk::Constants::PERMISSION_GRANTED) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities checkStaticCfgPermission error, result:%{public}d", result); + return ERR_STATIC_CFG_PERMISSION;// 是否需要新增错误码 + } + //校验拉起权限 specifyTokenId从哪里获取 默认为0 + result = CheckCallPermission(want, abilityInfo, abilityRequest, false, + false, specifyTokenId, callerBundleName); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities checkCallPermission error, result:%{public}d", result); + return result; + } + + //action1 + Want newWant = abilityRequest.want; + //action1 前置拦截器 + auto shouldBlockFunc = [aams = shared_from_this()]() { return aams->ShouldBlockAllAppStart(); }; + AbilityInterceptorParam interceptorParam = AbilityInterceptorParam(want, requestCode, GetUserId(), + true, nullptr, shouldBlockFunc); + auto result = interceptorExecuter_ == nullptr ? ERR_NULL_INTERCEPTOR_EXECUTER : + interceptorExecuter_->DoProcess(interceptorParam); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities interceptorExecuter_ null or DoProcess error"); + return START_ABILITIES_INTERCEPTOR_CHECK_FAILED; + } + //后置拦截器 + AbilityInterceptorParam afterCheckParam = AbilityInterceptorParam(newWant, requestCode, GetUserId(), + true, callerToken, std::make_shared(abilityInfo), isStartAsCaller, appIndex); + result = afterCheckExecuter_ == nullptr ? ERR_INVALID_VALUE : + afterCheckExecuter_->DoProcess(afterCheckParam); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities afterCheckExecuter_ null or DoProcess error"); + return START_ABILITIES_INTERCEPTOR_CHECK_FAILED; + } + // + bool isReplaceWantExist = newWant.GetBoolParam("queryWantFromErms", false); + newWant.RemoveParam("queryWantFromErms"); + + RemoveUnauthorizedLaunchReasonMessage(want, abilityRequest, callerToken); + + //abilityController权限校验 + if (!IsAbilityControllerStart(want, abilityInfo.bundleName)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities isAbilityControllerStart failed:%{public}s", abilityInfo.bundleName.c_str()); + return ERR_WOULD_BLOCK; + } + + //action1 需要 + abilityRequest.want.RemoveParam(SPECIFY_TOKEN_ID); + //action1 需要 + abilityRequest.want.RemoveParam(PARAM_SPECIFIED_PROCESS_FLAG); + + abilityRequestList.emplace_back(abilityRequest); + } + TAG_LOGD(AAFwkTag::ABILITYMGR, "StartAbilities ready to NotifySCBToStartUIAbilities"); + if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) { + for (AbilityRequest &abilityRequest : abilityRequestList) { + auto abilityInfo = abilityRequest.abilityInfo; + //action1 需要放到最后调多次,涉及与SCB通信 + ReportEventToRSS(abilityInfo, abilityRequest.callerToken); + //action1 需要 + abilityRequest.userId = oriValidUserId; + abilityRequest.want.SetParam(ServerConstant::IS_CALL_BY_SCB, false); + } + auto uiAbilityManager = GetUIAbilityManagerByUserId(oriValidUserId); + CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_INVALID_VALUE); + return uiAbilityManager->NotifySCBToStartUIAbilities(abilityRequestList); + } + //不支持 + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities is not supported"); + return ERR_CAPABILITY_NOT_SUPPORT; +} + int32_t AbilityManagerService::RequestDialogService(const Want &want, const sptr &callerToken) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); diff --git a/services/abilitymgr/src/ability_manager_stub.cpp b/services/abilitymgr/src/ability_manager_stub.cpp index bc0592a655b..aa17923c12f 100644 --- a/services/abilitymgr/src/ability_manager_stub.cpp +++ b/services/abilitymgr/src/ability_manager_stub.cpp @@ -575,6 +575,9 @@ int AbilityManagerStub::OnRemoteRequestInnerFourteenth(uint32_t code, MessagePar if (interfaceCode == AbilityManagerInterfaceCode::CLOSE_UI_EXTENSION_ABILITY_BY_SCB) { return CloseUIExtensionAbilityBySCBInner(data, reply); } + if (interfaceCode == AbilityManagerInterfaceCode::START_ABILITIES) { + return StartAbilitiesInner(data, reply); + } return ERR_CODE_NOT_EXIST; } @@ -3839,6 +3842,41 @@ int AbilityManagerStub::StartAbilityForResultAsCallerInner(MessageParcel &data, return NO_ERROR; } +int32_t AbilityManagerStub::StartAbilitiesInner(MessageParcel &data, MessageParcel &reply) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "call StartAbilitiesInner"); + + int32_t size = data.ReadInt32(); + int32_t threshold = 4; + if (size > threshold) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "vector size too large"); + return ERR_ENOUGH_DATA; + } + std::vector wantList; + for (auto i = 0; i < size; i++) { + std::unique_ptr want(data.ReadParcelable()); + if (want == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null want"); + return ERR_NATIVE_IPC_PARCEL_FAILED; + } + wantList.emplace_back(*want); + } + + sptr callerToken = data.ReadRemoteObject(); + if (callerToken == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null callerToken"); + return INVALID_CALLER_TOKEN; + } + int32_t userId = data.ReadInt32(); + + for (const Want &item : wantList) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "StartAbilitiesLog stub abilityName %{public}s", item.GetElement().GetAbilityName().c_str()); + } + int32_t result = StartAbilities(wantList, callerToken, userId); + reply.WriteInt32(result); + return NO_ERROR; +} + int AbilityManagerStub::StartAbilityForResultAsCallerForOptionsInner(MessageParcel &data, MessageParcel &reply) { TAG_LOGD(AAFwkTag::ABILITYMGR, "called"); diff --git a/services/abilitymgr/src/ability_record.cpp b/services/abilitymgr/src/ability_record.cpp index 865a3078b07..9b6dbe57657 100644 --- a/services/abilitymgr/src/ability_record.cpp +++ b/services/abilitymgr/src/ability_record.cpp @@ -3865,6 +3865,12 @@ void AbilityRecord::NotifyAbilityRequestSuccess(const std::string &requestId, co lifecycleDeal_->NotifyAbilityRequestSuccess(requestId, element); } +void AbilityRecord::NotifyAbilitiesRequestDone(const std::string &startTime, const int32_t resultCode) +{ + CHECK_POINTER(lifecycleDeal_); + lifecycleDeal_->NotifyAbilitiesRequestDone(startTime, resultCode); +} + void AbilityRecord::UpdateUIExtensionBindInfo(const WantParams &wantParams) { if (!UIExtensionUtils::IsUIExtension(GetAbilityInfo().extensionAbilityType)) { diff --git a/services/abilitymgr/src/ability_scheduler_proxy.cpp b/services/abilitymgr/src/ability_scheduler_proxy.cpp index 0e5bfb278c4..b43df1e48ef 100644 --- a/services/abilitymgr/src/ability_scheduler_proxy.cpp +++ b/services/abilitymgr/src/ability_scheduler_proxy.cpp @@ -1294,5 +1294,35 @@ void AbilitySchedulerProxy::ScheduleAbilityRequestSuccess(const std::string &req } return; } + +void AbilitySchedulerProxy::ScheduleAbilitiesRequestDone(const std::string &startTime, const int32_t resultCode) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!WriteInterfaceToken(data)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write interface token failed"); + return; + } + + auto msgKey = AbilityRuntime::ErrorMgsUtil::BuildErrorKey(reinterpret_cast(this), + "ScheduleAbilitiesRequestDone"); + if (!data.WriteString(startTime)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write startTime failed"); + AbilityRuntime::ErrorMgsUtil::GetInstance().UpdateErrorMsg(msgKey, "write startTime failed"); + return; + } + if (!data.WriteInt32(resultCode)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write resultCode failed"); + AbilityRuntime::ErrorMgsUtil::GetInstance().UpdateErrorMsg(msgKey, "write resultCode failed"); + return; + } + + int32_t err = SendTransactCmd(IAbilityScheduler::SCHEDULE_ABILITIES_REQUEST_DONE, data, reply, option); + if (err != NO_ERROR) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "fail, err: %{public}d", err); + } + return; +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/ability_scheduler_stub.cpp b/services/abilitymgr/src/ability_scheduler_stub.cpp index 47ee11a0318..9bfe2789740 100644 --- a/services/abilitymgr/src/ability_scheduler_stub.cpp +++ b/services/abilitymgr/src/ability_scheduler_stub.cpp @@ -160,6 +160,8 @@ int AbilitySchedulerStub::OnRemoteRequestInnerThird( return ScheduleAbilityRequestFailureInner(data); case SCHEDULE_ABILITY_REQUEST_SUCCESS: return ScheduleAbilityRequestSuccessInner(data); + case SCHEDULE_ABILITIES_REQUEST_DONE: + return ScheduleAbilitiesRequestDoneInner(data); } return ERR_CODE_NOT_EXIST; } @@ -780,6 +782,14 @@ int AbilitySchedulerStub::ScheduleAbilityRequestSuccessInner(MessageParcel &data return NO_ERROR; } +int AbilitySchedulerStub::ScheduleAbilitiesRequestDoneInner(MessageParcel &data) +{ + std::string startTime = data.ReadString(); + int32_t resultCode = data.ReadInt32(); + ScheduleAbilitiesRequestDone(startTime, resultCode); + return NO_ERROR; +} + void AbilitySchedulerRecipient::OnRemoteDied(const wptr &remote) { TAG_LOGE(AAFwkTag::ABILITYMGR, "call"); diff --git a/services/abilitymgr/src/lifecycle_deal.cpp b/services/abilitymgr/src/lifecycle_deal.cpp index 8fc5a020411..38efe62d151 100644 --- a/services/abilitymgr/src/lifecycle_deal.cpp +++ b/services/abilitymgr/src/lifecycle_deal.cpp @@ -215,5 +215,12 @@ void LifecycleDeal::NotifyAbilityRequestSuccess(const std::string &requestId, co CHECK_POINTER(abilityScheduler); abilityScheduler->ScheduleAbilityRequestSuccess(requestId, element); } + +void LifecycleDeal::NotifyAbilitiesRequestDone(const std::string &startTime, const int32_t resultCode) +{ + auto abilityScheduler = GetScheduler(); + CHECK_POINTER(abilityScheduler); + abilityScheduler->ScheduleAbilitiesRequestDone(startTime, resultCode); +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp b/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp index 7540506ec34..7ece5688588 100644 --- a/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp +++ b/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp @@ -58,6 +58,7 @@ constexpr const char* PARAM_SPECIFIED_PROCESS_FLAG = "ohoSpecifiedProcessFlag"; constexpr const char* DMS_PROCESS_NAME = "distributedsched"; constexpr const char* DMS_PERSISTENT_ID = "ohos.dms.persistentId"; constexpr const char* IS_SHELL_CALL = "isShellCall"; +constexpr const char* START_ABILITIES_REQUEST_ID = "startAbilitiesRequestId"; #ifdef SUPPORT_ASAN constexpr int KILL_TIMEOUT_MULTIPLE = 45; #else @@ -68,6 +69,7 @@ constexpr int32_t MAX_FIND_UIEXTENSION_CALLER_TIMES = 10; constexpr int32_t START_UI_ABILITY_PER_SECOND_UPPER_LIMIT = 20; constexpr int32_t API20 = 20; constexpr int32_t API_VERSION_MOD = 100; +constexpr int32_t REQUEST_LIST_ID_INIT = -1; constexpr const char* IS_CALLING_FROM_DMS = "supportCollaborativeCallingFromDmsInAAFwk"; constexpr int REMOVE_STARTING_BUNDLE_TIMEOUT_MICRO_SECONDS = 5000000; // 5s @@ -636,6 +638,270 @@ int UIAbilityLifecycleManager::NotifySCBToStartUIAbility(AbilityRequest &ability return ret; } +int UIAbilityLifecycleManager::NotifySCBToStartUIAbilities(std::vector &abilityRequestList) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::ABILITYMGR, "StartAbilities Call NotifySCBToStartUIAbilities"); + // list中的request加工 + for (AbilityRequest &abilityRequest : abilityRequestList) { + if (!AddStartCallerTimestamp(abilityRequest.want.GetIntParam(Want::PARAM_RESV_CALLER_UID, -1))) { + return ERR_INVALID_VALUE; + } + abilityRequest.want.SetParam(IS_SHELL_CALL, AAFwk::PermissionVerification::GetInstance()->IsShellCall()); + std::string callerKey = std::to_string(IPCSkeleton::GetCallingPid()) + ":" + + std::to_string(IPCSkeleton::GetCallingUid()); + bool isCallerKilling = IN_PROCESS_CALL(DelayedSingleton::GetInstance()->IsCallerKilling(callerKey)); + if (isCallerKilling) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartAbilities caller is killing"); + return ERR_INVALID_VALUE; + } + abilityRequest.want.SetParam(Want::PARAMS_REAL_CALLER_KEY, callerKey); + // want里面再set一个requestId参数,用于后续排序 + std::lock_guard guard(sessionLock_); + int32_t curRequestId = GetRequestId(); + abilityRequest.want.RemoveParam(START_ABILITIES_REQUEST_ID); + abilityRequest.want.SetParam(START_ABILITIES_REQUEST_ID, curRequestId); + } + int32_t requestListId; + std::shared_ptr abilitiesRequest = nullptr; + // func AddAbilitiesRequestList 初始化AbilitiesRequest + { + // 持锁修改requestId_ + std::lock_guard guard(sessionLock_); + requestListId = GetRequestId(); + // std::shared_ptr + abilitiesRequest = AbilitiesRequest(abilityRequestList); + // 持锁修改abilitiesRequestMap_ + std::lock_guard guard(startAbilitiesProcessLock_); + // 重复?排队?不需要? + abilitiesRequestMap_.emplace(requestListId, abilitiesRequest); + } + // func AddAbilitiesRequestList end + // 开始处理分支场景,做requestListId标记 + for (AbilityRequest &abilityRequest : abilityRequestList) { + std::lock_guard guard(sessionLock_); + if (IsStartSpecifiedProcessRequest(abilityRequest)) { + int32_t ret = StartSpecifiedProcessRequest(abilityRequest, requestListId); + if (ret != ERR_OK) { + // specified报错 + return ret; + } + // 继续遍历后续request + continue; + } + const auto &abilityInfo = abilityRequest.abilityInfo; + auto requestId = GetRequestId(); + auto isSpecified = (abilityInfo.launchMode == AppExecFwk::LaunchMode::SPECIFIED); + if (isSpecified) { + auto specifiedRequest = std::make_shared(requestId, abilityRequest); + specifiedRequest->preCreateProcessName = true; + specifiedRequest->requestListId = requestListId; + AddSpecifiedRequest(specifiedRequest); + // 继续遍历后续request + continue; + } + // 进入此分支,表示该abilityRequest,属于普通类型,不属于specifiedProcess或specifiedAbility + // 创建并 “普通”初始化 sessionInfo + auto sessionInfo = CreateSessionInfo(abilityRequest); + sessionInfo->requestCode = abilityRequest.requestCode; + sessionInfo->requestId = requestId; + // isCreating 一定是 false 下方场景确认一下 + auto isCreating = abilityRequest.want.GetBoolParam(Want::CREATE_APP_INSTANCE_KEY, false); + if (abilityInfo.applicationInfo.multiAppMode.multiAppModeType != AppExecFwk::MultiAppModeType::MULTI_INSTANCE || + !isCreating) { + sessionInfo->persistentId = GetPersistentIdByAbilityRequest(abilityRequest, sessionInfo->reuse); + } + // + sessionInfo->userId = userId_; + sessionInfo->isAtomicService = (abilityInfo.applicationInfo.bundleType == AppExecFwk::BundleType::ATOMIC_SERVICE); + TAG_LOGI(AAFwkTag::ABILITYMGR, "Reused sessionId: %{public}d, userId: %{public}d, requestId: %{public}d", + sessionInfo->persistentId, userId_, requestId); + // 将初始化完成的sessionInfo插入对应的abilitiesRequest中 + abilitiesRequest->UnsortedSessionInfoList.emplace_back(sessionInfo); + } + // 判断是否需要等待Specified + if (!abilitiesRequest->waitingRequestIdList.empty()) { + // 新增错误码 返回此错误码表示进入等待 + return START_ABILITIES_WAITTING_SPECIFIED_CODE; + } + // 进入这个分支,SessionInfoList是有序的,不用重排 + std::string errMsg; + TAG_LOGI(AAFwkTag::ABILITYMGR, "StartAbilities normal start. sessionInfoList size: %{public}zu", + abilitiesRequest->UnsortedSessionInfoList.size()); + // sptr sessionInfo0 = &sessionInfoList[0]; + for (auto &abilityRequest : abilityRequestList) { + abilityRequest.want.RemoveParam(START_ABILITIES_REQUEST_ID); + } + int ret = BatchNotifySCBPendingActivation( + abilitiesRequest->UnsortedSessionInfoList, abilityRequestList, errMsg); + for (auto sessionInfo : abilitiesRequest->UnsortedSessionInfoList) { + sessionInfo->want.RemoveAllFd(); + sessionInfo->want.RemoveParam(START_ABILITIES_REQUEST_ID); + } + abilitiesRequestMap_.erase(requestListId); + return ret; +} + +int32_t UIAbilityLifecycleManager::BatchNotifySCBPendingActivation(std::vector> &sessionInfoList, + const std::vector &abilityRequestList, std::string &errMsg) +{ + // 对sessionInfoList进行排序 按abilityRequest的顺序重组sessionInfoList + std::sort(sessionInfoList.begin(), sessionInfoList.end(), + [] (const auto infoOne, const auto infoTwo) { + int32_t idOne = infoOne->want.GetIntParam(START_ABILITIES_REQUEST_ID, -1); + int32_t idTwo = infoTwo->want.GetIntParam(START_ABILITIES_REQUEST_ID, -1); + return idOne < idTwo; + }) + // process sessionInfoList + for (auto sessionInfo : sessionInfoList) { + if (sessionInfo == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "sessionInfo is nullptr"); + errMsg = "sessionInfo is nullptr"; + return ERR_INVALID_VALUE; + } + TAG_LOGD(AAFwkTag::ABILITYMGR, "windowLeft=%{public}d,windowTop=%{public}d,windowHeight=%{public}d," + "windowWidth=%{public}d,windowMode=%{public}d,supportWindowModes.size=%{public}zu,specifiedFlag=%{public}s", + (sessionInfo->want).GetIntParam(Want::PARAM_RESV_WINDOW_LEFT, 0), + (sessionInfo->want).GetIntParam(Want::PARAM_RESV_WINDOW_TOP, 0), + (sessionInfo->want).GetIntParam(Want::PARAM_RESV_WINDOW_HEIGHT, 0), + (sessionInfo->want).GetIntParam(Want::PARAM_RESV_WINDOW_WIDTH, 0), + (sessionInfo->want).GetIntParam(Want::PARAM_RESV_WINDOW_MODE, 0), + (sessionInfo->supportWindowModes).size(), sessionInfo->specifiedFlag.c_str()); + bool hasStartWindowOption = (sessionInfo->startWindowOption != nullptr); + bool hasStartWindow = hasStartWindowOption ? sessionInfo->startWindowOption->hasStartWindow : false; + std::string backgroundColor = + hasStartWindowOption ? sessionInfo->startWindowOption->startWindowBackgroundColor : ""; + TAG_LOGI(AAFwkTag::ABILITYMGR, "appCloneIndex:%{public}d, instanceKey:%{public}s, " + "hasStartWindow:%{public}d, backgroundColor:%{public}s", + (sessionInfo->want).GetIntParam(Want::PARAM_APP_CLONE_INDEX_KEY, 0), sessionInfo->instanceKey.c_str(), + hasStartWindow, backgroundColor.c_str()); + sessionInfo->want.RemoveParam(START_ABILITIES_REQUEST_ID); + } + // 获取caller信息 + std::shared_ptr callerAbilityRecord; + callerAbilityRecord = GetAbilityRecordByToken(abilityRequestList[0].callerToken); + if (callerAbilityRecord == nullptr || callerAbilityRecord->GetRestartAppFlag()) + { + TAG_LOGE(AAFwkTag::ABILITYMGR, "callerAbilityRecord not exist."); + return ERR_INVALID_VALUE + } + // 处理caller + auto callerSessionInfo = callerAbilityRecord->GetSessionInfo(); + if (callerSessionInfo != nullptr) { + // CHECK_POINTER_AND_RETURN(callerSessionInfo, ERR_INVALID_VALUE); + CHECK_POINTER_AND_RETURN(callerSessionInfo->sessionToken, ERR_INVALID_VALUE); + auto callerSession = iface_cast(callerSessionInfo->sessionToken); + CHECK_POINTER_AND_RETURN(callerSession, ERR_INVALID_VALUE); + // 决定用callerSceneSession启动 + for (auto sessionInfo : sessionInfoList) { + CheckCallerFromBackground(callerAbilityRecord, sessionInfo); + } + for (auto abilityRequest : abilityRequestList) { + auto requestId = abilityRequest.want.GetStringParam(KEY_REQUEST_ID); + if (!requestId.empty()) { + callerAbilityRecord->NotifyAbilityRequestSuccess(requestId, abilityRequest.want.GetElement()); + } + const_cast(abilityRequest).want.RemoveParam(KEY_REQUEST_ID); + const_cast(abilityRequest).want.RemoveParam(START_ABILITIES_REQUEST_ID); + } + TAG_LOGI(AAFwkTag::ABILITYMGR, "scb call, StartAbilities BatchNotifySCBPendingActivation for callerSession"); + return static_cast(callerSession->PendingSessionActivations(sessionInfoList)); + } + // 使用rootSession启动 callerRecord存在 callerSession不存在 + auto tmpSceneSession = iface_cast(rootSceneSession_); + if (tmpSceneSession == nullptr) { + errMsg = "null tmpSceneSession, scb does not exist"; + TAG_LOGE(AAFwkTag::ABILITYMGR, "%{public}s", errMsg.c_str()); + return ERR_INVALID_VALUE; + } + for (auto sessionInfo : sessionInfoList) { + sessionInfo->canStartAbilityFromBackground = true; + } + for (auto abilityRequest : abilityRequestList) { + const_cast(abilityRequest).want.RemoveParam(START_ABILITIES_REQUEST_ID); + } + TAG_LOGI(AAFwkTag::ABILITYMGR, "scb call, StartAbilities NotifySCBPendingActivation for rootSceneSession"); + return static_cast(tmpSceneSession->PendingSessionActivations(sessionInfoList)); +} + +int32_t UIAbilityLifecycleManager::StartAbilitiesAddSessionInfo( + sptr &sessionInfo, int32_t requestId, int32_t requestListId) +{ + std::lock_guard guard(startAbilitiesProcessLock_); + // 若找不到requestListId对应的AbilitiesRequest,说明该AbilitiesRequest已失败返回 + if (abilitiesRequestMap_.find(requestListId) == abilitiesRequestMap_.end()) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "requestListId: %{public}d not found", requestListId); + return START_ABILITIES_REQUEST_DONE; + } + CHECK_POINTER_AND_RETURN_LOG(abilitiesRequestMap_[requestListId], ERR_INVALID_VALUE, + "abilitiesRequest nullptr"); + // 将处理完毕的sessionInfo添加到准备完成列表中,清除waiting list元素 + abilitiesRequestMap_[requestListId]->UnsortedSessionInfoList.emplace_back(sessionInfo); + auto waitingRequestIdList = abilitiesRequestMap_[requestListId]->waitingRequestIdList; + for (auto iter = waitingRequestIdList.begin(); iter != waitingRequestIdList.end(); iter++) { + if (*iter == requestId) { + waitingRequestIdList.erase(iter); + break; + } + } + return ERR_OK; +} + +// 相关的报错、成功分支都需要记录错误、返回处理promise并清除AbilitiesRequest +int32_t UIAbilityLifecycleManager::HandleAbilitiesRequestDone(int32_t requestId, int32_t requestListId, + int32_t resultCode) +{ + if (requestListId == REQUEST_LIST_ID_INIT) { + return ERR_OK; + } + std::lock_guard guard(startAbilitiesProcessLock_); + if (abilitiesRequestMap_.find(requestListId) == abilitiesRequestMap_.end()) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "requestListId: %{public}d not found", requestListId); + return START_ABILITIES_REQUEST_DONE; + } + CHECK_POINTER_AND_RETURN_LOG(abilitiesRequestMap_[requestListId], ERR_INVALID_VALUE, + "abilitiesRequest nullptr"); + auto abilitiesRequest = abilitiesRequestMap_[requestListId] + auto abilityRequestList = abilitiesRequest->abilityRequestList; + auto UnsortedSessionInfoList = abilitiesRequest->UnsortedSessionInfoList; + if (resultCode != ERR_OK) { + // 返回失败通知 + NotifyAbilitiesRequestDone(abilityRequestList[0], resultCode); + abilitiesRequestMap_.erase(requestListId); + return START_ABILITIES_REQUEST_DONE; + } + // 准备完成 + if (abilityRequestList.size() == UnsortedSessionInfoList.size()) { + // 启动pendingSCB + int32_t ret = BatchNotifySCBPendingActivation(); + // 返回pendingSCB结果 + NotifyAbilitiesRequestDone(abilityRequestList[0], ret); + abilitiesRequestMap_.erase(requestListId); + return START_ABILITIES_REQUEST_DONE; + } + // 本次abilityRequest没有提前失败,但是整体abilitiesRequest没有完成 + return ERR_OK; +} + +int32_t UIAbilityLifecycleManager::NotifyAbilitiesRequestDone(const AbilityRequest &abilityRequest, + const int32_t resultCode) +{ + // 走abilityScheduler,callerAbility不存在,原有context和promise也不存在,不通知 + sptr callerToken = abilityRequest.callerToken; + CHECK_POINTER_AND_RETURN_LOG(callerToken, ERR_INVALID_VALUE, "callerToken nullptr"); + std::string startTime = abilityRequest.want.GetStringParam(Want::PARAM_RESV_START_TIME); + + std::shared_ptr callerAbilityRecord; + callerAbilityRecord = GetAbilityRecordByToken(callerToken); + if (callerAbilityRecord == nullptr || callerAbilityRecord->GetRestartAppFlag()) + { + TAG_LOGE(AAFwkTag::ABILITYMGR, "callerAbilityRecord not exist."); + return ERR_INVALID_VALUE + } + callerAbilityRecord.NotifyAbilitiesRequestDone(startTime, resultCode); + return ERR_OK; +} + int32_t UIAbilityLifecycleManager::NotifySCBToRecoveryAfterInterception(const AbilityRequest &abilityRequest) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); @@ -2094,13 +2360,17 @@ void UIAbilityLifecycleManager::OnAcceptWantResponse(const AAFwk::Want &want, co } } - HandleLegacyAcceptWantDone(request->abilityRequest, requestId, flag, want); + int32_t ret = HandleLegacyAcceptWantDone(request, flag, want); + // 相关的报错、成功分支都需要记录错误、返回处理promise并清除AbilitiesRequest + HandleAbilitiesRequestDone(requestId, request->requestListId, ret); } -void UIAbilityLifecycleManager::HandleLegacyAcceptWantDone(AbilityRequest &abilityRequest, int32_t requestId, - const std::string &flag, const AAFwk::Want &want) +int32_t UIAbilityLifecycleManager::HandleLegacyAcceptWantDone( + std::shared_ptr specifiedRequest, const std::string &flag, const AAFwk::Want &want) { TAG_LOGI(AAFwkTag::ABILITYMGR, "%{public}s", want.GetElement().GetURI().c_str()); + auto abilityRequest = specifiedRequest->abilityRequest; + int32_t requestListId = specifiedRequest->requestListId auto callerAbility = GetAbilityRecordByToken(abilityRequest.callerToken); abilityRequest.specifiedFlag = flag; if (!flag.empty()) { @@ -2111,7 +2381,7 @@ void UIAbilityLifecycleManager::HandleLegacyAcceptWantDone(AbilityRequest &abili auto iter = sessionAbilityMap_.find(persistentId); if (iter == sessionAbilityMap_.end()) { TAG_LOGE(AAFwkTag::ABILITYMGR, "OnAcceptWantResponse Unexpected Error"); - return; + return START_ABILITIES_SESSION_ABILITY_NOT_FOUND; } TAG_LOGI(AAFwkTag::ABILITYMGR, "find specified ability, session:%{public}d", persistentId); abilityRecord = iter->second; @@ -2119,13 +2389,13 @@ void UIAbilityLifecycleManager::HandleLegacyAcceptWantDone(AbilityRequest &abili abilityRecord->SetWant(abilityRequest.want); abilityRecord->SetIsNewWant(true); UpdateAbilityRecordLaunchReason(abilityRequest, abilityRecord); - MoveAbilityToFront(abilityRequest, abilityRecord, callerAbility, nullptr, requestId); + MoveAbilityToFront(specifiedRequest, abilityRecord, callerAbility, nullptr); NotifyRestartSpecifiedAbility(abilityRequest, abilityRecord->GetToken()); - return; + return ERR_OK; } } NotifyStartSpecifiedAbility(abilityRequest, want); - StartAbilityBySpecifed(abilityRequest, callerAbility, requestId); + return StartAbilityBySpecifed(abilityRequest, callerAbility, requestId, requestListId); } void UIAbilityLifecycleManager::OnStartSpecifiedAbilityTimeoutResponse(int32_t requestId) @@ -2198,6 +2468,13 @@ void UIAbilityLifecycleManager::OnStartSpecifiedProcessResponse(const std::strin (abilityRequest.abilityInfo.applicationInfo.bundleType == AppExecFwk::BundleType::ATOMIC_SERVICE); TAG_LOGI(AAFwkTag::ABILITYMGR, "reused sessionId: %{public}d, userId: %{public}d", sessionInfo->persistentId, abilityRequest.userId); + int32_t requestListId = request->requestListId; + if (requestListId != REQUEST_LIST_ID_INIT) { + int32_t ret = StartAbilitiesAddSessionInfo(sessionInfo, requestId, requestListId); + // 相关的报错、成功分支都需要记录错误、返回处理promise并清除AbilitiesRequest + HandleAbilitiesRequestDone(requestId, requestListId, ret); + return; + } std::string errMsg; NotifySCBPendingActivation(sessionInfo, abilityRequest, errMsg); } @@ -2218,6 +2495,11 @@ void UIAbilityLifecycleManager::OnStartSpecifiedProcessTimeoutResponse(int32_t r if (nextRequest) { StartSpecifiedRequest(*nextRequest); } + int32_t requestListId = request->requestListId; + // 相关的报错、成功分支都需要记录错误、返回处理promise并清除AbilitiesRequest + // 新增 错误码 启动specified进程超时失败 方法内处理requestListId == -1 + HandleAbilitiesRequestDone(requestId, requestListId, START_ABILITIES_SPECIFIED_PROCESS_TIMEOUT_ERR); + } bool UIAbilityLifecycleManager::IsStartSpecifiedProcessRequest(const AbilityRequest &abilityRequest) @@ -2246,7 +2528,7 @@ bool UIAbilityLifecycleManager::IsStartSpecifiedProcessRequest(const AbilityRequ return true; } -int32_t UIAbilityLifecycleManager::StartSpecifiedProcessRequest(const AbilityRequest &abilityRequest) +int32_t UIAbilityLifecycleManager::StartSpecifiedProcessRequest(const AbilityRequest &abilityRequest, int32_t requestListId) { auto isCreating = abilityRequest.want.GetBoolParam(Want::CREATE_APP_INSTANCE_KEY, false); const auto &abilityInfo = abilityRequest.abilityInfo; @@ -2262,9 +2544,11 @@ int32_t UIAbilityLifecycleManager::StartSpecifiedProcessRequest(const AbilityReq const_cast(abilityRequest).want.SetParam(Want::APP_INSTANCE_KEY, instanceKey); } auto requestId = GetRequestId(); - TAG_LOGI(AAFwkTag::ABILITYMGR, "StartSpecifiedProcess, requestId:%{public}d", requestId); + TAG_LOGI(AAFwkTag::ABILITYMGR, "StartSpecifiedProcess, requestId:%{public}d, requestListId:%{public}d", + requestId, requestListId); auto specifiedRequest = std::make_shared(requestId, abilityRequest); specifiedRequest->specifiedProcessState = SpecifiedProcessState::STATE_PROCESS; + specifiedRequest->requestListId = requestListId; AddSpecifiedRequest(specifiedRequest); return ERR_OK; } @@ -2324,14 +2608,17 @@ void UIAbilityLifecycleManager::NotifyStartSpecifiedAbility(AbilityRequest &abil } } -int UIAbilityLifecycleManager::MoveAbilityToFront(const AbilityRequest &abilityRequest, +int32_t UIAbilityLifecycleManager::MoveAbilityToFront(std::shared_ptr specifiedRequest, const std::shared_ptr &abilityRecord, std::shared_ptr callerAbility, - std::shared_ptr startOptions, int32_t requestId) + std::shared_ptr startOptions) { if (!abilityRecord) { TAG_LOGE(AAFwkTag::ABILITYMGR, "ability record failed"); return ERR_INVALID_VALUE; } + auto abilityRequest = specifiedRequest->abilityRequest; + int32_t requestId = specifiedRequest->requestId; + int32_t requestListId = specifiedRequest->requestListId; sptr sessionInfo = abilityRecord->GetSessionInfo(); CHECK_POINTER_AND_RETURN(sessionInfo, ERR_INVALID_VALUE); sessionInfo->want = abilityRequest.want; @@ -2348,6 +2635,13 @@ int UIAbilityLifecycleManager::MoveAbilityToFront(const AbilityRequest &abilityR sessionInfo->specifiedFlag = abilityRequest.specifiedFlag; TAG_LOGI(AAFwkTag::ABILITYMGR, "MoveAbilityToFront: %{public}d-%{public}s", requestId, abilityRequest.specifiedFlag.c_str()); + if (requestListId != REQUEST_LIST_ID_INIT) { + int32_t ret = StartAbilitiesAddSessionInfo(sessionInfo, requestId, requestListId); + // 原来好像是在pendingActivation之后 + abilityRecord->RemoveWindowMode(); + return ret; + } + // 热启都是下方与SCB通信方式 与pendingActivation有差异 SendSessionInfoToSCB(callerAbility, sessionInfo); abilityRecord->RemoveWindowMode(); if (startOptions != nullptr) { @@ -2403,7 +2697,7 @@ int UIAbilityLifecycleManager::SendSessionInfoToSCB(std::shared_ptr &callerAbility, int32_t requestId) + std::shared_ptr &callerAbility, int32_t requestId, int32_t requestListId) { TAG_LOGD(AAFwkTag::ABILITYMGR, "call"); sptr sessionInfo = new SessionInfo(); @@ -2417,6 +2711,9 @@ int UIAbilityLifecycleManager::StartAbilityBySpecifed(const AbilityRequest &abil sessionInfo->requestId = requestId; sessionInfo->specifiedFlag = abilityRequest.specifiedFlag; TAG_LOGI(AAFwkTag::ABILITYMGR, "specified flag:%{public}s", abilityRequest.specifiedFlag.c_str()); + if (requestListId != REQUEST_LIST_ID_INIT) { + return ret = StartAbilitiesAddSessionInfo(sessionInfo, requestId, requestListId); + } SendSessionInfoToSCB(callerAbility, sessionInfo); return ERR_OK; } @@ -3552,6 +3849,18 @@ void UIAbilityLifecycleManager::AddSpecifiedRequest(std::shared_ptrrequestListId; + if (requestListId != REQUEST_LIST_ID_INIT) + { + // 在对应的startAbilities request中标记对应SpecifiedRequest的Id + std::lock_guard guard(startAbilitiesProcessLock_); + auto &abilitiesRequest = abilitiesRequestMap_[requestListId]; + abilitiesRequest.waitingRequestIdList.emplace_back(request->requestId); + TAG_LOGI(AAFwkTag::ABILITYMGR, + "Add waitingRequestIdList: requestListId %{public}d, requestId %{public}s", + requestListId, request->requestId); + } list.push_back(request); if (list.size() == 1) { StartSpecifiedRequest(*request); @@ -3605,8 +3914,17 @@ void UIAbilityLifecycleManager::StartSpecifiedRequest(SpecifiedRequest &specifie sessionInfo->requestId = specifiedRequest.requestId; sessionInfo->isFromIcon = request.isFromIcon; TAG_LOGI(AAFwkTag::ABILITYMGR, "StartSpecifiedRequest cold"); + int32_t requestListId = specifiedRequest->requestListId; + int32_t requestId = specifiedRequest.requestId; + if (requestListId != REQUEST_LIST_ID_INIT) { + int32_t ret = StartAbilitiesAddSessionInfo(sessionInfo, requestId, requestListId); + // 相关的报错、成功分支都需要记录错误、返回处理promise并清除AbilitiesRequest + HandleAbilitiesRequestDone(requestId, requestListId, ret); + return; + } std::string errMsg; NotifySCBPendingActivation(sessionInfo, request, errMsg); + // 这是做什么的,有些有,有些没有 sessionInfo->want.RemoveAllFd(); return; } -- Gitee