From 361c6d7ce1ef279017dcd632d4d6539ec3458e9d Mon Sep 17 00:00:00 2001 From: Gaelle Braud Date: Fri, 27 Feb 2026 12:16:00 +0100 Subject: [PATCH] fix paused status local conf --- Linphone/core/call/CallCore.cpp | 5 +++ Linphone/core/conference/ConferenceCore.cpp | 27 +++++++++++++ Linphone/core/conference/ConferenceCore.hpp | 6 +++ Linphone/data/languages/de.ts | 40 +++++++++---------- Linphone/data/languages/en.ts | 40 +++++++++---------- Linphone/data/languages/fr_FR.ts | 40 +++++++++---------- Linphone/model/call/CallModel.cpp | 20 +++++++--- .../Container/Call/ActiveSpeakerLayout.qml | 19 +++++---- 8 files changed, 124 insertions(+), 73 deletions(-) diff --git a/Linphone/core/call/CallCore.cpp b/Linphone/core/call/CallCore.cpp index f9584d5b8..6ea387fd5 100644 --- a/Linphone/core/call/CallCore.cpp +++ b/Linphone/core/call/CallCore.cpp @@ -271,6 +271,7 @@ void CallCore::setSelf(QSharedPointer me) { }); mCallModelConnection->invokeToCore([this, state, message]() { setState(LinphoneEnums::fromLinphone(state)); }); }); + mCallModelConnection->makeConnectToModel(&CallModel::statusChanged, [this](linphone::Call::Status status) { mCallModelConnection->invokeToCore([this, status]() { setStatus(LinphoneEnums::fromLinphone(status)); }); }); @@ -601,9 +602,13 @@ QSharedPointer CallCore::getConferenceCore() const { void CallCore::setConference(const QSharedPointer &conference) { mustBeInMainThread(log().arg(Q_FUNC_INFO)); + if (mConference) disconnect(mConference.get(), &ConferenceCore::isMePausedChanged, this, nullptr); if (mConference != conference) { mConference = conference; lDebug() << "[CallCore] Set conference : " << mConference; + if (mConference) + connect(mConference.get(), &ConferenceCore::isMePausedChanged, this, + [this] { setPaused(mConference->getIsMePaused()); }); setIsConference(conference != nullptr); emit conferenceChanged(); } diff --git a/Linphone/core/conference/ConferenceCore.cpp b/Linphone/core/conference/ConferenceCore.cpp index 624715fee..9d0f01dd8 100644 --- a/Linphone/core/conference/ConferenceCore.cpp +++ b/Linphone/core/conference/ConferenceCore.cpp @@ -50,10 +50,26 @@ ConferenceCore::ConferenceCore(const std::shared_ptr &conf auto me = conference->getMe(); if (me) { mMe = ParticipantCore::create(me); + auto meDevices = me->getDevices(); + for (auto &device : meDevices) { + auto deviceCore = ParticipantDeviceCore::create(device); + if (deviceCore) { + mMeDevices.append(deviceCore); + connect(deviceCore.get(), &ParticipantDeviceCore::stateChanged, this, [this, deviceCore] { + auto state = deviceCore->getState(); + lInfo() << "me state changed, paused =" + << (state == LinphoneEnums::ParticipantDeviceState::Left || + state == LinphoneEnums::ParticipantDeviceState::OnHold); + setIsMePaused(state == LinphoneEnums::ParticipantDeviceState::Left || + state == LinphoneEnums::ParticipantDeviceState::OnHold); + }); + } + } } } ConferenceCore::~ConferenceCore() { mustBeInMainThread("~" + getClassName()); + mMeDevices.clear(); if (mConferenceModel) emit mConferenceModel->removeListener(); } @@ -217,3 +233,14 @@ void ConferenceCore::setActiveSpeakerDevice(const QSharedPointer getModel() const; //--------------------------------------------------------------------------- @@ -92,6 +95,7 @@ signals: void activeSpeakerDeviceChanged(); void subjectChanged(); void isRecordingChanged(); + void isMePausedChanged(); void lToggleScreenSharing(); @@ -100,12 +104,14 @@ private: std::shared_ptr mConferenceModel; QSharedPointer mActiveSpeakerDevice; QSharedPointer mMe; + QList> mMeDevices; int mParticipantDeviceCount = 0; bool mIsReady = false; bool mIsRecording = false; bool mIsLocalScreenSharing = false; bool mIsScreenSharingEnabled = false; + bool mIsMePaused = false; QString mSubject; QDateTime mStartDate = QDateTime::currentDateTime(); diff --git a/Linphone/data/languages/de.ts b/Linphone/data/languages/de.ts index 50036841b..a894f1746 100644 --- a/Linphone/data/languages/de.ts +++ b/Linphone/data/languages/de.ts @@ -659,64 +659,64 @@ Die Aufnahme wurde in der folgenden Datei gespeichert: %1 - - + + call_stats_codec_label "Codec: %1 / %2 kHz" Codec: %1 / %2 kHz - - + + call_stats_bandwidth_label "Bande passante : %1 %2 kbits/s %3 %4 kbits/s" Bandbreite: %1 %2 kbits/s %3 %4 kbits/s - - + + call_stats_loss_rate_label "Taux de perte: %1% %2%" Verlustquote: %1% %2% - + call_stats_jitter_buffer_label "Tampon de gigue: %1 ms" Jitter-Puffer: %1 ms - + call_stats_resolution_label "Définition vidéo : %1 %2 %3 %4" Videoauflösung: %1 %2 %3 %4 - + call_stats_fps_label "FPS : %1 %2 %3 %4" FPS : %1 %2 %3 %4 - + media_encryption_dtls DTLS DTLS - + media_encryption_none None Keine - + media_encryption_srtp SRTP SRTP - + media_encryption_post_quantum "ZRTP - Post quantique" Post-quantum ZRTP @@ -847,43 +847,43 @@ CallModel - + call_error_user_declined_toast "Le correspondant a décliné l'appel" Der Benutzer hat den Anruf abgelehnt - + call_error_user_not_found_toast "Le correspondant n'a pas été trouvé" Benutzer nicht gefunden - + call_error_user_busy_toast "Le correspondant est occupé" Der Benutzer ist beschäftigt - + call_error_incompatible_media_params_toast "Le correspondant ne peut accepter votre appel." Der Benutzer kann Ihren Anruf nicht annehmen - + call_error_io_error_toast "Service indisponible ou erreur réseau" Dienst nicht verfügbar oder Netzwerkfehler - + call_error_temporarily_unavailable_toast "Temporairement indisponible" Vorübergehend nicht verfügbar - + call_error_server_timeout_toast "Délai d'attente du serveur dépassé" Server-Zeitüberschreitung diff --git a/Linphone/data/languages/en.ts b/Linphone/data/languages/en.ts index b6c230598..940d6f592 100644 --- a/Linphone/data/languages/en.ts +++ b/Linphone/data/languages/en.ts @@ -659,64 +659,64 @@ Recording has been saved in file : %1 - - + + call_stats_codec_label "Codec: %1 / %2 kHz" Codec: %1 / %2 kHz - - + + call_stats_bandwidth_label "Bande passante : %1 %2 kbits/s %3 %4 kbits/s" Bandwidth : %1 %2 kbits/s %3 %4 kbits/s - - + + call_stats_loss_rate_label "Taux de perte: %1% %2%" Loss rate: %1% %2% - + call_stats_jitter_buffer_label "Tampon de gigue: %1 ms" Jitter buffer : %1 ms - + call_stats_resolution_label "Définition vidéo : %1 %2 %3 %4" Video resolution: %1 %2 %3 %4 - + call_stats_fps_label "FPS : %1 %2 %3 %4" FPS : %1 %2 %3 %4 - + media_encryption_dtls DTLS DTLS - + media_encryption_none None None - + media_encryption_srtp SRTP SRTP - + media_encryption_post_quantum "ZRTP - Post quantique" Post quantum ZRTP @@ -847,43 +847,43 @@ CallModel - + call_error_user_declined_toast "Le correspondant a décliné l'appel" User declined the call - + call_error_user_not_found_toast "Le correspondant n'a pas été trouvé" User was not found - + call_error_user_busy_toast "Le correspondant est occupé" User is busy - + call_error_incompatible_media_params_toast "Le correspondant ne peut accepter votre appel." User can't accept your call - + call_error_io_error_toast "Service indisponible ou erreur réseau" Unavailable service or network error - + call_error_temporarily_unavailable_toast "Temporairement indisponible" temporarily unavailable - + call_error_server_timeout_toast "Délai d'attente du serveur dépassé" Server tiemout diff --git a/Linphone/data/languages/fr_FR.ts b/Linphone/data/languages/fr_FR.ts index d41f1abe3..88cf51341 100644 --- a/Linphone/data/languages/fr_FR.ts +++ b/Linphone/data/languages/fr_FR.ts @@ -659,64 +659,64 @@ L'appel a été enregistré dans le fichier : %1 - - + + call_stats_codec_label "Codec: %1 / %2 kHz" Codec: %1 / %2 kHz - - + + call_stats_bandwidth_label "Bande passante : %1 %2 kbits/s %3 %4 kbits/s" Bande passante : %1 %2 kbits/s %3 %4 kbits/s - - + + call_stats_loss_rate_label "Taux de perte: %1% %2%" Taux de perte: %1% %2% - + call_stats_jitter_buffer_label "Tampon de gigue: %1 ms" Tampon de gigue: %1 ms - + call_stats_resolution_label "Définition vidéo : %1 %2 %3 %4" Définition vidéo : %1 %2 %3 %4 - + call_stats_fps_label "FPS : %1 %2 %3 %4" FPS : %1 %2 %3 %4 - + media_encryption_dtls DTLS DTLS - + media_encryption_none None None - + media_encryption_srtp SRTP SRTP - + media_encryption_post_quantum "ZRTP - Post quantique" ZRTP - Post quantique @@ -847,43 +847,43 @@ CallModel - + call_error_user_declined_toast "Le correspondant a décliné l'appel" Le correspondant a décliné l'appel - + call_error_user_not_found_toast "Le correspondant n'a pas été trouvé" Le correspondant n'a pas été trouvé - + call_error_user_busy_toast "Le correspondant est occupé" Le correspondant est occupé - + call_error_incompatible_media_params_toast "Le correspondant ne peut accepter votre appel." Le correspondant ne peut accepter votre appel - + call_error_io_error_toast "Service indisponible ou erreur réseau" Service indisponible ou erreur réseau - + call_error_temporarily_unavailable_toast "Temporairement indisponible" Temporairement indisponible - + call_error_server_timeout_toast "Délai d'attente du serveur dépassé" Délai d'attente du serveur dépassé diff --git a/Linphone/model/call/CallModel.cpp b/Linphone/model/call/CallModel.cpp index ac8192cd8..108e0c278 100644 --- a/Linphone/model/call/CallModel.cpp +++ b/Linphone/model/call/CallModel.cpp @@ -86,17 +86,27 @@ void CallModel::terminate() { void CallModel::setPaused(bool paused) { mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); if (paused) { - lInfo() << "Pausing call" - << (mMonitor->getRemoteAddress() ? mMonitor->getRemoteAddress()->asStringUriOnly() - : "no remote address"); if (mMonitor->getConference()) { + lInfo() << "Leaving conference" + << (mMonitor->getRemoteAddress() ? mMonitor->getRemoteAddress()->asStringUriOnly() : "no address"); mMonitor->getConference()->leave(); } else { + lInfo() << "Pausing call" + << (mMonitor->getRemoteAddress() ? mMonitor->getRemoteAddress()->asStringUriOnly() + : "no remote address"); mMonitor->pause(); } } else { - if (mMonitor->getConference()) mMonitor->getConference()->enter(); - mMonitor->resume(); + if (mMonitor->getConference()) { + lInfo() << "Entering conference" + << (mMonitor->getRemoteAddress() ? mMonitor->getRemoteAddress()->asStringUriOnly() : "no address"); + mMonitor->getConference()->enter(); + } else { + lInfo() << "Resuming call" + << (mMonitor->getRemoteAddress() ? mMonitor->getRemoteAddress()->asStringUriOnly() + : "no remote address"); + mMonitor->resume(); + } } } diff --git a/Linphone/view/Control/Container/Call/ActiveSpeakerLayout.qml b/Linphone/view/Control/Container/Call/ActiveSpeakerLayout.qml index 87bf83541..1db965cff 100644 --- a/Linphone/view/Control/Container/Call/ActiveSpeakerLayout.qml +++ b/Linphone/view/Control/Container/Call/ActiveSpeakerLayout.qml @@ -22,7 +22,8 @@ Item { : "" // currently speaking address (for hiding in list view) - property string activeSpeakerAddress + property string activeSpeakerAddress: activeSpeakerSticker.remoteAddress + onActiveSpeakerAddressChanged: console.log("active speaker address changed", activeSpeakerAddress) property ParticipantDeviceProxy participantDevices : ParticipantDeviceProxy { id: allDevices @@ -43,17 +44,19 @@ Item { call: mainItem.call displayAll: !mainItem.conference participantDevice: mainItem.conference && mainItem.conference.core.activeSpeakerDevice + useUniqueAddress: true property var address: participantDevice && participantDevice.core.address videoEnabled: (participantDevice && participantDevice.core.videoEnabled) || (!participantDevice && call && call.core.remoteVideoEnabled) qmlName: 'AS' securityBreach: !mainItem.conference && mainItem.call?.core.isMismatch || false displayPresence: false - Binding { - target: mainItem - property: "activeSpeakerAddress" - value: activeSpeakerSticker.address - when: true - } + onAddressChanged: console.log("active speaker adress changed ==================", address) + // Binding { + // target: mainItem + // property: "activeSpeakerAddress" + // value: activeSpeakerSticker.address + // when: true + // } } ListView{ id: sideStickers @@ -68,7 +71,7 @@ Item { clip: true delegate: Item{ // Spacing workaround visible: $modelData && mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released - && ($modelData.core.address != activeSpeakerAddress || mainItem.conference?.core.isScreenSharingEnabled) || false + && ($modelData.core.address != mainItem.activeSpeakerAddress || mainItem.conference?.core.isScreenSharingEnabled) || false height: visible ? Math.round((180 + 15) * DefaultStyle.dp) : 0 width: Math.round(300 * DefaultStyle.dp) Sticker {