fix #LINQT-1486 set default conference layout in parameters

LINQT-1487 add security/encryption settings
This commit is contained in:
Gaelle Braud 2024-12-10 15:15:47 +01:00
parent d5bc7c071b
commit 7faa4cba47
16 changed files with 305 additions and 20 deletions

View file

@ -178,7 +178,7 @@ CallCore::CallCore(const std::shared_ptr<linphone::Call> &call) : QObject(nullpt
}
mMicrophoneVolume = call->getRecordVolume();
mRecordable = mState == LinphoneEnums::CallState::StreamsRunning;
mConferenceVideoLayout = mCallModel->getConferenceVideoLayout();
mConferenceVideoLayout = LinphoneEnums::fromLinphone(SettingsModel::getInstance()->getDefaultConferenceLayout());
auto videoSource = call->getVideoSource();
mVideoSourceDescriptor = VideoSourceDescriptorCore::create(videoSource ? videoSource->clone() : nullptr);
}

View file

@ -105,7 +105,7 @@ ConferenceInfoCore::ConferenceInfoCore(std::shared_ptr<linphone::ConferenceInfo>
auto cleanedClonedAddress = accountAddress->clone();
cleanedClonedAddress->clean();
auto address = Utils::coreStringToAppString(cleanedClonedAddress->asStringUriOnly());
App::postCoreAsync([this, address]() { mOrganizerAddress = address; });
App::postCoreAsync([this, address]() { setOrganizerAddress(address); });
}
}
});

View file

