fix connect remote ability bug

Signed-off-by: zmx <1029211721@qq.com>
Change-Id: Ia3b371699f694584b8670947b6a9550e80bcc3f4
Signed-off-by: zmx <1029211721@qq.com>
This commit is contained in:
zmx 2022-02-21 15:48:45 +08:00
parent 3dc88d06c3
commit 2f3bab8241
2 changed files with 56 additions and 38 deletions

View File

@ -49,6 +49,12 @@ struct ConnectInfo {
AppExecFwk::ElementName element; AppExecFwk::ElementName element;
}; };
struct ProcessDiedNotifyInfo {
std::string remoteDeviceId;
CallerInfo callerInfo;
TargetComponent targetComponent;
};
class DistributedSchedService : public SystemAbility, public DistributedSchedStub { class DistributedSchedService : public SystemAbility, public DistributedSchedStub {
DECLARE_SYSTEM_ABILITY(DistributedSchedService); DECLARE_SYSTEM_ABILITY(DistributedSchedService);
@ -130,7 +136,8 @@ private:
const std::string& destinationDeviceId, const std::string& sourceDeviceId); const std::string& destinationDeviceId, const std::string& sourceDeviceId);
void NotifyDeviceOfflineToAppLocked(const sptr<IRemoteObject>& connect, const ConnectAbilitySession& session); void NotifyDeviceOfflineToAppLocked(const sptr<IRemoteObject>& connect, const ConnectAbilitySession& session);
int32_t NotifyApp(const sptr<IRemoteObject>& connect, const AppExecFwk::ElementName& element, int32_t errCode); int32_t NotifyApp(const sptr<IRemoteObject>& connect, const AppExecFwk::ElementName& element, int32_t errCode);
void NotifyProcessDiedLocked(const std::string& remoteDeviceId, const CallerInfo& callerInfo, void NotifyProcessDiedAll(const std::list<ProcessDiedNotifyInfo>& notifyList);
void NotifyProcessDied(const std::string& remoteDeviceId, const CallerInfo& callerInfo,
TargetComponent targetComponent); TargetComponent targetComponent);
int32_t CheckDistributedConnectLocked(const CallerInfo& callerInfo) const; int32_t CheckDistributedConnectLocked(const CallerInfo& callerInfo) const;
void DecreaseConnectLocked(int32_t uid); void DecreaseConnectLocked(int32_t uid);

View File

