From 925f8cbdcc6195aa4688d85b772e412bd746dbd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AE=B5=E5=97=A3=E9=92=8A?= Date: Thu, 8 Aug 2024 12:48:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DbackToCallerWithResult?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 段嗣钊 Change-Id: I41b994e874e8d23b88bfb22121b5d8c42a4e7d97 --- .../napi/ability_context/ability_context.js | 4 +- .../ability_runtime/ability_context_impl.cpp | 2 +- .../ability_runtime/js_ability_context.cpp | 83 ++++++++++++------- .../ui_extension_context.cpp | 4 + .../ui_extension_context.h | 4 +- services/abilitymgr/include/ability_record.h | 32 ++----- .../include/ams_configuration_parameter.h | 2 +- .../abilitymgr/include/mission_list_manager.h | 15 +++- .../include/mission_list_manager_interface.h | 2 + .../ui_ability_lifecycle_manager.h | 6 +- .../abilitymgr/include/start_ability_utils.h | 8 -- .../abilitymgr/src/ability_manager_proxy.cpp | 10 +-- .../src/ability_manager_service.cpp | 42 +++------- services/abilitymgr/src/ability_record.cpp | 23 ++--- .../src/ams_configuration_parameter.cpp | 6 +- .../abilitymgr/src/mission_list_manager.cpp | 51 +++++++++++- .../ui_ability_lifecycle_manager.cpp | 56 +++++++++++-- .../abilitymgr/src/start_ability_utils.cpp | 33 -------- utils/server/startup/include/startup_util.h | 9 ++ utils/server/startup/src/startup_util.cpp | 40 +++++++++ 20 files changed, 268 insertions(+), 164 deletions(-) diff --git a/frameworks/js/napi/ability_context/ability_context.js b/frameworks/js/napi/ability_context/ability_context.js index 6dd3fcfea7d..ee910a91ec7 100644 --- a/frameworks/js/napi/ability_context/ability_context.js +++ b/frameworks/js/napi/ability_context/ability_context.js @@ -173,8 +173,8 @@ class AbilityContext extends Context { return this.__context_impl__.terminateSelfWithResult(abilityResult, callback); } - backToCallerAbilityWithResult(abilityResult, requestCode, callback) { - return this.__context_impl__.backToCallerAbilityWithResult(abilityResult, requestCode, callback); + backToCallerAbilityWithResult(abilityResult, requestCode) { + return this.__context_impl__.backToCallerAbilityWithResult(abilityResult, requestCode); } restoreWindowStage(contentStorage) { diff --git a/frameworks/native/ability/ability_runtime/ability_context_impl.cpp b/frameworks/native/ability/ability_runtime/ability_context_impl.cpp index 6747bd856fe..cbb4f47ae27 100644 --- a/frameworks/native/ability/ability_runtime/ability_context_impl.cpp +++ b/frameworks/native/ability/ability_runtime/ability_context_impl.cpp @@ -342,7 +342,7 @@ ErrCode AbilityContextImpl::BackToCallerAbilityWithResult(const AAFwk::Want& wan { ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->BackToCallerAbilityWithResult( token_, resultCode, &want, requestCode); - TAG_LOGI(AAFwkTag::CONTEXT, "ret is %{public}d", err); + TAG_LOGI(AAFwkTag::CONTEXT, "ret:%{public}d", err); return static_cast(err); } 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 5a0872c7987..1f6071067e7 100644 --- a/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp @@ -17,7 +17,9 @@ #include #include +#include #include +#include #include "ability_manager_client.h" #include "ability_manager_errors.h" @@ -72,6 +74,31 @@ std::recursive_mutex gConnectsLock_; int64_t g_serialNumber = 0; const std::string ATOMIC_SERVICE_PREFIX = "com.atomicservice."; std::atomic g_hasSetContinueState = false; +// max request code is (1 << 49) - 1 +constexpr int64_t MAX_REQUEST_CODE = 562949953421311; +constexpr size_t MAX_REQUEST_CODE_LENGTH = 15; +constexpr int32_t BASE_REQUEST_CODE_NUM = 10; + +int64_t RequestCodeFromStringToInt64(const std::string &requestCode) +{ + if (requestCode.size() > MAX_REQUEST_CODE_LENGTH) { + TAG_LOGW(AAFwkTag::CONTEXT, "requestCode too long: %{public}s", requestCode.c_str()); + return 0; + } + std::regex formatRegex("^[1-9]\\d*|0$"); + std::smatch sm; + if (!std::regex_match(requestCode, sm, formatRegex)) { + TAG_LOGW(AAFwkTag::CONTEXT, "requestCode match failed: %{public}s", requestCode.c_str()); + return 0; + } + int64_t parsedRequestCode = 0; + parsedRequestCode = strtoll(requestCode.c_str(), nullptr, BASE_REQUEST_CODE_NUM); + if (parsedRequestCode > MAX_REQUEST_CODE) { + TAG_LOGW(AAFwkTag::CONTEXT, "requestCode too large: %{public}s", requestCode.c_str()); + return 0; + } + return parsedRequestCode; +} // This function has to be called from engine thread void RemoveConnection(int64_t connectId) @@ -1425,55 +1452,55 @@ napi_value JsAbilityContext::OnTerminateSelfWithResult(napi_env env, NapiCallbac napi_value JsAbilityContext::OnBackToCallerAbilityWithResult(napi_env env, NapiCallbackInfo& info) { - TAG_LOGI(AAFwkTag::CONTEXT, "OnBackToCallerAbilityWithResult start"); + TAG_LOGD(AAFwkTag::CONTEXT, "start"); if (info.argc < ARGC_TWO) { - TAG_LOGE(AAFwkTag::CONTEXT, "Not enough params"); + TAG_LOGE(AAFwkTag::CONTEXT, "invalid argc"); ThrowTooFewParametersError(env); return CreateJsUndefined(env); } - int resultCode = 0; + int32_t 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__); + TAG_LOGE(AAFwkTag::CONTEXT, "parse ability result failed"); 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."); + std::string requestCodeStr; + if (!OHOS::AppExecFwk::UnwrapStringFromJS2(env, info.argv[INDEX_ONE], requestCodeStr)) { + TAG_LOGE(AAFwkTag::CONTEXT, "invalid requestCode."); + ThrowInvalidParamError(env, "Parse param requestCode failed, requestCode must be string."); return CreateJsUndefined(env); } + auto requestCode = RequestCodeFromStringToInt64(requestCodeStr); + TAG_LOGD(AAFwkTag::CONTEXT, "requestCode: %{public}s", requestCodeStr.c_str()); - 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 innerErrorCode = std::make_shared(ERR_OK); + NapiAsyncTask::ExecuteCallback execute = [weak = context_, want, resultCode, requestCode, innerErrorCode]() { + TAG_LOGI(AAFwkTag::CONTEXT, "aync execute"); + auto context = weak.lock(); + if (!context) { + TAG_LOGW(AAFwkTag::CONTEXT, "context is released"); + *innerErrorCode = static_cast(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)); - } - }; + *innerErrorCode = context->BackToCallerAbilityWithResult(want, resultCode, requestCode); + }; - napi_value lastParam = (info.argc > ARGC_TWO) ? info.argv[ARGC_TWO] : nullptr; + NapiAsyncTask::CompleteCallback complete = [innerErrorCode](napi_env env, NapiAsyncTask& task, int32_t status) { + (*innerErrorCode == ERR_OK) ? task.ResolveWithNoError(env, CreateJsUndefined(env)) : + task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrorCode)); + }; + // only support promise method + napi_value lastParam = nullptr; napi_value result = nullptr; NapiAsyncTask::ScheduleHighQos("JsAbilityContext::OnBackToCallerAbilityWithResult", - env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result)); - TAG_LOGD(AAFwkTag::CONTEXT, "OnBackToCallerAbilityWithResult end"); + env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result)); return result; } - napi_value JsAbilityContext::OnConnectAbility(napi_env env, NapiCallbackInfo& info) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); diff --git a/frameworks/native/ability/native/ui_extension_ability/ui_extension_context.cpp b/frameworks/native/ability/native/ui_extension_ability/ui_extension_context.cpp index c98a41ab363..e1b25639d33 100755 --- a/frameworks/native/ability/native/ui_extension_ability/ui_extension_context.cpp +++ b/frameworks/native/ability/native/ui_extension_ability/ui_extension_context.cpp @@ -242,6 +242,7 @@ void UIExtensionContext::OnAbilityResultInner(int requestCode, int resultCode, c int UIExtensionContext::GenerateCurRequestCode() { + std::lock_guard lock(requestCodeMutex_); curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1); return curRequestCode_; } @@ -291,5 +292,8 @@ ErrCode UIExtensionContext::AddFreeInstallObserver(const sptr resultCallbacks_; - - int curRequestCode_ = 0; + static int32_t curRequestCode_; + static std::mutex requestCodeMutex_; #ifdef SUPPORT_SCREEN sptr window_ = nullptr; #endif // SUPPORT_SCREEN diff --git a/services/abilitymgr/include/ability_record.h b/services/abilitymgr/include/ability_record.h index 58be5de8008..9051374b9b3 100644 --- a/services/abilitymgr/include/ability_record.h +++ b/services/abilitymgr/include/ability_record.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "cpp/mutex.h" #include "cpp/condition_variable.h" @@ -194,38 +195,23 @@ public: } bool IsHistoryRequestCode(int32_t requestCode) { - for (auto it = requestCodeList_.begin(); it != requestCodeList_.end(); it++) { - if (requestCode == *it) { - return true; - } - } - return false; + return requestCodeSet_.count(requestCode) > 0; } void RemoveHistoryRequestCode(int32_t requestCode) { - for (auto it = requestCodeList_.begin(); it != requestCodeList_.end(); it++) { - if (requestCode == *it) { - requestCodeList_.erase(it); - return; - } - } + requestCodeSet_.erase(requestCode); } void AddHistoryRequestCode(int32_t requestCode) { - if (IsHistoryRequestCode(requestCode)) { - return; - } - requestCodeList_.emplace_back(requestCode); + requestCodeSet_.insert(requestCode); } - - void SetRequestCodeList(std::list requestCodeList) + void SetRequestCodeSet(const std::set &requestCodeSet) { - requestCodeList_ = requestCodeList; + requestCodeSet_ = requestCodeSet; } - - std::list GetRequestCodeList() + std::set GetRequestCodeSet() { - return requestCodeList_; + return requestCodeSet_; } private: @@ -233,7 +219,7 @@ private: std::weak_ptr caller_; std::shared_ptr saCaller_ = nullptr; std::shared_ptr callerInfo_ = nullptr; - std::list requestCodeList_; + std::set requestCodeSet_; }; /** diff --git a/services/abilitymgr/include/ams_configuration_parameter.h b/services/abilitymgr/include/ams_configuration_parameter.h index 11d50cef2a4..4039ef57664 100644 --- a/services/abilitymgr/include/ams_configuration_parameter.h +++ b/services/abilitymgr/include/ams_configuration_parameter.h @@ -151,7 +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); + int32_t LoadBackToCallerConfig(nlohmann::json& Object); private: bool nonConfigFile_ {false}; diff --git a/services/abilitymgr/include/mission_list_manager.h b/services/abilitymgr/include/mission_list_manager.h index 5580a41d694..d9c3e13dc64 100644 --- a/services/abilitymgr/include/mission_list_manager.h +++ b/services/abilitymgr/include/mission_list_manager.h @@ -129,6 +129,18 @@ public: * @return int error code */ int MoveAbilityToBackground(const std::shared_ptr &abilityRecord) override; + + /** + * @brief Back to caller ability with result + * + * @param abilityRecord the ability to move + * @param resultCode result code + * @param resultWant result want + * @param callerRequestCode request code of caller + * @return int error code + */ + int32_t BackToCallerAbilityWithResult(std::shared_ptr abilityRecord, + int32_t resultCode, const Want *resultWant, int64_t callerRequestCode) override; /** * @brief Terminate ability with the given abilityRecord @@ -443,7 +455,8 @@ private: const std::shared_ptr &list); int ClearMissionLocked(int missionId, const std::shared_ptr &mission); int ClearMissionLocking(int missionId, const std::shared_ptr &mission); - int MoveAbilityToBackgroundLocked(const std::shared_ptr &abilityRecord); + int MoveAbilityToBackgroundLocked(const std::shared_ptr &abilityRecord, + const std::shared_ptr &specifiedNextRecord = nullptr); void RemoveBackgroundingAbility(const std::shared_ptr &abilityRecord); int TerminateAbilityLocked(const std::shared_ptr &abilityRecord, bool flag); /** diff --git a/services/abilitymgr/include/mission_list_manager_interface.h b/services/abilitymgr/include/mission_list_manager_interface.h index 162abc076a9..2661a5ba784 100644 --- a/services/abilitymgr/include/mission_list_manager_interface.h +++ b/services/abilitymgr/include/mission_list_manager_interface.h @@ -56,6 +56,8 @@ public: virtual std::shared_ptr GetAbilityRecordByToken(const sptr &token) = 0; virtual std::shared_ptr GetAbilityRecordByMissionId(int missionId) = 0; virtual int MoveAbilityToBackground(const std::shared_ptr &abilityRecord) = 0; + virtual int32_t BackToCallerAbilityWithResult(std::shared_ptr abilityRecord, + int32_t resultCode, const Want *resultWant, int64_t callerRequestCode) = 0; virtual int TerminateAbility(const std::shared_ptr &abilityRecord, int resultCode, const Want *resultWant, bool flag) = 0; virtual int AbilityTransactionDone(const sptr &token, int state, const PacMap &saveData) = 0; 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 224bd98e4bc..3c58dc2ce9a 100644 --- a/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h +++ b/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h @@ -140,8 +140,8 @@ public: */ std::shared_ptr GetUIAbilityRecordBySessionInfo(const sptr &sessionInfo); - int BackToCallerAbilityWithResult(sptr currentSessionInfo, - std::shared_ptr abilityRecord); + int32_t BackToCallerAbilityWithResult(std::shared_ptr abilityRecord, + int resultCode, const Want *resultWant, int64_t callerRequestCode); /** * CloseUIAbility, close the special ability by scb. @@ -446,6 +446,8 @@ private: void TerminateSession(std::shared_ptr abilityRecord); int StartWithPersistentIdByDistributed(const AbilityRequest &abilityRequest, int32_t persistentId); void CheckCallerFromBackground(std::shared_ptr callerAbility, sptr &sessionInfo); + int32_t BackToCallerAbilityWithResultLocked(sptr currentSessionInfo, + std::shared_ptr callerAbilityRecord); int32_t userId_ = -1; mutable ffrt::mutex sessionLock_; diff --git a/services/abilitymgr/include/start_ability_utils.h b/services/abilitymgr/include/start_ability_utils.h index 52296d7c5e6..2e41c0167f9 100644 --- a/services/abilitymgr/include/start_ability_utils.h +++ b/services/abilitymgr/include/start_ability_utils.h @@ -26,12 +26,6 @@ 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); @@ -61,8 +55,6 @@ 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/src/ability_manager_proxy.cpp b/services/abilitymgr/src/ability_manager_proxy.cpp index a95417a05d5..5d072ffb3d5 100644 --- a/services/abilitymgr/src/ability_manager_proxy.cpp +++ b/services/abilitymgr/src/ability_manager_proxy.cpp @@ -877,7 +877,7 @@ int AbilityManagerProxy::BackToCallerAbilityWithResult(const sptr MessageParcel reply; MessageOption option; - CHECK_POINTER_AND_RETURN_LOG(token, ERR_INVALID_VALUE, "token is nullptr"); + CHECK_POINTER_AND_RETURN_LOG(token, ERR_INVALID_VALUE, "null token"); if (!WriteInterfaceToken(data)) { return INNER_ERR; @@ -885,21 +885,21 @@ int AbilityManagerProxy::BackToCallerAbilityWithResult(const sptr if (token) { if (!data.WriteBool(true) || !data.WriteRemoteObject(token)) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "flag and token write failed."); + TAG_LOGE(AAFwkTag::ABILITYMGR, "token write failed"); return INNER_ERR; } } else { if (!data.WriteBool(false)) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "flag write failed."); + 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."); + TAG_LOGE(AAFwkTag::ABILITYMGR, "write ability result failed"); return INNER_ERR; } if (!data.WriteInt64(callerRequestCode)) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "data write requestCode failed."); + TAG_LOGE(AAFwkTag::ABILITYMGR, "write requestCode failed"); return INNER_ERR; } error = SendRequest(AbilityManagerInterfaceCode::BACK_TO_CALLER_UIABILITY, data, reply, option); diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index 59cbe3824d3..b84a7415c07 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -1016,9 +1016,9 @@ int AbilityManagerService::StartAbilityInner(const Want &want, const sptr 0 && callerAbilityRecord != nullptr) { bool backFlag = AmsConfigurationParameter::GetInstance().IsSupportBackToCaller(); - long long fullRequestCode = StartAbilityUtils::GenerateFullRequestCode( + auto fullRequestCode = StartupUtil::GenerateFullRequestCode( callerAbilityRecord->GetPid(), backFlag, requestCode); - const_cast(want).SetParam(CALLER_REQUEST_CODE, fullRequestCode); + const_cast(want).SetParam(CALLER_REQUEST_CODE, std::to_string(fullRequestCode)); TAG_LOGI(AAFwkTag::ABILITYMGR, "pid: %{public}d, requestCode: %{public}d, fullRequestCode: %{public}lld.", callerAbilityRecord->GetPid(), requestCode, fullRequestCode); } @@ -1616,9 +1616,9 @@ int AbilityManagerService::StartAbilityForOptionInner(const Want &want, const St auto callerAbilityRecord = Token::GetAbilityRecordByToken(callerToken); if (requestCode > 0 && callerAbilityRecord != nullptr) { bool backFlag = AmsConfigurationParameter::GetInstance().IsSupportBackToCaller(); - long long fullRequestCode = StartAbilityUtils::GenerateFullRequestCode( + auto fullRequestCode = StartupUtil::GenerateFullRequestCode( callerAbilityRecord->GetPid(), backFlag, requestCode); - const_cast(want).SetParam(CALLER_REQUEST_CODE, fullRequestCode); + const_cast(want).SetParam(CALLER_REQUEST_CODE, std::to_string(fullRequestCode)); TAG_LOGI(AAFwkTag::ABILITYMGR, "pid: %{public}d, requestCode: %{public}d, fullRequestCode: %{public}lld.", callerAbilityRecord->GetPid(), requestCode, fullRequestCode); } @@ -2040,7 +2040,7 @@ int AbilityManagerService::StartUIAbilityBySCBDefault(sptr sessionI } StartAbilityInfoWrap threadLocalInfo(sessionInfo->want, currentUserId, appIndex, sessionInfo->callerToken); if (sessionInfo->want.GetBoolParam(IS_CALL_BY_SCB, true)) { - TAG_LOGI(AAFwkTag::ABILITYMGR, "interceptorExecuter_ called"); + TAG_LOGD(AAFwkTag::ABILITYMGR, "interceptorExecuter_ called"); AbilityInterceptorParam interceptorParam = AbilityInterceptorParam(sessionInfo->want, requestCode, currentUserId, true, nullptr); auto result = interceptorExecuter_ == nullptr ? ERR_INVALID_VALUE : @@ -3280,38 +3280,16 @@ int AbilityManagerService::BackToCallerAbilityWithResult(const sptrGetCallerByRequestCode(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 uiAbilityManager->BackToCallerAbilityWithResult(abilityRecord, resultCode, resultWant, + callerRequestCode); } - return ERR_OK; + auto missionListManager = GetMissionListManagerByUserId(ownerUserId); + CHECK_POINTER_AND_RETURN(missionListManager, ERR_INVALID_VALUE); + return missionListManager->BackToCallerAbilityWithResult(abilityRecord, resultCode, resultWant, callerRequestCode); } int AbilityManagerService::CloseAbility(const sptr &token, int resultCode, const Want *resultWant) diff --git a/services/abilitymgr/src/ability_record.cpp b/services/abilitymgr/src/ability_record.cpp index 112a78244d8..f6562c9e0c1 100644 --- a/services/abilitymgr/src/ability_record.cpp +++ b/services/abilitymgr/src/ability_record.cpp @@ -1814,29 +1814,20 @@ std::shared_ptr AbilityRecord::GetCallerByRequestCode(int32_t req { for (auto caller : GetCallerRecordList()) { if (caller == nullptr) { - TAG_LOGW(AAFwkTag::ABILITYMGR, "caller is nullptr."); + TAG_LOGD(AAFwkTag::ABILITYMGR, "null caller"); continue; } std::shared_ptr callerAbilityRecord = caller->GetCaller(); - if (callerAbilityRecord == nullptr) { - TAG_LOGW(AAFwkTag::ABILITYMGR, "caller abilityRecord is nullptr."); + if (callerAbilityRecord == nullptr || callerAbilityRecord->GetPid() != pid) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "callerAbility not match"); 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"); + TAG_LOGI(AAFwkTag::ABILITYMGR, "found callerAbility"); return callerAbilityRecord; } } - TAG_LOGW(AAFwkTag::ABILITYMGR, "Not found caller by requestCode and pid."); + TAG_LOGI(AAFwkTag::ABILITYMGR, "Can't found caller"); return nullptr; } @@ -2001,7 +1992,7 @@ void AbilityRecord::RemoveCallerRequestCode(std::shared_ptr calle for (auto it = callerList_.begin(); it != callerList_.end(); it++) { if ((*it)->GetCaller() == callerAbilityRecord) { (*it)->RemoveHistoryRequestCode(requestCode); - if ((*it)->GetRequestCodeList().empty()) { + if ((*it)->GetRequestCodeSet().empty()) { callerList_.erase(it); TAG_LOGI(AAFwkTag::ABILITYMGR, "remove a callerRecord."); } @@ -2029,7 +2020,7 @@ 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()); + newCallerRecord->SetRequestCodeSet((*record)->GetRequestCodeSet()); callerList_.erase(record); } newCallerRecord->AddHistoryRequestCode(requestCode); diff --git a/services/abilitymgr/src/ams_configuration_parameter.cpp b/services/abilitymgr/src/ams_configuration_parameter.cpp index 6ce82c12bff..bbaf44e230d 100644 --- a/services/abilitymgr/src/ams_configuration_parameter.cpp +++ b/services/abilitymgr/src/ams_configuration_parameter.cpp @@ -271,15 +271,15 @@ int AmsConfigurationParameter::LoadSystemConfiguration(nlohmann::json& Object) return READ_FAIL; } -int AmsConfigurationParameter::LoadBackToCallerConfig(nlohmann::json& Object) +int32_t AmsConfigurationParameter::LoadBackToCallerConfig(nlohmann::json& Object) { - TAG_LOGI(AAFwkTag::ABILITYMGR, "load backTocaller config."); + 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."); + TAG_LOGE(AAFwkTag::ABILITYMGR, "load backTocaller failed"); return READ_FAIL; } diff --git a/services/abilitymgr/src/mission_list_manager.cpp b/services/abilitymgr/src/mission_list_manager.cpp index dcef86e5aa8..4ad477d3d49 100644 --- a/services/abilitymgr/src/mission_list_manager.cpp +++ b/services/abilitymgr/src/mission_list_manager.cpp @@ -29,9 +29,11 @@ #include "hisysevent.h" #include "mission_info_mgr.h" #include "in_process_call_wrapper.h" +#include "permission_constants.h" #include "res_sched_util.h" #include "server_constant.h" #include "startup_util.h" +#include "ui_extension_utils.h" #ifdef SUPPORT_GRAPHICS #include "ability_first_frame_state_observer_manager.h" #endif @@ -1439,6 +1441,50 @@ void MissionListManager::CompleteBackground(const std::shared_ptr } } +int32_t MissionListManager::BackToCallerAbilityWithResult(std::shared_ptr abilityRecord, + int32_t resultCode, const Want *resultWant, int64_t callerRequestCode) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + std::lock_guard guard(managerLock_); + auto requestInfo = StartupUtil::ParseFullRequestCode(callerRequestCode); + TAG_LOGI(AAFwkTag::ABILITYMGR, "pid:%{public}d, backFlag:%{public}d, requestCode:%{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); + abilityRecord->RemoveCallerRequestCode(callerAbilityRecord, requestInfo.requestCode); + if (!requestInfo.backFlag) { + TAG_LOGW(AAFwkTag::ABILITYMGR, "Not support back to caller"); + return ERR_NOT_SUPPORT_BACK_TO_CALLER; + } + if (callerAbilityRecord == abilityRecord) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "caller is self"); + return ERR_OK; + } + auto tokenId = abilityRecord->GetAbilityInfo().applicationInfo.accessTokenId; + TAG_LOGD(AAFwkTag::ABILITYMGR, "tokenId: %{public}d.", tokenId); + if (!abilityRecord->IsForeground() && !abilityRecord->GetAbilityForegroundingFlag() && + !PermissionVerification::GetInstance()->VerifyPermissionByTokenId(tokenId, + PermissionConstants::PERMISSION_START_ABILITIES_FROM_BACKGROUND)) { + TAG_LOGW(AAFwkTag::ABILITYMGR, "can't start ability from background."); + return CHECK_PERMISSION_FAILED; + } + // find host of UI Extension + if (UIExtensionUtils::IsUIExtension(callerAbilityRecord->GetAbilityInfo().extensionAbilityType)) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "caller is uiExtension."); + callerAbilityRecord = callerAbilityRecord->GetCallerRecord(); + } + return MoveAbilityToBackgroundLocked(abilityRecord, callerAbilityRecord); +} + int MissionListManager::MoveAbilityToBackground(const std::shared_ptr &abilityRecord) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); @@ -1446,7 +1492,8 @@ int MissionListManager::MoveAbilityToBackground(const std::shared_ptr &abilityRecord) +int MissionListManager::MoveAbilityToBackgroundLocked(const std::shared_ptr &abilityRecord, + const std::shared_ptr &specifiedNextRecord) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); if (abilityRecord == nullptr) { @@ -1459,7 +1506,7 @@ int MissionListManager::MoveAbilityToBackgroundLocked(const std::shared_ptrIsAbilityState(FOREGROUND) || abilityRecord->IsAbilityState(FOREGROUNDING)) { TAG_LOGD(AAFwkTag::ABILITYMGR, "current ability is active"); abilityRecord->SetPendingState(AbilityState::BACKGROUND); - auto nextAbilityRecord = abilityRecord->GetNextAbilityRecord(); + auto nextAbilityRecord = specifiedNextRecord ? specifiedNextRecord : abilityRecord->GetNextAbilityRecord(); if (nextAbilityRecord) { nextAbilityRecord->SetPreAbilityRecord(abilityRecord); #ifdef SUPPORT_SCREEN 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 c6d71a47280..069baacb42f 100644 --- a/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp +++ b/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp @@ -26,6 +26,7 @@ #include "session_manager_lite.h" #include "session/host/include/zidl/session_interface.h" #include "startup_util.h" +#include "ui_extension_utils.h" #ifdef SUPPORT_GRAPHICS #include "ability_first_frame_state_observer_manager.h" #endif @@ -124,7 +125,9 @@ int UIAbilityLifecycleManager::StartUIAbility(AbilityRequest &abilityRequest, sp UpdateAbilityRecordLaunchReason(abilityRequest, uiAbilityRecord); NotifyAbilityToken(uiAbilityRecord->GetToken(), abilityRequest); - AddCallerRecord(abilityRequest, sessionInfo, uiAbilityRecord); + if (!uiAbilityRecord->IsReady() || sessionInfo->isNewWant) { + AddCallerRecord(abilityRequest, sessionInfo, uiAbilityRecord); + } uiAbilityRecord->ProcessForegroundAbility(sessionInfo->callingTokenId, sceneFlag); CheckSpecified(abilityRequest, uiAbilityRecord); SendKeyEvent(abilityRequest); @@ -1134,8 +1137,51 @@ void UIAbilityLifecycleManager::CompleteBackground(const std::shared_ptr currentSessionInfo, - std::shared_ptr abilityRecord) +int32_t UIAbilityLifecycleManager::BackToCallerAbilityWithResult(std::shared_ptr abilityRecord, + int resultCode, const Want *resultWant, int64_t callerRequestCode) +{ + std::lock_guard guard(sessionLock_); + auto requestInfo = StartupUtil::ParseFullRequestCode(callerRequestCode); + TAG_LOGI(AAFwkTag::ABILITYMGR, "pid:%{public}d, backFlag:%{public}d, requestCode:%{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); + abilityRecord->RemoveCallerRequestCode(callerAbilityRecord, requestInfo.requestCode); + if (!requestInfo.backFlag) { + TAG_LOGW(AAFwkTag::ABILITYMGR, "Not support back to caller"); + return ERR_NOT_SUPPORT_BACK_TO_CALLER; + } + if (callerAbilityRecord == abilityRecord) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "caller is self"); + return ERR_OK; + } + auto tokenId = abilityRecord->GetAbilityInfo().applicationInfo.accessTokenId; + TAG_LOGD(AAFwkTag::ABILITYMGR, "tokenId: %{public}d.", tokenId); + if (!abilityRecord->IsForeground() && !abilityRecord->GetAbilityForegroundingFlag() && + !PermissionVerification::GetInstance()->VerifyPermissionByTokenId(tokenId, + PermissionConstants::PERMISSION_START_ABILITIES_FROM_BACKGROUND)) { + TAG_LOGW(AAFwkTag::ABILITYMGR, "can't start ability from background."); + return CHECK_PERMISSION_FAILED; + } + // find host of UI Extension + if (UIExtensionUtils::IsUIExtension(callerAbilityRecord->GetAbilityInfo().extensionAbilityType)) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "caller is uiExtension."); + callerAbilityRecord = callerAbilityRecord->GetCallerRecord(); + } + return BackToCallerAbilityWithResultLocked(abilityRecord->GetSessionInfo(), callerAbilityRecord); +} + +int32_t UIAbilityLifecycleManager::BackToCallerAbilityWithResultLocked(sptr currentSessionInfo, + std::shared_ptr callerAbilityRecord) { TAG_LOGI(AAFwkTag::ABILITYMGR, "called."); if (currentSessionInfo == nullptr || currentSessionInfo->sessionToken == nullptr) { @@ -1143,12 +1189,12 @@ int UIAbilityLifecycleManager::BackToCallerAbilityWithResult(sptr c return ERR_INVALID_VALUE; } - if (abilityRecord == nullptr) { + if (callerAbilityRecord == nullptr) { TAG_LOGI(AAFwkTag::ABILITYMGR, "callerAbility is invalid."); return ERR_INVALID_VALUE; } - auto callerSessionInfo = abilityRecord->GetSessionInfo(); + auto callerSessionInfo = callerAbilityRecord->GetSessionInfo(); if (callerSessionInfo == nullptr || callerSessionInfo->sessionToken == nullptr) { TAG_LOGI(AAFwkTag::ABILITYMGR, "callerSessionInfo is invalid."); return ERR_INVALID_VALUE; diff --git a/services/abilitymgr/src/start_ability_utils.cpp b/services/abilitymgr/src/start_ability_utils.cpp index c464e7e8ab6..c343d0013ca 100644 --- a/services/abilitymgr/src/start_ability_utils.cpp +++ b/services/abilitymgr/src/start_ability_utils.cpp @@ -30,9 +30,6 @@ constexpr const char* SCREENSHOT_ABILITY_NAME = "com.huawei.ohos.screenshot.Serv constexpr int32_t ERMS_ISALLOW_RESULTCODE = 10; 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; @@ -335,35 +332,5 @@ 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 diff --git a/utils/server/startup/include/startup_util.h b/utils/server/startup/include/startup_util.h index 29720b1895d..3ade0d0c232 100644 --- a/utils/server/startup/include/startup_util.h +++ b/utils/server/startup/include/startup_util.h @@ -29,6 +29,13 @@ namespace AppExecFwk { enum class ExtensionAbilityType; } // namespace AppExecFwk namespace AbilityRuntime { + +struct CallerRequestInfo { + int32_t requestCode = 0; + int32_t pid = 0; + bool backFlag = false; +}; + class StartupUtil { public: static bool GetAppIndex(const AAFwk::Want &want, int32_t &appIndex); @@ -36,6 +43,8 @@ public: static bool IsSupportAppClone(AppExecFwk::ExtensionAbilityType type); static void InitAbilityInfoFromExtension(AppExecFwk::ExtensionAbilityInfo &extensionInfo, AppExecFwk::AbilityInfo &abilityInfo); + static int64_t GenerateFullRequestCode(int32_t pid, bool backFlag, int32_t requestCode); + static CallerRequestInfo ParseFullRequestCode(int64_t fullRequestCode); }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/utils/server/startup/src/startup_util.cpp b/utils/server/startup/src/startup_util.cpp index 0560d8f4c8b..bd2ee63d125 100644 --- a/utils/server/startup/src/startup_util.cpp +++ b/utils/server/startup/src/startup_util.cpp @@ -22,6 +22,12 @@ #include "want.h" namespace OHOS::AbilityRuntime { +namespace { +constexpr int32_t REQUEST_CODE_LENGTH = 32; +constexpr int32_t PID_LENGTH = 16; +constexpr int32_t REQUEST_CODE_PID_LENGTH = 48; +constexpr int32_t VALID_REQUEST_CODE_LENGTH = 49; +} bool StartupUtil::GetAppIndex(const AAFwk::Want &want, int32_t &appIndex) { appIndex = want.GetIntParam(ServerConstant::DLP_INDEX, 0); @@ -89,4 +95,38 @@ void StartupUtil::InitAbilityInfoFromExtension(AppExecFwk::ExtensionAbilityInfo abilityInfo.hapPath = extensionInfo.hapPath; } } + +int64_t StartupUtil::GenerateFullRequestCode(int32_t pid, bool backFlag, int32_t requestCode) +{ + if (requestCode <= 0 || pid <= 0) { + return 0; + } + uint64_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 StartupUtil::ParseFullRequestCode(int64_t fullRequestCode) +{ + CallerRequestInfo requestInfo; + if (fullRequestCode <= 0) { + return requestInfo; + } + uint64_t tempFullRequestCode = fullRequestCode; + if ((tempFullRequestCode >> VALID_REQUEST_CODE_LENGTH) > 0) { + return requestInfo; + } + uint64_t tempNum = 1; + requestInfo.requestCode = (tempFullRequestCode & ((tempNum << REQUEST_CODE_LENGTH) - 1)); + tempFullRequestCode >>= REQUEST_CODE_LENGTH; + requestInfo.pid = (tempFullRequestCode & ((tempNum << PID_LENGTH) - 1)); + tempFullRequestCode >>= PID_LENGTH; + requestInfo.backFlag = (tempFullRequestCode == 1); + return requestInfo; +} } // namespace OHOS::AbilityRuntime -- Gitee