diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp index 93a08f42e..699ebb091 100644 --- a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp +++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp @@ -35,15 +35,15 @@ #include #include "app/App.hpp" +#include "components/calls/CallsListModel.hpp" #include "components/conferenceScheduler/ConferenceScheduler.hpp" #include "components/core/CoreManager.hpp" #include "components/other/timeZone/TimeZoneModel.hpp" #include "components/participant/ParticipantListModel.hpp" +#include "components/settings/SettingsModel.hpp" #include "components/timeline/TimelineListModel.hpp" -#include "utils/Utils.hpp" #include "utils/LinphoneEnums.hpp" - - +#include "utils/Utils.hpp" // ============================================================================= @@ -63,10 +63,14 @@ QSharedPointer ConferenceInfoModel::create(std::shared_ptr< ConferenceInfoModel::ConferenceInfoModel (QObject * parent) : QObject(parent){ mConferenceInfo = linphone::Factory::get()->createConferenceInfo(); mIsScheduled = false; + if(CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled()) + mConferenceInfo->setSecurityLevel(linphone::Conference::SecurityLevel::EndToEnd); initDateTime(); auto defaultAccount = CoreManager::getInstance()->getCore()->getDefaultAccount(); if(defaultAccount){ - auto accountAddress = defaultAccount->getContactAddress(); + std::shared_ptr accountAddress = defaultAccount->getContactAddress(); + if(!accountAddress) + accountAddress = defaultAccount->getParams()->getIdentityAddress(); if(accountAddress){ auto cleanedClonedAddress = accountAddress->clone(); cleanedClonedAddress->clean(); @@ -163,7 +167,7 @@ QDateTime ConferenceInfoModel::getEndDateTimeUtc() const{ } QString ConferenceInfoModel::getOrganizer() const{ - return Utils::coreStringToAppString(mConferenceInfo->getOrganizer()->asString()); + return Utils::coreStringToAppString(mConferenceInfo->getOrganizer() ? mConferenceInfo->getOrganizer()->asString() : "Self"); } QString ConferenceInfoModel::getSubject() const{ @@ -199,6 +203,11 @@ bool ConferenceInfoModel::isEnded() const{ return mIsEnded; } +bool ConferenceInfoModel::isSecured() const{ + return mConferenceInfo ? mConferenceInfo->getSecurityLevel() != linphone::Conference::SecurityLevel::None + : CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled(); +} + bool ConferenceInfoModel::getIsEnded() const{ return getEndDateTimeUtc() < QDateTime::currentDateTimeUtc(); } @@ -323,6 +332,14 @@ void ConferenceInfoModel::setIsEnded(const bool& end){ } } +void ConferenceInfoModel::setIsSecured(const bool& on){ + if( on != isSecured()){ + if(mConferenceInfo) + mConferenceInfo->setSecurityLevel(on ? linphone::Conference::SecurityLevel::EndToEnd : linphone::Conference::SecurityLevel::None); + emit isSecuredChanged(); + } +} + void ConferenceInfoModel::setInviteMode(const int& mode){ if( mode != mInviteMode){ mInviteMode = mode; @@ -353,20 +370,46 @@ void ConferenceInfoModel::resetConferenceInfo() { } } -void ConferenceInfoModel::createConference(const int& securityLevel) { +void ConferenceInfoModel::createConference() { CoreManager::getInstance()->getTimelineListModel()->mAutoSelectAfterCreation = false; shared_ptr core = CoreManager::getInstance()->getCore(); static std::shared_ptr conference; - qInfo() << "Conference creation of " << getSubject() << " at " << securityLevel << " security, organized by " << getOrganizer() << " for " << getDateTimeSystem().toString(); + qInfo() << "Conference creation of " << getSubject() << " at " << (int)mConferenceInfo->getSecurityLevel() << " security, organized by " << getOrganizer() << " for " << getDateTimeSystem().toString(); qInfo() << "Participants:"; for(auto p : mConferenceInfo->getParticipants()) qInfo() << "\t" << p->asString().c_str(); - - mConferenceScheduler = ConferenceScheduler::create(); - mConferenceScheduler->mSendInvite = mInviteMode; - connect(mConferenceScheduler.get(), &ConferenceScheduler::invitationsSent, this, &ConferenceInfoModel::onInvitationsSent); - connect(mConferenceScheduler.get(), &ConferenceScheduler::stateChanged, this, &ConferenceInfoModel::onConferenceSchedulerStateChanged); - mConferenceScheduler->getConferenceScheduler()->setInfo(mConferenceInfo); + + if(isScheduled()) { + mConferenceScheduler = ConferenceScheduler::create(); + mConferenceScheduler->mSendInvite = mInviteMode; + connect(mConferenceScheduler.get(), &ConferenceScheduler::invitationsSent, this, &ConferenceInfoModel::onInvitationsSent); + connect(mConferenceScheduler.get(), &ConferenceScheduler::stateChanged, this, &ConferenceInfoModel::onConferenceSchedulerStateChanged); + mConferenceScheduler->getConferenceScheduler()->setInfo(mConferenceInfo); + }else { + // Since SDK 5.4, unscheduled conference must be created from a group call. + auto callListModel = CoreManager::getInstance()->getCallsListModel(); + auto settingsModel = CoreManager::getInstance()->getSettingsModel(); + bool videoEnabled = CoreManager::getInstance()->getSettingsModel()->getVideoConferenceEnabled() && settingsModel->getVideoConferenceEnabled(); + + auto parameters = core->createConferenceParams(nullptr); + if(!CoreManager::getInstance()->getSettingsModel()->getVideoConferenceEnabled()) { + parameters->enableVideo(false); + parameters->setConferenceFactoryAddress(nullptr);// Do a local conference + }else { + parameters->enableVideo(videoEnabled); + conference = core->createConferenceWithParams(parameters); + } + if(!conference) emit conferenceCreationFailed(); + else { + auto callParameters = CoreManager::getInstance()->getCore()->createCallParams(nullptr); + callParameters->enableVideo(videoEnabled); + if(!conference->inviteParticipants(mConferenceInfo->getParticipants(), callParameters)) { + emit conferenceCreated(); + }else{ + emit conferenceCreationFailed(); + } + } + } } void ConferenceInfoModel::cancelConference(){ diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp index c625e4d7b..5581e8ce7 100644 --- a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp +++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp @@ -50,6 +50,7 @@ public: Q_PROPERTY(QString uri READ getUri NOTIFY uriChanged) Q_PROPERTY(bool isScheduled READ isScheduled WRITE setIsScheduled NOTIFY isScheduledChanged) Q_PROPERTY(bool isEnded READ isEnded WRITE setIsEnded NOTIFY isEndedChanged) + Q_PROPERTY(bool isSecured READ isSecured WRITE setIsSecured NOTIFY isSecuredChanged) Q_PROPERTY(int inviteMode READ getInviteMode WRITE setInviteMode NOTIFY inviteModeChanged) Q_PROPERTY(int participantCount READ getParticipantCount NOTIFY participantsChanged) Q_PROPERTY(int allParticipantCount READ getAllParticipantCount NOTIFY participantsChanged) @@ -78,6 +79,7 @@ public: QString getUri() const; bool isScheduled() const; bool isEnded() const; + bool isSecured() const; bool getIsEnded() const; int getInviteMode() const; Q_INVOKABLE QVariantList getParticipants() const; @@ -96,6 +98,7 @@ public: void setDescription(const QString& description); void setIsScheduled(const bool& on); void setIsEnded(const bool& end); + void setIsSecured(const bool& on); void setInviteMode(const int& modes); void setDateTime(const QDate& date, const QTime& time, TimeZoneModel * model); @@ -105,7 +108,7 @@ public: // Tools Q_INVOKABLE void resetConferenceInfo();// Recreate a new conference info from factory - Q_INVOKABLE void createConference(const int& securityLevel); + Q_INVOKABLE void createConference(); Q_INVOKABLE void cancelConference(); Q_INVOKABLE void deleteConferenceInfo();// Remove completly this conference info from DB @@ -124,6 +127,7 @@ signals: void uriChanged(); void isScheduledChanged(); void isEndedChanged(); + void isSecuredChanged(); void inviteModeChanged(); void conferenceInfoStateChanged(); void conferenceSchedulerStateChanged(); @@ -140,6 +144,7 @@ private: bool mIsScheduled = true; bool mIsEnded = false; + bool mIsSecured = true; QTimer mCheckEndTimer; int mInviteMode = 0; bool mRemoveRequested = false;// true if user has request its deletion from DB diff --git a/linphone-app/ui/modules/Linphone/Timeline/Timeline.qml b/linphone-app/ui/modules/Linphone/Timeline/Timeline.qml index bb4c3d81c..792b9dceb 100644 --- a/linphone-app/ui/modules/Linphone/Timeline/Timeline.qml +++ b/linphone-app/ui/modules/Linphone/Timeline/Timeline.qml @@ -154,13 +154,13 @@ Rectangle { asynchronous: index > 20 active: true sourceComponent: TimelineItem{ - timelineModel: $modelData + timelineModel: !!$modelData ? $modelData : null modelIndex: index optionsTogglable: timeline.optionsTogglable actions: timeline.actions Connections{ - target: $modelData + target: !!$modelData ? $modelData : null onSelectedChanged:{ if(selected) { view.currentIndex = index; diff --git a/linphone-app/ui/views/App/Dialog/NewConference.qml b/linphone-app/ui/views/App/Dialog/NewConference.qml index 8032a0006..f24707184 100644 --- a/linphone-app/ui/views/App/Dialog/NewConference.qml +++ b/linphone-app/ui/views/App/Dialog/NewConference.qml @@ -51,7 +51,6 @@ DialogPlus { Layout.alignment: Qt.AlignLeft Layout.leftMargin: 15 spacing:4 - visible: false // TODO Text { Layout.fillWidth: true //: 'Would you like to encrypt your meeting ?' : Ask about setting the meeting as secured. @@ -80,14 +79,12 @@ DialogPlus { anchors.verticalCenter: parent.verticalCenter width:50 enabled:true - checked: !SettingsModel.standardChatEnabled && SettingsModel.secureChatEnabled - + checked: conferenceInfoModel.isSecured onClicked: { var newCheck = checked if(SettingsModel.standardChatEnabled && checked || SettingsModel.secureChatEnabled && !checked) newCheck = !checked; - - checked = newCheck; + conferenceInfoModel.isSecured = newCheck } indicatorStyle: SwitchStyle.aux } @@ -141,7 +138,8 @@ DialogPlus { conferenceInfoModel.setParticipants(selectedParticipants.participantListModel) conferenceInfoModel.inviteMode = getInviteMode(); - conferenceInfoModel.createConference(false && secureSwitch.checked) // TODO remove false when Encryption is ready to use + conferenceInfoModel.isSecured = secureSwitch.checked + conferenceInfoModel.createConference() } TooltipArea{ visible: AccountSettingsModel.conferenceUri == '' || subject.text == '' || selectedParticipants.count < conferenceManager.minParticipants diff --git a/linphone-app/ui/views/App/Main/Conversation.qml b/linphone-app/ui/views/App/Main/Conversation.qml index fd47271f1..d2850f913 100644 --- a/linphone-app/ui/views/App/Main/Conversation.qml +++ b/linphone-app/ui/views/App/Main/Conversation.qml @@ -341,7 +341,8 @@ ColumnLayout { conferenceInfoModel.setParticipants(conversation.chatRoomModel.participants) conferenceInfoModel.inviteMode = 0; - conferenceInfoModel.createConference(false)// TODO activate it when secure video conference is implemented + conferenceInfoModel.isSecured = conversation.securityLevel + conferenceInfoModel.createConference() }else{ Logic.openConferenceManager({chatRoomModel:conversation.chatRoomModel, autoCall:true}) }