diff --git a/frameworks/js/napi/js_dialog_session/js_dialog_session_utils.cpp b/frameworks/js/napi/js_dialog_session/js_dialog_session_utils.cpp index f2ce86c3c5..9b1d01a567 100644 --- a/frameworks/js/napi/js_dialog_session/js_dialog_session_utils.cpp +++ b/frameworks/js/napi/js_dialog_session/js_dialog_session_utils.cpp @@ -67,6 +67,10 @@ napi_value WrapDialogAbilityInfo(napi_env env, const AAFwk::DialogAbilityInfo &d SetPropertyValueByPropertyName(env, jsObject, "abilityLabelId", jsValue); jsValue = WrapBoolToJS(env, dialogAbilityInfo.visible); SetPropertyValueByPropertyName(env, jsObject, "visible", jsValue); + jsValue = WrapInt32ToJS(env, dialogAbilityInfo.appIndex); + SetPropertyValueByPropertyName(env, jsObject, "appIndex", jsValue); + jsValue = WrapMultiAppModeData(env, dialogAbilityInfo.multiAppMode); + SetPropertyValueByPropertyName(env, jsObject, "multiAppMode", jsValue); return jsObject; } @@ -89,5 +93,20 @@ napi_value WrapDialogSessionInfo(napi_env env, const AAFwk::DialogSessionInfo &d return jsObject; } + +napi_value WrapMultiAppModeData(napi_env env, const AppExecFwk::MultiAppModeData &multiAppMode) +{ + napi_value jsObject = nullptr; + napi_value jsValue = nullptr; + NAPI_CALL(env, napi_create_object(env, &jsObject)); + + jsValue = WrapInt32ToJS(env, static_cast(multiAppMode.multiAppModeType)); + SetPropertyValueByPropertyName(env, jsObject, "multiAppModeType", jsValue); + + jsValue = WrapInt32ToJS(env, static_cast(multiAppMode.maxCount)); + SetPropertyValueByPropertyName(env, jsObject, "maxCount", jsValue); + + return jsObject; +} } // namespace AbilityRuntime } // nampspace OHOS diff --git a/frameworks/js/napi/js_dialog_session/js_dialog_session_utils.h b/frameworks/js/napi/js_dialog_session/js_dialog_session_utils.h index 81984a9569..a7932e032b 100644 --- a/frameworks/js/napi/js_dialog_session/js_dialog_session_utils.h +++ b/frameworks/js/napi/js_dialog_session/js_dialog_session_utils.h @@ -30,6 +30,7 @@ namespace AppExecFwk { napi_value WrapArrayDialogAbilityInfoToJS(napi_env env, const std::vector &value); napi_value WrapDialogSessionInfo(napi_env env, const AAFwk::DialogSessionInfo &dialogSessionInfo); napi_value WrapDialogAbilityInfo(napi_env env, const AAFwk::DialogAbilityInfo &dialogAbilityInfo); +napi_value WrapMultiAppModeData(napi_env env, const AppExecFwk::MultiAppModeData &multiAppMode); } // namespace AppExecFwk } // namespace OHOS #endif // OHOS_ABILITY_RUNTIME_JS_DIALOG_SESSION_UTILS_H diff --git a/frameworks/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.cpp b/frameworks/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.cpp index ade080cba5..5871f802d0 100644 --- a/frameworks/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.cpp +++ b/frameworks/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.cpp @@ -866,5 +866,19 @@ ErrCode BundleMgrHelper::QueryCloneExtensionAbilityInfoWithAppIndex(const Elemen return bundleMgr->QueryCloneExtensionAbilityInfoWithAppIndex(element, flags, appCloneIndex, extensionInfo, userId); } +ErrCode BundleMgrHelper::GetCloneAppIndexes(const std::string &bundleName, std::vector &appIndexes, + int32_t userId) +{ + TAG_LOGD(AAFwkTag::BUNDLEMGRHELPER, "Called."); + auto bundleMgr = Connect(); + if (bundleMgr == nullptr) { + TAG_LOGE(AAFwkTag::BUNDLEMGRHELPER, "Failed to connect."); + return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR; + } + + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + return bundleMgr->GetCloneAppIndexes(bundleName, appIndexes, userId); +} + } // namespace AppExecFwk } // namespace OHOS \ No newline at end of file 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 a8e19e2fb9..b889cc7a45 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_client.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_client.h @@ -1034,7 +1034,7 @@ public: void UpdateMissionSnapShot(sptr token, std::shared_ptr pixelMap); - ErrCode GetDialogSessionInfo(const std::string dialogSessionId, sptr &info); + ErrCode GetDialogSessionInfo(const std::string &dialogSessionId, sptr &info); ErrCode SendDialogResult(const Want &want, const std::string &dialogSessionId, bool isAllow); #endif 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 f69c47c729..d1d5f4f3f5 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h @@ -936,7 +936,7 @@ public: return 0; } - virtual int GetDialogSessionInfo(const std::string dialogSessionId, sptr &dialogSessionInfo) + virtual int GetDialogSessionInfo(const std::string &dialogSessionId, sptr &dialogSessionInfo) { return 0; } diff --git a/interfaces/inner_api/ability_manager/include/dialog_session_info.h b/interfaces/inner_api/ability_manager/include/dialog_session_info.h index fc6f550944..af2b7303cf 100644 --- a/interfaces/inner_api/ability_manager/include/dialog_session_info.h +++ b/interfaces/inner_api/ability_manager/include/dialog_session_info.h @@ -19,6 +19,7 @@ #include #include +#include "application_info.h" #include "json_serializer.h" #include "parcel.h" #include "refbase.h" @@ -35,6 +36,8 @@ struct DialogAbilityInfo { int32_t abilityIconId = 0; int32_t abilityLabelId = 0; bool visible = true; + int32_t appIndex = 0; + AppExecFwk::MultiAppModeData multiAppMode; std::string GetURI() const; bool ParseURI(const std::string &uri); diff --git a/interfaces/kits/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.h b/interfaces/kits/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.h index a7b8f81e58..c5082b7feb 100644 --- a/interfaces/kits/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.h +++ b/interfaces/kits/native/appkit/ability_bundle_manager_helper/bundle_mgr_helper.h @@ -99,6 +99,7 @@ public: BundleInfo &bundleInfo, int32_t userId); ErrCode QueryCloneExtensionAbilityInfoWithAppIndex(const ElementName &element, int32_t flags, int32_t appCloneIndex, ExtensionAbilityInfo &extensionInfo, int32_t userId); + ErrCode GetCloneAppIndexes(const std::string &bundleName, std::vector &appIndexes, int32_t userId); private: sptr Connect(); diff --git a/services/abilitymgr/include/ability_manager_proxy.h b/services/abilitymgr/include/ability_manager_proxy.h index 865312904e..c561cee2ff 100644 --- a/services/abilitymgr/include/ability_manager_proxy.h +++ b/services/abilitymgr/include/ability_manager_proxy.h @@ -728,7 +728,7 @@ public: virtual int PrepareTerminateAbility( const sptr &token, sptr &callback) override; - virtual int GetDialogSessionInfo(const std::string dialogSessionId, sptr &info) override; + virtual int GetDialogSessionInfo(const std::string &dialogSessionId, sptr &info) override; virtual int SendDialogResult(const Want &want, const std::string &dialogSessionId, bool isAllow) override; diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index 3367d69076..e702ab45c8 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -1136,11 +1136,13 @@ public: void HandleUnfocused(const sptr &focusChangeInfo); - virtual int GetDialogSessionInfo(const std::string dialogSessionId, + virtual int GetDialogSessionInfo(const std::string &dialogSessionId, sptr &dialogSessionInfo) override; virtual int SendDialogResult(const Want &want, const std::string &dialogSessionId, bool isAllowed) override; + int CreateCloneSelectorDialog(AbilityRequest &request, int32_t userId, const std::string &replaceWantString = ""); + virtual int RegisterAbilityFirstFrameStateObserver(const sptr &observer, const std::string &bundleName) override; diff --git a/services/abilitymgr/include/dialog_session/dialog_session_manager.h b/services/abilitymgr/include/dialog_session/dialog_session_manager.h index 5e26da4165..ba8f1c4d4f 100644 --- a/services/abilitymgr/include/dialog_session/dialog_session_manager.h +++ b/services/abilitymgr/include/dialog_session/dialog_session_manager.h @@ -38,37 +38,61 @@ struct DialogCallerInfo { bool isSelector = false; }; +enum class SelectorType { + IMPLICIT_START_SELECTOR = 0, + APP_CLONR_SELECTOR = 1 +}; + class DialogSessionManager { public: static DialogSessionManager &GetInstance(); ~DialogSessionManager() = default; - sptr GetDialogSessionInfo(const std::string dialogSessionId) const; + sptr GetDialogSessionInfo(const std::string &dialogSessionId) const; - std::shared_ptr GetDialogCallerInfo(const std::string dialogSessionId) const; + std::shared_ptr GetDialogCallerInfo(const std::string &dialogSessionId) const; int SendDialogResult(const Want &want, const std::string &dialogSessionId, bool isAllowed); int CreateJumpModalDialog(AbilityRequest &abilityRequest, int32_t userId, const Want &replaceWant); - int CreateSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want, int32_t userId, + int CreateImplicitSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want, int32_t userId, std::vector &dialogAppInfos); + int CreateCloneSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want, int32_t userId, + std::vector &dialogAppInfos, const std::string &replaceWant); + + int HandleErmsResult(AbilityRequest &abilityRequest, int32_t userId, const Want &replaceWant); + + bool IsCreateCloneSelectorDialog(const std::string &bundleName, int32_t userId); + private: DialogSessionManager() = default; std::string GenerateDialogSessionId(); - void SetDialogSessionInfo(const std::string dialogSessionId, sptr &dilogSessionInfo, + void SetDialogSessionInfo(const std::string &dialogSessionId, sptr &dilogSessionInfo, std::shared_ptr &dialogCallerInfo); - void ClearDialogContext(const std::string dialogSessionId); + void ClearDialogContext(const std::string &dialogSessionId); void ClearAllDialogContexts(); - bool GenerateDialogSessionRecord(AbilityRequest &abilityRequest, int32_t userId, - std::string &dialogSessionId, std::vector &dialogAppInfos, bool isSelector); + std::string GenerateDialogSessionRecordCommon(AbilityRequest &abilityRequest, int32_t userId, + const AAFwk::WantParams ¶meters, std::vector &dialogAppInfos, bool isSelector); - int CreateModalDialogCommon(const Want &replaceWant, sptr callerToken, std::string dialogSessionId); + void GenerateCallerAbilityInfo(AbilityRequest &abilityRequest, DialogAbilityInfo &callerAbilityInfo); + + void GenerateSelectorTargetAbilityInfos(std::vector &dialogAppInfos, + std::vector &targetAbilityInfos); + + void GenerateJumpTargetAbilityInfos(AbilityRequest &abilityRequest, + std::vector &targetAbilityInfos); + + void GenerateDialogCallerInfo(AbilityRequest &abilityRequest, int32_t userId, + std::shared_ptr dialogCallerInfo, bool isSelector); + + int CreateModalDialogCommon(const Want &replaceWant, sptr callerToken, + const std::string &dialogSessionId); mutable ffrt::mutex dialogSessionRecordLock_; std::unordered_map> dialogSessionInfoMap_; diff --git a/services/abilitymgr/include/ecological_rule/ability_ecological_rule_mgr_service_param.h b/services/abilitymgr/include/ecological_rule/ability_ecological_rule_mgr_service_param.h index a49f530125..6214fe5836 100644 --- a/services/abilitymgr/include/ecological_rule/ability_ecological_rule_mgr_service_param.h +++ b/services/abilitymgr/include/ecological_rule/ability_ecological_rule_mgr_service_param.h @@ -28,7 +28,7 @@ namespace EcologicalRuleMgrService { using Want = OHOS::AAFwk::Want; struct AbilityExperienceRule : public Parcelable { - bool isAllow = true; + int32_t resultCode = 10; std::string sceneCode = ""; sptr replaceWant = nullptr; diff --git a/services/abilitymgr/include/implicit_start_processor.h b/services/abilitymgr/include/implicit_start_processor.h index e28eefac21..697cdf804d 100644 --- a/services/abilitymgr/include/implicit_start_processor.h +++ b/services/abilitymgr/include/implicit_start_processor.h @@ -58,7 +58,8 @@ public: static bool IsImplicitStartAction(const Want &want); - int ImplicitStartAbility(AbilityRequest &request, int32_t userId, int32_t windowMode = 0); + int ImplicitStartAbility(AbilityRequest &request, int32_t userId, int32_t windowMode = 0, + const std::string &replaceWantString = "", bool isAppCloneSelector = false); void ResetCallingIdentityAsCaller(int32_t tokenId); @@ -69,6 +70,13 @@ public: private: int GenerateAbilityRequestByAction(int32_t userId, AbilityRequest &request, std::vector &dialogAppInfos, bool isMoreHapList, bool &findDefaultApp); + + int GenerateAbilityRequestByAppIndexes(int32_t userId, AbilityRequest &request, + std::vector &dialogAppInfos); + + int FindExtensionInfo(const Want &want, int32_t flags, int32_t userId, int32_t appIndex, + AppExecFwk::AbilityInfo &abilityInfo); + std::string MatchTypeAndUri(const AAFwk::Want &want); std::shared_ptr GetBundleManagerHelper(); std::vector SplitStr(const std::string& str, char delimiter); diff --git a/services/abilitymgr/include/start_ability_utils.h b/services/abilitymgr/include/start_ability_utils.h index a0db5eeb9b..0ad2487d01 100644 --- a/services/abilitymgr/include/start_ability_utils.h +++ b/services/abilitymgr/include/start_ability_utils.h @@ -53,6 +53,7 @@ struct StartAbilityUtils { static bool GetCallerAbilityInfo(const sptr &callerToken, 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 bool IsCallFromAncoShellOrBroker(const sptr &callerToken); @@ -61,6 +62,8 @@ struct StartAbilityUtils { static thread_local bool skipCrowTest; static thread_local bool skipStartOther; static thread_local bool skipErms; + static thread_local int32_t ermsResultCode; + static thread_local bool isWantWithAppCloneIndex; }; struct StartAbilityInfoWrap { diff --git a/services/abilitymgr/include/system_dialog_scheduler.h b/services/abilitymgr/include/system_dialog_scheduler.h index 39254c47ca..06d3662509 100644 --- a/services/abilitymgr/include/system_dialog_scheduler.h +++ b/services/abilitymgr/include/system_dialog_scheduler.h @@ -17,6 +17,7 @@ #include +#include "application_info.h" #include "bundle_mgr_interface.h" #include "singleton.h" @@ -59,6 +60,8 @@ struct DialogAppInfo { std::string abilityName = {}; std::string moduleName = {}; bool visible = true; + int32_t appIndex = 0; + AppExecFwk::MultiAppModeData multiAppMode; }; /** * @class SystemDialogScheduler diff --git a/services/abilitymgr/src/ability_manager_client.cpp b/services/abilitymgr/src/ability_manager_client.cpp index 3391c4b05f..22e8d694e4 100644 --- a/services/abilitymgr/src/ability_manager_client.cpp +++ b/services/abilitymgr/src/ability_manager_client.cpp @@ -1330,7 +1330,7 @@ ErrCode AbilityManagerClient::PrepareTerminateAbility(sptr token, return abms->PrepareTerminateAbility(token, callback); } -ErrCode AbilityManagerClient::GetDialogSessionInfo(const std::string dialogSessionId, sptr &info) +ErrCode AbilityManagerClient::GetDialogSessionInfo(const std::string &dialogSessionId, sptr &info) { auto abms = GetAbilityManager(); CHECK_POINTER_RETURN_NOT_CONNECTED(abms); diff --git a/services/abilitymgr/src/ability_manager_proxy.cpp b/services/abilitymgr/src/ability_manager_proxy.cpp index 077a20c733..758caa021c 100644 --- a/services/abilitymgr/src/ability_manager_proxy.cpp +++ b/services/abilitymgr/src/ability_manager_proxy.cpp @@ -3056,7 +3056,7 @@ int AbilityManagerProxy::PrepareTerminateAbility(const sptr &toke return reply.ReadInt32(); } -int AbilityManagerProxy::GetDialogSessionInfo(const std::string dialogSessionId, sptr &info) +int AbilityManagerProxy::GetDialogSessionInfo(const std::string &dialogSessionId, sptr &info) { MessageParcel data; MessageParcel reply; diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index 4fd38befcb..b29a270420 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -1152,7 +1152,12 @@ int AbilityManagerService::StartAbilityInner(const Want &want, const sptr(abilityRequest.abilityInfo)); result = afterCheckExecuter_ == nullptr ? ERR_INVALID_VALUE : afterCheckExecuter_->DoProcess(afterCheckParam); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "afterCheckExecuter_ is nullptr or DoProcess return error."); + return result; + } if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) { ReportEventToRSS(abilityRequest.abilityInfo, callerToken); abilityRequest.want.SetParam(IS_CALL_BY_SCB, false); @@ -6929,11 +6943,6 @@ int AbilityManagerService::StartAbilityByCall(const Want &want, const sptrResolveLocked(abilityRequest); } @@ -10263,7 +10272,7 @@ int32_t AbilityManagerService::OpenFile(const Uri& uri, uint32_t flag) return collaborator->OpenFile(uri, flag); } #ifdef SUPPORT_SCREEN -int AbilityManagerService::GetDialogSessionInfo(const std::string dialogSessionId, +int AbilityManagerService::GetDialogSessionInfo(const std::string &dialogSessionId, sptr &dialogSessionInfo) { CHECK_CALLER_IS_SYSTEM_APP; @@ -10281,6 +10290,13 @@ int AbilityManagerService::SendDialogResult(const Want &want, const std::string CHECK_CALLER_IS_SYSTEM_APP; return DialogSessionManager::GetInstance().SendDialogResult(want, dialogSessionId, isAllowed); } + +int AbilityManagerService::CreateCloneSelectorDialog(AbilityRequest &request, int32_t userId, + const std::string &replaceWantString) +{ + CHECK_POINTER_AND_RETURN(implicitStartProcessor_, ERR_IMPLICIT_START_ABILITY_FAIL); + return implicitStartProcessor_->ImplicitStartAbility(request, userId, 0, replaceWantString, true); +} #endif // SUPPORT_SCREEN void AbilityManagerService::RemoveLauncherDeathRecipient(int32_t userId) { @@ -11238,9 +11254,13 @@ int AbilityManagerService::StartUIAbilityByPreInstallInner(sptr ses return result; } #ifdef SUPPORT_SCREEN - if (result != ERR_OK && isReplaceWantExist && - callerBundleName != BUNDLE_NAME_DIALOG) { - return DialogSessionManager::GetInstance().CreateJumpModalDialog(abilityRequest, GetUserId(), newWant); + if (result != ERR_OK && isReplaceWantExist && callerBundleName != BUNDLE_NAME_DIALOG) { + return DialogSessionManager::GetInstance().HandleErmsResult(abilityRequest, GetUserId(), newWant); + } + if (result == ERR_OK && + DialogSessionManager::GetInstance().IsCreateCloneSelectorDialog(abilityInfo.bundleName, GetUserId())) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "create clone selector dialog"); + return CreateCloneSelectorDialog(abilityRequest, GetUserId()); } #endif // SUPPORT_SCREEN diff --git a/services/abilitymgr/src/dialog_session/dialog_session_info.cpp b/services/abilitymgr/src/dialog_session/dialog_session_info.cpp index 80ca9e2ae5..b1fd746cea 100644 --- a/services/abilitymgr/src/dialog_session/dialog_session_info.cpp +++ b/services/abilitymgr/src/dialog_session/dialog_session_info.cpp @@ -24,14 +24,16 @@ namespace OHOS { namespace AAFwk { constexpr int32_t CYCLE_LIMIT = 1000; -constexpr size_t MEMBER_NUM = 8; +constexpr size_t MEMBER_NUM = 11; std::string DialogAbilityInfo::GetURI() const { return bundleName + "/" + moduleName + "/" + abilityName + "/" + std::to_string(bundleIconId) + "/" + std::to_string(bundleLabelId) + "/" + std::to_string(abilityIconId) + "/" + std::to_string(abilityLabelId) + "/" + - std::to_string(visible); + std::to_string(visible) + "/" + std::to_string(appIndex) + "/" + + std::to_string(static_cast(multiAppMode.multiAppModeType)) + "/" + + std::to_string(multiAppMode.maxCount); } bool DialogAbilityInfo::ParseURI(const std::string &uri) @@ -54,6 +56,9 @@ bool DialogAbilityInfo::ParseURI(const std::string &uri) abilityIconId = static_cast(std::stoi(uriVec[index++])); abilityLabelId = static_cast(std::stoi(uriVec[index++])); visible = std::stoi(uriVec[index++]); + appIndex = static_cast(std::stoi(uriVec[index++])); + multiAppMode.multiAppModeType = static_cast(std::stoi(uriVec[index++])); + multiAppMode.maxCount = static_cast(std::stoi(uriVec[index++])); return true; } diff --git a/services/abilitymgr/src/dialog_session/dialog_session_manager.cpp b/services/abilitymgr/src/dialog_session/dialog_session_manager.cpp index 4af1a0344c..5c9be3ad27 100644 --- a/services/abilitymgr/src/dialog_session/dialog_session_manager.cpp +++ b/services/abilitymgr/src/dialog_session/dialog_session_manager.cpp @@ -26,7 +26,9 @@ #include "int_wrapper.h" #include "modal_system_ui_extension.h" #include "parameters.h" +#include "start_ability_utils.h" #include "string_wrapper.h" +#include "want.h" #include "want_params_wrapper.h" namespace OHOS { @@ -34,6 +36,7 @@ namespace AAFwk { using OHOS::AppExecFwk::BundleInfo; namespace { constexpr const char* UIEXTENSION_MODAL_TYPE = "ability.want.params.modalType"; +constexpr int32_t ERMS_ISALLOW_RESULTCODE = 10; constexpr const char* SUPPORT_CLOSE_ON_BLUR = "supportCloseOnBlur"; } @@ -63,7 +66,7 @@ std::string DialogSessionManager::GenerateDialogSessionId() return dialogSessionId; } -void DialogSessionManager::SetDialogSessionInfo(const std::string dialogSessionId, +void DialogSessionManager::SetDialogSessionInfo(const std::string &dialogSessionId, sptr &dilogSessionInfo, std::shared_ptr &dialogCallerInfo) { std::lock_guard guard(dialogSessionRecordLock_); @@ -71,7 +74,7 @@ void DialogSessionManager::SetDialogSessionInfo(const std::string dialogSessionI dialogCallerInfoMap_[dialogSessionId] = dialogCallerInfo; } -sptr DialogSessionManager::GetDialogSessionInfo(const std::string dialogSessionId) const +sptr DialogSessionManager::GetDialogSessionInfo(const std::string &dialogSessionId) const { std::lock_guard guard(dialogSessionRecordLock_); auto it = dialogSessionInfoMap_.find(dialogSessionId); @@ -82,7 +85,7 @@ sptr DialogSessionManager::GetDialogSessionInfo(const std::st return nullptr; } -std::shared_ptr DialogSessionManager::GetDialogCallerInfo(const std::string dialogSessionId) const +std::shared_ptr DialogSessionManager::GetDialogCallerInfo(const std::string &dialogSessionId) const { std::lock_guard guard(dialogSessionRecordLock_); auto it = dialogCallerInfoMap_.find(dialogSessionId); @@ -93,7 +96,7 @@ std::shared_ptr DialogSessionManager::GetDialogCallerInfo(cons return nullptr; } -void DialogSessionManager::ClearDialogContext(const std::string dialogSessionId) +void DialogSessionManager::ClearDialogContext(const std::string &dialogSessionId) { std::lock_guard guard(dialogSessionRecordLock_); auto it = dialogSessionInfoMap_.find(dialogSessionId); @@ -114,26 +117,29 @@ void DialogSessionManager::ClearAllDialogContexts() dialogCallerInfoMap_.clear(); } -bool DialogSessionManager::GenerateDialogSessionRecord(AbilityRequest &abilityRequest, int32_t userId, - std::string &dialogSessionId, std::vector &dialogAppInfos, bool isSelector) +void DialogSessionManager::GenerateCallerAbilityInfo(AbilityRequest &abilityRequest, + DialogAbilityInfo &callerAbilityInfo) { - HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); - auto dialogSessionInfo = sptr::MakeSptr(); - CHECK_POINTER_AND_RETURN(dialogSessionInfo, ERR_INVALID_VALUE); sptr callerToken = abilityRequest.callerToken; if (callerToken != nullptr) { auto callerRecord = Token::GetAbilityRecordByToken(callerToken); - CHECK_POINTER_AND_RETURN(callerRecord, ERR_INVALID_VALUE); - dialogSessionInfo->callerAbilityInfo.bundleName = callerRecord->GetAbilityInfo().bundleName; - dialogSessionInfo->callerAbilityInfo.moduleName = callerRecord->GetAbilityInfo().moduleName; - dialogSessionInfo->callerAbilityInfo.abilityName = callerRecord->GetAbilityInfo().name; - dialogSessionInfo->callerAbilityInfo.abilityIconId = callerRecord->GetAbilityInfo().iconId; - dialogSessionInfo->callerAbilityInfo.abilityLabelId = callerRecord->GetAbilityInfo().labelId; - dialogSessionInfo->callerAbilityInfo.bundleIconId = callerRecord->GetApplicationInfo().iconId; - dialogSessionInfo->callerAbilityInfo.bundleLabelId = callerRecord->GetApplicationInfo().labelId; + CHECK_POINTER(callerRecord); + callerAbilityInfo.bundleName = callerRecord->GetAbilityInfo().bundleName; + callerAbilityInfo.moduleName = callerRecord->GetAbilityInfo().moduleName; + callerAbilityInfo.abilityName = callerRecord->GetAbilityInfo().name; + callerAbilityInfo.abilityIconId = callerRecord->GetAbilityInfo().iconId; + callerAbilityInfo.abilityLabelId = callerRecord->GetAbilityInfo().labelId; + callerAbilityInfo.bundleIconId = callerRecord->GetApplicationInfo().iconId; + callerAbilityInfo.bundleLabelId = callerRecord->GetApplicationInfo().labelId; + callerAbilityInfo.visible = callerRecord->GetAbilityInfo().visible; + callerAbilityInfo.appIndex = callerRecord->GetApplicationInfo().appIndex; + callerAbilityInfo.multiAppMode = callerRecord->GetApplicationInfo().multiAppMode; } - dialogSessionInfo->parameters.SetParam("deviceType", AAFwk::String::Box(OHOS::system::GetDeviceType())); - dialogSessionInfo->parameters.SetParam("userId", AAFwk::Integer::Box(userId)); +} + +void DialogSessionManager::GenerateSelectorTargetAbilityInfos(std::vector &dialogAppInfos, + std::vector &targetAbilityInfos) +{ for (auto &dialogAppInfo : dialogAppInfos) { DialogAbilityInfo targetDialogAbilityInfo; targetDialogAbilityInfo.bundleName = dialogAppInfo.bundleName; @@ -144,22 +150,39 @@ bool DialogSessionManager::GenerateDialogSessionRecord(AbilityRequest &abilityRe targetDialogAbilityInfo.bundleIconId = dialogAppInfo.bundleIconId; targetDialogAbilityInfo.bundleLabelId = dialogAppInfo.bundleLabelId; targetDialogAbilityInfo.visible = dialogAppInfo.visible; - dialogSessionInfo->targetAbilityInfos.emplace_back(targetDialogAbilityInfo); + targetDialogAbilityInfo.appIndex = dialogAppInfo.appIndex; + targetDialogAbilityInfo.multiAppMode = dialogAppInfo.multiAppMode; + targetAbilityInfos.emplace_back(targetDialogAbilityInfo); } - std::shared_ptr dialogCallerInfo = std::make_shared(); - if (isSelector) { - dialogSessionInfo->parameters.SetParam("action", AAFwk::String::Box(abilityRequest.want.GetAction())); - dialogSessionInfo->parameters.SetParam("wantType", AAFwk::String::Box(abilityRequest.want.GetType())); - dialogSessionInfo->parameters.SetParam("uri", AAFwk::String::Box(abilityRequest.want.GetUriString())); - dialogCallerInfo->isSelector = true; - } - dialogCallerInfo->callerToken = callerToken; +} + +void DialogSessionManager::GenerateJumpTargetAbilityInfos(AbilityRequest &abilityRequest, + std::vector &targetAbilityInfos) +{ + DialogAbilityInfo targetDialogAbilityInfo; + targetDialogAbilityInfo.bundleName = abilityRequest.abilityInfo.bundleName; + targetDialogAbilityInfo.moduleName = abilityRequest.abilityInfo.moduleName; + targetDialogAbilityInfo.abilityName = abilityRequest.abilityInfo.name; + targetDialogAbilityInfo.abilityIconId = abilityRequest.abilityInfo.iconId; + targetDialogAbilityInfo.abilityLabelId = abilityRequest.abilityInfo.labelId; + targetDialogAbilityInfo.bundleIconId = abilityRequest.abilityInfo.applicationInfo.iconId; + targetDialogAbilityInfo.bundleLabelId = abilityRequest.abilityInfo.applicationInfo.labelId; + targetDialogAbilityInfo.visible = abilityRequest.abilityInfo.visible; + targetDialogAbilityInfo.appIndex = abilityRequest.abilityInfo.applicationInfo.appIndex; + targetDialogAbilityInfo.multiAppMode = abilityRequest.abilityInfo.applicationInfo.multiAppMode; + targetAbilityInfos.emplace_back(targetDialogAbilityInfo); +} + +void DialogSessionManager::GenerateDialogCallerInfo(AbilityRequest &abilityRequest, int32_t userId, + std::shared_ptr dialogCallerInfo, bool isSelector) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + CHECK_POINTER(dialogCallerInfo); + dialogCallerInfo->isSelector = isSelector; + dialogCallerInfo->callerToken = abilityRequest.callerToken; dialogCallerInfo->requestCode = abilityRequest.requestCode; dialogCallerInfo->targetWant = abilityRequest.want; dialogCallerInfo->userId = userId; - dialogSessionId = GenerateDialogSessionId(); - SetDialogSessionInfo(dialogSessionId, dialogSessionInfo, dialogCallerInfo); - return true; } int DialogSessionManager::SendDialogResult(const Want &want, const std::string &dialogSessionId, bool isAllowed) @@ -179,6 +202,10 @@ int DialogSessionManager::SendDialogResult(const Want &want, const std::string & targetWant.SetElement(want.GetElement()); targetWant.SetParam("isSelector", dialogCallerInfo->isSelector); targetWant.SetParam("dialogSessionId", dialogSessionId); + if (want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY)) { + int32_t appIndex = want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0); + targetWant.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, appIndex); + } sptr callerToken = dialogCallerInfo->callerToken; auto abilityMgr = DelayedSingleton::GetInstance(); if (!abilityMgr) { @@ -193,39 +220,105 @@ int DialogSessionManager::SendDialogResult(const Want &want, const std::string & return ret; } +std::string DialogSessionManager::GenerateDialogSessionRecordCommon(AbilityRequest &abilityRequest, int32_t userId, + const AAFwk::WantParams ¶meters, std::vector &dialogAppInfos, bool isSelector) +{ + auto dialogSessionInfo = sptr::MakeSptr(); + CHECK_POINTER_AND_RETURN(dialogSessionInfo, ""); + + GenerateCallerAbilityInfo(abilityRequest, dialogSessionInfo->callerAbilityInfo); + + if (isSelector) { + GenerateSelectorTargetAbilityInfos(dialogAppInfos, dialogSessionInfo->targetAbilityInfos); + } else { + GenerateJumpTargetAbilityInfos(abilityRequest, dialogSessionInfo->targetAbilityInfos); + } + + dialogSessionInfo->parameters = parameters; + + std::shared_ptr dialogCallerInfo = std::make_shared(); + GenerateDialogCallerInfo(abilityRequest, userId, dialogCallerInfo, isSelector); + + std::string dialogSessionId = GenerateDialogSessionId(); + SetDialogSessionInfo(dialogSessionId, dialogSessionInfo, dialogCallerInfo); + + return dialogSessionId; +} + int DialogSessionManager::CreateJumpModalDialog(AbilityRequest &abilityRequest, int32_t userId, const Want &replaceWant) { - std::string dialogSessionId; - std::vector dialogAppInfos(1); - dialogAppInfos.front().bundleName = abilityRequest.abilityInfo.bundleName; - dialogAppInfos.front().moduleName = abilityRequest.abilityInfo.moduleName; - dialogAppInfos.front().abilityName = abilityRequest.abilityInfo.name; - dialogAppInfos.front().abilityIconId = abilityRequest.abilityInfo.iconId; - dialogAppInfos.front().abilityLabelId = abilityRequest.abilityInfo.labelId; - dialogAppInfos.front().bundleIconId = abilityRequest.abilityInfo.applicationInfo.iconId; - dialogAppInfos.front().bundleLabelId = abilityRequest.abilityInfo.applicationInfo.labelId; - if (!GenerateDialogSessionRecord(abilityRequest, userId, dialogSessionId, dialogAppInfos, false)) { + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + + AAFwk::WantParams parameters; + + parameters.SetParam("deviceType", AAFwk::String::Box(OHOS::system::GetDeviceType())); + parameters.SetParam("userId", AAFwk::Integer::Box(userId)); + + std::vector dialogAppInfos; + std::string dialogSessionId = GenerateDialogSessionRecordCommon(abilityRequest, userId, parameters, + dialogAppInfos, false); + if (dialogSessionId == "") { TAG_LOGE(AAFwkTag::ABILITYMGR, "generate dialog session record failed"); - return INNER_ERR; + return ERR_INVALID_VALUE; } + return CreateModalDialogCommon(replaceWant, abilityRequest.callerToken, dialogSessionId); } -int DialogSessionManager::CreateSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want, int32_t userId, - std::vector &dialogAppInfos) +int DialogSessionManager::CreateImplicitSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want, + int32_t userId, std::vector &dialogAppInfos) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); - std::string dialogSessionId; - if (!GenerateDialogSessionRecord(abilityRequest, userId, dialogSessionId, dialogAppInfos, true)) { + + AAFwk::Want sessionWant; + + sessionWant.SetParam("deviceType", OHOS::system::GetDeviceType()); + sessionWant.SetParam("userId", userId); + sessionWant.SetParam("action", abilityRequest.want.GetAction()); + sessionWant.SetParam("wantType", abilityRequest.want.GetType()); + sessionWant.SetParam("uri", abilityRequest.want.GetUriString()); + sessionWant.SetParam("entities", abilityRequest.want.GetEntities()); + sessionWant.SetParam("appselector.selectorType", static_cast(SelectorType::IMPLICIT_START_SELECTOR)); + bool showCaller = abilityRequest.want.GetBoolParam("showcaller", false); + sessionWant.SetParam("showCaller", showCaller); + + std::string dialogSessionId = GenerateDialogSessionRecordCommon(abilityRequest, userId, sessionWant.GetParams(), + dialogAppInfos, true); + if (dialogSessionId == "") { TAG_LOGE(AAFwkTag::ABILITYMGR, "generate dialog session record failed"); - return INNER_ERR; + return ERR_INVALID_VALUE; } + + return CreateModalDialogCommon(want, abilityRequest.callerToken, dialogSessionId); +} + +int DialogSessionManager::CreateCloneSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want, + int32_t userId, std::vector &dialogAppInfos, const std::string &replaceWant) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + AAFwk::WantParams parameters; + + parameters.SetParam("deviceType", AAFwk::String::Box(OHOS::system::GetDeviceType())); + parameters.SetParam("userId", AAFwk::Integer::Box(userId)); + parameters.SetParam("appselector.selectorType", + AAFwk::Integer::Box(static_cast(SelectorType::APP_CLONR_SELECTOR))); + if (replaceWant != "") { + parameters.SetParam("replaceWant", AAFwk::String::Box(replaceWant)); + } + + std::string dialogSessionId = GenerateDialogSessionRecordCommon(abilityRequest, userId, parameters, + dialogAppInfos, true); + if (dialogSessionId == "") { + TAG_LOGE(AAFwkTag::ABILITYMGR, "generate dialog session record failed"); + return ERR_INVALID_VALUE; + } + return CreateModalDialogCommon(want, abilityRequest.callerToken, dialogSessionId); } int DialogSessionManager::CreateModalDialogCommon(const Want &replaceWant, sptr callerToken, - std::string dialogSessionId) + const std::string &dialogSessionId) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); (const_cast(replaceWant)).SetParam("dialogSessionId", dialogSessionId); @@ -265,5 +358,36 @@ int DialogSessionManager::CreateModalDialogCommon(const Want &replaceWant, sptr< (const_cast(replaceWant)).SetParam(SUPPORT_CLOSE_ON_BLUR, true); return connection->CreateModalUIExtension(replaceWant) ? ERR_OK : INNER_ERR; } + +int DialogSessionManager::HandleErmsResult(AbilityRequest &abilityRequest, int32_t userId, + const Want &replaceWant) +{ + std::string bundleName = abilityRequest.abilityInfo.bundleName; + if (StartAbilityUtils::ermsResultCode < ERMS_ISALLOW_RESULTCODE || + !IsCreateCloneSelectorDialog(bundleName, userId)) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "create jump modal dialog"); + return CreateJumpModalDialog(abilityRequest, userId, replaceWant); + } + auto abilityMgr = DelayedSingleton::GetInstance(); + if (!abilityMgr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityMgr is nullptr."); + return INNER_ERR; + } + return abilityMgr->CreateCloneSelectorDialog(abilityRequest, userId, replaceWant.ToString()); +} + +bool DialogSessionManager::IsCreateCloneSelectorDialog(const std::string &bundleName, int32_t userId) +{ + if (StartAbilityUtils::isWantWithAppCloneIndex) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "want with app clone index."); + return false; + } + auto appIndexes = StartAbilityUtils::GetCloneAppIndexes(bundleName, userId); + if (appIndexes.empty()) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "The application do not create clone index."); + return false; + } + return true; +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/ecological_rule/ability_ecological_rule_mgr_service.cpp b/services/abilitymgr/src/ecological_rule/ability_ecological_rule_mgr_service.cpp index 39d1379431..626227843a 100644 --- a/services/abilitymgr/src/ecological_rule/ability_ecological_rule_mgr_service.cpp +++ b/services/abilitymgr/src/ecological_rule/ability_ecological_rule_mgr_service.cpp @@ -144,8 +144,8 @@ int32_t AbilityEcologicalRuleMgrServiceClient::QueryStartExperience(const OHOS:: if (rule.replaceWant != nullptr) { rule.replaceWant->SetParam(ERMS_ORIGINAL_TARGET, want.ToString()); TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, - "queryStart finish: isAllow = %{public}d, sceneCode = %{public}s, replaceWant = %{public}s", rule.isAllow, - rule.sceneCode.c_str(), (*(rule.replaceWant)).ToString().c_str()); + "queryStart finish: resultCode = %{public}d, sceneCode = %{public}s, replaceWant = %{public}s", + rule.resultCode, rule.sceneCode.c_str(), (*(rule.replaceWant)).ToString().c_str()); } int64_t cost = GetCurrentTimeMicro() - start; TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, diff --git a/services/abilitymgr/src/ecological_rule/ability_ecological_rule_mgr_service_param.cpp b/services/abilitymgr/src/ecological_rule/ability_ecological_rule_mgr_service_param.cpp index 5ca1d22fad..e841cbf30f 100644 --- a/services/abilitymgr/src/ecological_rule/ability_ecological_rule_mgr_service_param.cpp +++ b/services/abilitymgr/src/ecological_rule/ability_ecological_rule_mgr_service_param.cpp @@ -34,7 +34,7 @@ AbilityExperienceRule *AbilityExperienceRule::Unmarshalling(Parcel &in) return nullptr; } - if (!in.ReadBool(rule->isAllow)) { + if (!in.ReadInt32(rule->resultCode)) { delete rule; return nullptr; } @@ -51,8 +51,8 @@ AbilityExperienceRule *AbilityExperienceRule::Unmarshalling(Parcel &in) bool AbilityExperienceRule::Marshalling(Parcel &parcel) const { - if (!parcel.WriteBool(isAllow)) { - TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write isAllow failed"); + if (!parcel.WriteInt32(resultCode)) { + TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write resultCode failed"); return false; } diff --git a/services/abilitymgr/src/implicit_start_processor.cpp b/services/abilitymgr/src/implicit_start_processor.cpp index 15a2ad272e..16ded7359a 100644 --- a/services/abilitymgr/src/implicit_start_processor.cpp +++ b/services/abilitymgr/src/implicit_start_processor.cpp @@ -25,12 +25,14 @@ #include "errors.h" #include "ecological_rule/ability_ecological_rule_mgr_service.h" #include "event_report.h" +#include "global_constant.h" #include "hilog_tag_wrapper.h" #include "hitrace_meter.h" #include "in_process_call_wrapper.h" #include "parameters.h" #include "scene_board_judgement.h" #include "start_ability_utils.h" +#include "startup_util.h" #include "want.h" namespace OHOS { @@ -86,7 +88,8 @@ bool ImplicitStartProcessor::IsImplicitStartAction(const Want &want) return false; } -int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_t userId, int32_t windowMode) +int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_t userId, int32_t windowMode, + const std::string &replaceWantString, bool isAppCloneSelector) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGI(AAFwkTag::ABILITYMGR, "implicit start ability by type: %{public}d", request.callType); @@ -96,9 +99,14 @@ int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_ std::vector dialogAppInfos; request.want.RemoveParam(APP_CLONE_INDEX); bool findDefaultApp = false; - auto ret = GenerateAbilityRequestByAction(userId, request, dialogAppInfos, false, findDefaultApp); + int32_t ret = ERR_OK; + if (isAppCloneSelector) { + ret = GenerateAbilityRequestByAppIndexes(userId, request, dialogAppInfos); + } else { + ret = GenerateAbilityRequestByAction(userId, request, dialogAppInfos, false, findDefaultApp); + } if (ret != ERR_OK) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "generate ability request by action failed."); + TAG_LOGE(AAFwkTag::ABILITYMGR, "generate ability request failed."); return ret; } AbilityUtil::WantSetParameterWindowMode(request.want, windowMode); @@ -136,7 +144,8 @@ int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_ } if (want.GetBoolParam("isCreateAppGallerySelector", false)) { want.RemoveParam("isCreateAppGallerySelector"); - DialogSessionManager::GetInstance().CreateSelectorModalDialog(request, want, userId, dialogAppInfos); + DialogSessionManager::GetInstance().CreateImplicitSelectorModalDialog(request, want, userId, + dialogAppInfos); return ERR_IMPLICIT_START_ABILITY_FAIL; } TAG_LOGE(AAFwkTag::ABILITYMGR, "implicit query ability infos failed, show tips dialog."); @@ -153,7 +162,8 @@ int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_ } if (want.GetBoolParam("isCreateAppGallerySelector", false)) { want.RemoveParam("isCreateAppGallerySelector"); - DialogSessionManager::GetInstance().CreateSelectorModalDialog(request, want, userId, dialogAppInfos); + DialogSessionManager::GetInstance().CreateImplicitSelectorModalDialog(request, want, userId, + dialogAppInfos); return ERR_IMPLICIT_START_ABILITY_FAIL; } std::vector dialogAllAppInfos; @@ -206,7 +216,12 @@ int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_ } if (want.GetBoolParam("isCreateAppGallerySelector", false)) { want.RemoveParam("isCreateAppGallerySelector"); - return DialogSessionManager::GetInstance().CreateSelectorModalDialog(request, want, userId, dialogAppInfos); + if (isAppCloneSelector) { + return DialogSessionManager::GetInstance().CreateCloneSelectorModalDialog(request, want, + userId, dialogAppInfos, replaceWantString); + } + return DialogSessionManager::GetInstance().CreateImplicitSelectorModalDialog(request, + want, userId, dialogAppInfos); } ret = abilityMgr->ImplicitStartAbilityAsCaller(request.want, request.callerToken, nullptr); // reset calling indentity @@ -225,7 +240,12 @@ int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_ } if (want.GetBoolParam("isCreateAppGallerySelector", false)) { want.RemoveParam("isCreateAppGallerySelector"); - return DialogSessionManager::GetInstance().CreateSelectorModalDialog(request, want, userId, dialogAppInfos); + if (isAppCloneSelector) { + return DialogSessionManager::GetInstance().CreateCloneSelectorModalDialog(request, want, userId, + dialogAppInfos, replaceWantString); + } + return DialogSessionManager::GetInstance().CreateImplicitSelectorModalDialog(request, want, userId, + dialogAppInfos); } ret = abilityMgr->ImplicitStartAbilityAsCaller(request.want, request.callerToken, nullptr); // reset calling indentity @@ -446,12 +466,78 @@ int ImplicitStartProcessor::GenerateAbilityRequestByAction(int32_t userId, dialogAppInfo.bundleIconId = info.applicationInfo.iconId; dialogAppInfo.bundleLabelId = info.applicationInfo.labelId; dialogAppInfo.visible = info.visible; + dialogAppInfo.appIndex = info.applicationInfo.appIndex; + dialogAppInfo.multiAppMode = info.applicationInfo.multiAppMode; dialogAppInfos.emplace_back(dialogAppInfo); } return ERR_OK; } +int ImplicitStartProcessor::GenerateAbilityRequestByAppIndexes(int32_t userId, AbilityRequest &request, + std::vector &dialogAppInfos) +{ + auto appIndexes = StartAbilityUtils::GetCloneAppIndexes(request.want.GetBundle(), userId); + if (appIndexes.size() > AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "The size of appIndexes is too large."); + return ERR_INVALID_VALUE; + } + auto bms = GetBundleManagerHelper(); + CHECK_POINTER_AND_RETURN(bms, GET_ABILITY_SERVICE_FAILED); + auto abilityInfoFlag = static_cast(AbilityRuntime::StartupUtil::BuildAbilityInfoFlag()) | + static_cast(AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL); + std::vector abilityInfos; + abilityInfos.emplace_back(request.abilityInfo); + for (auto &appIndex: appIndexes) { + AppExecFwk::AbilityInfo abilityInfo; + IN_PROCESS_CALL_WITHOUT_RET(bms->QueryCloneAbilityInfo(request.want.GetElement(), abilityInfoFlag, appIndex, + abilityInfo, userId)); + if (abilityInfo.name.empty() || abilityInfo.bundleName.empty()) { + int32_t ret = FindExtensionInfo(request.want, abilityInfoFlag, userId, appIndex, abilityInfo); + if (ret != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "query clone extension info failed."); + return ret; + } + } + abilityInfos.emplace_back(abilityInfo); + } + for (const auto &info : abilityInfos) { + DialogAppInfo dialogAppInfo; + dialogAppInfo.abilityName = info.name; + dialogAppInfo.bundleName = info.bundleName; + dialogAppInfo.moduleName = info.moduleName; + dialogAppInfo.abilityIconId = info.iconId; + dialogAppInfo.abilityLabelId = info.labelId; + dialogAppInfo.bundleIconId = info.applicationInfo.iconId; + dialogAppInfo.bundleLabelId = info.applicationInfo.labelId; + dialogAppInfo.visible = info.visible; + dialogAppInfo.appIndex = info.applicationInfo.appIndex; + dialogAppInfo.multiAppMode = info.applicationInfo.multiAppMode; + dialogAppInfos.emplace_back(dialogAppInfo); + } + return ERR_OK; +} + +int ImplicitStartProcessor::FindExtensionInfo(const Want &want, int32_t flags, int32_t userId, + int32_t appIndex, AppExecFwk::AbilityInfo &abilityInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + auto bms = GetBundleManagerHelper(); + CHECK_POINTER_AND_RETURN(bms, GET_ABILITY_SERVICE_FAILED); + AppExecFwk::ExtensionAbilityInfo extensionInfo; + IN_PROCESS_CALL_WITHOUT_RET(bms->QueryCloneExtensionAbilityInfoWithAppIndex(want.GetElement(), + flags, appIndex, extensionInfo, userId)); + if (extensionInfo.bundleName.empty() || extensionInfo.name.empty()) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionInfo empty."); + return RESOLVE_ABILITY_ERR; + } + if (AbilityRuntime::StartupUtil::IsSupportAppClone(extensionInfo.type)) { + AbilityRuntime::StartupUtil::InitAbilityInfoFromExtension(extensionInfo, abilityInfo); + return ERR_OK; + } + return ERR_APP_CLONE_INDEX_INVALID; +} + int ImplicitStartProcessor::QueryBmsAppInfos(AbilityRequest &request, int32_t userId, std::vector &dialogAppInfos) { @@ -489,6 +575,9 @@ int ImplicitStartProcessor::QueryBmsAppInfos(AbilityRequest &request, int32_t us dialogAppInfo.abilityLabelId = abilityInfo.labelId; dialogAppInfo.bundleIconId = abilityInfo.applicationInfo.iconId; dialogAppInfo.bundleLabelId = abilityInfo.applicationInfo.labelId; + dialogAppInfo.visible = abilityInfo.visible; + dialogAppInfo.appIndex = abilityInfo.applicationInfo.appIndex; + dialogAppInfo.multiAppMode = abilityInfo.applicationInfo.multiAppMode; dialogAppInfos.emplace_back(dialogAppInfo); } } @@ -720,6 +809,8 @@ void ImplicitStartProcessor::AddAbilityInfoToDialogInfos(const AddInfoParam &par dialogAppInfo.bundleIconId = param.info.applicationInfo.iconId; dialogAppInfo.bundleLabelId = param.info.applicationInfo.labelId; dialogAppInfo.visible = param.info.visible; + dialogAppInfo.appIndex = param.info.applicationInfo.appIndex; + dialogAppInfo.multiAppMode = param.info.applicationInfo.multiAppMode; dialogAppInfos.emplace_back(dialogAppInfo); } diff --git a/services/abilitymgr/src/interceptor/ecological_rule_interceptor.cpp b/services/abilitymgr/src/interceptor/ecological_rule_interceptor.cpp index 58cc2e324c..6cb141e264 100644 --- a/services/abilitymgr/src/interceptor/ecological_rule_interceptor.cpp +++ b/services/abilitymgr/src/interceptor/ecological_rule_interceptor.cpp @@ -31,6 +31,7 @@ namespace { constexpr const char* ABILITY_SUPPORT_ECOLOGICAL_RULEMGRSERVICE = "persist.sys.abilityms.support.ecologicalrulemgrservice"; constexpr const char* BUNDLE_NAME_SCENEBOARD = "com.ohos.sceneboard"; +constexpr int32_t ERMS_ISALLOW_RESULTCODE = 10; } ErrCode EcologicalRuleInterceptor::DoProcess(AbilityInterceptorParam param) { @@ -63,7 +64,8 @@ ErrCode EcologicalRuleInterceptor::DoProcess(AbilityInterceptorParam param) return ERR_OK; } TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "check ecological rule success"); - if (rule.isAllow) { + StartAbilityUtils::ermsResultCode = rule.resultCode; + if (rule.resultCode == ERMS_ISALLOW_RESULTCODE) { TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "ecological rule is allow, keep going."); return ERR_OK; } @@ -125,7 +127,7 @@ bool EcologicalRuleInterceptor::DoProcess(Want &want, int32_t userId) TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "check ecological rule failed, keep going."); return true; } - return rule.isAllow; + return rule.resultCode == ERMS_ISALLOW_RESULTCODE; } void EcologicalRuleInterceptor::GetEcologicalTargetInfo(const Want &want, diff --git a/services/abilitymgr/src/start_ability_utils.cpp b/services/abilitymgr/src/start_ability_utils.cpp index 7af936c303..d1d1ac7ca0 100644 --- a/services/abilitymgr/src/start_ability_utils.cpp +++ b/services/abilitymgr/src/start_ability_utils.cpp @@ -30,6 +30,7 @@ namespace AAFwk { namespace { constexpr const char* SCREENSHOT_BUNDLE_NAME = "com.huawei.ohos.screenshot"; constexpr const char* SCREENSHOT_ABILITY_NAME = "com.huawei.ohos.screenshot.ServiceExtAbility"; +constexpr int32_t ERMS_ISALLOW_RESULTCODE = 10; constexpr const char* SHELL_ASSISTANT_BUNDLENAME = "com.huawei.shell_assistant"; constexpr int32_t BROKER_UID = 5557; } @@ -38,6 +39,8 @@ thread_local std::shared_ptr StartAbilityUtils::callerAbilityI thread_local bool StartAbilityUtils::skipCrowTest = false; thread_local bool StartAbilityUtils::skipStartOther = false; thread_local bool StartAbilityUtils::skipErms = false; +thread_local int32_t StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE; +thread_local bool StartAbilityUtils::isWantWithAppCloneIndex = false; bool StartAbilityUtils::GetAppIndex(const Want &want, sptr callerToken, int32_t &appIndex) { @@ -116,6 +119,15 @@ int32_t StartAbilityUtils::CheckAppProvisionMode(const Want& want, int32_t userI return ERR_OK; } +std::vector StartAbilityUtils::GetCloneAppIndexes(const std::string &bundleName, int32_t userId) +{ + std::vector appIndexes; + auto bms = AbilityUtil::GetBundleManagerHelper(); + CHECK_POINTER_AND_RETURN(bms, appIndexes); + IN_PROCESS_CALL_WITHOUT_RET(bms->GetCloneAppIndexes(bundleName, appIndexes, userId)); + return appIndexes; +} + StartAbilityInfoWrap::StartAbilityInfoWrap(const Want &want, int32_t validUserId, int32_t appIndex, const sptr &callerToken, bool isExtension) { @@ -154,6 +166,13 @@ StartAbilityInfoWrap::StartAbilityInfoWrap(const Want &want, int32_t validUserId TAG_LOGW(AAFwkTag::ABILITYMGR, "callerAbilityInfo has been created"); } StartAbilityUtils::callerAbilityInfo = StartAbilityInfo::CreateCallerAbilityInfo(callerToken); + + StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE; + StartAbilityUtils::isWantWithAppCloneIndex = false; + if (want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY) && appIndex >= 0 && + appIndex < AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) { + StartAbilityUtils::isWantWithAppCloneIndex = true; + } } StartAbilityInfoWrap::~StartAbilityInfoWrap() @@ -163,6 +182,8 @@ StartAbilityInfoWrap::~StartAbilityInfoWrap() StartAbilityUtils::skipCrowTest = false; StartAbilityUtils::skipStartOther = false; StartAbilityUtils::skipErms = false; + StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE; + StartAbilityUtils::isWantWithAppCloneIndex = false; } std::shared_ptr StartAbilityInfo::CreateStartAbilityInfo(const Want &want, int32_t userId, diff --git a/services/abilitymgr/src/system_dialog_scheduler.cpp b/services/abilitymgr/src/system_dialog_scheduler.cpp index b325c8a647..46d05dde2b 100644 --- a/services/abilitymgr/src/system_dialog_scheduler.cpp +++ b/services/abilitymgr/src/system_dialog_scheduler.cpp @@ -351,6 +351,9 @@ const std::string SystemDialogScheduler::GetSelectorParams(const std::vector = new Map(); for (let i = 1; i <= globalThis.params.hapList.length; i++) { - console.info(TAG, 'hapList[' + (i - 1).toString() + ']: ' + JSON.stringify(globalThis.params.hapList[i])); + console.info(TAG, 'hapList[' + (i - 1).toString() + ']: ' + JSON.stringify(globalThis.params.hapList[i - 1])); await this.getHapResource(globalThis.params.hapList[i - 1], showHapList, jsonIconMap); if (i % lineNums === 0) { phoneShowHapList.push(showHapList); @@ -65,7 +65,7 @@ export default class SelectorServiceExtensionAbility extends extension { let signalRowShowHapList = []; let signalRowPhoneShowHapList = []; for (let i = 1; i <= globalThis.params.hapList.length; i++) { - console.info(TAG, 'hapList[' + (i - 1).toString() + ']: ' + JSON.stringify(globalThis.params.hapList[i])); + console.info(TAG, 'hapList[' + (i - 1).toString() + ']: ' + JSON.stringify(globalThis.params.hapList[i - 1])); await this.getHapResource(globalThis.params.hapList[i - 1], signalRowShowHapList, jsonIconMap); if (i % signalRowlineNums === 0) { signalRowPhoneShowHapList.push(signalRowShowHapList); @@ -99,19 +99,30 @@ export default class SelectorServiceExtensionAbility extends extension { let appIcon = ''; let type = ''; let userId = Number('0'); + let appIndex = Number(hap.appIndex); if (!globalThis.params.isDefaultSelector) { type = hap.type; userId = Number(hap.userId); } let lableId = Number(hap.label); + if (lableId === 0) { + lableId = Number(hap.bundleLabel); + } let moduleContext = globalThis.selectExtensionContext.createModuleContext(bundleName, moduleName); await moduleContext.resourceManager.getString(lableId).then(value => { - appName = value; + if (appIndex === 0) { + appName = value; + } else { + appName = value + hap.appIndex; + } }).catch(error => { console.error(TAG, 'getString error:' + JSON.stringify(error)); }); let iconId = Number(hap.icon); + if (iconId === 0) { + iconId = Number(hap.bundleIcon); + } await moduleContext.resourceManager.getMediaBase64(iconId).then(value => { appIcon = value; if (appIcon.indexOf('image/json') > -1) { @@ -123,7 +134,8 @@ export default class SelectorServiceExtensionAbility extends extension { imageDescriptor; let foregroundDescriptor: drawableDescriptor.DrawableDescriptor = layeredDrawableDescriptor.getForeground(); if (foregroundDescriptor !== null && foregroundDescriptor !== undefined) { - jsonIconMap.set(bundleName + ':' + moduleName + ':' + abilityName, foregroundDescriptor.getPixelMap()); + jsonIconMap.set(bundleName + ':' + moduleName + ':' + abilityName + ':' + hap.appIndex, + foregroundDescriptor.getPixelMap()); } else { console.error(TAG, 'get foregroundDescriptor is null'); } @@ -136,7 +148,7 @@ export default class SelectorServiceExtensionAbility extends extension { console.error(TAG, 'getMediaBase64 error:' + JSON.stringify(error)); }); showHapList.push(bundleName + '#' + abilityName + '#' + appName + - '#' + appIcon + '#' + moduleName + '#' + type + '#' + userId); + '#' + appIcon + '#' + moduleName + '#' + type + '#' + userId + '#' + appIndex); } async onRequest(want, startId) { diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPcDialog.ets b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPcDialog.ets index 1b99992ab0..f6cebc23be 100644 --- a/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPcDialog.ets +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPcDialog.ets @@ -79,6 +79,7 @@ struct SelectorPcDialog { globalThis.abilityWant.bundleName = item.split('#')[0]; globalThis.abilityWant.abilityName = item.split('#')[1]; globalThis.abilityWant.moduleName = item.split('#')[4]; + globalThis.abilityWant.parameters['ohos.extra.param.key.appCloneIndex'] = Number(item.split('#')[7]); globalThis.selectExtensionContext.startAbilityAsCaller(globalThis.abilityWant, (data, error) => { if (error) { console.error(this.TAG + ' startAbility finish, error: ' + JSON.stringify(error)); @@ -148,7 +149,7 @@ struct SelectorPcDialog { let foregroundDescriptor: drawableDescriptor.DrawableDescriptor = layeredDrawableDescriptor.getForeground(); if (foregroundDescriptor !== null && foregroundDescriptor !== undefined) { - globalThis.jsonIconMap.set(bundleName + ':' + moduleName + ':' + abilityName, + globalThis.jsonIconMap.set(bundleName + ':' + moduleName + ':' + abilityName + ':' + hap.appIndex, foregroundDescriptor.getPixelMap()); } else { console.error(this.TAG, 'get foregroundDescriptor is null'); @@ -276,7 +277,7 @@ struct SelectorPcDialog { if (item.split('#')[3] != '') { if (item.split('#')[3].indexOf('image/json') > -1) { Image(globalThis.jsonIconMap.get(item.split('#')[0] + ':' + item.split('#')[4] + - ':' + item.split('#')[1])) + ':' + item.split('#')[1] + ':' + item.split('#')[7])) .height(48) .width(48) .alignSelf(ItemAlign.Center) @@ -372,7 +373,7 @@ struct SelectorPcDialog { if (item.split('#')[3] != '') { if (item.split('#')[3].indexOf('image/json') > -1) { Image(globalThis.jsonIconMap.get(item.split('#')[0] + ':' + item.split('#')[4] + - ':' + item.split('#')[1])) + ':' + item.split('#')[1] + ':' + item.split('#')[7])) .height(48) .width(48) .alignSelf(ItemAlign.Center) diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPhoneDialog.ets b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPhoneDialog.ets index 4c46f0e0df..577e3de206 100644 --- a/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPhoneDialog.ets +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/ets/pages/selectorPhoneDialog.ets @@ -83,6 +83,29 @@ struct SelectorPhoneDialog { @State private hapList: HapInfo[] = []; private TAG = 'SelectorDialog_Phone_Page'; + @Builder + elementIconCombine(iconSrc: string, appIndex: string) { + RelativeContainer() { + Image(iconSrc) + .id('iconLab') + .height(60) + .width(60) + .alignSelf(ItemAlign.Center); + if (appIndex !== '0') { + Image($r('app.media.app_icon_clone_index_' + appIndex)) + .height(18) + .width(18) + .alignRules({ + end: { anchor: 'iconLab', align: HorizontalAlign.End }, + bottom: { anchor: 'iconLab', align: VerticalAlign.Bottom } + }) + } + } + .height(60) + .width(60) + .alignSelf(ItemAlign.Center); + } + aboutToAppear(): void { console.log(this.TAG, 'dialog page appears'); this.hapList = globalThis.params.hapList; @@ -99,6 +122,7 @@ struct SelectorPhoneDialog { globalThis.abilityWant.bundleName = item.split('#')[0]; globalThis.abilityWant.abilityName = item.split('#')[1]; globalThis.abilityWant.moduleName = item.split('#')[4]; + globalThis.abilityWant.parameters['ohos.extra.param.key.appCloneIndex'] = Number(item.split('#')[7]); globalThis.selectExtensionContext.startAbilityAsCaller(globalThis.abilityWant, (data, error) => { if (error) { console.error(this.TAG + ' startAbility finish, error: ' + JSON.stringify(error)); @@ -158,16 +182,11 @@ struct SelectorPhoneDialog { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) { if (item.split('#')[3] != '') { if (item.split('#')[3].indexOf('image/json') > -1) { - Image(globalThis.jsonIconMap.get(item.split('#')[0] + ':' + item.split('#')[4] + - ':' + item.split('#')[1])) - .height(60) - .width(60) - .alignSelf(ItemAlign.Center); + this.elementIconCombine(globalThis.jsonIconMap.get(item.split('#')[0] + ':' + + item.split('#')[4] + ':' + item.split('#')[1] + ':' + item.split('#')[7]), + item.split('#')[7]); } else { - Image(item.split('#')[3]) - .height(60) - .width(60) - .alignSelf(ItemAlign.Center); + this.elementIconCombine(item.split('#')[3], item.split('#')[7]); } } else { Image($r('app.media.app_icon')) diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_1.svg b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_1.svg new file mode 100644 index 0000000000..9ffedee3d2 --- /dev/null +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_1.svg @@ -0,0 +1,10 @@ + + + 画板 + + + + + + + \ No newline at end of file diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_2.svg b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_2.svg new file mode 100644 index 0000000000..ed4b17f123 --- /dev/null +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_2.svg @@ -0,0 +1,10 @@ + + + 画板备份 6 + + + + + + + \ No newline at end of file diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_3.svg b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_3.svg new file mode 100644 index 0000000000..39852e4570 --- /dev/null +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_3.svg @@ -0,0 +1,10 @@ + + + 画板备份 7 + + + + + + + \ No newline at end of file diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_4.svg b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_4.svg new file mode 100644 index 0000000000..fbce202557 --- /dev/null +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_4.svg @@ -0,0 +1,10 @@ + + + 画板备份 8 + + + + + + + \ No newline at end of file diff --git a/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_5.svg b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_5.svg new file mode 100644 index 0000000000..91c4473567 --- /dev/null +++ b/services/dialog_ui/ams_system_dialog/entry/src/main/resources/base/media/app_icon_clone_index_5.svg @@ -0,0 +1,10 @@ + + + 画板备份 9 + + + + + + + \ No newline at end of file