From 1b9c9e40e3b5618ea8d93f5a8476e7fd3f7ad6ea Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 18:27:18 +0800 Subject: [PATCH 1/4] Code cleanup with Chromium's coding style --- brightray/brightray.gyp | 7 +- .../browser/win/notification_presenter_win.cc | 18 +- .../browser/win/notification_presenter_win.h | 9 +- .../browser/win/windows_toast_notification.cc | 589 +++++++++--------- .../browser/win/windows_toast_notification.h | 93 +-- 5 files changed, 358 insertions(+), 358 deletions(-) diff --git a/brightray/brightray.gyp b/brightray/brightray.gyp index db04f5672ceb..9b548e70a7fa 100644 --- a/brightray/brightray.gyp +++ b/brightray/brightray.gyp @@ -164,8 +164,11 @@ 'msvs_settings': { 'VCLinkerTool': { 'AdditionalDependencies': [ + # Windows Runtime. + 'crypt32.lib', 'runtimeobject.lib', - 'windowsapp.lib' + 'shlwapi.lib', + 'windowsapp.lib', ], }, }, @@ -203,8 +206,6 @@ 'msvs_settings': { 'VCLinkerTool': { 'AdditionalDependencies': [ - 'Shlwapi.lib', - 'Crypt32.lib', 'advapi32.lib', 'dbghelp.lib', 'delayimp.lib', diff --git a/brightray/browser/win/notification_presenter_win.cc b/brightray/browser/win/notification_presenter_win.cc index 8870de36e3e1..20b2a3333a88 100644 --- a/brightray/browser/win/notification_presenter_win.cc +++ b/brightray/browser/win/notification_presenter_win.cc @@ -5,13 +5,12 @@ #include "browser/win/notification_presenter_win.h" #include "base/win/windows_version.h" +#include "common/application_info.h" #include "content/public/browser/desktop_notification_delegate.h" #include "content/public/common/platform_notification_data.h" #include "third_party/skia/include/core/SkBitmap.h" -#include "common/application_info.h" #pragma comment(lib, "runtimeobject.lib") -#pragma comment(lib, "Crypt32.lib") using namespace WinToasts; using namespace Microsoft::WRL; @@ -34,14 +33,13 @@ NotificationPresenterWin::~NotificationPresenterWin() { } void NotificationPresenterWin::ShowNotification( - const content::PlatformNotificationData& data, - const SkBitmap& icon, - scoped_ptr delegate_ptr, - base::Closure* cancel_callback) { - + const content::PlatformNotificationData& data, + const SkBitmap& icon, + scoped_ptr delegate_ptr, + base::Closure* cancel_callback) { std::wstring title = data.title; std::wstring body = data.body; - std::string iconPath = data.icon.spec(); + std::string iconPath = data.icon.spec(); std::string appName = GetApplicationName(); // toast notification supported in version >= Windows 8 @@ -50,7 +48,7 @@ void NotificationPresenterWin::ShowNotification( wtn = new WindowsToastNotification(appName.c_str(), delegate_ptr.release()); wtn->ShowNotification(title.c_str(), body.c_str(), iconPath, m_lastNotification); } - + if (cancel_callback) { *cancel_callback = base::Bind( &NotificationPresenterWin::RemoveNotification, @@ -64,4 +62,4 @@ void NotificationPresenterWin::RemoveNotification() { } } -} // namespace brightray \ No newline at end of file +} // namespace brightray diff --git a/brightray/browser/win/notification_presenter_win.h b/brightray/browser/win/notification_presenter_win.h index a2ecd81b9526..fa7ccf40d1f6 100644 --- a/brightray/browser/win/notification_presenter_win.h +++ b/brightray/browser/win/notification_presenter_win.h @@ -13,9 +13,8 @@ // windowsNotification.onclick = function () { console.log("Notification clicked") }; // windowsNotification.onclose = function () { console.log("Notification dismissed") }; - -#ifndef BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_WIN_H_ -#define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_WIN_H_ +#ifndef BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_ +#define BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_ #include "base/compiler_specific.h" #include "browser/notification_presenter.h" @@ -38,7 +37,7 @@ class NotificationPresenterWin : public NotificationPresenter { const SkBitmap& icon, scoped_ptr delegate, base::Closure* cancel_callback) override; - + void RemoveNotification(); private: @@ -48,4 +47,4 @@ class NotificationPresenterWin : public NotificationPresenter { } // namespace -#endif // BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_WIN_H_ +#endif // BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_ diff --git a/brightray/browser/win/windows_toast_notification.cc b/brightray/browser/win/windows_toast_notification.cc index 830a6f670035..79aa2b4a0e60 100644 --- a/brightray/browser/win/windows_toast_notification.cc +++ b/brightray/browser/win/windows_toast_notification.cc @@ -3,100 +3,100 @@ // Thanks to both of those folks mentioned above who first thought up a bunch of this code // and released it as MIT to the world. -#include "windows_toast_notification.h" +#include "browser/win/windows_toast_notification.h" + #include "content/public/browser/desktop_notification_delegate.h" using namespace WinToasts; -using namespace Microsoft::WRL; -using namespace ABI::Windows::UI::Notifications; using namespace ABI::Windows::Data::Xml::Dom; -#define BREAK_IF_BAD(hr) if(!SUCCEEDED(hr)) break; +#define BREAK_IF_BAD(hr) if(!SUCCEEDED(hr)) break; namespace WinToasts { +namespace { + // Initialize Windows Runtime -static HRESULT init = Windows::Foundation::Initialize(RO_INIT_MULTITHREADED); +HRESULT init = Windows::Foundation::Initialize(RO_INIT_MULTITHREADED); -WindowsToastNotification::WindowsToastNotification(const char* appName, content::DesktopNotificationDelegate* delegate) -{ - HSTRING toastNotifMgrStr = NULL; - HSTRING appId = NULL; +} // namespace - HRESULT hr = CreateHString(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager, &toastNotifMgrStr); +WindowsToastNotification::WindowsToastNotification( + const char* appName, content::DesktopNotificationDelegate* delegate) { + HSTRING toastNotifMgrStr = nullptr; + HSTRING appId = nullptr; - hr = Windows::Foundation::GetActivationFactory(toastNotifMgrStr, &m_toastManager); + HRESULT hr = CreateHString(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager, &toastNotifMgrStr); - WCHAR wAppName[MAX_PATH]; - swprintf(wAppName, ARRAYSIZE(wAppName), L"%S", appName); - hr = CreateHString(wAppName, &appId); + hr = Windows::Foundation::GetActivationFactory(toastNotifMgrStr, &m_toastManager); - m_toastManager->CreateToastNotifierWithId(appId, &m_toastNotifier); + WCHAR wAppName[MAX_PATH]; + swprintf(wAppName, ARRAYSIZE(wAppName), L"%S", appName); + hr = CreateHString(wAppName, &appId); - if (toastNotifMgrStr != NULL) { - WindowsDeleteString(toastNotifMgrStr); - } + m_toastManager->CreateToastNotifierWithId(appId, &m_toastNotifier); - if (appId != NULL) { - WindowsDeleteString(appId); - } + if (toastNotifMgrStr) { + WindowsDeleteString(toastNotifMgrStr); + } - n_delegate = delegate; + if (appId) { + WindowsDeleteString(appId); + } + + n_delegate = delegate; } -WindowsToastNotification::~WindowsToastNotification() -{ - if (n_delegate) { - delete n_delegate; - } +WindowsToastNotification::~WindowsToastNotification() { + if (n_delegate) { + delete n_delegate; + } } -void WindowsToastNotification::ShowNotification(const WCHAR* title, const WCHAR* msg, std::string iconPath, ComPtr& toast) -{ - HRESULT hr; - HSTRING toastNotifStr = NULL; +void WindowsToastNotification::ShowNotification( + const WCHAR* title, const WCHAR* msg, std::string iconPath, ComPtr& toast) { + HRESULT hr; + HSTRING toastNotifStr = nullptr; - do { - ComPtr toastXml; - hr = GetToastXml(m_toastManager.Get(), title, msg, iconPath, &toastXml); - BREAK_IF_BAD(hr); + do { + ComPtr toastXml; + hr = GetToastXml(m_toastManager.Get(), title, msg, iconPath, &toastXml); + BREAK_IF_BAD(hr); - hr = CreateHString(RuntimeClass_Windows_UI_Notifications_ToastNotification, &toastNotifStr); - BREAK_IF_BAD(hr); + hr = CreateHString(RuntimeClass_Windows_UI_Notifications_ToastNotification, &toastNotifStr); + BREAK_IF_BAD(hr); - ComPtr toastFactory; - hr = Windows::Foundation::GetActivationFactory(toastNotifStr, &toastFactory); - BREAK_IF_BAD(hr); + ComPtr toastFactory; + hr = Windows::Foundation::GetActivationFactory(toastNotifStr, &toastFactory); + BREAK_IF_BAD(hr); - hr = toastFactory->CreateToastNotification(toastXml.Get(), &toast); - BREAK_IF_BAD(hr); + hr = toastFactory->CreateToastNotification(toastXml.Get(), &toast); + BREAK_IF_BAD(hr); - hr = SetupCallbacks(toast.Get()); - BREAK_IF_BAD(hr); + hr = SetupCallbacks(toast.Get()); + BREAK_IF_BAD(hr); - hr = m_toastNotifier->Show(toast.Get()); - BREAK_IF_BAD(hr); + hr = m_toastNotifier->Show(toast.Get()); + BREAK_IF_BAD(hr); - n_delegate->NotificationDisplayed(); - } while (FALSE); + n_delegate->NotificationDisplayed(); + } while (FALSE); - if (toastNotifStr != NULL) { - WindowsDeleteString(toastNotifStr); - } + if (toastNotifStr) { + WindowsDeleteString(toastNotifStr); + } } -void WindowsToastNotification::DismissNotification(ComPtr toast) -{ - m_toastNotifier->Hide(toast.Get()); +void WindowsToastNotification::DismissNotification( + ComPtr toast) { + m_toastNotifier->Hide(toast.Get()); } -void WindowsToastNotification::NotificationClicked() -{ +void WindowsToastNotification::NotificationClicked() { delete this; } -void WindowsToastNotification::NotificationDismissed() -{ +void WindowsToastNotification::NotificationDismissed() { delete this; } @@ -106,261 +106,260 @@ HRESULT WindowsToastNotification::GetToastXml( const WCHAR* msg, std::string iconPath, IXmlDocument** toastXml) { - - HRESULT hr; - ToastTemplateType templateType; - if (title == NULL || msg == NULL) { - // Single line toast - templateType = iconPath.length() == 0 ? ToastTemplateType_ToastText01 : ToastTemplateType_ToastImageAndText01; - hr = m_toastManager->GetTemplateContent(templateType, toastXml); - if (SUCCEEDED(hr)) { - const WCHAR* text = title != NULL ? title : msg; - hr = SetXmlText(*toastXml, text); - } - } else { - // Title and body toast - templateType = iconPath.length() == 0 ? ToastTemplateType_ToastText02 : ToastTemplateType_ToastImageAndText02; - hr = toastManager->GetTemplateContent(templateType, toastXml); - if (SUCCEEDED(hr)) { - hr = SetXmlText(*toastXml, title, msg); - } - } - - if (iconPath.length() != 0 && SUCCEEDED(hr)) { - // Toast has image - if (SUCCEEDED(hr)) { - hr = SetXmlImage(*toastXml, iconPath); - } - - // Don't stop a notification from showing just because an image couldn't be displayed. By default the app icon will be shown. - hr = S_OK; - } - - return hr; -} - -HRESULT WindowsToastNotification::SetXmlText(IXmlDocument* doc, const WCHAR* text) -{ - HSTRING tag = NULL; - - ComPtr nodeList; - HRESULT hr = GetTextNodeList(&tag, doc, &nodeList, 1); - do { - BREAK_IF_BAD(hr); - - ComPtr node; - hr = nodeList->Item(0, &node); - BREAK_IF_BAD(hr); - - hr = AppendTextToXml(doc, node.Get(), text); - } while (FALSE); - - if (tag != NULL) { - WindowsDeleteString(tag); - } - - return hr; -} - -HRESULT WindowsToastNotification::SetXmlText(IXmlDocument* doc, const WCHAR* title, const WCHAR* body) -{ - HSTRING tag = NULL; - ComPtr nodeList; - HRESULT hr = GetTextNodeList(&tag, doc, &nodeList, 2); - do { - BREAK_IF_BAD(hr); - - ComPtr node; - hr = nodeList->Item(0, &node); - BREAK_IF_BAD(hr); - - hr = AppendTextToXml(doc, node.Get(), title); - BREAK_IF_BAD(hr); - - hr = nodeList->Item(1, &node); - BREAK_IF_BAD(hr); - - hr = AppendTextToXml(doc, node.Get(), body); - } while (FALSE); - - if (tag != NULL) { - WindowsDeleteString(tag); - } - - return hr; -} - -HRESULT WindowsToastNotification::SetXmlImage(IXmlDocument* doc, std::string iconPath) -{ - HSTRING tag = NULL; - HSTRING src = NULL; - HSTRING imgPath = NULL; - HRESULT hr = CreateHString(L"image", &tag); - - do { - BREAK_IF_BAD(hr); - - ComPtr nodeList; - hr = doc->GetElementsByTagName(tag, &nodeList); - BREAK_IF_BAD(hr); - - ComPtr imageNode; - hr = nodeList->Item(0, &imageNode); - BREAK_IF_BAD(hr); - - ComPtr attrs; - hr = imageNode->get_Attributes(&attrs); - BREAK_IF_BAD(hr); - - hr = CreateHString(L"src", &src); - BREAK_IF_BAD(hr); - - ComPtr srcAttr; - hr = attrs->GetNamedItem(src, &srcAttr); - BREAK_IF_BAD(hr); - - WCHAR xmlPath[MAX_PATH]; - swprintf(xmlPath, ARRAYSIZE(xmlPath), L"%S", iconPath); - hr = CreateHString(xmlPath, &imgPath); - BREAK_IF_BAD(hr); - - ComPtr srcText; - hr = doc->CreateTextNode(imgPath, &srcText); - BREAK_IF_BAD(hr); - - ComPtr srcNode; - hr = srcText.As(&srcNode); - BREAK_IF_BAD(hr); - - ComPtr childNode; - hr = srcAttr->AppendChild(srcNode.Get(), &childNode); - } while (FALSE); - - if (tag != NULL) { - WindowsDeleteString(tag); - } - if (src != NULL) { - WindowsDeleteString(src); - } - if (imgPath != NULL) { - WindowsDeleteString(imgPath); - } - - return hr; -} - -HRESULT WindowsToastNotification::GetTextNodeList(HSTRING* tag, IXmlDocument* doc, IXmlNodeList** nodeList, UINT32 reqLength) -{ - HRESULT hr = CreateHString(L"text", tag); - do{ - BREAK_IF_BAD(hr); - - hr = doc->GetElementsByTagName(*tag, nodeList); - BREAK_IF_BAD(hr); - - UINT32 nodeLength; - hr = (*nodeList)->get_Length(&nodeLength); - BREAK_IF_BAD(hr); - - if (nodeLength < reqLength) { - hr = E_INVALIDARG; - } - } while (FALSE); - - if (!SUCCEEDED(hr)) { - // Allow the caller to delete this string on success - WindowsDeleteString(*tag); - } - - return hr; -} - -HRESULT WindowsToastNotification::AppendTextToXml(IXmlDocument* doc, IXmlNode* node, const WCHAR* text) -{ - HSTRING str = NULL; - HRESULT hr = CreateHString(text, &str); - do { - BREAK_IF_BAD(hr); - - ComPtr xmlText; - hr = doc->CreateTextNode(str, &xmlText); - BREAK_IF_BAD(hr); - - ComPtr textNode; - hr = xmlText.As(&textNode); - BREAK_IF_BAD(hr); - - ComPtr appendNode; - hr = node->AppendChild(textNode.Get(), &appendNode); - } while (FALSE); - - if (str != NULL) { - WindowsDeleteString(str); - } - - return hr; -} - -HRESULT WindowsToastNotification::SetupCallbacks(IToastNotification* toast) -{ - EventRegistrationToken activatedToken, dismissedToken; - m_eventHandler = Make(this, n_delegate); - HRESULT hr = toast->add_Activated(m_eventHandler.Get(), &activatedToken); - + HRESULT hr; + ToastTemplateType templateType; + if (title == NULL || msg == NULL) { + // Single line toast + templateType = iconPath.length() == 0 ? ToastTemplateType_ToastText01 : ToastTemplateType_ToastImageAndText01; + hr = m_toastManager->GetTemplateContent(templateType, toastXml); if (SUCCEEDED(hr)) { - hr = toast->add_Dismissed(m_eventHandler.Get(), &dismissedToken); + const WCHAR* text = title != NULL ? title : msg; + hr = SetXmlText(*toastXml, text); + } + } else { + // Title and body toast + templateType = iconPath.length() == 0 ? ToastTemplateType_ToastText02 : ToastTemplateType_ToastImageAndText02; + hr = toastManager->GetTemplateContent(templateType, toastXml); + if (SUCCEEDED(hr)) { + hr = SetXmlText(*toastXml, title, msg); + } + } + + if (iconPath.length() != 0 && SUCCEEDED(hr)) { + // Toast has image + if (SUCCEEDED(hr)) { + hr = SetXmlImage(*toastXml, iconPath); } - return hr; + // Don't stop a notification from showing just because an image couldn't be displayed. By default the app icon will be shown. + hr = S_OK; + } + + return hr; } -HRESULT WindowsToastNotification::CreateHString(const WCHAR* source, HSTRING* dest) -{ - if (source == NULL || dest == NULL) { - return E_INVALIDARG; - } +HRESULT WindowsToastNotification::SetXmlText( + IXmlDocument* doc, const WCHAR* text) { + HSTRING tag = NULL; - HRESULT hr = WindowsCreateString(source, wcslen(source), dest); - return hr; + ComPtr nodeList; + HRESULT hr = GetTextNodeList(&tag, doc, &nodeList, 1); + do { + BREAK_IF_BAD(hr); + + ComPtr node; + hr = nodeList->Item(0, &node); + BREAK_IF_BAD(hr); + + hr = AppendTextToXml(doc, node.Get(), text); + } while (FALSE); + + if (tag != NULL) { + WindowsDeleteString(tag); + } + + return hr; +} + +HRESULT WindowsToastNotification::SetXmlText( + IXmlDocument* doc, const WCHAR* title, const WCHAR* body) { + HSTRING tag = NULL; + ComPtr nodeList; + HRESULT hr = GetTextNodeList(&tag, doc, &nodeList, 2); + do { + BREAK_IF_BAD(hr); + + ComPtr node; + hr = nodeList->Item(0, &node); + BREAK_IF_BAD(hr); + + hr = AppendTextToXml(doc, node.Get(), title); + BREAK_IF_BAD(hr); + + hr = nodeList->Item(1, &node); + BREAK_IF_BAD(hr); + + hr = AppendTextToXml(doc, node.Get(), body); + } while (FALSE); + + if (tag != NULL) { + WindowsDeleteString(tag); + } + + return hr; +} + +HRESULT WindowsToastNotification::SetXmlImage( + IXmlDocument* doc, std::string iconPath) { + HSTRING tag = NULL; + HSTRING src = NULL; + HSTRING imgPath = NULL; + HRESULT hr = CreateHString(L"image", &tag); + + do { + BREAK_IF_BAD(hr); + + ComPtr nodeList; + hr = doc->GetElementsByTagName(tag, &nodeList); + BREAK_IF_BAD(hr); + + ComPtr imageNode; + hr = nodeList->Item(0, &imageNode); + BREAK_IF_BAD(hr); + + ComPtr attrs; + hr = imageNode->get_Attributes(&attrs); + BREAK_IF_BAD(hr); + + hr = CreateHString(L"src", &src); + BREAK_IF_BAD(hr); + + ComPtr srcAttr; + hr = attrs->GetNamedItem(src, &srcAttr); + BREAK_IF_BAD(hr); + + WCHAR xmlPath[MAX_PATH]; + swprintf(xmlPath, ARRAYSIZE(xmlPath), L"%S", iconPath); + hr = CreateHString(xmlPath, &imgPath); + BREAK_IF_BAD(hr); + + ComPtr srcText; + hr = doc->CreateTextNode(imgPath, &srcText); + BREAK_IF_BAD(hr); + + ComPtr srcNode; + hr = srcText.As(&srcNode); + BREAK_IF_BAD(hr); + + ComPtr childNode; + hr = srcAttr->AppendChild(srcNode.Get(), &childNode); + } while (FALSE); + + if (tag != NULL) { + WindowsDeleteString(tag); + } + if (src != NULL) { + WindowsDeleteString(src); + } + if (imgPath != NULL) { + WindowsDeleteString(imgPath); + } + + return hr; +} + +HRESULT WindowsToastNotification::GetTextNodeList( + HSTRING* tag, + IXmlDocument* doc, + IXmlNodeList** nodeList, + UINT32 reqLength) { + HRESULT hr = CreateHString(L"text", tag); + do { + BREAK_IF_BAD(hr); + + hr = doc->GetElementsByTagName(*tag, nodeList); + BREAK_IF_BAD(hr); + + UINT32 nodeLength; + hr = (*nodeList)->get_Length(&nodeLength); + BREAK_IF_BAD(hr); + + if (nodeLength < reqLength) { + hr = E_INVALIDARG; + } + } while (FALSE); + + if (!SUCCEEDED(hr)) { + // Allow the caller to delete this string on success + WindowsDeleteString(*tag); + } + + return hr; +} + +HRESULT WindowsToastNotification::AppendTextToXml( + IXmlDocument* doc, IXmlNode* node, const WCHAR* text) { + HSTRING str = NULL; + HRESULT hr = CreateHString(text, &str); + do { + BREAK_IF_BAD(hr); + + ComPtr xmlText; + hr = doc->CreateTextNode(str, &xmlText); + BREAK_IF_BAD(hr); + + ComPtr textNode; + hr = xmlText.As(&textNode); + BREAK_IF_BAD(hr); + + ComPtr appendNode; + hr = node->AppendChild(textNode.Get(), &appendNode); + } while (FALSE); + + if (str != NULL) { + WindowsDeleteString(str); + } + + return hr; +} + +HRESULT WindowsToastNotification::SetupCallbacks(IToastNotification* toast) { + EventRegistrationToken activatedToken, dismissedToken; + m_eventHandler = Make(this, n_delegate); + HRESULT hr = toast->add_Activated(m_eventHandler.Get(), &activatedToken); + + if (SUCCEEDED(hr)) { + hr = toast->add_Dismissed(m_eventHandler.Get(), &dismissedToken); + } + + return hr; +} + +HRESULT WindowsToastNotification::CreateHString( + const WCHAR* source, HSTRING* dest) { + if (source == NULL || dest == NULL) { + return E_INVALIDARG; + } + + HRESULT hr = WindowsCreateString(source, wcslen(source), dest); + return hr; } /* / Toast Event Handler */ -ToastEventHandler::ToastEventHandler(WindowsToastNotification* notification, content::DesktopNotificationDelegate* delegate) -{ - m_notification = notification; - n_delegate = delegate; +ToastEventHandler::ToastEventHandler( + WindowsToastNotification* notification, + content::DesktopNotificationDelegate* delegate) { + m_notification = notification; + n_delegate = delegate; } -ToastEventHandler::~ToastEventHandler() -{ - // Empty +ToastEventHandler::~ToastEventHandler() { } -IFACEMETHODIMP ToastEventHandler::Invoke(IToastNotification* sender, IInspectable* args) -{ - // Notification "activated" (clicked) - n_delegate->NotificationClick(); - - if (m_notification != NULL) { - m_notification->NotificationClicked(); - } - - return S_OK; +IFACEMETHODIMP ToastEventHandler::Invoke( + IToastNotification* sender, IInspectable* args) { + // Notification "activated" (clicked) + n_delegate->NotificationClick(); + + if (m_notification != NULL) { + m_notification->NotificationClicked(); + } + + return S_OK; } -IFACEMETHODIMP ToastEventHandler::Invoke(IToastNotification* sender, IToastDismissedEventArgs* e) -{ - // Notification dismissed - n_delegate->NotificationClosed(); +IFACEMETHODIMP ToastEventHandler::Invoke( + IToastNotification* sender, IToastDismissedEventArgs* e) { + // Notification dismissed + n_delegate->NotificationClosed(); - if (m_notification != NULL) { - m_notification->NotificationDismissed(); - - } - - return S_OK; + if (m_notification != NULL) { + m_notification->NotificationDismissed(); + } + + return S_OK; } } //namespace diff --git a/brightray/browser/win/windows_toast_notification.h b/brightray/browser/win/windows_toast_notification.h index d501954ec5c3..8b354309742f 100644 --- a/brightray/browser/win/windows_toast_notification.h +++ b/brightray/browser/win/windows_toast_notification.h @@ -3,70 +3,73 @@ // Thanks to both of those folks mentioned above who first thought up a bunch of this code // and released it as MIT to the world. -#ifndef __WINDOWS_TOAST_NOTIFICATION_H__ -#define __WINDOWS_TOAST_NOTIFICATION_H__ - -#include "content/public/browser/desktop_notification_delegate.h" -#include "content/public/common/platform_notification_data.h" -#include "base/bind.h" +#ifndef BRIGHTRAY_BROWSER_WIN_WINDOWS_TOAST_NOTIFICATION_H_ +#define BRIGHTRAY_BROWSER_WIN_WINDOWS_TOAST_NOTIFICATION_H_ #include #include #include +#include "base/bind.h" +#include "content/public/browser/desktop_notification_delegate.h" +#include "content/public/common/platform_notification_data.h" + using namespace Microsoft::WRL; using namespace ABI::Windows::UI::Notifications; using namespace ABI::Windows::Foundation; namespace WinToasts { - typedef ITypedEventHandler DesktopToastActivatedEventHandler; - typedef ITypedEventHandler DesktopToastDismissedEventHandler; +using DesktopToastActivatedEventHandler = + ITypedEventHandler; +using DesktopToastDismissedEventHandler = + ITypedEventHandler; - class ToastEventHandler; +class ToastEventHandler; - class WindowsToastNotification - { - public: - WindowsToastNotification(const char* appName, content::DesktopNotificationDelegate* delegate); - ~WindowsToastNotification(); - void ShowNotification(const WCHAR* title, const WCHAR* msg, std::string iconPath, ComPtr& toast); - void DismissNotification(ComPtr toast); - void NotificationClicked(); - void NotificationDismissed(); +class WindowsToastNotification { + public: + WindowsToastNotification(const char* appName, content::DesktopNotificationDelegate* delegate); + ~WindowsToastNotification(); - private: - ComPtr m_eventHandler; + void ShowNotification(const WCHAR* title, const WCHAR* msg, std::string iconPath, ComPtr& toast); + void DismissNotification(ComPtr toast); + void NotificationClicked(); + void NotificationDismissed(); - content::DesktopNotificationDelegate* n_delegate; - ComPtr m_toastManager; - ComPtr m_toastNotifier; + private: + ComPtr m_eventHandler; - HRESULT GetToastXml(IToastNotificationManagerStatics* toastManager, const WCHAR* title, const WCHAR* msg, std::string iconPath, ABI::Windows::Data::Xml::Dom::IXmlDocument** toastXml); - HRESULT SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const WCHAR* text); - HRESULT SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const WCHAR* title, const WCHAR* body); - HRESULT SetXmlImage(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, std::string iconPath); - HRESULT GetTextNodeList(HSTRING* tag, ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, ABI::Windows::Data::Xml::Dom::IXmlNodeList** nodeList, UINT32 reqLength); - HRESULT AppendTextToXml(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, ABI::Windows::Data::Xml::Dom::IXmlNode* node, const WCHAR* text); - HRESULT SetupCallbacks(IToastNotification* toast); - HRESULT CreateHString(const WCHAR* source, HSTRING* dest); - }; + content::DesktopNotificationDelegate* n_delegate; + ComPtr m_toastManager; + ComPtr m_toastNotifier; + + HRESULT GetToastXml(IToastNotificationManagerStatics* toastManager, const WCHAR* title, const WCHAR* msg, std::string iconPath, ABI::Windows::Data::Xml::Dom::IXmlDocument** toastXml); + HRESULT SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const WCHAR* text); + HRESULT SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const WCHAR* title, const WCHAR* body); + HRESULT SetXmlImage(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, std::string iconPath); + HRESULT GetTextNodeList(HSTRING* tag, ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, ABI::Windows::Data::Xml::Dom::IXmlNodeList** nodeList, UINT32 reqLength); + HRESULT AppendTextToXml(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, ABI::Windows::Data::Xml::Dom::IXmlNode* node, const WCHAR* text); + HRESULT SetupCallbacks(IToastNotification* toast); + HRESULT CreateHString(const WCHAR* source, HSTRING* dest); +}; - class ToastEventHandler : - public RuntimeClass, DesktopToastActivatedEventHandler, DesktopToastDismissedEventHandler> - { - public: - ToastEventHandler(WindowsToastNotification* notification, content::DesktopNotificationDelegate* delegate); - ~ToastEventHandler(); - IFACEMETHODIMP Invoke(IToastNotification* sender, IInspectable* args); - IFACEMETHODIMP Invoke(IToastNotification* sender, IToastDismissedEventArgs* e); +class ToastEventHandler : public RuntimeClass, + DesktopToastActivatedEventHandler, + DesktopToastDismissedEventHandler> { + public: + ToastEventHandler(WindowsToastNotification* notification, content::DesktopNotificationDelegate* delegate); + ~ToastEventHandler(); - private: - WindowsToastNotification* m_notification; - content::DesktopNotificationDelegate* n_delegate; - }; + IFACEMETHODIMP Invoke(IToastNotification* sender, IInspectable* args); + IFACEMETHODIMP Invoke(IToastNotification* sender, IToastDismissedEventArgs* e); + + private: + WindowsToastNotification* m_notification; + content::DesktopNotificationDelegate* n_delegate; +}; } // namespace -#endif //__WINDOWS_TOAST_NOTIFICATION_H__ \ No newline at end of file +#endif // BRIGHTRAY_BROWSER_WIN_WINDOWS_TOAST_NOTIFICATION_H_ From 6b9371c4cd71effd33aa4b51756bed5e5309f2a7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 19:50:38 +0800 Subject: [PATCH 2/4] Use smart pointer for everything --- .../browser/win/notification_presenter_win.cc | 4 +- brightray/browser/win/scoped_hstring.cc | 28 ++ brightray/browser/win/scoped_hstring.h | 36 ++ .../browser/win/windows_toast_notification.cc | 403 +++++++----------- .../browser/win/windows_toast_notification.h | 35 +- brightray/filenames.gypi | 2 + 6 files changed, 240 insertions(+), 268 deletions(-) create mode 100644 brightray/browser/win/scoped_hstring.cc create mode 100644 brightray/browser/win/scoped_hstring.h diff --git a/brightray/browser/win/notification_presenter_win.cc b/brightray/browser/win/notification_presenter_win.cc index 20b2a3333a88..23ec1303c7ca 100644 --- a/brightray/browser/win/notification_presenter_win.cc +++ b/brightray/browser/win/notification_presenter_win.cc @@ -35,7 +35,7 @@ NotificationPresenterWin::~NotificationPresenterWin() { void NotificationPresenterWin::ShowNotification( const content::PlatformNotificationData& data, const SkBitmap& icon, - scoped_ptr delegate_ptr, + scoped_ptr delegate, base::Closure* cancel_callback) { std::wstring title = data.title; std::wstring body = data.body; @@ -45,7 +45,7 @@ void NotificationPresenterWin::ShowNotification( // toast notification supported in version >= Windows 8 // for prior versions, use Tray.displayBalloon if (base::win::GetVersion() >= base::win::VERSION_WIN8) { - wtn = new WindowsToastNotification(appName.c_str(), delegate_ptr.release()); + wtn = new WindowsToastNotification(appName.c_str(), delegate.Pass()); wtn->ShowNotification(title.c_str(), body.c_str(), iconPath, m_lastNotification); } diff --git a/brightray/browser/win/scoped_hstring.cc b/brightray/browser/win/scoped_hstring.cc new file mode 100644 index 000000000000..7954bf1552fc --- /dev/null +++ b/brightray/browser/win/scoped_hstring.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "browser/win/scoped_hstring.h" + +#include + +ScopedHString::ScopedHString(const wchar_t* source) + : str_(nullptr) { + Set(source); +} + +ScopedHString::ScopedHString() : str_(nullptr) { +} + +ScopedHString::~ScopedHString() { + if (str_) + WindowsDeleteString(str_); +} + +void ScopedHString::Set(const wchar_t* source) { + if (str_) { + WindowsDeleteString(str_); + str_ = nullptr; + } + WindowsCreateString(source, wcslen(source), &str_); +} diff --git a/brightray/browser/win/scoped_hstring.h b/brightray/browser/win/scoped_hstring.h new file mode 100644 index 000000000000..71c8bfcbe03f --- /dev/null +++ b/brightray/browser/win/scoped_hstring.h @@ -0,0 +1,36 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#ifndef BRIGHTRAY_BROWSER_WIN_SCOPED_HSTRING_H_ +#define BRIGHTRAY_BROWSER_WIN_SCOPED_HSTRING_H_ + +#include +#include + +#include "base/basictypes.h" + +class ScopedHString { + public: + // Copy from |source|. + ScopedHString(const wchar_t* source); + // Create empty string. + ScopedHString(); + ~ScopedHString(); + + // Sets to |source|. + void Set(const wchar_t* source); + + // Returns string. + operator HSTRING() const { return str_; } + + // Whether there is a string created. + bool success() const { return str_; } + + private: + HSTRING str_; + + DISALLOW_COPY_AND_ASSIGN(ScopedHString); +}; + +#endif // BRIGHTRAY_BROWSER_WIN_SCOPED_HSTRING_H_ diff --git a/brightray/browser/win/windows_toast_notification.cc b/brightray/browser/win/windows_toast_notification.cc index 79aa2b4a0e60..192b5a25db5d 100644 --- a/brightray/browser/win/windows_toast_notification.cc +++ b/brightray/browser/win/windows_toast_notification.cc @@ -5,6 +5,8 @@ #include "browser/win/windows_toast_notification.h" +#include "base/strings/utf_string_conversions.h" +#include "browser/win/scoped_hstring.h" #include "content/public/browser/desktop_notification_delegate.h" using namespace WinToasts; @@ -22,317 +24,232 @@ HRESULT init = Windows::Foundation::Initialize(RO_INIT_MULTITHREADED); } // namespace WindowsToastNotification::WindowsToastNotification( - const char* appName, content::DesktopNotificationDelegate* delegate) { - HSTRING toastNotifMgrStr = nullptr; - HSTRING appId = nullptr; + const char* app_name, + scoped_ptr delegate) + : delegate_(delegate.Pass()) { + ScopedHString toast_manager_str( + RuntimeClass_Windows_UI_Notifications_ToastNotificationManager); + if (!toast_manager_str.success()) + return; + HRESULT hr = Windows::Foundation::GetActivationFactory( + toast_manager_str, &toast_manager_); + if (FAILED(hr)) + return; - HRESULT hr = CreateHString(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager, &toastNotifMgrStr); + ScopedHString app_id(base::UTF8ToUTF16(app_name).c_str()); + if (!app_id.success()) + return; - hr = Windows::Foundation::GetActivationFactory(toastNotifMgrStr, &m_toastManager); - - WCHAR wAppName[MAX_PATH]; - swprintf(wAppName, ARRAYSIZE(wAppName), L"%S", appName); - hr = CreateHString(wAppName, &appId); - - m_toastManager->CreateToastNotifierWithId(appId, &m_toastNotifier); - - if (toastNotifMgrStr) { - WindowsDeleteString(toastNotifMgrStr); - } - - if (appId) { - WindowsDeleteString(appId); - } - - n_delegate = delegate; + toast_manager_->CreateToastNotifierWithId(app_id, &toast_notifier_); } WindowsToastNotification::~WindowsToastNotification() { - if (n_delegate) { - delete n_delegate; - } } void WindowsToastNotification::ShowNotification( - const WCHAR* title, const WCHAR* msg, std::string iconPath, ComPtr& toast) { - HRESULT hr; - HSTRING toastNotifStr = nullptr; + const WCHAR* title, + const WCHAR* msg, + std::string icon_path, + ComPtr& toast) { + ComPtr toast_xml; + if(FAILED(GetToastXml(toast_manager_.Get(), title, msg, icon_path, &toast_xml))) + return; - do { - ComPtr toastXml; - hr = GetToastXml(m_toastManager.Get(), title, msg, iconPath, &toastXml); - BREAK_IF_BAD(hr); + ScopedHString toast_str( + RuntimeClass_Windows_UI_Notifications_ToastNotification); + if (!toast_str.success()) + return; - hr = CreateHString(RuntimeClass_Windows_UI_Notifications_ToastNotification, &toastNotifStr); - BREAK_IF_BAD(hr); + ComPtr toastFactory; + if (FAILED(Windows::Foundation::GetActivationFactory(toast_str, &toastFactory))) + return; - ComPtr toastFactory; - hr = Windows::Foundation::GetActivationFactory(toastNotifStr, &toastFactory); - BREAK_IF_BAD(hr); + if (FAILED(toastFactory->CreateToastNotification(toast_xml.Get(), &toast))) + return; - hr = toastFactory->CreateToastNotification(toastXml.Get(), &toast); - BREAK_IF_BAD(hr); + if (FAILED(SetupCallbacks(toast.Get()))) + return; - hr = SetupCallbacks(toast.Get()); - BREAK_IF_BAD(hr); + if (FAILED(toast_notifier_->Show(toast.Get()))) + return; - hr = m_toastNotifier->Show(toast.Get()); - BREAK_IF_BAD(hr); - - n_delegate->NotificationDisplayed(); - } while (FALSE); - - if (toastNotifStr) { - WindowsDeleteString(toastNotifStr); - } + delegate_->NotificationDisplayed(); } void WindowsToastNotification::DismissNotification( ComPtr toast) { - m_toastNotifier->Hide(toast.Get()); + toast_notifier_->Hide(toast.Get()); } void WindowsToastNotification::NotificationClicked() { - delete this; + delegate_->NotificationClick(); + delete this; } void WindowsToastNotification::NotificationDismissed() { - delete this; + delegate_->NotificationClosed(); + delete this; } -HRESULT WindowsToastNotification::GetToastXml( +bool WindowsToastNotification::GetToastXml( IToastNotificationManagerStatics* toastManager, const WCHAR* title, const WCHAR* msg, - std::string iconPath, - IXmlDocument** toastXml) { - HRESULT hr; - ToastTemplateType templateType; - if (title == NULL || msg == NULL) { - // Single line toast - templateType = iconPath.length() == 0 ? ToastTemplateType_ToastText01 : ToastTemplateType_ToastImageAndText01; - hr = m_toastManager->GetTemplateContent(templateType, toastXml); - if (SUCCEEDED(hr)) { - const WCHAR* text = title != NULL ? title : msg; - hr = SetXmlText(*toastXml, text); - } + std::string icon_path, + IXmlDocument** toast_xml) { + ToastTemplateType template_type; + if (!title || !msg) { + // Single line toast. + template_type = icon_path.empty() ? ToastTemplateType_ToastText01 : + ToastTemplateType_ToastImageAndText01; + if (FAILED(toast_manager_->GetTemplateContent(template_type, toast_xml))) + return false; + if (!SetXmlText(*toast_xml, title ? title : msg)) + return false; } else { - // Title and body toast - templateType = iconPath.length() == 0 ? ToastTemplateType_ToastText02 : ToastTemplateType_ToastImageAndText02; - hr = toastManager->GetTemplateContent(templateType, toastXml); - if (SUCCEEDED(hr)) { - hr = SetXmlText(*toastXml, title, msg); - } + // Title and body toast. + template_type = icon_path.empty() ? ToastTemplateType_ToastText02 : + ToastTemplateType_ToastImageAndText02; + if (FAILED(toastManager->GetTemplateContent(template_type, toast_xml))) + return false; + if (!SetXmlText(*toast_xml, title, msg)) + return false; } - if (iconPath.length() != 0 && SUCCEEDED(hr)) { - // Toast has image - if (SUCCEEDED(hr)) { - hr = SetXmlImage(*toastXml, iconPath); - } + // Toast has image + if (!icon_path.empty()) + return SetXmlImage(*toast_xml, icon_path); - // Don't stop a notification from showing just because an image couldn't be displayed. By default the app icon will be shown. - hr = S_OK; - } - - return hr; + return true; } -HRESULT WindowsToastNotification::SetXmlText( +bool WindowsToastNotification::SetXmlText( IXmlDocument* doc, const WCHAR* text) { - HSTRING tag = NULL; + ScopedHString tag; + ComPtr node_list; + if (!GetTextNodeList(&tag, doc, &node_list, 1)) + return false; - ComPtr nodeList; - HRESULT hr = GetTextNodeList(&tag, doc, &nodeList, 1); - do { - BREAK_IF_BAD(hr); + ComPtr node; + if (FAILED(node_list->Item(0, &node))) + return false; - ComPtr node; - hr = nodeList->Item(0, &node); - BREAK_IF_BAD(hr); - - hr = AppendTextToXml(doc, node.Get(), text); - } while (FALSE); - - if (tag != NULL) { - WindowsDeleteString(tag); - } - - return hr; + return AppendTextToXml(doc, node.Get(), text); } -HRESULT WindowsToastNotification::SetXmlText( +bool WindowsToastNotification::SetXmlText( IXmlDocument* doc, const WCHAR* title, const WCHAR* body) { - HSTRING tag = NULL; - ComPtr nodeList; - HRESULT hr = GetTextNodeList(&tag, doc, &nodeList, 2); - do { - BREAK_IF_BAD(hr); + ScopedHString tag; + ComPtr node_list; + if (!GetTextNodeList(&tag, doc, &node_list, 2)) + return false; - ComPtr node; - hr = nodeList->Item(0, &node); - BREAK_IF_BAD(hr); + ComPtr node; + if (FAILED(node_list->Item(0, &node))) + return false; - hr = AppendTextToXml(doc, node.Get(), title); - BREAK_IF_BAD(hr); + if (!AppendTextToXml(doc, node.Get(), title)) + return false; - hr = nodeList->Item(1, &node); - BREAK_IF_BAD(hr); + if (FAILED(node_list->Item(1, &node))) + return false; - hr = AppendTextToXml(doc, node.Get(), body); - } while (FALSE); - - if (tag != NULL) { - WindowsDeleteString(tag); - } - - return hr; + return AppendTextToXml(doc, node.Get(), body); } -HRESULT WindowsToastNotification::SetXmlImage( - IXmlDocument* doc, std::string iconPath) { - HSTRING tag = NULL; - HSTRING src = NULL; - HSTRING imgPath = NULL; - HRESULT hr = CreateHString(L"image", &tag); +bool WindowsToastNotification::SetXmlImage( + IXmlDocument* doc, std::string icon_path) { + ScopedHString tag(L"imag"); + if (!tag.success()) + return false; - do { - BREAK_IF_BAD(hr); + ComPtr node_list; + if (FAILED(doc->GetElementsByTagName(tag, &node_list))) + return false; - ComPtr nodeList; - hr = doc->GetElementsByTagName(tag, &nodeList); - BREAK_IF_BAD(hr); + ComPtr image_node; + if (FAILED(node_list->Item(0, &image_node))) + return false; - ComPtr imageNode; - hr = nodeList->Item(0, &imageNode); - BREAK_IF_BAD(hr); + ComPtr attrs; + if (FAILED(image_node->get_Attributes(&attrs))) + return false; - ComPtr attrs; - hr = imageNode->get_Attributes(&attrs); - BREAK_IF_BAD(hr); + ScopedHString src(L"src"); + if (!src.success()) + return false; - hr = CreateHString(L"src", &src); - BREAK_IF_BAD(hr); + ComPtr src_attr; + if (FAILED(attrs->GetNamedItem(src, &src_attr))) + return false; - ComPtr srcAttr; - hr = attrs->GetNamedItem(src, &srcAttr); - BREAK_IF_BAD(hr); + ScopedHString img_path(base::UTF8ToUTF16(icon_path).c_str()); + if (!img_path.success()) + return false; - WCHAR xmlPath[MAX_PATH]; - swprintf(xmlPath, ARRAYSIZE(xmlPath), L"%S", iconPath); - hr = CreateHString(xmlPath, &imgPath); - BREAK_IF_BAD(hr); + ComPtr src_text; + if (FAILED(doc->CreateTextNode(img_path, &src_text))) + return false; - ComPtr srcText; - hr = doc->CreateTextNode(imgPath, &srcText); - BREAK_IF_BAD(hr); + ComPtr src_node; + if (FAILED(src_text.As(&src_node))) + return false; - ComPtr srcNode; - hr = srcText.As(&srcNode); - BREAK_IF_BAD(hr); - - ComPtr childNode; - hr = srcAttr->AppendChild(srcNode.Get(), &childNode); - } while (FALSE); - - if (tag != NULL) { - WindowsDeleteString(tag); - } - if (src != NULL) { - WindowsDeleteString(src); - } - if (imgPath != NULL) { - WindowsDeleteString(imgPath); - } - - return hr; + ComPtr child_node; + return SUCCEEDED(src_attr->AppendChild(src_node.Get(), &child_node)); } -HRESULT WindowsToastNotification::GetTextNodeList( - HSTRING* tag, +bool WindowsToastNotification::GetTextNodeList( + ScopedHString* tag, IXmlDocument* doc, - IXmlNodeList** nodeList, - UINT32 reqLength) { - HRESULT hr = CreateHString(L"text", tag); - do { - BREAK_IF_BAD(hr); + IXmlNodeList** node_list, + UINT32 req_length) { + tag->Set(L"text"); + if (!tag->success()) + return false; - hr = doc->GetElementsByTagName(*tag, nodeList); - BREAK_IF_BAD(hr); + if (FAILED(doc->GetElementsByTagName(*tag, node_list))) + return false; - UINT32 nodeLength; - hr = (*nodeList)->get_Length(&nodeLength); - BREAK_IF_BAD(hr); + UINT32 node_length; + if (FAILED((*node_list)->get_Length(&node_length))) + return false; - if (nodeLength < reqLength) { - hr = E_INVALIDARG; - } - } while (FALSE); - - if (!SUCCEEDED(hr)) { - // Allow the caller to delete this string on success - WindowsDeleteString(*tag); - } - - return hr; + return node_length >= req_length; } -HRESULT WindowsToastNotification::AppendTextToXml( +bool WindowsToastNotification::AppendTextToXml( IXmlDocument* doc, IXmlNode* node, const WCHAR* text) { - HSTRING str = NULL; - HRESULT hr = CreateHString(text, &str); - do { - BREAK_IF_BAD(hr); + ScopedHString str(text); + if (!str.success()) + return false; - ComPtr xmlText; - hr = doc->CreateTextNode(str, &xmlText); - BREAK_IF_BAD(hr); + ComPtr xml_text; + if (FAILED(doc->CreateTextNode(str, &xml_text))) + return false; - ComPtr textNode; - hr = xmlText.As(&textNode); - BREAK_IF_BAD(hr); + ComPtr text_node; + if (FAILED(xml_text.As(&text_node))) + return false; - ComPtr appendNode; - hr = node->AppendChild(textNode.Get(), &appendNode); - } while (FALSE); - - if (str != NULL) { - WindowsDeleteString(str); - } - - return hr; + ComPtr append_node; + return SUCCEEDED(node->AppendChild(text_node.Get(), &append_node)); } -HRESULT WindowsToastNotification::SetupCallbacks(IToastNotification* toast) { +bool WindowsToastNotification::SetupCallbacks(IToastNotification* toast) { EventRegistrationToken activatedToken, dismissedToken; - m_eventHandler = Make(this, n_delegate); - HRESULT hr = toast->add_Activated(m_eventHandler.Get(), &activatedToken); + event_handler_ = Make(this); + if (FAILED(toast->add_Activated(event_handler_.Get(), &activatedToken))) + return false; - if (SUCCEEDED(hr)) { - hr = toast->add_Dismissed(m_eventHandler.Get(), &dismissedToken); - } - - return hr; -} - -HRESULT WindowsToastNotification::CreateHString( - const WCHAR* source, HSTRING* dest) { - if (source == NULL || dest == NULL) { - return E_INVALIDARG; - } - - HRESULT hr = WindowsCreateString(source, wcslen(source), dest); - return hr; + return SUCCEEDED(toast->add_Dismissed(event_handler_.Get(), &dismissedToken)); } /* / Toast Event Handler */ -ToastEventHandler::ToastEventHandler( - WindowsToastNotification* notification, - content::DesktopNotificationDelegate* delegate) { - m_notification = notification; - n_delegate = delegate; +ToastEventHandler::ToastEventHandler(WindowsToastNotification* notification) + : notification_(notification) { } ToastEventHandler::~ToastEventHandler() { @@ -340,26 +257,14 @@ ToastEventHandler::~ToastEventHandler() { IFACEMETHODIMP ToastEventHandler::Invoke( IToastNotification* sender, IInspectable* args) { - // Notification "activated" (clicked) - n_delegate->NotificationClick(); - - if (m_notification != NULL) { - m_notification->NotificationClicked(); - } - + notification_->NotificationClicked(); return S_OK; } IFACEMETHODIMP ToastEventHandler::Invoke( IToastNotification* sender, IToastDismissedEventArgs* e) { - // Notification dismissed - n_delegate->NotificationClosed(); - - if (m_notification != NULL) { - m_notification->NotificationDismissed(); - } - + notification_->NotificationDismissed(); return S_OK; } -} //namespace +} // namespace WinToasts diff --git a/brightray/browser/win/windows_toast_notification.h b/brightray/browser/win/windows_toast_notification.h index 8b354309742f..6dee88698b6c 100644 --- a/brightray/browser/win/windows_toast_notification.h +++ b/brightray/browser/win/windows_toast_notification.h @@ -18,6 +18,8 @@ using namespace Microsoft::WRL; using namespace ABI::Windows::UI::Notifications; using namespace ABI::Windows::Foundation; +class ScopedHString; + namespace WinToasts { using DesktopToastActivatedEventHandler = @@ -29,7 +31,9 @@ class ToastEventHandler; class WindowsToastNotification { public: - WindowsToastNotification(const char* appName, content::DesktopNotificationDelegate* delegate); + WindowsToastNotification( + const char* app_name, + scoped_ptr delegate); ~WindowsToastNotification(); void ShowNotification(const WCHAR* title, const WCHAR* msg, std::string iconPath, ComPtr& toast); @@ -38,20 +42,18 @@ class WindowsToastNotification { void NotificationDismissed(); private: - ComPtr m_eventHandler; + scoped_ptr delegate_; + ComPtr event_handler_; + ComPtr toast_manager_; + ComPtr toast_notifier_; - content::DesktopNotificationDelegate* n_delegate; - ComPtr m_toastManager; - ComPtr m_toastNotifier; - - HRESULT GetToastXml(IToastNotificationManagerStatics* toastManager, const WCHAR* title, const WCHAR* msg, std::string iconPath, ABI::Windows::Data::Xml::Dom::IXmlDocument** toastXml); - HRESULT SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const WCHAR* text); - HRESULT SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const WCHAR* title, const WCHAR* body); - HRESULT SetXmlImage(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, std::string iconPath); - HRESULT GetTextNodeList(HSTRING* tag, ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, ABI::Windows::Data::Xml::Dom::IXmlNodeList** nodeList, UINT32 reqLength); - HRESULT AppendTextToXml(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, ABI::Windows::Data::Xml::Dom::IXmlNode* node, const WCHAR* text); - HRESULT SetupCallbacks(IToastNotification* toast); - HRESULT CreateHString(const WCHAR* source, HSTRING* dest); + bool GetToastXml(IToastNotificationManagerStatics* toastManager, const WCHAR* title, const WCHAR* msg, std::string iconPath, ABI::Windows::Data::Xml::Dom::IXmlDocument** toastXml); + bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const WCHAR* text); + bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const WCHAR* title, const WCHAR* body); + bool SetXmlImage(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, std::string iconPath); + bool GetTextNodeList(ScopedHString* tag, ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, ABI::Windows::Data::Xml::Dom::IXmlNodeList** nodeList, UINT32 reqLength); + bool AppendTextToXml(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, ABI::Windows::Data::Xml::Dom::IXmlNode* node, const WCHAR* text); + bool SetupCallbacks(IToastNotification* toast); }; @@ -59,15 +61,14 @@ class ToastEventHandler : public RuntimeClass, DesktopToastActivatedEventHandler, DesktopToastDismissedEventHandler> { public: - ToastEventHandler(WindowsToastNotification* notification, content::DesktopNotificationDelegate* delegate); + ToastEventHandler(WindowsToastNotification* notification); ~ToastEventHandler(); IFACEMETHODIMP Invoke(IToastNotification* sender, IInspectable* args); IFACEMETHODIMP Invoke(IToastNotification* sender, IToastDismissedEventArgs* e); private: - WindowsToastNotification* m_notification; - content::DesktopNotificationDelegate* n_delegate; + WindowsToastNotification* notification_; // weak ref. }; } // namespace diff --git a/brightray/filenames.gypi b/brightray/filenames.gypi index 84dc4291ed2f..5b0fd733c998 100644 --- a/brightray/filenames.gypi +++ b/brightray/filenames.gypi @@ -67,6 +67,8 @@ 'browser/win/notification_presenter_win.cc', 'browser/win/windows_toast_notification.h', 'browser/win/windows_toast_notification.cc', + 'browser/win/scoped_hstring.h', + 'browser/win/scoped_hstring.cc', 'browser/special_storage_policy.cc', 'browser/special_storage_policy.h', 'browser/url_request_context_getter.cc', From 4f73de0930a0274aeba9544c2ca52bc3e09b7eff Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 20:07:12 +0800 Subject: [PATCH 3/4] Make the toast type really work --- .../browser/win/notification_presenter_win.cc | 5 +-- .../browser/win/notification_presenter_win.h | 13 ++++--- brightray/browser/win/scoped_hstring.cc | 5 +++ brightray/browser/win/scoped_hstring.h | 3 ++ .../browser/win/windows_toast_notification.cc | 25 ++++++-------- .../browser/win/windows_toast_notification.h | 34 ++++++++++++++----- 6 files changed, 53 insertions(+), 32 deletions(-) diff --git a/brightray/browser/win/notification_presenter_win.cc b/brightray/browser/win/notification_presenter_win.cc index 23ec1303c7ca..87fc6da55e4c 100644 --- a/brightray/browser/win/notification_presenter_win.cc +++ b/brightray/browser/win/notification_presenter_win.cc @@ -4,7 +4,9 @@ // found in the LICENSE-CHROMIUM file. #include "browser/win/notification_presenter_win.h" + #include "base/win/windows_version.h" +#include "browser/win/windows_toast_notification.h" #include "common/application_info.h" #include "content/public/browser/desktop_notification_delegate.h" #include "content/public/common/platform_notification_data.h" @@ -12,7 +14,6 @@ #pragma comment(lib, "runtimeobject.lib") -using namespace WinToasts; using namespace Microsoft::WRL; using namespace ABI::Windows::UI::Notifications; using namespace ABI::Windows::Data::Xml::Dom; @@ -46,7 +47,7 @@ void NotificationPresenterWin::ShowNotification( // for prior versions, use Tray.displayBalloon if (base::win::GetVersion() >= base::win::VERSION_WIN8) { wtn = new WindowsToastNotification(appName.c_str(), delegate.Pass()); - wtn->ShowNotification(title.c_str(), body.c_str(), iconPath, m_lastNotification); + wtn->ShowNotification(title, body, iconPath, m_lastNotification); } if (cancel_callback) { diff --git a/brightray/browser/win/notification_presenter_win.h b/brightray/browser/win/notification_presenter_win.h index fa7ccf40d1f6..9a1a1d6576b0 100644 --- a/brightray/browser/win/notification_presenter_win.h +++ b/brightray/browser/win/notification_presenter_win.h @@ -16,17 +16,16 @@ #ifndef BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_ #define BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_ -#include "base/compiler_specific.h" -#include "browser/notification_presenter.h" -#include "windows_toast_notification.h" - -#include #include -#include #include +#include "base/compiler_specific.h" +#include "browser/notification_presenter.h" + namespace brightray { +class WindowsToastNotification; + class NotificationPresenterWin : public NotificationPresenter { public: NotificationPresenterWin(); @@ -41,7 +40,7 @@ class NotificationPresenterWin : public NotificationPresenter { void RemoveNotification(); private: - WinToasts::WindowsToastNotification* wtn; + WindowsToastNotification* wtn; Microsoft::WRL::ComPtr m_lastNotification; }; diff --git a/brightray/browser/win/scoped_hstring.cc b/brightray/browser/win/scoped_hstring.cc index 7954bf1552fc..e3f5cbd29bbb 100644 --- a/brightray/browser/win/scoped_hstring.cc +++ b/brightray/browser/win/scoped_hstring.cc @@ -11,6 +11,11 @@ ScopedHString::ScopedHString(const wchar_t* source) Set(source); } +ScopedHString::ScopedHString(const std::wstring& source) + : str_(nullptr) { + WindowsCreateString(source.c_str(), source.length(), &str_); +} + ScopedHString::ScopedHString() : str_(nullptr) { } diff --git a/brightray/browser/win/scoped_hstring.h b/brightray/browser/win/scoped_hstring.h index 71c8bfcbe03f..de03c0469b3a 100644 --- a/brightray/browser/win/scoped_hstring.h +++ b/brightray/browser/win/scoped_hstring.h @@ -5,6 +5,8 @@ #ifndef BRIGHTRAY_BROWSER_WIN_SCOPED_HSTRING_H_ #define BRIGHTRAY_BROWSER_WIN_SCOPED_HSTRING_H_ +#include + #include #include @@ -14,6 +16,7 @@ class ScopedHString { public: // Copy from |source|. ScopedHString(const wchar_t* source); + ScopedHString(const std::wstring& source); // Create empty string. ScopedHString(); ~ScopedHString(); diff --git a/brightray/browser/win/windows_toast_notification.cc b/brightray/browser/win/windows_toast_notification.cc index 192b5a25db5d..2187788332a3 100644 --- a/brightray/browser/win/windows_toast_notification.cc +++ b/brightray/browser/win/windows_toast_notification.cc @@ -9,12 +9,9 @@ #include "browser/win/scoped_hstring.h" #include "content/public/browser/desktop_notification_delegate.h" -using namespace WinToasts; using namespace ABI::Windows::Data::Xml::Dom; -#define BREAK_IF_BAD(hr) if(!SUCCEEDED(hr)) break; - -namespace WinToasts { +namespace brightray { namespace { @@ -47,8 +44,8 @@ WindowsToastNotification::~WindowsToastNotification() { } void WindowsToastNotification::ShowNotification( - const WCHAR* title, - const WCHAR* msg, + const std::wstring& title, + const std::wstring& msg, std::string icon_path, ComPtr& toast) { ComPtr toast_xml; @@ -93,18 +90,18 @@ void WindowsToastNotification::NotificationDismissed() { bool WindowsToastNotification::GetToastXml( IToastNotificationManagerStatics* toastManager, - const WCHAR* title, - const WCHAR* msg, + const std::wstring& title, + const std::wstring& msg, std::string icon_path, IXmlDocument** toast_xml) { ToastTemplateType template_type; - if (!title || !msg) { + if (title.empty() || msg.empty()) { // Single line toast. template_type = icon_path.empty() ? ToastTemplateType_ToastText01 : ToastTemplateType_ToastImageAndText01; if (FAILED(toast_manager_->GetTemplateContent(template_type, toast_xml))) return false; - if (!SetXmlText(*toast_xml, title ? title : msg)) + if (!SetXmlText(*toast_xml, title.empty() ? msg : title)) return false; } else { // Title and body toast. @@ -124,7 +121,7 @@ bool WindowsToastNotification::GetToastXml( } bool WindowsToastNotification::SetXmlText( - IXmlDocument* doc, const WCHAR* text) { + IXmlDocument* doc, const std::wstring& text) { ScopedHString tag; ComPtr node_list; if (!GetTextNodeList(&tag, doc, &node_list, 1)) @@ -138,7 +135,7 @@ bool WindowsToastNotification::SetXmlText( } bool WindowsToastNotification::SetXmlText( - IXmlDocument* doc, const WCHAR* title, const WCHAR* body) { + IXmlDocument* doc, const std::wstring& title, const std::wstring& body) { ScopedHString tag; ComPtr node_list; if (!GetTextNodeList(&tag, doc, &node_list, 2)) @@ -219,7 +216,7 @@ bool WindowsToastNotification::GetTextNodeList( } bool WindowsToastNotification::AppendTextToXml( - IXmlDocument* doc, IXmlNode* node, const WCHAR* text) { + IXmlDocument* doc, IXmlNode* node, const std::wstring& text) { ScopedHString str(text); if (!str.success()) return false; @@ -267,4 +264,4 @@ IFACEMETHODIMP ToastEventHandler::Invoke( return S_OK; } -} // namespace WinToasts +} // namespace brightray diff --git a/brightray/browser/win/windows_toast_notification.h b/brightray/browser/win/windows_toast_notification.h index 6dee88698b6c..8a8c52935291 100644 --- a/brightray/browser/win/windows_toast_notification.h +++ b/brightray/browser/win/windows_toast_notification.h @@ -20,7 +20,7 @@ using namespace ABI::Windows::Foundation; class ScopedHString; -namespace WinToasts { +namespace brightray { using DesktopToastActivatedEventHandler = ITypedEventHandler; @@ -36,7 +36,10 @@ class WindowsToastNotification { scoped_ptr delegate); ~WindowsToastNotification(); - void ShowNotification(const WCHAR* title, const WCHAR* msg, std::string iconPath, ComPtr& toast); + void ShowNotification(const std::wstring& title, + const std::wstring& msg, + std::string icon_path, + ComPtr& toast); void DismissNotification(ComPtr toast); void NotificationClicked(); void NotificationDismissed(); @@ -47,12 +50,25 @@ class WindowsToastNotification { ComPtr toast_manager_; ComPtr toast_notifier_; - bool GetToastXml(IToastNotificationManagerStatics* toastManager, const WCHAR* title, const WCHAR* msg, std::string iconPath, ABI::Windows::Data::Xml::Dom::IXmlDocument** toastXml); - bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const WCHAR* text); - bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const WCHAR* title, const WCHAR* body); - bool SetXmlImage(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, std::string iconPath); - bool GetTextNodeList(ScopedHString* tag, ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, ABI::Windows::Data::Xml::Dom::IXmlNodeList** nodeList, UINT32 reqLength); - bool AppendTextToXml(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, ABI::Windows::Data::Xml::Dom::IXmlNode* node, const WCHAR* text); + bool GetToastXml(IToastNotificationManagerStatics* toastManager, + const std::wstring& title, + const std::wstring& msg, + std::string icon_path, + ABI::Windows::Data::Xml::Dom::IXmlDocument** toastXml); + bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, + const std::wstring& text); + bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, + const std::wstring& title, + const std::wstring& body); + bool SetXmlImage(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, + std::string icon_path); + bool GetTextNodeList(ScopedHString* tag, + ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, + ABI::Windows::Data::Xml::Dom::IXmlNodeList** nodeList, + UINT32 reqLength); + bool AppendTextToXml(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, + ABI::Windows::Data::Xml::Dom::IXmlNode* node, + const std::wstring& text); bool SetupCallbacks(IToastNotification* toast); }; @@ -71,6 +87,6 @@ class ToastEventHandler : public RuntimeClass, WindowsToastNotification* notification_; // weak ref. }; -} // namespace +} // namespace brightray #endif // BRIGHTRAY_BROWSER_WIN_WINDOWS_TOAST_NOTIFICATION_H_ From f9f8a289d90e3c308933936684062e52a82121f7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Nov 2015 20:23:08 +0800 Subject: [PATCH 4/4] Simplify the management of objects --- .../platform_notification_service_impl.cc | 12 +++---- .../browser/win/notification_presenter_win.cc | 34 ++++++++---------- .../browser/win/notification_presenter_win.h | 11 +----- .../browser/win/windows_toast_notification.cc | 25 ++++++------- .../browser/win/windows_toast_notification.h | 36 ++++++++++++------- 5 files changed, 58 insertions(+), 60 deletions(-) diff --git a/brightray/browser/platform_notification_service_impl.cc b/brightray/browser/platform_notification_service_impl.cc index 36045f6db4f2..e93408ebe108 100644 --- a/brightray/browser/platform_notification_service_impl.cc +++ b/brightray/browser/platform_notification_service_impl.cc @@ -24,13 +24,13 @@ PlatformNotificationServiceImpl::PlatformNotificationServiceImpl() {} PlatformNotificationServiceImpl::~PlatformNotificationServiceImpl() {} NotificationPresenter* PlatformNotificationServiceImpl::notification_presenter() { + #if defined(OS_WIN) + // Bail out if on Windows 7 or even lower, no operating will follow + if (base::win::GetVersion() < base::win::VERSION_WIN8) + return nullptr; + #endif + if (!notification_presenter_) { - #if defined(OS_WIN) - // Bail out if on Windows 7 or even lower, no operating will follow - if (base::win::GetVersion() < base::win::VERSION_WIN8) { - return notification_presenter_.get(); - } - #endif // Create a new presenter if on OS X, Linux, or Windows 8+ notification_presenter_.reset(NotificationPresenter::Create()); } diff --git a/brightray/browser/win/notification_presenter_win.cc b/brightray/browser/win/notification_presenter_win.cc index 87fc6da55e4c..9b981443dcbc 100644 --- a/brightray/browser/win/notification_presenter_win.cc +++ b/brightray/browser/win/notification_presenter_win.cc @@ -21,13 +21,21 @@ using namespace ABI::Windows::Foundation; namespace brightray { +namespace { + +void RemoveNotification(base::WeakPtr notification) { + if (notification) + notification->DismissNotification(); +} + +} // namespace + // static NotificationPresenter* NotificationPresenter::Create() { return new NotificationPresenterWin; } NotificationPresenterWin::NotificationPresenterWin() { - m_lastNotification = nullptr; } NotificationPresenterWin::~NotificationPresenterWin() { @@ -38,28 +46,14 @@ void NotificationPresenterWin::ShowNotification( const SkBitmap& icon, scoped_ptr delegate, base::Closure* cancel_callback) { - std::wstring title = data.title; - std::wstring body = data.body; - std::string iconPath = data.icon.spec(); - std::string appName = GetApplicationName(); - - // toast notification supported in version >= Windows 8 - // for prior versions, use Tray.displayBalloon - if (base::win::GetVersion() >= base::win::VERSION_WIN8) { - wtn = new WindowsToastNotification(appName.c_str(), delegate.Pass()); - wtn->ShowNotification(title, body, iconPath, m_lastNotification); - } + // This class manages itself. + auto notification = new WindowsToastNotification( + GetApplicationName(), delegate.Pass()); + notification->ShowNotification(data.title, data.body, data.icon.spec()); if (cancel_callback) { *cancel_callback = base::Bind( - &NotificationPresenterWin::RemoveNotification, - base::Unretained(this)); - } -} - -void NotificationPresenterWin::RemoveNotification() { - if (m_lastNotification != nullptr && wtn != NULL) { - wtn->DismissNotification(m_lastNotification); + &RemoveNotification, notification->GetWeakPtr()); } } diff --git a/brightray/browser/win/notification_presenter_win.h b/brightray/browser/win/notification_presenter_win.h index 9a1a1d6576b0..5bc84feb92af 100644 --- a/brightray/browser/win/notification_presenter_win.h +++ b/brightray/browser/win/notification_presenter_win.h @@ -16,16 +16,10 @@ #ifndef BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_ #define BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_ -#include -#include - -#include "base/compiler_specific.h" #include "browser/notification_presenter.h" namespace brightray { -class WindowsToastNotification; - class NotificationPresenterWin : public NotificationPresenter { public: NotificationPresenterWin(); @@ -37,11 +31,8 @@ class NotificationPresenterWin : public NotificationPresenter { scoped_ptr delegate, base::Closure* cancel_callback) override; - void RemoveNotification(); - private: - WindowsToastNotification* wtn; - Microsoft::WRL::ComPtr m_lastNotification; + DISALLOW_COPY_AND_ASSIGN(NotificationPresenterWin); }; } // namespace diff --git a/brightray/browser/win/windows_toast_notification.cc b/brightray/browser/win/windows_toast_notification.cc index 2187788332a3..cbeda90c360a 100644 --- a/brightray/browser/win/windows_toast_notification.cc +++ b/brightray/browser/win/windows_toast_notification.cc @@ -21,9 +21,10 @@ HRESULT init = Windows::Foundation::Initialize(RO_INIT_MULTITHREADED); } // namespace WindowsToastNotification::WindowsToastNotification( - const char* app_name, + const std::string& app_name, scoped_ptr delegate) - : delegate_(delegate.Pass()) { + : delegate_(delegate.Pass()), + weak_factory_(this) { ScopedHString toast_manager_str( RuntimeClass_Windows_UI_Notifications_ToastNotificationManager); if (!toast_manager_str.success()) @@ -46,8 +47,7 @@ WindowsToastNotification::~WindowsToastNotification() { void WindowsToastNotification::ShowNotification( const std::wstring& title, const std::wstring& msg, - std::string icon_path, - ComPtr& toast) { + std::string icon_path) { ComPtr toast_xml; if(FAILED(GetToastXml(toast_manager_.Get(), title, msg, icon_path, &toast_xml))) return; @@ -57,25 +57,26 @@ void WindowsToastNotification::ShowNotification( if (!toast_str.success()) return; - ComPtr toastFactory; - if (FAILED(Windows::Foundation::GetActivationFactory(toast_str, &toastFactory))) + ComPtr toast_factory; + if (FAILED(Windows::Foundation::GetActivationFactory(toast_str, + &toast_factory))) return; - if (FAILED(toastFactory->CreateToastNotification(toast_xml.Get(), &toast))) + if (FAILED(toast_factory->CreateToastNotification(toast_xml.Get(), + &toast_notification_))) return; - if (FAILED(SetupCallbacks(toast.Get()))) + if (FAILED(SetupCallbacks(toast_notification_.Get()))) return; - if (FAILED(toast_notifier_->Show(toast.Get()))) + if (FAILED(toast_notifier_->Show(toast_notification_.Get()))) return; delegate_->NotificationDisplayed(); } -void WindowsToastNotification::DismissNotification( - ComPtr toast) { - toast_notifier_->Hide(toast.Get()); +void WindowsToastNotification::DismissNotification() { + toast_notifier_->Hide(toast_notification_.Get()); } void WindowsToastNotification::NotificationClicked() { diff --git a/brightray/browser/win/windows_toast_notification.h b/brightray/browser/win/windows_toast_notification.h index 8a8c52935291..bab6612c9f3e 100644 --- a/brightray/browser/win/windows_toast_notification.h +++ b/brightray/browser/win/windows_toast_notification.h @@ -11,6 +11,7 @@ #include #include "base/bind.h" +#include "base/memory/weak_ptr.h" #include "content/public/browser/desktop_notification_delegate.h" #include "content/public/common/platform_notification_data.h" @@ -27,28 +28,27 @@ using DesktopToastActivatedEventHandler = using DesktopToastDismissedEventHandler = ITypedEventHandler; -class ToastEventHandler; - class WindowsToastNotification { public: WindowsToastNotification( - const char* app_name, + const std::string& app_name, scoped_ptr delegate); ~WindowsToastNotification(); void ShowNotification(const std::wstring& title, const std::wstring& msg, - std::string icon_path, - ComPtr& toast); - void DismissNotification(ComPtr toast); - void NotificationClicked(); - void NotificationDismissed(); + std::string icon_path); + void DismissNotification(); + + base::WeakPtr GetWeakPtr() { + return weak_factory_.GetWeakPtr(); + } private: - scoped_ptr delegate_; - ComPtr event_handler_; - ComPtr toast_manager_; - ComPtr toast_notifier_; + friend class ToastEventHandler; + + void NotificationClicked(); + void NotificationDismissed(); bool GetToastXml(IToastNotificationManagerStatics* toastManager, const std::wstring& title, @@ -70,6 +70,16 @@ class WindowsToastNotification { ABI::Windows::Data::Xml::Dom::IXmlNode* node, const std::wstring& text); bool SetupCallbacks(IToastNotification* toast); + + scoped_ptr delegate_; + ComPtr event_handler_; + ComPtr toast_manager_; + ComPtr toast_notifier_; + ComPtr toast_notification_; + + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(WindowsToastNotification); }; @@ -85,6 +95,8 @@ class ToastEventHandler : public RuntimeClass, private: WindowsToastNotification* notification_; // weak ref. + + DISALLOW_COPY_AND_ASSIGN(ToastEventHandler); }; } // namespace brightray