diff --git a/frameworks/js/napi/ability_context/ability_context.js b/frameworks/js/napi/ability_context/ability_context.js index fd296cfa55..af39506dc2 100644 --- a/frameworks/js/napi/ability_context/ability_context.js +++ b/frameworks/js/napi/ability_context/ability_context.js @@ -244,6 +244,22 @@ class AbilityContext extends Context { revokeDelegator() { return this.__context_impl__.revokeDelegator(); } + + startAppServiceExtensionAbility(want) { + return this.__context_impl__.startAppServiceExtensionAbility(want); + } + + stopAppServiceExtensionAbility(want) { + return this.__context_impl__.stopAppServiceExtensionAbility(want); + } + + connectAppServiceExtensionAbility(want, options) { + return this.__context_impl__.connectAppServiceExtensionAbility(want, options); + } + + disconnectAppServiceExtensionAbility(connection, callback) { + return this.__context_impl__.disconnectAppServiceExtensionAbility(connection, callback); + } } export default AbilityContext; diff --git a/frameworks/native/ability/ability_runtime/ability_context_impl.cpp b/frameworks/native/ability/ability_runtime/ability_context_impl.cpp index 1127347fa9..07ee28e036 100644 --- a/frameworks/native/ability/ability_runtime/ability_context_impl.cpp +++ b/frameworks/native/ability/ability_runtime/ability_context_impl.cpp @@ -1357,5 +1357,43 @@ void AbilityContextImpl::OnRequestFailure(const std::string &requestId, const Ap TAG_LOGE(AAFwkTag::CONTEXT, "requestId=%{public}s not exist", requestId.c_str()); } + + +ErrCode AbilityContextImpl::StartAppServiceExtensionAbility(const AAFwk::Want& want) +{ + TAG_LOGI(AAFwkTag::CONTEXT, "StartAppServiceExtensionAbility, name:%{public}s %{public}s", + want.GetElement().GetBundleName().c_str(), want.GetElement().GetAbilityName().c_str()); + ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility( + want, token_, DEFAULT_INVAL_VALUE, AppExecFwk::ExtensionAbilityType::APP_SERVICE); + if (err != ERR_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "failed:%{public}d", err); + } + return err; +} + +ErrCode AbilityContextImpl::StopAppServiceExtensionAbility(const AAFwk::Want& want) +{ + TAG_LOGD(AAFwkTag::CONTEXT, "StopAppServiceExtensionAbility, name:%{public}s %{public}s", + want.GetElement().GetBundleName().c_str(), want.GetElement().GetAbilityName().c_str()); + ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StopExtensionAbility( + want, token_, DEFAULT_INVAL_VALUE, AppExecFwk::ExtensionAbilityType::APP_SERVICE); + if (err != ERR_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "failed %{public}d", err); + } + return err; +} + +ErrCode AbilityContextImpl::ConnectAppServiceExtensionAbility(const AAFwk::Want& want, + const sptr& connectCallback) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGI(AAFwkTag::CONTEXT, "ConnectAppServiceExtensionAbility, caller:%{public}s, target:%{public}s", + abilityInfo_ == nullptr ? "" : abilityInfo_->name.c_str(), want.GetElement().GetAbilityName().c_str()); + ErrCode ret = ConnectionManager::GetInstance().ConnectAppServiceExtensionAbility(token_, want, connectCallback); + if (ret != ERR_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "failed %{public}d", ret); + } + return ret; +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/ability/ability_runtime/connection_manager.cpp b/frameworks/native/ability/ability_runtime/connection_manager.cpp index 5eae8cc435..32cdd0a94b 100644 --- a/frameworks/native/ability/ability_runtime/connection_manager.cpp +++ b/frameworks/native/ability/ability_runtime/connection_manager.cpp @@ -51,11 +51,19 @@ ErrCode ConnectionManager::ConnectAbilityWithAccount(const sptr& ErrCode ConnectionManager::ConnectUIServiceExtensionAbility(const sptr& connectCaller, const AAFwk::Want& want, const sptr& connectCallback) { - return ConnectAbilityInner(connectCaller, want, AAFwk::DEFAULT_INVAL_VALUE, connectCallback, true); + return ConnectAbilityInner(connectCaller, want, AAFwk::DEFAULT_INVAL_VALUE, connectCallback, + AppExecFwk::ExtensionAbilityType::UI_SERVICE); } -ErrCode ConnectionManager::ConnectAbilityInner(const sptr& connectCaller, - const AAFwk::Want& want, int accountId, const sptr& connectCallback, bool isUIService) +ErrCode ConnectionManager::ConnectAppServiceExtensionAbility(const sptr& connectCaller, + const AAFwk::Want& want, const sptr& connectCallback) +{ + return ConnectAbilityInner(connectCaller, want, AAFwk::DEFAULT_INVAL_VALUE, connectCallback, + AppExecFwk::ExtensionAbilityType::APP_SERVICE); +} + +ErrCode ConnectionManager::ConnectAbilityInner(const sptr& connectCaller, const AAFwk::Want& want, + int accountId, const sptr& connectCallback, AppExecFwk::ExtensionAbilityType extensionType) { if (connectCaller == nullptr || connectCallback == nullptr) { TAG_LOGE(AAFwkTag::CONNECTION, "null connectCaller or connectCallback"); @@ -96,10 +104,10 @@ ErrCode ConnectionManager::ConnectAbilityInner(const sptr& connec } else { TAG_LOGE(AAFwkTag::CONNECTION, "abilityConnection disconnected"); abilityConnections_.erase(connectionIter); - return CreateConnection(connectCaller, want, accountId, connectCallback, isUIService); + return CreateConnection(connectCaller, want, accountId, connectCallback, extensionType); } } else { - return CreateConnection(connectCaller, want, accountId, connectCallback, isUIService); + return CreateConnection(connectCaller, want, accountId, connectCallback, extensionType); } } @@ -138,8 +146,8 @@ bool ConnectionManager::MatchConnection( } } -ErrCode ConnectionManager::CreateConnection(const sptr& connectCaller, - const AAFwk::Want& want, int accountId, const sptr& connectCallback, bool isUIService) +ErrCode ConnectionManager::CreateConnection(const sptr& connectCaller, const AAFwk::Want& want, + int accountId, const sptr& connectCallback, AppExecFwk::ExtensionAbilityType extensionType) { TAG_LOGD(AAFwkTag::CONNECTION, "called"); sptr abilityConnection = new AbilityConnection(); @@ -150,13 +158,8 @@ ErrCode ConnectionManager::CreateConnection(const sptr& connectCa abilityConnection->AddConnectCallback(connectCallback); abilityConnection->SetConnectionState(CONNECTION_STATE_CONNECTING); ErrCode ret = ERR_OK; - if (isUIService) { - ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectUIServiceExtesnionAbility( - want, abilityConnection, connectCaller, accountId); - } else { - ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility( - want, abilityConnection, connectCaller, accountId); - } + ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbilityWithExtensionType( + want, abilityConnection, connectCaller, accountId, extensionType); std::lock_guard lock(connectionsLock_); if (ret == ERR_OK) { ConnectionInfo connectionInfo(connectCaller, want.GetOperation(), abilityConnection, accountId); 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 ef12b1b884..5c312bafd8 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 @@ -259,6 +259,8 @@ static std::unordered_map INNER_TO_JS_ERROR_CODE_MAP {ERR_NOT_HOOK, AbilityErrorCode::ERROR_CODE_NOT_HOOK}, {ERR_FROM_WINDOW, AbilityErrorCode::ERROR_CODE_FROM_WINDOW}, {ERR_INVALID_CONTEXT, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT}, + {ERR_TARGET_NOT_IN_APP_IDENTIFIER_ALLOW_LIST, AbilityErrorCode::ERROR_TARGET_NOT_IN_APP_IDENTIFIER_ALLOW_LIST}, + {ERR_TARGET_NOT_STARTED, AbilityErrorCode::ERROR_CODE_TARGET_NOT_STARTED}, }; } diff --git a/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp b/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp index 6f7ecb2160..dd7389583f 100644 --- a/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp @@ -414,6 +414,26 @@ napi_value JsAbilityContext::SetColorMode(napi_env env, napi_callback_info info) GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnSetColorMode); } +napi_value JsAbilityContext::StartAppServiceExtensionAbility(napi_env env, napi_callback_info info) +{ + GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnStartAppServiceExtensionAbility); +} + +napi_value JsAbilityContext::StopAppServiceExtensionAbility(napi_env env, napi_callback_info info) +{ + GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnStopAppServiceExtensionAbility); +} + +napi_value JsAbilityContext::ConnectAppServiceExtensionAbility(napi_env env, napi_callback_info info) +{ + GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnConnectAppServiceExtensionAbility); +} + +napi_value JsAbilityContext::DisconnectAppServiceExtensionAbility(napi_env env, napi_callback_info info) +{ + GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnDisconnectAbility); +} + napi_value JsAbilityContext::RevokeDelegator(napi_env env, napi_callback_info info) { GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnRevokeDelegator); @@ -1362,6 +1382,12 @@ napi_value JsAbilityContext::OnStartAbilityForResultWithAccount(napi_env env, Na napi_value JsAbilityContext::OnStartExtensionAbility(napi_env env, NapiCallbackInfo& info) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + return StartExtensionAbilityCommon(env, info, AppExecFwk::ExtensionAbilityType::SERVICE); +} + +napi_value JsAbilityContext::StartExtensionAbilityCommon(napi_env env, NapiCallbackInfo& info, + AppExecFwk::ExtensionAbilityType extensionType) +{ TAG_LOGI(AAFwkTag::CONTEXT, "called"); if (info.argc < ARGC_ONE) { ThrowTooFewParametersError(env); @@ -1376,14 +1402,21 @@ napi_value JsAbilityContext::OnStartExtensionAbility(napi_env env, NapiCallbackI } auto innerErrCode = std::make_shared(ERR_OK); NapiAsyncTask::ExecuteCallback execute = - [weak = context_, want, innerErrCode]() { + [weak = context_, want, innerErrCode, extensionType]() { auto context = weak.lock(); if (!context) { TAG_LOGW(AAFwkTag::CONTEXT, "null context"); *innerErrCode = static_cast(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); return; } - *innerErrCode = context->StartServiceExtensionAbility(want); + if (extensionType == AppExecFwk::ExtensionAbilityType::SERVICE) { + *innerErrCode = context->StartServiceExtensionAbility(want); + } else if (extensionType == AppExecFwk::ExtensionAbilityType::APP_SERVICE) { + *innerErrCode = context->StartAppServiceExtensionAbility(want); + } else { + TAG_LOGE(AAFwkTag::CONTEXT, "extensionType error, type: %{public}d", + static_cast(extensionType)); + } }; NapiAsyncTask::CompleteCallback complete = @@ -1399,7 +1432,7 @@ napi_value JsAbilityContext::OnStartExtensionAbility(napi_env env, NapiCallbackI napi_value lastParam = (info.argc > ARGC_ONE) ? info.argv[INDEX_ONE] : nullptr; napi_value result = nullptr; - NapiAsyncTask::ScheduleHighQos("JsAbilityContext::OnStartExtensionAbility", + NapiAsyncTask::ScheduleHighQos("JsAbilityContext::StartExtensionAbilityCommon", env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result)); return result; } @@ -1453,6 +1486,12 @@ napi_value JsAbilityContext::OnStartExtensionAbilityWithAccount(napi_env env, Na napi_value JsAbilityContext::OnStopExtensionAbility(napi_env env, NapiCallbackInfo& info) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + return StopExtensionAbilityCommon(env, info, AppExecFwk::ExtensionAbilityType::SERVICE); +} + +napi_value JsAbilityContext::StopExtensionAbilityCommon(napi_env env, NapiCallbackInfo& info, + AppExecFwk::ExtensionAbilityType extensionType) +{ TAG_LOGI(AAFwkTag::CONTEXT, "called"); if (info.argc < ARGC_ONE) { TAG_LOGE(AAFwkTag::CONTEXT, "param too few"); @@ -1467,14 +1506,21 @@ napi_value JsAbilityContext::OnStopExtensionAbility(napi_env env, NapiCallbackIn } auto innerErrCode = std::make_shared(ERR_OK); NapiAsyncTask::ExecuteCallback execute = - [weak = context_, want, innerErrCode]() { + [weak = context_, want, innerErrCode, extensionType]() { auto context = weak.lock(); if (!context) { TAG_LOGW(AAFwkTag::CONTEXT, "null context"); *innerErrCode = static_cast(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); return; } - *innerErrCode = context->StopServiceExtensionAbility(want); + if (extensionType == AppExecFwk::ExtensionAbilityType::SERVICE) { + *innerErrCode = context->StopServiceExtensionAbility(want); + } else if (extensionType == AppExecFwk::ExtensionAbilityType::APP_SERVICE) { + *innerErrCode = context->StopAppServiceExtensionAbility(want); + } else { + TAG_LOGE(AAFwkTag::CONTEXT, "extensionType error, type: %{public}d", + static_cast(extensionType)); + } }; NapiAsyncTask::CompleteCallback complete = [innerErrCode](napi_env env, NapiAsyncTask& task, int32_t status) { @@ -1489,7 +1535,7 @@ napi_value JsAbilityContext::OnStopExtensionAbility(napi_env env, NapiCallbackIn napi_value lastParam = (info.argc > ARGC_ONE) ? info.argv[INDEX_ONE] : nullptr; napi_value result = nullptr; - NapiAsyncTask::Schedule("JsAbilityContext::OnStopExtensionAbility", + NapiAsyncTask::Schedule("JsAbilityContext::StopExtensionAbilityCommon", env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result)); return result; } @@ -1648,6 +1694,12 @@ napi_value JsAbilityContext::OnBackToCallerAbilityWithResult(napi_env env, NapiC napi_value JsAbilityContext::OnConnectAbility(napi_env env, NapiCallbackInfo& info) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + return ConnectExtensionAbilityCommon(env, info, AppExecFwk::ExtensionAbilityType::SERVICE); +} + +napi_value JsAbilityContext::ConnectExtensionAbilityCommon(napi_env env, NapiCallbackInfo& info, + AppExecFwk::ExtensionAbilityType extensionType) +{ // only support two params if (info.argc < ARGC_TWO) { TAG_LOGE(AAFwkTag::CONTEXT, "invalid argc"); @@ -1668,15 +1720,23 @@ napi_value JsAbilityContext::OnConnectAbility(napi_env env, NapiCallbackInfo& in int64_t connectId = InsertConnection(connection, want); auto innerErrCode = std::make_shared(ERR_OK); NapiAsyncTask::ExecuteCallback execute = - [weak = context_, want, connection, connectId, innerErrCode]() { + [weak = context_, want, connection, connectId, innerErrCode, extensionType]() { auto context = weak.lock(); if (!context) { TAG_LOGE(AAFwkTag::CONTEXT, "null context"); *innerErrCode = static_cast(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); return; } - TAG_LOGD(AAFwkTag::CONTEXT, "connectAbility: %{public}d", static_cast(connectId)); - *innerErrCode = context->ConnectAbility(want, connection); + TAG_LOGD(AAFwkTag::CONTEXT, "connectAbility: %{public}d, extensionType: type: %{public}d", + static_cast(connectId), static_cast(extensionType)); + if (extensionType == AppExecFwk::ExtensionAbilityType::SERVICE) { + *innerErrCode = context->ConnectAbility(want, connection); + } else if (extensionType == AppExecFwk::ExtensionAbilityType::APP_SERVICE) { + *innerErrCode = context->ConnectAppServiceExtensionAbility(want, connection); + } else { + TAG_LOGE(AAFwkTag::CONTEXT, "extensionType error, type: %{public}d", + static_cast(extensionType)); + } }; NapiAsyncTask::CompleteCallback complete = [connection, connectId, innerErrCode](napi_env env, NapiAsyncTask& task, int32_t status) { @@ -1693,7 +1753,7 @@ napi_value JsAbilityContext::OnConnectAbility(napi_env env, NapiCallbackInfo& in } }; napi_value result = nullptr; - NapiAsyncTask::ScheduleHighQos("JsAbilityContext::OnConnectAbility", + NapiAsyncTask::ScheduleHighQos("JsAbilityContext::ConnectExtensionAbilityCommon", env, CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), &result)); return CreateJsValue(env, connectId); } @@ -2149,6 +2209,14 @@ napi_value CreateJsAbilityContext(napi_env env, std::shared_ptr BindNativeFunction(env, object, "setMissionIcon", moduleName, JsAbilityContext::SetMissionIcon); BindNativeFunction(env, object, "setAbilityInstanceInfo", moduleName, JsAbilityContext::SetAbilityInstanceInfo); #endif + BindNativeFunction(env, object, "startAppServiceExtensionAbility", moduleName, + JsAbilityContext::StartAppServiceExtensionAbility); + BindNativeFunction(env, object, "stopAppServiceExtensionAbility", moduleName, + JsAbilityContext::StopAppServiceExtensionAbility); + BindNativeFunction(env, object, "connectAppServiceExtensionAbility", moduleName, + JsAbilityContext::ConnectAppServiceExtensionAbility); + BindNativeFunction(env, object, "disconnectAppServiceExtensionAbility", moduleName, + JsAbilityContext::DisconnectAppServiceExtensionAbility); return object; } @@ -3000,6 +3068,24 @@ napi_value JsAbilityContext::OnRevokeDelegator(napi_env env, NapiCallbackInfo& i return result; } +napi_value JsAbilityContext::OnStartAppServiceExtensionAbility(napi_env env, NapiCallbackInfo& info) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + return StartExtensionAbilityCommon(env, info, AppExecFwk::ExtensionAbilityType::APP_SERVICE); +} + +napi_value JsAbilityContext::OnStopAppServiceExtensionAbility(napi_env env, NapiCallbackInfo& info) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + return StopExtensionAbilityCommon(env, info, AppExecFwk::ExtensionAbilityType::APP_SERVICE); +} + +napi_value JsAbilityContext::OnConnectAppServiceExtensionAbility(napi_env env, NapiCallbackInfo& info) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + return ConnectExtensionAbilityCommon(env, info, AppExecFwk::ExtensionAbilityType::APP_SERVICE); +} + int32_t JsAbilityContext::GenerateRequestCode() { std::lock_guard lock(requestCodeMutex_); 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 8f98b075b0..4f67d9c4f3 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_client.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_client.h @@ -550,6 +550,21 @@ public: sptr connect, sptr callerToken, int32_t userId = DEFAULT_INVAL_VALUE); + + /** + * ConnectAbilityWithExtensionType, connect session with specified extentionType ability. + * + * @param want, Special want for appService type's ability. + * @param connect, Callback used to notify caller the result of connecting or disconnecting. + * @param callerToken, caller ability token. + * @return Returns ERR_OK on success, others on failure. + */ + ErrCode ConnectAbilityWithExtensionType( + const Want &want, + sptr connect, + sptr callerToken, + int32_t userId = DEFAULT_INVAL_VALUE, + AppExecFwk::ExtensionAbilityType extensionType = AppExecFwk::ExtensionAbilityType::SERVICE); /** * ConnectUIServiceExtensionAbility, connect session with uiService ability. 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 52ec15105d..f2866e0f20 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_errors.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_errors.h @@ -787,6 +787,17 @@ enum { * Native error(2097331) for kill app while starting. */ ERR_KILL_APP_WHILE_STARTING = 2097331, + + /** + * Result (2097332) for target not in app identifier allow list. + */ + ERR_TARGET_NOT_IN_APP_IDENTIFIER_ALLOW_LIST = 2097332, + + /** + * Result (2097333) for target has not been started yet. + */ + ERR_TARGET_NOT_STARTED = 2097333, + /** * Native error(3000000) for target bundle not exist. */ diff --git a/interfaces/kits/native/ability/ability_runtime/ability_context.h b/interfaces/kits/native/ability/ability_runtime/ability_context.h index ee40075e11..c7fd8ed4e9 100644 --- a/interfaces/kits/native/ability/ability_runtime/ability_context.h +++ b/interfaces/kits/native/ability/ability_runtime/ability_context.h @@ -216,6 +216,18 @@ public: virtual ErrCode ConnectUIServiceExtensionAbility(const AAFwk::Want& want, const sptr& connectCallback) = 0; + virtual ErrCode StartAppServiceExtensionAbility(const AAFwk::Want &want) = 0; + virtual ErrCode StopAppServiceExtensionAbility(const AAFwk::Want& want) = 0; + /** + * @brief Connects the current ability to an appService ability using the AbilityInfo.AbilityType.SERVICE template. + * + * @param want Indicates the want containing information about the ability to connect + * @param connectCallback Indicates the callback object when the target ability is connected. + * @return True means success and false means failure + */ + virtual ErrCode ConnectAppServiceExtensionAbility(const AAFwk::Want& want, + const sptr& connectCallback) = 0; + /** * @brief Disconnects the current ability from an ability * diff --git a/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h b/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h index ad91904296..98bc1bf900 100644 --- a/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h +++ b/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h @@ -364,6 +364,11 @@ public: void OnRequestFailure(const std::string &requestId, const AppExecFwk::ElementName &element, const std::string &message) override; + ErrCode StartAppServiceExtensionAbility(const Want &want) override; + ErrCode StopAppServiceExtensionAbility(const Want& want) override; + ErrCode ConnectAppServiceExtensionAbility(const AAFwk::Want& want, + const sptr& connectCallback) override; + private: sptr token_ = nullptr; std::shared_ptr abilityInfo_ = nullptr; diff --git a/interfaces/kits/native/ability/ability_runtime/connection_manager.h b/interfaces/kits/native/ability/ability_runtime/connection_manager.h index 28660196f7..438ea931bf 100644 --- a/interfaces/kits/native/ability/ability_runtime/connection_manager.h +++ b/interfaces/kits/native/ability/ability_runtime/connection_manager.h @@ -23,6 +23,7 @@ #include "ability_connection.h" #include "element_name.h" #include "errors.h" +#include "extension_ability_info.h" #include "operation.h" #include "want.h" @@ -145,6 +146,17 @@ public: ErrCode ConnectUIServiceExtensionAbility(const sptr& connectCaller, const AAFwk::Want& want, const sptr& connectCallback); + /** + * @brief connect appService ability connection. + * + * @param connectCaller The connection caller. + * @param connectReceiver The connection receiver. + * @param connectCallback The connection callback. + * @return Returns the result of connecting appService ability connection. + */ + ErrCode ConnectAppServiceExtensionAbility(const sptr& connectCaller, + const AAFwk::Want& want, const sptr& connectCallback); + /** * @brief disconnect ability connection. * @@ -206,9 +218,10 @@ private: std::map>> abilityConnections_; ErrCode ConnectAbilityInner(const sptr &connectCaller, const AAFwk::Want &want, int accountId, const sptr &connectCallback, - bool isUIService = false); - ErrCode CreateConnection(const sptr &connectCaller, - const AAFwk::Want &want, int accountId, const sptr &connectCallback, bool isUIService); + AppExecFwk::ExtensionAbilityType extensionType = AppExecFwk::ExtensionAbilityType::SERVICE); + ErrCode CreateConnection(const sptr &connectCaller, const AAFwk::Want &want, int accountId, + const sptr &connectCallback, + AppExecFwk::ExtensionAbilityType extensionType = AppExecFwk::ExtensionAbilityType::SERVICE); bool IsConnectingTimeout(const ConnectionInfo& info); }; } // namespace AbilityRuntime 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 f380d3d155..e28f4b54e3 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 @@ -192,6 +192,12 @@ enum class AbilityErrorCode { // The interaction process between Ability and the Window encountered an error. ERROR_CODE_FROM_WINDOW = 16000085, + // the target not in app identifier allow list. + ERROR_TARGET_NOT_IN_APP_IDENTIFIER_ALLOW_LIST = 16000200, + + // the target has not been started yet. + ERROR_CODE_TARGET_NOT_STARTED = 16000201, + // invalid caller. ERROR_CODE_INVALID_CALLER = 16200001, diff --git a/interfaces/kits/native/ability/native/ability_runtime/js_ability_context.h b/interfaces/kits/native/ability/native/ability_runtime/js_ability_context.h index e3471d1bf0..8438244e57 100644 --- a/interfaces/kits/native/ability/native/ability_runtime/js_ability_context.h +++ b/interfaces/kits/native/ability/native/ability_runtime/js_ability_context.h @@ -75,6 +75,10 @@ public: static napi_value SetRestoreEnabled(napi_env env, napi_callback_info info); static napi_value SetColorMode(napi_env env, napi_callback_info info); static napi_value RevokeDelegator(napi_env env, napi_callback_info info); + static napi_value StartAppServiceExtensionAbility(napi_env env, napi_callback_info info); + static napi_value StopAppServiceExtensionAbility(napi_env env, napi_callback_info info); + static napi_value ConnectAppServiceExtensionAbility(napi_env env, napi_callback_info info); + static napi_value DisconnectAppServiceExtensionAbility(napi_env env, napi_callback_info info); static void ConfigurationUpdated(napi_env env, std::shared_ptr &jsContext, const std::shared_ptr &config); @@ -148,6 +152,15 @@ private: napi_value OnDisconnectUIServiceExtension(napi_env env, NapiCallbackInfo& info); napi_value OnSetColorMode(napi_env env, NapiCallbackInfo& info); napi_value OnRevokeDelegator(napi_env env, NapiCallbackInfo& info); + napi_value OnStartAppServiceExtensionAbility(napi_env env, NapiCallbackInfo& info); + napi_value OnStopAppServiceExtensionAbility(napi_env env, NapiCallbackInfo& info); + napi_value OnConnectAppServiceExtensionAbility(napi_env env, NapiCallbackInfo& info); + napi_value StartExtensionAbilityCommon(napi_env env, NapiCallbackInfo& info, + AppExecFwk::ExtensionAbilityType extensionType); + napi_value StopExtensionAbilityCommon(napi_env env, NapiCallbackInfo& info, + AppExecFwk::ExtensionAbilityType extensionType); + napi_value ConnectExtensionAbilityCommon(napi_env env, NapiCallbackInfo& info, + AppExecFwk::ExtensionAbilityType extensionType); static bool UnWrapWant(napi_env env, napi_value argv, AAFwk::Want& want); static napi_value WrapWant(napi_env env, const AAFwk::Want& want); diff --git a/services/abilitymgr/include/ability_connect_manager.h b/services/abilitymgr/include/ability_connect_manager.h index 67035891d2..3093d94f88 100644 --- a/services/abilitymgr/include/ability_connect_manager.h +++ b/services/abilitymgr/include/ability_connect_manager.h @@ -362,6 +362,14 @@ public: */ void HandleExtensionDisconnectTask(const std::shared_ptr &connectRecord); + /** + * GetServiceRecordByAbilityRequest. + * + * @param abilityRequest, the request of the service ability to start. + * @return Returns AbilityRecord shared_ptr. + */ + std::shared_ptr GetServiceRecordByAbilityRequest(const AbilityRequest &abilityRequest); + private: /** * StartAbilityLocked with request. diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index 648709a7e7..3d952a189f 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -2122,6 +2122,17 @@ protected: int32_t GetCollaboratorType(const std::string &codePath) const; int32_t KillProcessForCollaborator(int32_t collaboratorType, const std::string &bundleName, int32_t userId); + + /** + * Check if Caller is allowed to start AppServiceExtension(Stage). + * + * @param abilityRequest, abilityRequest. + * @param isVerifyAppIdentifierAllowList, isVerifyAppIdentifierAllowList + * @param isFromConnect, isFromConnect + * @return Returns whether the caller is allowed to start AppServiceExtension. + */ + int32_t CheckCallAppServiceExtensionPermission(const AbilityRequest &abilityRequest, + bool isVerifyAppIdentifierAllowList, bool isFromConnect); private: int TerminateAbilityWithFlag(const sptr &token, int resultCode = DEFAULT_INVAL_VALUE, const Want *resultWant = nullptr, bool flag = true); @@ -2543,6 +2554,7 @@ private: int32_t CheckRestartAppWant(const AAFwk::Want &want, int32_t appIndex, int32_t userId); int32_t CheckDebugAssertPermission(); + bool VerifySameAppOrAppIdentifierAllowListPermission(const AbilityRequest &abilityRequest); std::shared_ptr ConnectInitAbilityDebugDeal(); int32_t SetBackgroundCall(const AppExecFwk::RunningProcessInfo &processInfo, diff --git a/services/abilitymgr/src/ability_connect_manager.cpp b/services/abilitymgr/src/ability_connect_manager.cpp index e57c983949..e864da9cad 100644 --- a/services/abilitymgr/src/ability_connect_manager.cpp +++ b/services/abilitymgr/src/ability_connect_manager.cpp @@ -1366,6 +1366,15 @@ void AbilityConnectManager::CompleteStartServiceReq(const std::string &serviceUr } } +std::shared_ptr AbilityConnectManager::GetServiceRecordByAbilityRequest( + const AbilityRequest &abilityRequest) +{ + AppExecFwk::ElementName element(abilityRequest.abilityInfo.deviceId, GenerateBundleName(abilityRequest), + abilityRequest.abilityInfo.name, abilityRequest.abilityInfo.moduleName); + std::string serviceKey = element.GetURI(); + return GetServiceRecordByElementName(serviceKey); +} + std::shared_ptr AbilityConnectManager::GetServiceRecordByElementName(const std::string &element) { std::lock_guard guard(serviceMapMutex_); diff --git a/services/abilitymgr/src/ability_manager_client.cpp b/services/abilitymgr/src/ability_manager_client.cpp index b1b5b8ab99..193f5239b8 100644 --- a/services/abilitymgr/src/ability_manager_client.cpp +++ b/services/abilitymgr/src/ability_manager_client.cpp @@ -553,6 +553,19 @@ ErrCode AbilityManagerClient::ConnectAbility( return abms->ConnectAbilityCommon(want, connect, callerToken, AppExecFwk::ExtensionAbilityType::SERVICE, userId); } +ErrCode AbilityManagerClient::ConnectAbilityWithExtensionType( + const Want &want, sptr connect, sptr callerToken, int32_t userId, + AppExecFwk::ExtensionAbilityType extensionType) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + auto abms = GetAbilityManager(); + CHECK_POINTER_RETURN_NOT_CONNECTED(abms); + TAG_LOGI(AAFwkTag::ABILITYMGR, "name:%{public}s %{public}s, userId:%{public}d", + want.GetElement().GetBundleName().c_str(), want.GetElement().GetAbilityName().c_str(), userId); + return abms->ConnectAbilityCommon(want, connect, callerToken, + extensionType, userId); +} + ErrCode AbilityManagerClient::ConnectUIServiceExtesnionAbility( const Want &want, sptr connect, sptr callerToken, int32_t userId) { diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index 4dc0509d90..5b66820036 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -2753,6 +2753,11 @@ int AbilityManagerService::CheckOptExtensionAbility(const Want &want, AbilityReq if (result != ERR_OK) { return result; } + } else if (abilityInfo.extensionAbilityType == AppExecFwk::ExtensionAbilityType::APP_SERVICE) { + result = CheckCallAppServiceExtensionPermission(abilityRequest, true, false); + if (result != ERR_OK) { + return result; + } } else { result = CheckCallOtherExtensionPermission(abilityRequest); if (result != ERR_OK) { @@ -2998,7 +3003,8 @@ int32_t AbilityManagerService::StartExtensionAbility(const Want &want, const spt } InsightIntentExecuteParam::RemoveInsightIntent(const_cast(want)); if (extensionType == AppExecFwk::ExtensionAbilityType::VPN || - extensionType == AppExecFwk::ExtensionAbilityType::UI_SERVICE) { + extensionType == AppExecFwk::ExtensionAbilityType::UI_SERVICE || + extensionType == AppExecFwk::ExtensionAbilityType::APP_SERVICE) { return StartExtensionAbilityInner(want, callerToken, userId, extensionType, false); } return StartExtensionAbilityInner(want, callerToken, userId, extensionType, true); @@ -4830,7 +4836,23 @@ int32_t AbilityManagerService::ConnectLocalAbility(const Want &want, const int32 return result; } - result = CheckCallServicePermission(abilityRequest); + auto connectManager = GetConnectManagerByUserId(validUserId); + if (connectManager == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "connectManager null userId=%{public}d", validUserId); + return ERR_INVALID_VALUE; + } + + if (extensionType == AppExecFwk::ExtensionAbilityType::APP_SERVICE) { + auto targetService = connectManager->GetServiceRecordByAbilityRequest(abilityRequest); + if (targetService != nullptr && targetService->IsAbilityState(AbilityState::ACTIVE)) { + result = CheckCallAppServiceExtensionPermission(abilityRequest, false, true); + } else { + result = CheckCallAppServiceExtensionPermission(abilityRequest, true, true); + } + TAG_LOGD(AAFwkTag::SERVICE_EXT, "CheckCallAppServiceExtensionPermission result: %{public}d", result); + } else { + result = CheckCallServicePermission(abilityRequest); + } if (result != ERR_OK) { TAG_LOGE(AAFwkTag::SERVICE_EXT, "%{public}s checkCallServicePermission error", __func__); return result; @@ -4851,12 +4873,6 @@ int32_t AbilityManagerService::ConnectLocalAbility(const Want &want, const int32 return result; } - auto connectManager = GetConnectManagerByUserId(validUserId); - if (connectManager == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "connectManager null userId=%{public}d", validUserId); - return ERR_INVALID_VALUE; - } - SetAbilityRequestSessionInfo(abilityRequest, targetExtensionType); if (!ResSchedUtil::GetInstance().NeedReportByPidWhenConnect(abilityInfo)) { // these extension type is reported in connectManager instead of here @@ -10268,6 +10284,25 @@ AAFwk::PermissionVerification::VerificationInfo AbilityManagerService::CreateVer return verificationInfo; } +int32_t AbilityManagerService::CheckCallAppServiceExtensionPermission(const AbilityRequest &abilityRequest, + bool isVerifyAppIdentifierAllowList, bool isFromConnect) +{ + if (!AppUtils::GetInstance().IsSupportAppServiceExtension()) { + return ERR_CAPABILITY_NOT_SUPPORT; + } + if (isVerifyAppIdentifierAllowList && !VerifySameAppOrAppIdentifierAllowListPermission(abilityRequest)) { + if (isFromConnect) { + return ERR_TARGET_NOT_STARTED; + } + return ERR_TARGET_NOT_IN_APP_IDENTIFIER_ALLOW_LIST; + } + if (!PermissionVerification::GetInstance()->VerifyPermissionByTokenId(abilityRequest.appInfo.accessTokenId, + PermissionConstants::PERMISSION_SUPPORT_APP_SERVICE_EXTENSION)) { + return CHECK_PERMISSION_FAILED; + } + return ERR_OK; +} + int AbilityManagerService::CheckCallServiceExtensionPermission(const AbilityRequest &abilityRequest) { TAG_LOGD(AAFwkTag::ABILITYMGR, "begin"); @@ -12188,6 +12223,54 @@ int32_t AbilityManagerService::CheckDebugAssertPermission() return ERR_OK; } +bool AbilityManagerService::VerifySameAppOrAppIdentifierAllowListPermission(const AbilityRequest &abilityRequest) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "called"); + std::string targetBundleName = abilityRequest.abilityInfo.bundleName; + int32_t callerUid = IPCSkeleton::GetCallingUid(); + int32_t targetUid = abilityRequest.uid; + if (callerUid == targetUid) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "same app"); + return true; + } + auto bms = AbilityUtil::GetBundleManagerHelper(); + CHECK_POINTER_AND_RETURN(bms, false); + AppExecFwk::BundleInfo targetBundleInfo; + int32_t userId = GetUserId(); + std::string callerAppIdentifier = abilityRequest.want.GetStringParam(Want::PARAM_RESV_CALLER_APP_IDENTIFIER); + if (callerAppIdentifier.empty()) { + AppExecFwk::SignatureInfo signatureInfo; + auto abilityRecord = Token::GetAbilityRecordByToken(abilityRequest.callerToken); + if (abilityRecord == nullptr) { + return false; + } + std::string callerBundleName = abilityRecord->GetApplicationInfo().bundleName; + if (IN_PROCESS_CALL(bms->GetSignatureInfoByBundleName(callerBundleName, + signatureInfo)) != ERR_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, + "bms GetSignatureInfoByBundleName error, bundleName: %{public}s", callerBundleName.c_str()); + return false; + }; + callerAppIdentifier = signatureInfo.appIdentifier; + } + if (!IN_PROCESS_CALL(bms->GetBundleInfo(targetBundleName, AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, + targetBundleInfo, userId))) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "bms GetBundleInfo error, BundleFlag: GET_BUNDLE_WITH_EXTENSION_INFO"); + return false; + } + for (const AppExecFwk::ExtensionAbilityInfo& info: targetBundleInfo.extensionInfos) { + if (info.type == AppExecFwk::ExtensionAbilityType::APP_SERVICE && + info.name == abilityRequest.abilityInfo.name) { + if (std::find(info.appIdentifierAllowList.begin(), info.appIdentifierAllowList.end(), + callerAppIdentifier) != info.appIdentifierAllowList.end()) { + return true; + } + return false; + } + } + return false; +} + void AbilityManagerService::CloseAssertDialog(const std::string &assertSessionId) { TAG_LOGD(AAFwkTag::ABILITYMGR, "Close assert fault dialog begin."); diff --git a/services/common/include/app_utils.h b/services/common/include/app_utils.h index f6dee306f4..075017b38f 100644 --- a/services/common/include/app_utils.h +++ b/services/common/include/app_utils.h @@ -291,6 +291,13 @@ public: */ bool IsConnectSupportCrossUser(); + /** + * IsSupportAppServiceExtension, check if it support app service extension. + * + * @return Whether it supports app service extension. + */ + bool IsSupportAppServiceExtension(); + /** * IsPrepareTerminateEnabled, check if it supports prepare terminate. * @@ -393,6 +400,7 @@ private: volatile DeviceConfiguration isSupportMultiInstance_ = {false, false}; std::mutex isConnectSupportCrossUserMutex_; volatile DeviceConfiguration isConnectSupportCrossUser_ = {false, false}; + volatile DeviceConfiguration isSupportAppServiceExtension_ = {false, false}; DeviceConfiguration>> residentProcessInExtremeMemory_ = {false, {}}; std::mutex residentProcessInExtremeMemoryMutex_; diff --git a/services/common/include/permission_constants.h b/services/common/include/permission_constants.h index 6a321a7cda..ebf1219337 100644 --- a/services/common/include/permission_constants.h +++ b/services/common/include/permission_constants.h @@ -75,6 +75,7 @@ constexpr const char* PERMISSION_NDK_START_SELF_UI_ABILITY = "ohos.permission.ND constexpr const char* PERMISSION_FUSION_ACCESS = "ohos.permission.ACCESS_AMS_FROM_FUSION"; constexpr const char* PERMISSION_CUSTOM_SANDBOX = "ohos.permission.CUSTOM_SANDBOX"; constexpr const char* PERMISSION_FILE_ACCESS_PERSIST = "ohos.permission.FILE_ACCESS_PERSIST"; +constexpr const char* PERMISSION_SUPPORT_APP_SERVICE_EXTENSION = "ohos.permission.SUPPORT_APP_SERVICE_EXTENSION"; } // namespace PermissionConstants } // namespace AAFwk } // namespace OHOS diff --git a/services/common/src/app_utils.cpp b/services/common/src/app_utils.cpp index 79f9c143df..3fab5e70b9 100644 --- a/services/common/src/app_utils.cpp +++ b/services/common/src/app_utils.cpp @@ -77,6 +77,7 @@ constexpr const char* MAX_CHILD_PROCESS = "const.max_native_child_process"; constexpr const char* SUPPORT_MULTI_INSTANCE = "const.abilityms.support_multi_instance"; constexpr const char* MIGRATE_CLIENT_BUNDLE_NAME = "const.sys.abilityms.migrate_client_bundle_name"; constexpr const char* CONNECT_SUPPORT_CROSS_USER = "const.abilityms.connect_support_cross_user"; +constexpr const char* SUPPORT_APP_SERVICE_EXTENSION = "const.abilityms.support_app_service"; // Support prepare terminate constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6; constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate"; @@ -725,5 +726,15 @@ bool AppUtils::InResidentWhiteList(const std::string &bundleName) } return false; } + +bool AppUtils::IsSupportAppServiceExtension() +{ + if (!isSupportAppServiceExtension_.isLoaded) { + isSupportAppServiceExtension_.value = system::GetBoolParameter(SUPPORT_APP_SERVICE_EXTENSION, false); + isSupportAppServiceExtension_.isLoaded = true; + } + TAG_LOGD(AAFwkTag::DEFAULT, "called %{public}d", isSupportAppServiceExtension_.value); + return isSupportAppServiceExtension_.value; +} } // namespace AAFwk } // namespace OHOS diff --git a/test/unittest/frameworks_kits_ability_ability_runtime_test/ability_context_test.cpp b/test/unittest/frameworks_kits_ability_ability_runtime_test/ability_context_test.cpp index 0831c72138..ca16d1f8f0 100644 --- a/test/unittest/frameworks_kits_ability_ability_runtime_test/ability_context_test.cpp +++ b/test/unittest/frameworks_kits_ability_ability_runtime_test/ability_context_test.cpp @@ -309,6 +309,19 @@ public: { return ERR_OK; } + virtual ErrCode StartAppServiceExtensionAbility(const AAFwk::Want &want) + { + return ERR_OK; + } + virtual ErrCode StopAppServiceExtensionAbility(const AAFwk::Want& want) + { + return ERR_OK; + } + virtual ErrCode ConnectAppServiceExtensionAbility(const AAFwk::Want& want, + const sptr& connectCallback) + { + return ERR_OK; + } virtual void DisconnectAbility(const AAFwk::Want &want, const sptr &connectCallback, int32_t accountId = -1) { diff --git a/test/unittest/frameworks_kits_ability_native_test/ability_connection_manager_test.cpp b/test/unittest/frameworks_kits_ability_native_test/ability_connection_manager_test.cpp index 89eb119629..7026b28ffc 100644 --- a/test/unittest/frameworks_kits_ability_native_test/ability_connection_manager_test.cpp +++ b/test/unittest/frameworks_kits_ability_native_test/ability_connection_manager_test.cpp @@ -280,7 +280,7 @@ HWTEST_F(ConnectionManagerTest, CreateConnection_0100, TestSize.Level1) AAFwk::Want want; int32_t accountId = 0; sptr connectCallback = new (std::nothrow) MockAbilityConnectCallback(); - auto result = mgr->CreateConnection(connectCallernew, want, accountId, connectCallback, false); + auto result = mgr->CreateConnection(connectCallernew, want, accountId, connectCallback); EXPECT_EQ(result, AAFwk::CHECK_PERMISSION_FAILED); GTEST_LOG_(INFO) << "ConnectionManagerTest CreateConnection_0100 end"; }