mirror of
https://github.com/openharmony/ability_ability_runtime.git
synced 2026-08-24 22:21:36 -04:00
excute disconnect before ability restart
Signed-off-by: donglin <donglin9@huawei.com> Change-Id: I09b27df53654a1eb98426e6ab541859437f37727
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user