@ -58,6 +58,16 @@ SettingsCore::SettingsCore(QObject *parent) : QObject(parent) {
mCaptureDevice = settingsModel->getCaptureDevice();
mPlaybackDevice = settingsModel->getPlaybackDevice();
mConferenceLayouts = LinphoneEnums::conferenceLayoutsToVariant();
mConferenceLayout =
LinphoneEnums::toVariant(LinphoneEnums::fromLinphone(settingsModel->getDefaultConferenceLayout()));
mMediaEncryptions = LinphoneEnums::mediaEncryptionsToVariant();
mMediaEncryption =
LinphoneEnums::toVariant(LinphoneEnums::fromLinphone(settingsModel->getDefaultMediaEncryption()));
mMediaEncryptionMandatory = settingsModel->getMediaEncryptionMandatory();
mCaptureGain = settingsModel->getCaptureGain();
mPlaybackGain = settingsModel->getPlaybackGain();
@ -258,6 +268,46 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
});
});
mSettingsModelConnection->makeConnectToCore(&SettingsCore::lSetConferenceLayout, [this](QVariantMap layout) {
auto linLayout = LinphoneEnums::toLinphone(LinphoneEnums::ConferenceLayout(layout["id"].toInt()));
mSettingsModelConnection->invokeToModel(
[this, linLayout]() { SettingsModel::getInstance()->setDefaultConferenceLayout(linLayout); });
});
mSettingsModelConnection->makeConnectToModel(&SettingsModel::conferenceLayoutChanged, [this]() {
auto layout = LinphoneEnums::fromLinphone(SettingsModel::getInstance()->getDefaultConferenceLayout());
mSettingsModelConnection->invokeToCore([this, layout]() {
mConferenceLayout = LinphoneEnums::toVariant(layout);
emit conferenceLayoutChanged();
});
});
mSettingsModelConnection->makeConnectToCore(
&SettingsCore::lSetMediaEncryption, [this](const QVariantMap &encryption) {
auto linEncryption = LinphoneEnums::toLinphone(LinphoneEnums::MediaEncryption(encryption["id"].toInt()));
mSettingsModelConnection->invokeToModel(
[this, linEncryption]() { SettingsModel::getInstance()->setDefaultMediaEncryption(linEncryption); });
});
mSettingsModelConnection->makeConnectToModel(&SettingsModel::mediaEncryptionChanged, [this]() {
auto encryption = LinphoneEnums::toVariant(
LinphoneEnums::fromLinphone(SettingsModel::getInstance()->getDefaultMediaEncryption()));
mSettingsModelConnection->invokeToCore([this, encryption]() {
mMediaEncryption = encryption;
emit mediaEncryptionChanged();
});
});
mSettingsModelConnection->makeConnectToCore(&SettingsCore::lSetMediaEncryptionMandatory, [this](bool mandatory) {
mSettingsModelConnection->invokeToModel(
[this, mandatory]() { SettingsModel::getInstance()->setMediaEncryptionMandatory(mandatory); });
});
mSettingsModelConnection->makeConnectToModel(&SettingsModel::mediaEncryptionMandatoryChanged, [this]() {
auto mandatory = SettingsModel::getInstance()->getMediaEncryptionMandatory();
mSettingsModelConnection->invokeToCore([this, mandatory]() {
mMediaEncryptionMandatory = mandatory;
emit mediaEncryptionMandatoryChanged(mandatory);
});
});
mSettingsModelConnection->makeConnectToModel(&SettingsModel::videoDevicesChanged,
[this](const QStringList devices) {
mSettingsModelConnection->invokeToCore([this, devices]() {
@ -391,6 +441,18 @@ QVariantList SettingsCore::getRingerDevices() const {
return mRingerDevices;
}
QVariantList SettingsCore::getConferenceLayouts() const {
return mConferenceLayouts;
}
QVariantList SettingsCore::getMediaEncryptions() const {
return mMediaEncryptions;
}
bool SettingsCore::isMediaEncryptionMandatory() const {
return mMediaEncryptionMandatory;
}
int SettingsCore::getVideoDeviceIndex() const {
return mVideoDevices.indexOf(mVideoDevice);
}
@ -407,6 +469,14 @@ float SettingsCore::getCaptureGain() const {
return mCaptureGain;
}
QVariantMap SettingsCore::getConferenceLayout() const {
return mConferenceLayout;
}
QVariantMap SettingsCore::getMediaEncryption() const {
return mMediaEncryption;
}
float SettingsCore::getPlaybackGain() const {
return mPlaybackGain;
}

View file

@ -50,6 +50,8 @@ public:
Q_PROPERTY(QVariantList captureDevices READ getCaptureDevices NOTIFY captureDevicesChanged)
Q_PROPERTY(QVariantList playbackDevices READ getPlaybackDevices NOTIFY playbackDevicesChanged)
Q_PROPERTY(QVariantList ringerDevices READ getRingerDevices NOTIFY ringerDevicesChanged)
Q_PROPERTY(QVariantList conferenceLayouts READ getConferenceLayouts NOTIFY conferenceLayoutsChanged)
Q_PROPERTY(QVariantList mediaEncryptions READ getMediaEncryptions NOTIFY mediaEncryptionsChanged)
Q_PROPERTY(float playbackGain READ getPlaybackGain WRITE lSetPlaybackGain NOTIFY playbackGainChanged)
Q_PROPERTY(float captureGain READ getCaptureGain WRITE lSetCaptureGain NOTIFY captureGainChanged)
@ -58,6 +60,13 @@ public:
Q_PROPERTY(QVariantMap playbackDevice READ getPlaybackDevice WRITE lSetPlaybackDevice NOTIFY playbackDeviceChanged)
Q_PROPERTY(QVariantMap ringerDevice READ getRingerDevice WRITE lSetRingerDevice NOTIFY ringerDeviceChanged)
Q_PROPERTY(
QVariantMap conferenceLayout READ getConferenceLayout WRITE lSetConferenceLayout NOTIFY conferenceLayoutChanged)
Q_PROPERTY(
QVariantMap mediaEncryption READ getMediaEncryption WRITE lSetMediaEncryption NOTIFY mediaEncryptionChanged)
Q_PROPERTY(bool mediaEncryptionMandatory READ isMediaEncryptionMandatory WRITE lSetMediaEncryptionMandatory NOTIFY
mediaEncryptionMandatoryChanged)
Q_PROPERTY(QStringList videoDevices READ getVideoDevices NOTIFY videoDevicesChanged)
Q_PROPERTY(QString videoDevice READ getVideoDevice WRITE lSetVideoDevice NOTIFY videoDeviceChanged)
Q_PROPERTY(int videoDeviceIndex READ getVideoDeviceIndex NOTIFY videoDeviceChanged)
@ -109,13 +118,19 @@ public:
float getCaptureGain() const;
QVariantMap getMediaEncryption() const;
bool isMediaEncryptionMandatory() const;
QVariantList getCaptureDevices() const;
QVariantList getPlaybackDevices() const;
QVariantList getRingerDevices() const;
QVariantList getConferenceLayouts() const;
QVariantList getMediaEncryptions() const;
QVariantMap getCaptureDevice() const;
QVariantMap getPlaybackDevice() const;
QVariantMap getRingerDevice() const;
QVariantMap getConferenceLayout() const;
QString getVideoDevice() const {
return mVideoDevice;
@ -193,10 +208,21 @@ signals:
void captureDevicesChanged(const QVariantList &devices);
void playbackDevicesChanged(const QVariantList &devices);
void ringerDevicesChanged(const QVariantList &devices);
void conferenceLayoutsChanged(const QVariantList &layouts);
void mediaEncryptionsChanged(const QVariantList &encryptions);
void lSetCaptureDevice(const QVariantMap &device);
void captureDeviceChanged(const QVariantMap &device);
void lSetConferenceLayout(QVariantMap confLayout);
void conferenceLayoutChanged();
void lSetMediaEncryption(const QVariantMap &id);
void mediaEncryptionChanged();
void lSetMediaEncryptionMandatory(bool mandatory);
void mediaEncryptionMandatoryChanged(bool mandatory);
void lSetPlaybackDevice(const QVariantMap &device);
void playbackDeviceChanged(const QVariantMap &device);
@ -239,6 +265,9 @@ private:
// Security
bool mVfsEnabled;
QVariantList mMediaEncryptions;
QVariantMap mMediaEncryption;
bool mMediaEncryptionMandatory;
// Call
bool mVideoEnabled;
@ -249,9 +278,11 @@ private:
QVariantList mCaptureDevices;
QVariantList mPlaybackDevices;
QVariantList mRingerDevices;
QVariantList mConferenceLayouts;
QVariantMap mCaptureDevice;
QVariantMap mPlaybackDevice;
QVariantMap mRingerDevice;
QVariantMap mConferenceLayout;
// Video
QStringList mVideoDevices;

View file

@ -296,6 +296,39 @@ void SettingsModel::setCaptureDevice(const QVariantMap &device) {
} else qWarning() << "Cannot set Capture device. The ID cannot be matched with an existant device : " << device;
}
linphone::Conference::Layout SettingsModel::getDefaultConferenceLayout() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
return CoreModel::getInstance()->getCore()->getDefaultConferenceLayout();
}
void SettingsModel::setDefaultConferenceLayout(const linphone::Conference::Layout layout) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
CoreModel::getInstance()->getCore()->setDefaultConferenceLayout(layout);
emit conferenceLayoutChanged();
}
linphone::MediaEncryption SettingsModel::getDefaultMediaEncryption() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
return CoreModel::getInstance()->getCore()->getMediaEncryption();
}
void SettingsModel::setDefaultMediaEncryption(const linphone::MediaEncryption encryption) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
CoreModel::getInstance()->getCore()->setMediaEncryption(encryption);
emit mediaEncryptionChanged();
}
bool SettingsModel::getMediaEncryptionMandatory() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
return CoreModel::getInstance()->getCore()->isMediaEncryptionMandatory();
}
void SettingsModel::setMediaEncryptionMandatory(bool mandatory) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
CoreModel::getInstance()->getCore()->setMediaEncryptionMandatory(mandatory);
emit mediaEncryptionMandatoryChanged();
}
// -----------------------------------------------------------------------------
QVariantMap SettingsModel::getPlaybackDevice() const {

View file

@ -93,6 +93,15 @@ public:
QVariantMap getPlaybackDevice() const;
void setPlaybackDevice(const QVariantMap &device);
linphone::Conference::Layout getDefaultConferenceLayout() const;
void setDefaultConferenceLayout(const linphone::Conference::Layout layout);
linphone::MediaEncryption getDefaultMediaEncryption() const;
void setDefaultMediaEncryption(const linphone::MediaEncryption encryption);
bool getMediaEncryptionMandatory() const;
void setMediaEncryptionMandatory(bool mandatory);
QVariantMap getRingerDevice() const;
void setRingerDevice(const QVariantMap &device);
@ -183,6 +192,9 @@ signals:
void playbackDeviceChanged(QVariantMap device);
void ringerDeviceChanged(QVariantMap device);
void videoDeviceChanged(QString device);
void conferenceLayoutChanged();
void mediaEncryptionChanged();
void mediaEncryptionMandatoryChanged();
void showAudioCodecsChanged(bool status);

View file

@ -69,6 +69,7 @@ public:
static void updateCodecs();
static QVariantMap createVariant(const std::shared_ptr<const linphone::AudioDevice> &device);
static QVariantMap createVariant(linphone::Conference::Layout layout);
static QString getOsProduct();
static QString computeUserAgent(const std::shared_ptr<linphone::Config> &config);

View file

@ -57,18 +57,43 @@ LinphoneEnums::MediaEncryption LinphoneEnums::fromLinphone(const linphone::Media
QString LinphoneEnums::toString(LinphoneEnums::MediaEncryption encryption) {
switch (encryption) {
case LinphoneEnums::MediaEncryption::Dtls:
return "DTLS";
return QObject::tr("DTLS");
case LinphoneEnums::MediaEncryption::None:
return "None";
return QObject::tr("None");
case LinphoneEnums::MediaEncryption::Srtp:
return "SRTP";
return QObject::tr("SRTP");
case LinphoneEnums::MediaEncryption::Zrtp:
return "ZRTP";
return QObject::tr("ZRTP - Post quantique");
default:
return QString();
}
}
QVariantList LinphoneEnums::mediaEncryptionsToVariant(QList<LinphoneEnums::MediaEncryption> list) {
QVariantList variantList;
for (auto &item : list)
variantList.append(LinphoneEnums::toVariant(item));
return variantList;
}
QVariantMap LinphoneEnums::toVariant(LinphoneEnums::MediaEncryption encryption) {
QVariantMap map;
if (encryption == LinphoneEnums::MediaEncryption::None) {
map.insert("id", QVariant::fromValue(encryption));
map.insert("display_name", toString(encryption));
} else if (encryption == LinphoneEnums::MediaEncryption::Srtp) {
map.insert("id", QVariant::fromValue(encryption));
map.insert("display_name", toString(encryption));
} else if (encryption == LinphoneEnums::MediaEncryption::Zrtp) {
map.insert("id", QVariant::fromValue(encryption));
map.insert("display_name", toString(encryption));
} else if (encryption == LinphoneEnums::MediaEncryption::Dtls) {
map.insert("id", QVariant::fromValue(encryption));
map.insert("display_name", toString(encryption));
}
return map;
}
linphone::Friend::Capability LinphoneEnums::toLinphone(const LinphoneEnums::FriendCapability &data) {
return static_cast<linphone::Friend::Capability>(data);
}
@ -177,6 +202,31 @@ LinphoneEnums::ConferenceLayout LinphoneEnums::fromLinphone(const linphone::Conf
return static_cast<LinphoneEnums::ConferenceLayout>(layout);
}
QString LinphoneEnums::toString(LinphoneEnums::ConferenceLayout layout) {
if (layout == LinphoneEnums::ConferenceLayout::ActiveSpeaker) return QObject::tr("Participant actif");
else if (layout == LinphoneEnums::ConferenceLayout::Grid) return QObject::tr("Grille");
else return QObject::tr("Audio seulement");
}
QVariantList LinphoneEnums::conferenceLayoutsToVariant(QList<LinphoneEnums::ConferenceLayout> list) {
QVariantList variantList;
for (auto &item : list)
variantList.append(LinphoneEnums::toVariant(item));
return variantList;
}
QVariantMap LinphoneEnums::toVariant(LinphoneEnums::ConferenceLayout layout) {
QVariantMap map;
if (layout == LinphoneEnums::ConferenceLayout::ActiveSpeaker) {
map.insert("id", QVariant::fromValue(layout));
map.insert("display_name", toString(layout));
} else {
map.insert("id", QVariant::fromValue(layout));
map.insert("display_name", toString(layout));
}
return map;
}
linphone::ConferenceInfo::State LinphoneEnums::toLinphone(const LinphoneEnums::ConferenceInfoState &state) {
return static_cast<linphone::ConferenceInfo::State>(state);
}

View file

@ -45,6 +45,9 @@ Q_ENUM_NS(MediaEncryption)
linphone::MediaEncryption toLinphone(const LinphoneEnums::MediaEncryption &encryption);
LinphoneEnums::MediaEncryption fromLinphone(const linphone::MediaEncryption &encryption);
QString toString(LinphoneEnums::MediaEncryption encryption);
QVariantList mediaEncryptionsToVariant(QList<MediaEncryption> list = {MediaEncryption::None, MediaEncryption::Srtp,
MediaEncryption::Zrtp, MediaEncryption::Dtls});
QVariantMap toVariant(LinphoneEnums::MediaEncryption encryption);
enum class FriendCapability {
None = int(linphone::Friend::Capability::None),
@ -220,6 +223,10 @@ Q_ENUM_NS(ConferenceLayout)
linphone::Conference::Layout toLinphone(const LinphoneEnums::ConferenceLayout &layout);
LinphoneEnums::ConferenceLayout fromLinphone(const linphone::Conference::Layout &layout);
QVariantList conferenceLayoutsToVariant(QList<ConferenceLayout> list = {ConferenceLayout::Grid,
ConferenceLayout::ActiveSpeaker});
QVariantMap toVariant(LinphoneEnums::ConferenceLayout layout);
QString toString(LinphoneEnums::ConferenceLayout layout);
enum class ConferenceInfoState {
New = int(linphone::ConferenceInfo::State::New),

View file

@ -115,6 +115,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
view/Page/Layout/Settings/AccountSettingsParametersLayout.qml
view/Page/Layout/Settings/CallSettingsLayout.qml
view/Page/Layout/Settings/ContactsSettingsLayout.qml
view/Page/Layout/Settings/MeetingsSettingsLayout.qml
view/Page/Layout/Settings/ContactsSettingsProviderLayout.qml
view/Page/Layout/Settings/DebugSettingsLayout.qml
view/Page/Layout/Settings/LdapSettingsLayout.qml

View file

@ -17,12 +17,12 @@ FocusScope {
anchors.leftMargin: 17 * DefaultStyle.dp
anchors.rightMargin: 17 * DefaultStyle.dp
spacing: 12 * DefaultStyle.dp
Text {
Layout.fillWidth: true
text: qsTr("La disposition choisie sera enregistrée pour vos prochaines réunions")
font.pixelSize: 14 * DefaultStyle.dp
color: DefaultStyle.main2_500main
}
// Text {
// Layout.fillWidth: true
// text: qsTr("La disposition choisie sera enregistrée pour vos prochaines réunions")
// font.pixelSize: 14 * DefaultStyle.dp
// color: DefaultStyle.main2_500main
// }
RoundedPane {
Layout.fillWidth: true
contentItem: ColumnLayout {

View file

@ -9,11 +9,7 @@ import SettingsCpp
AbstractSettingsMenu {
layoutsPath: "qrc:/qt/qml/Linphone/view/Page/Layout/Settings"
titleText: qsTr("Mon compte")
property AccountProxy accounts: AccountProxy {
id: accountProxy
sourceModel: AppCpp.accounts
}
property AccountGui account: accountProxy.defaultAccount
property AccountGui account
signal accountRemoved()
families: [
{title: qsTr("Général"), layout: "AccountSettingsGeneralLayout", model: account},

View file

@ -9,10 +9,9 @@ AbstractSettingsMenu {
titleText: qsTr("Paramètres")
families: [
{title: qsTr("Appels"), layout: "CallSettingsLayout"},
//{title: qsTr("Sécurité"), layout: "SecuritySettingsLayout"},
{title: qsTr("Conversations"), layout: "ChatSettingsLayout", visible: !SettingsCpp.disableChatFeature},
{title: qsTr("Contacts"), layout: "ContactsSettingsLayout"},
//{title: qsTr("Réunions"), layout: "MeetingsSettingsLayout", visible: !SettingsCpp.disableMeetingsFeature},
{title: qsTr("Réunions"), layout: "MeetingsSettingsLayout", visible: !SettingsCpp.disableMeetingsFeature},
//{title: qsTr("Affichage"), layout: "DisplaySettingsLayout"},
{title: qsTr("Réseau"), layout: "NetworkSettingsLayout"},
{title: qsTr("Paramètres avancés"), layout: "AdvancedSettingsLayout"}

View file

@ -21,6 +21,11 @@ AbstractSettingsLayout {
contentComponent: remoteProvisioningComponent,
hideTopSeparator: true
},
{
title: qsTr("Sécurité / Chiffrement"),
subTitle: "",
contentComponent: securityComponent,
},
{
title: qsTr("Codecs audio"),
subTitle: "",
@ -82,6 +87,37 @@ AbstractSettingsLayout {
}
}
Component {
id: securityComponent
ColumnLayout {
spacing: 20 * DefaultStyle.dp
ColumnLayout {
spacing: 5 * DefaultStyle.dp
Text {
text: qsTr("Chiffrement du média")
font {
pixelSize: 14 * DefaultStyle.dp
weight: 700 * DefaultStyle.dp
}
}
ComboSetting {
Layout.fillWidth: true
Layout.preferredWidth: parent.width
entries: SettingsCpp.mediaEncryptions
propertyName: "mediaEncryption"
textRole: 'display_name'
propertyOwner: SettingsCpp
}
}
SwitchSetting {
Layout.fillWidth: true
titleText: qsTr("Chiffrement du média obligatoire")
propertyName: "mediaEncryptionMandatory"
propertyOwner: SettingsCpp
}
}
}
// Audio codecs
//////////////

View file

@ -0,0 +1,49 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls.Basic as Control
import SettingsCpp 1.0
import Linphone
AbstractSettingsLayout {
id: mainItem
width: parent?.width
contentModel: [
{
title: qsTr("Affichage"),
subTitle: "",
contentComponent: confDisplayParametersComponent,
hideTopMargin: true
}
]
Component {
id: confDisplayParametersComponent
ColumnLayout {
spacing: 5 * DefaultStyle.dp
Text {
text: qsTr("Mode daffichage par défaut")
font {
pixelSize: 14 * DefaultStyle.dp
weight: 700 * DefaultStyle.dp
}
}
Text {
text: qsTr("Le mode daffichage des participants en réunions")
font {
pixelSize: 14 * DefaultStyle.dp
weight: 400 * DefaultStyle.dp
}
}
ComboSetting {
Layout.fillWidth: true
Layout.topMargin: 12 * DefaultStyle.dp
Layout.preferredWidth: parent.width
entries: SettingsCpp.conferenceLayouts
propertyName: "conferenceLayout"
propertyOwner: SettingsCpp
textRole: 'display_name'
}
}
}
}

View file

@ -26,4 +26,4 @@ AbstractSettingsLayout {
}
}
}
}
}