From b6d7b20afdc254fd758c7f351ac4abd15d5fec72 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Fri, 13 Jan 2023 13:56:10 +0100 Subject: [PATCH] Close window when the call end and there is no error. Fix call windows behaviours when choosing a call to be displayed (outgoing, paused, waiting room) Fix a crash on stopping call when video was active. --- .../src/components/call/CallModel.cpp | 4 ++ .../src/components/call/CallModel.hpp | 1 + .../src/components/calls/CallsListModel.cpp | 16 +++--- linphone-app/src/components/camera/Camera.cpp | 5 ++ linphone-app/src/components/camera/Camera.hpp | 1 + .../ui/modules/Linphone/Calls/Calls.js | 53 +++++++++++++++---- .../ui/modules/Linphone/Calls/Calls.qml | 6 +-- .../ui/views/App/Calls/CallsWindow.qml | 2 +- 8 files changed, 66 insertions(+), 22 deletions(-) diff --git a/linphone-app/src/components/call/CallModel.cpp b/linphone-app/src/components/call/CallModel.cpp index 63225c720..a62957cdc 100644 --- a/linphone-app/src/components/call/CallModel.cpp +++ b/linphone-app/src/components/call/CallModel.cpp @@ -130,6 +130,10 @@ CallModel::CallModel (shared_ptr call){ CallModel::~CallModel () { mMagicSearch->removeListener(mSearch); + removeCall(); +} + +void CallModel::removeCall(){ if(mCall){ mCall->removeListener(mCallListener); mConferenceModel = nullptr;// Ordering deletion. diff --git a/linphone-app/src/components/call/CallModel.hpp b/linphone-app/src/components/call/CallModel.hpp index 1d0c4f53f..a4bd3e04e 100644 --- a/linphone-app/src/components/call/CallModel.hpp +++ b/linphone-app/src/components/call/CallModel.hpp @@ -126,6 +126,7 @@ public: CallModel (std::shared_ptr call); ~CallModel (); + void removeCall(); std::shared_ptr getCall () const { return mCall; diff --git a/linphone-app/src/components/calls/CallsListModel.cpp b/linphone-app/src/components/calls/CallsListModel.cpp index 4ab22c46b..3157b87c4 100644 --- a/linphone-app/src/components/calls/CallsListModel.cpp +++ b/linphone-app/src/components/calls/CallsListModel.cpp @@ -540,6 +540,8 @@ void CallsListModel::handleCallStateChanged (const shared_ptr &c if(call->dataExists("call-model")) { CallModel * model = &call->getData("call-model"); model->endCall(); + if(model->getCallError() == "") + removeCall(call); } } break; case linphone::Call::State::Released: @@ -608,22 +610,20 @@ void CallsListModel::addDummyCall () { void CallsListModel::removeCall (const shared_ptr &call) { CallModel *callModel = nullptr; - try { - callModel = &call->getData("call-model"); - } catch (const out_of_range &) { - // The call model not exists because the linphone call state - // `CallStateIncomingReceived`/`CallStateOutgoingInit` was not notified. - qWarning() << QStringLiteral("Unable to find call:") << call.get(); + if(!call->dataExists("call-model")) return; - } + callModel = &call->getData("call-model"); if( callModel && callModel->getCallError() != ""){ // Wait some time to display an error on ending call. QTimer::singleShot( DelayBeforeRemoveCall , this, [this, callModel] { removeCallCb(callModel); }); - }else + }else{ + callModel->removeCall(); remove(callModel); + } } void CallsListModel::removeCallCb (CallModel *callModel) { + callModel->removeCall(); remove(callModel); } diff --git a/linphone-app/src/components/camera/Camera.cpp b/linphone-app/src/components/camera/Camera.cpp index bacbd5afd..55f002dbd 100644 --- a/linphone-app/src/components/camera/Camera.cpp +++ b/linphone-app/src/components/camera/Camera.cpp @@ -159,6 +159,10 @@ void Camera::removeParticipantDeviceModel(){ mParticipantDeviceModel = nullptr; } +void Camera::callRemoved(){ + mCallModel = nullptr; +} + QQuickFramebufferObject::Renderer *Camera::createRenderer () const { QQuickFramebufferObject::Renderer * renderer = NULL; if(mWindowIdLocation == CorePreview){ @@ -229,6 +233,7 @@ void Camera::setCallModel (CallModel *callModel) { disconnect(mCallModel, &CallModel::statusChanged, this, &Camera::onCallStateChanged); mCallModel = callModel; connect(mCallModel, &CallModel::statusChanged, this, &Camera::onCallStateChanged); + connect(mCallModel, &QObject::destroyed, this, &Camera::callRemoved); updateWindowIdLocation(); update(); diff --git a/linphone-app/src/components/camera/Camera.hpp b/linphone-app/src/components/camera/Camera.hpp index 201acb73b..093d1ac79 100644 --- a/linphone-app/src/components/camera/Camera.hpp +++ b/linphone-app/src/components/camera/Camera.hpp @@ -94,6 +94,7 @@ private: void deactivatePreview(); void updateWindowIdLocation(); void removeParticipantDeviceModel(); + void callRemoved(); QVariantMap mLastVideoDefinition; QTimer mLastVideoDefinitionChecker; diff --git a/linphone-app/ui/modules/Linphone/Calls/Calls.js b/linphone-app/ui/modules/Linphone/Calls/Calls.js index f8a0464a4..771eb6106 100644 --- a/linphone-app/ui/modules/Linphone/Calls/Calls.js +++ b/linphone-app/ui/modules/Linphone/Calls/Calls.js @@ -165,6 +165,16 @@ function updateSelectedCall (call, index) { } } +function getCallToStatusCondition(model, condition){ + for(var index = count - 1 ; index >= 0 ; --index){ + var callModel = model.data(model.index(index, 0)) + if(callModel.status === condition){ + return {'callModel': callModel, 'index': index} + } + } + return null +} + function resetSelectedCall () { updateSelectedCall(null, -1) } @@ -193,20 +203,43 @@ function handleCountChanged (count) { } var call = calls._selectedCall + var model = calls.model - if (call == null) { - if (calls.conferenceModel.count > 0) { + if (call == null) {// No selected call. + if (calls.conferenceModel.count > 0) {// TODO : Is this needed? return } - - var model = calls.model - var index = count - 1 - if(model){ - var callModel = model.data(model.index(index, 0)) - if( callModel.status === Linphone.CallModel.CallStatusConnected || callModel.isOutgoing ) - updateSelectedCall(callModel, index) + if(model){// Choose one call + var candidate = getCallToStatusCondition(model, Linphone.CallModel.CallStatusConnected) + if(candidate && candidate.callModel.isOutgoing) { + updateSelectedCall(candidate.callModel, candidate.index) + return; + } + candidate = getCallToStatusCondition(model, Linphone.CallModel.CallStatusOutgoing) + if(candidate){ + updateSelectedCall(candidate.callModel, candidate.index) + return; + } + candidate = getCallToStatusCondition(model, Linphone.CallModel.CallStatusPaused) + if(candidate){ + updateSelectedCall(candidate.callModel, candidate.index) + return; + }else + calls.refreshLastCall() + } + } else{ + if(model){// Select a call that has been localy initiated. + var candidate = getCallToStatusCondition(model, Linphone.CallModel.CallStatusConnected) + if(candidate && candidate.callModel.isOutgoing) { + updateSelectedCall(candidate.callModel, candidate.index) + return; + } + candidate = getCallToStatusCondition(model, Linphone.CallModel.CallStatusOutgoing) + if(candidate){ + updateSelectedCall(candidate.callModel, candidate.index) + return; + } } - } else { setIndexWithCall(call) } } diff --git a/linphone-app/ui/modules/Linphone/Calls/Calls.qml b/linphone-app/ui/modules/Linphone/Calls/Calls.qml index 6e01b445c..191796556 100644 --- a/linphone-app/ui/modules/Linphone/Calls/Calls.qml +++ b/linphone-app/ui/modules/Linphone/Calls/Calls.qml @@ -33,12 +33,12 @@ ListView { Logic.resetSelectedCall() } function refreshLastCall(){ - if(lastCall && lastCall.status === CallModel.CallStatusConnected) + if(lastCall && (lastCall.status === CallModel.CallStatusConnected || lastCall.status === CallModel.CallStatusOutgoing)) Logic.setIndexWithCall(lastCall) else{ for(var i = 0 ; i < model.rowCount() ; ++i){ var call = model.data(model.index(i, 0)) - if( call && call.status === CallModel.CallStatusConnected){ + if( call && (call.status === CallModel.CallStatusConnected || call.status === CallModel.CallStatusPaused || call.status == CallModel.CallStatusOutgoing)){ Logic.updateSelectedCall(call, i) return; } @@ -80,7 +80,7 @@ ListView { ActionButton { id: button - property bool isSelected : calls.currentIndex === callId && call.status !== CallModel.CallStatusEnded + property bool isSelected : calls.currentIndex === callId isCustom: true backgroundRadius: 4 colorSet: isSelected ? CallsStyle.entry.selectedBurgerMenu : CallsStyle.entry.burgerMenu diff --git a/linphone-app/ui/views/App/Calls/CallsWindow.qml b/linphone-app/ui/views/App/Calls/CallsWindow.qml index 965191e0f..d66112701 100644 --- a/linphone-app/ui/views/App/Calls/CallsWindow.qml +++ b/linphone-app/ui/views/App/Calls/CallsWindow.qml @@ -88,7 +88,7 @@ Window { maximumLeftLimit: CallsWindowStyle.callsList.maximumWidth minimumLeftLimit: CallsWindowStyle.callsList.minimumWidth - hideSplitter: !window.callsIsOpened && middlePane.sourceComponent == incall || middlePane.sourceComponent == waitingRoom + hideSplitter: !window.callsIsOpened && (middlePane.sourceComponent == incall && window.call.status != CallModel.CallStatusPaused) || middlePane.sourceComponent == waitingRoom // ------------------------------------------------------------------------- // Calls list.