Compare commits

...

8 commits

Author SHA1 Message Date
Sylvain Berfini
de99f1f69a Updated SDK 2025-05-16 09:48:14 +02:00
Gaelle Braud
6b02ebed39 update sdk 2025-05-14 10:06:47 +02:00
Gaelle Braud
490f5cdca1 fix #LINQT-1657 do not manipulate internal gains 2025-05-14 10:06:07 +02:00
Peio Rigaux
fb786c2a9d Fix windows signature return code, as we are using Invoke-Expression, and makes sure that this job doesn't prevent upload even when it fails 2025-05-13 18:04:32 +02:00
Gaelle Braud
23e32d1953 docker update : ubuntu 22.04, qt6.9.0
update gitlab ci file
2025-05-13 15:47:48 +02:00
Gaelle Braud
d025aaaeec changelog 2025-05-07 10:50:08 +02:00
Christophe Deschamps
faeed359fb German translations 2025-05-05 08:23:02 +00:00
Jehan Monnier
1e82f48839 Fix basic auth mode for oidc.
Make sure refresh token is optionnal
2025-04-30 13:14:19 +02:00
14 changed files with 5676 additions and 5438 deletions

View file

@ -0,0 +1,171 @@
.factorize_ubuntu2204: &docker_image_platform_and_runner_tag
tags: [ "docker" ]
image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-ubuntu-22-04-lts:$UBUNTU_2204_IMAGE_VERSION
ubuntu2204-ninja-gcc:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $DOCKER_UPDATE == null && $SKIP_LINUX == null
variables:
CMAKE_GENERATOR: Ninja
CMAKE_OPTIONS: -DENABLE_PQCRYPTO=ON
CC: gcc
CXX: g++
extends: .linux-desktop
<<: *docker_image_platform_and_runner_tag
#################################################
# Nightly
#################################################
ubuntu2204-makefile-gcc:
rules:
- !reference [.rules-merge-request-manual, rules]
- if: $NIGHTLY_MASTER
variables:
CMAKE_GENERATOR: Unix Makefiles
CMAKE_OPTIONS: -DENABLE_PQCRYPTO=ON
CC: gcc
CXX: g++
ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS
extends: .linux-desktop
<<: *docker_image_platform_and_runner_tag
ubuntu2204-ninja-clang:
rules:
- !reference [.rules-merge-request-manual, rules]
- if: $NIGHTLY_MASTER
variables:
CMAKE_OPTIONS: -DENABLE_DOC=ON -DENABLE_G729=ON -DENABLE_PQCRYPTO=ON -DENABLE_GPL_THIRD_PARTIES=ON
CMAKE_GENERATOR: Ninja
CC: clang
CXX: clang++
extends: .linux-desktop
allow_failure: true
<<: *docker_image_platform_and_runner_tag
ubuntu2204-ninja-clang-small:
rules:
- !reference [.rules-merge-request-manual, rules]
- if: $NIGHTLY_MASTER
variables:
CMAKE_OPTIONS: -DENABLE_VIDEO=NO -DENABLE_ADVANCED_IM=NO -DENABLE_DB_STORAGE=NO -DENABLE_PQCRYPTO=OFF
allow_failure: true
extends: ubuntu2204-ninja-clang
ubuntu2204-makefile-gcc:
rules:
- !reference [.rules-merge-request-manual, rules]
- if: $NIGHTLY_MASTER
- if: $DEPLOY_PLUGINS
variables:
CMAKE_OPTIONS: -DLINPHONE_BUILDER_SIGNING_IDENTITY=$GPG_SIGNING_KEYID -DENABLE_G729=ON -DENABLE_PQCRYPTO=ON -DENABLE_GPL_THIRD_PARTIES=ON
CMAKE_GENERATOR: Unix Makefiles
CC: gcc
CXX: g++
ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS
APPIMAGETOOL_SIGN_PASSPHRASE: $GPG_SIGNING_PASS
script:
- echo "$GPG_SIGNING_PUB" > file.key && sed -i 's/\r /\n/g' file.key && chmod 600 file.key
- gpg --import file.key
- rm -f file.key
- echo "$GPG_SIGNING_KEY" > file.key && sed -i 's/\r /\n/g' file.key && chmod 600 file.key
- base64 -w 0 file.key | base64 -d | gpg --import --no-tty --batch --yes
- rm -f file.key
- cmake --version
- export CC=$CC
- export CXX=$CXX
- mkdir -p build/OUTPUT
- echo $CI_BUILD_TYPE
- echo $CMAKE_GENERATOR
- echo $DEFAULT_LINUX_CMAKE_OPTIONS
- echo $CMAKE_SANITIZER_OPTIONS
- eval "$(qtchooser -qt=$QT_LINUX_VER -print-env)"
- export PATH=${QTTOOLDIR}:$PATH
- export Qt6_DIR=${QTLIBDIR}/cmake/Qt6
- echo "Using Qt $QT_LINUX_VER at ${QTLIBDIR}"
- cd build
- cmake .. -G "$CMAKE_GENERATOR" -DCMAKE_VERBOSE_MAKEFILE=ON -DLINPHONESDK_PLATFORM=Desktop -DCMAKE_BUILD_TYPE=$CI_BUILD_TYPE -DLINPHONEAPP_APPLICATION_NAME="$APPLICATION_NAME" -DLINPHONEAPP_EXECUABLE_NAME="$EXECUTABLE_NAME" $DEFAULT_LINUX_CMAKE_OPTIONS $CMAKE_OPTIONS $SCHEDULE_CMAKE_OPTIONS $CMAKE_SANITIZER_OPTIONS
- cmake --build . --target install --config $CI_BUILD_TYPE $LBC_NODEBUG_OPTIONS
extends: .linux-desktop
<<: *docker_image_platform_and_runner_tag
#################################################
# Package - Nightly
#################################################
ubuntu2204-makefile-gcc-package:
stage: package
tags: [ "docker" ]
image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-ubuntu-22-04-lts:$UBUNTU_2204_IMAGE_VERSION
dependencies: []
rules:
- !reference [.rules-merge-request-manual, rules]
- if: $NIGHTLY_MASTER
- if: $PACKAGE_LINUX
- if: $DEPLOY_LINUX
variables:
CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES -DLINPHONE_BUILDER_SIGNING_IDENTITY=$GPG_SIGNING_KEYID -DENABLE_G729=ON -DLINPHONE_SDK_MAKE_RELEASE_FILE_URL=$MAKE_RELEASE_FILE_URL/$LINUX_PLATFORM/$APP_FOLDER -DENABLE_PQCRYPTO=ON -DENABLE_GPL_THIRD_PARTIES=ON
CMAKE_GENERATOR: Unix Makefiles
CC: gcc
CXX: g++
APPIMAGETOOL_SIGN_PASSPHRASE: $GPG_SIGNING_PASS
extends: .linux-desktop
script:
- echo "$GPG_SIGNING_PUB" > file.key && sed -i 's/\r /\n/g' file.key && chmod 600 file.key
- gpg --import file.key
- rm -f file.key
- echo "$GPG_SIGNING_KEY" > file.key && sed -i 's/\r /\n/g' file.key && chmod 600 file.key
- base64 -w 0 file.key | base64 -d | gpg --import --no-tty --batch --yes
- rm -f file.key
- cmake --version
- export CC=$CC
- export CXX=$CXX
- mkdir -p build/OUTPUT
- echo $CI_BUILD_TYPE
- echo $CMAKE_GENERATOR
- echo $DEFAULT_LINUX_CMAKE_OPTIONS
- echo $CMAKE_SANITIZER_OPTIONS
- eval "$(qtchooser -qt=$QT_LINUX_VER -print-env)"
- export PATH=${QTTOOLDIR}:$PATH
- cd build
- cmake .. -G "$CMAKE_GENERATOR" -DCMAKE_VERBOSE_MAKEFILE=ON -DLINPHONESDK_PLATFORM=Desktop -DCMAKE_BUILD_TYPE=$CI_BUILD_TYPE -DLINPHONEAPP_APPLICATION_NAME="$APPLICATION_NAME" -DLINPHONEAPP_EXECUTABLE_NAME="$EXECUTABLE_NAME" $DEFAULT_LINUX_CMAKE_OPTIONS $CMAKE_OPTIONS $SCHEDULE_CMAKE_OPTIONS $CMAKE_SANITIZER_OPTIONS
- cmake --build . --target install --config $CI_BUILD_TYPE $LBC_NODEBUG_OPTIONS
artifacts:
paths:
- build/OUTPUT/*
expire_in: 1 week
#################################################
# Deploy - Nightly
#################################################
ubuntu2204-makefile-gcc-deploy:
stage: deploy
tags: [ "deploy" ]
needs:
- ubuntu2204-makefile-gcc-package
only:
variables:
- $NIGHTLY_MASTER
- $DEPLOY_LINUX
script:
- rsync -rlv --ignore-existing build/OUTPUT/Packages/*.AppImage $DEPLOY_SERVER:$UPLOAD_ROOT_PATH/$LINUX_PLATFORM/$APP_FOLDER
- |-
if [[ $MAKE_RELEASE_FILE_URL != "" ]]; then
rsync -rlv build/OUTPUT/Packages/RELEASE $DEPLOY_SERVER:$UPLOAD_ROOT_PATH/$LINUX_PLATFORM
rsync -rlv build/OUTPUT/Packages/RELEASE $MAIN_DEPLOY_SERVER:$UPLOAD_ROOT_PATH/$LINUX_PLATFORM
fi
ubuntu2204-makefile-gcc-plugins-deploy:
stage: deploy
tags: [ "deploy" ]
needs:
- ubuntu2204-makefile-gcc
only:
variables:
- $DEPLOY_PLUGINS
script:
- rsync -rlv --ignore-existing build/OUTPUT/plugins/app/*.so $DEPLOY_SERVER:$UPLOAD_ROOT_PATH/$LINUX_PLATFORM/$APP_FOLDER/plugins/

View file

@ -204,6 +204,7 @@ win64-ninja-vs2022-package-windows:
win64-codesigning:
stage: signing
allow_failure: true
extends:
- .windows-codesigning
needs:
@ -218,6 +219,7 @@ win64-codesigning:
script:
- cd build-desktop/OUTPUT/Packages/
- Invoke-Expression "& ${WINDOWS_SIGN_TOOL} sign /fd SHA256 /t ${WINDOWS_SIGN_TIMESTAMP_URL} /sha1 ${WINDOWS_SIGN_HASH} *.exe"
- 'if (-not ($LastExitCode -eq 0)) {throw "Error: Signature failed"}'
artifacts:
paths:
- build-desktop\OUTPUT\Packages\*

View file

@ -27,6 +27,7 @@ variables:
DEBIAN_10_IMAGE_VERSION: 20210217_python3
UBUNTU_ROLLING_IMAGE_VERSION: 20211012_add_qtwebview
UBUNTU_2004_IMAGE_VERSION: 20250226_qt6-8-0
UBUNTU_2204_IMAGE_VERSION: 20250512_qt6-9-0
workflow:
@ -50,7 +51,8 @@ include:
- '.gitlab-ci-files/rules.yml'
- '.gitlab-ci-files/linux-prepare.yml'
- '.gitlab-ci-files/linux-desktop.yml'
- '.gitlab-ci-files/linux-desktop-ubuntu-2004.yml'
# - '.gitlab-ci-files/linux-desktop-ubuntu-2004.yml'
- '.gitlab-ci-files/linux-desktop-ubuntu-2204.yml'
- '.gitlab-ci-files/windows-desktop.yml'
- '.gitlab-ci-files/macosx-desktop.yml'

33
CHANGELOG.md Normal file
View file

@ -0,0 +1,33 @@
# Change Log
All notable changes to this project will be documented in this file.
Group changes to describe their impact on the project, as follows:
Added for new features.
Changed for changes in existing functionality.
Deprecated for once-stable features removed in upcoming releases.
Removed for deprecated features removed in this release.
Fixed for any bug fixes.
Security to invite users to upgrade in case of vulnerabilities.
## [6.0.0] - 2025-04-17
6.0.0 release is a complete rework of Linphone Desktop, with only the call and contact list features availables
### Added
- Contacts trust: contacts for which all devices have been validated through a ZRTP call with SAS exchange are now highlighted with a blue circle (and with a red one in case of mistrust). That trust is now handled at contact level (instead of conversation level in previous versions).
- Security focus: security & trust is more visible than ever, and unsecure conversations & calls are even more visible than before.
- CardDAV: you can configure as many CardDAV servers you want to synchronize you contacts in Linphone (in addition or in replacement of native addressbook import).
- OpenID: when used with a SSO compliant SIP server (such as Flexisip), we support single-sign-on login.
- MWI support: display and allow to call your voicemail when you have new messages (if supported by your VoIP provider and properly configured in your account params).
- CCMP support: if you configure a CCMP server URL in your accounts params, it will be used when scheduling meetings & to fetch list of meetings you've organized/been invited to.
- Devices list: check on which device your sip.linphone.org account is connected and the last connection date & time (like on subscribe.linphone.org).
### Changed
- Separated threads: Contrary to previous versions, our SDK is now running in it's own thread, meaning it won't freeze the UI anymore in case of heavy work, thus reducing the number of ANR and greatly increasing the fluidity of the app.
- Asymmetrical video : you no longer need to send your own camera feed to receive the one from the remote end of the call, and vice versa.
- Call transfer: Blind & Attended call transfer have been merged into one: during a call, if you initiate a transfer action, either pick another call to do the attended transfer or select a contact from the list (you can input a SIP URI not already in the suggestions list) to start a blind transfer.
- Settings: a lot of them are gone, the one that are still there have been reworked to increase user friendliness.
- Default screen (between contacts, call history, conversations & meetings list) will change depending on where you were when the app was paused or killed, and you will return to that last visited screen on the next startup.
- Minimum supported Qt version is now 6.5.3
- Some settings have changed name and/or section in linphonerc file.

View file

@ -206,6 +206,13 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
mustBeInLinphoneThread(getClassName());
mSettingsModelConnection = SafeConnection<SettingsCore, SettingsModel>::create(me, SettingsModel::getInstance());
mSettingsModelConnection->makeConnectToModel(&SettingsModel::captureGraphRunningChanged, [this](bool running) {
mSettingsModelConnection->invokeToCore([this, running] {
mCaptureGraphRunning = running;
emit captureGraphRunningChanged(running);
});
});
// VFS
mSettingsModelConnection->makeConnectToModel(&SettingsModel::vfsEnabledChanged, [this](const bool enabled) {
mSettingsModelConnection->invokeToCore([this, enabled]() { setVfsEnabled(enabled); });

File diff suppressed because it is too large Load diff

View file

@ -81,15 +81,21 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
mOidc.setClientIdentifierSharedKey(clientSecret->getPassword().c_str());
}
QString scope = OIDCScope;
;
QSet<QByteArray> scopeTokens = {OIDCScope};
if (autorizationUrl.hasQuery()) {
QUrlQuery query(autorizationUrl);
if (query.hasQueryItem("scope")) {
scope = query.queryItemValue("scope");
auto scopeList = query.queryItemValue("scope").split(' ');
for (const auto &scopeItem : scopeList) {
scopeTokens.insert(scopeItem.toUtf8());
}
}
}
mOidc.setScope(scope);
#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
mOidc.setRequestedScopeTokens(scopeTokens);
#else
mOidc.setScope(QStringList(scopeTokens.begin(), scopeTokens.end()).join(' '));
#endif
mTimeout.setInterval(1000 * 60 * 2); // 2minutes
connect(&mTimeout, &QTimer::timeout, [this]() {
@ -189,6 +195,30 @@ OIDCModel::OIDCModel(const std::shared_ptr<linphone::AuthInfo> &authInfo, QObjec
connect(this, &OIDCModel::authenticated, this, &OIDCModel::setBearers);
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
// Connect the signal to the tokensReceived handler to get id_token
connect(mOidc.replyHandler(), &QOAuthHttpServerReplyHandler::tokensReceived, this,
[this](const QVariantMap &tokens) {
// for (auto it = tokens.cbegin(); it != tokens.cend(); ++it) {
// qDebug() << "Token key:" << it.key() << ", value:" << it.value().toString();
// }
if (tokens.contains("id_token")) {
auto idToken = tokens["id_token"].toString();
qDebug() << "ID Token received:" << idToken.left(3) + "..." + idToken.right(3);
mIdToken = idToken;
} else if (tokens.contains("access_token")) {
auto accessToken = tokens["access_token"].toString();
qDebug() << "Access Token received:" << accessToken.left(3) + "..." + accessToken.right(3);
mIdToken = accessToken;
} else {
mIdToken.clear();
qWarning() << "No ID Token or Access Token found in the tokens.";
emit requestFailed(tr("oidc_authentication_no_token_found_error"));
emit finished();
}
});
#endif
// in case we want to add parameters. Needed to override redirect_url
mOidc.setModifyParametersFunction([&, username = Utils::coreStringToAppString(authInfo->getUsername())](
QAbstractOAuth::Stage stage, QMultiMap<QString, QVariant> *parameters) {
@ -244,7 +274,11 @@ void OIDCModel::openIdConfigReceived() {
return;
}
if (rootArray.contains("token_endpoint")) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
mOidc.setTokenUrl(QUrl(rootArray["token_endpoint"].toString()));
#else
mOidc.setAccessTokenUrl(QUrl(rootArray["token_endpoint"].toString()));
#endif
mAuthInfo->setTokenEndpointUri(
Utils::appStringToCoreString(QUrl(rootArray["token_endpoint"].toString()).toString()));
} else {
@ -262,13 +296,27 @@ void OIDCModel::setBearers() {
auto expiration = QDateTime::currentDateTime().secsTo(mOidc.expirationAt());
auto timeT = mOidc.expirationAt().toSecsSinceEpoch();
qDebug() << "Authenticated for " << expiration << "s";
auto refreshBearer =
linphone::Factory::get()->createBearerToken(Utils::appStringToCoreString(mOidc.refreshToken()), timeT);
auto accessBearer = linphone::Factory::get()->createBearerToken(Utils::appStringToCoreString(mOidc.token()), timeT);
mAuthInfo->setRefreshToken(refreshBearer);
auto accessBearer = linphone::Factory::get()->createBearerToken(Utils::appStringToCoreString(idToken()), timeT);
mAuthInfo->setAccessToken(accessBearer);
if (mOidc.refreshToken() != nullptr) {
auto refreshBearer =
linphone::Factory::get()->createBearerToken(Utils::appStringToCoreString(mOidc.refreshToken()), timeT);
mAuthInfo->setRefreshToken(refreshBearer);
} else {
qWarning() << "No refresh token found";
}
CoreModel::getInstance()->getCore()->addAuthInfo(mAuthInfo);
emit CoreModel::getInstance()->bearerAccountAdded();
emit CoreModel::getInstance() -> bearerAccountAdded();
emit finished();
}
QString OIDCModel::idToken() const {
#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
return mOidc.idToken().isEmpty() ? mOidc.token() : mOidc.idToken();
#else
return mIdToken;
#endif
}

View file

@ -44,11 +44,26 @@ signals:
void finished();
private:
/**
* @brief Retrieves the ID token.
*
* This function returns the ID token as a QString. The ID token is typically
* used for authentication and authorization purposes in OpenID Connect (OIDC)
* workflows. Implementation is specific to QT version
*
* @return The ID token as a QString.
*/
QString idToken() const;
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
QString mIdToken;
#endif
QOAuth2AuthorizationCodeFlow mOidc;
std::shared_ptr<linphone::AuthInfo> mAuthInfo;
QTimer mTimeout;
DECLARE_ABSTRACT_OBJECT
};
;
#endif

