diff --git a/frameworks/js/napi/ability_context/ability_context.js b/frameworks/js/napi/ability_context/ability_context.js index 7a83688596910558e9c32ff030f1277b7b1e26ea..6dd3fcfea7d03d7cc8c7da3d301e06ad015abedf 100644 --- a/frameworks/js/napi/ability_context/ability_context.js +++ b/frameworks/js/napi/ability_context/ability_context.js @@ -173,6 +173,10 @@ class AbilityContext extends Context { return this.__context_impl__.terminateSelfWithResult(abilityResult, callback); } + backToCallerAbilityWithResult(abilityResult, requestCode, callback) { + return this.__context_impl__.backToCallerAbilityWithResult(abilityResult, requestCode, callback); + } + restoreWindowStage(contentStorage) { return this.__context_impl__.restoreWindowStage(contentStorage); } diff --git a/frameworks/js/napi/wantConstant/want_constant.cpp b/frameworks/js/napi/wantConstant/want_constant.cpp index 73d838c0b0afb9b8cf1f332ec53be35541e14958..d568ca160775ff2505336a2db25cd969ad86ac41 100644 --- a/frameworks/js/napi/wantConstant/want_constant.cpp +++ b/frameworks/js/napi/wantConstant/want_constant.cpp @@ -120,6 +120,7 @@ napi_value WantConstantInit(napi_env env, napi_value exports) SetNamedProperty(env, params, "ohos.param.atomicservice.pageSourceFile", "PAGE_SOURCE_FILE"); SetNamedProperty(env, params, "ohos.param.atomicservice.buildFunction", "BUILD_FUNCTION"); SetNamedProperty(env, params, "ohos.param.atomicservice.subpackageName", "SUB_PACKAGE_NAME"); + SetNamedProperty(env, params, "ohos.extra.param.key.callerRequestCode", "CALLER_REQUEST_CODE"); napi_property_descriptor exportFuncs[] = { DECLARE_NAPI_PROPERTY("Action", action), DECLARE_NAPI_PROPERTY("Entity", entity), diff --git a/frameworks/native/ability/ability_runtime/ability_context_impl.cpp b/frameworks/native/ability/ability_runtime/ability_context_impl.cpp index 4bb4134cc2793a81bdbb043465d3ed9709acd7fd..a4e107f49b3c0a3d08a969e76d1c75454accd77f 100644 --- a/frameworks/native/ability/ability_runtime/ability_context_impl.cpp +++ b/frameworks/native/ability/ability_runtime/ability_context_impl.cpp @@ -338,6 +338,14 @@ ErrCode AbilityContextImpl::TerminateAbilityWithResult(const AAFwk::Want& want, #endif } +ErrCode AbilityContextImpl::BackToCallerAbilityWithResult(const AAFwk::Want& want, int resultCode, int64_t requestCode) +{ + ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->BackToCallerAbilityWithResult( + token_, resultCode, &want, requestCode); + TAG_LOGI(AAFwkTag::CONTEXT, "ret is %{public}d", err); + return static_cast(err); +} + void AbilityContextImpl::SetWeakSessionToken(const wptr& sessionToken) { std::lock_guard lock(sessionTokenMutex_); diff --git a/frameworks/native/ability/native/ability_business_error/ability_business_error.cpp b/frameworks/native/ability/native/ability_business_error/ability_business_error.cpp index b25cdd878388dd29f4bf932240a3f47edf8b7bc7..980e7a08173098f05564a68e30a94fb89a826124 100644 --- a/frameworks/native/ability/native/ability_business_error/ability_business_error.cpp +++ b/frameworks/native/ability/native/ability_business_error/ability_business_error.cpp @@ -81,6 +81,10 @@ constexpr const char* ERROR_MSG_MULTI_APP_NOT_SUPPORTED = "App clone or multi-in constexpr const char* ERROR_MSG_NOT_APP_CLONE = "The target app is not Clone."; constexpr const char* ERROR_MSG_APP_CLONE_INDEX_INVALID = "The target app clone with the specified index does not exist."; +constexpr const char* ERROR_MSG_CALLER_NOT_EXIST = + "The caller application does not exist."; +constexpr const char* ERROR_MSG_NOT_SUPPROT_BACK_TO_CALLER = + "Current application does not support back to caller application."; constexpr const char* ERROR_MSG_EXTENSION_START_THIRD_PARTY_APP_CONTROLLED = "The extension can not start the specified third party application."; constexpr const char* ERROR_MSG_EXTENSION_START_SERVICE_CONTROLLED = "The extension can not start the service."; @@ -140,6 +144,8 @@ static std::unordered_map ERR_CODE_MAP = { { AbilityErrorCode::ERROR_CODE_MULTI_APP_NOT_SUPPORTED, ERROR_MSG_MULTI_APP_NOT_SUPPORTED }, { AbilityErrorCode::ERROR_NOT_APP_CLONE, ERROR_MSG_NOT_APP_CLONE }, { AbilityErrorCode::ERROR_APP_CLONE_INDEX_INVALID, ERROR_MSG_APP_CLONE_INDEX_INVALID }, + { AbilityErrorCode::ERROR_CODE_CALLER_NOT_EXIST, ERROR_MSG_CALLER_NOT_EXIST }, + { AbilityErrorCode::ERROR_CODE_NOT_SUPPROT_BACK_TO_CALLER, ERROR_MSG_NOT_SUPPROT_BACK_TO_CALLER }, { AbilityErrorCode::ERROR_CODE_EXTENSION_START_THIRD_PARTY_APP_CONTROLLED, ERROR_MSG_EXTENSION_START_THIRD_PARTY_APP_CONTROLLED }, { AbilityErrorCode::ERROR_CODE_EXTENSION_START_SERVICE_CONTROLLED, ERROR_MSG_EXTENSION_START_SERVICE_CONTROLLED}, @@ -202,6 +208,8 @@ static std::unordered_map INNER_TO_JS_ERROR_CODE_MAP {ERR_NO_RESIDENT_PERMISSION, AbilityErrorCode::ERROR_CODE_NO_RESIDENT_PERMISSION}, {ERR_MULTI_APP_NOT_SUPPORTED, AbilityErrorCode::ERROR_CODE_MULTI_APP_NOT_SUPPORTED}, {ERR_APP_CLONE_INDEX_INVALID, AbilityErrorCode::ERROR_APP_CLONE_INDEX_INVALID}, + {ERR_CALLER_NOT_EXISTS, AbilityErrorCode::ERROR_CODE_CALLER_NOT_EXIST}, + {ERR_NOT_SUPPORT_BACK_TO_CALLER, AbilityErrorCode::ERROR_CODE_NOT_SUPPROT_BACK_TO_CALLER}, {EXTENSION_BLOCKED_BY_THIRD_PARTY_APP_FLAG, AbilityErrorCode::ERROR_CODE_EXTENSION_START_THIRD_PARTY_APP_CONTROLLED}, {EXTENSION_BLOCKED_BY_SERVICE_LIST, AbilityErrorCode::ERROR_CODE_EXTENSION_START_SERVICE_CONTROLLED}, diff --git a/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp b/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp index 7cd896af47efa070f5d54220d4361ad1d3269d18..5a0872c79871df9c0d01cc583e5efb97ef43bbad 100644 --- a/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "ability_manager_client.h" #include "ability_manager_errors.h" @@ -305,6 +306,11 @@ napi_value JsAbilityContext::TerminateSelfWithResult(napi_env env, napi_callback GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnTerminateSelfWithResult); } +napi_value JsAbilityContext::BackToCallerAbilityWithResult(napi_env env, napi_callback_info info) +{ + GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnBackToCallerAbilityWithResult); +} + napi_value JsAbilityContext::RestoreWindowStage(napi_env env, napi_callback_info info) { GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnRestoreWindowStage); @@ -705,8 +711,7 @@ bool JsAbilityContext::CreateOpenLinkTask(const napi_env &env, const napi_value isInner ? asyncTask->Reject(env, CreateJsErrorByNativeErr(env, resultCode)) : asyncTask->ResolveWithNoError(env, abilityResult); }; - curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1); - requestCode = curRequestCode_; + requestCode = GenerateRequestCode(); auto context = context_.lock(); if (!context) { TAG_LOGW(AAFwkTag::CONTEXT, "context is released"); @@ -1118,9 +1123,9 @@ napi_value JsAbilityContext::OnStartAbilityForResult(napi_env env, NapiCallbackI asyncTask->Reject(env, CreateJsError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT)); } else { want.SetParam(Want::PARAM_RESV_FOR_RESULT, true); - curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1); - (unwrapArgc == ARGC_ONE) ? context->StartAbilityForResult(want, curRequestCode_, std::move(task)) : - context->StartAbilityForResult(want, startOptions, curRequestCode_, std::move(task)); + auto requestCode = GenerateRequestCode(); + (unwrapArgc == ARGC_ONE) ? context->StartAbilityForResult(want, requestCode, std::move(task)) : + context->StartAbilityForResult(want, startOptions, requestCode, std::move(task)); } TAG_LOGD(AAFwkTag::CONTEXT, "OnStartAbilityForResult is called end"); return result; @@ -1203,10 +1208,10 @@ napi_value JsAbilityContext::OnStartAbilityForResultWithAccount(napi_env env, Na TAG_LOGW(AAFwkTag::CONTEXT, "context is released"); asyncTask->Reject(env, CreateJsError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT)); } else { - curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1); + auto requestCode = GenerateRequestCode(); (unwrapArgc == INDEX_TWO) ? context->StartAbilityForResultWithAccount( - want, accountId, curRequestCode_, std::move(task)) : context->StartAbilityForResultWithAccount( - want, accountId, startOptions, curRequestCode_, std::move(task)); + want, accountId, requestCode, std::move(task)) : context->StartAbilityForResultWithAccount( + want, accountId, startOptions, requestCode, std::move(task)); } TAG_LOGD(AAFwkTag::CONTEXT, "OnStartAbilityForResultWithAccount is called end"); return result; @@ -1418,6 +1423,57 @@ napi_value JsAbilityContext::OnTerminateSelfWithResult(napi_env env, NapiCallbac return result; } +napi_value JsAbilityContext::OnBackToCallerAbilityWithResult(napi_env env, NapiCallbackInfo& info) +{ + TAG_LOGI(AAFwkTag::CONTEXT, "OnBackToCallerAbilityWithResult start"); + if (info.argc < ARGC_TWO) { + TAG_LOGE(AAFwkTag::CONTEXT, "Not enough params"); + ThrowTooFewParametersError(env); + return CreateJsUndefined(env); + } + + int resultCode = 0; + AAFwk::Want want; + if (!AppExecFwk::UnWrapAbilityResult(env, info.argv[INDEX_ZERO], resultCode, want)) { + TAG_LOGE(AAFwkTag::CONTEXT, "%s Failed to parse ability result!", __func__); + ThrowInvalidParamError(env, "Parse param want failed, want must be Want."); + return CreateJsUndefined(env); + } + + int64_t requestCode = -1; + if (!OHOS::AppExecFwk::UnwrapInt64FromJS2(env, info.argv[INDEX_ONE], requestCode)) { + TAG_LOGE(AAFwkTag::CONTEXT, "the second parameter is invalid."); + ThrowInvalidParamError(env, "Parse param requestCode failed, requestCode must be number."); + return CreateJsUndefined(env); + } + + NapiAsyncTask::CompleteCallback complete = + [weak = context_, want, resultCode, requestCode](napi_env env, NapiAsyncTask& task, int32_t status) { + TAG_LOGI(AAFwkTag::CONTEXT, "TerminateSelfWithResult async"); + auto context = weak.lock(); + if (!context) { + TAG_LOGW(AAFwkTag::CONTEXT, "context is released"); + task.Reject(env, CreateJsError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT)); + return; + } + + auto errorCode = context->BackToCallerAbilityWithResult(want, resultCode, requestCode); + if (errorCode == 0) { + task.Resolve(env, CreateJsUndefined(env)); + } else { + task.Reject(env, CreateJsErrorByNativeErr(env, errorCode)); + } + }; + + napi_value lastParam = (info.argc > ARGC_TWO) ? info.argv[ARGC_TWO] : nullptr; + napi_value result = nullptr; + NapiAsyncTask::ScheduleHighQos("JsAbilityContext::OnBackToCallerAbilityWithResult", + env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result)); + TAG_LOGD(AAFwkTag::CONTEXT, "OnBackToCallerAbilityWithResult end"); + return result; +} + + napi_value JsAbilityContext::OnConnectAbility(napi_env env, NapiCallbackInfo& info) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); @@ -1850,6 +1906,8 @@ napi_value CreateJsAbilityContext(napi_env env, std::shared_ptr BindNativeFunction(env, object, "terminateSelf", moduleName, JsAbilityContext::TerminateSelf); BindNativeFunction(env, object, "terminateSelfWithResult", moduleName, JsAbilityContext::TerminateSelfWithResult); + BindNativeFunction(env, object, "backToCallerAbilityWithResult", moduleName, + JsAbilityContext::BackToCallerAbilityWithResult); BindNativeFunction(env, object, "restoreWindowStage", moduleName, JsAbilityContext::RestoreWindowStage); BindNativeFunction(env, object, "isTerminating", moduleName, JsAbilityContext::IsTerminating); BindNativeFunction(env, object, "startRecentAbility", moduleName, @@ -2484,8 +2542,8 @@ napi_value JsAbilityContext::OpenAtomicServiceInner(napi_env env, NapiCallbackIn return CreateJsUndefined(env); } else { want.SetParam(Want::PARAM_RESV_FOR_RESULT, true); - curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1); - context->OpenAtomicService(want, options, curRequestCode_, std::move(task)); + auto requestCode = GenerateRequestCode(); + context->OpenAtomicService(want, options, requestCode, std::move(task)); } TAG_LOGD(AAFwkTag::CONTEXT, "OnOpenAtomicService is called end"); return result; @@ -2547,5 +2605,15 @@ napi_value JsAbilityContext::OnSetRestoreEnabled(napi_env env, NapiCallbackInfo& abilityContext->SetRestoreEnabled(enabled); return CreateJsUndefined(env); } + +int32_t JsAbilityContext::GenerateRequestCode() +{ + std::lock_guard lock(requestCodeMutex_); + curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1); + return curRequestCode_; +} + +int32_t JsAbilityContext::curRequestCode_ = 0; +std::mutex JsAbilityContext::requestCodeMutex_; } // namespace AbilityRuntime } // namespace OHOS 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 98c1e1f4d7bb5489a9dd86e76f0057510a62caac..331f30762885e1d6d0de82cfeab1f7a3a7ea73a3 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_client.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_client.h @@ -372,6 +372,18 @@ public: */ ErrCode TerminateAbility(sptr token, int resultCode, const Want *resultWant); + /** + * BackToCallerAbilityWithResult, return to the caller ability. + * + * @param token, the token of the ability to terminate. + * @param resultCode, the resultCode of the ability to terminate. + * @param resultWant, the Want of the ability to return. + * @param callerRequestCode, the requestCode of caller ability. + * @return Returns ERR_OK on success, others on failure. + */ + ErrCode BackToCallerAbilityWithResult(const sptr &token, int resultCode, + const Want *resultWant, int64_t callerRequestCode); + /** * TerminateUIExtensionAbility with want, return want from 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 f0b30cfa01725a8a7a2baa87db70f8e2d17391c6..4af76e0510c9556c07f7c40b411a2e42887f4475 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_errors.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_errors.h @@ -559,6 +559,16 @@ enum { * Result (2097260) for target free install task does not exist. */ ERR_FREE_INSTALL_TASK_NOT_EXIST = 2097260, + + /* + * Result (2097261) caller not exists. + */ + ERR_CALLER_NOT_EXISTS = 2097261, + + /* + * Result (2097262) Not support back to caller. + */ + ERR_NOT_SUPPORT_BACK_TO_CALLER = 2097262, /** * Native error(3000000) for target bundle not exist. 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 26dd88187137e1e6749835ab04d81496fd129978..b5b5122d233c9122aeceb9bc3f3142f847fd6c89 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h @@ -439,6 +439,21 @@ public: */ virtual int TerminateAbility( const sptr &token, int resultCode, const Want *resultWant = nullptr) = 0; + + /** + * BackToCallerAbilityWithResult, return to the caller ability. + * + * @param token, the token of the ability to terminate. + * @param resultCode, the resultCode of the ability to terminate. + * @param resultWant, the Want of the ability to return. + * @param callerRequestCode, the requestCode of caller ability.ยท + * @return Returns ERR_OK on success, others on failure. + */ + virtual int BackToCallerAbilityWithResult(const sptr &token, int resultCode, + const Want *resultWant, int64_t callerRequestCode) + { + return 0; + }; /** * TerminateUIExtensionAbility, terminate the special ui extension ability. 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 ef14947d345f2b39fe144cade1be423095902932..626a4c000f23822b3cc19e741d1e789f0697ecf1 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 @@ -247,6 +247,9 @@ enum class AbilityManagerInterfaceCode { // ipc id for ability window config transition done (81) ABILITY_WINDOW_CONFIG_TRANSITION_DONE = 81, + // Back to caller. + BACK_TO_CALLER_UIABILITY = 82, + // ipc id 1001-2000 for DMS // ipc id for starting ability (1001) START_ABILITY = 1001, diff --git a/interfaces/kits/native/ability/ability_runtime/ability_context.h b/interfaces/kits/native/ability/ability_runtime/ability_context.h index 0fc555e5bd88fdc9871615ec15012ec23172b26e..bc7e259cd94278794e3b63883c5105490594b745 100644 --- a/interfaces/kits/native/ability/ability_runtime/ability_context.h +++ b/interfaces/kits/native/ability/ability_runtime/ability_context.h @@ -165,6 +165,8 @@ public: virtual ErrCode TerminateAbilityWithResult(const AAFwk::Want &want, int resultCode) = 0; + virtual ErrCode BackToCallerAbilityWithResult(const AAFwk::Want &want, int resultCode, int64_t requestCode) = 0; + virtual ErrCode RestoreWindowStage(napi_env env, napi_value contentStorage) = 0; virtual void OnAbilityResult(int requestCode, int resultCode, const AAFwk::Want &resultData) = 0; diff --git a/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h b/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h index 9d4c07c387f2b6b2d6b07ec412f32bd5c4f2a066..aec1d82749426ad070fba2776677159b725d627e 100644 --- a/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h +++ b/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h @@ -80,6 +80,7 @@ public: ErrCode StartServiceExtensionAbility(const Want &want, int32_t accountId = -1) override; ErrCode StopServiceExtensionAbility(const Want& want, int32_t accountId = -1) override; ErrCode TerminateAbilityWithResult(const AAFwk::Want &want, int resultCode) override; + ErrCode BackToCallerAbilityWithResult(const AAFwk::Want &want, int resultCode, int64_t requestCode) override; void OnAbilityResult(int requestCode, int resultCode, const AAFwk::Want &resultData) override; ErrCode ConnectAbility(const AAFwk::Want &want, const sptr &connectCallback) override; diff --git a/interfaces/kits/native/ability/native/ability_business_error/ability_business_error.h b/interfaces/kits/native/ability/native/ability_business_error/ability_business_error.h index c26ead497315e4ab56acd9a798b2c91d32054591..1afe0885c00b02a0e0c15b2e771500028fb319f3 100644 --- a/interfaces/kits/native/ability/native/ability_business_error/ability_business_error.h +++ b/interfaces/kits/native/ability/native/ability_business_error/ability_business_error.h @@ -156,6 +156,12 @@ enum class AbilityErrorCode { // app clone index does not exist. ERROR_APP_CLONE_INDEX_INVALID = 16000073, + // Caller does not exists. + ERROR_CODE_CALLER_NOT_EXIST = 16000074, + + // Not support back to caller. + ERROR_CODE_NOT_SUPPROT_BACK_TO_CALLER = 16000075, + // invalid caller. ERROR_CODE_INVALID_CALLER = 16200001, diff --git a/interfaces/kits/native/ability/native/ability_runtime/js_ability_context.h b/interfaces/kits/native/ability/native/ability_runtime/js_ability_context.h index f084b2336675fa4f4a01d6f87f3f08fd89246d2e..9c604db0f4b23a803329b84f11061f47f1567ab9 100644 --- a/interfaces/kits/native/ability/native/ability_runtime/js_ability_context.h +++ b/interfaces/kits/native/ability/native/ability_runtime/js_ability_context.h @@ -57,6 +57,7 @@ public: static napi_value DisconnectAbility(napi_env env, napi_callback_info info); static napi_value TerminateSelf(napi_env env, napi_callback_info info); static napi_value TerminateSelfWithResult(napi_env env, napi_callback_info info); + static napi_value BackToCallerAbilityWithResult(napi_env env, napi_callback_info info); static napi_value RestoreWindowStage(napi_env env, napi_callback_info info); static napi_value RequestDialogService(napi_env env, napi_callback_info info); static napi_value IsTerminating(napi_env env, napi_callback_info info); @@ -108,6 +109,7 @@ private: napi_value OnStopExtensionAbility(napi_env env, NapiCallbackInfo& info); napi_value OnStopExtensionAbilityWithAccount(napi_env env, NapiCallbackInfo& info); napi_value OnTerminateSelfWithResult(napi_env env, NapiCallbackInfo& info); + napi_value OnBackToCallerAbilityWithResult(napi_env env, NapiCallbackInfo& info); napi_value OnConnectAbility(napi_env env, NapiCallbackInfo& info); napi_value OnConnectAbilityWithAccount(napi_env env, NapiCallbackInfo& info); napi_value OnDisconnectAbility(napi_env env, NapiCallbackInfo& info); @@ -150,9 +152,11 @@ private: bool CheckStartAbilityByCallParams(napi_env env, NapiCallbackInfo& info, AAFwk::Want &want, int32_t &userId, napi_value &lastParam); napi_value SyncSetMissionContinueState(napi_env env, NapiCallbackInfo& info, const AAFwk::ContinueState& state); + static int32_t GenerateRequestCode(); + static int32_t curRequestCode_; + static std::mutex requestCodeMutex_; std::weak_ptr context_; - int curRequestCode_ = 0; sptr freeInstallObserver_ = nullptr; friend class JsEmbeddableUIAbilityContext; }; diff --git a/services/abilitymgr/include/ability_manager_proxy.h b/services/abilitymgr/include/ability_manager_proxy.h index 8db603f525713965edc54478e33129bed05bacce..5f36eb52220cef3ab5a00bc9154e00d8f2b977d1 100644 --- a/services/abilitymgr/include/ability_manager_proxy.h +++ b/services/abilitymgr/include/ability_manager_proxy.h @@ -314,6 +314,18 @@ public: */ virtual int TerminateAbility( const sptr &token, int resultCode, const Want *resultWant = nullptr) override; + + /** + * BackToCallerAbilityWithResult, return to the caller ability. + * + * @param token, the token of the ability to terminate. + * @param resultCode, the resultCode of the ability to terminate. + * @param resultWant, the Want of the ability to return. + * @param callerRequestCode, the requestCode of caller ability. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int BackToCallerAbilityWithResult(const sptr &token, int resultCode, + const Want *resultWant, int64_t callerRequestCode) override; /** * TerminateUIExtensionAbility, terminate the special ui extension ability. diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index 1b5945efb5cf80b29b4268bdaab202b3175852ba..47dd0b165168c7be4874e3f84c11de6551db10ac 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -455,6 +455,18 @@ public: */ virtual int TerminateAbility(const sptr &token, int resultCode = DEFAULT_INVAL_VALUE, const Want *resultWant = nullptr) override; + + /** + * BackToCallerAbilityWithResult, return to the caller ability. + * + * @param token, the token of the ability to terminate. + * @param resultCode, the resultCode of the ability to terminate. + * @param resultWant, the Want of the ability to return. + * @param callerRequestCode, the requestCode of caller ability. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int BackToCallerAbilityWithResult(const sptr &token, int resultCode, + const Want *resultWant, int64_t callerRequestCode) override; /** * TerminateAbility, terminate the special ui extension ability. diff --git a/services/abilitymgr/include/ability_manager_stub.h b/services/abilitymgr/include/ability_manager_stub.h index 0f32fcc62490e81a2becd930baf986e929c31069..1367d34dc6617db50a3c57336469a807d006743b 100644 --- a/services/abilitymgr/include/ability_manager_stub.h +++ b/services/abilitymgr/include/ability_manager_stub.h @@ -69,6 +69,7 @@ public: private: int TerminateAbilityInner(MessageParcel &data, MessageParcel &reply); + int BackToCallerInner(MessageParcel &data, MessageParcel &reply); int TerminateUIExtensionAbilityInner(MessageParcel &data, MessageParcel &reply); int CloseUIAbilityBySCBInner(MessageParcel &data, MessageParcel &reply); int SendResultToAbilityInner(MessageParcel &data, MessageParcel &reply); diff --git a/services/abilitymgr/include/ability_record.h b/services/abilitymgr/include/ability_record.h index eb3d8fcc8d3f9d2a6ad2867ac85fd5bf00b44a37..4d70ae9a1b02663d68cd8feb014814f6b7ea5144 100644 --- a/services/abilitymgr/include/ability_record.h +++ b/services/abilitymgr/include/ability_record.h @@ -192,12 +192,48 @@ public: { return callerInfo_; } + bool IsHistoryRequestCode(int32_t requestCode) + { + for (auto it = requestCodeList_.begin(); it != requestCodeList_.end(); it++) { + if (requestCode == *it) { + return true; + } + } + return false; + } + void RemoveHistoryRequestCode(int32_t requestCode) + { + for (auto it = requestCodeList_.begin(); it != requestCodeList_.end(); it++) { + if (requestCode == *it) { + requestCodeList_.erase(it); + return; + } + } + } + void AddHistoryRequestCode(int32_t requestCode) + { + if (IsHistoryRequestCode(requestCode)) { + return; + } + requestCodeList_.emplace_back(requestCode); + } + + void SetRequestCodeList(std::list requestCodeList) + { + requestCodeList_ = requestCodeList; + } + + std::list GetRequestCodeList() + { + return requestCodeList_; + } private: int requestCode_ = -1; // requestCode of for-result start mode std::weak_ptr caller_; std::shared_ptr saCaller_ = nullptr; std::shared_ptr callerInfo_ = nullptr; + std::list requestCodeList_; }; /** @@ -711,6 +747,12 @@ public: */ void SendResult(bool isSandboxApp, uint32_t tokeId); + /** + * send result object to caller ability thread. + * + */ + void SendResultByBackToCaller(const std::shared_ptr &result); + /** * send result object to caller ability thread for sandbox app file saving. */ @@ -728,6 +770,8 @@ public: */ void SaveResultToCallers(const int resultCode, const Want *resultWant); + std::shared_ptr GetCallerByRequestCode(int32_t requestCode, int32_t pid); + /** * save result to caller ability. * @@ -771,6 +815,8 @@ public: */ bool IsConnectListEmpty(); + void RemoveCallerRequestCode(std::shared_ptr callerAbilityRecord, int32_t requestCode); + /** * add caller record * diff --git a/services/abilitymgr/include/ams_configuration_parameter.h b/services/abilitymgr/include/ams_configuration_parameter.h index 459cc1db003e61dab0cfb41b882714f7212825d6..11d50cef2a4d4d25e23d30a6f30769ec7d6afd72 100644 --- a/services/abilitymgr/include/ams_configuration_parameter.h +++ b/services/abilitymgr/include/ams_configuration_parameter.h @@ -48,6 +48,7 @@ constexpr const char* UIEATENSION = "uiextension"; constexpr const char* UIEATENSION_TYPE = "type"; constexpr const char* UIEATENSION_TYPE_PICKER = "typePicker"; constexpr const char* MULTI_USER_TYPE = "multiUserType"; +constexpr const char* SUPPORT_BACK_TO_CALLER = "supportBackToCaller"; } // namespace AmsConfig enum class SatrtUiMode { STATUSBAR = 1, NAVIGATIONBAR = 2, STARTUIBOTH = 3 }; @@ -114,6 +115,8 @@ public: */ int GetAppStartTimeoutTime() const; + bool IsSupportBackToCaller() const; + /** * set picker json object. */ @@ -148,6 +151,7 @@ private: void UpdateStartUpServiceConfigString(nlohmann::json& Object, const std::string &configName, std::string &value); void UpdatePickerConfigurationString(nlohmann::json& Object, const std::string &configName, std::string &value); void LoadUIExtensionPickerConfig(const std::string &filePath); + int LoadBackToCallerConfig(nlohmann::json& Object); private: bool nonConfigFile_ {false}; @@ -166,6 +170,7 @@ private: nlohmann::json pickerJsonObject_ = nlohmann::json::object(); std::map picker_; int multiUserType_ {0}; + bool supportBackToCaller_ {true}; }; } // namespace AAFwk } // namespace OHOS 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 53b7df5ade87e22dc1945afa3351fa883c73af4b..aca4830569c758bf5f014b8008b9ba551a2841d9 100644 --- a/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h +++ b/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h @@ -139,6 +139,9 @@ public: */ std::shared_ptr GetUIAbilityRecordBySessionInfo(const sptr &sessionInfo); + int BackToCallerAbilityWithResult(sptr currentSessionInfo, + std::shared_ptr abilityRecord); + /** * CloseUIAbility, close the special ability by scb. * diff --git a/services/abilitymgr/include/start_ability_utils.h b/services/abilitymgr/include/start_ability_utils.h index 0ad2487d01bf7cef72b2bfa09dffcc95ebd947cb..52296d7c5e6f5345db87480abb3871cc9fa1c997 100644 --- a/services/abilitymgr/include/start_ability_utils.h +++ b/services/abilitymgr/include/start_ability_utils.h @@ -25,6 +25,13 @@ namespace OHOS { namespace AAFwk { + +struct CallerRequestInfo { + int32_t requestCode; + int32_t pid; + bool backFlag; +}; + struct StartAbilityInfo { static std::shared_ptr CreateStartAbilityInfo(const Want &want, int32_t userId, int32_t appIndex); @@ -54,6 +61,8 @@ struct StartAbilityUtils { AppExecFwk::AbilityInfo &abilityInfo); static int32_t CheckAppProvisionMode(const Want& want, int32_t userId); static std::vector GetCloneAppIndexes(const std::string &bundleName, int32_t userId); + static int64_t GenerateFullRequestCode(int32_t pid, bool backFlag, int32_t requestCode); + static CallerRequestInfo ParseFullRequestCode(int64_t fullRequestCode); static bool IsCallFromAncoShellOrBroker(const sptr &callerToken); diff --git a/services/abilitymgr/resource/ams_service_config.json b/services/abilitymgr/resource/ams_service_config.json index 236f0c5a8b5995df06ec69be0b150f372d8c1242..97d76b9b813131875654eb98544f2ff4434b8a32 100644 --- a/services/abilitymgr/resource/ams_service_config.json +++ b/services/abilitymgr/resource/ams_service_config.json @@ -13,5 +13,6 @@ }, "system_configuration":{ "system_orientation": "vertical" - } + }, + "supportBackToCaller": true } diff --git a/services/abilitymgr/src/ability_manager_client.cpp b/services/abilitymgr/src/ability_manager_client.cpp index c08d3d9f75fc5eaf1e40425ec183fcac9ac07286..8e77d2f3f29e50c195b2fa41f8869e3b608ed24a 100644 --- a/services/abilitymgr/src/ability_manager_client.cpp +++ b/services/abilitymgr/src/ability_manager_client.cpp @@ -379,6 +379,15 @@ ErrCode AbilityManagerClient::TerminateAbility(sptr token, int re return abms->TerminateAbility(token, resultCode, resultWant); } +ErrCode AbilityManagerClient::BackToCallerAbilityWithResult(const sptr &token, int resultCode, + const Want *resultWant, int64_t callerRequestCode) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + auto abms = GetAbilityManager(); + CHECK_POINTER_RETURN_NOT_CONNECTED(abms); + return abms->BackToCallerAbilityWithResult(token, resultCode, resultWant, callerRequestCode); +} + ErrCode AbilityManagerClient::TerminateUIExtensionAbility(sptr extensionSessionInfo, int resultCode, const Want *resultWant) { diff --git a/services/abilitymgr/src/ability_manager_proxy.cpp b/services/abilitymgr/src/ability_manager_proxy.cpp index 6fff4d2071627ae1b3e1a7348c5ba81169ee0571..5f5d3ed4be589d6656fc5cf5575819949afc90bb 100644 --- a/services/abilitymgr/src/ability_manager_proxy.cpp +++ b/services/abilitymgr/src/ability_manager_proxy.cpp @@ -876,6 +876,47 @@ int AbilityManagerProxy::TerminateAbility(const sptr &token, return reply.ReadInt32(); } +int AbilityManagerProxy::BackToCallerAbilityWithResult(const sptr &token, int resultCode, + const Want *resultWant, int64_t callerRequestCode) +{ + int error; + MessageParcel data; + MessageParcel reply; + MessageOption option; + + CHECK_POINTER_AND_RETURN_LOG(token, ERR_INVALID_VALUE, "token is nullptr"); + + if (!WriteInterfaceToken(data)) { + return INNER_ERR; + } + + if (token) { + if (!data.WriteBool(true) || !data.WriteRemoteObject(token)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "flag and token write failed."); + return INNER_ERR; + } + } else { + if (!data.WriteBool(false)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "flag write failed."); + return INNER_ERR; + } + } + if (!data.WriteInt32(resultCode) || !data.WriteParcelable(resultWant)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "data write ability result failed."); + return INNER_ERR; + } + if (!data.WriteInt64(callerRequestCode)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "data write requestCode failed."); + return INNER_ERR; + } + error = SendRequest(AbilityManagerInterfaceCode::BACK_TO_CALLER_UIABILITY, data, reply, option); + if (error != NO_ERROR) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Send request error: %{public}d", error); + return error; + } + return reply.ReadInt32(); +} + int AbilityManagerProxy::TerminateUIExtensionAbility(const sptr &extensionSessionInfo, int resultCode, const Want *resultWant) { diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index 7c2464421192ee3768e48f00c538133294bfb9c8..83c09eb892322c74ee68a2ad16e85efb1855f353 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -214,6 +214,7 @@ constexpr const char* SUPPORT_CLOSE_ON_BLUR = "supportCloseOnBlur"; constexpr const char* ATOMIC_SERVICE_PREFIX = "com.atomicservice."; constexpr const char* PARAM_SPECIFIED_PROCESS_FLAG = "ohosSpecifiedProcessFlag"; constexpr const char* VERIFY_DOMINATE_SCREEN = "persist.sys.abilityms.verify_start_ability_without_caller_token"; +constexpr const char* CALLER_REQUEST_CODE = "ohos.extra.param.key.callerRequestCode"; constexpr char ASSERT_FAULT_DETAIL[] = "assertFaultDialogDetail"; constexpr char PRODUCT_ASSERT_FAULT_DIALOG_ENABLED[] = "persisit.sys.abilityms.support_assert_fault_dialog"; @@ -1055,6 +1056,18 @@ int AbilityManagerService::StartAbilityInner(const Want &want, const sptr(want).RemoveParam(CALLER_REQUEST_CODE); + } + auto callerAbilityRecord = Token::GetAbilityRecordByToken(callerToken); + if (requestCode > 0 && callerAbilityRecord != nullptr) { + bool backFlag = AmsConfigurationParameter::GetInstance().IsSupportBackToCaller(); + long long fullRequestCode = StartAbilityUtils::GenerateFullRequestCode( + callerAbilityRecord->GetPid(), backFlag, requestCode); + const_cast(want).SetParam(CALLER_REQUEST_CODE, fullRequestCode); + TAG_LOGI(AAFwkTag::ABILITYMGR, "pid: %{public}d, requestCode: %{public}d, fullRequestCode: %{public}lld.", + callerAbilityRecord->GetPid(), requestCode, fullRequestCode); + } AbilityRequest abilityRequest; #ifdef SUPPORT_SCREEN if (ImplicitStartProcessor::IsImplicitStartAction(want)) { @@ -1642,6 +1655,18 @@ int AbilityManagerService::StartAbilityForOptionInner(const Want &want, const St SendAbilityEvent(EventName::START_ABILITY_ERROR, HiSysEventType::FAULT, eventInfo); return ERR_CROSS_USER; } + if (want.HasParameter(CALLER_REQUEST_CODE)) { + const_cast(want).RemoveParam(CALLER_REQUEST_CODE); + } + auto callerAbilityRecord = Token::GetAbilityRecordByToken(callerToken); + if (requestCode > 0 && callerAbilityRecord != nullptr) { + bool backFlag = AmsConfigurationParameter::GetInstance().IsSupportBackToCaller(); + long long fullRequestCode = StartAbilityUtils::GenerateFullRequestCode( + callerAbilityRecord->GetPid(), backFlag, requestCode); + const_cast(want).SetParam(CALLER_REQUEST_CODE, fullRequestCode); + TAG_LOGI(AAFwkTag::ABILITYMGR, "pid: %{public}d, requestCode: %{public}d, fullRequestCode: %{public}lld.", + callerAbilityRecord->GetPid(), requestCode, fullRequestCode); + } AbilityRequest abilityRequest; #ifdef SUPPORT_SCREEN @@ -2060,7 +2085,7 @@ int AbilityManagerService::StartUIAbilityBySCBDefault(sptr sessionI } StartAbilityInfoWrap threadLocalInfo(sessionInfo->want, currentUserId, appIndex, sessionInfo->callerToken); if (sessionInfo->want.GetBoolParam(IS_CALL_BY_SCB, true)) { - TAG_LOGD(AAFwkTag::ABILITYMGR, "interceptorExecuter_ called"); + TAG_LOGI(AAFwkTag::ABILITYMGR, "interceptorExecuter_ called"); AbilityInterceptorParam interceptorParam = AbilityInterceptorParam(sessionInfo->want, requestCode, currentUserId, true, nullptr); auto result = interceptorExecuter_ == nullptr ? ERR_INVALID_VALUE : @@ -3292,6 +3317,48 @@ int AbilityManagerService::TerminateAbility(const sptr &token, in return TerminateAbilityWithFlag(token, resultCode, resultWant, true); } +int AbilityManagerService::BackToCallerAbilityWithResult(const sptr &token, int resultCode, + const Want *resultWant, int64_t callerRequestCode) +{ + auto abilityRecord = Token::GetAbilityRecordByToken(token); + if (!abilityRecord) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityRecord is Null."); + return ERR_INVALID_VALUE; + } + + auto requestInfo = StartAbilityUtils::ParseFullRequestCode(callerRequestCode); + TAG_LOGI(AAFwkTag::ABILITYMGR, "pid is %{public}d, backFlag is %{public}d, requestCode is %{public}d.", + requestInfo.pid, requestInfo.backFlag, requestInfo.requestCode); + + if (requestInfo.requestCode < 0 || requestInfo.pid <= 0) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Cant't find caller by requestCode."); + return ERR_CALLER_NOT_EXISTS; + } + + auto callerAbilityRecord = abilityRecord->GetCallerByRequestCode(requestInfo.requestCode, requestInfo.pid); + if (callerAbilityRecord == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Caller not exists."); + return ERR_CALLER_NOT_EXISTS; + } + auto abilityResult = std::make_shared(requestInfo.requestCode, resultCode, *resultWant); + callerAbilityRecord->SendResultByBackToCaller(abilityResult); + + // remove requestCode after send result + abilityRecord->RemoveCallerRequestCode(callerAbilityRecord, requestInfo.requestCode); + + if (!requestInfo.backFlag) { + TAG_LOGW(AAFwkTag::ABILITYMGR, "Not support back to caller."); + return ERR_NOT_SUPPORT_BACK_TO_CALLER; + } + auto ownerUserId = abilityRecord->GetOwnerMissionUserId(); + if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) { + auto uiAbilityManager = GetUIAbilityManagerByUserId(ownerUserId); + CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_INVALID_VALUE); + return uiAbilityManager->BackToCallerAbilityWithResult(abilityRecord->GetSessionInfo(), callerAbilityRecord); + } + return ERR_OK; +} + int AbilityManagerService::CloseAbility(const sptr &token, int resultCode, const Want *resultWant) { EventInfo eventInfo; diff --git a/services/abilitymgr/src/ability_manager_stub.cpp b/services/abilitymgr/src/ability_manager_stub.cpp index 633882edecb327860c939a79c1766e0ceb4f64fe..097da49ea0919d15e6e4ecf859b436fc165b2af2 100644 --- a/services/abilitymgr/src/ability_manager_stub.cpp +++ b/services/abilitymgr/src/ability_manager_stub.cpp @@ -83,6 +83,9 @@ int AbilityManagerStub::OnRemoteRequestInnerFirst(uint32_t code, MessageParcel & if (interfaceCode == AbilityManagerInterfaceCode::RELEASE_DATA_ABILITY) { return ReleaseDataAbilityInner(data, reply); } + if (interfaceCode == AbilityManagerInterfaceCode::BACK_TO_CALLER_UIABILITY) { + return BackToCallerInner(data, reply); + } return ERR_CODE_NOT_EXIST; } @@ -962,6 +965,23 @@ int AbilityManagerStub::TerminateAbilityInner(MessageParcel &data, MessageParcel return NO_ERROR; } +int AbilityManagerStub::BackToCallerInner(MessageParcel &data, MessageParcel &reply) +{ + sptr token = nullptr; + if (data.ReadBool()) { + token = data.ReadRemoteObject(); + } + int resultCode = data.ReadInt32(); + Want *resultWant = data.ReadParcelable(); + int64_t callerRequestCode = data.ReadInt64(); + int32_t result = BackToCallerAbilityWithResult(token, resultCode, resultWant, callerRequestCode); + reply.WriteInt32(result); + if (resultWant != nullptr) { + delete resultWant; + } + return NO_ERROR; +} + int AbilityManagerStub::TerminateUIExtensionAbilityInner(MessageParcel &data, MessageParcel &reply) { sptr extensionSessionInfo = nullptr; diff --git a/services/abilitymgr/src/ability_record.cpp b/services/abilitymgr/src/ability_record.cpp index dcfb0c95ebc796ff20f1b49eb3c07e41631671cd..cee1225cfb8314c4283fc1d078b571218a6ca33b 100644 --- a/services/abilitymgr/src/ability_record.cpp +++ b/services/abilitymgr/src/ability_record.cpp @@ -1768,6 +1768,15 @@ void AbilityRecord::SendResult(bool isSandboxApp, uint32_t tokeId) SetResult(nullptr); } +void AbilityRecord::SendResultByBackToCaller(const std::shared_ptr &result) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "ability:%{public}s.", abilityInfo_.name.c_str()); + std::lock_guard guard(lock_); + CHECK_POINTER(scheduler_); + CHECK_POINTER(result); + scheduler_->SendResult(result->requestCode_, result->resultCode_, result->resultWant_); +} + void AbilityRecord::SendSandboxSavefileResult(const Want &want, int resultCode, int requestCode) { TAG_LOGI(AAFwkTag::ABILITYMGR, "ability:%{public}s.", abilityInfo_.name.c_str()); @@ -1832,6 +1841,36 @@ void AbilityRecord::SendResultToCallers(bool schedulerdied) } } +std::shared_ptr AbilityRecord::GetCallerByRequestCode(int32_t requestCode, int32_t pid) +{ + for (auto caller : GetCallerRecordList()) { + if (caller == nullptr) { + TAG_LOGW(AAFwkTag::ABILITYMGR, "caller is nullptr."); + continue; + } + std::shared_ptr callerAbilityRecord = caller->GetCaller(); + if (callerAbilityRecord == nullptr) { + TAG_LOGW(AAFwkTag::ABILITYMGR, "caller abilityRecord is nullptr."); + continue; + } + if (callerAbilityRecord->GetPid() != pid) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "pid not match: %{public}d, %{public}d", + callerAbilityRecord->GetPid(), pid); + continue; + } + auto recordList = caller->GetRequestCodeList(); + for (auto code: recordList) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "callerRequestCode is %{public}d", code); + } + if (caller->IsHistoryRequestCode(requestCode)) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "requestcode is invalid"); + return callerAbilityRecord; + } + } + TAG_LOGW(AAFwkTag::ABILITYMGR, "Not found caller by requestCode and pid."); + return nullptr; +} + void AbilityRecord::SaveResultToCallers(const int resultCode, const Want *resultWant) { auto callerRecordList = GetCallerRecordList(); @@ -1984,11 +2023,29 @@ void AbilityRecord::RemoveSpecifiedWantParam(const std::string &key) } } +void AbilityRecord::RemoveCallerRequestCode(std::shared_ptr callerAbilityRecord, int32_t requestCode) +{ + if (callerAbilityRecord == nullptr) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "callerAbilityRecord is null."); + return; + } + for (auto it = callerList_.begin(); it != callerList_.end(); it++) { + if ((*it)->GetCaller() == callerAbilityRecord) { + (*it)->RemoveHistoryRequestCode(requestCode); + if ((*it)->GetRequestCodeList().empty()) { + callerList_.erase(it); + TAG_LOGI(AAFwkTag::ABILITYMGR, "remove a callerRecord."); + } + return; + } + } +} + void AbilityRecord::AddCallerRecord(const sptr &callerToken, int requestCode, std::string srcAbilityId, uint32_t callingTokenId) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); - TAG_LOGD(AAFwkTag::ABILITYMGR, "Add caller record."); + TAG_LOGI(AAFwkTag::ABILITYMGR, "Add caller record, callingTokenId is %{public}u", callingTokenId); if (!srcAbilityId.empty() && IsSystemAbilityCall(callerToken, callingTokenId)) { AddSystemAbilityCallerRecord(callerToken, requestCode, srcAbilityId); return; @@ -2001,19 +2058,21 @@ void AbilityRecord::AddCallerRecord(const sptr &callerToken, int }; auto record = std::find_if(callerList_.begin(), callerList_.end(), isExist); + auto newCallerRecord = std::make_shared(requestCode, abilityRecord); if (record != callerList_.end()) { + newCallerRecord->SetRequestCodeList((*record)->GetRequestCodeList()); callerList_.erase(record); } - - callerList_.emplace_back(std::make_shared(requestCode, abilityRecord)); + newCallerRecord->AddHistoryRequestCode(requestCode); + callerList_.emplace_back(newCallerRecord); lifeCycleStateInfo_.caller.requestCode = requestCode; lifeCycleStateInfo_.caller.deviceId = abilityRecord->GetAbilityInfo().deviceId; lifeCycleStateInfo_.caller.bundleName = abilityRecord->GetAbilityInfo().bundleName; lifeCycleStateInfo_.caller.abilityName = abilityRecord->GetAbilityInfo().name; - TAG_LOGD(AAFwkTag::ABILITYMGR, "caller %{public}s, %{public}s", + TAG_LOGD(AAFwkTag::ABILITYMGR, "caller %{public}s, %{public}s, callerSize: %{public}zu", abilityRecord->GetAbilityInfo().bundleName.c_str(), - abilityRecord->GetAbilityInfo().name.c_str()); + abilityRecord->GetAbilityInfo().name.c_str(), callerList_.size()); } bool AbilityRecord::IsSystemAbilityCall(const sptr &callerToken, uint32_t callingTokenId) diff --git a/services/abilitymgr/src/ams_configuration_parameter.cpp b/services/abilitymgr/src/ams_configuration_parameter.cpp index 014e6b39a6c108b29ef9abe3c6813990da9d3b94..6ce82c12bff8f110b9a1514775073f69d83cca11 100644 --- a/services/abilitymgr/src/ams_configuration_parameter.cpp +++ b/services/abilitymgr/src/ams_configuration_parameter.cpp @@ -215,6 +215,7 @@ int AmsConfigurationParameter::LoadAmsConfiguration(const std::string &filePath) } LoadSystemConfiguration(amsJson); + LoadBackToCallerConfig(amsJson); SetPickerJsonObject(amsJson); amsJson.clear(); inFile.close(); @@ -270,6 +271,23 @@ int AmsConfigurationParameter::LoadSystemConfiguration(nlohmann::json& Object) return READ_FAIL; } +int AmsConfigurationParameter::LoadBackToCallerConfig(nlohmann::json& Object) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "load backTocaller config."); + if (Object.contains(AmsConfig::SUPPORT_BACK_TO_CALLER) && + Object.at(AmsConfig::SUPPORT_BACK_TO_CALLER).is_boolean()) { + supportBackToCaller_ = Object.at(AmsConfig::SUPPORT_BACK_TO_CALLER).get(); + return READ_OK; + } + TAG_LOGE(AAFwkTag::ABILITYMGR, "load backTocaller failed."); + return READ_FAIL; +} + +bool AmsConfigurationParameter::IsSupportBackToCaller() const +{ + return supportBackToCaller_; +} + bool AmsConfigurationParameter::CheckServiceConfigEnable(nlohmann::json& Object, const std::string &configName, JsonValueType type) { 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 77db71169d975803320483ac114888af6020007a..7a8710c9154d15f54c89391af3210479d4a9e4a9 100644 --- a/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp +++ b/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp @@ -1141,6 +1141,33 @@ void UIAbilityLifecycleManager::CompleteBackground(const std::shared_ptr currentSessionInfo, + std::shared_ptr abilityRecord) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "called."); + if (currentSessionInfo == nullptr || currentSessionInfo->sessionToken == nullptr) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "currentSessionInfo is invalid."); + return ERR_INVALID_VALUE; + } + + if (abilityRecord == nullptr) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "callerAbility is invalid."); + return ERR_INVALID_VALUE; + } + + auto callerSessionInfo = abilityRecord->GetSessionInfo(); + if (callerSessionInfo == nullptr || callerSessionInfo->sessionToken == nullptr) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "callerSessionInfo is invalid."); + return ERR_INVALID_VALUE; + } + + auto currentSession = iface_cast(currentSessionInfo->sessionToken); + callerSessionInfo->isBackTransition = true; + auto ret = static_cast(currentSession->PendingSessionActivation(callerSessionInfo)); + callerSessionInfo->isBackTransition = false; + return ret; +} + int UIAbilityLifecycleManager::CloseUIAbility(const std::shared_ptr &abilityRecord, int resultCode, const Want *resultWant, bool isClearSession) { diff --git a/services/abilitymgr/src/start_ability_utils.cpp b/services/abilitymgr/src/start_ability_utils.cpp index 0ee1f922bb2fb398d45ec1644d06051ead99df12..42fbd1377d1e6606604823ed6c6c1e6c290242bd 100644 --- a/services/abilitymgr/src/start_ability_utils.cpp +++ b/services/abilitymgr/src/start_ability_utils.cpp @@ -35,6 +35,9 @@ constexpr const char* SHELL_ASSISTANT_BUNDLENAME = "com.huawei.shell_assistant"; constexpr int32_t BROKER_UID = 5557; constexpr const char* PARAM_RESV_ANCO_CALLER_UID = "ohos.anco.param.callerUid"; constexpr const char* PARAM_RESV_ANCO_CALLER_BUNDLENAME = "ohos.anco.param.callerBundleName"; +constexpr int32_t REQUEST_CODE_LENGTH = 32; +constexpr int32_t PID_LENGTH = 16; +constexpr int32_t REQUEST_CODE_PID_LENGTH = 48; } thread_local std::shared_ptr StartAbilityUtils::startAbilityInfo; thread_local std::shared_ptr StartAbilityUtils::callerAbilityInfo; @@ -337,5 +340,35 @@ bool StartAbilityUtils::IsCallFromAncoShellOrBroker(const sptr &c } return false; } + +int64_t StartAbilityUtils::GenerateFullRequestCode(int32_t pid, bool backFlag, int32_t requestCode) +{ + if (requestCode <= 0 || pid <= 0) { + return 0; + } + int64_t fullRequestCode = requestCode; + uint64_t tempNum = pid; + fullRequestCode |= (tempNum << REQUEST_CODE_LENGTH); + if (backFlag) { + tempNum = 1; + fullRequestCode |= (tempNum << REQUEST_CODE_PID_LENGTH); + } + return fullRequestCode; +} + +CallerRequestInfo StartAbilityUtils::ParseFullRequestCode(int64_t fullRequestCode) +{ + CallerRequestInfo requestInfo; + if (fullRequestCode <= 0) { + return requestInfo; + } + uint64_t tempNum = 1; + requestInfo.requestCode = (fullRequestCode & ((tempNum << REQUEST_CODE_LENGTH) - 1)); + fullRequestCode >>= REQUEST_CODE_LENGTH; + requestInfo.pid = (fullRequestCode & ((tempNum << PID_LENGTH) - 1)); + fullRequestCode >>= PID_LENGTH; + requestInfo.backFlag = (fullRequestCode == 1); + return requestInfo; +} } } \ No newline at end of file