From a676ad395ac8cf30d8b060b586e23ed958628984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois-Simon=20Fauteux-Chapleau?= <francois-simon.fauteux-chapleau@savoirfairelinux.com> Date: Fri, 2 Feb 2024 15:27:45 -0500 Subject: [PATCH] callmodel: don't turn video on when accepting a call in audio The function which is responsible for muting the camera when accepting a call in audio assumes that the call's mediaList has already been initialized, but this wasn't actually the case. This caused a bug where the 'Accept in audio' button behaved exactly like the 'Accept in video' button. GitLab: #1621 Change-Id: I26251f51862cf5cd9b6d4daaf15270943c0e3c4e --- src/app/calladapter.cpp | 9 +-- src/app/calladapter.h | 2 +- .../mainview/components/InitialCallPage.qml | 8 +-- src/libclient/api/callmodel.h | 6 +- src/libclient/callmodel.cpp | 64 +++++++++++-------- 5 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/app/calladapter.cpp b/src/app/calladapter.cpp index 6ac9b3d55..169ba6cf7 100644 --- a/src/app/calladapter.cpp +++ b/src/app/calladapter.cpp @@ -389,16 +389,13 @@ CallAdapter::hangUpACall(const QString& accountId, const QString& convUid) } void -CallAdapter::setCallMedia(const QString& accountId, const QString& convUid, bool video) +CallAdapter::setCallMedia(const QString& accountId, const QString& convUid, bool videoMuted) { const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId); if (convInfo.uid.isEmpty()) return; - try { - lrcInstance_->getAccountInfo(accountId).callModel->updateCallMediaList(convInfo.callId, - video); - } catch (...) { - } + + lrcInstance_->getAccountInfo(accountId).callModel->setVideoMuted(convInfo.callId, videoMuted); } void diff --git a/src/app/calladapter.h b/src/app/calladapter.h index cefeee014..a3ebf6153 100644 --- a/src/app/calladapter.h +++ b/src/app/calladapter.h @@ -67,7 +67,7 @@ public: Q_INVOKABLE void placeAudioOnlyCall(); Q_INVOKABLE void placeCall(); Q_INVOKABLE void hangUpACall(const QString& accountId, const QString& convUid); - Q_INVOKABLE void setCallMedia(const QString& accountId, const QString& convUid, bool video); + Q_INVOKABLE void setCallMedia(const QString& accountId, const QString& convUid, bool videoMuted); Q_INVOKABLE void acceptACall(const QString& accountId, const QString& convUid); Q_INVOKABLE void connectCallModel(const QString& accountId); diff --git a/src/app/mainview/components/InitialCallPage.qml b/src/app/mainview/components/InitialCallPage.qml index 4c9448e99..869833366 100644 --- a/src/app/mainview/components/InitialCallPage.qml +++ b/src/app/mainview/components/InitialCallPage.qml @@ -213,12 +213,8 @@ Rectangle { onClicked: { if (type === "cam" || type === "mic") { - var acceptVideoMedia = true; - if (type === "cam") - acceptVideoMedia = true; - else if (type === "mic") - acceptVideoMedia = false; - CallAdapter.setCallMedia(CurrentAccount.id, CurrentConversation.id, acceptVideoMedia); + var muteVideo = (type === "mic"); + CallAdapter.setCallMedia(CurrentAccount.id, CurrentConversation.id, muteVideo); callAccepted(); } else { callCanceled(); diff --git a/src/libclient/api/callmodel.h b/src/libclient/api/callmodel.h index e0812ca61..e9a077895 100644 --- a/src/libclient/api/callmodel.h +++ b/src/libclient/api/callmodel.h @@ -287,12 +287,12 @@ public: void setCurrentCall(const QString& callId) const; /** - * Update call mediaList to be used in the call answering + * Set whether the user's video media should be muted * * @param callId - * @param acceptVideo + * @param videoMuted */ - void updateCallMediaList(const QString& callId, bool acceptVideo); + void setVideoMuted(const QString& callId, bool videoMuted); /** * Change the conference layout diff --git a/src/libclient/callmodel.cpp b/src/libclient/callmodel.cpp index 18587c799..6b78b742d 100644 --- a/src/libclient/callmodel.cpp +++ b/src/libclient/callmodel.cpp @@ -348,42 +348,47 @@ CallModel::getParticipantsInfos(const QString& callId) } void -CallModel::updateCallMediaList(const QString& callId, bool acceptVideo) +CallModel::setVideoMuted(const QString& callId, bool videoMuted) { - try { - auto callInfos = pimpl_->calls.find(callId); - if (callInfos != pimpl_->calls.end()) { - for (auto it = callInfos->second->mediaList.begin(); - it != callInfos->second->mediaList.end(); - it++) { - if ((*it)[MediaAttributeKey::MEDIA_TYPE] == MediaAttributeValue::VIDEO - && !acceptVideo) { - (*it)[MediaAttributeKey::ENABLED] = TRUE_STR; - (*it)[MediaAttributeKey::MUTED] = TRUE_STR; - callInfos->second->videoMuted = !acceptVideo; - } - } + auto call = pimpl_->calls.find(callId); + if (call == pimpl_->calls.end()) + return; + + auto& callInfo = call->second; + callInfo->videoMuted = videoMuted; + + for (auto& media : callInfo->mediaList) { + if (!media.contains(MediaAttributeKey::MEDIA_TYPE)) + continue; + + if (media[MediaAttributeKey::MEDIA_TYPE] == MediaAttributeValue::VIDEO) { + media[MediaAttributeKey::MUTED] = videoMuted ? TRUE_STR : FALSE_STR; } - } catch (...) { } } +static void +initializeMediaList(VectorMapStringString& mediaList, bool audioOnly) +{ + mediaList.push_back({{MediaAttributeKey::MEDIA_TYPE, MediaAttributeValue::AUDIO}, + {MediaAttributeKey::ENABLED, TRUE_STR}, + {MediaAttributeKey::MUTED, FALSE_STR}, + {MediaAttributeKey::SOURCE, ""}, + {MediaAttributeKey::LABEL, "audio_0"}}); + if (audioOnly) + return; + mediaList.push_back({{MediaAttributeKey::MEDIA_TYPE, MediaAttributeValue::VIDEO}, + {MediaAttributeKey::ENABLED, TRUE_STR}, + {MediaAttributeKey::MUTED, FALSE_STR}, + {MediaAttributeKey::SOURCE, ""}, + {MediaAttributeKey::LABEL, "video_0"}}); +} + QString CallModel::createCall(const QString& uri, bool isAudioOnly, VectorMapStringString mediaList) { if (mediaList.isEmpty()) { - MapStringString mediaAttribute = {{MediaAttributeKey::MEDIA_TYPE, - MediaAttributeValue::AUDIO}, - {MediaAttributeKey::ENABLED, TRUE_STR}, - {MediaAttributeKey::MUTED, FALSE_STR}, - {MediaAttributeKey::SOURCE, ""}, - {MediaAttributeKey::LABEL, "audio_0"}}; - mediaList.push_back(mediaAttribute); - if (!isAudioOnly) { - mediaAttribute[MediaAttributeKey::MEDIA_TYPE] = MediaAttributeValue::VIDEO; - mediaAttribute[MediaAttributeKey::LABEL] = "video_0"; - mediaList.push_back(mediaAttribute); - } + initializeMediaList(mediaList, isAudioOnly); } #ifdef ENABLE_LIBWRAP auto callId = CallManager::instance().placeCallWithMedia(owner.id, uri, mediaList); @@ -1456,7 +1461,10 @@ CallModelPimpl::slotCallStateChanged(const QString& accountId, callInfo->type = call::Type::DIALOG; callInfo->isAudioOnly = details["AUDIO_ONLY"] == TRUE_STR; callInfo->videoMuted = details["VIDEO_MUTED"] == TRUE_STR; - callInfo->mediaList = {}; + // NOTE: The CallModel::setVideoMuted function currently relies on callInfo->mediaList + // having been initialized. Not doing so leads to a bug where the user's camera wrongly + // gets turned on when they receive a call and click on "Answer in audio". + initializeMediaList(callInfo->mediaList, callInfo->isAudioOnly); calls.emplace(callId, std::move(callInfo)); if (!(details["CALL_TYPE"] == "1") && !linked.owner.confProperties.allowIncoming -- GitLab