View file

@ -411,7 +411,7 @@ void CallModel::onStateChanged(const std::shared_ptr<linphone::Call> &call,
emit localVideoEnabledChanged(videoDirection == linphone::MediaDirection::SendOnly ||
videoDirection == linphone::MediaDirection::SendRecv);
emit remoteVideoEnabledChanged(remoteVideoDirection == linphone::MediaDirection::SendOnly ||
remoteVideoDirection == linphone::MediaDirection::SendRecv);
remoteVideoDirection == linphone::MediaDirection::SendRecv);
updateConferenceVideoLayout();
} else if (state == linphone::Call::State::End || state == linphone::Call::State::Error) {
mDurationTimer.stop();

View file

@ -116,15 +116,19 @@ void CoreModel::start() {
mCore->enableFriendListSubscription(true);
if (mCore->getLogCollectionUploadServerUrl().empty())
mCore->setLogCollectionUploadServerUrl(Constants::DefaultUploadLogsServer);
/// These 2 API should not be used as they manage internal gains insterad of those of the soundcard.
// Use playback/capture gain from capture graph and call only
mCore->setMicGainDb(0.0);
mCore->setPlaybackGainDb(0.0);
mIterateTimer->start();
auto linphoneSearch = mCore->createMagicSearch();
linphoneSearch->setLimitedSearch(true);
mMagicSearch = Utils::makeQObject_ptr<MagicSearchModel>(linphoneSearch);
mMagicSearch->setSelf(mMagicSearch);
connect(mMagicSearch.get(), &MagicSearchModel::searchResultsReceived, this, [this] {
emit magicSearchResultReceived(mMagicSearch->mLastSearch);
});
connect(mMagicSearch.get(), &MagicSearchModel::searchResultsReceived, this,
[this] { emit magicSearchResultReceived(mMagicSearch->mLastSearch); });
}
// -----------------------------------------------------------------------------
@ -352,10 +356,11 @@ void CoreModel::migrate() {
config->setInt(SettingsModel::UiSection, Constants::RcVersionName, Constants::RcVersionCurrent);
}
void CoreModel::searchInMagicSearch(QString filter, int sourceFlags,
LinphoneEnums::MagicSearchAggregation aggregation,
int maxResults) {
mMagicSearch->search(filter, sourceFlags, aggregation, maxResults);
void CoreModel::searchInMagicSearch(QString filter,
int sourceFlags,
LinphoneEnums::MagicSearchAggregation aggregation,
int maxResults) {
mMagicSearch->search(filter, sourceFlags, aggregation, maxResults);
}
//---------------------------------------------------------------------------------------------------------------------------

View file

@ -172,6 +172,7 @@ void SettingsModel::stopCaptureGraph() {
void SettingsModel::accessCallSettings() {
// Audio
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
startCaptureGraph();
CoreModel::getInstance()->getCore()->reloadSoundDevices();
emit captureDevicesChanged(getCaptureDevices());
emit playbackDevicesChanged(getPlaybackDevices());
@ -182,7 +183,6 @@ void SettingsModel::accessCallSettings() {
emit playbackGainChanged(getPlaybackGain());
emit captureGainChanged(getCaptureGain());
startCaptureGraph();
// Video
CoreModel::getInstance()->getCore()->reloadVideoDevices();
emit videoDevicesChanged(getVideoDevices());
@ -202,13 +202,12 @@ bool SettingsModel::getCaptureGraphRunning() {
float SettingsModel::getMicVolume() {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
float v = 0.0;
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
v = mSimpleCaptureGraph->getCaptureVolume();
} else {
auto call = CoreModel::getInstance()->getCore()->getCurrentCall();
if (call) {
v = MediastreamerUtils::computeVu(call->getRecordVolume());
v = call->getRecordVolume();
}
}
@ -218,33 +217,49 @@ float SettingsModel::getMicVolume() {
float SettingsModel::getPlaybackGain() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
float dbGain = CoreModel::getInstance()->getCore()->getPlaybackGainDb();
return MediastreamerUtils::dbToLinear(dbGain);
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
return mSimpleCaptureGraph->getPlaybackGain();
} else {
auto call = CoreModel::getInstance()->getCore()->getCurrentCall();
if (call) return call->getSpeakerVolumeGain();
else return 0.0;
}
}
void SettingsModel::setPlaybackGain(float gain) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
float oldGain = getPlaybackGain();
CoreModel::getInstance()->getCore()->setPlaybackGainDb(MediastreamerUtils::linearToDb(gain));
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
mSimpleCaptureGraph->setPlaybackGain(gain);
}
auto currentCall = CoreModel::getInstance()->getCore()->getCurrentCall();
if (currentCall) {
currentCall->setSpeakerVolumeGain(gain);
}
if ((int)(oldGain * 1000) != (int)(gain * 1000)) emit playbackGainChanged(gain);
}
float SettingsModel::getCaptureGain() const {
mustBeInLinphoneThread(getClassName());
float dbGain = CoreModel::getInstance()->getCore()->getMicGainDb();
return MediastreamerUtils::dbToLinear(dbGain);
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
return mSimpleCaptureGraph->getCaptureGain();
} else {
auto call = CoreModel::getInstance()->getCore()->getCurrentCall();
if (call) return call->getMicrophoneVolumeGain();
else return 0.0;
}
}
void SettingsModel::setCaptureGain(float gain) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
float oldGain = getCaptureGain();
CoreModel::getInstance()->getCore()->setMicGainDb(MediastreamerUtils::linearToDb(gain));
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
mSimpleCaptureGraph->setCaptureGain(gain);
}
auto currentCall = CoreModel::getInstance()->getCore()->getCurrentCall();
if (currentCall) {
currentCall->setMicrophoneVolumeGain(gain);
}
if ((int)(oldGain * 1000) != (int)(gain * 1000)) emit captureGainChanged(gain);
}

