diff --git a/frameworks/native/ability/ability_runtime/ability_connection.cpp b/frameworks/native/ability/ability_runtime/ability_connection.cpp index 6293571bb2..c56d9951f6 100644 --- a/frameworks/native/ability/ability_runtime/ability_connection.cpp +++ b/frameworks/native/ability/ability_runtime/ability_connection.cpp @@ -26,22 +26,29 @@ namespace { constexpr int32_t DIED = -1; } // namespace -AbilityConnection::AbilityConnection(const sptr &abilityConnectCallback) -{ - abilityConnectCallback_ = abilityConnectCallback; -} - void AbilityConnection::OnAbilityConnectDone( const AppExecFwk::ElementName &element, const sptr &remoteObject, int resultCode) { HILOG_DEBUG("%{public}s begin.", __func__); - if (abilityConnectCallback_ == nullptr) { - HILOG_ERROR("%{public}s abilityConnectCallback is nullptr.", __func__); + mutex_.lock(); + if (abilityConnectCallbackList_.empty()) { + HILOG_ERROR("%{public}s abilityConnectCallbackList is empty.", __func__); + mutex_.unlock(); return; } + SetRemoteObject(remoteObject); SetResultCode(resultCode); - abilityConnectCallback_->OnAbilityConnectDone(element, remoteObject, resultCode); + SetConnectionState(CONNECTION_STATE_CONNECTED); + + std::vector> callbacks = GetCallbackList(); + mutex_.unlock(); + + auto item = callbacks.begin(); + while (item != callbacks.end()) { + (*item)->OnAbilityConnectDone(element, remoteObject, resultCode); + item++; + } HILOG_DEBUG("%{public}s end, bundleName:%{public}s, abilityName:%{public}s.", __func__, element.GetBundleName().c_str(), element.GetAbilityName().c_str()); } @@ -49,8 +56,11 @@ void AbilityConnection::OnAbilityConnectDone( void AbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) { HILOG_DEBUG("%{public}s begin, resultCode:%{public}d.", __func__, resultCode); - if (abilityConnectCallback_ == nullptr) { - HILOG_ERROR("%{public}s abilityConnectCallback is nullptr.", __func__); + mutex_.lock(); + SetConnectionState(CONNECTION_STATE_DISCONNECTED); + if (abilityConnectCallbackList_.empty()) { + HILOG_ERROR("%{public}s abilityConnectCallback is empty.", __func__); + mutex_.unlock(); return; } // if resultCode < 0 that means the connectReceiver is died @@ -60,17 +70,46 @@ void AbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &e ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid()); HILOG_INFO("The service connection is not disconnected."); } - abilityConnectCallback_->OnAbilityDisconnectDone(element, DIED + 1); - } else { - abilityConnectCallback_->OnAbilityDisconnectDone(element, resultCode); + resultCode = DIED + 1; + } + + std::vector> callbacks = GetCallbackList(); + mutex_.unlock(); + + auto item = callbacks.begin(); + while (item != callbacks.end()) { + (*item)->OnAbilityDisconnectDone(element, resultCode); + item++; } HILOG_DEBUG("%{public}s end, bundleName:%{public}s, abilityName:%{public}s.", __func__, element.GetBundleName().c_str(), element.GetAbilityName().c_str()); } -void AbilityConnection::SetConnectCallback(const sptr &abilityConnectCallback) +void AbilityConnection::AddConnectCallback(const sptr &abilityConnectCallback) { - abilityConnectCallback_ = abilityConnectCallback; + std::lock_guard lock(mutex_); + auto item = abilityConnectCallbackList_.begin(); + while (item != abilityConnectCallbackList_.end()) { + if (*item == abilityConnectCallback) { + return; + } + item++; + } + abilityConnectCallbackList_.push_back(abilityConnectCallback); +} + +void AbilityConnection::RemoveConnectCallback(const sptr &abilityConnectCallback) +{ + std::lock_guard lock(mutex_); + auto item = abilityConnectCallbackList_.begin(); + while (item != abilityConnectCallbackList_.end()) { + if (*item == abilityConnectCallback) { + abilityConnectCallbackList_.erase(item); + break; + } else { + item++; + } + } } void AbilityConnection::SetRemoteObject(const sptr &remoteObject) @@ -83,6 +122,11 @@ void AbilityConnection::SetResultCode(int resultCode) resultCode_ = resultCode; } +void AbilityConnection::SetConnectionState(int connectionState) +{ + connectionState_ = connectionState; +} + sptr AbilityConnection::GetRemoteObject() const { return remoteObject_; @@ -92,5 +136,15 @@ int AbilityConnection::GetResultCode() const { return resultCode_; } + +int AbilityConnection::GetConnectionState() const +{ + return connectionState_; +} + +std::vector> AbilityConnection::GetCallbackList() +{ + return abilityConnectCallbackList_; +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/ability/ability_runtime/connection_manager.cpp b/frameworks/native/ability/ability_runtime/connection_manager.cpp index 667717bc4e..0c9e9394b8 100644 --- a/frameworks/native/ability/ability_runtime/connection_manager.cpp +++ b/frameworks/native/ability/ability_runtime/connection_manager.cpp @@ -67,18 +67,26 @@ ErrCode ConnectionManager::ConnectAbilityInner(const sptr &connec callbacks.push_back(connectCallback); abilityConnections_[item->first] = callbacks; abilityConnection = item->first.abilityConnection; - abilityConnection->SetConnectCallback(connectCallback); - HILOG_INFO("%{public}s end, find abilityConnection exist, callbackSize:%{public}d.", - __func__, (int32_t)callbacks.size()); - if (abilityConnection->GetResultCode() == ERR_OK) { + abilityConnection->AddConnectCallback(connectCallback); + HILOG_INFO("%{public}s end, find abilityConnection exist, callbackSize:%{public}zu.", + __func__, callbacks.size()); + if (abilityConnection->GetConnectionState() == CONNECTION_STATE_CONNECTED) { connectCallback->OnAbilityConnectDone(connectReceiver, abilityConnection->GetRemoteObject(), abilityConnection->GetResultCode()); return ERR_OK; + } else if (abilityConnection->GetConnectionState() == CONNECTION_STATE_CONNECTING) { + return ERR_OK; } else { - return HandleCallbackTimeOut(connectCaller, want, connectReceiver, abilityConnection, connectCallback); + HILOG_ERROR("%{public}s, AbilityConnection has disconnected", __func__); + abilityConnections_.erase(item); + HILOG_DEBUG("%{public}s end, not find connection, abilityConnectionsSize:%{public}zu.", + __func__, abilityConnections_.size()); + return ERR_INVALID_VALUE; } } else { - abilityConnection = new AbilityConnection(connectCallback); + abilityConnection = new AbilityConnection(); + abilityConnection->AddConnectCallback(connectCallback); + abilityConnection->SetConnectionState(CONNECTION_STATE_CONNECTING); ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility( want, abilityConnection, connectCaller, accountId); if (ret == ERR_OK) { @@ -86,9 +94,11 @@ ErrCode ConnectionManager::ConnectAbilityInner(const sptr &connec std::vector> callbacks; callbacks.push_back(connectCallback); abilityConnections_[connectionInfo] = callbacks; + } else { + HILOG_ERROR("%{public}s, Call AbilityManagerService's ConnectAbility error:%{public}d", __func__, ret); } - HILOG_DEBUG("%{public}s end, not find connection, abilityConnectionsSize:%{public}d.", - __func__, (int32_t)abilityConnections_.size()); + HILOG_DEBUG("%{public}s end, not find connection, abilityConnectionsSize:%{public}zu.", + __func__, abilityConnections_.size()); return ret; } } @@ -123,18 +133,16 @@ ErrCode ConnectionManager::DisconnectAbility(const sptr &connectC } sptr abilityConnection = item->first.abilityConnection; - if (abilityConnection) { - abilityConnection->SetConnectCallback(connectCallback); - } - HILOG_INFO("%{public}s end, find abilityConnection exist, abilityConnectionsSize:%{public}d.", - __func__, (int32_t)abilityConnections_.size()); + HILOG_INFO("%{public}s end, find abilityConnection exist, abilityConnectionsSize:%{public}zu.", + __func__, abilityConnections_.size()); if (item->second.empty()) { abilityConnections_.erase(item); HILOG_DEBUG("%{public}s no callback left, so disconnectAbility.", __func__); return AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(abilityConnection); } else { connectCallback->OnAbilityDisconnectDone(connectReceiver, ERR_OK); + abilityConnection->RemoveConnectCallback(connectCallback); HILOG_DEBUG("%{public}s callbacks is not empty, do not need disconnectAbility.", __func__); return ERR_OK; } @@ -152,8 +160,8 @@ bool ConnectionManager::DisconnectCaller(const sptr &connectCalle return false; } - HILOG_DEBUG("%{public}s, abilityConnectionsSize:%{public}d.", - __func__, (int32_t)abilityConnections_.size()); + HILOG_DEBUG("%{public}s, abilityConnectionsSize:%{public}zu.", + __func__, abilityConnections_.size()); bool isDisconnect = false; auto iter = abilityConnections_.begin(); @@ -173,14 +181,14 @@ bool ConnectionManager::DisconnectCaller(const sptr &connectCalle } } - HILOG_DEBUG("%{public}s end, abilityConnectionsSize:%{public}d.", __func__, (int32_t)abilityConnections_.size()); + HILOG_DEBUG("%{public}s end, abilityConnectionsSize:%{public}zu.", __func__, abilityConnections_.size()); return isDisconnect; } bool ConnectionManager::DisconnectReceiver(const AppExecFwk::ElementName &connectReceiver) { - HILOG_DEBUG("%{public}s begin, abilityConnectionsSize:%{public}d, bundleName:%{public}s, abilityName:%{public}s.", - __func__, (int32_t)abilityConnections_.size(), connectReceiver.GetBundleName().c_str(), + HILOG_DEBUG("%{public}s begin, abilityConnectionsSize:%{public}zu, bundleName:%{public}s, abilityName:%{public}s.", + __func__, abilityConnections_.size(), connectReceiver.GetBundleName().c_str(), connectReceiver.GetAbilityName().c_str()); bool isDisconnect = false; @@ -195,7 +203,7 @@ bool ConnectionManager::DisconnectReceiver(const AppExecFwk::ElementName &connec } } - HILOG_DEBUG("%{public}s end, abilityConnectionsSize:%{public}d.", __func__, (int32_t)abilityConnections_.size()); + HILOG_DEBUG("%{public}s end, abilityConnectionsSize:%{public}zu.", __func__, abilityConnections_.size()); return isDisconnect; } @@ -231,22 +239,5 @@ bool ConnectionManager::IsConnectReceiverEqual(const AppExecFwk::ElementName &co return connectReceiver.GetBundleName() == connectReceiverOther.GetBundleName() && connectReceiver.GetAbilityName() == connectReceiverOther.GetAbilityName(); } - -ErrCode ConnectionManager::HandleCallbackTimeOut(const sptr &connectCaller, const AAFwk::Want &want, - const AppExecFwk::ElementName &connectReceiver, sptr abilityConnection, - const sptr &connectCallback) -{ - if (abilityConnection->GetRemoteObject() == nullptr) { - while (true) { - if (abilityConnection->GetRemoteObject() != nullptr) { - connectCallback->OnAbilityConnectDone(connectReceiver, abilityConnection->GetRemoteObject(), - abilityConnection->GetResultCode()); - return ERR_OK; - } - } - } else { - return AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, abilityConnection, connectCaller); - } -} } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/kits/native/ability/ability_runtime/ability_connection.h b/interfaces/kits/native/ability/ability_runtime/ability_connection.h index c5b11882a0..020794736e 100644 --- a/interfaces/kits/native/ability/ability_runtime/ability_connection.h +++ b/interfaces/kits/native/ability/ability_runtime/ability_connection.h @@ -16,6 +16,7 @@ #ifndef OHOS_ABILITY_RUNTIME_ABILITY_CONNECTION_H #define OHOS_ABILITY_RUNTIME_ABILITY_CONNECTION_H +#include #include "ability_connect_callback.h" #include "ability_connect_callback_stub.h" #include "want.h" @@ -25,6 +26,13 @@ namespace OHOS { namespace AbilityRuntime { +enum { + CONNECTION_STATE_DISCONNECTED = -1, + + CONNECTION_STATE_CONNECTED = 0, + + CONNECTION_STATE_CONNECTING = 1 +}; class AbilityConnection : public AAFwk::AbilityConnectionStub { public: /** @@ -33,12 +41,6 @@ public: */ AbilityConnection() = default; - /** - * @brief Constructor. - * @param abilityConnectCallback is used to notify caller ability that connect or disconnect is complete - */ - explicit AbilityConnection(const sptr &abilityConnectCallback); - /** * @brief Destructor. * @@ -64,23 +66,33 @@ public: void OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) override; /** - * set abilityConnectCallback + * add abilityConnectCallback * * @param abilityConnectCallback is used to notify caller ability that connect or disconnect is complete */ - void SetConnectCallback(const sptr &abilityConnectCallback); + void AddConnectCallback(const sptr &abilityConnectCallback); + + void RemoveConnectCallback(const sptr &abilityConnectCallback); void SetRemoteObject(const sptr &remoteObject); void SetResultCode(int resultCode); + void SetConnectionState(int connectionState); + sptr GetRemoteObject() const; int GetResultCode() const; + + int GetConnectionState() const; + + std::vector> GetCallbackList(); private: - sptr abilityConnectCallback_ = nullptr; + std::vector> abilityConnectCallbackList_; sptr remoteObject_ = nullptr; int resultCode_ = -1; + int connectionState_ = CONNECTION_STATE_DISCONNECTED; + std::mutex mutex_; }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/kits/native/ability/ability_runtime/connection_manager.h b/interfaces/kits/native/ability/ability_runtime/connection_manager.h index 9a572ecb2a..ba8393c887 100644 --- a/interfaces/kits/native/ability/ability_runtime/connection_manager.h +++ b/interfaces/kits/native/ability/ability_runtime/connection_manager.h @@ -140,9 +140,6 @@ private: bool IsConnectCallerEqual(const sptr &connectCaller, const sptr &connectCallerOther); bool IsConnectReceiverEqual(const AppExecFwk::ElementName &connectReceiver, const AppExecFwk::ElementName &connectReceiverOther); - ErrCode HandleCallbackTimeOut(const sptr &connectCaller, const AAFwk::Want &want, - const AppExecFwk::ElementName &connectReceiver, sptr abilityConnection, - const sptr &connectCallback); std::map>> abilityConnections_; ErrCode ConnectAbilityInner(const sptr &connectCaller, const AAFwk::Want &want, int accountId, const sptr &connectCallback); diff --git a/services/abilitymgr/src/ability_connect_manager.cpp b/services/abilitymgr/src/ability_connect_manager.cpp index 23a6248285..e0761b06d3 100644 --- a/services/abilitymgr/src/ability_connect_manager.cpp +++ b/services/abilitymgr/src/ability_connect_manager.cpp @@ -261,7 +261,7 @@ int AbilityConnectManager::ConnectAbilityLocked(const AbilityRequest &abilityReq bool isCallbackConnected = !connectRecordList.empty(); // 3. If this service ability and callback has been connected, There is no need to connect repeatedly if (isLoadedAbility && (isCallbackConnected) && IsAbilityConnected(targetService, connectRecordList)) { - HILOG_ERROR("Service and callback was connected."); + HILOG_INFO("Service and callback was connected."); return ERR_OK; } @@ -280,6 +280,7 @@ int AbilityConnectManager::ConnectAbilityLocked(const AbilityRequest &abilityReq connectMap_.emplace(connect->AsObject(), connectRecordList); // 5. load or connect ability + int ret = ERR_OK; if (!isLoadedAbility) { LoadAbility(targetService); } else if (targetService->IsAbilityState(AbilityState::ACTIVE)) { @@ -293,13 +294,16 @@ int AbilityConnectManager::ConnectAbilityLocked(const AbilityRequest &abilityReq ConnectAbility(targetService); } } else { - HILOG_ERROR("Target service is already activating."); + HILOG_ERROR("Target service ability is activating, connect failed"); + targetService->RemoveConnectRecordFromList(connectRecord); + RemoveConnectionRecordFromMap(connectRecord); + ret = START_SERVICE_ABILITY_ACTIVATING; } auto token = targetService->GetToken(); auto preToken = iface_cast(connectRecord->GetToken()); DelayedSingleton::GetInstance()->AbilityBehaviorAnalysis(token, preToken, 0, 1, 1); - return ERR_OK; + return ret; } int AbilityConnectManager::DisconnectAbilityLocked(const sptr &connect) @@ -710,7 +714,7 @@ void AbilityConnectManager::HandleStartTimeoutTask(const std::shared_ptrCompleteConnect(resultCode); + connectRecord->CompleteDisconnect(ERR_OK, true); abilityRecord->RemoveConnectRecordFromList(connectRecord); RemoveConnectionRecordFromMap(connectRecord); } @@ -1113,6 +1117,14 @@ void AbilityConnectManager::HandleAbilityDiedTask( return; } + ConnectListType connlist = abilityRecord->GetConnectRecordList(); + for (auto &connectRecord : connlist) { + HILOG_WARN("This record complete disconnect directly. recordId:%{public}d", connectRecord->GetRecordId()); + connectRecord->CompleteDisconnect(ERR_OK, true); + abilityRecord->RemoveConnectRecordFromList(connectRecord); + RemoveConnectionRecordFromMap(connectRecord); + } + if (IsAbilityNeedRestart(abilityRecord)) { HILOG_INFO("restart ability: %{public}s", abilityRecord->GetAbilityInfo().name.c_str()); AbilityRequest requestInfo; @@ -1137,14 +1149,6 @@ void AbilityConnectManager::HandleAbilityDiedTask( return; } - ConnectListType connlist = abilityRecord->GetConnectRecordList(); - for (auto &connectRecord : connlist) { - HILOG_WARN("This record complete disconnect directly. recordId:%{public}d", connectRecord->GetRecordId()); - connectRecord->CompleteDisconnect(ERR_OK, true); - abilityRecord->RemoveConnectRecordFromList(connectRecord); - RemoveConnectionRecordFromMap(connectRecord); - } - RemoveServiceAbility(abilityRecord); }