excute disconnect before ability restart

Signed-off-by: donglin <donglin9@huawei.com>
Change-Id: I09b27df53654a1eb98426e6ab541859437f37727
This commit is contained in:
donglin
2022-09-01 17:19:57 +08:00
parent 8306184592
commit 9cfbfca648
5 changed files with 133 additions and 75 deletions
@@ -26,22 +26,29 @@ namespace {
constexpr int32_t DIED = -1;
} // namespace
AbilityConnection::AbilityConnection(const sptr<AbilityConnectCallback> &abilityConnectCallback)
{
abilityConnectCallback_ = abilityConnectCallback;
}
void AbilityConnection::OnAbilityConnectDone(
const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &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<sptr<AbilityConnectCallback>> 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<sptr<AbilityConnectCallback>> 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> &abilityConnectCallback)
void AbilityConnection::AddConnectCallback(const sptr<AbilityConnectCallback> &abilityConnectCallback)
{
abilityConnectCallback_ = abilityConnectCallback;
std::lock_guard<std::mutex> 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> &abilityConnectCallback)
{
std::lock_guard<std::mutex> lock(mutex_);
auto item = abilityConnectCallbackList_.begin();
while (item != abilityConnectCallbackList_.end()) {
if (*item == abilityConnectCallback) {
abilityConnectCallbackList_.erase(item);
break;
} else {
item++;
}
}
}
void AbilityConnection::SetRemoteObject(const sptr<IRemoteObject> &remoteObject)
@@ -83,6 +122,11 @@ void AbilityConnection::SetResultCode(int resultCode)
resultCode_ = resultCode;
}
void AbilityConnection::SetConnectionState(int connectionState)
{
connectionState_ = connectionState;
}
sptr<IRemoteObject> AbilityConnection::GetRemoteObject() const
{
return remoteObject_;
@@ -92,5 +136,15 @@ int AbilityConnection::GetResultCode() const
{
return resultCode_;
}
int AbilityConnection::GetConnectionState() const
{
return connectionState_;
}
std::vector<sptr<AbilityConnectCallback>> AbilityConnection::GetCallbackList()
{
return abilityConnectCallbackList_;
}
} // namespace AbilityRuntime
} // namespace OHOS
@@ -67,18 +67,26 @@ ErrCode ConnectionManager::ConnectAbilityInner(const sptr<IRemoteObject> &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<IRemoteObject> &connec
std::vector<sptr<AbilityConnectCallback>> 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<IRemoteObject> &connectC
}
sptr<AbilityConnection> 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<IRemoteObject> &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<IRemoteObject> &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<IRemoteObject> &connectCaller, const AAFwk::Want &want,
const AppExecFwk::ElementName &connectReceiver, sptr<AbilityConnection> abilityConnection,
const sptr<AbilityConnectCallback> &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
@@ -16,6 +16,7 @@
#ifndef OHOS_ABILITY_RUNTIME_ABILITY_CONNECTION_H
#define OHOS_ABILITY_RUNTIME_ABILITY_CONNECTION_H
#include <mutex>
#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> &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> &abilityConnectCallback);
void AddConnectCallback(const sptr<AbilityConnectCallback> &abilityConnectCallback);
void RemoveConnectCallback(const sptr<AbilityConnectCallback> &abilityConnectCallback);
void SetRemoteObject(const sptr<IRemoteObject> &remoteObject);
void SetResultCode(int resultCode);
void SetConnectionState(int connectionState);
sptr<IRemoteObject> GetRemoteObject() const;
int GetResultCode() const;
int GetConnectionState() const;
std::vector<sptr<AbilityConnectCallback>> GetCallbackList();
private:
sptr<AbilityConnectCallback> abilityConnectCallback_ = nullptr;
std::vector<sptr<AbilityConnectCallback>> abilityConnectCallbackList_;
sptr<IRemoteObject> remoteObject_ = nullptr;
int resultCode_ = -1;
int connectionState_ = CONNECTION_STATE_DISCONNECTED;
std::mutex mutex_;
};
} // namespace AbilityRuntime
} // namespace OHOS
@@ -140,9 +140,6 @@ private:
bool IsConnectCallerEqual(const sptr<IRemoteObject> &connectCaller, const sptr<IRemoteObject> &connectCallerOther);
bool IsConnectReceiverEqual(const AppExecFwk::ElementName &connectReceiver,
const AppExecFwk::ElementName &connectReceiverOther);
ErrCode HandleCallbackTimeOut(const sptr<IRemoteObject> &connectCaller, const AAFwk::Want &want,
const AppExecFwk::ElementName &connectReceiver, sptr<AbilityConnection> abilityConnection,
const sptr<AbilityConnectCallback> &connectCallback);
std::map<ConnectionInfo, std::vector<sptr<AbilityConnectCallback>>> abilityConnections_;
ErrCode ConnectAbilityInner(const sptr<IRemoteObject> &connectCaller,
const AAFwk::Want &want, int accountId, const sptr<AbilityConnectCallback> &connectCallback);
@@ -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<Token>(connectRecord->GetToken());
DelayedSingleton<AppScheduler>::GetInstance()->AbilityBehaviorAnalysis(token, preToken, 0, 1, 1);
return ERR_OK;
return ret;
}
int AbilityConnectManager::DisconnectAbilityLocked(const sptr<IAbilityConnection> &connect)
@@ -710,7 +714,7 @@ void AbilityConnectManager::HandleStartTimeoutTask(const std::shared_ptr<Ability
HILOG_WARN("ConnectRecord is nullptr.");
continue;
}
connectRecord->CompleteConnect(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);
}