diff --git a/Linphone/core/App.cpp b/Linphone/core/App.cpp index 5ca546900..c80afd7f0 100644 --- a/Linphone/core/App.cpp +++ b/Linphone/core/App.cpp @@ -124,6 +124,8 @@ #if defined(Q_OS_WIN) #include "core/notifier/WindowsNotificationBackend.hpp" +#else +#include "core/notifier/SysTrayNotificationBackend.hpp" #endif DEFINE_ABSTRACT_OBJECT(App) diff --git a/Linphone/core/CMakeLists.txt b/Linphone/core/CMakeLists.txt index c8a54fa72..be3f844c6 100644 --- a/Linphone/core/CMakeLists.txt +++ b/Linphone/core/CMakeLists.txt @@ -135,6 +135,9 @@ if(WIN32) core/notifier/NotificationActivator.cpp core/notifier/DesktopNotificationManagerCompat.cpp core/notifier/WindowsNotificationBackend.cpp) +else() + list(APPEND _LINPHONEAPP_SOURCES + core/notifier/SysTrayNotificationBackend.cpp) endif() if(APPLE) list(APPEND _LINPHONEAPP_SOURCES core/event-count-notifier/EventCountNotifierMacOs.m) diff --git a/Linphone/core/notifier/AbstractNotificationBackend.hpp b/Linphone/core/notifier/AbstractNotificationBackend.hpp index 102f64322..779bcfbf7 100644 --- a/Linphone/core/notifier/AbstractNotificationBackend.hpp +++ b/Linphone/core/notifier/AbstractNotificationBackend.hpp @@ -43,10 +43,6 @@ public: }; protected: - virtual void sendNotification(const QString &title = QString(), - const QString &message = QString(), - const QList &actions = {}) = 0; - virtual void sendNotification(NotificationType type, QVariantMap data) = 0; static const QHash Notifications; diff --git a/Linphone/core/notifier/SysTrayNotificationBackend.cpp b/Linphone/core/notifier/SysTrayNotificationBackend.cpp new file mode 100644 index 000000000..944ca8c89 --- /dev/null +++ b/Linphone/core/notifier/SysTrayNotificationBackend.cpp @@ -0,0 +1,47 @@ +#include "tool/Utils.hpp" + +// #include "NotificationActivator.hpp" +#include "WindowsNotificationBackend.hpp" +#include "core/App.hpp" +#include "core/call/CallGui.hpp" +#include "core/chat/ChatGui.hpp" +#include "core/event-filter/LockEventFilter.hpp" +#include "tool/Utils.hpp" +#include + +NotificationBackend::NotificationBackend(QObject *parent) : AbstractNotificationBackend(parent) { + // connect(App::getInstance(), &App::sessionLockedChanged, this, [this] { + // if (!App::getInstance()->getSessionLocked()) { + // qDebug() << "Session unlocked, flush pending notifications"; + // flushPendingNotifications(); + // } + // }); +} + +void NotificationBackend::flushPendingNotifications() { + for (const auto ¬if : mPendingNotifications) { + sendNotification(notif.type, notif.data); + } + mPendingNotifications.clear(); +} + +void NotificationBackend::sendMessageNotification(QVariantMap data) { +} + +void NotificationBackend::sendCallNotification(QVariantMap data) { +} + +void NotificationBackend::sendNotification(NotificationType type, QVariantMap data) { + // if (App::getInstance()->getSessionLocked()) { + // mPendingNotifications.append({type, data}); + // return; + // } + switch (type) { + case NotificationType::ReceivedCall: + sendCallNotification(data); + break; + case NotificationType::ReceivedMessage: + sendMessageNotification(data); + break; + } +} diff --git a/Linphone/core/notifier/SysTrayNotificationBackend.hpp b/Linphone/core/notifier/SysTrayNotificationBackend.hpp new file mode 100644 index 000000000..c4a91be83 --- /dev/null +++ b/Linphone/core/notifier/SysTrayNotificationBackend.hpp @@ -0,0 +1,37 @@ +#ifndef SYSTRAYNOTIFICATIONBACKEND_HPP +#define SYSTRAYNOTIFICATIONBACKEND_HPP + +#include "AbstractNotificationBackend.hpp" +#include +#include +#include +#include + +class NotificationBackend : public AbstractNotificationBackend { + + Q_OBJECT +public: + struct PendingNotification { + NotificationType type; + QVariantMap data; + }; + + NotificationBackend(QObject *parent = nullptr); + ~NotificationBackend() = default; + + void sendCallNotification(QVariantMap data); + void sendMessageNotification(QVariantMap data); + + void sendNotification(NotificationType type, QVariantMap data) override; + + void flushPendingNotifications(); + +signals: + void toastButtonTriggered(const QString &arg); + void sessionLockedChanged(bool locked); + +private: + QList mPendingNotifications; +}; + +#endif // SYSTRAYNOTIFICATIONBACKEND_HPP diff --git a/Linphone/core/notifier/WindowsNotificationBackend.cpp b/Linphone/core/notifier/WindowsNotificationBackend.cpp index ad677f078..84a9cc693 100644 --- a/Linphone/core/notifier/WindowsNotificationBackend.cpp +++ b/Linphone/core/notifier/WindowsNotificationBackend.cpp @@ -37,98 +37,6 @@ void NotificationBackend::flushPendingNotifications() { mPendingNotifications.clear(); } -void NotificationBackend::sendNotification(const QString &title, - const QString &message, - const QList &actions) { - IToastNotifier *notifier = nullptr; - HRESULT hr = DesktopNotificationManagerCompat::CreateToastNotifier(¬ifier); - if (FAILED(hr) || !notifier) { - lWarning() << "CreateToastNotifier failed:" << Qt::hex << hr; - return; - } - - std::wstring wTitle = title.toStdWString(); - std::wstring wMessage = message.toStdWString(); - - std::wstring wActions; - if (!actions.isEmpty()) { - wActions += L""; - for (const auto &action : actions) { - std::wstring wLabel = action.label.toStdWString(); - std::wstring wArg = action.argument.toStdWString(); - wActions += L""; - } - wActions += L""; - } - - std::wstring xml = L"" - L" " - L" " - L" " + - wTitle + - L"" - L" " + - wMessage + - L"" - L" " - L" " + - wActions + L""; - - ABI::Windows::Data::Xml::Dom::IXmlDocument *doc = nullptr; - hr = DesktopNotificationManagerCompat::CreateXmlDocumentFromString(xml.c_str(), &doc); - if (FAILED(hr) || !doc) { - lWarning() << "CreateXmlDocumentFromString failed:" << Qt::hex << hr; - notifier->Release(); - return; - } - - IToastNotification *toast = nullptr; - hr = DesktopNotificationManagerCompat::CreateToastNotification(doc, &toast); - if (FAILED(hr) || !toast) { - qWarning() << "CreateToastNotification failed:" << Qt::hex << hr; - doc->Release(); - notifier->Release(); - return; - } - - EventRegistrationToken token; - toast->add_Activated(Microsoft::WRL::Callback>( - [this](IToastNotification *sender, IInspectable *args) -> HRESULT { - qInfo() << "Toast clicked!"; - // Cast args en IToastActivatedEventArgs - Microsoft::WRL::ComPtr activatedArgs; - HRESULT hr = args->QueryInterface(IID_PPV_ARGS(&activatedArgs)); - if (SUCCEEDED(hr)) { - HSTRING argumentsHString; - activatedArgs->get_Arguments(&argumentsHString); - - // Convertir HSTRING en wstring - UINT32 length; - const wchar_t *rawStr = WindowsGetStringRawBuffer(argumentsHString, &length); - std::wstring arguments(rawStr, length); - - qInfo() << "Toast activated with args:" << QString::fromStdWString(arguments); - emit toastActivated(QString::fromStdWString(arguments)); - - WindowsDeleteString(argumentsHString); - } - return S_OK; - }) - .Get(), - &token); - - hr = notifier->Show(toast); - lInfo() << "Show toast:" << Qt::hex << hr; - - if (FAILED(hr)) { - qWarning() << "Toast Show failed:" << Qt::hex << hr; - } - - toast->Release(); - doc->Release(); - notifier->Release(); -} - void NotificationBackend::sendMessageNotification(QVariantMap data) { IToastNotifier *notifier = nullptr; diff --git a/Linphone/core/notifier/WindowsNotificationBackend.hpp b/Linphone/core/notifier/WindowsNotificationBackend.hpp index ffdd565cb..f2f7c12ad 100644 --- a/Linphone/core/notifier/WindowsNotificationBackend.hpp +++ b/Linphone/core/notifier/WindowsNotificationBackend.hpp @@ -18,9 +18,6 @@ public: NotificationBackend(QObject *parent = nullptr); ~NotificationBackend() = default; - void sendNotification(const QString &title = QString(), - const QString &message = QString(), - const QList &actions = {}) override; void sendCallNotification(QVariantMap data); void sendMessageNotification(QVariantMap data); diff --git a/Linphone/main.cpp b/Linphone/main.cpp index add2193fc..346482fde 100644 --- a/Linphone/main.cpp +++ b/Linphone/main.cpp @@ -2,21 +2,21 @@ #ifdef _WIN32 #include +#include // CLSID_ShellLink +#include // IShellLinkW, IPropertyStore + FILE *gStream = NULL; +#include "core/notifier/DesktopNotificationManagerCompat.hpp" +#include "core/notifier/NotificationActivator.hpp" #include // StringFromCLSID, CoTaskMemFree #include // PKEY_AppUserModel_ID, PKEY_AppUserModel_ToastActivatorCLSID #include // InitPropVariantFromString, PropVariantClear -#include // CLSID_ShellLink -#include // IShellLinkW, IPropertyStore #endif #include "core/App.hpp" #include "core/logger/QtLogger.hpp" #include "core/path/Paths.hpp" -#include "core/notifier/DesktopNotificationManagerCompat.hpp" -#include "core/notifier/NotificationActivator.hpp" - #include #include #include @@ -59,6 +59,7 @@ int main(int argc, char *argv[]) { // HRESULT hrCom = CoInitializeEx(nullptr, COINIT_MULTITHREADED); // qInfo() << "CoInitializeEx result:" << Qt::hex << hrCom; +#if defined _WIN32 qInfo() << "Thread ID:" << GetCurrentThreadId(); APTTYPE aptBefore; APTTYPEQUALIFIER qualBefore; @@ -68,6 +69,18 @@ int main(int argc, char *argv[]) { HRESULT hrCom = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); qInfo() << "CoInitializeEx STA result:" << Qt::hex << hrCom; + auto hr = DesktopNotificationManagerCompat::CreateStartMenuShortcut(mAumid, __uuidof(NotificationActivator)); + if (FAILED(hr)) { + qWarning() << "CreateStartMenuShortcut failed:" << Qt::hex << hr; + } + + // Register AUMID and COM server (for a packaged app, this is a no-operation) + hr = DesktopNotificationManagerCompat::RegisterAumidAndComServer(L"Linphone", __uuidof(NotificationActivator)); + if (FAILED(hr)) { + qWarning() << "RegisterAumidAndComServer failed:" << Qt::hex << hr; + } +#endif + // Useful to share camera on Fullscreen (other context) or multiscreens lDebug() << "[Main] Setting ShareOpenGLContexts"; QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); @@ -83,23 +96,14 @@ int main(int argc, char *argv[]) { setlocale(LC_CTYPE, ".UTF8"); lDebug() << "[Main] Creating application"; - auto hr = DesktopNotificationManagerCompat::CreateStartMenuShortcut(mAumid, __uuidof(NotificationActivator)); - if (FAILED(hr)) { - qWarning() << "CreateStartMenuShortcut failed:" << Qt::hex << hr; - } - - // Register AUMID and COM server (for a packaged app, this is a no-operation) - hr = DesktopNotificationManagerCompat::RegisterAumidAndComServer(L"Linphone", __uuidof(NotificationActivator)); - if (FAILED(hr)) { - qWarning() << "RegisterAumidAndComServer failed:" << Qt::hex << hr; - } - auto app = QSharedPointer::create(argc, argv); +#if defined _WIN32 hr = DesktopNotificationManagerCompat::RegisterActivator(); if (FAILED(hr)) { qWarning() << "RegisterActivator failed:" << Qt::hex << hr; } +#endif #ifdef ACCESSBILITY_WORKAROUND QAccessible::installUpdateHandler(DummyUpdateHandler); diff --git a/Linphone/tool/thread/SafeConnection.hpp b/Linphone/tool/thread/SafeConnection.hpp index 86b333575..d7055f7a7 100644 --- a/Linphone/tool/thread/SafeConnection.hpp +++ b/Linphone/tool/thread/SafeConnection.hpp @@ -154,7 +154,6 @@ public: } bool tryLock() { - if (!this) return false; mLocker.lock(); auto coreLocked = mCore.lock(); auto modelLocked = mModel.lock();