Skip to content

Commit 946ee50

Browse files
committed
[Notification] [WIN] disable audio for toast notification, better fallback for toast notification, it immediately pass the failed message to the windows default bubble notification
1 parent 0cea837 commit 946ee50

File tree

3 files changed

+44
-9
lines changed

3 files changed

+44
-9
lines changed

src/nw_notification_manager_toast_win.cc

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ typedef ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notificat
106106
class ToastEventHandler :
107107
public Microsoft::WRL::Implements<DesktopToastActivatedEventHandler, DesktopToastDismissedEventHandler, DesktopToastFailedEventHandler> {
108108
public:
109-
ToastEventHandler::ToastEventHandler(const int render_process_id, const int notification_id);
109+
ToastEventHandler::ToastEventHandler(const int render_process_id, const int notification_id, const content::PlatformNotificationData& params, const SkBitmap& icon);
110110
~ToastEventHandler();
111111

112112
// DesktopToastActivatedEventHandler
@@ -150,12 +150,15 @@ class ToastEventHandler :
150150
private:
151151
ULONG _ref;
152152
const int _render_process_id, _notification_id;
153+
// _params and _icon is stored for fallback to bubble notification
154+
const content::PlatformNotificationData _params;
155+
const SkBitmap _icon;
153156
};
154157

155158
// ============= ToastEventHandler Implementation =============
156159

157-
ToastEventHandler::ToastEventHandler(const int render_process_id, const int notification_id) :
158-
_ref(0), _render_process_id(render_process_id), _notification_id(notification_id) {
160+
ToastEventHandler::ToastEventHandler(const int render_process_id, const int notification_id, const content::PlatformNotificationData& params, const SkBitmap& icon) :
161+
_ref(0), _render_process_id(render_process_id), _notification_id(notification_id), _params(params), _icon(icon) {
159162
}
160163

161164
ToastEventHandler::~ToastEventHandler() {
@@ -195,6 +198,7 @@ IFACEMETHODIMP ToastEventHandler::Invoke(_In_ IToastNotification* /* sender */,
195198
if (fallBack) {
196199
NotificationManagerToastWin::ForceDisable = true;
197200
delete nmtw;
201+
NotificationManager::getSingleton()->AddDesktopNotification(_params, _render_process_id, _notification_id, _icon);
198202
}
199203
return succeeded ? S_OK : E_FAIL;
200204
}
@@ -244,6 +248,30 @@ HRESULT NotificationManagerToastWin::SetTextValues(_In_reads_(textValuesCount) c
244248
return hr;
245249
}
246250

251+
HRESULT NotificationManagerToastWin::SilentAudio(_In_ IXmlDocument *toastXml) {
252+
ComPtr<IXmlNodeList> nodeList;
253+
HRESULT hr = toastXml->GetElementsByTagName(StringReferenceWrapper(L"toast").Get(), &nodeList);
254+
if (SUCCEEDED(hr)) {
255+
ComPtr<IXmlNode> toastNode;
256+
hr = nodeList->Item(0, &toastNode);
257+
if (SUCCEEDED(hr)) {
258+
ComPtr<IXmlElement> soundElement;
259+
hr = toastXml->CreateElement(StringReferenceWrapper(L"audio").Get(), &soundElement);
260+
if (SUCCEEDED(hr)) {
261+
hr = soundElement->SetAttribute(StringReferenceWrapper(L"silent").Get(), StringReferenceWrapper(L"true").Get());
262+
if (SUCCEEDED(hr)) {
263+
ComPtr<IXmlNode> soundNode, appendedSoundNode;
264+
hr = soundElement.As<IXmlNode>(&soundNode);
265+
if (SUCCEEDED(hr)) {
266+
hr = toastNode->AppendChild(soundNode.Get(), &appendedSoundNode);
267+
}
268+
}
269+
}
270+
}
271+
}
272+
return hr;
273+
}
274+
247275
HRESULT NotificationManagerToastWin::SetImageSrc(_In_z_ const wchar_t *imagePath, _In_ IXmlDocument *toastXml) {
248276
wchar_t imageSrc[MAX_PATH] = L"";
249277
HRESULT hr = StringCchCat(imageSrc, ARRAYSIZE(imageSrc), imagePath);
@@ -304,13 +332,16 @@ HRESULT NotificationManagerToastWin::CreateToastXml(_In_ IToastNotificationManag
304332
};
305333
UINT32 textLengths[] = { params.title.length(), params.body.length() };
306334
hr = SetTextValues(textValues, 2, textLengths, *inputXml);
335+
if (SUCCEEDED(hr)) {
336+
hr = SilentAudio(*inputXml);
337+
}
307338
}
308339
}
309340
return hr;
310341
}
311342