@ -526,26 +526,25 @@ int32_t DistributedSchedService::ConnectRemoteAbility(const OHOS::AAFwk::Want& w
HILOGE("ConnectRemoteAbility check uid failed"); HILOGE("ConnectRemoteAbility check uid failed");
return INVALID_PARAMETERS_ERR; return INVALID_PARAMETERS_ERR;
} }
CallerInfo callerInfo; CallerInfo callerInfo = { callerUid, callerPid, CALLER_TYPE_HARMONY, localDeviceId };
callerInfo.accessToken = accessToken;
{ {
std::lock_guard<std::mutex> autoLock(distributedLock_); std::lock_guard<std::mutex> autoLock(distributedLock_);
callerInfo = { callerUid, callerPid, CALLER_TYPE_HARMONY, localDeviceId };
callerInfo.accessToken = accessToken;
int32_t checkResult = CheckDistributedConnectLocked(callerInfo); int32_t checkResult = CheckDistributedConnectLocked(callerInfo);
if (checkResult != ERR_OK) { if (checkResult != ERR_OK) {
return checkResult; return checkResult;
} }
}
if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) { if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
HILOGE("ConnectRemoteAbility GetCallerAppIdFromBms failed"); HILOGE("ConnectRemoteAbility GetCallerAppIdFromBms failed");
return INVALID_PARAMETERS_ERR; return INVALID_PARAMETERS_ERR;
} }
int32_t ret = DistributedSchedAdapter::GetInstance().GetBundleNameListFromBms( int32_t ret = DistributedSchedAdapter::GetInstance().GetBundleNameListFromBms(
callerInfo.uid, callerInfo.bundleNames); callerInfo.uid, callerInfo.bundleNames);
if (ret != ERR_OK) { if (ret != ERR_OK) {
HILOGE("ConnectRemoteAbility GetBundleNameListFromBms failed"); HILOGE("ConnectRemoteAbility GetBundleNameListFromBms failed");
return INVALID_PARAMETERS_ERR; return INVALID_PARAMETERS_ERR;
}
} }
HILOGD("[PerformanceTest] ConnectRemoteAbility begin"); HILOGD("[PerformanceTest] ConnectRemoteAbility begin");
@ -889,19 +888,25 @@ int32_t DistributedSchedService::ConnectAbilityFromRemote(const OHOS::AAFwk::Wan
HILOGD("ConnectAbilityFromRemote callerType is %{public}d", callerInfo.callerType); HILOGD("ConnectAbilityFromRemote callerType is %{public}d", callerInfo.callerType);
sptr<IRemoteObject> callbackWrapper = connect; sptr<IRemoteObject> callbackWrapper = connect;
std::map<sptr<IRemoteObject>, ConnectInfo>::iterator itConnect;
if (callerInfo.callerType == CALLER_TYPE_HARMONY) { if (callerInfo.callerType == CALLER_TYPE_HARMONY) {
std::lock_guard<std::mutex> autoLock(connectLock_); std::lock_guard<std::mutex> autoLock(connectLock_);
auto itConnect = connectAbilityMap_.find(connect); itConnect = connectAbilityMap_.find(connect);
if (itConnect != connectAbilityMap_.end()) { if (itConnect != connectAbilityMap_.end()) {
callbackWrapper = itConnect->second.callbackWrapper; callbackWrapper = itConnect->second.callbackWrapper;
} else { } else {
callbackWrapper = new AbilityConnectionWrapperStub(connect); callbackWrapper = new AbilityConnectionWrapperStub(connect);
ConnectInfo connectInfo {callerInfo, callbackWrapper};
connectAbilityMap_.emplace(connect, connectInfo);
} }
} }
int32_t errCode = DistributedSchedAdapter::GetInstance().ConnectAbility(want, callbackWrapper, this); int32_t errCode = DistributedSchedAdapter::GetInstance().ConnectAbility(want, callbackWrapper, this);
HILOGD("[PerformanceTest] ConnectAbilityFromRemote end"); HILOGD("[PerformanceTest] ConnectAbilityFromRemote end");
if (errCode == ERR_OK) {
std::lock_guard<std::mutex> autoLock(connectLock_);
if (itConnect == connectAbilityMap_.end()) {
ConnectInfo connectInfo {callerInfo, callbackWrapper};
connectAbilityMap_.emplace(connect, connectInfo);
}
}
return errCode; return errCode;
} }
@ -1103,8 +1108,7 @@ void DistributedSchedService::ProcessConnectDied(const sptr<IRemoteObject>& conn
return; return;
} }
std::list<ConnectAbilitySession> sessionsList; std::list<ProcessDiedNotifyInfo> notifyList;
CallerInfo callerInfo;
{ {
std::lock_guard<std::mutex> autoLock(distributedLock_); std::lock_guard<std::mutex> autoLock(distributedLock_);
auto it = distributedConnectAbilityMap_.find(connect); auto it = distributedConnectAbilityMap_.find(connect);
@ -1115,11 +1119,24 @@ void DistributedSchedService::ProcessConnectDied(const sptr<IRemoteObject>& conn
if (connectSessionsList.empty()) { if (connectSessionsList.empty()) {
return; return;
} }
callerInfo = connectSessionsList.front().GetCallerInfo(); CallerInfo callerInfo = connectSessionsList.front().GetCallerInfo();
std::set<std::string> processedDeviceSet;
// to reduce the number of communications between devices, clean all the died process's connections // to reduce the number of communications between devices, clean all the died process's connections
for (auto iter = distributedConnectAbilityMap_.begin(); iter != distributedConnectAbilityMap_.end();) { for (auto iter = distributedConnectAbilityMap_.begin(); iter != distributedConnectAbilityMap_.end();) {
sessionsList = iter->second; std::list<ConnectAbilitySession>& sessionsList = iter->second;
if (!sessionsList.empty() && sessionsList.front().IsSameCaller(callerInfo)) { if (!sessionsList.empty() && sessionsList.front().IsSameCaller(callerInfo)) {
for (const auto& session : sessionsList) {
std::string remoteDeviceId = session.GetDestinationDeviceId();
TargetComponent targetComponent = session.GetTargetComponent();
// the same session can connect different types component on the same device
std::string key = remoteDeviceId + std::to_string(static_cast<int32_t>(targetComponent));
// just notify one time for same remote device
auto [_, isSuccess] = processedDeviceSet.emplace(key);
if (isSuccess) {
ProcessDiedNotifyInfo notifyInfo = { remoteDeviceId, callerInfo, targetComponent };
notifyList.push_back(notifyInfo);
}
}
DecreaseConnectLocked(callerInfo.uid); DecreaseConnectLocked(callerInfo.uid);
if (iter->first != nullptr) { if (iter->first != nullptr) {
iter->first->RemoveDeathRecipient(connectDeathRecipient_); iter->first->RemoveDeathRecipient(connectDeathRecipient_);
@ -1130,37 +1147,31 @@ void DistributedSchedService::ProcessConnectDied(const sptr<IRemoteObject>& conn
} }
} }
} }
std::set<std::string> processedDeviceSet; NotifyProcessDiedAll(notifyList);
if (!sessionsList.empty() && sessionsList.front().IsSameCaller(callerInfo)) { }
for (const auto& session : sessionsList) {
std::string remoteDeviceId = session.GetDestinationDeviceId(); void DistributedSchedService::NotifyProcessDiedAll(const std::list<ProcessDiedNotifyInfo>& notifyList)
TargetComponent targetComponent = session.GetTargetComponent(); {
// the same session can connect different types component on the same device for (auto it = notifyList.begin(); it != notifyList.end(); ++it) {
std::string key = remoteDeviceId + std::to_string(static_cast<int32_t>(targetComponent)); NotifyProcessDied(it->remoteDeviceId, it->callerInfo, it->targetComponent);
// just notify one time for same remote device
auto [_, isSuccess] = processedDeviceSet.emplace(key);
if (isSuccess) {
NotifyProcessDiedLocked(remoteDeviceId, callerInfo, targetComponent);
}
}
} }
} }
void DistributedSchedService::NotifyProcessDiedLocked(const std::string& remoteDeviceId, void DistributedSchedService::NotifyProcessDied(const std::string& remoteDeviceId,
const CallerInfo& callerInfo, TargetComponent targetComponent) const CallerInfo& callerInfo, TargetComponent targetComponent)
{ {
if (targetComponent != TargetComponent::HARMONY_COMPONENT) { if (targetComponent != TargetComponent::HARMONY_COMPONENT) {
HILOGD("NotifyProcessDiedLocked not harmony component, no need to notify"); HILOGD("NotifyProcessDied not harmony component, no need to notify");
return; return;
} }
sptr<IDistributedSched> remoteDms = GetRemoteDms(remoteDeviceId); sptr<IDistributedSched> remoteDms = GetRemoteDms(remoteDeviceId);
if (remoteDms == nullptr) { if (remoteDms == nullptr) {
HILOGE("NotifyProcessDiedLocked get remote dms failed"); HILOGE("NotifyProcessDied get remote dms failed");
return; return;
} }
int32_t result = remoteDms->NotifyProcessDiedFromRemote(callerInfo); int32_t result = remoteDms->NotifyProcessDiedFromRemote(callerInfo);
HILOGI("NotifyProcessDiedLocked result is %{public}d", result); HILOGI("NotifyProcessDied result is %{public}d", result);
} }
ConnectAbilitySession::ConnectAbilitySession(const std::string& sourceDeviceId, const std::string& destinationDeviceId, ConnectAbilitySession::ConnectAbilitySession(const std::string& sourceDeviceId, const std::string& destinationDeviceId,