View file

@ -10,7 +10,7 @@ ARG QT6_VERSION=6.8.0
#Do not use it. It seems that it cannot be used from python command.
#ARG QT_MODULES=qtnetworkauth qtquick3d qtmultimedia
MAINTAINER Gaelle Braud <gaelle.braud@belledonne-communications.com>
LABEL Gaelle Braud <gaelle.braud@belledonne-communications.com>
# Use a Swiss mirror
RUN sed -i -E 's/(archive|security)\.ubuntu\.com/ch.archive.ubuntu.com/' /etc/apt/sources.list

View file

@ -0,0 +1,100 @@
###############################################################################
# Dockerfile used to make gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-ubuntu-20-04-lts:20231024_add_multimedia
###############################################################################
FROM ubuntu:22.04
# Qt on Ubuntu 22.04 is too old. Use a downloader.
ARG QT_VERSION=5.15.2
ARG QT6_VERSION=6.9.0
#Do not use it. It seems that it cannot be used from python command.
#ARG QT_MODULES=qtnetworkauth qtquick3d qtmultimedia
LABEL Gaelle Braud <gaelle.braud@belledonne-communications.com>
# Use a Swiss mirror
RUN sed -i -E 's/(archive|security)\.ubuntu\.com/ch.archive.ubuntu.com/' /etc/apt/sources.list
# add fallbacks for timeout connections.
#France
RUN echo "deb http://fr.archive.ubuntu.com/ubuntu/ jammy main restricted" >> /etc/apt/sources.list
RUN echo "deb http://security.ubuntu.com/ubuntu jammy-security main restricted" >> /etc/apt/sources.list
RUN echo "deb http://ch.archive.ubuntu.com/ubuntu/ jammy-updates main restricted" >> /etc/apt/sources.list
#Belgium
RUN echo "deb http://be.archive.ubuntu.com/ubuntu/ jammy main restricted" >> /etc/apt/sources.list
RUN echo "deb http://security.ubuntu.com/ubuntu jammy-security main restricted" >> /etc/apt/sources.list
RUN echo "deb http://be.archive.ubuntu.com/ubuntu/ jammy-updates main restricted" >> /etc/apt/sources.list
#International
RUN echo "deb http://archive.ubuntu.com/ubuntu/ jammy main restricted" >> /etc/apt/sources.list
RUN echo "deb http://security.ubuntu.com/ubuntu jammy-security main restricted" >> /etc/apt/sources.list
RUN echo "deb http://archive.ubuntu.com/ubuntu/ jammy-updates main restricted" >> /etc/apt/sources.list
# Configure locale
RUN apt-get update && \
apt-get install -y locales && \
apt-get clean && \
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
ENV TZ=Europe/Paris
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ARG DEBIAN_FRONTEND=noninteractive
ENV SHELL=/bin/bash
#ENV PS1='\[\e[33m\]\u@bc-dev-ubuntu-20-04>\[\e[0m\] '
# Install common general tools
RUN apt-get update && \
apt-get install -y nano sudo vim && \
apt-get clean
# Install development tools
RUN apt-get update && \
apt-get install -y alien at autoconf bison ccache clang doxygen elfutils g++ gdb git graphviz intltool libtool lsb-release make ninja-build openssh-client patch perl python3-pip python3-pystache python3-six python3-jsonschema python3-jinja2 meson yasm && \
apt-get clean
# Install linphone & flexisip dependencies development packages
RUN apt-get update && \
apt-get install -y libasound2-dev libavcodec-dev libavutil-dev libbsd-dev libegl1-mesa-dev libglew-dev libgsm1-dev libjansson-dev libmariadb-dev-compat libmbedtls-dev libopus-dev libpq-dev libprotobuf-dev libpulse-dev libqt5svg5-dev libsnmp-dev libspeex-dev libspeexdsp-dev libsqlite3-dev libsrtp2-dev libssl-dev libswscale-dev libturbojpeg0-dev libv4l-dev libvpx-dev libxerces-c-dev libxml2-dev libxv-dev protobuf-compiler qttools5-dev qttools5-dev-tools xsdcxx cmake nasm && \
apt-get clean
# Install signing tools
RUN sudo apt-get install -y gnupg2
# Install configuration tools
RUN sudo apt-get install -y wget
# Configure user bc
RUN useradd -ms /bin/bash bc && \
echo 'bc:cotcot' | chpasswd && \
echo 'bc ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
########### QT
RUN sudo apt-get update && sudo apt-get install -y libxkbcommon* flite1-dev libspeechd-dev speech-dispatcher libfontconfig1-dev libfreetype6-dev libx11-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libx11-xcb* libxcb* qdbus-qt5 libqt5dbus5 libdbus-1-dev libdbus-glib-1-dev libatspi2.0-0 libatspi2.0-dev
RUN sudo apt-get update && sudo apt-get install -y libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync0-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev
USER bc
WORKDIR /home/bc
# RUN sudo apt install python3-pip --upgrade -y
RUN sudo apt install --upgrade -y python3-importlib-metadata
RUN sudo apt install --upgrade -y python3-setuptools
# RUN sudo apt install python3-ez_setup
## Install Qt download tool
# installation is split because there is a way where some modules are not downloaded in the first attempt.
RUN sudo apt install -y python3-py7zr
RUN sudo pip3 install --upgrade aqtinstall
RUN sudo python3 -m aqt install-qt linux desktop $QT_VERSION -O /opt/Qt
RUN sudo python3 -m aqt install-qt linux desktop $QT_VERSION -O /opt/Qt --noarchives -m qtnetworkauth qtquick3d
RUN sudo python3 -m aqt install-qt linux desktop $QT6_VERSION -O /opt/Qt
RUN sudo python3 -m aqt install-qt linux desktop $QT6_VERSION -O /opt/Qt --noarchives -m qtnetworkauth qtquick3d qtmultimedia
RUN sudo chown -R bc:bc /opt/Qt/
RUN qtchooser -install $QT_VERSION /opt/Qt/$QT_VERSION/gcc_64/bin/qmake
RUN qtchooser -install $QT6_VERSION /opt/Qt/$QT6_VERSION/gcc_64/bin/qmake
CMD bash

@ -1 +1 @@
Subproject commit 96a6385bfdb3e6c0ed85df42bda99467e8f6fc5f
Subproject commit fe690e75c6ab33804c36079763c90d8e0cb84c08