* Copyright (c) 2021-2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "connection_record.h"
#include "ability_manager_service.h"
#include "ability_util.h"
#include "agent_card.h"
#include "agent_extension_connection_constants.h"
#include "agent_receiver_proxy.h"
#include "connection_state_manager.h"
#include "freeze_util.h"
#include "ui_service_extension_connection_constants.h"
#include "utils/agent_ability_util.h"
namespace OHOS {
namespace AAFwk {
int64_t ConnectionRecord::connectRecordId = 0;
#ifdef SUPPORT_ASAN
const int DISCONNECT_TIMEOUT_MULTIPLE = 75;
#else
const int DISCONNECT_TIMEOUT_MULTIPLE = 1;
#endif
ConnectionRecord::ConnectionRecord(const sptr<IRemoteObject> &callerToken,
const std::shared_ptr<BaseExtensionRecord> &targetService, const sptr<IAbilityConnection> &connCallback,
std::shared_ptr<AbilityConnectManager> abilityConnectManager)
: state_(ConnectionState::INIT),
callerToken_(callerToken),
targetService_(targetService),
connCallback_(connCallback),
abilityConnectManager_(abilityConnectManager)
{
recordId_ = connectRecordId++;
}
ConnectionRecord::~ConnectionRecord()
{}
std::shared_ptr<ConnectionRecord> ConnectionRecord::CreateConnectionRecord(const sptr<IRemoteObject> &callerToken,
const std::shared_ptr<BaseExtensionRecord> &targetService, const sptr<IAbilityConnection> &connCallback,
std::shared_ptr<AbilityConnectManager> abilityConnectManager)
{
auto connRecord = std::make_shared<ConnectionRecord>(
callerToken, targetService, connCallback, abilityConnectManager);
CHECK_POINTER_AND_RETURN(connRecord, nullptr);
connRecord->SetConnectState(ConnectionState::INIT);
return connRecord;
}
void ConnectionRecord::SetConnectState(const ConnectionState &state)
{
state_ = state;
}
ConnectionState ConnectionRecord::GetConnectState() const
{
return state_;
}
sptr<IRemoteObject> ConnectionRecord::GetToken() const
{
return callerToken_;
}
std::shared_ptr<BaseExtensionRecord> ConnectionRecord::GetAbilityRecord() const
{
return targetService_;
}
sptr<IAbilityConnection> ConnectionRecord::GetAbilityConnectCallback() const
{
std::lock_guard lock(callbackMutex_);
return connCallback_;
}
void ConnectionRecord::ClearConnCallBack()
{
std::lock_guard lock(callbackMutex_);
if (connCallback_) {
connCallback_.clear();
}
}
int ConnectionRecord::DisconnectAbility()
{
if (state_ != ConnectionState::CONNECTED) {
TAG_LOGE(AAFwkTag::CONNECTION, "connection not established, state: %{public}d",
static_cast<int32_t>(state_));
return INVALID_CONNECTION_STATE;
}
SetConnectState(ConnectionState::DISCONNECTING);
CHECK_POINTER_AND_RETURN(targetService_, ERR_INVALID_VALUE);
const auto &abilityInfo = targetService_->GetAbilityInfo();
auto extAbilityType = abilityInfo.extensionAbilityType;
bool isPerConnectionType = (extAbilityType == AppExecFwk::ExtensionAbilityType::UI_SERVICE ||
extAbilityType == AppExecFwk::ExtensionAbilityType::AGENT);
size_t connectNums = targetService_->GetConnectRecordList().size();
if (connectNums == 1 || isPerConnectionType) {
ScheduleDisconnectTimeout();
if (isPerConnectionType) {
const char *extName = (extAbilityType == AppExecFwk::ExtensionAbilityType::UI_SERVICE) ?
"UIServiceExtension" : "AgentExtension";
TAG_LOGI(AAFwkTag::CONNECTION,
"Disconnect %{public}s ability, recordId=%{public}d, state=%{public}d, connectNums=%{public}zu, "
"agentId=%{public}s, cardType=%{public}d, callbackNull=%{public}d",
extName, GetRecordId(), static_cast<int32_t>(state_), connectNums,
connectWant_.GetStringParam(AgentRuntime::AGENTID_KEY).c_str(),
connectWant_.GetIntParam(AgentRuntime::AGENT_CARD_TYPE_KEY, -1),
GetAbilityConnectCallback() == nullptr ? 1 : 0);
targetService_->DisconnectAbilityWithWant(GetConnectWant());
} else {
TAG_LOGI(AAFwkTag::CONNECTION, "Disconnect %{public}s", abilityInfo.name.c_str());
targetService_->DisconnectAbility();
}
} else {
TAG_LOGI(AAFwkTag::CONNECTION,
"current:%{public}zu,%{public}s:%{public}s,remove",
connectNums, abilityInfo.bundleName.c_str(), abilityInfo.name.c_str());
targetService_->RemoveConnectRecordFromList(shared_from_this());
SetConnectState(ConnectionState::DISCONNECTED);
}
return ERR_OK;
}
void ConnectionRecord::CompleteConnect()
{
SetConnectState(ConnectionState::CONNECTED);
CHECK_POINTER(targetService_);
targetService_->SetAbilityState(AbilityState::ACTIVE);
TAG_LOGI(AAFwkTag::ABILITYMGR, "Connect,%{public}s", targetService_->GetAbilityInfo().name.c_str());
const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
AppExecFwk::ElementName element(targetService_->GetWant().GetDeviceIdRef(), abilityInfo.bundleName,
abilityInfo.name, abilityInfo.moduleName);
auto remoteObject = targetService_->GetConnRemoteObject();
auto callback = GetAbilityConnectCallback();
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
if (remoteObject == nullptr) {
TAG_LOGW(AAFwkTag::CONNECTION, "null remoteObject: %{public}s/%{public}s",
element.GetBundleName().c_str(), element.GetAbilityName().c_str());
if (handler) {
SetConnectState(ConnectionState::DISCONNECTING);
handler->SubmitTask([service = targetService_]() {
DelayedSingleton<AbilityManagerService>::GetInstance()->ScheduleDisconnectAbilityDone(
service->GetToken());
});
}
return;
}
if (callback && handler) {
handler->SubmitTask([callback, element, remoteObject, weakConnectionRecord = weak_from_this(),
weakConnectManager = abilityConnectManager_] {
TAG_LOGD(AAFwkTag::CONNECTION, "OnAbilityConnectDone");
auto ret = ConnectionRecord::CallOnAbilityConnectDone(callback, element, remoteObject, ERR_OK);
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::CONNECTION, "OnAbilityConnectDone failed");
auto connectionRecord = weakConnectionRecord.lock();
CHECK_POINTER(connectionRecord);
auto abilityConnectManager = weakConnectManager.lock();
CHECK_POINTER(abilityConnectManager);
abilityConnectManager->HandleExtensionDisconnectTask(connectionRecord);
}
});
}
DelayedSingleton<ConnectionStateManager>::GetInstance()->AddConnection(shared_from_this());
TAG_LOGI(AAFwkTag::CONNECTION, "state:%{public}d", state_);
}
void ConnectionRecord::CompleteConnectAndOnlyCallConnectDone()
{
if (GetConnectState() != ConnectionState::CONNECTED) {
auto extensionType = targetService_ == nullptr ? -1 :
static_cast<int32_t>(targetService_->GetAbilityInfo().extensionAbilityType);
TAG_LOGI(AAFwkTag::ABILITYMGR,
"Connect state is %{public}d, not connected state, extType=%{public}d, agentId=%{public}s, "
"cardType=%{public}d",
static_cast<int32_t>(GetConnectState()), extensionType,
connectWant_.GetStringParam(AgentRuntime::AGENTID_KEY).c_str(),
connectWant_.GetIntParam(AgentRuntime::AGENT_CARD_TYPE_KEY, -1));
return;
}
CHECK_POINTER(targetService_);
TAG_LOGI(AAFwkTag::ABILITYMGR, "CompleteConnect,%{public}s", targetService_->GetAbilityInfo().name.c_str());
const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
AppExecFwk::ElementName element(targetService_->GetWant().GetDeviceIdRef(), abilityInfo.bundleName,
abilityInfo.name, abilityInfo.moduleName);
auto remoteObject = targetService_->GetConnRemoteObject();
auto callback = GetAbilityConnectCallback();
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
if (remoteObject == nullptr) {
TAG_LOGW(AAFwkTag::CONNECTION, "Complete null remoteObject: %{public}s/%{public}s",
element.GetBundleName().c_str(), element.GetAbilityName().c_str());
return;
}
if (callback && handler) {
handler->SubmitTask([callback, element, remoteObject] {
TAG_LOGD(AAFwkTag::CONNECTION, "CallOnAbilityConnectDone");
auto ret = ConnectionRecord::CallOnAbilityConnectDone(callback, element, remoteObject, ERR_OK);
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::CONNECTION, "CallOnAbilityConnectDone failed");
}
});
}
TAG_LOGI(AAFwkTag::CONNECTION, "Complete connectState:%{public}d", state_);
}
void ConnectionRecord::QueueLowCodeAgentInvocation(const Want &want, const sptr<IAbilityConnection> &callback)
{
if (!IsLowCodeAgentWant(want)) {
return;
}
if (GetConnectState() == ConnectionState::CONNECTED) {
CompleteLowCodeAgentInvocation(want, callback);
return;
}
if (GetConnectState() != ConnectionState::CONNECTING) {
TAG_LOGI(AAFwkTag::SER_ROUTER, "skip low-code invocation in state %{public}d",
static_cast<int32_t>(GetConnectState()));
return;
}
std::lock_guard lock(pendingLowCodeMutex_);
pendingLowCodeInvocations_.push_back({ want, callback });
}
int32_t ConnectionRecord::CallOnAbilityConnectDone(sptr<IAbilityConnection> callback,
const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int resultCode)
{
CHECK_POINTER_AND_RETURN(callback, ERR_INVALID_VALUE);
sptr<IRemoteObject> obj = callback->AsObject();
CHECK_POINTER_AND_RETURN(obj, ERR_INVALID_VALUE);
if (!obj->IsProxyObject()) {
callback->OnAbilityConnectDone(element, remoteObject, ERR_OK);
return ERR_OK;
}
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_ASYNC);
if (!data.WriteInterfaceToken(IAbilityConnection::GetDescriptor())) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "WriteInterfaceToken fail");
return ERR_FLATTEN_OBJECT;
}
if (!data.WriteParcelable(&element)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "element error");
return ERR_FLATTEN_OBJECT;
}
if (!data.WriteRemoteObject(remoteObject)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "remoteObject error");
return ERR_FLATTEN_OBJECT;
}
if (!data.WriteInt32(resultCode)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "resultCode error");
return ERR_FLATTEN_OBJECT;
}
int32_t ret = obj->SendRequest(IAbilityConnection::ON_ABILITY_CONNECT_DONE, data, reply, option);
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "fail. ret: %{public}d", ret);
}
return ret;
}
void ConnectionRecord::CompleteDisconnect(int resultCode, bool isCallerDied, bool isTargetDied)
{
if (resultCode == ERR_OK) {
SetConnectState(ConnectionState::DISCONNECTED);
}
CHECK_POINTER(targetService_);
const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
AppExecFwk::ElementName element(targetService_->GetWant().GetDeviceIdRef(), abilityInfo.bundleName,
abilityInfo.name, abilityInfo.moduleName);
auto code = isTargetDied ? (resultCode - 1) : resultCode;
auto onDisconnectDoneTask = [connCallback = GetAbilityConnectCallback(), element, code,
recordId = GetRecordId()]() {
TAG_LOGD(AAFwkTag::CONNECTION, "OnAbilityDisconnectDone, recordId=%{public}d, callbackNull=%{public}d",
recordId, connCallback == nullptr ? 1 : 0);
if (!connCallback) {
TAG_LOGD(AAFwkTag::CONNECTION, "null connCallback");
return;
}
connCallback->OnAbilityDisconnectDone(element, code);
};
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
if (handler == nullptr) {
TAG_LOGE(AAFwkTag::CONNECTION, "null handler");
return;
}
handler->SubmitTask(onDisconnectDoneTask);
DelayedSingleton<ConnectionStateManager>::GetInstance()->RemoveConnection(shared_from_this(), isCallerDied);
TAG_LOGD(AAFwkTag::CONNECTION,
"Complete disconnect, recordId=%{public}d, result=%{public}d, state=%{public}d, extType=%{public}d, "
"callerDied=%{public}d, targetDied=%{public}d, agentId=%{public}s, cardType=%{public}d, "
"callbackNull=%{public}d",
GetRecordId(), resultCode, static_cast<int32_t>(state_), static_cast<int32_t>(abilityInfo.extensionAbilityType),
isCallerDied ? 1 : 0, isTargetDied ? 1 : 0,
connectWant_.GetStringParam(AgentRuntime::AGENTID_KEY).c_str(),
connectWant_.GetIntParam(AgentRuntime::AGENT_CARD_TYPE_KEY, -1),
GetAbilityConnectCallback() == nullptr ? 1 : 0);
}
void ConnectionRecord::ScheduleDisconnectAbilityDone()
{
int32_t extType = targetService_ == nullptr ? -1 :
static_cast<int32_t>(targetService_->GetAbilityInfo().extensionAbilityType);
TAG_LOGD(AAFwkTag::CONNECTION,
"ScheduleDisconnectAbilityDone, recordId=%{public}d, state=%{public}d, extType=%{public}d, "
"agentId=%{public}s, cardType=%{public}d, callbackNull=%{public}d",
GetRecordId(), static_cast<int32_t>(state_), extType,
connectWant_.GetStringParam(AgentRuntime::AGENTID_KEY).c_str(),
connectWant_.GetIntParam(AgentRuntime::AGENT_CARD_TYPE_KEY, -1),
GetAbilityConnectCallback() == nullptr ? 1 : 0);
if (state_ != ConnectionState::DISCONNECTING) {
TAG_LOGE(AAFwkTag::CONNECTION, "failed, current state not disconnecting");
return;
}
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
if (handler == nullptr) {
TAG_LOGE(AAFwkTag::CONNECTION, "fail to get AbilityTaskHandler");
} else {
std::string taskName = std::string("DisconnectTimeout_") + std::to_string(recordId_);
handler->CancelTask(taskName);
}
CompleteDisconnect(ERR_OK, GetAbilityConnectCallback() == nullptr);
}
void ConnectionRecord::ScheduleConnectAbilityDone()
{
if (state_ != ConnectionState::CONNECTING) {
TAG_LOGE(AAFwkTag::CONNECTION, "failed, current state not connecting");
return;
}
sptr<IRemoteObject> hostproxy = nullptr;
if (connectWant_.HasParameter(UISERVICEHOSTPROXY_KEY)) {
hostproxy = connectWant_.GetRemoteObject(UISERVICEHOSTPROXY_KEY);
}
sptr<IRemoteObject> connectorProxy = nullptr;
if (connectWant_.HasParameter(AgentRuntime::AGENTEXTENSIONHOSTPROXY_KEY)) {
connectorProxy = connectWant_.GetRemoteObject(AgentRuntime::AGENTEXTENSIONHOSTPROXY_KEY);
}
std::string agentId;
if (connectWant_.HasParameter(AgentRuntime::AGENTID_KEY)) {
agentId = connectWant_.GetStringParam(AgentRuntime::AGENTID_KEY);
}
bool hasAgentCardType = connectWant_.HasParameter(AgentRuntime::AGENT_CARD_TYPE_KEY);
int32_t agentCardType = connectWant_.GetIntParam(AgentRuntime::AGENT_CARD_TYPE_KEY, 0);
bool isLowCodeAgentConnect = IsLowCodeAgentWant(connectWant_);
bool hasAgentNonce = connectWant_.HasParameter(AgentRuntime::AGENT_VERIFICATION_NONCE_KEY);
int64_t agentNonce = AgentAbilityUtil::GetAgentVerificationNonceParam(connectWant_);
auto element = connectWant_.GetElement();
Want::ClearWant(&connectWant_);
connectWant_.SetElement(element);
if (hostproxy != nullptr) {
connectWant_.SetParam(UISERVICEHOSTPROXY_KEY, hostproxy);
}
if (connectorProxy != nullptr) {
connectWant_.SetParam(AgentRuntime::AGENTEXTENSIONHOSTPROXY_KEY, connectorProxy);
}
if (!agentId.empty()) {
connectWant_.SetParam(AgentRuntime::AGENTID_KEY, agentId);
}
if (hasAgentCardType) {
connectWant_.SetParam(AgentRuntime::AGENT_CARD_TYPE_KEY, agentCardType);
}
if (hasAgentNonce && !isLowCodeAgentConnect) {
AgentAbilityUtil::SetAgentVerificationNonceParam(connectWant_, agentNonce);
}
CancelConnectTimeoutTask();
if (targetService_ != nullptr) {
NotifyLowCodeAgentInvoked(targetService_->GetConnRemoteObject());
}
CompleteConnect();
if (GetConnectState() == ConnectionState::CONNECTED) {
FlushPendingLowCodeAgentInvocations();
}
}
bool ConnectionRecord::IsLowCodeAgentConnect() const
{
return IsLowCodeAgentWant(connectWant_);
}
bool ConnectionRecord::IsLowCodeAgentWant(const Want &want) const
{
return targetService_ != nullptr &&
targetService_->GetAbilityInfo().extensionAbilityType == AppExecFwk::ExtensionAbilityType::AGENT &&
want.GetIntParam(AgentRuntime::AGENT_CARD_TYPE_KEY, -1) ==
static_cast<int32_t>(AgentRuntime::AgentCardType::LOW_CODE);
}
void ConnectionRecord::NotifyLowCodeAgentInvoked(const sptr<IRemoteObject> &remoteObject)
{
NotifyLowCodeAgentInvoked(remoteObject, connectWant_);
}
void ConnectionRecord::NotifyLowCodeAgentInvoked(const sptr<IRemoteObject> &remoteObject, const Want &want)
{
if (!IsLowCodeAgentWant(want) || targetService_ == nullptr) {
return;
}
if (!targetService_->GetApplicationInfo().isSystemApp) {
TAG_LOGI(AAFwkTag::SER_ROUTER, "Skip low-code agent invoked for non-system target");
return;
}
std::string agentId = want.GetStringParam(AgentRuntime::AGENTID_KEY);
if (agentId.empty()) {
TAG_LOGW(AAFwkTag::SER_ROUTER, "Skip low-code agent invoked without agent id");
return;
}
auto receiver = iface_cast<AgentRuntime::IAgentReceiver>(remoteObject);
if (receiver == nullptr) {
TAG_LOGE(AAFwkTag::SER_ROUTER, "agent receiver null");
return;
}
auto ret = receiver->AgentInvoked(agentId);
if (ret == ERR_OK) {
return;
}
TAG_LOGW(AAFwkTag::SER_ROUTER, "AgentInvoked failed: %{public}d", ret);
}
void ConnectionRecord::CompleteLowCodeAgentInvocation(const Want &want, const sptr<IAbilityConnection> &callback)
{
CHECK_POINTER(targetService_);
const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
AppExecFwk::ElementName element(targetService_->GetWant().GetDeviceIdRef(), abilityInfo.bundleName,
abilityInfo.name, abilityInfo.moduleName);
auto remoteObject = targetService_->GetConnRemoteObject();
if (remoteObject == nullptr) {
TAG_LOGW(AAFwkTag::SER_ROUTER, "low-code invocation remote is null");
return;
}
NotifyLowCodeAgentInvoked(remoteObject, want);
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
if (callback == nullptr || handler == nullptr) {
return;
}
handler->SubmitTask([callback, element, remoteObject] {
auto ret = ConnectionRecord::CallOnAbilityConnectDone(callback, element, remoteObject, ERR_OK);
if (ret == ERR_OK) {
return;
}
TAG_LOGE(AAFwkTag::SER_ROUTER, "low-code connect callback failed");
});
}
void ConnectionRecord::FlushPendingLowCodeAgentInvocations()
{
std::list<LowCodeAgentInvocation> invocations;
{
std::lock_guard lock(pendingLowCodeMutex_);
invocations.swap(pendingLowCodeInvocations_);
}
for (const auto &invocation : invocations) {
CompleteLowCodeAgentInvocation(invocation.want, invocation.callback);
}
}
void ConnectionRecord::CancelConnectTimeoutTask()
{
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
CHECK_POINTER(handler);
std::string taskName = std::to_string(recordId_);
TAG_LOGI(AAFwkTag::ABILITYMGR, "CancelConnectTimeoutTask:%{public}s", taskName.c_str());
handler->RemoveEvent(AbilityManagerService::CONNECT_TIMEOUT_MSG, taskName);
handler->RemoveEvent(AbilityManagerService::CONNECT_HALF_TIMEOUT_MSG, taskName);
auto targetToken = GetTargetToken();
CHECK_POINTER(targetToken);
AbilityRuntime::FreezeUtil::GetInstance().DeleteLifecycleEvent(targetToken);
}
void ConnectionRecord::DisconnectTimeout()
{
CHECK_POINTER(targetService_);
DelayedSingleton<AbilityManagerService>::GetInstance()->ScheduleDisconnectAbilityDone(targetService_->GetToken());
}
void ConnectionRecord::ScheduleDisconnectTimeout()
{
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
if (handler == nullptr) {
TAG_LOGE(AAFwkTag::CONNECTION, "null handler");
return;
}
auto disconnectTask = [weakPtr = weak_from_this()]() {
auto connectionRecord = weakPtr.lock();
if (connectionRecord == nullptr) {
TAG_LOGE(AAFwkTag::CONNECTION, "null connectionRecord");
return;
}
TAG_LOGE(AAFwkTag::CONNECTION, "Disconnect timeout");
connectionRecord->DisconnectTimeout();
};
std::string taskName = "DisconnectTimeout_" + std::to_string(recordId_);
int disconnectTimeout =
AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * DISCONNECT_TIMEOUT_MULTIPLE;
handler->SubmitTask(disconnectTask, taskName, disconnectTimeout);
}
std::string ConnectionRecord::ConvertConnectionState(const ConnectionState &state) const
{
switch (state) {
case ConnectionState::INIT:
return "INIT";
case ConnectionState::CONNECTING:
return "CONNECTING";
case ConnectionState::CONNECTED:
return "CONNECTED";
case ConnectionState::DISCONNECTING:
return "DISCONNECTING";
case ConnectionState::DISCONNECTED:
return "DISCONNECTED";
default:
return "INVALIDSTATE";
}
}
void ConnectionRecord::Dump(std::vector<std::string> &info) const
{
auto abilityRecord = GetAbilityRecord();
CHECK_POINTER(abilityRecord);
info.emplace_back(" > " + abilityRecord->GetAbilityInfo().bundleName + "/" +
abilityRecord->GetAbilityInfo().name + " connectionState #" +
ConvertConnectionState(GetConnectState()));
}
void ConnectionRecord::AttachCallerInfo(std::shared_ptr<IndirectCallerInfo> indirectCallerInfo)
{
SetDirectCallerInfo();
if (indirectCallerInfo != nullptr) {
callerTokenId_ = indirectCallerInfo->tokenId;
callerUid_ = indirectCallerInfo->callerUid;
callerPid_ = indirectCallerInfo->callerPid;
callerName_ = ConnectionStateManager::GetProcessNameByPid(callerPid_);
TAG_LOGD(AAFwkTag::CONNECTION, "callerTokenId_:%{public}u, callerUid_:%{public}d, callerPid_:%{public}d, "
"callerName_:%{public}s", callerTokenId_, callerUid_, callerPid_, callerName_.c_str());
return;
}
callerTokenId_ = GetDirectCallerTokenId();
callerUid_ = GetDirectCallerUid();
callerPid_ = GetDirectCallerPid();
callerName_ = GetDirectCallerName();
TAG_LOGD(AAFwkTag::CONNECTION, "callerTokenId_:%{public}u, callerUid_:%{public}d, callerPid_:%{public}d, "
"callerName_:%{public}s", callerTokenId_, callerUid_, callerPid_, callerName_.c_str());
}
int32_t ConnectionRecord::GetCallerUid() const
{
return callerUid_;
}
int32_t ConnectionRecord::GetCallerPid() const
{
return callerPid_;
}
uint32_t ConnectionRecord::GetCallerTokenId() const
{
return callerTokenId_;
}
std::string ConnectionRecord::GetCallerName() const
{
return callerName_;
}
int32_t ConnectionRecord::GetDirectCallerUid() const
{
return directCallerUid_;
}
int32_t ConnectionRecord::GetDirectCallerPid() const
{
return directCallerPid_;
}
uint32_t ConnectionRecord::GetDirectCallerTokenId() const
{
return directCallerTokenId_;
}
std::string ConnectionRecord::GetDirectCallerName() const
{
return directCallerName_;
}
void ConnectionRecord::SetDirectCallerInfo()
{
directCallerTokenId_ = IPCSkeleton::GetCallingTokenID();
auto targetRecord = Token::GetAbilityRecordByToken(callerToken_);
if (targetRecord) {
directCallerUid_ = targetRecord->GetUid();
directCallerPid_ = targetRecord->GetPid();
directCallerName_ = targetRecord->GetAbilityInfo().bundleName;
return;
}
directCallerUid_ = static_cast<int32_t>(IPCSkeleton::GetCallingUid());
directCallerPid_ = static_cast<int32_t>(IPCSkeleton::GetCallingPid());
directCallerName_ = ConnectionStateManager::GetProcessNameByPid(directCallerPid_);
TAG_LOGD(AAFwkTag::CONNECTION, "directCallerTokenId_:%{public}u, directCallerUid_:%{public}d, "
"directCallerPid_:%{public}d, directCallerName_:%{public}s", directCallerTokenId_, directCallerUid_,
directCallerPid_, directCallerName_.c_str());
}
sptr<IRemoteObject> ConnectionRecord::GetTargetToken() const
{
auto targetService = targetService_;
if (!targetService) {
return nullptr;
}
auto token = targetService->GetToken();
if (!token) {
return nullptr;
}
return token->AsObject();
}
sptr<IRemoteObject> ConnectionRecord::GetConnection() const
{
auto callback = GetAbilityConnectCallback();
if (!callback) {
return nullptr;
}
return callback->AsObject();
}
void ConnectionRecord::SetConnectWant(const Want &want)
{
connectWant_ = want;
if (!IsLowCodeAgentWant(want)) {
return;
}
connectWant_.RemoveParam(AgentRuntime::AGENT_VERIFICATION_NONCE_KEY);
}
Want ConnectionRecord::GetConnectWant() const
{
return connectWant_;
}
int32_t ConnectionRecord::SuspendExtensionAbility()
{
if (state_ != ConnectionState::CONNECTED) {
TAG_LOGE(AAFwkTag::CONNECTION, "connection not established, state: %{public}d",
static_cast<int32_t>(state_));
return INVALID_CONNECTION_STATE;
}
DelayedSingleton<ConnectionStateManager>::GetInstance()->SuspendConnection(shared_from_this());
return ERR_OK;
}
int32_t ConnectionRecord::ResumeExtensionAbility()
{
if (state_ != ConnectionState::CONNECTED) {
TAG_LOGE(AAFwkTag::CONNECTION, "connection not established, state: %{public}d",
static_cast<int32_t>(state_));
return INVALID_CONNECTION_STATE;
}
DelayedSingleton<ConnectionStateManager>::GetInstance()->ResumeConnection(shared_from_this());
return ERR_OK;
}
}
}