diff --git a/Linphone/core/notifier/AbstractNotificationBackend.cpp b/Linphone/core/notifier/AbstractNotificationBackend.cpp index 770059adb..e9e2cf4ec 100644 --- a/Linphone/core/notifier/AbstractNotificationBackend.cpp +++ b/Linphone/core/notifier/AbstractNotificationBackend.cpp @@ -1,10 +1,5 @@ #include "AbstractNotificationBackend.hpp" -#include -#include -#include -#include - DEFINE_ABSTRACT_OBJECT(AbstractNotificationBackend) const QHash AbstractNotificationBackend::Notifications = { @@ -13,26 +8,3 @@ const QHash AbstractNotification AbstractNotificationBackend::AbstractNotificationBackend(QObject *parent) : QObject(parent) { } - -QString AbstractNotificationBackend::getIconAsPng(const QString &imagePath, const QSize &size) { - // Convertit "image://internal/phone-disconnect.svg" en ":/data/image/phone-disconnect.svg" - QString resourcePath = imagePath; - if (imagePath.startsWith("image://internal/")) - resourcePath = ":/data/image/" + imagePath.mid(QString("image://internal/").length()); - - QSvgRenderer renderer(resourcePath); - if (!renderer.isValid()) return QString(); - - QImage image(size, QImage::Format_ARGB32_Premultiplied); - image.fill(Qt::transparent); - QPainter painter(&image); - renderer.render(&painter); - painter.end(); - - QString outPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/linphone_" + - QFileInfo(resourcePath).baseName() + ".png"; - - if (!QFile::exists(outPath)) image.save(outPath, "PNG"); - - return outPath; -} \ No newline at end of file diff --git a/Linphone/core/notifier/AbstractNotificationBackend.hpp b/Linphone/core/notifier/AbstractNotificationBackend.hpp index 033a77662..1d2a91f4b 100644 --- a/Linphone/core/notifier/AbstractNotificationBackend.hpp +++ b/Linphone/core/notifier/AbstractNotificationBackend.hpp @@ -23,8 +23,6 @@ public: AbstractNotificationBackend(QObject *parent = Q_NULLPTR); ~AbstractNotificationBackend() = default; - QString getIconAsPng(const QString &imagePath, const QSize &size = QSize(64, 64)); - enum NotificationType { ReceivedMessage, ReceivedCall diff --git a/Linphone/core/notifier/DesktopNotificationManagerCompat.cpp b/Linphone/core/notifier/DesktopNotificationManagerCompat.cpp index 5984722dc..2f481eeed 100644 --- a/Linphone/core/notifier/DesktopNotificationManagerCompat.cpp +++ b/Linphone/core/notifier/DesktopNotificationManagerCompat.cpp @@ -43,7 +43,7 @@ using namespace Microsoft::WRL::Wrappers; namespace DesktopNotificationManagerCompat { HRESULT RegisterComServer(GUID clsid, const wchar_t exePath[]); -HRESULT RegisterAumidInRegistry(const wchar_t *aumid); +HRESULT RegisterAumidInRegistry(const wchar_t *aumid, const wchar_t *iconPath = nullptr); HRESULT EnsureRegistered(); bool IsRunningAsUwp(); @@ -100,7 +100,7 @@ HRESULT CreateStartMenuShortcut(const wchar_t *aumid, GUID clsid) { return persistFile->Save(shortcutPath, TRUE); } -HRESULT RegisterAumidInRegistry(const wchar_t *aumid) { +HRESULT RegisterAumidInRegistry(const wchar_t *aumid, const wchar_t *iconPath) { std::wstring keyPath = std::wstring(L"Software\\Classes\\AppUserModelId\\") + aumid; HKEY key; @@ -114,11 +114,16 @@ HRESULT RegisterAumidInRegistry(const wchar_t *aumid) { res = ::RegSetValueExW(key, L"DisplayName", 0, REG_SZ, reinterpret_cast(displayName), static_cast((wcslen(displayName) + 1) * sizeof(wchar_t))); + if (iconPath != nullptr) { + res = ::RegSetValueExW(key, L"IconUri", 0, REG_SZ, reinterpret_cast(iconPath), + static_cast((wcslen(iconPath) + 1) * sizeof(wchar_t))); + } + ::RegCloseKey(key); return HRESULT_FROM_WIN32(res); } -HRESULT RegisterAumidAndComServer(const wchar_t *aumid, GUID clsid) { +HRESULT RegisterAumidAndComServer(const wchar_t *aumid, GUID clsid, const wchar_t *iconPath) { // If running as Desktop Bridge qDebug() << QString("CLSID : {%1-%2-%3-%4%5-%6%7%8%9%10%11}") .arg(clsid.Data1, 8, 16, QChar('0')) @@ -168,7 +173,7 @@ HRESULT RegisterAumidAndComServer(const wchar_t *aumid, GUID clsid) { RETURN_IF_FAILED(RegisterComServer(clsid, exePath)); qInfo() << "Register aumid in registry"; - RETURN_IF_FAILED(RegisterAumidInRegistry(aumid)); + RETURN_IF_FAILED(RegisterAumidInRegistry(aumid, iconPath)); s_registeredAumidAndComServer = true; return S_OK; diff --git a/Linphone/core/notifier/DesktopNotificationManagerCompat.hpp b/Linphone/core/notifier/DesktopNotificationManagerCompat.hpp index 5f731b089..9737a5c56 100644 --- a/Linphone/core/notifier/DesktopNotificationManagerCompat.hpp +++ b/Linphone/core/notifier/DesktopNotificationManagerCompat.hpp @@ -34,7 +34,7 @@ HRESULT CreateStartMenuShortcut(const wchar_t *aumid, GUID clsid); /// /// An AUMID that uniquely identifies your application. /// The CLSID of your NotificationActivator class. -HRESULT RegisterAumidAndComServer(const wchar_t *aumid, GUID clsid); +HRESULT RegisterAumidAndComServer(const wchar_t *aumid, GUID clsid, const wchar_t *iconPath = nullptr); /// /// Registers your module to handle COM activations. Call this upon application startup. diff --git a/Linphone/core/notifier/Notifier.cpp b/Linphone/core/notifier/Notifier.cpp index a06569b04..ea59e22bc 100644 --- a/Linphone/core/notifier/Notifier.cpp +++ b/Linphone/core/notifier/Notifier.cpp @@ -349,17 +349,19 @@ void Notifier::notifyReceivedCall(const shared_ptr &call) { auto callLog = call->getCallLog(); auto displayName = callLog && callLog->getConferenceInfo() ? Utils::coreStringToAppString(callLog->getConferenceInfo()->getSubject()) - : ToolModel::getDisplayName(call->getRemoteAddress()); + : ToolModel::getDisplayName(remoteAddress); + auto remoteAddrString = Utils::coreStringToAppString(remoteAddress->asStringUriOnly()); // Accessibility alert //: New call from %1 AccessibilityHelper::announceMessage(tr("new_call_alert_accessible_name").arg(displayName)); - App::postCoreAsync([this, gui, displayName]() { + App::postCoreAsync([this, gui, displayName, remoteAddrString]() { mustBeInMainThread(getClassName()); QVariantMap map; map["displayName"].setValue(displayName); + map["remoteAddress"].setValue(remoteAddrString); map["call"].setValue(gui); CREATE_NOTIFICATION(AbstractNotificationBackend::ReceivedCall, map) diff --git a/Linphone/core/notifier/SysTrayNotificationBackend.cpp b/Linphone/core/notifier/SysTrayNotificationBackend.cpp index c996c0dfa..dbcd0e9a4 100644 --- a/Linphone/core/notifier/SysTrayNotificationBackend.cpp +++ b/Linphone/core/notifier/SysTrayNotificationBackend.cpp @@ -79,7 +79,7 @@ uint NotificationBackend::sendCallNotification(QVariantMap data) { // Actions : paires (clé, label) QStringList actions = {"accept", tr("accept_button"), "decline", tr("decline_button")}; - QString appIcon = getIconAsPng(Utils::getAppIcon("logo").toString()); + QString appIcon = Utils::getIconAsPng(Utils::getAppIcon("logo").toString()); // QString appIcon = QString("call-start"); // icône freedesktop standard QDBusReply reply = mInterface->call(QString("Notify"), diff --git a/Linphone/core/notifier/WindowsNotificationBackend.cpp b/Linphone/core/notifier/WindowsNotificationBackend.cpp index 2be603804..a9cc4ef78 100644 --- a/Linphone/core/notifier/WindowsNotificationBackend.cpp +++ b/Linphone/core/notifier/WindowsNotificationBackend.cpp @@ -46,6 +46,7 @@ void NotificationBackend::sendMessageNotification(QVariantMap data) { auto remoteAddress = data["remoteAddress"].toString().toStdWString(); auto chatRoomName = data["chatRoomName"].toString().toStdWString(); auto chatRoomAddress = data["chatRoomAddress"].toString().toStdWString(); + auto appIcon = Utils::getIconAsPng(Utils::getAppIcon("logo").toString()).toStdWString(); auto avatarUri = data["avatarUri"].toString().toStdWString(); bool isGroup = data["isGroupChat"].toBool(); ChatGui *chat = data["chat"].value(); @@ -53,6 +54,9 @@ void NotificationBackend::sendMessageNotification(QVariantMap data) { std::wstring xml = L"" L" " L" " + L" " L" " @@ -82,7 +86,7 @@ void NotificationBackend::sendMessageNotification(QVariantMap data) { IToastNotification *toast = nullptr; hr = DesktopNotificationManagerCompat::CreateToastNotification(doc, &toast); if (FAILED(hr) || !toast) { - qWarning() << "CreateToastNotification failed:" << Qt::hex << hr; + lWarning() << "CreateToastNotification failed:" << Qt::hex << hr; doc->Release(); notifier->Release(); Utils::showInformationPopup(tr("info_popup_error_title"), tr("info_popup_error_creating_notification"), false); @@ -103,7 +107,7 @@ void NotificationBackend::sendMessageNotification(QVariantMap data) { hr = notifier->Show(toast); if (FAILED(hr)) { - qWarning() << "Toast Show failed:" << Qt::hex << hr; + lWarning() << "Toast Show failed:" << Qt::hex << hr; } toast->Release(); @@ -121,6 +125,7 @@ void NotificationBackend::sendCallNotification(QVariantMap data) { } auto displayName = data["displayName"].toString().toStdWString(); + auto remoteAddress = data["remoteAddress"].toString().toStdWString(); CallGui *call = data["call"].value(); int timeout = 2; // AbstractNotificationBackend::Notifications[(int)NotificationType::ReceivedCall].getTimeout(); @@ -129,8 +134,9 @@ void NotificationBackend::sendCallNotification(QVariantMap data) { auto callDescription = tr("incoming_call").toStdWString(); QList actions; - QString declineIcon = getIconAsPng(Utils::getAppIcon("endCall").toString()); - QString acceptIcon = getIconAsPng(Utils::getAppIcon("phone").toString()); + QString declineIcon = Utils::getIconAsPng(Utils::getAppIcon("endCall").toString()); + QString acceptIcon = Utils::getIconAsPng(Utils::getAppIcon("phone").toString()); + auto appIcon = Utils::getIconAsPng(Utils::getAppIcon("logo").toString()).toStdWString(); actions.append(ToastButton(tr("accept_button"), "accept", acceptIcon)); actions.append(ToastButton(tr("decline_button"), "decline", declineIcon)); std::wstring wActions; @@ -150,9 +156,15 @@ void NotificationBackend::sendCallNotification(QVariantMap data) { std::wstring xml = L"" L" " L" " + L" " L" " + displayName + L"" + L" " + + remoteAddress + + L"" L" " + callDescription + L"" @@ -173,7 +185,7 @@ void NotificationBackend::sendCallNotification(QVariantMap data) { IToastNotification *toast = nullptr; hr = DesktopNotificationManagerCompat::CreateToastNotification(doc, &toast); if (FAILED(hr) || !toast) { - qWarning() << "CreateToastNotification failed:" << Qt::hex << hr; + lWarning() << "CreateToastNotification failed:" << Qt::hex << hr; doc->Release(); notifier->Release(); Utils::showInformationPopup(tr("info_popup_error_title"), tr("info_popup_error_creating_notification"), false); @@ -182,12 +194,12 @@ void NotificationBackend::sendCallNotification(QVariantMap data) { ComPtr toast2; hr = toast->QueryInterface(IID_PPV_ARGS(&toast2)); - if (FAILED(hr)) qWarning() << "QueryInterface failed"; + if (FAILED(hr)) lWarning() << "QueryInterface failed"; auto callId = call->mCore->getCallId(); qDebug() << "put tag to toast" << callId; hr = toast2->put_Tag(HStringReference(reinterpret_cast(callId.utf16())).Get()); toast2->put_Group(HStringReference(L"linphone").Get()); - if (FAILED(hr)) qWarning() << "puting tag on toast failed"; + if (FAILED(hr)) lWarning() << "puting tag on toast failed"; connect(call->mCore.get(), &CallCore::stateChanged, this, [this, call, notifier, toast] { if (call->mCore->getState() == LinphoneEnums::CallState::End || @@ -201,7 +213,7 @@ void NotificationBackend::sendCallNotification(QVariantMap data) { auto hr = history->RemoveGroupedTag(reinterpret_cast(callId.utf16()), L"linphone"); if (FAILED(hr)) { - qWarning() << "removing toast failed"; + lWarning() << "removing toast failed"; } } }); @@ -248,7 +260,7 @@ void NotificationBackend::sendCallNotification(QVariantMap data) { hr = notifier->Show(toast); if (FAILED(hr)) { - qWarning() << "Toast Show failed:" << Qt::hex << hr; + lWarning() << "Toast Show failed:" << Qt::hex << hr; } toast->Release(); diff --git a/Linphone/main.cpp b/Linphone/main.cpp index 346482fde..d5dcc9afe 100644 --- a/Linphone/main.cpp +++ b/Linphone/main.cpp @@ -31,7 +31,7 @@ FILE *gStream = NULL; #define WIDEN2(x) L##x #define WIDEN(x) WIDEN2(x) -static const wchar_t *mAumid = WIDEN(APPLICATION_ID); +static const wchar_t *mAumid = WIDEN(APPLICATION_NAME); void cleanStream() { #ifdef _WIN32 @@ -69,13 +69,8 @@ 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)); + auto hr = DesktopNotificationManagerCompat::RegisterAumidAndComServer(mAumid, __uuidof(NotificationActivator)); if (FAILED(hr)) { qWarning() << "RegisterAumidAndComServer failed:" << Qt::hex << hr; } diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index e4f4f5b34..75cc26de4 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -46,15 +46,19 @@ #include #include #include +#include #include #include #include +#include #include #include #include #include #include #include +#include +#include #ifdef Q_OS_WIN #ifndef NOMINMAX @@ -1815,6 +1819,29 @@ QUrl Utils::getAppIcon(const QString &iconName) { return QQmlProperty::read(appIconsSingleton, iconName).value(); } +QString Utils::getIconAsPng(const QString &imagePath, const QSize &size) { + // Convertit "image://internal/phone-disconnect.svg" en ":/data/image/phone-disconnect.svg" + QString resourcePath = imagePath; + if (imagePath.startsWith("image://internal/")) + resourcePath = ":/data/image/" + imagePath.mid(QString("image://internal/").length()); + + QSvgRenderer renderer(resourcePath); + if (!renderer.isValid()) return QString(); + + QImage image(size, QImage::Format_ARGB32_Premultiplied); + image.fill(Qt::transparent); + QPainter painter(&image); + renderer.render(&painter); + painter.end(); + + QString outPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/linphone_" + + QFileInfo(resourcePath).baseName() + ".png"; + + if (!QFile::exists(outPath)) image.save(outPath, "PNG"); + + return outPath; +} + QColor Utils::getPresenceColor(LinphoneEnums::Presence presence) { mustBeInMainThread(sLog().arg(Q_FUNC_INFO)); QColor presenceColor = QColorConstants::Transparent; diff --git a/Linphone/tool/Utils.hpp b/Linphone/tool/Utils.hpp index 1af9b2a1a..f8f933f63 100644 --- a/Linphone/tool/Utils.hpp +++ b/Linphone/tool/Utils.hpp @@ -254,6 +254,7 @@ public: // Presence + static QString getIconAsPng(const QString &imagePath, const QSize &size = QSize(64, 64)); static QColor getDefaultStyleColor(const QString &colorName); static QUrl getAppIcon(const QString &iconName); static QUrl getRegistrationStateIcon(LinphoneEnums::RegistrationState state);