🏁 🍎 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,
|
||||
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(),
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)];
|
||||
|
@ -43,6 +44,12 @@ void CocoaNotification::Show(const base::string16& title,
|
|||
[notification_ setContentImage:image];
|
||||
}
|
||||
|
||||
if (silent) {
|
||||
[notification_ setSoundName:nil];
|
||||
} else {
|
||||
[notification_ setSoundName:NSUserNotificationDefaultSoundName];
|
||||
}
|
||||
|
||||
[NSUserNotificationCenter.defaultUserNotificationCenter
|
||||
deliverNotification:notification_];
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<NotificationPresenterWin*>(presenter());
|
||||
std::wstring icon_path = presenter_win->SaveIconToFilesystem(icon, icon_url);
|
||||
|
||||
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();
|
||||
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()) {
|
||||
|
@ -172,13 +174,82 @@ bool WindowsToastNotification::GetToastXml(
|
|||
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())
|
||||
return SetXmlImage(*toast_xml, icon_path);
|
||||
|
||||
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(
|
||||
IXmlDocument* doc, const std::wstring& text) {
|
||||
ScopedHString tag;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue