diff --git a/frameworks/js/napi/service_extension_context/service_extension_context.js b/frameworks/js/napi/service_extension_context/service_extension_context.js index 548bdfb6a1..717724ceed 100644 --- a/frameworks/js/napi/service_extension_context/service_extension_context.js +++ b/frameworks/js/napi/service_extension_context/service_extension_context.js @@ -154,6 +154,11 @@ class ServiceExtensionContext extends ExtensionContext { return; }); } + + preStartMission(bundleName, moduleName, abilityName, startTime) { + console.log('preStartMission'); + return this.__context_impl__.preStartMission(bundleName, moduleName, abilityName, startTime); + } } export default ServiceExtensionContext; diff --git a/frameworks/js/napi/wantConstant/want_constant.cpp b/frameworks/js/napi/wantConstant/want_constant.cpp index 406a449b7b..9bda492061 100644 --- a/frameworks/js/napi/wantConstant/want_constant.cpp +++ b/frameworks/js/napi/wantConstant/want_constant.cpp @@ -114,6 +114,11 @@ napi_value WantConstantInit(napi_env env, napi_value exports) SetNamedProperty(env, params, "ohos.extra.param.key.supportContinueSourceExit", "SUPPORT_CONTINUE_SOURCE_EXIT_KEY"); SetNamedProperty(env, params, "ohos.extra.param.key.showMode", "SHOW_MODE_KEY"); SetNamedProperty(env, params, "ohos.extra.param.key.appCloneIndex", "APP_CLONE_INDEX_KEY"); + SetNamedProperty(env, params, "ohos.param.atomicservice.pagePath", "PAGE_PATH"); + SetNamedProperty(env, params, "ohos.param.atomicservice.routerName", "ROUTER_NAME"); + SetNamedProperty(env, params, "ohos.param.atomicservice.pageSourceFile", "PAGE_SOURCE_FILE"); + SetNamedProperty(env, params, "ohos.param.atomicservice.buildFunction", "BUILD_FUNCTION"); + SetNamedProperty(env, params, "ohos.param.atomicservice.subpackageName", "SUB_PACKAGE_NAME"); napi_property_descriptor exportFuncs[] = { DECLARE_NAPI_PROPERTY("Action", action), DECLARE_NAPI_PROPERTY("Entity", entity), diff --git a/frameworks/native/ability/native/ability_business_error/ability_business_error.cpp b/frameworks/native/ability/native/ability_business_error/ability_business_error.cpp index c067148df6..1df63993d6 100644 --- a/frameworks/native/ability/native/ability_business_error/ability_business_error.cpp +++ b/frameworks/native/ability/native/ability_business_error/ability_business_error.cpp @@ -85,6 +85,7 @@ constexpr const char* ERROR_MSG_NOT_APP_CLONE = "The target app is not Clone."; constexpr const char* ERROR_MSG_EXTENSION_START_THIRD_PARTY_APP_CONTROLLED = "The extension can not start the specified third party application."; constexpr const char* ERROR_MSG_EXTENSION_START_SERVICE_CONTROLLED = "The extension can not start the service."; +constexpr const char* ERROR_MSG_FREE_INSTALL_TASK_NOT_EXIST = "The target free install task does not exist."; // follow ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST of appexecfwk_errors.h in bundle_framework constexpr int32_t ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST = 8521220; @@ -144,7 +145,8 @@ static std::unordered_map ERR_CODE_MAP = { { AbilityErrorCode::ERROR_CODE_EXTENSION_START_THIRD_PARTY_APP_CONTROLLED, ERROR_MSG_EXTENSION_START_THIRD_PARTY_APP_CONTROLLED }, { AbilityErrorCode::ERROR_CODE_EXTENSION_START_SERVICE_CONTROLLED, ERROR_MSG_EXTENSION_START_SERVICE_CONTROLLED}, - { AbilityErrorCode::ERROR_CODE_BUNDLE_NAME_INVALID, ERROR_MSG_TARGET_BUNDLE_NOT_EXIST} + { AbilityErrorCode::ERROR_CODE_BUNDLE_NAME_INVALID, ERROR_MSG_TARGET_BUNDLE_NOT_EXIST}, + { AbilityErrorCode::ERROR_CODE_FREE_INSTALL_TASK_NOT_EXIST, ERROR_MSG_FREE_INSTALL_TASK_NOT_EXIST } }; static std::unordered_map INNER_TO_JS_ERROR_CODE_MAP { @@ -207,6 +209,7 @@ static std::unordered_map INNER_TO_JS_ERROR_CODE_MAP AbilityErrorCode::ERROR_CODE_EXTENSION_START_THIRD_PARTY_APP_CONTROLLED}, {EXTENSION_BLOCKED_BY_SERVICE_LIST, AbilityErrorCode::ERROR_CODE_EXTENSION_START_SERVICE_CONTROLLED}, {ERR_BUNDLE_NOT_EXIST, AbilityErrorCode::ERROR_CODE_BUNDLE_NAME_INVALID}, + {ERR_FREE_INSTALL_TASK_NOT_EXIST, AbilityErrorCode::ERROR_CODE_FREE_INSTALL_TASK_NOT_EXIST}, }; } diff --git a/frameworks/native/ability/native/js_service_extension_context.cpp b/frameworks/native/ability/native/js_service_extension_context.cpp index 5507b4343f..fe1df2a755 100644 --- a/frameworks/native/ability/native/js_service_extension_context.cpp +++ b/frameworks/native/ability/native/js_service_extension_context.cpp @@ -45,12 +45,14 @@ namespace { constexpr int32_t INDEX_ZERO = 0; constexpr int32_t INDEX_ONE = 1; constexpr int32_t INDEX_TWO = 2; +constexpr int32_t INDEX_THREE = 3; constexpr int32_t ERROR_CODE_ONE = 1; constexpr int32_t ERROR_CODE_TWO = 2; constexpr size_t ARGC_ZERO = 0; constexpr size_t ARGC_ONE = 1; constexpr size_t ARGC_TWO = 2; constexpr size_t ARGC_THREE = 3; +constexpr size_t ARGC_FOUR = 4; class StartAbilityByCallParameters { public: @@ -170,6 +172,11 @@ public: GET_NAPI_INFO_AND_CALL(env, info, JsServiceExtensionContext, OnRequestModalUIExtension); } + static napi_value PreStartMission(napi_env env, napi_callback_info info) + { + GET_NAPI_INFO_AND_CALL(env, info, JsServiceExtensionContext, OnPreStartMission); + } + private: std::weak_ptr context_; sptr freeInstallObserver_ = nullptr; @@ -1043,6 +1050,76 @@ private: return result; } + bool ParsePreStartMissionArgs(const napi_env &env, const NapiCallbackInfo &info, std::string& bundleName, + std::string& moduleName, std::string& abilityName, std::string& startTime) + { + if (info.argc < ARGC_FOUR) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "wrong arguments num"); + ThrowTooFewParametersError(env); + return false; + } + + std::string args[ARGC_FOUR]; + for (size_t i = 0; i < ARGC_FOUR; i++) { + if (!CheckTypeForNapiValue(env, info.argv[i], napi_string)) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "param must be string"); + return false; + } + if (!ConvertFromJsValue(env, info.argv[i], args[i])) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "parameter invalid"); + return false; + } + } + + bundleName = args[INDEX_ZERO]; + moduleName = args[INDEX_ONE]; + abilityName = args[INDEX_TWO]; + startTime = args[INDEX_THREE]; + + return true; + } + + napi_value OnPreStartMission(napi_env env, NapiCallbackInfo& info) + { + TAG_LOGD(AAFwkTag::SERVICE_EXT, "called"); + if (info.argc < ARGC_FOUR) { + ThrowTooFewParametersError(env); + return CreateJsUndefined(env); + } + + std::string bundleName; + std::string moduleName; + std::string abilityName; + std::string startTime; + if (!ParsePreStartMissionArgs(env, info, bundleName, moduleName, abilityName, startTime)) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "parse preStartMission arguments failed"); + ThrowInvalidParamError(env, "Parse params failed, params must be strings."); + return CreateJsUndefined(env); + } + + NapiAsyncTask::CompleteCallback complete = + [weak = context_, bundleName, moduleName, abilityName, startTime]( + napi_env env, NapiAsyncTask& task, int32_t status) { + auto context = weak.lock(); + if (!context) { + TAG_LOGW(AAFwkTag::SERVICE_EXT, "context is released"); + task.Reject(env, CreateJsError(env, AbilityErrorCode::ERROR_CODE_INNER)); + return; + } + auto errcode = context->PreStartMission(bundleName, moduleName, abilityName, startTime); + if (errcode == 0) { + task.ResolveWithNoError(env, CreateJsUndefined(env)); + return; + } + task.Reject(env, CreateJsErrorByNativeErr(env, errcode)); + }; + + napi_value result = nullptr; + NapiAsyncTask::ScheduleHighQos("JSServiceExtensionContext::OnPreStartMission", + env, CreateAsyncTaskWithLastParam(env, nullptr, nullptr, std::move(complete), &result)); + return result; + } + NapiAsyncTask::ExecuteCallback GetStartAbilityExecFunc(const AAFwk::Want &want, const AAFwk::StartOptions &startOptions, int32_t userId, bool useOption, std::shared_ptr retCode) { @@ -1154,6 +1231,8 @@ napi_value CreateJsServiceExtensionContext(napi_env env, std::shared_ptrtype; } + +ErrCode ServiceExtensionContext::PreStartMission(const std::string& bundleName, const std::string& moduleName, + const std::string& abilityName, const std::string& startTime) +{ + TAG_LOGI(AAFwkTag::APPKIT, "Called."); + ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->PreStartMission( + bundleName, moduleName, abilityName, startTime); + if (err != ERR_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "ServiceExtensionContext::PreStartMission is failed %{public}d", err); + } + TAG_LOGI(AAFwkTag::APPKIT, "End."); + return err; +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_client.h b/interfaces/inner_api/ability_manager/include/ability_manager_client.h index ec1bc2bb16..ae28461a43 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_client.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_client.h @@ -1499,6 +1499,18 @@ public: */ void NotifyFrozenProcessByRSS(const std::vector &pidList, int32_t uid); + /** + * Open atomic service window prior to finishing free install. + * + * @param bundleName, the bundle name of the atomic service. + * @param moduleName, the module name of the atomic service. + * @param abilityName, the ability name of the atomic service. + * @param startTime, the starting time of the free install task. + * @return Returns ERR_OK on success, others on failure. + */ + int32_t PreStartMission(const std::string& bundleName, const std::string& moduleName, + const std::string& abilityName, const std::string& startTime); + private: AbilityManagerClient(); DISALLOW_COPY_AND_MOVE(AbilityManagerClient); diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_errors.h b/interfaces/inner_api/ability_manager/include/ability_manager_errors.h index 531e2a7c6b..d87203b303 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_errors.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_errors.h @@ -550,6 +550,11 @@ enum { */ ERR_BUNDLE_NOT_EXIST, + /* + * Result (2097260) for target free install task does not exist. + */ + ERR_FREE_INSTALL_TASK_NOT_EXIST = 2097260, + /** * Native error(3000000) for target bundle not exist. */ diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h index 2d1974bf9c..8d8418726e 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h @@ -1632,6 +1632,21 @@ public: { return; } + + /** + * Open atomic service window prior to finishing free install. + * + * @param bundleName, the bundle name of the atomic service. + * @param moduleName, the module name of the atomic service. + * @param abilityName, the ability name of the atomic service. + * @param startTime, the starting time of the free install task. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int32_t PreStartMission(const std::string& bundleName, const std::string& moduleName, + const std::string& abilityName, const std::string& startTime) + { + return 0; + } }; } // namespace AAFwk } // namespace OHOS diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h b/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h index b1df9a4286..eb493e49a4 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h @@ -447,6 +447,9 @@ enum class AbilityManagerInterfaceCode { // ipc for notify frozen process by RSS NOTIFY_FROZEN_PROCESS_BY_RSS = 1130, + // ipc id for pre-start mission + PRE_START_MISSION = 1135, + // ipc id 2001-3000 for tools // ipc id for dumping state (2001) DUMP_STATE = 2001, diff --git a/interfaces/kits/native/ability/native/ability_business_error/ability_business_error.h b/interfaces/kits/native/ability/native/ability_business_error/ability_business_error.h index d17d0afba0..424f861a83 100644 --- a/interfaces/kits/native/ability/native/ability_business_error/ability_business_error.h +++ b/interfaces/kits/native/ability/native/ability_business_error/ability_business_error.h @@ -179,6 +179,9 @@ enum class AbilityErrorCode { ERROR_CODE_SET_SUPPORTED_PROCESS_CACHE_AGAIN = 16300006, + // target free install task does not exist. + ERROR_CODE_FREE_INSTALL_TASK_NOT_EXIST = 16300007, + ERROR_CODE_BUNDLE_NAME_INVALID = 18500001, }; diff --git a/interfaces/kits/native/appkit/ability_runtime/service_extension_context.h b/interfaces/kits/native/appkit/ability_runtime/service_extension_context.h index e50ebbdc46..8a2fc9cff6 100644 --- a/interfaces/kits/native/appkit/ability_runtime/service_extension_context.h +++ b/interfaces/kits/native/appkit/ability_runtime/service_extension_context.h @@ -158,6 +158,9 @@ public: ErrCode RequestModalUIExtension(const Want &want); + ErrCode PreStartMission(const std::string& bundleName, const std::string& moduleName, + const std::string& abilityName, const std::string& startTime); + using SelfType = ServiceExtensionContext; static const size_t CONTEXT_TYPE_ID; diff --git a/services/abilitymgr/include/ability_manager_proxy.h b/services/abilitymgr/include/ability_manager_proxy.h index 5f0815559e..3a930db0bb 100644 --- a/services/abilitymgr/include/ability_manager_proxy.h +++ b/services/abilitymgr/include/ability_manager_proxy.h @@ -1268,6 +1268,18 @@ public: */ virtual void NotifyFrozenProcessByRSS(const std::vector &pidList, int32_t uid) override; + /** + * Open atomic service window prior to finishing free install. + * + * @param bundleName, the bundle name of the atomic service. + * @param moduleName, the module name of the atomic service. + * @param abilityName, the ability name of the atomic service. + * @param startTime, the starting time of the free install task. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int32_t PreStartMission(const std::string& bundleName, const std::string& moduleName, + const std::string& abilityName, const std::string& startTime) override; + private: template int GetParcelableInfos(MessageParcel &reply, std::vector &parcelableInfos); diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index 43d3ff7022..ab4d88d7ca 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -16,6 +16,7 @@ #ifndef OHOS_ABILITY_RUNTIME_ABILITY_MANAGER_SERVICE_H #define OHOS_ABILITY_RUNTIME_ABILITY_MANAGER_SERVICE_H +#include #include #include #include @@ -30,6 +31,7 @@ #include "ability_connect_manager.h" #include "ability_debug_deal.h" #include "ability_event_handler.h" +#include "ability_info.h" #include "ability_manager_event_subscriber.h" #include "ability_manager_stub.h" #include "ams_configuration_parameter.h" @@ -83,6 +85,7 @@ enum class ServiceRunningState { STATE_NOT_START, STATE_RUNNING }; constexpr int32_t BASE_USER_RANGE = 200000; constexpr int32_t U0_USER_ID = 0; constexpr int32_t INVALID_USER_ID = -1; +constexpr const char* KEY_SESSION_ID = "com.ohohs.param.sessionId"; using OHOS::AppExecFwk::IAbilityController; class PendingWantManager; struct StartAbilityInfo; @@ -1698,6 +1701,23 @@ public: void HandleRestartResidentProcessDependedOnWeb(); + /** + * Open atomic service window prior to finishing free install. + * + * @param bundleName, the bundle name of the atomic service. + * @param moduleName, the module name of the atomic service. + * @param abilityName, the ability name of the atomic service. + * @param startTime, the starting time of the free install task. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int32_t PreStartMission(const std::string& bundleName, const std::string& moduleName, + const std::string& abilityName, const std::string& startTime) override; + + int32_t StartUIAbilityByPreInstall(const FreeInstallInfo &taskInfo); + + void NotifySCBToHandleException(sptr callerToken, int errCode, + const std::string& reason); + // MSG 0 - 20 represents timeout message static constexpr uint32_t LOAD_TIMEOUT_MSG = 0; static constexpr uint32_t ACTIVE_TIMEOUT_MSG = 1; @@ -1808,6 +1828,12 @@ private: int StartRemoteAbility(const Want &want, int requestCode, int32_t validUserId, const sptr &callerToken); + int StartUIAbilityBySCBDefault(sptr sessionInfo, bool &isColdStart); + int StartUIAbilityByPreInstallInner(sptr sessionInfo, + uint32_t specifyTokenId, bool &isColdStart); + int32_t PreStartInner(const FreeInstallInfo& taskInfo); + void RemovePreStartSession(const std::string& sessionId); + int ConnectLocalAbility( const Want &want, const int32_t userId, @@ -2172,6 +2198,28 @@ private: int CheckUIExtensionUsage(AppExecFwk::UIExtensionUsage uiExtensionUsage, AppExecFwk::ExtensionAbilityType extensionType); + int CheckExtensionCallPermission(const Want& want, const AbilityRequest& abilityRequest); + + int CheckServiceCallPermission(const AbilityRequest& abilityRequest, + const AppExecFwk::AbilityInfo& abilityInfo); + + int CheckBrokerCallPermission(const AbilityRequest& abilityRequest, + const AppExecFwk::AbilityInfo& abilityInfo); + + int CheckAbilityCallPermission(const AbilityRequest& abilityRequest, + const AppExecFwk::AbilityInfo& abilityInfo, uint32_t specifyTokenId); + + int CheckCallPermission(const Want& want, const AppExecFwk::AbilityInfo& abilityInfo, + const AbilityRequest& abilityRequest, bool isForegroundToRestartApp, + bool isSendDialogResult, uint32_t specifyTokenId, + const std::string& callerBundleName); + + int StartAbilityByConnectManager(const Want& want, const AbilityRequest& abilityRequest, + const AppExecFwk::AbilityInfo& abilityInfo, int validUserId, sptr callerToken); + + int PreStartFreeInstall(const Want &want, sptr callerToken, + uint32_t specifyTokenId, bool isStartAsCaller, Want &localWant); + constexpr static int REPOLL_TIME_MICRO_SECONDS = 1000000; constexpr static int WAITING_BOOT_ANIMATION_TIMER = 5; @@ -2194,8 +2242,10 @@ private: ffrt::mutex globalLock_; ffrt::mutex bgtaskObserverMutex_; ffrt::mutex abilityTokenLock_; + ffrt::mutex preStartSessionMapLock_; std::multimap timeoutMap_; + std::map> preStartSessionMap_; static sptr instance_; int32_t uniqueId_ = 0; diff --git a/services/abilitymgr/include/ability_manager_stub.h b/services/abilitymgr/include/ability_manager_stub.h index e0f2423669..cf8242d279 100644 --- a/services/abilitymgr/include/ability_manager_stub.h +++ b/services/abilitymgr/include/ability_manager_stub.h @@ -295,6 +295,7 @@ private: int32_t GetAbilityStateByPersistentIdInner(MessageParcel &data, MessageParcel &reply); int32_t TransferAbilityResultForExtensionInner(MessageParcel &data, MessageParcel &reply); int32_t NotifyFrozenProcessByRSSInner(MessageParcel &data, MessageParcel &reply); + int32_t PreStartMissionInner(MessageParcel &data, MessageParcel &reply); int OnRemoteRequestInnerFirst(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); int OnRemoteRequestInnerSecond(uint32_t code, MessageParcel &data, diff --git a/services/abilitymgr/include/free_install_manager.h b/services/abilitymgr/include/free_install_manager.h index 15285b8de1..fa4ca9c1fa 100644 --- a/services/abilitymgr/include/free_install_manager.h +++ b/services/abilitymgr/include/free_install_manager.h @@ -39,6 +39,9 @@ struct FreeInstallInfo { std::string identity; sptr callerToken = nullptr; sptr dmsCallback = nullptr; + bool isPreStartMissionCalled = false; + bool isStartUIAbilityBySCBCalled = false; + uint32_t specifyTokenId = 0; }; /** @@ -79,7 +82,7 @@ public: * @return Returns ERR_OK on success, others on failure. */ int StartFreeInstall(const Want &want, int32_t userId, int requestCode, const sptr &callerToken, - bool isAsync = false); + bool isAsync = false, uint32_t specifyTokenId = 0); /** * Start to remote free install. @@ -130,6 +133,60 @@ public: */ void OnRemoveTimeoutTask(const Want &want); + /** + * Get free install task info. + * + * @param bundleName, the bundle name of the task. + * @param abilityName, the ability name of the task. + * @param startTime, the start time of the task. + * @param taskInfo, the found task info + * @return Returns true on success, false on failure. + */ + bool GetFreeInstallTaskInfo(const std::string& bundleName, const std::string& abilityName, + const std::string& startTime, FreeInstallInfo& taskInfo); + + /** + * Get free install task info. + * + * @param sessionId, the sessionId of the task. + * @param taskInfo, the found task info + * @return Returns true on success, false on failure. + */ + bool GetFreeInstallTaskInfo(const std::string& sessionId, FreeInstallInfo& taskInfo); + + /** + * Set the isStartUIAbilityBySCBCalled flag of the given free install task. + * + * @param bundleName, the bundle name of the task. + * @param abilityName, the abilitu name of the task. + * @param startTime, the start time of the task. + * @param scbCallStatus, the status of whether StartUIAbilityBySCB is called. + */ + void SetSCBCallStatus(const std::string& bundleName, const std::string& abilityName, + const std::string& startTime, bool scbCallStatus); + + /** + * Set the isPreStartMissionCalled flag of the given free install task. + * + * @param bundleName, the bundle name of the task. + * @param abilityName, the abilitu name of the task. + * @param startTime, the start time of the task. + * @param preStartMissionCallStatus, the status of whether PreStartMission is called. + */ + void SetPreStartMissionCallStatus(const std::string& bundleName, const std::string& abilityName, + const std::string& startTime, bool preStartMissionCallStatus); + + /** + * Set the sessionId of the given free install task. + * + * @param bundleName, the bundle name of the task. + * @param abilityName, the abilitu name of the task. + * @param startTime, the start time of the task. + * @param sessionId, the sessionId of the free install task. + */ + void SetFreeInstallTaskSessionId(const std::string& bundleName, const std::string& abilityName, + const std::string& startTime, const std::string& sessionId); + private: std::weak_ptr server_; std::vector freeInstallList_; @@ -153,7 +210,7 @@ private: bool IsTopAbility(const sptr &callerToken); void NotifyFreeInstallResult(const Want &want, int resultCode, bool isAsync = false); FreeInstallInfo BuildFreeInstallInfo(const Want &want, int32_t userId, int requestCode, - const sptr &callerToken, bool isAsync); + const sptr &callerToken, bool isAsync, uint32_t specifyTokenId = 0); std::time_t GetTimeStamp(); void RemoveFreeInstallInfo(const std::string &bundleName, const std::string &abilityName, @@ -167,7 +224,13 @@ private: void StartAbilityByFreeInstall(FreeInstallInfo &info, std::string &bundleName, std::string &abilityName, std::string &startTime); + void StartAbilityByPreInstall(FreeInstallInfo &info, std::string &bundleName, std::string &abilityName, + std::string &startTime); int32_t UpdateElementName(Want &want, int32_t userId) const; + void HandleFreeInstallResult(FreeInstallInfo &freeInstallInfo, int resultCode, bool isAsync); + void HandleOnFreeInstallSuccess(FreeInstallInfo &freeInstallInfo, bool isAsync); + void HandleOnFreeInstallFail(FreeInstallInfo &freeInstallInfo, int resultCode, bool isAsync); + void NotifySCBToHandleException(const FreeInstallInfo &info, int resultCode); }; } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h b/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h index 0110e3f3e4..5de5dbc783 100644 --- a/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h +++ b/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h @@ -150,6 +150,9 @@ public: int NotifySCBToStartUIAbility(const AbilityRequest &abilityRequest); + int NotifySCBToPreStartUIAbility(const AbilityRequest &abilityRequest, + sptr &sessionInfo); + /** * @brief handle time out event * @@ -353,6 +356,9 @@ public: int32_t GetAbilityStateByPersistentId(int32_t persistentId, bool &state); + void NotifySCBToHandleException(const std::shared_ptr &ability, int32_t errorCode, + const std::string& errorReason); + private: int32_t GetPersistentIdByAbilityRequest(const AbilityRequest &abilityRequest, bool &reuse) const; int32_t GetReusedSpecifiedPersistentId(const AbilityRequest &abilityRequest, bool &reuse) const; @@ -374,8 +380,6 @@ private: void HandleForegroundFailed(const std::shared_ptr &ability, AbilityState state = AbilityState::INITIAL); void HandleForegroundTimeout(const std::shared_ptr &ability); - void NotifySCBToHandleException(const std::shared_ptr &ability, int32_t errorCode, - std::string errorReason); void MoveToBackground(const std::shared_ptr &abilityRecord); void CompleteBackground(const std::shared_ptr &abilityRecord); void PrintTimeOutLog(std::shared_ptr ability, uint32_t msgId, bool isHalf = false); diff --git a/services/abilitymgr/src/ability_manager_client.cpp b/services/abilitymgr/src/ability_manager_client.cpp index dcc954fe2c..a774b10e71 100644 --- a/services/abilitymgr/src/ability_manager_client.cpp +++ b/services/abilitymgr/src/ability_manager_client.cpp @@ -1911,5 +1911,14 @@ void AbilityManagerClient::NotifyFrozenProcessByRSS(const std::vector & CHECK_POINTER_RETURN(abms); return abms->NotifyFrozenProcessByRSS(pidList, uid); } + +ErrCode AbilityManagerClient::PreStartMission(const std::string& bundleName, const std::string& moduleName, + const std::string& abilityName, const std::string& startTime) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + auto abms = GetAbilityManager(); + CHECK_POINTER_RETURN_NOT_CONNECTED(abms); + return abms->PreStartMission(bundleName, moduleName, abilityName, startTime); +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/ability_manager_proxy.cpp b/services/abilitymgr/src/ability_manager_proxy.cpp index 1acf8c728a..5bb68fad08 100644 --- a/services/abilitymgr/src/ability_manager_proxy.cpp +++ b/services/abilitymgr/src/ability_manager_proxy.cpp @@ -5303,5 +5303,38 @@ void AbilityManagerProxy::NotifyFrozenProcessByRSS(const std::vector &p TAG_LOGE(AAFwkTag::ABILITYMGR, "AbilityManagerProxy: SendRequest err %{public}d", error); } } + +int32_t AbilityManagerProxy::PreStartMission(const std::string& bundleName, const std::string& moduleName, + const std::string& abilityName, const std::string& startTime) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!WriteInterfaceToken(data)) { + return IPC_PROXY_ERR; + } + if (!data.WriteString(bundleName)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write bundleName failed."); + return INNER_ERR; + } + if (!data.WriteString(moduleName)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write moduleName failed."); + return INNER_ERR; + } + if (!data.WriteString(abilityName)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write abilityName failed."); + return INNER_ERR; + } + if (!data.WriteString(startTime)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "write startTime failed."); + return INNER_ERR; + } + auto error = SendRequest(AbilityManagerInterfaceCode::PRE_START_MISSION, data, reply, option); + if (error != NO_ERROR) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Send request error: %{public}d", error); + return error; + } + return reply.ReadInt32(); +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index 0dd4989ee3..f0a0cdadfe 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -33,7 +33,6 @@ #include "ability_background_connection.h" #include "ability_connect_manager.h" #include "ability_debug_deal.h" -#include "ability_info.h" #include "ability_manager_constants.h" #include "ability_manager_errors.h" #include "ability_manager_radar.h" @@ -914,6 +913,97 @@ void AbilityManagerService::SetReserveInfo(const std::string &linkString) #endif // SUPPORT_SCREEN } +int AbilityManagerService::CheckExtensionCallPermission(const Want& want, const AbilityRequest& abilityRequest) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "startExtensionCheck"); + auto isSACall = AAFwk::PermissionVerification::GetInstance()->IsSACall(); + auto isSystemAppCall = AAFwk::PermissionVerification::GetInstance()->IsSystemAppCall(); + auto isShellCall = AAFwk::PermissionVerification::GetInstance()->IsShellCall(); + auto isToPermissionMgr = IsTargetPermission(want); + if (!isSACall && !isSystemAppCall && !isShellCall && !isToPermissionMgr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, + "Cannot start extension by start ability, use startServiceExtensionAbility."); + return ERR_WRONG_INTERFACE_CALL; + } + int result = CheckCallServicePermission(abilityRequest); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Check permission failed"); + } + return result; +} + +int AbilityManagerService::CheckServiceCallPermission(const AbilityRequest& abilityRequest, + const AppExecFwk::AbilityInfo& abilityInfo) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, + "Check call service or extension permission, name is %{public}s.", abilityInfo.name.c_str()); + int result = CheckCallServicePermission(abilityRequest); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Check permission failed"); + } + return result; +} + +int AbilityManagerService::CheckBrokerCallPermission(const AbilityRequest& abilityRequest, + const AppExecFwk::AbilityInfo& abilityInfo) +{ + // temp add for broker, remove when delete issacall + if (abilityRequest.collaboratorType != CollaboratorType::RESERVE_TYPE && !abilityInfo.visible) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "Check permission failed"); + return CHECK_PERMISSION_FAILED; + } + TAG_LOGD(AAFwkTag::ABILITYMGR, + "Check call service or extension permission, name is %{public}s.", abilityInfo.name.c_str()); + auto collaborator = GetCollaborator(CollaboratorType::RESERVE_TYPE); + if (collaborator == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Collaborator is nullptr."); + return CHECK_PERMISSION_FAILED; + } + int result = collaborator->CheckCallAbilityPermission(abilityRequest.want); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Check permission failed from broker."); + return CHECK_PERMISSION_FAILED; + } + return result; +} + +int AbilityManagerService::CheckAbilityCallPermission(const AbilityRequest& abilityRequest, + const AppExecFwk::AbilityInfo& abilityInfo, uint32_t specifyTokenId) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "Check call ability permission, name is %{public}s.", abilityInfo.name.c_str()); + int result = CheckCallAbilityPermission(abilityRequest, specifyTokenId); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Check permission failed"); + } + return result; +} + +int AbilityManagerService::CheckCallPermission(const Want& want, const AppExecFwk::AbilityInfo& abilityInfo, + const AbilityRequest& abilityRequest, bool isForegroundToRestartApp, + bool isSendDialogResult, uint32_t specifyTokenId, + const std::string& callerBundleName) +{ + auto type = abilityInfo.type; + if (type == AppExecFwk::AbilityType::DATA) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Cannot start data ability by start ability."); + return ERR_WRONG_INTERFACE_CALL; + } + if (type == AppExecFwk::AbilityType::EXTENSION) { + return CheckExtensionCallPermission(want, abilityRequest); + } + if (type == AppExecFwk::AbilityType::SERVICE) { + return CheckServiceCallPermission(abilityRequest, abilityInfo); + } + if ((callerBundleName == SHELL_ASSISTANT_BUNDLENAME && AppUtils::GetInstance().IsSupportAncoApp()) || + IPCSkeleton::GetCallingUid() == BROKER_UID) { + return CheckBrokerCallPermission(abilityRequest, abilityInfo); + } + if (!isForegroundToRestartApp && (!isSendDialogResult || want.GetBoolParam("isSelector", false))) { + return CheckAbilityCallPermission(abilityRequest, abilityInfo, specifyTokenId); + } + return ERR_OK; +} + int AbilityManagerService::StartAbilityInner(const Want &want, const sptr &callerToken, int requestCode, int32_t userId, bool isStartAsCaller, bool isSendDialogResult, uint32_t specifyTokenId, bool isForegroundToRestartApp, bool isImplicit) @@ -1017,23 +1107,16 @@ int AbilityManagerService::StartAbilityInner(const Want &want, const sptr(want)).RemoveParam("send_to_erms_embedded"); - Want localWant = want; - if (!localWant.GetDeviceId().empty()) { - localWant.SetDeviceId(""); - } - if (specifyTokenId > 0 && callerToken != nullptr) { // for sa specify tokenId and caller token - UpdateCallerInfoFromToken(localWant, callerToken); - } else if (!isStartAsCaller) { - TAG_LOGD(AAFwkTag::ABILITYMGR, "do not start as caller, UpdateCallerInfo"); - UpdateCallerInfo(localWant, callerToken); + Want localWant; + result = PreStartFreeInstall(want, callerToken, specifyTokenId, isStartAsCaller, localWant); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "PreStartFreeInstall failed."); + return result; } if (isStartFreeInstallByWant) { - return freeInstallManager_->StartFreeInstall(localWant, validUserId, requestCode, callerToken, true); + return freeInstallManager_->StartFreeInstall(localWant, validUserId, requestCode, + callerToken, true, specifyTokenId); } int32_t ret = freeInstallManager_->StartFreeInstall(localWant, validUserId, requestCode, callerToken, false); if (ret == ERR_OK) { @@ -1078,60 +1161,11 @@ int AbilityManagerService::StartAbilityInner(const Want &want, const sptrIsSACall(); - auto isSystemAppCall = AAFwk::PermissionVerification::GetInstance()->IsSystemAppCall(); - auto isShellCall = AAFwk::PermissionVerification::GetInstance()->IsShellCall(); - auto isToPermissionMgr = IsTargetPermission(want); - if (!isSACall && !isSystemAppCall && !isShellCall && !isToPermissionMgr) { - TAG_LOGE(AAFwkTag::ABILITYMGR, - "Cannot start extension by start ability, use startServiceExtensionAbility."); - return ERR_WRONG_INTERFACE_CALL; - } - result = CheckCallServicePermission(abilityRequest); - if (result != ERR_OK) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "Check permission failed"); - return result; - } - } else if (type == AppExecFwk::AbilityType::SERVICE) { - TAG_LOGD(AAFwkTag::ABILITYMGR, - "Check call service or extension permission, name is %{public}s.", abilityInfo.name.c_str()); - result = CheckCallServicePermission(abilityRequest); - if (result != ERR_OK) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "Check permission failed"); - return result; - } - } else if ((callerBundleName == SHELL_ASSISTANT_BUNDLENAME && AppUtils::GetInstance().IsSupportAncoApp()) || - IPCSkeleton::GetCallingUid() == BROKER_UID) { - // temp add for broker, remove when delete issacall - if (abilityRequest.collaboratorType != CollaboratorType::RESERVE_TYPE && !abilityInfo.visible) { - TAG_LOGD(AAFwkTag::ABILITYMGR, "Check permission failed"); - return CHECK_PERMISSION_FAILED; - } - TAG_LOGD(AAFwkTag::ABILITYMGR, - "Check call service or extension permission, name is %{public}s.", abilityInfo.name.c_str()); - auto collaborator = GetCollaborator(CollaboratorType::RESERVE_TYPE); - if (collaborator == nullptr) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "Collaborator is nullptr."); - return CHECK_PERMISSION_FAILED; - } - result = collaborator->CheckCallAbilityPermission(abilityRequest.want); - if (result != ERR_OK) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "Check permission failed from broker."); - return CHECK_PERMISSION_FAILED; - } - } else if (!isForegroundToRestartApp && (!isSendDialogResult || want.GetBoolParam("isSelector", false))) { - TAG_LOGD(AAFwkTag::ABILITYMGR, "Check call ability permission, name is %{public}s.", abilityInfo.name.c_str()); - result = CheckCallAbilityPermission(abilityRequest, specifyTokenId); - if (result != ERR_OK) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "Check permission failed"); - return result; - } + result = CheckCallPermission(want, abilityInfo, abilityRequest, isForegroundToRestartApp, + isSendDialogResult, specifyTokenId, callerBundleName); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "CheckCallPermission error, result is %{public}d.", result); + return result; } Want newWant = abilityRequest.want; @@ -1170,16 +1204,9 @@ int AbilityManagerService::StartAbilityInner(const Want &want, const sptr(want)); - return connectManager->StartAbility(abilityRequest); + if (abilityInfo.type == AppExecFwk::AbilityType::SERVICE || + abilityInfo.type == AppExecFwk::AbilityType::EXTENSION) { + return StartAbilityByConnectManager(want, abilityRequest, abilityInfo, validUserId, callerToken); } if (!IsAbilityControllerStart(want, abilityInfo.bundleName)) { @@ -1224,6 +1251,42 @@ int AbilityManagerService::StartAbilityInner(const Want &want, const sptrStartAbility(abilityRequest); } +int AbilityManagerService::PreStartFreeInstall(const Want &want, sptr callerToken, + uint32_t specifyTokenId, bool isStartAsCaller, Want &localWant) +{ + if (freeInstallManager_ == nullptr) { + return ERR_INVALID_VALUE; + } + (const_cast(want)).RemoveParam("send_to_erms_embedded"); + localWant = want; + if (!localWant.GetDeviceId().empty()) { + localWant.SetDeviceId(""); + } + if (specifyTokenId > 0 && callerToken != nullptr) { // for sa specify tokenId and caller token + UpdateCallerInfoFromToken(localWant, callerToken); + } else if (!isStartAsCaller) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "do not start as caller, UpdateCallerInfo"); + UpdateCallerInfo(localWant, callerToken); + } else { + TAG_LOGD(AAFwkTag::ABILITYMGR, "start as caller, skip UpdateCallerInfo!"); + } + return ERR_OK; +} + +int AbilityManagerService::StartAbilityByConnectManager(const Want& want, const AbilityRequest& abilityRequest, + const AppExecFwk::AbilityInfo& abilityInfo, int validUserId, sptr callerToken) +{ + auto connectManager = GetConnectManagerByUserId(validUserId); + if (!connectManager) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "connectManager is nullptr. userId=%{public}d", validUserId); + return ERR_INVALID_VALUE; + } + TAG_LOGD(AAFwkTag::ABILITYMGR, "Start service or extension, name is %{public}s.", abilityInfo.name.c_str()); + ReportEventToRSS(abilityInfo, callerToken); + InsightIntentExecuteParam::RemoveInsightIntent(const_cast(want)); + return connectManager->StartAbility(abilityRequest); +} + int AbilityManagerService::StartAbility(const Want &want, const AbilityStartSetting &abilityStartSetting, const sptr &callerToken, int32_t userId, int requestCode) { @@ -1583,7 +1646,8 @@ int AbilityManagerService::StartAbilityForOptionInner(const Want &want, const St TAG_LOGD(AAFwkTag::ABILITYMGR, "do not start as caller, UpdateCallerInfo"); UpdateCallerInfo(localWant, callerToken); } - return freeInstallManager_->StartFreeInstall(localWant, validUserId, requestCode, callerToken, true); + return freeInstallManager_->StartFreeInstall(localWant, validUserId, requestCode, + callerToken, true, specifyTokenId); } if (!JudgeMultiUserConcurrency(validUserId)) { TAG_LOGE(AAFwkTag::ABILITYMGR, "Multi-user non-concurrent mode is not satisfied."); @@ -1926,6 +1990,52 @@ int AbilityManagerService::StartUIAbilityBySCB(sptr sessionInfo, bo return ERR_WRONG_INTERFACE_CALL; } + if (!(sessionInfo->want).HasParameter(KEY_SESSION_ID)) { + return StartUIAbilityBySCBDefault(sessionInfo, isColdStart); + } + + std::string sessionId = (sessionInfo->want).GetStringParam(KEY_SESSION_ID); + if (sessionId.empty()) { + return StartUIAbilityBySCBDefault(sessionInfo, isColdStart); + } + + TAG_LOGI(AAFwkTag::ABILITYMGR, "sessionId=%{public}s", sessionId.c_str()); + FreeInstallInfo taskInfo; + if (!freeInstallManager_->GetFreeInstallTaskInfo(sessionId, taskInfo)) { + TAG_LOGW(AAFwkTag::ABILITYMGR, "failed to find free isntall task"); + return StartUIAbilityBySCBDefault(sessionInfo, isColdStart); + } + + if (taskInfo.isInstalled) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "free install task is already finished"); + auto err = StartUIAbilityByPreInstallInner(sessionInfo, taskInfo.specifyTokenId, isColdStart); + if (err != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartUIAbilityByPreInstallInner failed."); + } + return err; + } + + { + std::lock_guard guard(preStartSessionMapLock_); + preStartSessionMap_.insert(std::make_pair(sessionId, sessionInfo)); + } + + TAG_LOGI(AAFwkTag::ABILITYMGR, "free install task is still in progress"); + const Want& want = sessionInfo->want; + if (freeInstallManager_ == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "freeInstallManager_ is nullptr."); + return ERR_INVALID_VALUE; + } + freeInstallManager_->SetSCBCallStatus(want.GetElement().GetBundleName(), want.GetElement().GetAbilityName(), + want.GetStringParam(Want::PARAM_RESV_START_TIME), true); + return ERR_OK; +} + +int AbilityManagerService::StartUIAbilityBySCBDefault(sptr sessionInfo, bool &isColdStart) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::ABILITYMGR, "Call."); + auto currentUserId = IPCSkeleton::GetCallingUid() / BASE_USER_RANGE; if (sessionInfo->userId == DEFAULT_INVAL_VALUE) { sessionInfo->userId = currentUserId; @@ -10869,5 +10979,288 @@ void AbilityManagerService::HandleRestartResidentProcessDependedOnWeb() CHECK_POINTER_LOG(appMgr, "get appMgr fail"); appMgr->RestartResidentProcessDependedOnWeb(); } + +int32_t AbilityManagerService::PreStartMission(const std::string& bundleName, const std::string& moduleName, + const std::string& abilityName, const std::string& startTime) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "Called."); + CHECK_CALLER_IS_SYSTEM_APP; + + if (!PermissionVerification::GetInstance()->VerifyPreStartAtomicServicePermission()) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "calling user is not ag."); + return ERR_PERMISSION_DENIED; + } + + if (!freeInstallManager_) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "freeInstallManager_ is nullptr."); + return ERR_INVALID_VALUE; + } + + FreeInstallInfo taskInfo; + if (!freeInstallManager_->GetFreeInstallTaskInfo(bundleName, abilityName, startTime, taskInfo)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, + "failed to find free install task info:bundleName=%{public}s,abilityName=%{public}s,startTime=%{public}s", + bundleName.c_str(), abilityName.c_str(), startTime.c_str()); + return ERR_FREE_INSTALL_TASK_NOT_EXIST; + } + + if (taskInfo.isInstalled) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "atomic service is already installed."); + return ERR_OK; + } + + return PreStartInner(taskInfo); +} + +int32_t AbilityManagerService::PreStartInner(const FreeInstallInfo& taskInfo) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "Called."); + + const Want& want = taskInfo.want; + sptr callerToken = taskInfo.callerToken; + + EventInfo eventInfo = BuildEventInfo(want, taskInfo.userId); + SendAbilityEvent(EventName::START_ABILITY, HiSysEventType::BEHAVIOR, eventInfo); + + if (callerToken != nullptr && !VerificationAllToken(callerToken)) { + eventInfo.errCode = ERR_INVALID_VALUE; + SendAbilityEvent(EventName::START_ABILITY_ERROR, HiSysEventType::FAULT, eventInfo); + return ERR_INVALID_CALLER; + } + + int32_t oriValidUserId = GetValidUserId(taskInfo.userId); + + int32_t appIndex = 0; + StartAbilityInfoWrap threadLocalInfo(want, oriValidUserId, + StartAbilityUtils::GetAppIndex(want, callerToken, appIndex), callerToken); + + AbilityRequest abilityRequest = { + .want = want, + .requestCode = taskInfo.requestCode, + .callerToken = callerToken, + .startSetting = nullptr + }; + + TAG_LOGD(AAFwkTag::ABILITYMGR, "do not start as caller, UpdateCallerInfo"); + UpdateCallerInfo(abilityRequest.want, callerToken); + + // sceneboard + abilityRequest.userId = oriValidUserId; + abilityRequest.want.SetParam(IS_CALL_BY_SCB, false); + std::string sessionId = std::to_string(std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count()); + abilityRequest.want.SetParam(KEY_SESSION_ID, sessionId); + auto uiAbilityManager = GetUIAbilityManagerByUserId(oriValidUserId); + CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_INVALID_VALUE); + sptr sessionInfo = nullptr; + auto errCode = uiAbilityManager->NotifySCBToPreStartUIAbility(abilityRequest, sessionInfo); + if (errCode != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "failed to notify sceneboard to pre-start uiability."); + return errCode; + } + freeInstallManager_->SetFreeInstallTaskSessionId(taskInfo.want.GetElement().GetBundleName(), + taskInfo.want.GetElement().GetAbilityName(), + taskInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME), sessionId); + + freeInstallManager_->SetPreStartMissionCallStatus(taskInfo.want.GetElement().GetBundleName(), + taskInfo.want.GetElement().GetAbilityName(), + taskInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME), + true); + return ERR_OK; +} + +int32_t AbilityManagerService::StartUIAbilityByPreInstall(const FreeInstallInfo &taskInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGI(AAFwkTag::ABILITYMGR, "Called."); + const auto& want = taskInfo.want; + auto sessionId = want.GetStringParam(KEY_SESSION_ID); + if (sessionId.empty()) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "session id is empty."); + return ERR_INVALID_VALUE; + } + auto bundleName = want.GetElement().GetBundleName(); + auto abilityName = want.GetElement().GetAbilityName(); + auto startTime = want.GetStringParam(Want::PARAM_RESV_START_TIME); + TAG_LOGI(AAFwkTag::ABILITYMGR, "Called." + "sessionId=%{public}s,bundleName=%{public}s,abilityName=%{public}s,startTime=%{public}s", + sessionId.c_str(), bundleName.c_str(), abilityName.c_str(), startTime.c_str()); + sptr sessionInfo = nullptr; + { + std::lock_guard guard(preStartSessionMapLock_); + auto it = preStartSessionMap_.find(sessionId); + if (it == preStartSessionMap_.end()) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "failed to find session info with sessionId=%{public}s", + sessionId.c_str()); + return ERR_INVALID_VALUE; + } + sessionInfo = it->second; + } + + if (!taskInfo.isStartUIAbilityBySCBCalled) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "Free install is finished, StartUIAbilityBySCB has not been called."); + return ERR_OK; + } + + int errCode = ERR_OK; + bool isColdStart = true; + if ((errCode = StartUIAbilityByPreInstallInner(sessionInfo, taskInfo.specifyTokenId, isColdStart)) != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "StartUIAbilityByPreInstallInner failed,errCode=%{public}d.", errCode); + } + RemovePreStartSession(sessionId); + return errCode; +} + +// StartUIAbilityByPreInstallInner is called when free install task is already finished +int AbilityManagerService::StartUIAbilityByPreInstallInner(sptr sessionInfo, + uint32_t specifyTokenId, bool &isColdStart) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "Called."); + auto callerToken = sessionInfo->callerToken; + const auto& want = sessionInfo->want; + const auto userId = sessionInfo->userId; + const auto requestCode = sessionInfo->requestCode; + bool isStartAsCaller = false; + + if (callerToken != nullptr && !VerificationAllToken(callerToken)) { + auto isSpecificSA = AAFwk::PermissionVerification::GetInstance()-> + CheckSpecificSystemAbilityAccessPermission(DMS_PROCESS_NAME); + if (!isSpecificSA) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "%{public}s VerificationAllToken failed.", __func__); + return ERR_INVALID_CALLER; + } + TAG_LOGI(AAFwkTag::ABILITYMGR, "%{public}s: Caller is specific system ability.", __func__); + } + + int32_t oriValidUserId = GetValidUserId(userId); + int32_t validUserId = oriValidUserId; + + int32_t appIndex = 0; + if (!StartAbilityUtils::GetAppIndex(want, callerToken, appIndex)) { + return ERR_APP_CLONE_INDEX_INVALID; + } + StartAbilityInfoWrap threadLocalInfo(want, validUserId, appIndex, callerToken); + AbilityInterceptorParam interceptorParam = AbilityInterceptorParam(want, requestCode, GetUserId(), + true, nullptr); + auto result = interceptorExecuter_ == nullptr ? ERR_INVALID_VALUE : + interceptorExecuter_->DoProcess(interceptorParam); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "interceptorExecuter_ is nullptr or DoProcess return error."); + return result; + } + + AbilityRequest abilityRequest; + result = GenerateAbilityRequest(want, requestCode, abilityRequest, callerToken, validUserId); + auto abilityRecord = Token::GetAbilityRecordByToken(callerToken); + std::string callerBundleName = abilityRecord ? abilityRecord->GetAbilityInfo().bundleName : ""; + + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Generate ability request local error."); + return result; + } + if (!UriUtils::GetInstance().CheckNonImplicitShareFileUri(abilityRequest)) { + return ERR_SHARE_FILE_URI_NON_IMPLICITLY; + } + + if (specifyTokenId > 0 && callerToken != nullptr) { // for sa specify tokenId and caller token + UpdateCallerInfoFromToken(abilityRequest.want, callerToken); + } else if (!isStartAsCaller) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "do not start as caller, UpdateCallerInfo"); + UpdateCallerInfo(abilityRequest.want, callerToken); + } else if (callerBundleName == BUNDLE_NAME_DIALOG) { +#ifdef SUPPORT_SCREEN + CHECK_POINTER_AND_RETURN(implicitStartProcessor_, ERR_IMPLICIT_START_ABILITY_FAIL); + implicitStartProcessor_->ResetCallingIdentityAsCaller(abilityRequest.want.GetIntParam( + Want::PARAM_RESV_CALLER_TOKEN, 0)); +#endif // SUPPORT_SCREEN + } + + auto abilityInfo = abilityRequest.abilityInfo; + validUserId = abilityInfo.applicationInfo.singleton ? U0_USER_ID : validUserId; + TAG_LOGD(AAFwkTag::ABILITYMGR, "userId is : %{public}d, singleton is : %{public}d", + validUserId, static_cast(abilityInfo.applicationInfo.singleton)); + + result = CheckStaticCfgPermission(abilityRequest, isStartAsCaller, + abilityRequest.want.GetIntParam(Want::PARAM_RESV_CALLER_TOKEN, 0), false, false, false); + if (result != AppExecFwk::Constants::PERMISSION_GRANTED) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "CheckStaticCfgPermission error, result is %{public}d.", result); + return ERR_STATIC_CFG_PERMISSION; + } + + result = CheckCallPermission(want, abilityInfo, abilityRequest, false, + false, specifyTokenId, callerBundleName); + if (result != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "CheckCallPermission error, result is %{public}d.", result); + return result; + } + + Want newWant = abilityRequest.want; + AbilityInterceptorParam afterCheckParam = AbilityInterceptorParam(newWant, requestCode, GetUserId(), + true, callerToken, std::make_shared(abilityInfo), isStartAsCaller); + result = afterCheckExecuter_ == nullptr ? ERR_INVALID_VALUE : + afterCheckExecuter_->DoProcess(afterCheckParam); + bool isReplaceWantExist = newWant.GetBoolParam("queryWantFromErms", false); + newWant.RemoveParam("queryWantFromErms"); + if (result != ERR_OK && isReplaceWantExist == false) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "DoProcess failed or replaceWant not exist"); + return result; + } + if (result != ERR_OK && isReplaceWantExist && + callerBundleName != BUNDLE_NAME_DIALOG) { + std::string dialogSessionId; +#ifdef SUPPORT_SCREEN + std::vector dialogAppInfos(1); + if (GenerateDialogSessionRecord(abilityRequest, GetUserId(), dialogSessionId, dialogAppInfos, false)) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "create dialog by ui extension"); + return CreateModalDialog(newWant, callerToken, dialogSessionId); + } +#endif // SUPPORT_SCREEN + TAG_LOGE(AAFwkTag::ABILITYMGR, "create dialog by ui extension failed"); + return INNER_ERR; + } + + if (abilityInfo.type == AppExecFwk::AbilityType::SERVICE || + abilityInfo.type == AppExecFwk::AbilityType::EXTENSION) { + return StartAbilityByConnectManager(want, abilityRequest, abilityInfo, validUserId, callerToken); + } + + if (!IsAbilityControllerStart(want, abilityInfo.bundleName)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "IsAbilityControllerStart failed: %{public}s.", abilityInfo.bundleName.c_str()); + return ERR_WOULD_BLOCK; + } + + abilityRequest.want.RemoveParam(SPECIFY_TOKEN_ID); + if (specifyTokenId > 0) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "Set specifyTokenId, the specifyTokenId is %{public}d.", specifyTokenId); + abilityRequest.want.SetParam(SPECIFY_TOKEN_ID, static_cast(specifyTokenId)); + abilityRequest.specifyTokenId = specifyTokenId; + } + abilityRequest.want.RemoveParam(PARAM_SPECIFIED_PROCESS_FLAG); + + auto uiAbilityManager = GetCurrentUIAbilityManager(); + CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_INVALID_VALUE); + + return uiAbilityManager->StartUIAbility(abilityRequest, sessionInfo, isColdStart); +} + +void AbilityManagerService::NotifySCBToHandleException(sptr callerToken, int32_t errCode, + const std::string& reason) +{ + auto abilityRecord = Token::GetAbilityRecordByToken(callerToken); + if (abilityRecord == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "no such ability record matched token"); + return; + } + auto uiAbilityManager = GetCurrentUIAbilityManager(); + CHECK_POINTER(uiAbilityManager); + + return uiAbilityManager->NotifySCBToHandleException(abilityRecord, errCode, reason); +} + +void AbilityManagerService::RemovePreStartSession(const std::string& sessionId) +{ + std::lock_guard guard(preStartSessionMapLock_); + preStartSessionMap_.erase(sessionId); +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/ability_manager_stub.cpp b/services/abilitymgr/src/ability_manager_stub.cpp index adb20bfbb5..cf5eb84b3d 100644 --- a/services/abilitymgr/src/ability_manager_stub.cpp +++ b/services/abilitymgr/src/ability_manager_stub.cpp @@ -743,6 +743,9 @@ int AbilityManagerStub::OnRemoteRequestInnerNineteenth(uint32_t code, MessagePar if (interfaceCode == AbilityManagerInterfaceCode::NOTIFY_FROZEN_PROCESS_BY_RSS) { return NotifyFrozenProcessByRSSInner(data, reply); } + if (interfaceCode == AbilityManagerInterfaceCode::PRE_START_MISSION) { + return PreStartMissionInner(data, reply); + } return ERR_CODE_NOT_EXIST; } @@ -3892,5 +3895,16 @@ int32_t AbilityManagerStub::NotifyFrozenProcessByRSSInner(MessageParcel &data, M NotifyFrozenProcessByRSS(pidList, uid); return NO_ERROR; } + +int32_t AbilityManagerStub::PreStartMissionInner(MessageParcel &data, MessageParcel &reply) +{ + std::string bundleName = data.ReadString(); + std::string moduleName = data.ReadString(); + std::string abilityName = data.ReadString(); + std::string startTime = data.ReadString(); + int32_t result = PreStartMission(bundleName, moduleName, abilityName, startTime); + reply.WriteInt32(result); + return NO_ERROR; +} } // namespace AAFwk } // namespace OHOS \ No newline at end of file diff --git a/services/abilitymgr/src/free_install_manager.cpp b/services/abilitymgr/src/free_install_manager.cpp index 0613d673b1..d7e626a454 100644 --- a/services/abilitymgr/src/free_install_manager.cpp +++ b/services/abilitymgr/src/free_install_manager.cpp @@ -83,7 +83,7 @@ bool FreeInstallManager::IsTopAbility(const sptr &callerToken) } int FreeInstallManager::StartFreeInstall(const Want &want, int32_t userId, int requestCode, - const sptr &callerToken, bool isAsync) + const sptr &callerToken, bool isAsync, uint32_t specifyTokenId) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGI(AAFwkTag::FREE_INSTALL, "StartFreeInstall called"); @@ -91,7 +91,7 @@ int FreeInstallManager::StartFreeInstall(const Want &want, int32_t userId, int r if (!isSaCall && !IsTopAbility(callerToken)) { return NOT_TOP_ABILITY; } - FreeInstallInfo info = BuildFreeInstallInfo(want, userId, requestCode, callerToken, isAsync); + FreeInstallInfo info = BuildFreeInstallInfo(want, userId, requestCode, callerToken, isAsync, specifyTokenId); { std::lock_guard lock(freeInstallListLock_); freeInstallList_.push_back(info); @@ -162,13 +162,14 @@ int FreeInstallManager::RemoteFreeInstall(const Want &want, int32_t userId, int } FreeInstallInfo FreeInstallManager::BuildFreeInstallInfo(const Want &want, int32_t userId, int requestCode, - const sptr &callerToken, bool isAsync) + const sptr &callerToken, bool isAsync, uint32_t specifyTokenId) { FreeInstallInfo info = { .want = want, .userId = userId, .requestCode = requestCode, - .callerToken = callerToken + .callerToken = callerToken, + .specifyTokenId = specifyTokenId }; if (!isAsync) { auto promise = std::make_shared>(); @@ -259,42 +260,73 @@ void FreeInstallManager::NotifyFreeInstallResult(const Want &want, int resultCod bool isFromRemote = want.GetBoolParam(FROM_REMOTE_KEY, false); TAG_LOGI(AAFwkTag::FREE_INSTALL, "isFromRemote = %{public}d", isFromRemote); for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { - std::string bundleName = (*it).want.GetElement().GetBundleName(); - std::string abilityName = (*it).want.GetElement().GetAbilityName(); - std::string startTime = (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME); + FreeInstallInfo &freeInstallInfo = *it; + std::string bundleName = freeInstallInfo.want.GetElement().GetBundleName(); + std::string abilityName = freeInstallInfo.want.GetElement().GetAbilityName(); + std::string startTime = freeInstallInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME); if (want.GetElement().GetBundleName().compare(bundleName) != 0 || want.GetElement().GetAbilityName().compare(abilityName) != 0 || want.GetStringParam(Want::PARAM_RESV_START_TIME).compare(startTime) != 0) { - it++; continue; } - if (!isAsync && (*it).promise == nullptr) { + if (!isAsync && freeInstallInfo.promise == nullptr) { it++; continue; } - - if (resultCode == ERR_OK) { - TAG_LOGI(AAFwkTag::FREE_INSTALL, "FreeInstall success."); - if (isAsync) { - StartAbilityByFreeInstall(*it, bundleName, abilityName, startTime); - } else { - (*it).promise->set_value(resultCode); - } - } else { - TAG_LOGI(AAFwkTag::FREE_INSTALL, "FreeInstall failed."); - if (isAsync) { - DelayedSingleton::GetInstance()->OnInstallFinished( - bundleName, abilityName, startTime, resultCode); - } else { - (*it).promise->set_value(resultCode); - } - } - + freeInstallInfo.isInstalled = true; + HandleFreeInstallResult(freeInstallInfo, resultCode, isAsync); it = freeInstallList_.erase(it); } } +void FreeInstallManager::HandleOnFreeInstallSuccess(FreeInstallInfo &freeInstallInfo, bool isAsync) +{ + TAG_LOGI(AAFwkTag::FREE_INSTALL, "FreeInstall success."); + + if (isAsync) { + std::string startTime = freeInstallInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME); + std::string bundleName = freeInstallInfo.want.GetElement().GetBundleName(); + std::string abilityName = freeInstallInfo.want.GetElement().GetAbilityName(); + if (freeInstallInfo.isPreStartMissionCalled) { + StartAbilityByPreInstall(freeInstallInfo, bundleName, abilityName, startTime); + return; + } + StartAbilityByFreeInstall(freeInstallInfo, bundleName, abilityName, startTime); + return; + } + freeInstallInfo.promise->set_value(ERR_OK); +} + +void FreeInstallManager::HandleOnFreeInstallFail(FreeInstallInfo &freeInstallInfo, int resultCode, bool isAsync) +{ + TAG_LOGI(AAFwkTag::FREE_INSTALL, "FreeInstall failed."); + + if (isAsync) { + if (freeInstallInfo.isPreStartMissionCalled) { + DelayedSingleton::GetInstance()->NotifySCBToHandleException( + freeInstallInfo.callerToken, resultCode, "free install failed"); + } + std::string startTime = freeInstallInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME); + std::string bundleName = freeInstallInfo.want.GetElement().GetBundleName(); + std::string abilityName = freeInstallInfo.want.GetElement().GetAbilityName(); + + DelayedSingleton::GetInstance()->OnInstallFinished( + bundleName, abilityName, startTime, resultCode); + return; + } + freeInstallInfo.promise->set_value(resultCode); +} + +void FreeInstallManager::HandleFreeInstallResult(FreeInstallInfo &freeInstallInfo, int resultCode, bool isAsync) +{ + if (resultCode == ERR_OK) { + HandleOnFreeInstallSuccess(freeInstallInfo, isAsync); + return; + } + HandleOnFreeInstallFail(freeInstallInfo, resultCode, isAsync); +} + void FreeInstallManager::StartAbilityByFreeInstall(FreeInstallInfo &info, std::string &bundleName, std::string &abilityName, std::string &startTime) { @@ -315,6 +347,25 @@ void FreeInstallManager::StartAbilityByFreeInstall(FreeInstallInfo &info, std::s bundleName, abilityName, startTime, result); } +void FreeInstallManager::StartAbilityByPreInstall(FreeInstallInfo &info, std::string &bundleName, + std::string &abilityName, std::string &startTime) +{ + info.want.SetFlags(info.want.GetFlags() ^ Want::FLAG_INSTALL_ON_DEMAND); + auto identity = IPCSkeleton::ResetCallingIdentity(); + IPCSkeleton::SetCallingIdentity(info.identity); + int32_t result = ERR_OK; + if (info.want.GetElement().GetAbilityName().empty()) { + result = UpdateElementName(info.want, info.userId); + } + if (result == ERR_OK) { + result = DelayedSingleton::GetInstance()->StartUIAbilityByPreInstall(info); + } + IPCSkeleton::SetCallingIdentity(identity); + TAG_LOGI(AAFwkTag::FREE_INSTALL, "The result of StartAbility is %{public}d.", result); + DelayedSingleton::GetInstance()->OnInstallFinished( + bundleName, abilityName, startTime, result); +} + int32_t FreeInstallManager::UpdateElementName(Want &want, int32_t userId) const { auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper(); @@ -528,5 +579,79 @@ void FreeInstallManager::RemoveFreeInstallInfo(const std::string &bundleName, co } } } + +bool FreeInstallManager::GetFreeInstallTaskInfo(const std::string& bundleName, const std::string& abilityName, + const std::string& startTime, FreeInstallInfo& taskInfo) +{ + std::lock_guard lock(freeInstallListLock_); + for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { + if ((*it).want.GetElement().GetBundleName() == bundleName && + (*it).want.GetElement().GetAbilityName() == abilityName && + (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) { + taskInfo = *it; + return true; + } + it++; + } + return false; +} + +bool FreeInstallManager::GetFreeInstallTaskInfo(const std::string& sessionId, FreeInstallInfo& taskInfo) +{ + std::lock_guard lock(freeInstallListLock_); + for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { + if ((*it).want.GetStringParam(KEY_SESSION_ID) == sessionId) { + taskInfo = *it; + return true; + } + it++; + } + return false; +} + +void FreeInstallManager::SetSCBCallStatus(const std::string& bundleName, const std::string& abilityName, + const std::string& startTime, bool scbCallStatus) +{ + std::lock_guard lock(freeInstallListLock_); + for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { + if ((*it).want.GetElement().GetBundleName() == bundleName && + (*it).want.GetElement().GetAbilityName() == abilityName && + (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) { + (*it).isStartUIAbilityBySCBCalled = scbCallStatus; + return; + } + it++; + } +} + +void FreeInstallManager::SetPreStartMissionCallStatus(const std::string& bundleName, const std::string& abilityName, + const std::string& startTime, bool preStartMissionCallStatus) +{ + std::lock_guard lock(freeInstallListLock_); + for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { + if ((*it).want.GetElement().GetBundleName() == bundleName && + (*it).want.GetElement().GetAbilityName() == abilityName && + (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) { + (*it).isPreStartMissionCalled = preStartMissionCallStatus; + return; + } + it++; + } +} + +void FreeInstallManager::SetFreeInstallTaskSessionId(const std::string& bundleName, const std::string& abilityName, + const std::string& startTime, const std::string& sessionId) +{ + std::lock_guard lock(freeInstallListLock_); + for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { + if ((*it).want.GetElement().GetBundleName() == bundleName && + (*it).want.GetElement().GetAbilityName() == abilityName && + (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) { + (*it).want.SetParam(KEY_SESSION_ID, sessionId); + return; + } + it++; + } +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp b/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp index 24d589bbd3..1b9988980c 100644 --- a/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp +++ b/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp @@ -341,6 +341,7 @@ int UIAbilityLifecycleManager::NotifySCBToStartUIAbility(const AbilityRequest &a sessionInfo->persistentId = GetPersistentIdByAbilityRequest(abilityRequest, sessionInfo->reuse); sessionInfo->userId = userId_; sessionInfo->processOptions = abilityRequest.processOptions; + sessionInfo->isAtomicService = (abilityInfo.applicationInfo.bundleType == AppExecFwk::BundleType::ATOMIC_SERVICE); TAG_LOGI( AAFwkTag::ABILITYMGR, "Reused sessionId: %{public}d, userId: %{public}d.", sessionInfo->persistentId, userId_); int ret = NotifySCBPendingActivation(sessionInfo, abilityRequest); @@ -348,6 +349,18 @@ int UIAbilityLifecycleManager::NotifySCBToStartUIAbility(const AbilityRequest &a return ret; } +int UIAbilityLifecycleManager::NotifySCBToPreStartUIAbility(const AbilityRequest &abilityRequest, + sptr &sessionInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + + std::lock_guard guard(sessionLock_); + sessionInfo = CreateSessionInfo(abilityRequest); + sessionInfo->requestCode = abilityRequest.requestCode; + sessionInfo->isAtomicService = true; + return NotifySCBPendingActivation(sessionInfo, abilityRequest); +} + int UIAbilityLifecycleManager::DispatchState(const std::shared_ptr &abilityRecord, int state) { switch (state) { @@ -821,6 +834,7 @@ int UIAbilityLifecycleManager::CallAbilityLocked(const AbilityRequest &abilityRe NotifyAbilityToken(uiAbilityRecord->GetToken(), abilityRequest); // new version started by call type + const auto& abilityInfo = abilityRequest.abilityInfo; auto ret = ResolveAbility(uiAbilityRecord, abilityRequest); if (ret == ResolveResultType::OK_HAS_REMOTE_OBJ) { TAG_LOGD(AAFwkTag::ABILITYMGR, "target ability has been resolved."); @@ -831,6 +845,8 @@ int UIAbilityLifecycleManager::CallAbilityLocked(const AbilityRequest &abilityRe sessionInfo->state = CallToState::FOREGROUND; sessionInfo->reuse = reuse; sessionInfo->uiAbilityId = uiAbilityRecord->GetAbilityRecordId(); + sessionInfo->isAtomicService = + (abilityInfo.applicationInfo.bundleType == AppExecFwk::BundleType::ATOMIC_SERVICE); uiAbilityRecord->PostForegroundTimeoutTask(); DelayedSingleton::GetInstance()->MoveToForeground(uiAbilityRecord->GetToken()); return NotifySCBPendingActivation(sessionInfo, abilityRequest); @@ -845,6 +861,7 @@ int UIAbilityLifecycleManager::CallAbilityLocked(const AbilityRequest &abilityRe sessionInfo->persistentId = persistentId; sessionInfo->reuse = reuse; sessionInfo->uiAbilityId = uiAbilityRecord->GetAbilityRecordId(); + sessionInfo->isAtomicService = (abilityInfo.applicationInfo.bundleType == AppExecFwk::BundleType::ATOMIC_SERVICE); if (abilityRequest.want.GetBoolParam(Want::PARAM_RESV_CALL_TO_FOREGROUND, false)) { sessionInfo->state = CallToState::FOREGROUND; } else { @@ -1362,7 +1379,7 @@ void UIAbilityLifecycleManager::SetRootSceneSession(const sptr &r } void UIAbilityLifecycleManager::NotifySCBToHandleException(const std::shared_ptr &abilityRecord, - int32_t errorCode, std::string errorReason) + int32_t errorCode, const std::string& errorReason) { TAG_LOGD(AAFwkTag::ABILITYMGR, "call"); if (abilityRecord == nullptr) { @@ -1514,6 +1531,8 @@ void UIAbilityLifecycleManager::OnStartSpecifiedProcessResponse(const AAFwk::Wan sessionInfo->requestCode = abilityRequest.requestCode; sessionInfo->persistentId = GetPersistentIdByAbilityRequest(abilityRequest, sessionInfo->reuse); sessionInfo->userId = abilityRequest.userId; + sessionInfo->isAtomicService = + (abilityRequest.abilityInfo.applicationInfo.bundleType == AppExecFwk::BundleType::ATOMIC_SERVICE); TAG_LOGI(AAFwkTag::ABILITYMGR, "Reused sessionId: %{public}d, userId: %{public}d.", sessionInfo->persistentId, abilityRequest.userId); NotifySCBPendingActivation(sessionInfo, abilityRequest); @@ -2453,6 +2472,8 @@ int UIAbilityLifecycleManager::StartWithPersistentIdByDistributed(const AbilityR sessionInfo->persistentId = persistentId; sessionInfo->userId = userId_; sessionInfo->processOptions = abilityRequest.processOptions; + sessionInfo->isAtomicService = + (abilityRequest.abilityInfo.applicationInfo.bundleType == AppExecFwk::BundleType::ATOMIC_SERVICE); return NotifySCBPendingActivation(sessionInfo, abilityRequest); } diff --git a/services/common/include/permission_constants.h b/services/common/include/permission_constants.h index 25f5d28bc4..60c80808e0 100644 --- a/services/common/include/permission_constants.h +++ b/services/common/include/permission_constants.h @@ -56,6 +56,7 @@ constexpr const char* PERMISSION_START_SHORTCUT = "ohos.permission.START_SHORTCU constexpr const char* PERMISSION_PRELOAD_APPLICATION = "ohos.permission.PRELOAD_APPLICATION"; constexpr const char* PERMISSION_SET_PROCESS_CACHE_STATE = "ohos.permission.SET_PROCESS_CACHE_STATE"; constexpr const char* PERMISSION_PRELOAD_UI_EXTENSION_ABILITY = "ohos.permission.PRELOAD_UI_EXTENSION_ABILITY"; +constexpr const char* PERMISSION_PRE_START_ATOMIC_SERVICE = "ohos.permission.PRE_START_ATOMIC_SERVICE"; } // namespace PermissionConstants } // namespace AAFwk } // namespace OHOS diff --git a/services/common/include/permission_verification.h b/services/common/include/permission_verification.h index c45ab2a48a..b38bf5a2c6 100644 --- a/services/common/include/permission_verification.h +++ b/services/common/include/permission_verification.h @@ -101,6 +101,8 @@ struct VerificationInfo { bool VerifySetProcessCachePermission() const; + bool VerifyPreStartAtomicServicePermission() const; + private: DISALLOW_COPY_AND_MOVE(PermissionVerification); diff --git a/services/common/src/permission_verification.cpp b/services/common/src/permission_verification.cpp index c851f29542..92608fa1db 100644 --- a/services/common/src/permission_verification.cpp +++ b/services/common/src/permission_verification.cpp @@ -482,5 +482,17 @@ bool PermissionVerification::VerifySetProcessCachePermission() const TAG_LOGW(AAFwkTag::APPMGR, "Permission verification failed"); return false; } + +bool PermissionVerification::VerifyPreStartAtomicServicePermission() const +{ + if (VerifyCallingPermission(PermissionConstants::PERMISSION_PRE_START_ATOMIC_SERVICE)) { + TAG_LOGD(AAFwkTag::APPMGR, "verify permission %{public}s succeeded.", + PermissionConstants::PERMISSION_PRE_START_ATOMIC_SERVICE); + return true; + } + TAG_LOGW(AAFwkTag::APPMGR, "verify permission %{public}s failed.", + PermissionConstants::PERMISSION_PRE_START_ATOMIC_SERVICE); + return false; +} } // namespace AAFwk } // namespace OHOS