312343
HRESULT NotificationManagerToastWin::CreateToast(_In_ IToastNotificationManagerStatics *toastManager, _In_ IXmlDocument *xml,
313-
const int render_process_id, const int notification_id) {
344+
const int render_process_id, const int notification_id, const content::PlatformNotificationData& params, const SkBitmap& icon) {
314345
ComPtr<IToastNotificationFactory> factory;
315346
HRESULT hr = GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), &factory);
316347
if (SUCCEEDED(hr)) {
@@ -319,7 +350,7 @@ HRESULT NotificationManagerToastWin::CreateToast(_In_ IToastNotificationManagerS
319350
if (SUCCEEDED(hr)) {
320351
// Register the event handlers
321352
EventRegistrationToken activatedToken, dismissedToken, failedToken;
322-
ComPtr<ToastEventHandler> eventHandler = new ToastEventHandler(render_process_id, notification_id);
353+
ComPtr<ToastEventHandler> eventHandler = new ToastEventHandler(render_process_id, notification_id, params, icon);
323354

324355
hr = toast->add_Activated(eventHandler.Get(), &activatedToken);
325356
if (SUCCEEDED(hr)) {
@@ -384,7 +415,7 @@ bool NotificationManagerToastWin::AddDesktopNotification(const content::Platform
384415
ComPtr<IXmlDocument> toastXml;
385416
HRESULT hr = CreateToastXml(toastStatics_.Get(), params, icon, &toastXml);
386417
if (SUCCEEDED(hr)) {
387-
hr = CreateToast(toastStatics_.Get(), toastXml.Get(), render_process_id, notification_id);
418+
hr = CreateToast(toastStatics_.Get(), toastXml.Get(), render_process_id, notification_id, params, icon);
388419
if (SUCCEEDED(hr))
389420
DesktopNotificationPostDisplay(render_process_id, notification_id);
390421
}

src/nw_notification_manager_toast_win.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class NotificationManagerToastWin : public NotificationManager {
3939
static bool ForceDisable;
4040

4141
HRESULT CreateToast(_In_ IToastNotificationManagerStatics *toastManager, _In_ IXmlDocument *xml,
42-
const int render_process_id, const int notification_id);
42+
const int render_process_id, const int notification_id, const content::PlatformNotificationData& params, const SkBitmap& icon);
4343

4444
// Create the toast XML from a template
4545
HRESULT CreateToastXml(_In_ IToastNotificationManagerStatics *toastManager,
@@ -48,6 +48,9 @@ class NotificationManagerToastWin : public NotificationManager {
4848
// Set the value of the "src" attribute of the "image" node
4949
HRESULT SetImageSrc(_In_z_ const wchar_t *imagePath, _In_ IXmlDocument *toastXml);
5050

51+
// Set the value of the "silent" attribute of the "audio" node
52+
HRESULT SilentAudio( _In_ IXmlDocument *toastXml);
53+
5154
// Set the values of each of the text nodes
5255
HRESULT SetTextValues(_In_reads_(textValuesCount) const wchar_t **textValues, _In_ UINT32 textValuesCount,
5356
_In_reads_(textValuesCount) UINT32 *textValuesLengths, _In_ IXmlDocument *toastXml);

src/nw_notification_manager_win.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ NotificationManagerWin::~NotificationManagerWin() {
132132
bool NotificationManagerWin::AddDesktopNotification(const content::PlatformNotificationData& params,
133133
const int render_process_id, const int notification_id, const SkBitmap& bitmap_icon) {
134134

135-
if (status_tray_ == NULL) Init();
135+
if (status_tray_ == NULL)
136+
if(!Init()) return false;
136137

137138
content::Shell* shell = content::Shell::windows()[0];
138139

@@ -150,7 +151,7 @@ bool NotificationManagerWin::AddDesktopNotification(const content::PlatformNotif
150151
if (status_icon == NULL) {
151152
nw::Package* package = shell->GetPackage();
152153
status_icon_ = status_tray_->CreateStatusIcon(StatusTray::NOTIFICATION_TRAY_ICON,
153-
*(shell->window()->app_icon().ToImageSkia()), base::UTF8ToUTF16(package->GetName()));
154+
icon.IsEmpty() ? gfx::ImageSkia() : *icon.ToImageSkia(), base::UTF8ToUTF16(package->GetName()));
154155
status_icon = status_icon_;
155156
status_observer_ = new TrayObserver(this);
156157
status_icon->AddObserver(status_observer_);

0 commit comments

Comments
 (0)