From 311b8eec1ac0bb00ff3567ec69c43e5b92b47123 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Fri, 29 Mar 2024 14:33:53 +0100 Subject: [PATCH] Crash fix and behavior on URI handlers (fetching provisionning and call) --- CHANGELOG.md | 3 +- linphone-app/src/app/App.cpp | 113 ++++++++++-------- linphone-app/src/app/App.hpp | 2 +- .../src/components/core/CoreManager.cpp | 11 +- .../components/history/CallHistoryModel.cpp | 3 +- 5 files changed, 73 insertions(+), 59 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3359cf611..e3c395b64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 5.2.3 - Undefined +## 5.2.3 - 2024-03-29 ### Fixed - Call logs : incoming filter will not display missed calls. - Call logs synchronization. +- URI handlers when mixing remote provisioning and call. ## 5.2.2 - 2024-03-11 diff --git a/linphone-app/src/app/App.cpp b/linphone-app/src/app/App.cpp index 26f34a21f..7bcbc6316 100644 --- a/linphone-app/src/app/App.cpp +++ b/linphone-app/src/app/App.cpp @@ -222,11 +222,11 @@ QString App::getFetchConfig(QCommandLineParser *parser) { return filePath; } -void App::useFetchConfig(const QString &filePath) { +bool App::useFetchConfig(const QString &filePath) { if (!filePath.isEmpty()) { if (CoreManager::getInstance()->isInitialized()) { if (CoreManager::getInstance()->getSettingsModel()->getAutoApplyProvisioningConfigUriHandlerEnabled()) - setFetchConfig(filePath); + return setFetchConfig(filePath); else emit requestFetchConfig(filePath); } else { QObject *context = new QObject(); @@ -237,6 +237,7 @@ void App::useFetchConfig(const QString &filePath) { }); } } + return false; } bool App::setFetchConfig(QString filePath) { @@ -253,8 +254,11 @@ bool App::setFetchConfig(QString filePath) { } } if (!fetched) { - qWarning() << "Remote provisionning cannot be retrieved. Command have beend cleaned"; - } else restart(); + qWarning() << "Remote provisioning cannot be retrieved. Command have beend cleaned"; + } else { + qInfo() << "Restarting to apply remote provisioning"; + restart(); + } return fetched; } // ----------------------------------------------------------------------------- @@ -547,20 +551,6 @@ void App::initContentApp() { openAppAfterInit(mustBeIconified); } }); - - // Execute command argument if needed - // Commands are executed only once. clearPsitionalArguments doesn't work as its name suggest : - // getPositionalArguments still retrieve user arguments. So execute the command only once. - static bool firstRun = false; - if (!firstRun) { - firstRun = true; - const QString commandArgument = getCommandArgument(); - if (!commandArgument.isEmpty()) { - Cli::CommandFormat format; - Cli::executeCommand(commandArgument, &format); - if (format == Cli::UriFormat || format == Cli::UrlFormat) mustBeIconified = true; - } - } } // ----------------------------------------------------------------------------- @@ -961,14 +951,13 @@ void App::initLocale(const shared_ptr &config) { // QStringList qtLocale = QLocale::system().name().split('_'); // if(qtLocale[0] != preferredLanguage){ // qInfo() << "Override Qt language from " << qtLocale[0] << " to the preferred language : " << - //preferredLanguage; qtLocale[0] = preferredLanguage; + // preferredLanguage; qtLocale[0] = preferredLanguage; // } // QLocale sysLocale = QLocale(qtLocale.join('_')); // #else - QLocale sysLocale( - QLocale::system().name()); // Use Locale from name because Qt has a bug where it didn't use the - // QLocale::language (aka : translator.language != locale.language) on Mac. - // #endif + QLocale sysLocale(QLocale::system().name()); // Use Locale from name because Qt has a bug where it didn't use the + // QLocale::language (aka : translator.language != locale.language) on + // Mac. #endif if (installLocale(*this, *mTranslator, sysLocale)) { mLocale = sysLocale; return; @@ -1177,40 +1166,60 @@ void App::openAppAfterInit(bool mustBeIconified) { checkForUpdates(); #endif // ifdef ENABLE_UPDATE_CHECK - // Launch call if wanted and clean parser - if (mParser->isSet("call") && coreManager->isLastRemoteProvisioningGood()) { - QString sipAddress = mParser->value("call"); - mParser->parse(cleanParserKeys(mParser, QStringList("call"))); // Clean call from parser - if (coreManager->started()) { - coreManager->getCallsListModel()->launchAudioCall(sipAddress); - } else { - QObject *context = new QObject(); - QObject::connect(CoreManager::getInstance(), &CoreManager::coreManagerInitialized, context, - [sipAddress, coreManager, context]() mutable { - if (context) { - delete context; - context = nullptr; - coreManager->getCallsListModel()->launchAudioCall(sipAddress); - } - }); - } - } QString fetchFilePath = getFetchConfig(mParser); - mustBeIconified = mustBeIconified && fetchFilePath.isEmpty(); + mustBeIconified = + mustBeIconified && + (fetchFilePath.isEmpty() || + CoreManager::getInstance()->getSettingsModel()->getAutoApplyProvisioningConfigUriHandlerEnabled()); + bool showWindow = true; + if (fetchFilePath.isEmpty()) { + QString lastRunningVersion = CoreManager::getInstance()->getSettingsModel()->getLastRunningVersionOfApp(); + if (lastRunningVersion != "unknown" && lastRunningVersion != applicationVersion()) { + emit CoreManager::getInstance()->userInitiatedVersionUpdateCheckResult(3, "", ""); + } + CoreManager::getInstance()->getSettingsModel()->setLastRunningVersionOfApp(applicationVersion()); + // Launch call if wanted and clean parser + if (mParser->isSet("call") && coreManager->isLastRemoteProvisioningGood()) { + QString sipAddress = mParser->value("call"); + mParser->parse(cleanParserKeys(mParser, QStringList("call"))); // Clean call from parser + if (coreManager->started()) { + coreManager->getCallsListModel()->launchAudioCall(sipAddress); + } else { + QObject *context = new QObject(); + QObject::connect(CoreManager::getInstance(), &CoreManager::coreManagerInitialized, context, + [sipAddress, coreManager, context]() mutable { + if (context) { + delete context; + context = nullptr; + coreManager->getCallsListModel()->launchAudioCall(sipAddress); + } + }); + } + } else { + // Execute command argument if needed + // Commands are executed only once. clearPsitionalArguments doesn't work as its name suggest : + // getPositionalArguments still retrieve user arguments. So execute the command only once. + static bool firstRun = false; + if (!firstRun) { + firstRun = true; + const QString commandArgument = getCommandArgument(); + if (!commandArgument.isEmpty()) { + Cli::CommandFormat format; + Cli::executeCommand(commandArgument, &format); + if (format == Cli::UriFormat || format == Cli::UrlFormat) mustBeIconified = true; + } + } + } + } else showWindow = !useFetchConfig(fetchFilePath); + if (showWindow) { #ifndef __APPLE__ - if (!mustBeIconified) smartShowWindow(mainWindow); + if (!mustBeIconified) smartShowWindow(mainWindow); #else - Q_UNUSED(mustBeIconified); - smartShowWindow(mainWindow); + Q_UNUSED(mustBeIconified); + smartShowWindow(mainWindow); #endif - setOpened(true); - useFetchConfig(fetchFilePath); - - QString lastRunningVersion = CoreManager::getInstance()->getSettingsModel()->getLastRunningVersionOfApp(); - if (lastRunningVersion != "unknown" && lastRunningVersion != applicationVersion()) { - emit CoreManager::getInstance()->userInitiatedVersionUpdateCheckResult(3, "", ""); + setOpened(true); } - CoreManager::getInstance()->getSettingsModel()->setLastRunningVersionOfApp(applicationVersion()); } // ----------------------------------------------------------------------------- diff --git a/linphone-app/src/app/App.hpp b/linphone-app/src/app/App.hpp index eadfa4844..0aa851d15 100644 --- a/linphone-app/src/app/App.hpp +++ b/linphone-app/src/app/App.hpp @@ -68,7 +68,7 @@ public: QString getFetchConfig(QString filePath, bool *error); QString getFetchConfig(QCommandLineParser *parser); // Return file path of fetch-config - void useFetchConfig(const QString &filePath); // Check if the fetch is auto or not and make gui request if needed. + bool useFetchConfig(const QString &filePath); // Check if the fetch is auto or not and make gui request if needed. Q_INVOKABLE bool setFetchConfig(QString filePath); // return true if filepath has been set. #ifdef Q_OS_MACOS diff --git a/linphone-app/src/components/core/CoreManager.cpp b/linphone-app/src/components/core/CoreManager.cpp index ba6b659cd..f65508eea 100644 --- a/linphone-app/src/components/core/CoreManager.cpp +++ b/linphone-app/src/components/core/CoreManager.cpp @@ -79,6 +79,7 @@ CoreManager::CoreManager (QObject *parent, const QString &configPath) : QObject::connect(coreHandlers, &CoreHandlers::logsUploadStateChanged, this, &CoreManager::handleLogsUploadStateChanged); QObject::connect(coreHandlers, &CoreHandlers::callLogUpdated, this, &CoreManager::callLogsCountChanged); QObject::connect(coreHandlers, &CoreHandlers::eventCountChanged, this, &CoreManager::eventCountChanged); + connect(this, &CoreManager::coreManagerInitialized, this, &CoreManager::eventCountChanged); QTimer::singleShot(10, [this, configPath](){// Delay the creation in order to have the CoreManager instance set before createLinphoneCore(configPath); @@ -100,6 +101,7 @@ void CoreManager::initCoreManager(){ mAccountSettingsModel = new AccountSettingsModel(this); connect(this, &CoreManager::eventCountChanged, mAccountSettingsModel, &AccountSettingsModel::missedCallsCountChanged); connect(this, &CoreManager::eventCountChanged, mAccountSettingsModel, &AccountSettingsModel::unreadMessagesCountChanged); + mSettingsModel = new SettingsModel(this); mEmojisSettingsModel = new EmojisSettingsModel(this); mCallsListModel = new CallsListModel(this); @@ -114,7 +116,6 @@ void CoreManager::initCoreManager(){ qInfo() << QStringLiteral("CoreManager initialized"); emit coreManagerInitialized(); - emit eventCountChanged(); } bool CoreManager::isInitialized() const{ @@ -422,9 +423,11 @@ void CoreManager::startIterate(){ void CoreManager::stopIterate(){ qInfo() << QStringLiteral("Stop iterate"); - mCbsTimer->stop(); - mCbsTimer->deleteLater();// allow the timer to continue its stuff - mCbsTimer = nullptr; + if(mCbsTimer){ + mCbsTimer->stop(); + mCbsTimer->deleteLater();// allow the timer to continue its stuff + mCbsTimer = nullptr; + } } void CoreManager::iterate () { diff --git a/linphone-app/src/components/history/CallHistoryModel.cpp b/linphone-app/src/components/history/CallHistoryModel.cpp index 2bf986f48..5550cc29b 100644 --- a/linphone-app/src/components/history/CallHistoryModel.cpp +++ b/linphone-app/src/components/history/CallHistoryModel.cpp @@ -80,7 +80,8 @@ void CallHistoryModel::update(const std::shared_ptr callLog){ callDate = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000); } if(callDate >= mLastCallDate){ - setLastCallStatus(LinphoneEnums::fromLinphone(callLog->getStatus())); + setLastCallStatus(LinphoneEnums::fromLinphone(callLog->getStatus())); + setLastCallIsOutgoing(callLog->getDir() == linphone::Call::Dir::Outgoing); if(mShowEnd && mLastCallStatus == LinphoneEnums::CallStatusSuccess){ setLastCallDate(QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000)); setLastCallIsStart(false);