From 728f0f985b550abb9d8b353b9ac3545c1dc96155 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Wed, 20 Jan 2016 16:36:41 -0800 Subject: [PATCH] :checkered_flag: :apple: Add Silent Notification Support * Implements support for silent notifications on Windows and OS X * Exposes bool `silent` to Linux notification presenters --- .../browser/linux/libnotify_notification.cc | 3 +- .../browser/linux/libnotify_notification.h | 3 +- brightray/browser/mac/cocoa_notification.h | 3 +- brightray/browser/mac/cocoa_notification.mm | 9 ++- brightray/browser/notification.h | 3 +- .../browser/platform_notification_service.cc | 2 +- .../browser/win/windows_toast_notification.cc | 77 ++++++++++++++++++- .../browser/win/windows_toast_notification.h | 5 +- 8 files changed, 95 insertions(+), 10 deletions(-) diff --git a/brightray/browser/linux/libnotify_notification.cc b/brightray/browser/linux/libnotify_notification.cc index 98aa3ffd8a7d..a903007b5238 100644 --- a/brightray/browser/linux/libnotify_notification.cc +++ b/brightray/browser/linux/libnotify_notification.cc @@ -89,7 +89,8 @@ LibnotifyNotification::~LibnotifyNotification() { void LibnotifyNotification::Show(const base::string16& title, const base::string16& body, const GURL& icon_url, - const SkBitmap& icon) { + const SkBitmap& icon, + const bool silent) { notification_ = libnotify_loader_.notify_notification_new( base::UTF16ToUTF8(title).c_str(), base::UTF16ToUTF8(body).c_str(), diff --git a/brightray/browser/linux/libnotify_notification.h b/brightray/browser/linux/libnotify_notification.h index be2f4280bc4f..17fb427bcf4c 100644 --- a/brightray/browser/linux/libnotify_notification.h +++ b/brightray/browser/linux/libnotify_notification.h @@ -23,7 +23,8 @@ class LibnotifyNotification : public Notification { void Show(const base::string16& title, const base::string16& msg, const GURL& icon_url, - const SkBitmap& icon) override; + const SkBitmap& icon, + const bool silent) override; void Dismiss() override; private: diff --git a/brightray/browser/mac/cocoa_notification.h b/brightray/browser/mac/cocoa_notification.h index b1709568210e..8cefb3a59b71 100644 --- a/brightray/browser/mac/cocoa_notification.h +++ b/brightray/browser/mac/cocoa_notification.h @@ -23,7 +23,8 @@ class CocoaNotification : public Notification { void Show(const base::string16& title, const base::string16& msg, const GURL& icon_url, - const SkBitmap& icon) override; + const SkBitmap& icon, + const bool silent) override; void Dismiss() override; void NotifyDisplayed(); diff --git a/brightray/browser/mac/cocoa_notification.mm b/brightray/browser/mac/cocoa_notification.mm index 24174e226a90..68f22d336370 100644 --- a/brightray/browser/mac/cocoa_notification.mm +++ b/brightray/browser/mac/cocoa_notification.mm @@ -31,7 +31,8 @@ CocoaNotification::~CocoaNotification() { void CocoaNotification::Show(const base::string16& title, const base::string16& body, const GURL& icon_url, - const SkBitmap& icon) { + const SkBitmap& icon, + const bool silent) { notification_.reset([[NSUserNotification alloc] init]); [notification_ setTitle:base::SysUTF16ToNSString(title)]; [notification_ setInformativeText:base::SysUTF16ToNSString(body)]; @@ -42,6 +43,12 @@ void CocoaNotification::Show(const base::string16& title, icon, base::mac::GetGenericRGBColorSpace()); [notification_ setContentImage:image]; } + + if (silent) { + [notification_ setSoundName:nil]; + } else { + [notification_ setSoundName:NSUserNotificationDefaultSoundName]; + } [NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification_]; diff --git a/brightray/browser/notification.h b/brightray/browser/notification.h index 9d0deccbf451..5f1396c8e3ec 100644 --- a/brightray/browser/notification.h +++ b/brightray/browser/notification.h @@ -22,7 +22,8 @@ class Notification { virtual void Show(const base::string16& title, const base::string16& msg, const GURL& icon_url, - const SkBitmap& icon) = 0; + const SkBitmap& icon, + const bool silent) = 0; // Closes the notification, this instance will be destroyed after the // notification gets closed. virtual void Dismiss() = 0; diff --git a/brightray/browser/platform_notification_service.cc b/brightray/browser/platform_notification_service.cc index 7d91ce5f2e42..e4658f35ffb2 100644 --- a/brightray/browser/platform_notification_service.cc +++ b/brightray/browser/platform_notification_service.cc @@ -57,7 +57,7 @@ void PlatformNotificationService::DisplayNotification( auto notification = presenter->CreateNotification(adapter.get()); if (notification) { ignore_result(adapter.release()); // it will release itself automatically. - notification->Show(data.title, data.body, data.icon, icon); + notification->Show(data.title, data.body, data.icon, icon, data.silent); *cancel_callback = base::Bind(&RemoveNotification, notification); } } diff --git a/brightray/browser/win/windows_toast_notification.cc b/brightray/browser/win/windows_toast_notification.cc index d08b888e4a8f..c1be87223cd1 100644 --- a/brightray/browser/win/windows_toast_notification.cc +++ b/brightray/browser/win/windows_toast_notification.cc @@ -85,12 +85,13 @@ void WindowsToastNotification::Show( const base::string16& title, const base::string16& msg, const GURL& icon_url, - const SkBitmap& icon) { + const SkBitmap& icon, + const bool silent) { auto presenter_win = static_cast(presenter()); std::wstring icon_path = presenter_win->SaveIconToFilesystem(icon, icon_url); ComPtr toast_xml; - if(FAILED(GetToastXml(toast_manager_.Get(), title, msg, icon_path, &toast_xml))) { + if(FAILED(GetToastXml(toast_manager_.Get(), title, msg, icon_path, silent, &toast_xml))) { NotificationFailed(); return; } @@ -152,6 +153,7 @@ bool WindowsToastNotification::GetToastXml( const std::wstring& title, const std::wstring& msg, const std::wstring& icon_path, + const bool silent, IXmlDocument** toast_xml) { ABI::Windows::UI::Notifications::ToastTemplateType template_type; if (title.empty() || msg.empty()) { @@ -171,14 +173,83 @@ bool WindowsToastNotification::GetToastXml( if (!SetXmlText(*toast_xml, title, msg)) return false; } + + // Configure the toast's notification sound + if (silent) { + if (FAILED(SetXmlAudioSilent(*toast_xml))) + return false; + } - // Toast has image + // Configure the toast's image if (!icon_path.empty()) return SetXmlImage(*toast_xml, icon_path); return true; } +bool WindowsToastNotification::SetXmlAudioSilent( + IXmlDocument* doc) { + ScopedHString tag(L"toast"); + if (!tag.success()) + return false; + + ComPtr node_list; + if (FAILED(doc->GetElementsByTagName(tag, &node_list))) + return false; + + ComPtr root; + if (FAILED(node_list->Item(0, &root))) + return false; + + ComPtr audio_element; + ScopedHString audio_str(L"audio"); + if (FAILED(doc->CreateElement(audio_str, &audio_element))) + return false; + + ComPtr audio_node_tmp; + if (FAILED(audio_element.As(&audio_node_tmp))) + return false; + + // Append audio node to toast xml + ComPtr audio_node; + if (FAILED(root->AppendChild(audio_node_tmp.Get(), &audio_node))) + return false; + + // Create silent attribute + ComPtr attributes; + if (FAILED(audio_node->get_Attributes(&attributes))) + return false; + + ComPtr silent_attribute; + ScopedHString silent_str(L"silent"); + if (FAILED(doc->CreateAttribute(silent_str, &silent_attribute))) + return false; + + ComPtr silent_attribute_node; + if (FAILED(silent_attribute.As(&silent_attribute_node))) + return false; + + // Set silent attribute to true + ScopedHString silent_value(L"true"); + if (!silent_value.success()) + return false; + + ComPtr silent_text; + if (FAILED(doc->CreateTextNode(silent_value, &silent_text))) + return false; + + ComPtr silent_node; + if (FAILED(silent_text.As(&silent_node))) + return false; + + ComPtr child_node; + if (FAILED(silent_attribute_node->AppendChild(silent_node.Get(), &child_node))) + return false; + + ComPtr silent_attribute_pnode; + return SUCCEEDED(attributes.Get()->SetNamedItem(silent_attribute_node.Get(), &silent_attribute_pnode)); +} + bool WindowsToastNotification::SetXmlText( IXmlDocument* doc, const std::wstring& text) { ScopedHString tag; diff --git a/brightray/browser/win/windows_toast_notification.h b/brightray/browser/win/windows_toast_notification.h index 02e056669928..cb69d3da2a14 100644 --- a/brightray/browser/win/windows_toast_notification.h +++ b/brightray/browser/win/windows_toast_notification.h @@ -42,7 +42,8 @@ class WindowsToastNotification : public Notification { void Show(const base::string16& title, const base::string16& msg, const GURL& icon_url, - const SkBitmap& icon) override; + const SkBitmap& icon, + const bool silent) override; void Dismiss() override; private: @@ -56,7 +57,9 @@ class WindowsToastNotification : public Notification { const std::wstring& title, const std::wstring& msg, const std::wstring& icon_path, + const bool silent, ABI::Windows::Data::Xml::Dom::IXmlDocument** toastXml); + bool SetXmlAudioSilent(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc); bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const std::wstring& text); bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc,