🏁 🍎 Add Silent Notification Support
* Implements support for silent notifications on Windows and OS X * Exposes bool `silent` to Linux notification presenters
This commit is contained in:
parent
c9993ccc26
commit
728f0f985b
8 changed files with 95 additions and 10 deletions
|
@ -89,7 +89,8 @@ LibnotifyNotification::~LibnotifyNotification() {
|
||||||
void LibnotifyNotification::Show(const base::string16& title,
|
void LibnotifyNotification::Show(const base::string16& title,
|
||||||
const base::string16& body,
|
const base::string16& body,
|
||||||
const GURL& icon_url,
|
const GURL& icon_url,
|
||||||
const SkBitmap& icon) {
|
const SkBitmap& icon,
|
||||||
|
const bool silent) {
|
||||||
notification_ = libnotify_loader_.notify_notification_new(
|
notification_ = libnotify_loader_.notify_notification_new(
|
||||||
base::UTF16ToUTF8(title).c_str(),
|
base::UTF16ToUTF8(title).c_str(),
|
||||||
base::UTF16ToUTF8(body).c_str(),
|
base::UTF16ToUTF8(body).c_str(),
|
||||||
|
|
|
@ -23,7 +23,8 @@ class LibnotifyNotification : public Notification {
|
||||||
void Show(const base::string16& title,
|
void Show(const base::string16& title,
|
||||||
const base::string16& msg,
|
const base::string16& msg,
|
||||||
const GURL& icon_url,
|
const GURL& icon_url,
|
||||||
const SkBitmap& icon) override;
|
const SkBitmap& icon,
|
||||||
|
const bool silent) override;
|
||||||
void Dismiss() override;
|
void Dismiss() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -23,7 +23,8 @@ class CocoaNotification : public Notification {
|
||||||
void Show(const base::string16& title,
|
void Show(const base::string16& title,
|
||||||
const base::string16& msg,
|
const base::string16& msg,
|
||||||
const GURL& icon_url,
|
const GURL& icon_url,
|
||||||
const SkBitmap& icon) override;
|
const SkBitmap& icon,
|
||||||
|
const bool silent) override;
|
||||||
void Dismiss() override;
|
void Dismiss() override;
|
||||||
|
|
||||||
void NotifyDisplayed();
|
void NotifyDisplayed();
|
||||||
|
|
|
@ -31,7 +31,8 @@ CocoaNotification::~CocoaNotification() {
|
||||||
void CocoaNotification::Show(const base::string16& title,
|
void CocoaNotification::Show(const base::string16& title,
|
||||||
const base::string16& body,
|
const base::string16& body,
|
||||||
const GURL& icon_url,
|
const GURL& icon_url,
|
||||||
const SkBitmap& icon) {
|
const SkBitmap& icon,
|
||||||
|
const bool silent) {
|
||||||
notification_.reset([[NSUserNotification alloc] init]);
|
notification_.reset([[NSUserNotification alloc] init]);
|
||||||
[notification_ setTitle:base::SysUTF16ToNSString(title)];
|
[notification_ setTitle:base::SysUTF16ToNSString(title)];
|
||||||
[notification_ setInformativeText:base::SysUTF16ToNSString(body)];
|
[notification_ setInformativeText:base::SysUTF16ToNSString(body)];
|
||||||
|
@ -43,6 +44,12 @@ void CocoaNotification::Show(const base::string16& title,
|
||||||
[notification_ setContentImage:image];
|
[notification_ setContentImage:image];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (silent) {
|
||||||
|
[notification_ setSoundName:nil];
|
||||||
|
} else {
|
||||||
|
[notification_ setSoundName:NSUserNotificationDefaultSoundName];
|
||||||
|
}
|
||||||
|
|
||||||
[NSUserNotificationCenter.defaultUserNotificationCenter
|
[NSUserNotificationCenter.defaultUserNotificationCenter
|
||||||
deliverNotification:notification_];
|
deliverNotification:notification_];
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,8 @@ class Notification {
|
||||||
virtual void Show(const base::string16& title,
|
virtual void Show(const base::string16& title,
|
||||||
const base::string16& msg,
|
const base::string16& msg,
|
||||||
const GURL& icon_url,
|
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
|
// Closes the notification, this instance will be destroyed after the
|
||||||
// notification gets closed.
|
// notification gets closed.
|
||||||
virtual void Dismiss() = 0;
|
virtual void Dismiss() = 0;
|
||||||
|
|
|
@ -57,7 +57,7 @@ void PlatformNotificationService::DisplayNotification(
|
||||||
auto notification = presenter->CreateNotification(adapter.get());
|
auto notification = presenter->CreateNotification(adapter.get());
|
||||||
if (notification) {
|
if (notification) {
|
||||||
ignore_result(adapter.release()); // it will release itself automatically.
|
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);
|
*cancel_callback = base::Bind(&RemoveNotification, notification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,12 +85,13 @@ void WindowsToastNotification::Show(
|
||||||
const base::string16& title,
|
const base::string16& title,
|
||||||
const base::string16& msg,
|
const base::string16& msg,
|
||||||
const GURL& icon_url,
|
const GURL& icon_url,
|
||||||
const SkBitmap& icon) {
|
const SkBitmap& icon,
|
||||||
|
const bool silent) {
|
||||||
auto presenter_win = static_cast<NotificationPresenterWin*>(presenter());
|
auto presenter_win = static_cast<NotificationPresenterWin*>(presenter());
|
||||||
std::wstring icon_path = presenter_win->SaveIconToFilesystem(icon, icon_url);
|
std::wstring icon_path = presenter_win->SaveIconToFilesystem(icon, icon_url);
|
||||||
|
|
||||||
ComPtr<IXmlDocument> toast_xml;
|
ComPtr<IXmlDocument> 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();
|
NotificationFailed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -152,6 +153,7 @@ bool WindowsToastNotification::GetToastXml(
|
||||||
const std::wstring& title,
|
const std::wstring& title,
|
||||||
const std::wstring& msg,
|
const std::wstring& msg,
|
||||||
const std::wstring& icon_path,
|
const std::wstring& icon_path,
|
||||||
|
const bool silent,
|
||||||
IXmlDocument** toast_xml) {
|
IXmlDocument** toast_xml) {
|
||||||
ABI::Windows::UI::Notifications::ToastTemplateType template_type;
|
ABI::Windows::UI::Notifications::ToastTemplateType template_type;
|
||||||
if (title.empty() || msg.empty()) {
|
if (title.empty() || msg.empty()) {
|
||||||
|
@ -172,13 +174,82 @@ bool WindowsToastNotification::GetToastXml(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toast has image
|
// Configure the toast's notification sound
|
||||||
|
if (silent) {
|
||||||
|
if (FAILED(SetXmlAudioSilent(*toast_xml)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure the toast's image
|
||||||
if (!icon_path.empty())
|
if (!icon_path.empty())
|
||||||
return SetXmlImage(*toast_xml, icon_path);
|
return SetXmlImage(*toast_xml, icon_path);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WindowsToastNotification::SetXmlAudioSilent(
|
||||||
|
IXmlDocument* doc) {
|
||||||
|
ScopedHString tag(L"toast");
|
||||||
|
if (!tag.success())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ComPtr<IXmlNodeList> node_list;
|
||||||
|
if (FAILED(doc->GetElementsByTagName(tag, &node_list)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ComPtr<IXmlNode> root;
|
||||||
|
if (FAILED(node_list->Item(0, &root)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ComPtr<IXmlElement> audio_element;
|
||||||
|
ScopedHString audio_str(L"audio");
|
||||||
|
if (FAILED(doc->CreateElement(audio_str, &audio_element)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ComPtr<IXmlNode> audio_node_tmp;
|
||||||
|
if (FAILED(audio_element.As(&audio_node_tmp)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Append audio node to toast xml
|
||||||
|
ComPtr<IXmlNode> audio_node;
|
||||||
|
if (FAILED(root->AppendChild(audio_node_tmp.Get(), &audio_node)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Create silent attribute
|
||||||
|
ComPtr<IXmlNamedNodeMap> attributes;
|
||||||
|
if (FAILED(audio_node->get_Attributes(&attributes)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ComPtr<IXmlAttribute> silent_attribute;
|
||||||
|
ScopedHString silent_str(L"silent");
|
||||||
|
if (FAILED(doc->CreateAttribute(silent_str, &silent_attribute)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ComPtr<IXmlNode> 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<IXmlText> silent_text;
|
||||||
|
if (FAILED(doc->CreateTextNode(silent_value, &silent_text)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ComPtr<IXmlNode> silent_node;
|
||||||
|
if (FAILED(silent_text.As(&silent_node)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ComPtr<IXmlNode> child_node;
|
||||||
|
if (FAILED(silent_attribute_node->AppendChild(silent_node.Get(), &child_node)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ComPtr<IXmlNode> silent_attribute_pnode;
|
||||||
|
return SUCCEEDED(attributes.Get()->SetNamedItem(silent_attribute_node.Get(), &silent_attribute_pnode));
|
||||||
|
}
|
||||||
|
|
||||||
bool WindowsToastNotification::SetXmlText(
|
bool WindowsToastNotification::SetXmlText(
|
||||||
IXmlDocument* doc, const std::wstring& text) {
|
IXmlDocument* doc, const std::wstring& text) {
|
||||||
ScopedHString tag;
|
ScopedHString tag;
|
||||||
|
|
|
@ -42,7 +42,8 @@ class WindowsToastNotification : public Notification {
|
||||||
void Show(const base::string16& title,
|
void Show(const base::string16& title,
|
||||||
const base::string16& msg,
|
const base::string16& msg,
|
||||||
const GURL& icon_url,
|
const GURL& icon_url,
|
||||||
const SkBitmap& icon) override;
|
const SkBitmap& icon,
|
||||||
|
const bool silent) override;
|
||||||
void Dismiss() override;
|
void Dismiss() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -56,7 +57,9 @@ class WindowsToastNotification : public Notification {
|
||||||
const std::wstring& title,
|
const std::wstring& title,
|
||||||
const std::wstring& msg,
|
const std::wstring& msg,
|
||||||
const std::wstring& icon_path,
|
const std::wstring& icon_path,
|
||||||
|
const bool silent,
|
||||||
ABI::Windows::Data::Xml::Dom::IXmlDocument** toastXml);
|
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,
|
bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc,
|
||||||
const std::wstring& text);
|
const std::wstring& text);
|
||||||
bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc,
|
bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc,
|
||||||
|
|
Loading…
Reference in a new issue