diff --git a/Linphone/core/account/AccountGui.cpp b/Linphone/core/account/AccountGui.cpp index 5e50d52fe..7ec4c92fa 100644 --- a/Linphone/core/account/AccountGui.cpp +++ b/Linphone/core/account/AccountGui.cpp @@ -24,10 +24,10 @@ DEFINE_ABSTRACT_OBJECT(AccountGui) AccountGui::AccountGui(QSharedPointer core) { - mustBeInMainThread(getClassName()); qDebug() << "[AccountGui] new" << this; App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); mCore = core; + if (isInLinphoneThread()) moveToThread(App::getInstance()->thread()); } AccountGui::~AccountGui() { diff --git a/Linphone/core/account/AccountList.cpp b/Linphone/core/account/AccountList.cpp index 09b9e1c8a..cbed1c2c3 100644 --- a/Linphone/core/account/AccountList.cpp +++ b/Linphone/core/account/AccountList.cpp @@ -54,18 +54,19 @@ void AccountList::setSelf(QSharedPointer me) { &QObject::deleteLater); mModelConnection->makeConnect(this, &AccountList::lUpdate, [this]() { mModelConnection->invokeToModel([this]() { - QList> accounts; + QList> *accounts = new QList>(); // Model thread. mustBeInLinphoneThread(getClassName()); auto linphoneAccounts = CoreModel::getInstance()->getCore()->getAccountList(); for (auto it : linphoneAccounts) { auto model = AccountCore::create(it); - accounts.push_back(model); + accounts->push_back(model); } mModelConnection->invokeToCore([this, accounts]() { mustBeInMainThread(getClassName()); - clearData(); - add(accounts); + resetData(); + add(*accounts); + delete accounts; }); }); }); diff --git a/Linphone/core/call/CallGui.cpp b/Linphone/core/call/CallGui.cpp index 55edbd380..293341953 100644 --- a/Linphone/core/call/CallGui.cpp +++ b/Linphone/core/call/CallGui.cpp @@ -24,10 +24,10 @@ DEFINE_ABSTRACT_OBJECT(CallGui) CallGui::CallGui(QSharedPointer core) { - mustBeInMainThread(getClassName()); qDebug() << "[CallGui] new" << this; App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); mCore = core; + if (isInLinphoneThread()) moveToThread(App::getInstance()->thread()); } CallGui::~CallGui() { diff --git a/Linphone/model/object/VariantObject.cpp b/Linphone/model/object/VariantObject.cpp index 5a7e78a21..684cda536 100644 --- a/Linphone/model/object/VariantObject.cpp +++ b/Linphone/model/object/VariantObject.cpp @@ -37,8 +37,15 @@ VariantObject::VariantObject(QVariant defaultValue, QObject *parent) { new SafeConnection(mCoreObject.objectCast(), mModelObject.objectCast()), &QObject::deleteLater); - mConnection->makeConnect(mCoreObject.get(), &SafeObject::setValue, &SafeObject::onSetValue); - mConnection->makeConnect(mModelObject.get(), &SafeObject::setValue, &SafeObject::onSetValue); + mConnection->makeConnect(mCoreObject.get(), &SafeObject::setValue, [this](QVariant value) { + mConnection->invokeToModel([this, value]() { mModelObject->onSetValue(value); }); + }); + mConnection->makeConnect(mModelObject.get(), &SafeObject::setValue, [this](QVariant value) { + mConnection->invokeToCore([this, value]() { mCoreObject->onSetValue(value); }); + }); + mConnection->makeConnect(mModelObject.get(), &SafeObject::valueChanged, [this](QVariant value) { + mConnection->invokeToCore([this, value]() { mCoreObject->valueChanged(value); }); + }); connect(mCoreObject.get(), &SafeObject::valueChanged, this, &VariantObject::valueChanged); } diff --git a/Linphone/model/tool/ToolModel.cpp b/Linphone/model/tool/ToolModel.cpp index 7f100a16a..bc80afe58 100644 --- a/Linphone/model/tool/ToolModel.cpp +++ b/Linphone/model/tool/ToolModel.cpp @@ -68,9 +68,9 @@ QString ToolModel::getDisplayName(QString address) { return displayName.isEmpty() ? address : displayName; } -QSharedPointer ToolModel::startAudioCall(const QString &sipAddress, - const QString &prepareTransfertAddress, - const QHash &headers) { +QSharedPointer ToolModel::createCall(const QString &sipAddress, + const QString &prepareTransfertAddress, + const QHash &headers) { bool waitRegistrationForCall = true; // getSettingsModel()->getWaitRegistrationForCall() std::shared_ptr core = CoreModel::getInstance()->getCore(); diff --git a/Linphone/model/tool/ToolModel.hpp b/Linphone/model/tool/ToolModel.hpp index 5e3f0bb49..5436acefd 100644 --- a/Linphone/model/tool/ToolModel.hpp +++ b/Linphone/model/tool/ToolModel.hpp @@ -39,9 +39,9 @@ public: static QString getDisplayName(const std::shared_ptr &address); static QString getDisplayName(QString address); - static QSharedPointer startAudioCall(const QString &sipAddress, - const QString &prepareTransfertAddress = "", - const QHash &headers = {}); + static QSharedPointer createCall(const QString &sipAddress, + const QString &prepareTransfertAddress = "", + const QHash &headers = {}); private: DECLARE_ABSTRACT_OBJECT diff --git a/Linphone/tool/AbstractObject.hpp b/Linphone/tool/AbstractObject.hpp index a97707fc5..162473e10 100644 --- a/Linphone/tool/AbstractObject.hpp +++ b/Linphone/tool/AbstractObject.hpp @@ -41,7 +41,9 @@ public: inline QString log() const { return QStringLiteral("[%1]: %2").arg(getClassName()).arg("%1"); } - + inline static bool isInLinphoneThread() { + return Thread::isInLinphoneThread(); + } inline static bool mustBeInLinphoneThread(const QString &context) { // For convenience : Alias to Thread return Thread::mustBeInLinphoneThread(context); } diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index 217a850cf..d4fc38318 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -50,13 +50,13 @@ VariantObject *Utils::getDisplayName(const QString &address) { return data; } -VariantObject *Utils::startAudioCall(const QString &sipAddress, - const QString &prepareTransfertAddress, - const QHash &headers) { +VariantObject *Utils::createCall(const QString &sipAddress, + const QString &prepareTransfertAddress, + const QHash &headers) { VariantObject *data = new VariantObject(QVariant()); // Scope : GUI data->makeRequest([sipAddress, prepareTransfertAddress, headers]() { - auto call = ToolModel::startAudioCall(sipAddress, prepareTransfertAddress, headers); + auto call = ToolModel::createCall(sipAddress, prepareTransfertAddress, headers); if (call) { return QVariant::fromValue(new CallGui(call)); } else return QVariant(); diff --git a/Linphone/tool/Utils.hpp b/Linphone/tool/Utils.hpp index f7f417be9..6a8dfa8cf 100644 --- a/Linphone/tool/Utils.hpp +++ b/Linphone/tool/Utils.hpp @@ -49,9 +49,9 @@ public: } Q_INVOKABLE static VariantObject *getDisplayName(const QString &address); - Q_INVOKABLE static VariantObject *startAudioCall(const QString &sipAddress, - const QString &prepareTransfertAddress = "", - const QHash &headers = {}); + Q_INVOKABLE static VariantObject *createCall(const QString &sipAddress, + const QString &prepareTransfertAddress = "", + const QHash &headers = {}); Q_INVOKABLE static VariantObject *haveAccount(); static inline QString coreStringToAppString(const std::string &str) { diff --git a/Linphone/tool/thread/Thread.cpp b/Linphone/tool/thread/Thread.cpp index 41a596d63..af126279d 100644 --- a/Linphone/tool/thread/Thread.cpp +++ b/Linphone/tool/thread/Thread.cpp @@ -33,12 +33,16 @@ void Thread::run() { if (result <= 0) toExit = true; } } +bool Thread::isInLinphoneThread() { + return QThread::currentThread() == CoreModel::getInstance()->thread(); +} bool Thread::mustBeInLinphoneThread(const QString &context) { - bool isLinphoneThread = QThread::currentThread() == CoreModel::getInstance()->thread(); + bool isLinphoneThread = isInLinphoneThread(); if (!isLinphoneThread) qCritical() << "[Thread] Not processing in Linphone thread from " << context; return isLinphoneThread; } + bool Thread::mustBeInMainThread(const QString &context) { bool isMainThread = QThread::currentThread() == App::getInstance()->thread(); if (!isMainThread) qCritical() << "[Thread] Not processing in Main thread from " << context; diff --git a/Linphone/tool/thread/Thread.hpp b/Linphone/tool/thread/Thread.hpp index d816e8e75..c3e40ca00 100644 --- a/Linphone/tool/thread/Thread.hpp +++ b/Linphone/tool/thread/Thread.hpp @@ -26,6 +26,7 @@ class Thread : public QThread { public: Thread(QObject *parent = nullptr); + static bool isInLinphoneThread(); static bool mustBeInLinphoneThread(const QString &context); static bool mustBeInMainThread(const QString &context); diff --git a/Linphone/view/Prototype/CallPrototype.qml b/Linphone/view/Prototype/CallPrototype.qml index a17cebd79..fd9ce1563 100644 --- a/Linphone/view/Prototype/CallPrototype.qml +++ b/Linphone/view/Prototype/CallPrototype.qml @@ -26,6 +26,10 @@ Window{ gc() } Component.onDestruction: gc() + Connections{ + target: call && call.core || null + onLastErrorMessageChanged: if(mainItem.call) errorMessageText.text=mainItem.call.core.lastErrorMessage + } ColumnLayout{ anchors.fill: parent RowLayout { @@ -69,8 +73,11 @@ Window{ id: accountStatus Layout.preferredWidth: 50 Layout.preferredHeight: 50 + property int accountCount: accountProxy.count + onAccountCountChanged: console.log("AccountCount:"+accountCount) property var defaultAccount: accountProxy.defaultAccount - property var state: accountProxy.count > 0 && defaultAccount? defaultAccount.registrationState : LoginPageCpp.registrationState + onDefaultAccountChanged: console.log("DefaultAccount:"+defaultAccount) + property var state: accountProxy.count > 0 && defaultAccount? defaultAccount.core.registrationState : LoginPageCpp.registrationState onStateChanged: console.log("State:"+state) color: state === LinphoneEnums.RegistrationState.Ok @@ -94,7 +101,9 @@ Window{ Button{ text: 'Call' onClicked: { - mainItem.callVarObject = UtilsCpp.startAudioCall(usernameToCall.inputText + "@sip.linphone.org") + var address = usernameToCall.text + "@sip.linphone.org" + console.log("Calling "+address) + mainItem.callVarObject = UtilsCpp.createCall(address) proto.component1 = comp } } @@ -123,7 +132,6 @@ Window{ } Text{ id: errorMessageText - text: mainItem.call ? mainItem.call.core.lastErrorMessage : '' color: 'red' } ItemPrototype{ diff --git a/external/linphone-sdk b/external/linphone-sdk index aaeaad94a..a9a7ff8bb 160000 --- a/external/linphone-sdk +++ b/external/linphone-sdk @@ -1 +1 @@ -Subproject commit aaeaad94a6e63f182f50318ed1a209c83b152d73 +Subproject commit a9a7ff8bb52d7535033b0cb60e2113b9ee377664