diff --git a/agent_runtime_framework/frameworks/ets/ani/agent_extension_ability/include/connection/ets_agent_connection.h b/agent_runtime_framework/frameworks/ets/ani/agent_extension_ability/include/connection/ets_agent_connection.h index 8f0e329c39..931a539b13 100644 --- a/agent_runtime_framework/frameworks/ets/ani/agent_extension_ability/include/connection/ets_agent_connection.h +++ b/agent_runtime_framework/frameworks/ets/ani/agent_extension_ability/include/connection/ets_agent_connection.h @@ -76,13 +76,15 @@ int64_t InsertAgentConnection(sptr connection, const AAFwk:: void FindAgentConnection(int64_t connectId, sptr &connection); /** - * Find agent connection by target identity. + * Find agent connection by want and callback. * + * @param env The ANI environment. * @param want The want information to match. - * @param agentId The agent ID to match. + * @param callback The callback object to match. * @param connection Output parameter for the found connection. */ -void FindAgentConnection(const AAFwk::Want &want, const std::string &agentId, sptr &connection); +void FindAgentConnection(ani_env *env, AAFwk::Want &want, ani_object callback, + sptr &connection); } class EtsAgentConnectorStubImpl; @@ -162,7 +164,7 @@ public: * * @param duplicatedCallback The callback object from ETS. */ - bool AddDuplicatedPendingCallback(ani_object duplicatedCallback); + void AddDuplicatedPendingCallback(ani_object duplicatedCallback); /** * Resolve all duplicated pending callbacks with the proxy. diff --git a/agent_runtime_framework/frameworks/ets/ani/agent_extension_ability/src/connection/ets_agent_connection.cpp b/agent_runtime_framework/frameworks/ets/ani/agent_extension_ability/src/connection/ets_agent_connection.cpp index 7ac9925d56..b86b26c061 100644 --- a/agent_runtime_framework/frameworks/ets/ani/agent_extension_ability/src/connection/ets_agent_connection.cpp +++ b/agent_runtime_framework/frameworks/ets/ani/agent_extension_ability/src/connection/ets_agent_connection.cpp @@ -37,22 +37,6 @@ constexpr const char *SIGNATURE_AGENT_EXTENSION_CALLBACK = "application.AgentExtensionConnectCallback.AgentExtensionConnectCallback"; constexpr const char *SIGNATURE_ON_DATA_AND_AUTH = "C{std.core.String}:"; constexpr const char *SIGNATURE_VOID = ":"; - -bool IsSameAgentConnection(const AAFwk::Want &storedWant, const AAFwk::Want &want, const std::string &agentId) -{ - std::string existingId = storedWant.GetStringParam(AGENTID_KEY); - if (existingId.empty() || agentId.empty() || existingId != agentId) { - return false; - } - const auto &storedElement = storedWant.GetElement(); - const auto &element = want.GetElement(); - if (storedElement.GetBundleName() != element.GetBundleName() || - storedElement.GetAbilityName() != element.GetAbilityName()) { - return false; - } - return storedElement.GetModuleName().empty() || element.GetModuleName().empty() || - storedElement.GetModuleName() == element.GetModuleName(); -} } // namespace namespace AgentConnectionUtils { @@ -117,13 +101,21 @@ void FindAgentConnection(int64_t connectId, sptr &connection } } -void FindAgentConnection(const AAFwk::Want &want, const std::string &agentId, sptr &connection) +void FindAgentConnection(ani_env *env, AAFwk::Want &want, ani_object callback, + sptr &connection) { - TAG_LOGD(AAFwkTag::SER_ROUTER, "FindAgentConnection by target"); + TAG_LOGD(AAFwkTag::SER_ROUTER, "FindAgentConnection by want+callback"); std::lock_guard lock(g_agentConnectsLock_); auto item = std::find_if(g_agentConnects.begin(), g_agentConnects.end(), - [&want, &agentId](const auto &obj) { - return IsSameAgentConnection(obj.first.want, want, agentId); + [&want, env, callback](const auto &obj) { + std::string existingId = obj.first.want.GetStringParam(AGENTID_KEY); + std::string agentId = want.GetStringParam(AGENTID_KEY); + bool wantEquals = obj.first.want.GetElement() == want.GetElement() && + !existingId.empty() && !agentId.empty() && existingId == agentId; + ani_ref tempCallbackRef = obj.second->GetEtsConnectionObject(); + bool callbackObjectEquals = + EtsAgentConnection::IsEtsCallbackObjectEquals(env, tempCallbackRef, callback); + return wantEquals && callbackObjectEquals; }); if (item == g_agentConnects.end()) { TAG_LOGD(AAFwkTag::SER_ROUTER, "Connection not found"); @@ -284,14 +276,13 @@ void EtsAgentConnection::ReleaseObjectReference(ani_ref etsObjRef) TAG_LOGE(AAFwkTag::SER_ROUTER, "etsVm_ or etsObjRef null"); return; } - bool isAttachThread = false; - ani_env *env = AppExecFwk::AttachAniEnv(etsVm_, isAttachThread); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::SER_ROUTER, "AttachAniEnv failed"); + ani_env *env = nullptr; + ani_status status = ANI_ERROR; + if ((status = etsVm_->GetEnv(ANI_VERSION_1, &env)) != ANI_OK || env == nullptr) { + TAG_LOGE(AAFwkTag::SER_ROUTER, "GetEnv failed status: %{public}d", status); return; } ReleaseObjectReference(env, etsObjRef); - AppExecFwk::DetachAniEnv(etsVm_, isAttachThread); } void EtsAgentConnection::CallObjectMethod(ani_env *env, const char *methodName, const char *signature, ...) @@ -380,31 +371,14 @@ void EtsAgentConnection::SetAniAsyncCallback(ani_object asyncCallback) TAG_LOGD(AAFwkTag::SER_ROUTER, "SetAniAsyncCallback success"); } -bool EtsAgentConnection::AddDuplicatedPendingCallback(ani_object duplicatedCallback) +void EtsAgentConnection::AddDuplicatedPendingCallback(ani_object duplicatedCallback) { TAG_LOGD(AAFwkTag::SER_ROUTER, "AddDuplicatedPendingCallback"); if (duplicatedCallback == nullptr) { TAG_LOGE(AAFwkTag::SER_ROUTER, "duplicatedCallback is null"); - return false; + return; } - if (etsVm_ == nullptr) { - TAG_LOGE(AAFwkTag::SER_ROUTER, "etsVm_ is null"); - return false; - } - ani_env *env = nullptr; - ani_status status = ANI_ERROR; - if ((status = etsVm_->GetEnv(ANI_VERSION_1, &env)) != ANI_OK || env == nullptr) { - TAG_LOGE(AAFwkTag::SER_ROUTER, "GetEnv failed status: %{public}d", status); - return false; - } - ani_ref globalRef = nullptr; - if ((status = env->GlobalReference_Create(duplicatedCallback, &globalRef)) != ANI_OK || - globalRef == nullptr) { - TAG_LOGE(AAFwkTag::SER_ROUTER, "GlobalReference_Create failed status: %{public}d", status); - return false; - } - duplicatedPendingCallbacks_.push_back(globalRef); - return true; + duplicatedPendingCallbacks_.push_back(duplicatedCallback); } void EtsAgentConnection::ResolveDuplicatedPendingCallbacks(ani_env *env, ani_object proxyObj) diff --git a/agent_runtime_framework/frameworks/ets/ani/agent_manager/src/ets_agent_manager.cpp b/agent_runtime_framework/frameworks/ets/ani/agent_manager/src/ets_agent_manager.cpp index 2ff033697c..2779e3ba60 100644 --- a/agent_runtime_framework/frameworks/ets/ani/agent_manager/src/ets_agent_manager.cpp +++ b/agent_runtime_framework/frameworks/ets/ani/agent_manager/src/ets_agent_manager.cpp @@ -57,12 +57,12 @@ class EtsAgentServiceConnection; std::map> g_serviceConnections; int64_t g_serviceConnectionSerialNumber = 0; -bool CheckConnectAlreadyExist(ani_env *env, const AAFwk::Want &want, const std::string &agentId, - ani_object asyncCallback) +bool CheckConnectAlreadyExist(ani_env *env, AAFwk::Want &want, + ani_object callback, ani_object asyncCallback) { TAG_LOGD(AAFwkTag::SER_ROUTER, "CheckConnectAlreadyExist called"); sptr connection = nullptr; - AgentConnectionUtils::FindAgentConnection(want, agentId, connection); + AgentConnectionUtils::FindAgentConnection(env, want, callback, connection); if (connection == nullptr) { TAG_LOGD(AAFwkTag::SER_ROUTER, "null connection"); return false; @@ -70,10 +70,7 @@ bool CheckConnectAlreadyExist(ani_env *env, const AAFwk::Want &want, const std:: ani_ref proxy = connection->GetProxyObject(); if (proxy == nullptr) { TAG_LOGW(AAFwkTag::SER_ROUTER, "null proxy"); - if (!connection->AddDuplicatedPendingCallback(asyncCallback)) { - AsyncCallback(env, SIGNATURE_AGENT_ASYNC_CALLBACK_WRAPPER, asyncCallback, - EtsErrorUtil::CreateError(env, AbilityErrorCode::ERROR_CODE_INNER), nullptr); - } + connection->AddDuplicatedPendingCallback(asyncCallback); } else { TAG_LOGI(AAFwkTag::SER_ROUTER, "Resolve, got proxy object"); AsyncCallback(env, SIGNATURE_AGENT_ASYNC_CALLBACK_WRAPPER, asyncCallback, @@ -534,7 +531,7 @@ void EtsAgentManager::ConnectAgentExtensionAbility(ani_env *env, ani_object aniW want.GetElement().GetBundleName().c_str(), want.GetElement().GetAbilityName().c_str()); // Check for duplicate connection - if (CheckConnectAlreadyExist(env, want, agentId, asyncCallback)) { + if (CheckConnectAlreadyExist(env, want, callbackObj, asyncCallback)) { TAG_LOGI(AAFwkTag::SER_ROUTER, "Duplicate connection found"); return; } diff --git a/agent_runtime_framework/frameworks/js/napi/agent_extension_ability/include/connection/js_agent_connection.h b/agent_runtime_framework/frameworks/js/napi/agent_extension_ability/include/connection/js_agent_connection.h index 62bddf9799..7252efadc1 100644 --- a/agent_runtime_framework/frameworks/js/napi/agent_extension_ability/include/connection/js_agent_connection.h +++ b/agent_runtime_framework/frameworks/js/napi/agent_extension_ability/include/connection/js_agent_connection.h @@ -77,13 +77,15 @@ int64_t InsertAgentConnection(sptr connection, const AAFwk::W void FindAgentConnection(int64_t connectId, sptr &connection); /** - * Find agent connection by target identity. + * Find agent connection by want and callback. * + * @param env The N-API environment. * @param want The want information to match. - * @param agentId The agent ID to match. + * @param callback The callback object to match. * @param connection Output parameter for the found connection. */ -void FindAgentConnection(const AAFwk::Want &want, const std::string &agentId, sptr &connection); +void FindAgentConnection(napi_env env, AAFwk::Want &want, napi_value callback, + sptr &connection); } class JsAgentConnectorStubImpl; diff --git a/agent_runtime_framework/frameworks/js/napi/agent_extension_ability/src/connection/js_agent_connection.cpp b/agent_runtime_framework/frameworks/js/napi/agent_extension_ability/src/connection/js_agent_connection.cpp index e4b995d593..b6eaee812d 100644 --- a/agent_runtime_framework/frameworks/js/napi/agent_extension_ability/src/connection/js_agent_connection.cpp +++ b/agent_runtime_framework/frameworks/js/napi/agent_extension_ability/src/connection/js_agent_connection.cpp @@ -33,22 +33,6 @@ constexpr int32_t ARGC_ONE = 1; static std::map, KeyCompare> g_agentConnects; static std::recursive_mutex g_agentConnectsLock_; static int64_t g_agentSerialNumber = 0; - -bool IsSameAgentConnection(const AAFwk::Want &storedWant, const AAFwk::Want &want, const std::string &agentId) -{ - std::string existingId = storedWant.GetStringParam(AGENTID_KEY); - if (existingId.empty() || agentId.empty() || existingId != agentId) { - return false; - } - const auto &storedElement = storedWant.GetElement(); - const auto &element = want.GetElement(); - if (storedElement.GetBundleName() != element.GetBundleName() || - storedElement.GetAbilityName() != element.GetAbilityName()) { - return false; - } - return storedElement.GetModuleName().empty() || element.GetModuleName().empty() || - storedElement.GetModuleName() == element.GetModuleName(); -} } // namespace namespace AgentConnectionUtils { @@ -109,13 +93,21 @@ void FindAgentConnection(int64_t connectId, sptr &connection) } } -void FindAgentConnection(const AAFwk::Want &want, const std::string &agentId, sptr &connection) +void FindAgentConnection(napi_env env, AAFwk::Want &want, napi_value callback, + sptr &connection) { - TAG_LOGD(AAFwkTag::SER_ROUTER, "FindAgentConnection by target"); + TAG_LOGD(AAFwkTag::SER_ROUTER, "FindAgentConnection by want+callback"); std::lock_guard lock(g_agentConnectsLock_); auto item = std::find_if(g_agentConnects.begin(), g_agentConnects.end(), - [&want, &agentId](const auto &obj) { - return IsSameAgentConnection(obj.first.want, want, agentId); + [&want, env, callback](const auto &obj) { + std::string exstingId = obj.first.want.GetStringParam(AGENTID_KEY); + std::string agentId = want.GetStringParam(AGENTID_KEY); + bool wantEquals = obj.first.want.GetElement() == want.GetElement() && + !exstingId.empty() && !agentId.empty() && exstingId == agentId; + std::unique_ptr &tempCallbackPtr = obj.second->GetJsConnectionObject(); + bool callbackObjectEquals = + JSAgentConnection::IsJsCallbackObjectEquals(env, tempCallbackPtr, callback); + return wantEquals && callbackObjectEquals; }); if (item == g_agentConnects.end()) { TAG_LOGD(AAFwkTag::SER_ROUTER, "Connection not found"); diff --git a/agent_runtime_framework/frameworks/js/napi/agent_manager/src/js_agent_manager.cpp b/agent_runtime_framework/frameworks/js/napi/agent_manager/src/js_agent_manager.cpp index bd7ab6420f..9eb220ef8e 100644 --- a/agent_runtime_framework/frameworks/js/napi/agent_manager/src/js_agent_manager.cpp +++ b/agent_runtime_framework/frameworks/js/napi/agent_manager/src/js_agent_manager.cpp @@ -54,7 +54,6 @@ constexpr int32_t ARG_INDEX_0 = 0; constexpr int32_t ARG_INDEX_1 = 1; constexpr int32_t ARG_INDEX_2 = 2; constexpr int64_t INVALID_CONNECT_ID = -1; -constexpr const char *INTERNAL_ERROR_MSG = "Internal error."; std::mutex g_serviceConnectionsLock; class JSAgentServiceConnection; @@ -233,12 +232,13 @@ void RemoveServiceConnection(int64_t connectionId) } // Helper function to check for duplicate connections -bool CheckConnectAlreadyExist(napi_env env, const AAFwk::Want &want, const std::string &agentId, napi_value &result) +bool CheckConnectAlreadyExist(napi_env env, AAFwk::Want &want, + napi_value callback, napi_value &result) { TAG_LOGD(AAFwkTag::SER_ROUTER, "CheckConnectAlreadyExist called"); sptr connection = nullptr; - AgentConnectionUtils::FindAgentConnection(want, agentId, connection); + AgentConnectionUtils::FindAgentConnection(env, want, callback, connection); if (connection == nullptr) { TAG_LOGD(AAFwkTag::SER_ROUTER, "No duplicate connection found"); return false; @@ -251,27 +251,13 @@ bool CheckConnectAlreadyExist(napi_env env, const AAFwk::Want &want, const std:: TAG_LOGD(AAFwkTag::SER_ROUTER, "Proxy not ready, queuing pending task"); std::unique_ptr asyncTask = CreateAsyncTaskWithLastParam(env, nullptr, nullptr, nullptr, &result); - if (asyncTask == nullptr) { - TAG_LOGE(AAFwkTag::SER_ROUTER, "Create async task failed"); - ThrowError(env, static_cast(AbilityErrorCode::ERROR_CODE_INNER), INTERNAL_ERROR_MSG); - result = CreateJsUndefined(env); - return true; - } connection->AddDuplicatedPendingTask(asyncTask); return true; } // Connection exists and proxy is ready, resolve immediately TAG_LOGD(AAFwkTag::SER_ROUTER, "Resolving with existing proxy"); - std::unique_ptr asyncTask = - CreateAsyncTaskWithLastParam(env, nullptr, nullptr, nullptr, &result); - if (asyncTask == nullptr) { - TAG_LOGE(AAFwkTag::SER_ROUTER, "Create async task failed"); - ThrowError(env, static_cast(AbilityErrorCode::ERROR_CODE_INNER), INTERNAL_ERROR_MSG); - result = CreateJsUndefined(env); - return true; - } - asyncTask->ResolveWithNoError(env, proxy); + result = proxy; return true; } @@ -580,7 +566,7 @@ napi_value JsAgentManager::OnConnectAgentExtensionAbility(napi_env env, size_t a // 2. Check for duplicate connection napi_value result = nullptr; - bool duplicated = CheckConnectAlreadyExist(env, want, agentId, result); + bool duplicated = CheckConnectAlreadyExist(env, want, callbackObject, result); if (duplicated) { TAG_LOGI(AAFwkTag::SER_ROUTER, "Duplicated connection found"); return result; @@ -669,11 +655,6 @@ napi_value JsAgentManager::ScheduleAgentConnection(napi_env env, const AAFwk::Wa napi_value result = nullptr; std::unique_ptr asyncTask = CreateAsyncTaskWithLastParam(env, nullptr, nullptr, nullptr, &result); - if (asyncTask == nullptr) { - TAG_LOGE(AAFwkTag::SER_ROUTER, "Create async task failed"); - ThrowError(env, static_cast(AbilityErrorCode::ERROR_CODE_INNER), INTERNAL_ERROR_MSG); - return CreateJsUndefined(env); - } std::shared_ptr asyncTaskShared = std::move(asyncTask); connection->SetNapiAsyncTask(asyncTaskShared); diff --git a/agent_runtime_framework/interfaces/inner_api/include/agent_connection_manager.h b/agent_runtime_framework/interfaces/inner_api/include/agent_connection_manager.h index ae33c8e0c7..2c4d2cd747 100644 --- a/agent_runtime_framework/interfaces/inner_api/include/agent_connection_manager.h +++ b/agent_runtime_framework/interfaces/inner_api/include/agent_connection_manager.h @@ -17,8 +17,7 @@ #define OHOS_AGENT_RUNTIME_AGENT_CONNECTION_MANAGER_H #include -#include -#include +#include #include #include @@ -40,7 +39,7 @@ class AgentConnection; * @struct AgentConnectionInfo * @brief Stores information about an agent connection. * - * The connection key consists of: agentId + connectReceiver + * The connection key consists of: agentId + agentExtProxy + connectReceiver */ struct AgentConnectionInfo { // Target agent identifier (from Want parameter AGENTID_KEY) @@ -50,8 +49,8 @@ struct AgentConnectionInfo { AAFwk::Operation connectReceiver; // The connection object sptr agentConnection; - // Agent extension host proxy from Want parameter AGENTEXTENSIONHOSTPROXY_KEY. - // It is per API call and is not part of the reusable connection identity. + // Agent extension proxy for bidirectional communication + // (from Want parameter AGENTEXTENSIONHOSTPROXY_KEY) void *agentExtProxy = nullptr; // Connection timestamp for timeout detection int64_t connectingTime = 0; @@ -84,6 +83,47 @@ struct AgentConnectionInfo { auto now = std::chrono::steady_clock::now().time_since_epoch(); connectingTime = std::chrono::duration_cast(now).count(); } + + /** + * @brief Comparison operator for map key ordering. + * + * Compares by: agentId -> agentExtProxy -> connectingTime -> connectReceiver + * (bundleName -> moduleName -> abilityName) + * + * @param that The other AgentConnectionInfo to compare with. + * @return Returns true if this is less than that. + */ + inline bool operator<(const AgentConnectionInfo &that) const + { + if (agentId < that.agentId) { + return true; + } + if (agentExtProxy < that.agentExtProxy) { + return true; + } + if (connectingTime < that.connectingTime) { + return true; + } + if (connectReceiver.GetBundleName() < that.connectReceiver.GetBundleName()) { + return true; + } + if (connectReceiver.GetBundleName() == that.connectReceiver.GetBundleName() && + connectReceiver.GetModuleName() < that.connectReceiver.GetModuleName()) { + return true; + } + if (connectReceiver.GetBundleName() == that.connectReceiver.GetBundleName() && + connectReceiver.GetModuleName() == that.connectReceiver.GetModuleName() && + connectReceiver.GetAbilityName() < that.connectReceiver.GetAbilityName()) { + return true; + } + if (connectReceiver.GetBundleName() == that.connectReceiver.GetBundleName() && + connectReceiver.GetModuleName() == that.connectReceiver.GetModuleName() && + connectReceiver.GetAbilityName() == that.connectReceiver.GetAbilityName() && + !(connectReceiver == that.connectReceiver)) { + return true; + } + return false; + } }; /** @@ -130,7 +170,7 @@ private: * @brief Manages connections to AgentExtensionAbility instances. * * This class is similar to ConnectionManager but specifically for agent extensions. - * Connections are identified by: agentId + connectReceiver. + * Connections are identified by: agentId + agentExtProxy + connectReceiver. */ class AgentConnectionManager { public: @@ -215,19 +255,16 @@ private: */ void *GetAgentExtProxyPtr(const AAFwk::Want &want); /** - * @brief Match connection by agentId + connectReceiver. + * @brief Match connection by agentId + agentExtProxy + connectReceiver. * * @param agentId The agent ID to match. * @param connectReceiver The connect receiver (Want) to match. * @param connection The existing connection entry. * @return Returns true if matches, false otherwise. */ - using AgentConnectionCallbacks = std::vector>; - using AgentConnectionRecord = std::pair; - using AgentConnectionRecords = std::list; - bool MatchConnection(const std::string &agentId, const AAFwk::Want &connectReceiver, - const AgentConnectionRecord &connection); + const std::map>>::value_type &connection); /** * @brief Create a new connection to the agent extension. * @@ -256,7 +293,7 @@ private: private: std::mutex connectionsLock_; - AgentConnectionRecords agentConnections_; + std::map>> agentConnections_; }; } // namespace AgentRuntime } // namespace OHOS diff --git a/agent_runtime_framework/interfaces/inner_api/src/agent_connection_manager.cpp b/agent_runtime_framework/interfaces/inner_api/src/agent_connection_manager.cpp index c4104f4004..f0afcff79b 100644 --- a/agent_runtime_framework/interfaces/inner_api/src/agent_connection_manager.cpp +++ b/agent_runtime_framework/interfaces/inner_api/src/agent_connection_manager.cpp @@ -242,23 +242,22 @@ void *AgentConnectionManager::GetAgentExtProxyPtr(const AAFwk::Want &want) } bool AgentConnectionManager::MatchConnection(const std::string &agentId, const AAFwk::Want &connectReceiver, - const AgentConnectionRecord &connection) + const std::map>>::value_type &connection) { // 1. Match by agentId if (agentId != connection.first.agentId) { return false; } - // 2. Match by connectReceiver (bundleName, moduleName, abilityName). - // AGENTEXTENSIONHOSTPROXY_KEY is per connect call, so it must not split reusable connections. - const AAFwk::Operation &storedReceiver = connection.first.connectReceiver; - const AppExecFwk::ElementName &element = connectReceiver.GetElement(); - if (element.GetBundleName() != storedReceiver.GetBundleName() || - element.GetAbilityName() != storedReceiver.GetAbilityName()) { + // 2. Match by agentExtProxy + void *agentExtProxy = GetAgentExtProxyPtr(connectReceiver); + if (agentExtProxy != connection.first.agentExtProxy) { return false; } - const std::string &moduleName = element.GetModuleName(); - const std::string &storedModuleName = storedReceiver.GetModuleName(); - return moduleName.empty() || storedModuleName.empty() || moduleName == storedModuleName; + // 3. Match by connectReceiver (bundleName, moduleName, abilityName) + const AAFwk::Operation &storedReceiver = connection.first.connectReceiver; + return connectReceiver.GetElement().GetBundleName() == storedReceiver.GetBundleName() && + connectReceiver.GetElement().GetModuleName() == storedReceiver.GetModuleName() && + connectReceiver.GetElement().GetAbilityName() == storedReceiver.GetAbilityName(); } ErrCode AgentConnectionManager::CreateConnection(const AAFwk::Want &want, @@ -282,19 +281,14 @@ ErrCode AgentConnectionManager::CreateConnection(const AAFwk::Want &want, { std::lock_guard lock(connectionsLock_); - agentConnections_.emplace_back(connectionInfo, AgentConnectionCallbacks { connectCallback }); + agentConnections_[connectionInfo] = { connectCallback }; } ErrCode ret = AgentManagerClient::GetInstance().ConnectAgentExtensionAbility(want, agentConnection); if (ret != ERR_OK) { TAG_LOGE(AAFwkTag::SER_ROUTER, "error:%{public}d", ret); std::lock_guard lock(connectionsLock_); - for (auto iter = agentConnections_.begin(); iter != agentConnections_.end(); ++iter) { - if (iter->first.agentConnection == agentConnection) { - agentConnections_.erase(iter); - break; - } - } + agentConnections_.erase(connectionInfo); } return ret; } diff --git a/agent_runtime_framework/services/agentmgr/include/agent_manager_service.h b/agent_runtime_framework/services/agentmgr/include/agent_manager_service.h index 1e14608eb5..2eb590307c 100644 --- a/agent_runtime_framework/services/agentmgr/include/agent_manager_service.h +++ b/agent_runtime_framework/services/agentmgr/include/agent_manager_service.h @@ -16,7 +16,6 @@ #ifndef OHOS_AGENT_RUNTIME_FRAMEWORK_AGENT_MANAGER_SERVICE_H #define OHOS_AGENT_RUNTIME_FRAMEWORK_AGENT_MANAGER_SERVICE_H -#include #include #include #include @@ -32,7 +31,6 @@ #include "task_handler_wrap.h" #include "agent_host_connection.h" #include "agent_host_connection_types.h" -#include "element_name.h" namespace OHOS { namespace AgentRuntime { @@ -85,41 +83,6 @@ public: private: friend class AgentServiceConnection; friend class AgentHostConnection; - - /** - * @struct StandardAgentKey - * @brief Identity key for deduplicating non-low-code agent connections: callerUid + agentId + target. - */ - struct StandardAgentKey { - int32_t callerUid = 0; - std::string agentId; - std::string bundleName; - std::string moduleName; - std::string abilityName; - }; - - enum class StandardAgentState : int32_t { - CONNECTING, - CONNECTED, - }; - - /** - * @struct StandardAgentSession - * @brief Collapsed session for standard agent connections sharing the same (callerUid, agentId, target). - */ - struct StandardAgentSession { - StandardAgentKey key; - StandardAgentState state = StandardAgentState::CONNECTING; - sptr serviceConnection = nullptr; - std::vector> pendingCallbacks; - std::vector> connectedCallbacks; - std::vector> callerRemotes; - AppExecFwk::ElementName cachedElement; - sptr cachedRemoteObject = nullptr; - int32_t cachedResultCode = ERR_OK; - bool isDisconnecting = false; - }; - /** * @struct TrackedConnectionRecord * @brief Stores one caller-visible connection together with the service-side wrapper used to talk to AMS. @@ -133,21 +96,6 @@ private: bool isLowCode = false; bool countTowardsCallerLimit = true; bool isDisconnecting = false; - StandardAgentKey standardKey; - }; - - using TrackedConnectionIter = std::map, TrackedConnectionRecord>::iterator; - using StandardSessionIter = std::list>::iterator; - - struct AgentDisconnectPlan { - sptr serviceConnection = nullptr; - sptr hostConnection = nullptr; - sptr callerRemote = nullptr; - AgentHostKey hostKey; - bool hasHostKey = false; - bool isStandard = false; - int32_t standardCallerUid = 0; - StandardAgentKey standardKey; }; AgentManagerService(); @@ -195,13 +143,8 @@ private: /** * @brief Finds the tracked record that matches the caller callback object or the fallback caller uid path. */ - TrackedConnectionIter FindTrackedConnectionLocked(const sptr &connection, - int32_t callerUid); - int32_t PrepareAgentDisconnectLocked(const sptr &connection, - AgentDisconnectPlan &plan); - int32_t PrepareLowCodeDisconnectLocked(TrackedConnectionIter it, AgentDisconnectPlan &plan); - int32_t PrepareStandardDisconnectLocked(TrackedConnectionIter it, AgentDisconnectPlan &plan); - void RollbackAgentDisconnectLocked(const AgentDisconnectPlan &plan); + std::map, TrackedConnectionRecord>::iterator FindTrackedConnectionLocked( + const sptr &connection, int32_t callerUid); void ReleaseCallerConnectionCountByUidLocked(int32_t callerUid); /** * @brief Forwards connect/disconnect completion from the service-side wrapper back to the original caller. @@ -214,12 +157,6 @@ private: const sptr &callerRemote); void HandleCallerConnectionDied(const wptr &remote); void HandleCallerConnectionDied(const sptr &remote); - void CleanupDeadStandardConnectionLocked(TrackedConnectionIter it, const sptr &remote, - sptr &serviceConnection); - void CleanupDeadLowCodeConnectionLocked(TrackedConnectionIter it, const sptr &remote, - sptr &hostConnection); - void DisconnectDeadServiceConnection(const sptr &serviceConnection); - void DisconnectDeadHostConnection(const sptr &hostConnection); /** * @brief Connect path for LOW_CODE agents, which reuse one shared host session per target host. */ @@ -249,38 +186,6 @@ private: * @brief Extracts the host-session identity from the target element and caller user context. */ AgentHostKey BuildAgentHostKey(const AAFwk::Want &want, int32_t callingUid) const; - /** - * @brief Builds the identity key for standard agent session deduplication. - */ - StandardAgentKey BuildStandardAgentKey(int32_t callerUid, const std::string &agentId, - const AAFwk::Want &want) const; - bool IsStandardAgentKeyEqual(const StandardAgentKey &left, const StandardAgentKey &right) const; - bool IsStandardAgentKeyMatched(const StandardAgentKey &storedKey, const StandardAgentKey &incomingKey) const; - /** - * @brief Finds an existing standard session matching the given key. - */ - std::shared_ptr FindStandardSessionLocked(const StandardAgentKey &key) const; - StandardSessionIter FindStandardSessionByServiceRemoteLocked(const sptr &serviceRemote); - /** - * @brief Registers a caller callback against an existing standard session without consuming another quota slot. - */ - int32_t RegisterStandardSessionCallerLocked(const std::shared_ptr &session, - const sptr &connection, bool countTowardsCallerLimit); - /** - * @brief Creates a new collapsed standard session, registers one quota, and issues the real AMS connect. - */ - int32_t CreateStandardAgentSession(const AAFwk::Want &connectWant, const std::string &agentId, - const StandardAgentKey &key, const sptr &connection); - /** - * @brief Handles AMS connect completion for a standard collapsed session. - */ - void HandleStandardAgentConnectDone(const sptr &serviceRemote, - const AppExecFwk::ElementName &element, const sptr &remoteObject, int32_t resultCode); - /** - * @brief Handles AMS disconnect completion for a standard collapsed session. - */ - void HandleStandardAgentDisconnectDone(const sptr &serviceRemote, - const AppExecFwk::ElementName &element, int32_t resultCode); /** * @brief Marks the target low-code agent as invoked so future callers can detect duplicate activation. */ @@ -318,7 +223,6 @@ private: std::mutex agentHostMutex_; std::map> agentHostSessions_; std::map> agentOwners_; - std::list> standardSessions_; }; } // namespace AgentRuntime } // namespace OHOS diff --git a/agent_runtime_framework/services/agentmgr/include/agent_service_connection.h b/agent_runtime_framework/services/agentmgr/include/agent_service_connection.h index b95cd13d0b..0e24437c45 100644 --- a/agent_runtime_framework/services/agentmgr/include/agent_service_connection.h +++ b/agent_runtime_framework/services/agentmgr/include/agent_service_connection.h @@ -25,14 +25,12 @@ public: explicit AgentServiceConnection(const sptr &connection); ~AgentServiceConnection() override = default; - void SetStandardSessionMode(); void OnAbilityConnectDone( const AppExecFwk::ElementName &element, const sptr &remoteObject, int resultCode) override; void OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) override; private: sptr callerConnection_; - bool isStandardSession_ = false; }; } // namespace AgentRuntime } // namespace OHOS diff --git a/agent_runtime_framework/services/agentmgr/src/agent_manager_service.cpp b/agent_runtime_framework/services/agentmgr/src/agent_manager_service.cpp index 501e7915e3..b4c0420073 100644 --- a/agent_runtime_framework/services/agentmgr/src/agent_manager_service.cpp +++ b/agent_runtime_framework/services/agentmgr/src/agent_manager_service.cpp @@ -81,19 +81,6 @@ bool IsMatchedAgentCardTarget(const AAFwk::Want &want, const AgentCard &card) return element.GetModuleName().empty() || card.appInfo->moduleName.empty() || element.GetModuleName() == card.appInfo->moduleName; } - -void NormalizeConnectAgentTarget(AAFwk::Want &want, const AgentCard &card) -{ - if (card.appInfo == nullptr || card.appInfo->moduleName.empty()) { - return; - } - const auto &element = want.GetElement(); - if (!element.GetModuleName().empty()) { - return; - } - want.SetElementName(element.GetBundleName(), element.GetAbilityName()); - want.SetModuleName(card.appInfo->moduleName); -} } sptr AgentManagerService::GetInstance() @@ -139,7 +126,6 @@ void AgentManagerService::OnStop() noexcept std::lock_guard lock(connectionLock_); trackedConnections_.clear(); callerConnectionCounts_.clear(); - standardSessions_.clear(); } std::lock_guard hostLock(agentHostMutex_); agentHostSessions_.clear(); @@ -359,40 +345,23 @@ int32_t AgentManagerService::ConnectAgentExtensionAbility(const AAFwk::Want &wan TAG_LOGI(AAFwkTag::SER_ROUTER, "connecting %{public}s-%{public}s", connectWant.GetBundle().c_str(), agentId.c_str()); - // Step 5: deduplicate standard agent connections at the service side. - StandardAgentKey key = BuildStandardAgentKey(callerUid, agentId, connectWant); - AppExecFwk::ElementName cachedElement; - sptr cachedRemoteObject = nullptr; - int32_t cachedResultCode = ERR_OK; - bool notifyCached = false; - { - std::lock_guard lock(connectionLock_); - auto existing = FindStandardSessionLocked(key); - if (existing != nullptr) { - ret = RegisterStandardSessionCallerLocked(existing, connection, false); - if (ret != ERR_OK) { - return ret; - } - if (existing->state == StandardAgentState::CONNECTING) { - TAG_LOGI(AAFwkTag::SER_ROUTER, "standard session connecting, append caller"); - return ERR_OK; - } - if (existing->state == StandardAgentState::CONNECTED) { - TAG_LOGI(AAFwkTag::SER_ROUTER, "standard session connected, return cached proxy"); - cachedElement = existing->cachedElement; - cachedRemoteObject = existing->cachedRemoteObject; - cachedResultCode = existing->cachedResultCode; - notifyCached = true; - } - } - } - if (notifyCached) { - connection->OnAbilityConnectDone(cachedElement, cachedRemoteObject, cachedResultCode); - return ERR_OK; + // Step 5: create the tracked wrapper connection before talking to AMS. + sptr serviceConnection; + ret = RegisterTrackedConnectionAndGetServiceConnection(connection, callerUid, true, serviceConnection); + if (ret != ERR_OK) { + return ret; } - // Step 6: no existing session — create one and issue the real AMS connect. - return CreateStandardAgentSession(connectWant, agentId, key, connection); + // Step 6: issue the actual extension connect request through AMS. + ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbilityWithExtensionType( + connectWant, serviceConnection, nullptr, AAFwk::DEFAULT_INVAL_VALUE, AppExecFwk::ExtensionAbilityType::AGENT); + if (ret != ERR_OK) { + TAG_LOGE(AAFwkTag::SER_ROUTER, "ConnectAbilityWithExtensionType failed: %{public}d", ret); + ReleaseTrackedConnection(connection); + return ret; + } + + return ERR_OK; } int32_t AgentManagerService::ConnectServiceExtensionAbility(const sptr &callerToken, @@ -488,7 +457,6 @@ int32_t AgentManagerService::ResolveConnectAgentTarget(const AAFwk::Want &want, TAG_LOGE(AAFwkTag::SER_ROUTER, "low-code target mismatch"); return AAFwk::INVALID_PARAMETERS_ERR; } - NormalizeConnectAgentTarget(connectWant, card); // Capture the caller UID once the target metadata is known-good. callingUid = IPCSkeleton::GetCallingUid(); @@ -610,27 +578,73 @@ int32_t AgentManagerService::DisconnectAgentExtensionAbility(const sptr serviceConnection = nullptr; + sptr hostConnection = nullptr; + sptr callerRemote = nullptr; + AgentHostKey hostKey; + bool hasHostKey = false; { std::scoped_lock lock(connectionLock_, agentHostMutex_); - auto ret = PrepareAgentDisconnectLocked(connection, plan); - if (ret != ERR_OK) { - return ret; + auto it = FindTrackedConnectionLocked(connection, IPCSkeleton::GetCallingUid()); + if (it == trackedConnections_.end()) { + TAG_LOGE(AAFwkTag::SER_ROUTER, "Connection not tracked"); + return ERR_INVALID_VALUE; + } + callerRemote = it->first; + if (it->second.isDisconnecting) { + TAG_LOGI(AAFwkTag::SER_ROUTER, "Connection is already disconnecting"); + return ERR_OK; + } + if (it->second.isLowCode) { + auto sessionIter = agentHostSessions_.find(it->second.hostKey); + if (sessionIter == agentHostSessions_.end() || sessionIter->second == nullptr) { + TAG_LOGE(AAFwkTag::SER_ROUTER, "Low-code host session missing"); + return ERR_INVALID_VALUE; + } + auto session = sessionIter->second; + if (session->isDisconnecting) { + return ERR_OK; + } + session->isDisconnecting = true; + it->second.isDisconnecting = true; + hostKey = it->second.hostKey; + hasHostKey = true; + if (!ReleaseCallerConnectionCountLocked(callerRemote)) { + session->isDisconnecting = false; + it->second.isDisconnecting = false; + TAG_LOGE(AAFwkTag::SER_ROUTER, "Release caller connection count failed"); + return ERR_INVALID_VALUE; + } + hostConnection = session->hostConnection; + } else { + it->second.isDisconnecting = true; + if (!ReleaseCallerConnectionCountLocked(callerRemote)) { + TAG_LOGE(AAFwkTag::SER_ROUTER, "Release caller connection count failed"); + return ERR_INVALID_VALUE; + } + serviceConnection = it->second.serviceConnection; } } - if (plan.serviceConnection == nullptr && plan.hostConnection == nullptr) { - return ERR_OK; - } - sptr disconnectConnection = plan.serviceConnection; - if (plan.hostConnection != nullptr) { - disconnectConnection = plan.hostConnection; + sptr disconnectConnection = serviceConnection; + if (hostConnection != nullptr) { + disconnectConnection = hostConnection; } auto ret = IN_PROCESS_CALL(AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(disconnectConnection)); if (ret != ERR_OK) { TAG_LOGE(AAFwkTag::SER_ROUTER, "DisconnectAbility failed: %{public}d", ret); std::scoped_lock lock(connectionLock_, agentHostMutex_); - RollbackAgentDisconnectLocked(plan); + auto it = trackedConnections_.find(callerRemote); + if (hasHostKey) { + auto sessionIter = agentHostSessions_.find(hostKey); + if (sessionIter != agentHostSessions_.end() && sessionIter->second != nullptr) { + sessionIter->second->isDisconnecting = false; + } + } + if (it != trackedConnections_.end() && it->second.isDisconnecting) { + it->second.isDisconnecting = false; + callerConnectionCounts_[it->second.callerUid]++; + } return ret; } @@ -664,7 +678,8 @@ sptr AgentManagerService::GetConnectionIdentityRemote( return connection->AsObject(); } -AgentManagerService::TrackedConnectionIter AgentManagerService::FindTrackedConnectionLocked( +std::map, AgentManagerService::TrackedConnectionRecord>::iterator +AgentManagerService::FindTrackedConnectionLocked( const sptr &connection, int32_t callerUid) { auto end = trackedConnections_.end(); @@ -705,115 +720,6 @@ AgentManagerService::TrackedConnectionIter AgentManagerService::FindTrackedConne return matched; } -int32_t AgentManagerService::PrepareAgentDisconnectLocked(const sptr &connection, - AgentDisconnectPlan &plan) -{ - auto it = FindTrackedConnectionLocked(connection, IPCSkeleton::GetCallingUid()); - if (it == trackedConnections_.end()) { - TAG_LOGE(AAFwkTag::SER_ROUTER, "Connection not tracked"); - return ERR_INVALID_VALUE; - } - - plan.callerRemote = it->first; - if (it->second.isDisconnecting) { - TAG_LOGI(AAFwkTag::SER_ROUTER, "Connection is already disconnecting"); - return ERR_OK; - } - if (it->second.isLowCode) { - return PrepareLowCodeDisconnectLocked(it, plan); - } - return PrepareStandardDisconnectLocked(it, plan); -} - -int32_t AgentManagerService::PrepareLowCodeDisconnectLocked(TrackedConnectionIter it, AgentDisconnectPlan &plan) -{ - auto sessionIter = agentHostSessions_.find(it->second.hostKey); - if (sessionIter == agentHostSessions_.end() || sessionIter->second == nullptr) { - TAG_LOGE(AAFwkTag::SER_ROUTER, "Low-code host session missing"); - return ERR_INVALID_VALUE; - } - - auto session = sessionIter->second; - if (session->isDisconnecting) { - return ERR_OK; - } - session->isDisconnecting = true; - it->second.isDisconnecting = true; - plan.hostKey = it->second.hostKey; - plan.hasHostKey = true; - if (!ReleaseCallerConnectionCountLocked(plan.callerRemote)) { - session->isDisconnecting = false; - it->second.isDisconnecting = false; - TAG_LOGE(AAFwkTag::SER_ROUTER, "Release caller connection count failed"); - return ERR_INVALID_VALUE; - } - plan.hostConnection = session->hostConnection; - return ERR_OK; -} - -int32_t AgentManagerService::PrepareStandardDisconnectLocked(TrackedConnectionIter it, AgentDisconnectPlan &plan) -{ - const auto &stdKey = it->second.standardKey; - if (stdKey.callerUid != 0 && !stdKey.agentId.empty()) { - auto sessionIt = std::find_if(standardSessions_.begin(), standardSessions_.end(), - [this, &stdKey](const auto &item) { - return item != nullptr && IsStandardAgentKeyEqual(item->key, stdKey); - }); - if (sessionIt != standardSessions_.end() && *sessionIt != nullptr) { - auto &session = *sessionIt; - if (session->isDisconnecting) { - TAG_LOGI(AAFwkTag::SER_ROUTER, "standard session already disconnecting"); - return ERR_OK; - } - session->isDisconnecting = true; - it->second.isDisconnecting = true; - plan.serviceConnection = session->serviceConnection; - plan.isStandard = true; - plan.standardCallerUid = session->key.callerUid; - plan.standardKey = session->key; - ReleaseCallerConnectionCountByUidLocked(plan.standardCallerUid); - return ERR_OK; - } - } - - it->second.isDisconnecting = true; - if (!ReleaseCallerConnectionCountLocked(plan.callerRemote)) { - TAG_LOGE(AAFwkTag::SER_ROUTER, "Release caller connection count failed"); - return ERR_INVALID_VALUE; - } - plan.serviceConnection = it->second.serviceConnection; - return ERR_OK; -} - -void AgentManagerService::RollbackAgentDisconnectLocked(const AgentDisconnectPlan &plan) -{ - auto it = trackedConnections_.find(plan.callerRemote); - if (plan.hasHostKey) { - auto sessionIter = agentHostSessions_.find(plan.hostKey); - if (sessionIter != agentHostSessions_.end() && sessionIter->second != nullptr) { - sessionIter->second->isDisconnecting = false; - } - } - if (plan.isStandard) { - auto sessionIt = std::find_if(standardSessions_.begin(), standardSessions_.end(), - [this, &plan](const auto &item) { - return item != nullptr && IsStandardAgentKeyEqual(item->key, plan.standardKey); - }); - if (sessionIt != standardSessions_.end() && *sessionIt != nullptr) { - (*sessionIt)->isDisconnecting = false; - } - if (plan.standardCallerUid != 0) { - callerConnectionCounts_[plan.standardCallerUid]++; - } - } - if (it != trackedConnections_.end() && it->second.isDisconnecting) { - it->second.isDisconnecting = false; - if (!plan.isStandard) { - callerConnectionCounts_[it->second.callerUid]++; - } - } -} - int32_t AgentManagerService::DisconnectServiceExtensionAbility(const sptr &callerToken, const sptr &connection) { @@ -1067,66 +973,53 @@ void AgentManagerService::TransferLowCodeCallerLimitLocked(const std::shared_ptr } } -void AgentManagerService::CleanupDeadStandardConnectionLocked(TrackedConnectionIter it, - const sptr &remote, sptr &serviceConnection) +void AgentManagerService::HandleCallerConnectionDied(const sptr &remote) { - serviceConnection = it->second.serviceConnection; - auto &stdKey = it->second.standardKey; - if (stdKey.callerUid != 0 && !stdKey.agentId.empty()) { - auto sessionIt = std::find_if(standardSessions_.begin(), standardSessions_.end(), - [this, &stdKey](const auto &item) { - return item != nullptr && IsStandardAgentKeyEqual(item->key, stdKey); - }); - if (sessionIt != standardSessions_.end() && *sessionIt != nullptr) { - serviceConnection = (*sessionIt)->serviceConnection; - for (const auto &callerRemote : (*sessionIt)->callerRemotes) { - if (callerRemote != remote) { - ReleaseTrackedConnectionByRemoteLocked(callerRemote); + sptr serviceConnection = nullptr; + sptr hostConnection = nullptr; + { + std::scoped_lock lock(connectionLock_, agentHostMutex_); + if (remote == nullptr) { + return; + } + auto it = trackedConnections_.find(remote); + if (it == trackedConnections_.end()) { + return; + } + + if (!it->second.isLowCode) { + serviceConnection = it->second.serviceConnection; + ReleaseTrackedConnectionByRemoteLocked(remote); + } else { + auto sessionIter = agentHostSessions_.find(it->second.hostKey); + if (sessionIter != agentHostSessions_.end() && sessionIter->second != nullptr) { + auto session = sessionIter->second; + session->callerConnections.erase(remote); + for (auto agentIter = session->agents.begin(); agentIter != session->agents.end();) { + if (agentIter->second.callerRemote == remote) { + agentOwners_.erase(AgentOwnerKey { session->hostUid, agentIter->first }); + agentIter = session->agents.erase(agentIter); + continue; + } + ++agentIter; + } + if (!session->isDisconnecting && session->agents.empty()) { + session->isDisconnecting = true; + hostConnection = session->hostConnection; + } else { + TransferLowCodeCallerLimitLocked(session, remote); } } - standardSessions_.erase(sessionIt); + ReleaseTrackedConnectionByRemoteLocked(remote); } } - ReleaseTrackedConnectionByRemoteLocked(remote); -} -void AgentManagerService::CleanupDeadLowCodeConnectionLocked(TrackedConnectionIter it, - const sptr &remote, sptr &hostConnection) -{ - auto sessionIter = agentHostSessions_.find(it->second.hostKey); - if (sessionIter != agentHostSessions_.end() && sessionIter->second != nullptr) { - auto session = sessionIter->second; - session->callerConnections.erase(remote); - for (auto agentIter = session->agents.begin(); agentIter != session->agents.end();) { - if (agentIter->second.callerRemote == remote) { - agentOwners_.erase(AgentOwnerKey { session->hostUid, agentIter->first }); - agentIter = session->agents.erase(agentIter); - continue; - } - ++agentIter; - } - if (!session->isDisconnecting && session->agents.empty()) { - session->isDisconnecting = true; - hostConnection = session->hostConnection; - } else { - TransferLowCodeCallerLimitLocked(session, remote); - } - } - ReleaseTrackedConnectionByRemoteLocked(remote); -} - -void AgentManagerService::DisconnectDeadServiceConnection(const sptr &serviceConnection) -{ if (serviceConnection != nullptr) { auto ret = IN_PROCESS_CALL(AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(serviceConnection)); if (ret != ERR_OK) { TAG_LOGW(AAFwkTag::SER_ROUTER, "DisconnectAbility after caller death failed: %{public}d", ret); } } -} - -void AgentManagerService::DisconnectDeadHostConnection(const sptr &hostConnection) -{ if (hostConnection != nullptr) { auto ret = IN_PROCESS_CALL(AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(hostConnection)); if (ret != ERR_OK) { @@ -1143,30 +1036,6 @@ void AgentManagerService::DisconnectDeadHostConnection(const sptr &remote) -{ - sptr serviceConnection = nullptr; - sptr hostConnection = nullptr; - { - std::scoped_lock lock(connectionLock_, agentHostMutex_); - if (remote == nullptr) { - return; - } - auto it = trackedConnections_.find(remote); - if (it == trackedConnections_.end()) { - return; - } - if (it->second.isLowCode) { - CleanupDeadLowCodeConnectionLocked(it, remote, hostConnection); - } else { - CleanupDeadStandardConnectionLocked(it, remote, serviceConnection); - } - } - - DisconnectDeadServiceConnection(serviceConnection); - DisconnectDeadHostConnection(hostConnection); -} - void AgentManagerService::HandleCallerConnectionDied(const wptr &remote) { auto remoteObject = remote.promote(); @@ -1519,207 +1388,5 @@ void AgentManagerService::ClearAgentHostSessionLocked(const AgentHostKey &key) } agentHostSessions_.erase(sessionIter); } - -AgentManagerService::StandardAgentKey AgentManagerService::BuildStandardAgentKey( - int32_t callerUid, const std::string &agentId, const AAFwk::Want &want) const -{ - StandardAgentKey key; - key.callerUid = callerUid; - key.agentId = agentId; - const auto &element = want.GetElement(); - key.bundleName = element.GetBundleName(); - key.moduleName = element.GetModuleName(); - key.abilityName = element.GetAbilityName(); - return key; -} - -bool AgentManagerService::IsStandardAgentKeyEqual(const StandardAgentKey &left, const StandardAgentKey &right) const -{ - return left.callerUid == right.callerUid && left.agentId == right.agentId && - left.bundleName == right.bundleName && left.moduleName == right.moduleName && - left.abilityName == right.abilityName; -} - -bool AgentManagerService::IsStandardAgentKeyMatched( - const StandardAgentKey &storedKey, const StandardAgentKey &incomingKey) const -{ - return storedKey.callerUid == incomingKey.callerUid && storedKey.agentId == incomingKey.agentId && - storedKey.bundleName == incomingKey.bundleName && storedKey.abilityName == incomingKey.abilityName && - (storedKey.moduleName.empty() || incomingKey.moduleName.empty() || - storedKey.moduleName == incomingKey.moduleName); -} - -std::shared_ptr AgentManagerService::FindStandardSessionLocked( - const StandardAgentKey &key) const -{ - for (const auto &entry : standardSessions_) { - if (entry != nullptr && IsStandardAgentKeyMatched(entry->key, key)) { - return entry; - } - } - return nullptr; -} - -AgentManagerService::StandardSessionIter AgentManagerService::FindStandardSessionByServiceRemoteLocked( - const sptr &serviceRemote) -{ - return std::find_if(standardSessions_.begin(), standardSessions_.end(), - [&serviceRemote](const auto &item) { - return item != nullptr && item->serviceConnection != nullptr && - item->serviceConnection->AsObject() == serviceRemote; - }); -} - -int32_t AgentManagerService::RegisterStandardSessionCallerLocked( - const std::shared_ptr &session, - const sptr &connection, bool countTowardsCallerLimit) -{ - if (session == nullptr || connection == nullptr || session->serviceConnection == nullptr) { - return ERR_INVALID_VALUE; - } - auto callerRemote = GetConnectionIdentityRemote(connection); - if (callerRemote == nullptr) { - return ERR_INVALID_VALUE; - } - - auto trackedIt = trackedConnections_.find(callerRemote); - if (trackedIt == trackedConnections_.end()) { - auto ret = TryRegisterConnectionLocked(connection, session->key.callerUid, - session->serviceConnection, nullptr, countTowardsCallerLimit); - if (ret != ERR_OK) { - return ret; - } - trackedIt = trackedConnections_.find(callerRemote); - } else if (trackedIt->second.standardKey.callerUid != 0 && - !IsStandardAgentKeyEqual(trackedIt->second.standardKey, session->key)) { - TAG_LOGE(AAFwkTag::SER_ROUTER, "Connection already belongs to another standard session"); - return ERR_INVALID_VALUE; - } - - if (trackedIt != trackedConnections_.end()) { - trackedIt->second.standardKey = session->key; - } - if (std::find(session->callerRemotes.begin(), session->callerRemotes.end(), callerRemote) == - session->callerRemotes.end()) { - session->callerRemotes.push_back(callerRemote); - } - auto &callbacks = session->state == StandardAgentState::CONNECTED ? - session->connectedCallbacks : session->pendingCallbacks; - if (std::find(callbacks.begin(), callbacks.end(), connection) == callbacks.end()) { - callbacks.push_back(connection); - } - return ERR_OK; -} - -int32_t AgentManagerService::CreateStandardAgentSession(const AAFwk::Want &connectWant, - const std::string &agentId, const StandardAgentKey &key, - const sptr &connection) -{ - auto serviceConnection = sptr::MakeSptr(connection); - if (serviceConnection == nullptr) { - return ERR_INVALID_VALUE; - } - - serviceConnection->SetStandardSessionMode(); - - auto session = std::make_shared(); - session->key = key; - session->state = StandardAgentState::CONNECTING; - session->serviceConnection = serviceConnection; - - { - std::lock_guard lock(connectionLock_); - auto ret = RegisterStandardSessionCallerLocked(session, connection, true); - if (ret != ERR_OK) { - return ret; - } - standardSessions_.emplace_back(session); - } - - auto ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbilityWithExtensionType( - connectWant, serviceConnection, nullptr, AAFwk::DEFAULT_INVAL_VALUE, AppExecFwk::ExtensionAbilityType::AGENT); - if (ret != ERR_OK) { - TAG_LOGE(AAFwkTag::SER_ROUTER, "ConnectAbilityWithExtensionType failed: %{public}d", ret); - ReleaseTrackedConnection(connection); - std::lock_guard lock(connectionLock_); - auto sessionIt = FindStandardSessionByServiceRemoteLocked(serviceConnection->AsObject()); - if (sessionIt != standardSessions_.end()) { - standardSessions_.erase(sessionIt); - } - return ret; - } - return ERR_OK; -} - -void AgentManagerService::HandleStandardAgentConnectDone( - const sptr &serviceRemote, - const AppExecFwk::ElementName &element, const sptr &remoteObject, int32_t resultCode) -{ - std::vector> callbacks; - { - std::lock_guard lock(connectionLock_); - auto sessionIt = FindStandardSessionByServiceRemoteLocked(serviceRemote); - if (sessionIt == standardSessions_.end() || *sessionIt == nullptr) { - return; - } - auto &session = *sessionIt; - session->cachedElement = element; - session->cachedRemoteObject = remoteObject; - session->cachedResultCode = resultCode; - - if (resultCode == ERR_OK && remoteObject != nullptr) { - session->state = StandardAgentState::CONNECTED; - callbacks = session->pendingCallbacks; - session->pendingCallbacks.clear(); - // Move all pending callers to connectedCallbacks for disconnect notification - session->connectedCallbacks.insert(session->connectedCallbacks.end(), - callbacks.begin(), callbacks.end()); - } else { - // Connect failed: clean up the entire collapsed session - callbacks = session->pendingCallbacks; - session->pendingCallbacks.clear(); - standardSessions_.erase(sessionIt); - } - } - - for (const auto &cb : callbacks) { - if (cb != nullptr) { - cb->OnAbilityConnectDone(element, remoteObject, resultCode); - } - if (resultCode != ERR_OK) { - ReleaseTrackedConnection(cb); - } - } -} - -void AgentManagerService::HandleStandardAgentDisconnectDone( - const sptr &serviceRemote, - const AppExecFwk::ElementName &element, int32_t resultCode) -{ - std::vector> callbacks; - { - std::lock_guard lock(connectionLock_); - auto sessionIt = FindStandardSessionByServiceRemoteLocked(serviceRemote); - if (sessionIt == standardSessions_.end() || *sessionIt == nullptr) { - return; - } - auto &session = *sessionIt; - // Collect all callers: pending + connected - callbacks = session->pendingCallbacks; - session->pendingCallbacks.clear(); - callbacks.insert(callbacks.end(), - session->connectedCallbacks.begin(), session->connectedCallbacks.end()); - session->connectedCallbacks.clear(); - // Erase session bookkeeping - standardSessions_.erase(sessionIt); - } - - for (const auto &cb : callbacks) { - if (cb != nullptr) { - cb->OnAbilityDisconnectDone(element, resultCode); - HandleConnectionDone(cb, resultCode, true); - } - } -} } // namespace AgentRuntime } // namespace OHOS diff --git a/agent_runtime_framework/services/agentmgr/src/agent_service_connection.cpp b/agent_runtime_framework/services/agentmgr/src/agent_service_connection.cpp index 963b1f5545..336b69175a 100644 --- a/agent_runtime_framework/services/agentmgr/src/agent_service_connection.cpp +++ b/agent_runtime_framework/services/agentmgr/src/agent_service_connection.cpp @@ -23,21 +23,9 @@ AgentServiceConnection::AgentServiceConnection(const sptr &remoteObject, int resultCode) { - if (isStandardSession_) { - auto service = AgentManagerService::GetInstance(); - if (service != nullptr) { - service->HandleStandardAgentConnectDone(AsObject(), element, remoteObject, resultCode); - } - return; - } if (callerConnection_ != nullptr) { callerConnection_->OnAbilityConnectDone(element, remoteObject, resultCode); } @@ -49,13 +37,6 @@ void AgentServiceConnection::OnAbilityConnectDone( void AgentServiceConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) { - if (isStandardSession_) { - auto service = AgentManagerService::GetInstance(); - if (service != nullptr) { - service->HandleStandardAgentDisconnectDone(AsObject(), element, resultCode); - } - return; - } if (callerConnection_ != nullptr) { callerConnection_->OnAbilityDisconnectDone(element, resultCode); } diff --git a/test/unittest/agent_runtime_framework/agent_connection_manager_test/agent_connection_manager_test.cpp b/test/unittest/agent_runtime_framework/agent_connection_manager_test/agent_connection_manager_test.cpp index dede936c0e..1706841732 100644 --- a/test/unittest/agent_runtime_framework/agent_connection_manager_test/agent_connection_manager_test.cpp +++ b/test/unittest/agent_runtime_framework/agent_connection_manager_test/agent_connection_manager_test.cpp @@ -884,9 +884,9 @@ HWTEST_F(AgentConnectionManagerTest, MatchConnection_001, TestSize.Level1) } /** -* @tc.name : MatchConnection_ShouldReturnTrue_WhenAgentExtProxyDiffers +* @tc.name : MatchConnection_ShouldReturnFalse_WhenAgentExtProxyDiffers * @tc.number: MatchConnection_002 -* @tc.desc : Test MatchConnection returns true when only agentExtProxy differs +* @tc.desc : Test MatchConnection returns false when agentExtProxy differs */ HWTEST_F(AgentConnectionManagerTest, MatchConnection_002, TestSize.Level1) { @@ -908,7 +908,7 @@ HWTEST_F(AgentConnectionManagerTest, MatchConnection_002, TestSize.Level1) auto &connectionEntry = *AgentConnectionManager::GetInstance().agentConnections_.begin(); auto result = AgentConnectionManager::GetInstance().MatchConnection("testAgent", want, connectionEntry); - EXPECT_TRUE(result); + EXPECT_FALSE(result); } /** @@ -959,30 +959,6 @@ HWTEST_F(AgentConnectionManagerTest, MatchConnection_004, TestSize.Level1) EXPECT_FALSE(result); } -/** -* @tc.name : MatchConnection_ShouldReturnTrue_WhenModuleNameIsEmpty -* @tc.number: MatchConnection_007 -* @tc.desc : Test MatchConnection returns true when the user-passed Want does not specify moduleName -*/ -HWTEST_F(AgentConnectionManagerTest, MatchConnection_007, TestSize.Level1) -{ - Want want; - want.SetParam(AGENTID_KEY, std::string("testAgent")); - want.SetElementName("", "test.bundle", "test.ability"); - - Want want2; - want2.SetParam(AGENTID_KEY, std::string("testAgent")); - want2.SetElementName("", "test.bundle", "test.ability", "test.module"); - - MyFlag::retConnectAgentExtensionAbility = ERR_OK; - sptr callback = new MockAbilityConnectCallback(); - AgentConnectionManager::GetInstance().ConnectAgentExtensionAbility(want2, callback); - - auto &connectionEntry = *AgentConnectionManager::GetInstance().agentConnections_.begin(); - auto result = AgentConnectionManager::GetInstance().MatchConnection("testAgent", want, connectionEntry); - EXPECT_TRUE(result); -} - /** * @tc.name : MatchConnection_ShouldReturnFalse_WhenAbilityNameDiffers * @tc.number: MatchConnection_005 @@ -1264,62 +1240,6 @@ HWTEST_F(AgentConnectionManagerTest, ConnectAbilityInner_002, TestSize.Level1) EXPECT_EQ(AgentConnectionManager::GetInstance().agentConnections_.size(), static_cast(1)); } -/** -* @tc.name : ConnectAbilityInner_ShouldReuseConnection_WhenHostProxyDiffers -* @tc.number: ConnectAbilityInner_004 -* @tc.desc : Test ConnectAbilityInner reuses connection for same agent and target with different host proxies -*/ -HWTEST_F(AgentConnectionManagerTest, ConnectAbilityInner_004, TestSize.Level1) -{ - Want want1; - want1.SetParam(AGENTID_KEY, std::string("testAgent")); - want1.SetElementName("", "test.bundle", "test.ability", "test.module"); - sptr remoteObj1 = sptr::MakeSptr(); - want1.SetParam(AGENTEXTENSIONHOSTPROXY_KEY, remoteObj1); - - Want want2; - want2.SetParam(AGENTID_KEY, std::string("testAgent")); - want2.SetElementName("", "test.bundle", "test.ability", "test.module"); - sptr remoteObj2 = sptr::MakeSptr(); - want2.SetParam(AGENTEXTENSIONHOSTPROXY_KEY, remoteObj2); - - MyFlag::retConnectAgentExtensionAbility = ERR_OK; - sptr callback1 = new MockAbilityConnectCallback(); - auto result = AgentConnectionManager::GetInstance().ConnectAgentExtensionAbility(want1, callback1); - EXPECT_EQ(result, ERR_OK); - - sptr callback2 = new MockAbilityConnectCallback(); - result = AgentConnectionManager::GetInstance().ConnectAgentExtensionAbility(want2, callback2); - EXPECT_EQ(result, ERR_OK); - EXPECT_EQ(AgentConnectionManager::GetInstance().agentConnections_.size(), static_cast(1)); - EXPECT_EQ(AgentConnectionManager::GetInstance().agentConnections_.begin()->second.size(), static_cast(2)); -} - -/** -* @tc.name : ConnectAbilityInner_ShouldCreateNewConnection_WhenExplicitModuleNameDiffers -* @tc.number: ConnectAbilityInner_005 -* @tc.desc : Test ConnectAbilityInner keeps same abilityName in different explicit modules separate -*/ -HWTEST_F(AgentConnectionManagerTest, ConnectAbilityInner_005, TestSize.Level1) -{ - Want want1; - want1.SetParam(AGENTID_KEY, std::string("testAgent")); - want1.SetElementName("", "test.bundle", "test.ability", "moduleA"); - - Want want2; - want2.SetParam(AGENTID_KEY, std::string("testAgent")); - want2.SetElementName("", "test.bundle", "test.ability", "moduleB"); - - MyFlag::retConnectAgentExtensionAbility = ERR_OK; - sptr callback1 = new MockAbilityConnectCallback(); - EXPECT_EQ(AgentConnectionManager::GetInstance().ConnectAgentExtensionAbility(want1, callback1), ERR_OK); - - sptr callback2 = new MockAbilityConnectCallback(); - EXPECT_EQ(AgentConnectionManager::GetInstance().ConnectAgentExtensionAbility(want2, callback2), ERR_OK); - - EXPECT_EQ(AgentConnectionManager::GetInstance().agentConnections_.size(), static_cast(2)); -} - /** * @tc.name : ConnectAbilityInner_ShouldRemoveConnection_WhenStateIsDisconnected (L394 coverage) * @tc.number: ConnectAbilityInner_003 diff --git a/test/unittest/agent_runtime_framework/agent_manager_service_test/agent_manager_service_test.cpp b/test/unittest/agent_runtime_framework/agent_manager_service_test/agent_manager_service_test.cpp index 9075d38bfa..fa287bc400 100644 --- a/test/unittest/agent_runtime_framework/agent_manager_service_test/agent_manager_service_test.cpp +++ b/test/unittest/agent_runtime_framework/agent_manager_service_test/agent_manager_service_test.cpp @@ -20,7 +20,6 @@ #include "ability_manager_errors.h" #include "agent_card.h" #include "agent_extension_connection_constants.h" -#include "agent_service_connection.h" #define private public #include "agent_bundle_event_callback.h" @@ -71,43 +70,6 @@ AgentCard BuildServiceTestAgentCard(const std::string &agentId) return card; } -AgentManagerService::StandardAgentKey BuildTestStandardKey() -{ - AgentManagerService::StandardAgentKey key; - key.callerUid = 100; - key.agentId = "testAgent"; - key.bundleName = "test.bundle"; - key.abilityName = "TestAbility"; - return key; -} - -std::shared_ptr AddTestStandardSession( - const sptr &service, const AgentManagerService::StandardAgentKey &key, - const sptr &serviceConnection, const std::vector> &callerRemotes, - bool isDisconnecting = false) -{ - auto session = std::make_shared(); - session->key = key; - session->serviceConnection = serviceConnection; - session->isDisconnecting = isDisconnecting; - session->callerRemotes = callerRemotes; - service->standardSessions_.emplace_back(session); - return session; -} - -void AddTestStandardTrackedConnection(const sptr &service, - const AgentManagerService::StandardAgentKey &key, const sptr &connection, - const sptr &serviceConnection, bool countTowardsCallerLimit) -{ - AgentManagerService::TrackedConnectionRecord record; - record.callerUid = key.callerUid; - record.callerRemote = connection->AsObject(); - record.serviceConnection = serviceConnection; - record.standardKey = key; - record.countTowardsCallerLimit = countTowardsCallerLimit; - service->trackedConnections_[connection->AsObject()] = record; -} - class AgentManagerServiceTest : public testing::Test { public: static void SetUpTestCase(void); @@ -166,7 +128,6 @@ void AgentManagerServiceTest::SetUp(void) auto service = AgentManagerService::GetInstance(); service->trackedConnections_.clear(); service->callerConnectionCounts_.clear(); - service->standardSessions_.clear(); MyFlag::connectAbilityWithExtensionTypeCallCount = 0; MyFlag::disconnectAbilityCallCount = 0; MyFlag::lastConnectAbilityConnection = nullptr; @@ -1485,43 +1446,6 @@ HWTEST_F(AgentManagerServiceTest, ConnectAgentExtensionAbility_026, TestSize.Lev EXPECT_EQ(connectionB->connectDoneCount, 1); } -/** - * @tc.name : ConnectAgentExtensionAbility_039 - * @tc.number: ConnectAgentExtensionAbility_039 - * @tc.desc : Test low-code connect reuses host session when moduleName is empty then explicit - */ -HWTEST_F(AgentManagerServiceTest, ConnectAgentExtensionAbility_039, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - MyFlag::retGetAgentCardByAgentId = ERR_OK; - MyFlag::agentCardType = static_cast(AgentCardType::LOW_CODE); - MyFlag::agentCardBundleName = "lowcode.bundle"; - MyFlag::agentCardAbilityName = "LowCodeExtAbility"; - MyFlag::agentCardModuleName = "entry"; - - AAFwk::Want wantA; - wantA.SetParam(AGENTID_KEY, std::string("agentA")); - wantA.SetElementName("", "lowcode.bundle", "LowCodeExtAbility", ""); - sptr connectionA = new MockAbilityConnection(); - - AAFwk::Want wantB; - wantB.SetParam(AGENTID_KEY, std::string("agentB")); - wantB.SetElementName("", "lowcode.bundle", "LowCodeExtAbility", "entry"); - sptr connectionB = new MockAbilityConnection(); - - EXPECT_EQ(service->ConnectAgentExtensionAbility(wantA, connectionA), ERR_OK); - EXPECT_EQ(MyFlag::connectAbilityWithExtensionTypeCallCount, 1); - ASSERT_EQ(service->agentHostSessions_.size(), 1); - EXPECT_EQ(service->agentHostSessions_.begin()->first.moduleName, "entry"); - - EXPECT_EQ(service->ConnectAgentExtensionAbility(wantB, connectionB), ERR_OK); - EXPECT_EQ(MyFlag::connectAbilityWithExtensionTypeCallCount, 1); - EXPECT_EQ(service->agentHostSessions_.size(), 1); - EXPECT_EQ(service->agentOwners_.size(), 2); - ASSERT_EQ(service->callerConnectionCounts_.size(), 1); - EXPECT_EQ(service->callerConnectionCounts_.begin()->second, 1); -} - /** * @tc.name : ConnectAgentExtensionAbility_027 * @tc.number: ConnectAgentExtensionAbility_027 @@ -1936,19 +1860,15 @@ HWTEST_F(AgentManagerServiceTest, ConnectAgentExtensionAbility_011, TestSize.Lev AAFwk::Want want; want.SetParam(AGENTID_KEY, std::string("testAgent")); want.SetBundle("test.bundle"); + want.SetElementName("test.bundle", "TestAbility"); std::vector> connections; for (size_t i = 0; i < AgentManagerService::MAX_CONNECTIONS_PER_CALLER; i++) { - std::string abilityName = "TestAbility" + std::to_string(i); - MyFlag::agentCardAbilityName = abilityName; - want.SetElementName("test.bundle", abilityName); auto connection = sptr::MakeSptr(); connections.emplace_back(connection); EXPECT_EQ(AgentManagerService::GetInstance()->ConnectAgentExtensionAbility(want, connection), ERR_OK); } - MyFlag::agentCardAbilityName = "OverflowAbility"; - want.SetElementName("test.bundle", "OverflowAbility"); auto overflowConnection = sptr::MakeSptr(); EXPECT_EQ(AgentManagerService::GetInstance()->ConnectAgentExtensionAbility(want, overflowConnection), ERR_MAX_AGENT_CONNECTIONS_REACHED); @@ -2126,10 +2046,7 @@ HWTEST_F(AgentManagerServiceTest, ConnectAgentExtensionAbility_013, TestSize.Lev auto connection = sptr::MakeSptr(); EXPECT_EQ(AgentManagerService::GetInstance()->ConnectAgentExtensionAbility(want, connection), ERR_OK); - EXPECT_EQ(AgentManagerService::GetInstance()->ConnectAgentExtensionAbility(want, connection), ERR_OK); - EXPECT_EQ(MyFlag::connectAbilityWithExtensionTypeCallCount, 1); - ASSERT_EQ(AgentManagerService::GetInstance()->standardSessions_.size(), 1); - EXPECT_EQ(AgentManagerService::GetInstance()->standardSessions_.front()->pendingCallbacks.size(), 1); + EXPECT_EQ(AgentManagerService::GetInstance()->ConnectAgentExtensionAbility(want, connection), ERR_INVALID_VALUE); } /** @@ -2568,36 +2485,6 @@ HWTEST_F(AgentManagerServiceTest, ResolveConnectAgentTarget_002, TestSize.Level1 callingUid), AAFwk::ERR_INVALID_AGENT_CARD_ID); } -/** -* @tc.name : ResolveConnectAgentTarget_003 -* @tc.number: ResolveConnectAgentTarget_003 -* @tc.desc : Test ResolveConnectAgentTarget normalizes module with the device-free SetElementName overload -*/ -HWTEST_F(AgentManagerServiceTest, ResolveConnectAgentTarget_003, TestSize.Level1) -{ - MyFlag::retGetAgentCardByAgentId = ERR_OK; - MyFlag::agentCardAgentId = "testAgent"; - MyFlag::agentCardType = static_cast(AgentCardType::APP); - MyFlag::agentCardBundleName = "agent.bundle"; - MyFlag::agentCardAbilityName = "AgentExtAbility"; - MyFlag::agentCardModuleName = "entry"; - - AAFwk::Want want; - want.SetParam(AGENTID_KEY, std::string("testAgent")); - want.SetElementName("remoteDevice", "agent.bundle", "AgentExtAbility"); - AAFwk::Want connectWant; - std::string agentId; - AgentCard card; - int32_t callingUid = -1; - - EXPECT_EQ(AgentManagerService::GetInstance()->ResolveConnectAgentTarget(want, connectWant, agentId, card, - callingUid), ERR_OK); - EXPECT_EQ(connectWant.GetElement().GetDeviceID(), "remoteDevice"); - EXPECT_EQ(connectWant.GetElement().GetBundleName(), "agent.bundle"); - EXPECT_EQ(connectWant.GetElement().GetAbilityName(), "AgentExtAbility"); - EXPECT_EQ(connectWant.GetElement().GetModuleName(), "entry"); -} - /** * @tc.name : PrepareStandardAgentConnectWant_001 * @tc.number: PrepareStandardAgentConnectWant_001 @@ -3769,84 +3656,6 @@ HWTEST_F(AgentManagerServiceTest, HandleCallerConnectionDied_006, TestSize.Level EXPECT_TRUE(service->agentHostSessions_.empty()); } -/** -* @tc.name : HandleCallerConnectionDied_007 -* @tc.number: HandleCallerConnectionDied_007 -* @tc.desc : Test HandleCallerConnectionDied cleans collapsed standard session and all tracked callers -*/ -HWTEST_F(AgentManagerServiceTest, HandleCallerConnectionDied_007, TestSize.Level1) -{ - auto connection1 = sptr::MakeSptr(); - auto connection2 = sptr::MakeSptr(); - auto service = AgentManagerService::GetInstance(); - auto serviceConnection = sptr::MakeSptr(connection1); - auto key = BuildTestStandardKey(); - AddTestStandardSession(service, key, serviceConnection, { connection1->AsObject(), connection2->AsObject() }); - AddTestStandardTrackedConnection(service, key, connection1, serviceConnection, true); - AddTestStandardTrackedConnection(service, key, connection2, serviceConnection, false); - service->callerConnectionCounts_[key.callerUid] = 1; - - ASSERT_EQ(service->standardSessions_.size(), 1); - - service->HandleCallerConnectionDied(wptr(connection1->AsObject())); - - EXPECT_EQ(MyFlag::disconnectAbilityCallCount, 1); - ASSERT_NE(MyFlag::lastDisconnectAbilityConnection, nullptr); - EXPECT_EQ(MyFlag::lastDisconnectAbilityConnection->AsObject(), serviceConnection->AsObject()); - EXPECT_TRUE(service->standardSessions_.empty()); - EXPECT_TRUE(service->trackedConnections_.empty()); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); -} - -/** -* @tc.name : HandleCallerConnectionDied_008 -* @tc.number: HandleCallerConnectionDied_008 -* @tc.desc : Test HandleCallerConnectionDied rolls back low-code host disconnecting flag when AMS disconnect fails -*/ -HWTEST_F(AgentManagerServiceTest, HandleCallerConnectionDied_008, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - int32_t callingUid = IPCSkeleton::GetCallingUid(); - AgentHostKey hostKey; - hostKey.userId = callingUid / 200000; - hostKey.bundleName = "lowcode.bundle"; - hostKey.moduleName = "entry"; - hostKey.abilityName = "LowCodeExtAbility"; - - auto connection = sptr::MakeSptr(); - auto remote = connection->AsObject(); - auto session = std::make_shared(); - session->key = hostKey; - session->hostUid = callingUid; - session->hostConnection = sptr::MakeSptr(hostKey); - session->callerConnections[remote] = connection; - session->agents["agentA"] = LowCodeAgentRecord { remote, false }; - service->agentHostSessions_[hostKey] = session; - service->agentOwners_[{callingUid, "agentA"}] = session; - - AgentManagerService::TrackedConnectionRecord record; - record.callerUid = callingUid; - record.callerRemote = remote; - record.serviceConnection = session->hostConnection; - record.hostKey = hostKey; - record.isLowCode = true; - service->trackedConnections_[remote] = record; - service->callerConnectionCounts_[callingUid] = 1; - MyFlag::retDisconnectAbility = ERR_INVALID_VALUE; - - service->HandleCallerConnectionDied(wptr(remote)); - - EXPECT_EQ(MyFlag::disconnectAbilityCallCount, 1); - ASSERT_EQ(service->agentHostSessions_.size(), 1); - EXPECT_FALSE(service->agentHostSessions_.begin()->second->isDisconnecting); - EXPECT_TRUE(service->agentHostSessions_.begin()->second->callerConnections.empty()); - EXPECT_TRUE(service->agentHostSessions_.begin()->second->agents.empty()); - EXPECT_TRUE(service->agentOwners_.empty()); - EXPECT_TRUE(service->trackedConnections_.empty()); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); - MyFlag::retDisconnectAbility = ERR_OK; -} - /** * @tc.name : HandleConnectionDone_001 * @tc.number: HandleConnectionDone_001 @@ -3885,967 +3694,5 @@ HWTEST_F(AgentManagerServiceTest, HandleConnectionDone_002, TestSize.Level1) EXPECT_TRUE(AgentManagerService::GetInstance()->trackedConnections_.empty()); EXPECT_TRUE(AgentManagerService::GetInstance()->callerConnectionCounts_.empty()); } - -/** - * @tc.name : ConnectAgentExtensionAbility_033 - * @tc.number: ConnectAgentExtensionAbility_033 - * @tc.desc : Test standard agent duplicate connect only triggers one AMS connect - */ -HWTEST_F(AgentManagerServiceTest, ConnectAgentExtensionAbility_033, TestSize.Level1) -{ - MyFlag::retVerifyCallingPermission = true; - MyFlag::retGetProcessRunningInfoByPid = ERR_OK; - MyFlag::processState = AppExecFwk::AppProcessState::APP_STATE_FOREGROUND; - MyFlag::retGetAgentCardByAgentId = ERR_OK; - MyFlag::agentCardAgentId = "testAgent"; - MyFlag::agentCardModuleName = "entry"; - MyFlag::agentCardType = static_cast(AgentCardType::APP); - MyFlag::retConnectAbilityWithExtensionType = ERR_OK; - - AAFwk::Want want; - want.SetParam(AGENTID_KEY, std::string("testAgent")); - want.SetBundle("test.bundle"); - want.SetElementName("test.bundle", "TestAbility"); - - sptr connection1 = new MockAbilityConnection(); - sptr connection2 = new MockAbilityConnection(); - - auto service = AgentManagerService::GetInstance(); - - // First connect - EXPECT_EQ(service->ConnectAgentExtensionAbility(want, connection1), ERR_OK); - EXPECT_EQ(MyFlag::connectAbilityWithExtensionTypeCallCount, 1); - - // Second connect (same caller+agentId+target) should not trigger another AMS connect - EXPECT_EQ(service->ConnectAgentExtensionAbility(want, connection2), ERR_OK); - EXPECT_EQ(MyFlag::connectAbilityWithExtensionTypeCallCount, 1); - - // Only one quota should be consumed - ASSERT_EQ(service->callerConnectionCounts_.size(), 1); - EXPECT_EQ(service->callerConnectionCounts_.begin()->second, 1); - - // Only one standard session should exist - ASSERT_EQ(service->standardSessions_.size(), 1); - auto &session = service->standardSessions_.front(); - ASSERT_EQ(session->pendingCallbacks.size(), 2); -} - -/** - * @tc.name : ConnectAgentExtensionAbility_034 - * @tc.number: ConnectAgentExtensionAbility_034 - * @tc.desc : Test standard agent session notifies all pending callers on connect done - */ -HWTEST_F(AgentManagerServiceTest, ConnectAgentExtensionAbility_034, TestSize.Level1) -{ - MyFlag::retVerifyCallingPermission = true; - MyFlag::retGetProcessRunningInfoByPid = ERR_OK; - MyFlag::processState = AppExecFwk::AppProcessState::APP_STATE_FOREGROUND; - MyFlag::retGetAgentCardByAgentId = ERR_OK; - MyFlag::agentCardAgentId = "testAgent"; - MyFlag::agentCardType = static_cast(AgentCardType::APP); - MyFlag::retConnectAbilityWithExtensionType = ERR_OK; - - AAFwk::Want want; - want.SetParam(AGENTID_KEY, std::string("testAgent")); - want.SetBundle("test.bundle"); - want.SetElementName("test.bundle", "TestAbility"); - - sptr connection1 = new MockAbilityConnection(); - sptr connection2 = new MockAbilityConnection(); - - auto service = AgentManagerService::GetInstance(); - - EXPECT_EQ(service->ConnectAgentExtensionAbility(want, connection1), ERR_OK); - EXPECT_EQ(service->ConnectAgentExtensionAbility(want, connection2), ERR_OK); - - ASSERT_EQ(service->standardSessions_.size(), 1); - auto svcConn = service->standardSessions_.front()->serviceConnection; - - // Simulate AMS connect done - AppExecFwk::ElementName element("", "test.bundle", "TestAbility"); - sptr mockRemote = new MockAbilityConnection(); - auto *rawSvcConn = static_cast(svcConn.GetRefPtr()); - rawSvcConn->OnAbilityConnectDone(element, mockRemote->AsObject(), ERR_OK); - - // Both callers should be notified - EXPECT_EQ(connection1->connectDoneCount, 1); - EXPECT_EQ(connection2->connectDoneCount, 1); -} - -/** - * @tc.name : ConnectAgentExtensionAbility_035 - * @tc.number: ConnectAgentExtensionAbility_035 - * @tc.desc : Test standard agent duplicate connect after connected returns cached proxy immediately - */ -HWTEST_F(AgentManagerServiceTest, ConnectAgentExtensionAbility_035, TestSize.Level1) -{ - MyFlag::retVerifyCallingPermission = true; - MyFlag::retGetProcessRunningInfoByPid = ERR_OK; - MyFlag::processState = AppExecFwk::AppProcessState::APP_STATE_FOREGROUND; - MyFlag::retGetAgentCardByAgentId = ERR_OK; - MyFlag::agentCardAgentId = "testAgent"; - MyFlag::agentCardType = static_cast(AgentCardType::APP); - MyFlag::retConnectAbilityWithExtensionType = ERR_OK; - - AAFwk::Want want; - want.SetParam(AGENTID_KEY, std::string("testAgent")); - want.SetBundle("test.bundle"); - want.SetElementName("test.bundle", "TestAbility"); - - sptr connection1 = new MockAbilityConnection(); - sptr connection2 = new MockAbilityConnection(); - sptr connection3 = new MockAbilityConnection(); - - auto service = AgentManagerService::GetInstance(); - - // First connect - EXPECT_EQ(service->ConnectAgentExtensionAbility(want, connection1), ERR_OK); - EXPECT_EQ(MyFlag::connectAbilityWithExtensionTypeCallCount, 1); - - // Simulate connect done - ASSERT_EQ(service->standardSessions_.size(), 1); - auto svcConn = service->standardSessions_.front()->serviceConnection; - AppExecFwk::ElementName element("", "test.bundle", "TestAbility"); - sptr mockRemote = new MockAbilityConnection(); - auto *rawSvcConn = static_cast(svcConn.GetRefPtr()); - rawSvcConn->OnAbilityConnectDone(element, mockRemote->AsObject(), ERR_OK); - EXPECT_EQ(connection1->connectDoneCount, 1); - - // Second connect (connecting) - added as pending but already moved to connected - EXPECT_EQ(service->ConnectAgentExtensionAbility(want, connection2), ERR_OK); - // Should not trigger another AMS connect - EXPECT_EQ(MyFlag::connectAbilityWithExtensionTypeCallCount, 1); - // Should immediately notify with cached proxy - EXPECT_EQ(connection2->connectDoneCount, 1); - - // Third connect also gets cached proxy - EXPECT_EQ(service->ConnectAgentExtensionAbility(want, connection3), ERR_OK); - EXPECT_EQ(MyFlag::connectAbilityWithExtensionTypeCallCount, 1); - EXPECT_EQ(connection3->connectDoneCount, 1); - - // Still only one quota - ASSERT_EQ(service->callerConnectionCounts_.size(), 1); - EXPECT_EQ(service->callerConnectionCounts_.begin()->second, 1); -} - -/** - * @tc.name : ConnectAgentExtensionAbility_036 - * @tc.number: ConnectAgentExtensionAbility_036 - * @tc.desc : Test standard agent connect with empty moduleName still deduplicates - */ -HWTEST_F(AgentManagerServiceTest, ConnectAgentExtensionAbility_036, TestSize.Level1) -{ - MyFlag::retVerifyCallingPermission = true; - MyFlag::retGetProcessRunningInfoByPid = ERR_OK; - MyFlag::processState = AppExecFwk::AppProcessState::APP_STATE_FOREGROUND; - MyFlag::retGetAgentCardByAgentId = ERR_OK; - MyFlag::agentCardAgentId = "testAgent"; - MyFlag::agentCardType = static_cast(AgentCardType::APP); - MyFlag::agentCardModuleName = "entry"; - MyFlag::retConnectAbilityWithExtensionType = ERR_OK; - - AAFwk::Want wantA; - wantA.SetParam(AGENTID_KEY, std::string("testAgent")); - wantA.SetBundle("test.bundle"); - wantA.SetElementName("", "test.bundle", "TestAbility", ""); - - AAFwk::Want wantB; - wantB.SetParam(AGENTID_KEY, std::string("testAgent")); - wantB.SetBundle("test.bundle"); - wantB.SetElementName("", "test.bundle", "TestAbility", "entry"); - - sptr connection1 = new MockAbilityConnection(); - sptr connection2 = new MockAbilityConnection(); - - auto service = AgentManagerService::GetInstance(); - - EXPECT_EQ(service->ConnectAgentExtensionAbility(wantA, connection1), ERR_OK); - EXPECT_EQ(MyFlag::connectAbilityWithExtensionTypeCallCount, 1); - ASSERT_EQ(service->standardSessions_.size(), 1); - ASSERT_NE(service->standardSessions_.front(), nullptr); - EXPECT_EQ(service->standardSessions_.front()->key.moduleName, "entry"); - - // Different moduleName should still deduplicate when first was empty - EXPECT_EQ(service->ConnectAgentExtensionAbility(wantB, connection2), ERR_OK); - EXPECT_EQ(MyFlag::connectAbilityWithExtensionTypeCallCount, 1); - EXPECT_EQ(service->standardSessions_.size(), 1); -} - -/** - * @tc.name : DisconnectAgentExtensionAbility_011 - * @tc.number: DisconnectAgentExtensionAbility_011 - * @tc.desc : Test standard agent disconnect releases collapsed session and notifies all callers - */ -HWTEST_F(AgentManagerServiceTest, DisconnectAgentExtensionAbility_011, TestSize.Level1) -{ - MyFlag::retVerifyCallingPermission = true; - MyFlag::retGetProcessRunningInfoByPid = ERR_OK; - MyFlag::processState = AppExecFwk::AppProcessState::APP_STATE_FOREGROUND; - MyFlag::retGetAgentCardByAgentId = ERR_OK; - MyFlag::agentCardAgentId = "testAgent"; - MyFlag::agentCardType = static_cast(AgentCardType::APP); - MyFlag::retConnectAbilityWithExtensionType = ERR_OK; - - AAFwk::Want want; - want.SetParam(AGENTID_KEY, std::string("testAgent")); - want.SetBundle("test.bundle"); - want.SetElementName("test.bundle", "TestAbility"); - - sptr connection1 = new MockAbilityConnection(); - sptr connection2 = new MockAbilityConnection(); - - auto service = AgentManagerService::GetInstance(); - - EXPECT_EQ(service->ConnectAgentExtensionAbility(want, connection1), ERR_OK); - EXPECT_EQ(service->ConnectAgentExtensionAbility(want, connection2), ERR_OK); - - // Simulate connect done - ASSERT_EQ(service->standardSessions_.size(), 1); - auto svcConn = service->standardSessions_.front()->serviceConnection; - AppExecFwk::ElementName element("", "test.bundle", "TestAbility"); - sptr mockRemote = new MockAbilityConnection(); - auto *rawSvcConn = static_cast(svcConn.GetRefPtr()); - rawSvcConn->OnAbilityConnectDone(element, mockRemote->AsObject(), ERR_OK); - - // Disconnect with the duplicate caller callback; it should tear down the collapsed session. - EXPECT_EQ(service->DisconnectAgentExtensionAbility(connection2), ERR_OK); - EXPECT_EQ(MyFlag::disconnectAbilityCallCount, 1); - - // Simulate disconnect done - rawSvcConn->OnAbilityDisconnectDone(element, ERR_OK); - EXPECT_EQ(connection1->disconnectDoneCount, 1); - EXPECT_EQ(connection2->disconnectDoneCount, 1); - - // Session should be cleaned up - EXPECT_TRUE(service->standardSessions_.empty()); - EXPECT_TRUE(service->trackedConnections_.empty()); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); -} - -/** - * @tc.name : ConnectAgentExtensionAbility_037 - * @tc.number: ConnectAgentExtensionAbility_037 - * @tc.desc : Test different targets create different standard sessions - */ -HWTEST_F(AgentManagerServiceTest, ConnectAgentExtensionAbility_037, TestSize.Level1) -{ - MyFlag::retVerifyCallingPermission = true; - MyFlag::retGetProcessRunningInfoByPid = ERR_OK; - MyFlag::processState = AppExecFwk::AppProcessState::APP_STATE_FOREGROUND; - MyFlag::retGetAgentCardByAgentId = ERR_OK; - MyFlag::agentCardAgentId = "testAgent"; - MyFlag::agentCardType = static_cast(AgentCardType::APP); - MyFlag::retConnectAbilityWithExtensionType = ERR_OK; - - AAFwk::Want wantA; - wantA.SetParam(AGENTID_KEY, std::string("testAgent")); - wantA.SetBundle("test.bundle"); - wantA.SetElementName("test.bundle", "AbilityA"); - - AAFwk::Want wantB; - wantB.SetParam(AGENTID_KEY, std::string("testAgent")); - wantB.SetBundle("test.bundle"); - wantB.SetElementName("test.bundle", "AbilityB"); - - sptr connectionA = new MockAbilityConnection(); - sptr connectionB = new MockAbilityConnection(); - - auto service = AgentManagerService::GetInstance(); - - MyFlag::agentCardAbilityName = "AbilityA"; - EXPECT_EQ(service->ConnectAgentExtensionAbility(wantA, connectionA), ERR_OK); - MyFlag::agentCardAbilityName = "AbilityB"; - EXPECT_EQ(service->ConnectAgentExtensionAbility(wantB, connectionB), ERR_OK); - - // Two different targets should trigger two AMS connects - EXPECT_EQ(MyFlag::connectAbilityWithExtensionTypeCallCount, 2); - ASSERT_EQ(service->standardSessions_.size(), 2); - - // Two quotas consumed - ASSERT_EQ(service->callerConnectionCounts_.size(), 1); - EXPECT_EQ(service->callerConnectionCounts_.begin()->second, 2); -} - -/** - * @tc.name : ConnectAgentExtensionAbility_038 - * @tc.number: ConnectAgentExtensionAbility_038 - * @tc.desc : Test standard agent connect failure cleans collapsed session and tracked callers - */ -HWTEST_F(AgentManagerServiceTest, ConnectAgentExtensionAbility_038, TestSize.Level1) -{ - MyFlag::retConnectAbilityWithExtensionType = ERR_OK; - - AAFwk::Want want; - want.SetParam(AGENTID_KEY, std::string("testAgent")); - want.SetBundle("test.bundle"); - want.SetElementName("test.bundle", "TestAbility"); - - sptr connection1 = new MockAbilityConnection(); - sptr connection2 = new MockAbilityConnection(); - auto service = AgentManagerService::GetInstance(); - - EXPECT_EQ(service->ConnectAgentExtensionAbility(want, connection1), ERR_OK); - EXPECT_EQ(service->ConnectAgentExtensionAbility(want, connection2), ERR_OK); - ASSERT_EQ(service->standardSessions_.size(), 1); - auto svcConn = service->standardSessions_.front()->serviceConnection; - - AppExecFwk::ElementName element("", "test.bundle", "TestAbility"); - auto *rawSvcConn = static_cast(svcConn.GetRefPtr()); - rawSvcConn->OnAbilityConnectDone(element, nullptr, ERR_INVALID_VALUE); - - EXPECT_EQ(connection1->connectDoneCount, 1); - EXPECT_EQ(connection1->lastConnectResultCode, ERR_INVALID_VALUE); - EXPECT_EQ(connection2->connectDoneCount, 1); - EXPECT_EQ(connection2->lastConnectResultCode, ERR_INVALID_VALUE); - EXPECT_TRUE(service->standardSessions_.empty()); - EXPECT_TRUE(service->trackedConnections_.empty()); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); -} - -/** - * @tc.name : DisconnectAgentExtensionAbility_012 - * @tc.number: DisconnectAgentExtensionAbility_012 - * @tc.desc : Test standard agent disconnect returns OK without AMS call when session already disconnecting - */ -HWTEST_F(AgentManagerServiceTest, DisconnectAgentExtensionAbility_012, TestSize.Level1) -{ - sptr connection = new MockAbilityConnection(); - auto service = AgentManagerService::GetInstance(); - auto serviceConnection = sptr::MakeSptr(connection); - auto key = BuildTestStandardKey(); - AddTestStandardSession(service, key, serviceConnection, { connection->AsObject() }, true); - AddTestStandardTrackedConnection(service, key, connection, serviceConnection, true); - service->callerConnectionCounts_[key.callerUid] = 1; - - ASSERT_EQ(service->standardSessions_.size(), 1); - - EXPECT_EQ(service->DisconnectAgentExtensionAbility(connection), ERR_OK); - EXPECT_EQ(MyFlag::disconnectAbilityCallCount, 0); - ASSERT_EQ(service->callerConnectionCounts_.size(), 1); - EXPECT_EQ(service->callerConnectionCounts_.begin()->second, 1); -} - -/** - * @tc.name : DisconnectAgentExtensionAbility_013 - * @tc.number: DisconnectAgentExtensionAbility_013 - * @tc.desc : Test standard agent disconnect failure rolls back session, tracked caller, and quota state - */ -HWTEST_F(AgentManagerServiceTest, DisconnectAgentExtensionAbility_013, TestSize.Level1) -{ - sptr connection1 = new MockAbilityConnection(); - sptr connection2 = new MockAbilityConnection(); - auto service = AgentManagerService::GetInstance(); - auto svcConn = sptr::MakeSptr(connection1); - auto key = BuildTestStandardKey(); - AddTestStandardSession(service, key, svcConn, { connection1->AsObject(), connection2->AsObject() }); - AddTestStandardTrackedConnection(service, key, connection1, svcConn, true); - AddTestStandardTrackedConnection(service, key, connection2, svcConn, false); - service->callerConnectionCounts_[key.callerUid] = 1; - - ASSERT_EQ(service->standardSessions_.size(), 1); - - MyFlag::retDisconnectAbility = ERR_INVALID_VALUE; - EXPECT_EQ(service->DisconnectAgentExtensionAbility(connection2), ERR_INVALID_VALUE); - EXPECT_EQ(MyFlag::disconnectAbilityCallCount, 1); - - ASSERT_EQ(service->standardSessions_.size(), 1); - EXPECT_FALSE(service->standardSessions_.front()->isDisconnecting); - auto trackedIt = service->trackedConnections_.find(connection2->AsObject()); - ASSERT_NE(trackedIt, service->trackedConnections_.end()); - EXPECT_FALSE(trackedIt->second.isDisconnecting); - ASSERT_EQ(service->callerConnectionCounts_.size(), 1); - EXPECT_EQ(service->callerConnectionCounts_.begin()->second, 1); -} - -/** - * @tc.name : HandleStandardAgentConnectDone_001 - * @tc.number: HandleStandardAgentConnectDone_001 - * @tc.desc : Test unknown standard service remote is ignored - */ -HWTEST_F(AgentManagerServiceTest, HandleStandardAgentConnectDone_001, TestSize.Level1) -{ - sptr connection = new MockAbilityConnection(); - AgentManagerService::StandardAgentKey key; - key.callerUid = IPCSkeleton::GetCallingUid(); - key.agentId = "testAgent"; - key.bundleName = "test.bundle"; - key.abilityName = "TestAbility"; - - auto service = AgentManagerService::GetInstance(); - auto session = std::make_shared(); - session->key = key; - session->pendingCallbacks.push_back(connection); - session->serviceConnection = sptr::MakeSptr(connection); - service->standardSessions_.emplace_back(session); - - AppExecFwk::ElementName element("", "test.bundle", "TestAbility"); - sptr unknownConnection = new MockAbilityConnection(); - service->HandleStandardAgentConnectDone(unknownConnection->AsObject(), element, unknownConnection->AsObject(), - ERR_OK); - - EXPECT_EQ(connection->connectDoneCount, 0); - ASSERT_EQ(service->standardSessions_.size(), 1); - EXPECT_EQ(service->standardSessions_.front()->state, - AgentManagerService::StandardAgentState::CONNECTING); -} - -/** - * @tc.name : StandardAgentKey_001 - * @tc.number: StandardAgentKey_001 - * @tc.desc : Test standard session key matching handles explicit and empty moduleName correctly - */ -HWTEST_F(AgentManagerServiceTest, StandardAgentKey_001, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - AgentManagerService::StandardAgentKey keyModuleA; - keyModuleA.callerUid = IPCSkeleton::GetCallingUid(); - keyModuleA.agentId = "testAgent"; - keyModuleA.bundleName = "test.bundle"; - keyModuleA.moduleName = "moduleA"; - keyModuleA.abilityName = "TestAbility"; - - AgentManagerService::StandardAgentKey keyModuleB = keyModuleA; - keyModuleB.moduleName = "moduleB"; - AgentManagerService::StandardAgentKey keyWithoutModule = keyModuleA; - keyWithoutModule.moduleName = ""; - - EXPECT_FALSE(service->IsStandardAgentKeyEqual(keyModuleA, keyModuleB)); - EXPECT_FALSE(service->IsStandardAgentKeyMatched(keyModuleA, keyModuleB)); - EXPECT_TRUE(service->IsStandardAgentKeyMatched(keyModuleA, keyWithoutModule)); - EXPECT_TRUE(service->IsStandardAgentKeyMatched(keyWithoutModule, keyModuleA)); -} - -/** - * @tc.name : StandardAgentSession_001 - * @tc.number: StandardAgentSession_001 - * @tc.desc : Test standard key build and session lookup helpers - */ -HWTEST_F(AgentManagerServiceTest, StandardAgentSession_001, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - AAFwk::Want want; - want.SetElementName("", "test.bundle", "TestAbility", "entry"); - auto key = service->BuildStandardAgentKey(100, "testAgent", want); - - EXPECT_EQ(key.callerUid, 100); - EXPECT_EQ(key.agentId, "testAgent"); - EXPECT_EQ(key.bundleName, "test.bundle"); - EXPECT_EQ(key.moduleName, "entry"); - EXPECT_EQ(key.abilityName, "TestAbility"); - - sptr connection = new MockAbilityConnection(); - auto session = std::make_shared(); - session->key = key; - session->serviceConnection = sptr::MakeSptr(connection); - service->standardSessions_.push_back(nullptr); - service->standardSessions_.push_back(session); - - auto findKey = key; - findKey.moduleName = ""; - EXPECT_EQ(service->FindStandardSessionLocked(findKey), session); - EXPECT_EQ(service->FindStandardSessionByServiceRemoteLocked(session->serviceConnection->AsObject()), - std::next(service->standardSessions_.begin())); - sptr unknownConnection = new MockAbilityConnection(); - EXPECT_EQ(service->FindStandardSessionByServiceRemoteLocked(unknownConnection->AsObject()), - service->standardSessions_.end()); -} - -/** - * @tc.name : RegisterStandardSessionCallerLocked_001 - * @tc.number: RegisterStandardSessionCallerLocked_001 - * @tc.desc : Test standard session caller registration validates input and records connected callbacks - */ -HWTEST_F(AgentManagerServiceTest, RegisterStandardSessionCallerLocked_001, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - AgentManagerService::StandardAgentKey key; - key.callerUid = IPCSkeleton::GetCallingUid(); - key.agentId = "testAgent"; - key.bundleName = "test.bundle"; - key.abilityName = "TestAbility"; - - EXPECT_EQ(service->RegisterStandardSessionCallerLocked(nullptr, connection, false), ERR_INVALID_VALUE); - auto session = std::make_shared(); - session->key = key; - EXPECT_EQ(service->RegisterStandardSessionCallerLocked(session, connection, false), ERR_INVALID_VALUE); - - session->serviceConnection = sptr::MakeSptr(connection); - session->state = AgentManagerService::StandardAgentState::CONNECTED; - EXPECT_EQ(service->RegisterStandardSessionCallerLocked(session, connection, false), ERR_OK); - EXPECT_EQ(service->RegisterStandardSessionCallerLocked(session, connection, false), ERR_OK); - - ASSERT_EQ(session->callerRemotes.size(), 1); - ASSERT_EQ(session->connectedCallbacks.size(), 1); - EXPECT_TRUE(session->pendingCallbacks.empty()); - ASSERT_EQ(service->trackedConnections_.size(), 1); - EXPECT_FALSE(service->trackedConnections_.begin()->second.countTowardsCallerLimit); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); -} - -/** - * @tc.name : RegisterStandardSessionCallerLocked_002 - * @tc.number: RegisterStandardSessionCallerLocked_002 - * @tc.desc : Test standard session caller registration rejects a connection from another standard session - */ -HWTEST_F(AgentManagerServiceTest, RegisterStandardSessionCallerLocked_002, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - AgentManagerService::StandardAgentKey existingKey; - existingKey.callerUid = 100; - existingKey.agentId = "agentA"; - existingKey.bundleName = "test.bundle"; - existingKey.abilityName = "AbilityA"; - - AgentManagerService::TrackedConnectionRecord record; - record.callerUid = existingKey.callerUid; - record.callerRemote = connection->AsObject(); - record.standardKey = existingKey; - service->trackedConnections_[connection->AsObject()] = record; - - auto session = std::make_shared(); - session->key = existingKey; - session->key.agentId = "agentB"; - session->serviceConnection = sptr::MakeSptr(connection); - EXPECT_EQ(service->RegisterStandardSessionCallerLocked(session, connection, false), ERR_INVALID_VALUE); -} - -/** - * @tc.name : CreateStandardAgentSession_001 - * @tc.number: CreateStandardAgentSession_001 - * @tc.desc : Test standard session creation rolls back tracking when AMS connect fails immediately - */ -HWTEST_F(AgentManagerServiceTest, CreateStandardAgentSession_001, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - AAFwk::Want want; - want.SetElementName("", "test.bundle", "TestAbility", "entry"); - auto key = service->BuildStandardAgentKey(IPCSkeleton::GetCallingUid(), "testAgent", want); - sptr connection = new MockAbilityConnection(); - MyFlag::retConnectAbilityWithExtensionType = ERR_INVALID_VALUE; - - EXPECT_EQ(service->CreateStandardAgentSession(want, "testAgent", key, connection), ERR_INVALID_VALUE); - EXPECT_EQ(MyFlag::connectAbilityWithExtensionTypeCallCount, 1); - EXPECT_TRUE(service->standardSessions_.empty()); - EXPECT_TRUE(service->trackedConnections_.empty()); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); - MyFlag::retConnectAbilityWithExtensionType = ERR_OK; -} - -/** - * @tc.name : HandleStandardAgentConnectDone_002 - * @tc.number: HandleStandardAgentConnectDone_002 - * @tc.desc : Test standard connect done caches proxy and moves pending callbacks to connected callbacks - */ -HWTEST_F(AgentManagerServiceTest, HandleStandardAgentConnectDone_002, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - auto session = std::make_shared(); - session->key.callerUid = IPCSkeleton::GetCallingUid(); - session->key.agentId = "testAgent"; - session->key.bundleName = "test.bundle"; - session->key.abilityName = "TestAbility"; - session->serviceConnection = sptr::MakeSptr(connection); - session->pendingCallbacks.push_back(connection); - service->standardSessions_.push_back(session); - - AppExecFwk::ElementName element("", "test.bundle", "TestAbility"); - sptr proxy = new MockAbilityConnection(); - service->HandleStandardAgentConnectDone(session->serviceConnection->AsObject(), element, proxy->AsObject(), - ERR_OK); - - EXPECT_EQ(connection->connectDoneCount, 1); - EXPECT_EQ(connection->lastConnectResultCode, ERR_OK); - EXPECT_EQ(session->state, AgentManagerService::StandardAgentState::CONNECTED); - EXPECT_TRUE(session->pendingCallbacks.empty()); - ASSERT_EQ(session->connectedCallbacks.size(), 1); - EXPECT_EQ(session->cachedRemoteObject, proxy->AsObject()); - ASSERT_EQ(service->standardSessions_.size(), 1); -} - -/** - * @tc.name : HandleStandardAgentDisconnectDone_001 - * @tc.number: HandleStandardAgentDisconnectDone_001 - * @tc.desc : Test standard disconnect done ignores unknown service remote - */ -HWTEST_F(AgentManagerServiceTest, HandleStandardAgentDisconnectDone_001, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - auto session = std::make_shared(); - session->serviceConnection = sptr::MakeSptr(connection); - session->connectedCallbacks.push_back(connection); - service->standardSessions_.push_back(session); - - sptr unknownConnection = new MockAbilityConnection(); - AppExecFwk::ElementName element("", "test.bundle", "TestAbility"); - service->HandleStandardAgentDisconnectDone(unknownConnection->AsObject(), element, ERR_OK); - - EXPECT_EQ(connection->disconnectDoneCount, 0); - ASSERT_EQ(service->standardSessions_.size(), 1); -} - -/** - * @tc.name : HandleStandardAgentDisconnectDone_002 - * @tc.number: HandleStandardAgentDisconnectDone_002 - * @tc.desc : Test standard disconnect done notifies pending and connected callbacks and clears tracking - */ -HWTEST_F(AgentManagerServiceTest, HandleStandardAgentDisconnectDone_002, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr pendingConnection = new MockAbilityConnection(); - sptr connectedConnection = new MockAbilityConnection(); - auto session = std::make_shared(); - session->serviceConnection = sptr::MakeSptr(connectedConnection); - session->pendingCallbacks.push_back(pendingConnection); - session->connectedCallbacks.push_back(connectedConnection); - service->standardSessions_.push_back(session); - - AgentManagerService::TrackedConnectionRecord pendingRecord; - pendingRecord.callerUid = 100; - pendingRecord.callerRemote = pendingConnection->AsObject(); - pendingRecord.isDisconnecting = true; - service->trackedConnections_[pendingConnection->AsObject()] = pendingRecord; - AgentManagerService::TrackedConnectionRecord connectedRecord; - connectedRecord.callerUid = 100; - connectedRecord.callerRemote = connectedConnection->AsObject(); - connectedRecord.isDisconnecting = true; - service->trackedConnections_[connectedConnection->AsObject()] = connectedRecord; - - AppExecFwk::ElementName element("", "test.bundle", "TestAbility"); - service->HandleStandardAgentDisconnectDone(session->serviceConnection->AsObject(), element, ERR_OK); - - EXPECT_EQ(pendingConnection->disconnectDoneCount, 1); - EXPECT_EQ(connectedConnection->disconnectDoneCount, 1); - EXPECT_TRUE(service->standardSessions_.empty()); - EXPECT_TRUE(service->trackedConnections_.empty()); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); -} - -/** - * @tc.name : PrepareLowCodeDisconnectLocked_001 - * @tc.number: PrepareLowCodeDisconnectLocked_001 - * @tc.desc : Test low-code disconnect preparation handles missing host session and quota rollback - */ -HWTEST_F(AgentManagerServiceTest, PrepareLowCodeDisconnectLocked_001, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - AgentHostKey hostKey; - hostKey.userId = 0; - hostKey.bundleName = "lowcode.bundle"; - hostKey.moduleName = "entry"; - hostKey.abilityName = "LowCodeExtAbility"; - - AgentManagerService::TrackedConnectionRecord record; - record.callerUid = 100; - record.callerRemote = connection->AsObject(); - record.hostKey = hostKey; - record.isLowCode = true; - service->trackedConnections_[connection->AsObject()] = record; - auto trackedIt = service->trackedConnections_.find(connection->AsObject()); - AgentManagerService::AgentDisconnectPlan plan; - - EXPECT_EQ(service->PrepareLowCodeDisconnectLocked(trackedIt, plan), ERR_INVALID_VALUE); - - auto session = std::make_shared(); - session->key = hostKey; - session->hostConnection = sptr::MakeSptr(hostKey); - service->agentHostSessions_[hostKey] = session; - EXPECT_EQ(service->PrepareLowCodeDisconnectLocked(trackedIt, plan), ERR_INVALID_VALUE); - EXPECT_FALSE(session->isDisconnecting); - EXPECT_FALSE(trackedIt->second.isDisconnecting); -} - -/** - * @tc.name : PrepareStandardDisconnectLocked_001 - * @tc.number: PrepareStandardDisconnectLocked_001 - * @tc.desc : Test standard disconnect preparation falls back when no standard key exists - */ -HWTEST_F(AgentManagerServiceTest, PrepareStandardDisconnectLocked_001, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - auto serviceConnection = sptr::MakeSptr(connection); - AgentManagerService::TrackedConnectionRecord record; - record.callerUid = 100; - record.callerRemote = connection->AsObject(); - record.serviceConnection = serviceConnection; - service->trackedConnections_[connection->AsObject()] = record; - service->callerConnectionCounts_[record.callerUid] = 1; - auto trackedIt = service->trackedConnections_.find(connection->AsObject()); - AgentManagerService::AgentDisconnectPlan plan; - plan.callerRemote = connection->AsObject(); - - EXPECT_EQ(service->PrepareStandardDisconnectLocked(trackedIt, plan), ERR_OK); - - EXPECT_TRUE(trackedIt->second.isDisconnecting); - EXPECT_EQ(plan.serviceConnection.GetRefPtr(), serviceConnection.GetRefPtr()); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); -} - -/** - * @tc.name : PrepareStandardDisconnectLocked_002 - * @tc.number: PrepareStandardDisconnectLocked_002 - * @tc.desc : Test standard disconnect preparation reports quota release failure - */ -HWTEST_F(AgentManagerServiceTest, PrepareStandardDisconnectLocked_002, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - AgentManagerService::TrackedConnectionRecord record; - record.callerUid = 100; - record.callerRemote = connection->AsObject(); - record.serviceConnection = sptr::MakeSptr(connection); - service->trackedConnections_[connection->AsObject()] = record; - auto trackedIt = service->trackedConnections_.find(connection->AsObject()); - AgentManagerService::AgentDisconnectPlan plan; - plan.callerRemote = connection->AsObject(); - - EXPECT_EQ(service->PrepareStandardDisconnectLocked(trackedIt, plan), ERR_INVALID_VALUE); - - EXPECT_TRUE(trackedIt->second.isDisconnecting); - EXPECT_EQ(plan.serviceConnection, nullptr); -} - -/** - * @tc.name : PrepareStandardDisconnectLocked_003 - * @tc.number: PrepareStandardDisconnectLocked_003 - * @tc.desc : Test standard disconnect preparation falls back when no matching standard session exists - */ -HWTEST_F(AgentManagerServiceTest, PrepareStandardDisconnectLocked_003, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - auto serviceConnection = sptr::MakeSptr(connection); - auto key = BuildTestStandardKey(); - AgentManagerService::TrackedConnectionRecord record; - record.callerUid = key.callerUid; - record.callerRemote = connection->AsObject(); - record.serviceConnection = serviceConnection; - record.standardKey = key; - service->trackedConnections_[connection->AsObject()] = record; - service->callerConnectionCounts_[key.callerUid] = 1; - service->standardSessions_.push_back(nullptr); - auto nonMatchingSession = std::make_shared(); - nonMatchingSession->key = key; - nonMatchingSession->key.agentId = "anotherAgent"; - service->standardSessions_.push_back(nonMatchingSession); - auto trackedIt = service->trackedConnections_.find(connection->AsObject()); - AgentManagerService::AgentDisconnectPlan plan; - plan.callerRemote = connection->AsObject(); - - EXPECT_EQ(service->PrepareStandardDisconnectLocked(trackedIt, plan), ERR_OK); - - EXPECT_TRUE(trackedIt->second.isDisconnecting); - EXPECT_EQ(plan.serviceConnection.GetRefPtr(), serviceConnection.GetRefPtr()); - EXPECT_FALSE(plan.isStandard); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); -} - -/** - * @tc.name : PrepareStandardDisconnectLocked_004 - * @tc.number: PrepareStandardDisconnectLocked_004 - * @tc.desc : Test standard disconnect preparation no-ops when session is already disconnecting - */ -HWTEST_F(AgentManagerServiceTest, PrepareStandardDisconnectLocked_004, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - auto serviceConnection = sptr::MakeSptr(connection); - auto key = BuildTestStandardKey(); - AddTestStandardSession(service, key, serviceConnection, { connection->AsObject() }, true); - AddTestStandardTrackedConnection(service, key, connection, serviceConnection, true); - service->callerConnectionCounts_[key.callerUid] = 1; - auto trackedIt = service->trackedConnections_.find(connection->AsObject()); - AgentManagerService::AgentDisconnectPlan plan; - plan.callerRemote = connection->AsObject(); - - EXPECT_EQ(service->PrepareStandardDisconnectLocked(trackedIt, plan), ERR_OK); - - EXPECT_FALSE(trackedIt->second.isDisconnecting); - EXPECT_EQ(plan.serviceConnection, nullptr); - EXPECT_FALSE(plan.isStandard); - ASSERT_EQ(service->callerConnectionCounts_.size(), 1); - EXPECT_EQ(service->callerConnectionCounts_[key.callerUid], 1); -} - -/** - * @tc.name : CleanupDeadStandardConnectionLocked_001 - * @tc.number: CleanupDeadStandardConnectionLocked_001 - * @tc.desc : Test dead standard cleanup releases a record without standard session metadata - */ -HWTEST_F(AgentManagerServiceTest, CleanupDeadStandardConnectionLocked_001, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - auto serviceConnection = sptr::MakeSptr(connection); - AgentManagerService::TrackedConnectionRecord record; - record.callerUid = 100; - record.callerRemote = connection->AsObject(); - record.serviceConnection = serviceConnection; - service->trackedConnections_[connection->AsObject()] = record; - service->callerConnectionCounts_[record.callerUid] = 1; - auto trackedIt = service->trackedConnections_.find(connection->AsObject()); - sptr disconnectedConnection = nullptr; - - service->CleanupDeadStandardConnectionLocked(trackedIt, connection->AsObject(), disconnectedConnection); - - EXPECT_EQ(disconnectedConnection.GetRefPtr(), serviceConnection.GetRefPtr()); - EXPECT_TRUE(service->trackedConnections_.empty()); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); -} - -/** - * @tc.name : CleanupDeadStandardConnectionLocked_002 - * @tc.number: CleanupDeadStandardConnectionLocked_002 - * @tc.desc : Test dead standard cleanup falls back when no matching standard session exists - */ -HWTEST_F(AgentManagerServiceTest, CleanupDeadStandardConnectionLocked_002, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - auto serviceConnection = sptr::MakeSptr(connection); - auto key = BuildTestStandardKey(); - AddTestStandardTrackedConnection(service, key, connection, serviceConnection, true); - service->callerConnectionCounts_[key.callerUid] = 1; - service->standardSessions_.push_back(nullptr); - auto nonMatchingSession = std::make_shared(); - nonMatchingSession->key = key; - nonMatchingSession->key.abilityName = "AnotherAbility"; - service->standardSessions_.push_back(nonMatchingSession); - auto trackedIt = service->trackedConnections_.find(connection->AsObject()); - sptr disconnectedConnection = nullptr; - - service->CleanupDeadStandardConnectionLocked(trackedIt, connection->AsObject(), disconnectedConnection); - - EXPECT_EQ(disconnectedConnection.GetRefPtr(), serviceConnection.GetRefPtr()); - EXPECT_TRUE(service->trackedConnections_.empty()); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); - ASSERT_EQ(service->standardSessions_.size(), 2); -} - -/** - * @tc.name : RollbackAgentDisconnectLocked_001 - * @tc.number: RollbackAgentDisconnectLocked_001 - * @tc.desc : Test disconnect rollback restores low-code and normal tracked state - */ -HWTEST_F(AgentManagerServiceTest, RollbackAgentDisconnectLocked_001, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - AgentHostKey hostKey; - hostKey.userId = 0; - hostKey.bundleName = "lowcode.bundle"; - hostKey.moduleName = "entry"; - hostKey.abilityName = "LowCodeExtAbility"; - - auto session = std::make_shared(); - session->key = hostKey; - session->isDisconnecting = true; - service->agentHostSessions_[hostKey] = session; - - AgentManagerService::TrackedConnectionRecord record; - record.callerUid = 100; - record.callerRemote = connection->AsObject(); - record.isDisconnecting = true; - service->trackedConnections_[connection->AsObject()] = record; - - AgentManagerService::AgentDisconnectPlan plan; - plan.callerRemote = connection->AsObject(); - plan.hostKey = hostKey; - plan.hasHostKey = true; - service->RollbackAgentDisconnectLocked(plan); - - EXPECT_FALSE(session->isDisconnecting); - EXPECT_FALSE(service->trackedConnections_[connection->AsObject()].isDisconnecting); - ASSERT_EQ(service->callerConnectionCounts_.size(), 1); - EXPECT_EQ(service->callerConnectionCounts_[100], 1); -} - -/** - * @tc.name : RollbackAgentDisconnectLocked_002 - * @tc.number: RollbackAgentDisconnectLocked_002 - * @tc.desc : Test standard rollback handles missing session, missing tracked record, and zero caller uid - */ -HWTEST_F(AgentManagerServiceTest, RollbackAgentDisconnectLocked_002, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - service->standardSessions_.push_back(nullptr); - sptr connection = new MockAbilityConnection(); - AgentManagerService::AgentDisconnectPlan plan; - plan.callerRemote = connection->AsObject(); - plan.isStandard = true; - plan.standardKey = BuildTestStandardKey(); - plan.standardCallerUid = 0; - - service->RollbackAgentDisconnectLocked(plan); - - EXPECT_TRUE(service->callerConnectionCounts_.empty()); - ASSERT_EQ(service->standardSessions_.size(), 1); -} - -/** - * @tc.name : RollbackAgentDisconnectLocked_003 - * @tc.number: RollbackAgentDisconnectLocked_003 - * @tc.desc : Test standard rollback restores session and tracked state without normal quota increment - */ -HWTEST_F(AgentManagerServiceTest, RollbackAgentDisconnectLocked_003, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - auto serviceConnection = sptr::MakeSptr(connection); - auto key = BuildTestStandardKey(); - auto session = AddTestStandardSession(service, key, serviceConnection, { connection->AsObject() }, true); - AddTestStandardTrackedConnection(service, key, connection, serviceConnection, true); - service->trackedConnections_[connection->AsObject()].isDisconnecting = true; - - AgentManagerService::AgentDisconnectPlan plan; - plan.callerRemote = connection->AsObject(); - plan.isStandard = true; - plan.standardKey = key; - plan.standardCallerUid = key.callerUid; - - service->RollbackAgentDisconnectLocked(plan); - - EXPECT_FALSE(session->isDisconnecting); - EXPECT_FALSE(service->trackedConnections_[connection->AsObject()].isDisconnecting); - ASSERT_EQ(service->callerConnectionCounts_.size(), 1); - EXPECT_EQ(service->callerConnectionCounts_[key.callerUid], 1); -} - -/** - * @tc.name : RollbackAgentDisconnectLocked_004 - * @tc.number: RollbackAgentDisconnectLocked_004 - * @tc.desc : Test rollback tolerates null low-code host session and non-disconnecting tracked record - */ -HWTEST_F(AgentManagerServiceTest, RollbackAgentDisconnectLocked_004, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - sptr connection = new MockAbilityConnection(); - AgentHostKey hostKey; - hostKey.userId = 0; - hostKey.bundleName = "lowcode.bundle"; - hostKey.moduleName = "entry"; - hostKey.abilityName = "LowCodeExtAbility"; - service->agentHostSessions_[hostKey] = nullptr; - AgentManagerService::TrackedConnectionRecord record; - record.callerUid = 100; - record.callerRemote = connection->AsObject(); - record.isDisconnecting = false; - service->trackedConnections_[connection->AsObject()] = record; - - AgentManagerService::AgentDisconnectPlan plan; - plan.callerRemote = connection->AsObject(); - plan.hostKey = hostKey; - plan.hasHostKey = true; - - service->RollbackAgentDisconnectLocked(plan); - - EXPECT_FALSE(service->trackedConnections_[connection->AsObject()].isDisconnecting); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); -} } // namespace AgentRuntime } // namespace OHOS diff --git a/test/unittest/agent_runtime_framework/agent_service_connection_test/agent_service_connection_test.cpp b/test/unittest/agent_runtime_framework/agent_service_connection_test/agent_service_connection_test.cpp index 1d623f8976..2ef0434dcb 100644 --- a/test/unittest/agent_runtime_framework/agent_service_connection_test/agent_service_connection_test.cpp +++ b/test/unittest/agent_runtime_framework/agent_service_connection_test/agent_service_connection_test.cpp @@ -71,7 +71,6 @@ public: auto service = AgentManagerService::GetInstance(); service->trackedConnections_.clear(); service->callerConnectionCounts_.clear(); - service->standardSessions_.clear(); } }; @@ -148,201 +147,5 @@ HWTEST_F(AgentServiceConnectionTest, OnAbilityDisconnectDone_001, TestSize.Level EXPECT_TRUE(service->trackedConnections_.empty()); EXPECT_TRUE(service->callerConnectionCounts_.empty()); } - -/** -* @tc.name : SetStandardSessionMode_001 -* @tc.number: SetStandardSessionMode_001 -* @tc.desc : Test SetStandardSessionMode sets the internal flag -*/ -HWTEST_F(AgentServiceConnectionTest, SetStandardSessionMode_001, TestSize.Level1) -{ - auto callerConnection = sptr::MakeSptr(); - auto agentConnection = sptr::MakeSptr(callerConnection); - - EXPECT_FALSE(agentConnection->isStandardSession_); - agentConnection->SetStandardSessionMode(); - EXPECT_TRUE(agentConnection->isStandardSession_); -} - -/** -* @tc.name : OnAbilityConnectDone_003 -* @tc.number: OnAbilityConnectDone_003 -* @tc.desc : Test standard session mode connect done routes to HandleStandardAgentConnectDone and notifies all -* pending callers -*/ -HWTEST_F(AgentServiceConnectionTest, OnAbilityConnectDone_003, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - - // Build a standard session with two pending callers - auto caller1 = sptr::MakeSptr(); - auto caller2 = sptr::MakeSptr(); - - AgentManagerService::StandardAgentKey key; - key.callerUid = 100; - key.agentId = "testAgent"; - key.bundleName = "test.bundle"; - key.abilityName = "TestAbility"; - - auto session = std::make_shared(); - session->key = key; - session->state = AgentManagerService::StandardAgentState::CONNECTING; - session->pendingCallbacks.push_back(caller1); - session->pendingCallbacks.push_back(caller2); - - auto agentConnection = sptr::MakeSptr(nullptr); - agentConnection->SetStandardSessionMode(); - session->serviceConnection = agentConnection; - - // Register the session so HandleStandardAgentConnectDone can find it - service->standardSessions_.emplace_back(session); - - // Simulate AMS connect done - AppExecFwk::ElementName element("", "test.bundle", "TestAbility"); - sptr remoteObject = new (std::nothrow) IPCObjectStub(u"test.remote"); - agentConnection->OnAbilityConnectDone(element, remoteObject, ERR_OK); - - // Both pending callers should be notified - EXPECT_EQ(caller1->connectDoneCount, 1); - EXPECT_EQ(caller1->lastResultCode, ERR_OK); - EXPECT_EQ(caller1->lastRemoteObject, remoteObject); - EXPECT_EQ(caller2->connectDoneCount, 1); - EXPECT_EQ(caller2->lastResultCode, ERR_OK); - EXPECT_EQ(caller2->lastRemoteObject, remoteObject); - - // Session should be CONNECTED and pendingCallbacks should be empty - EXPECT_EQ(session->state, AgentManagerService::StandardAgentState::CONNECTED); - EXPECT_TRUE(session->pendingCallbacks.empty()); - // Both should be in connectedCallbacks now - EXPECT_EQ(session->connectedCallbacks.size(), 2); -} - -/** -* @tc.name : OnAbilityConnectDone_004 -* @tc.number: OnAbilityConnectDone_004 -* @tc.desc : Test standard session mode connect failure cleans up session and notifies pending callers -*/ -HWTEST_F(AgentServiceConnectionTest, OnAbilityConnectDone_004, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - - auto caller1 = sptr::MakeSptr(); - - AgentManagerService::StandardAgentKey key; - key.callerUid = 100; - key.agentId = "testAgent"; - key.bundleName = "test.bundle"; - key.abilityName = "TestAbility"; - - auto session = std::make_shared(); - session->key = key; - session->state = AgentManagerService::StandardAgentState::CONNECTING; - session->pendingCallbacks.push_back(caller1); - - auto agentConnection = sptr::MakeSptr(nullptr); - agentConnection->SetStandardSessionMode(); - session->serviceConnection = agentConnection; - - service->standardSessions_.emplace_back(session); - - // Simulate AMS connect failure - AppExecFwk::ElementName element("", "test.bundle", "TestAbility"); - agentConnection->OnAbilityConnectDone(element, nullptr, ERR_INVALID_VALUE); - - // Caller should be notified of failure - EXPECT_EQ(caller1->connectDoneCount, 1); - EXPECT_EQ(caller1->lastResultCode, ERR_INVALID_VALUE); - - // Session should be cleaned up - EXPECT_TRUE(service->standardSessions_.empty()); -} - -/** -* @tc.name : OnAbilityDisconnectDone_002 -* @tc.number: OnAbilityDisconnectDone_002 -* @tc.desc : Test standard session mode disconnect done notifies all callers and cleans up session -*/ -HWTEST_F(AgentServiceConnectionTest, OnAbilityDisconnectDone_002, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - - auto caller1 = sptr::MakeSptr(); - auto caller2 = sptr::MakeSptr(); - - AgentManagerService::StandardAgentKey key; - key.callerUid = 100; - key.agentId = "testAgent"; - key.bundleName = "test.bundle"; - key.abilityName = "TestAbility"; - - auto session = std::make_shared(); - session->key = key; - session->state = AgentManagerService::StandardAgentState::CONNECTED; - session->connectedCallbacks.push_back(caller1); - session->connectedCallbacks.push_back(caller2); - - auto agentConnection = sptr::MakeSptr(nullptr); - agentConnection->SetStandardSessionMode(); - session->serviceConnection = agentConnection; - - // Also set up a tracked connection for the first caller so HandleConnectionDone can clean up - AgentManagerService::TrackedConnectionRecord record; - record.callerUid = 100; - record.isDisconnecting = true; - service->trackedConnections_.emplace(caller1->AsObject(), record); - - service->standardSessions_.emplace_back(session); - - // Simulate AMS disconnect done - AppExecFwk::ElementName element("", "test.bundle", "TestAbility"); - agentConnection->OnAbilityDisconnectDone(element, ERR_OK); - - // Both callers should be notified - EXPECT_EQ(caller1->disconnectDoneCount, 1); - EXPECT_EQ(caller1->lastResultCode, ERR_OK); - EXPECT_EQ(caller2->disconnectDoneCount, 1); - EXPECT_EQ(caller2->lastResultCode, ERR_OK); - - // Session should be cleaned up - EXPECT_TRUE(service->standardSessions_.empty()); - EXPECT_TRUE(service->trackedConnections_.empty()); - EXPECT_TRUE(service->callerConnectionCounts_.empty()); -} - -/** -* @tc.name : OnAbilityConnectDone_005 -* @tc.number: OnAbilityConnectDone_005 -* @tc.desc : Test standard session mode does not forward to callerConnection (which is null) -*/ -HWTEST_F(AgentServiceConnectionTest, OnAbilityConnectDone_005, TestSize.Level1) -{ - auto service = AgentManagerService::GetInstance(); - - AgentManagerService::StandardAgentKey key; - key.callerUid = 100; - key.agentId = "testAgent"; - key.bundleName = "test.bundle"; - key.abilityName = "TestAbility"; - - auto session = std::make_shared(); - session->key = key; - session->state = AgentManagerService::StandardAgentState::CONNECTING; - // No pending callbacks — session mode should still work without crash - - auto agentConnection = sptr::MakeSptr(nullptr); - agentConnection->SetStandardSessionMode(); - session->serviceConnection = agentConnection; - - service->standardSessions_.emplace_back(session); - - AppExecFwk::ElementName element("", "test.bundle", "TestAbility"); - sptr remoteObject = new (std::nothrow) IPCObjectStub(u"test.remote"); - // Should not crash even with no pending callbacks - agentConnection->OnAbilityConnectDone(element, remoteObject, ERR_OK); - - EXPECT_EQ(session->state, AgentManagerService::StandardAgentState::CONNECTED); - EXPECT_TRUE(session->pendingCallbacks.empty()); - EXPECT_TRUE(session->connectedCallbacks.empty()); -} } // namespace AgentRuntime } // namespace OHOS