diff --git a/brightray/browser/win/notification_presenter_win.cc b/brightray/browser/win/notification_presenter_win.cc index 925fab17e191..8870de36e3e1 100644 --- a/brightray/browser/win/notification_presenter_win.cc +++ b/brightray/browser/win/notification_presenter_win.cc @@ -1,30 +1,15 @@ // Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Copyright (c) 2015 Felix Rieseberg and Jason Poon . All rights reserved. +// Copyright (c) 2015 Felix Rieseberg and Jason Poon . 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/notification_presenter_win.h" -#include "base/strings/string_util.h" #include "base/win/windows_version.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" -#include -#include -#include - -// Windows Header -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include -#include -#include -#include "windows_toast_notification.h" - #pragma comment(lib, "runtimeobject.lib") #pragma comment(lib, "Crypt32.lib") @@ -42,6 +27,7 @@ NotificationPresenter* NotificationPresenter::Create() { } NotificationPresenterWin::NotificationPresenterWin() { + m_lastNotification = nullptr; } NotificationPresenterWin::~NotificationPresenterWin() { @@ -57,17 +43,25 @@ void NotificationPresenterWin::ShowNotification( 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_ptr.release()); + wtn->ShowNotification(title.c_str(), body.c_str(), iconPath, m_lastNotification); + } - WinToasts::WindowsToastNotification* wtn = new WinToasts::WindowsToastNotification(appName.c_str(), delegate_ptr.release()); - wtn->ShowNotification(title.c_str(), body.c_str(), iconPath); + if (cancel_callback) { + *cancel_callback = base::Bind( + &NotificationPresenterWin::RemoveNotification, + base::Unretained(this)); + } } -void NotificationPresenterWin::CancelNotification() { - // No can do. -} - -void NotificationPresenterWin::DeleteNotification() { - // No can do. +void NotificationPresenterWin::RemoveNotification() { + if (m_lastNotification != nullptr && wtn != NULL) { + wtn->DismissNotification(m_lastNotification); + } } } // namespace brightray \ No newline at end of file diff --git a/brightray/browser/win/notification_presenter_win.h b/brightray/browser/win/notification_presenter_win.h index bed6eea9902d..a2ecd81b9526 100644 --- a/brightray/browser/win/notification_presenter_win.h +++ b/brightray/browser/win/notification_presenter_win.h @@ -1,5 +1,5 @@ // Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Copyright (c) 2015 Felix Rieseberg and Jason Poon . All rights reserved. +// Copyright (c) 2015 Felix Rieseberg and Jason Poon . All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE-CHROMIUM file. @@ -19,8 +19,12 @@ #include "base/compiler_specific.h" #include "browser/notification_presenter.h" +#include "windows_toast_notification.h" #include +#include +#include +#include namespace brightray { @@ -29,7 +33,6 @@ class NotificationPresenterWin : public NotificationPresenter { NotificationPresenterWin(); ~NotificationPresenterWin(); - // NotificationPresenter: void ShowNotification( const content::PlatformNotificationData&, const SkBitmap& icon, @@ -39,11 +42,10 @@ class NotificationPresenterWin : public NotificationPresenter { void RemoveNotification(); private: - - void CancelNotification(); - void DeleteNotification(); + WinToasts::WindowsToastNotification* wtn; + Microsoft::WRL::ComPtr m_lastNotification; }; -} // namespace brightray +} // namespace -#endif +#endif // BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_WIN_H_ diff --git a/brightray/browser/win/windows_toast_notification.cc b/brightray/browser/win/windows_toast_notification.cc index 2bf262e21759..5d306032d684 100644 --- a/brightray/browser/win/windows_toast_notification.cc +++ b/brightray/browser/win/windows_toast_notification.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2015 Felix Rieseberg and Jason Poon . All rights reserved. +// Copyright (c) 2015 Felix Rieseberg and Jason Poon . All rights reserved. // Copyright (c) 2015 Ryan McShane and Brandon Smith // 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. @@ -6,26 +6,41 @@ #include "windows_toast_notification.h" #include "content/public/browser/desktop_notification_delegate.h" -#include -#include -#include -#include -#include -#include -#include - using namespace WinToasts; -using namespace Windows::Foundation; +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; -char WindowsToastNotification::s_appName[MAX_PATH] = {}; - namespace WinToasts { +// Initialize Windows Runtime +static HRESULT init = Windows::Foundation::Initialize(RO_INIT_MULTITHREADED); + WindowsToastNotification::WindowsToastNotification(const char* appName, content::DesktopNotificationDelegate* delegate) { - sprintf_s(s_appName, ARRAYSIZE(s_appName), "%s", appName); + HSTRING toastNotifMgrStr = NULL; + HSTRING appId = NULL; + + HRESULT hr = CreateHString(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager, &toastNotifMgrStr); + + 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 != NULL) { + WindowsDeleteString(toastNotifMgrStr); + } + + if (appId != NULL) { + WindowsDeleteString(appId); + } + m_eventHandler = NULL; n_delegate = delegate; } @@ -41,35 +56,14 @@ WindowsToastNotification::~WindowsToastNotification() } } -void WindowsToastNotification::ShowNotification(const WCHAR* title, const WCHAR* msg, std::string iconPath) +void WindowsToastNotification::ShowNotification(const WCHAR* title, const WCHAR* msg, std::string iconPath, ComPtr& toast) { - // Init using WRL - Windows::Foundation::Initialize(RO_INIT_MULTITHREADED); - - HSTRING toastNotifMgrStr = NULL; - HSTRING appId = NULL; - HSTRING toastNotifStr = NULL; HRESULT hr; + HSTRING toastNotifStr = NULL; do { - hr = CreateHString(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager, &toastNotifMgrStr); - BREAK_IF_BAD(hr); - - ComPtr toastMgr; - hr = Windows::Foundation::GetActivationFactory(toastNotifMgrStr, &toastMgr); - BREAK_IF_BAD(hr); - ComPtr toastXml; - hr = GetToastXml(toastMgr.Get(), title, msg, iconPath, &toastXml); - BREAK_IF_BAD(hr); - - WCHAR wAppName[MAX_PATH]; - swprintf(wAppName, ARRAYSIZE(wAppName), L"%S", s_appName); - hr = CreateHString(wAppName, &appId); - BREAK_IF_BAD(hr); - - ComPtr notifier; - toastMgr->CreateToastNotifierWithId(appId, ¬ifier); + hr = GetToastXml(m_toastManager.Get(), title, msg, iconPath, &toastXml); BREAK_IF_BAD(hr); hr = CreateHString(RuntimeClass_Windows_UI_Notifications_ToastNotification, &toastNotifStr); @@ -79,34 +73,26 @@ void WindowsToastNotification::ShowNotification(const WCHAR* title, const WCHAR* hr = Windows::Foundation::GetActivationFactory(toastNotifStr, &toastFactory); BREAK_IF_BAD(hr); - ComPtr toast; hr = toastFactory->CreateToastNotification(toastXml.Get(), &toast); BREAK_IF_BAD(hr); hr = SetupCallbacks(toast.Get()); BREAK_IF_BAD(hr); - hr = notifier->Show(toast.Get()); + hr = m_toastNotifier->Show(toast.Get()); BREAK_IF_BAD(hr); n_delegate->NotificationDisplayed(); } while (FALSE); - if (toastNotifMgrStr != NULL) { - WindowsDeleteString(toastNotifMgrStr); - } - - if (appId != NULL) { - WindowsDeleteString(appId); - } - if (toastNotifStr != NULL) { WindowsDeleteString(toastNotifStr); } +} - if (!SUCCEEDED(hr)) { - delete this; - } +void WindowsToastNotification::DismissNotification(ComPtr toast) +{ + m_toastNotifier->Hide(toast.Get()); } void WindowsToastNotification::NotificationClicked() @@ -120,7 +106,7 @@ void WindowsToastNotification::NotificationDismissed() } HRESULT WindowsToastNotification::GetToastXml( - IToastNotificationManagerStatics* toastMgr, + IToastNotificationManagerStatics* toastManager, const WCHAR* title, const WCHAR* msg, std::string iconPath, @@ -131,7 +117,7 @@ HRESULT WindowsToastNotification::GetToastXml( if (title == NULL || msg == NULL) { // Single line toast templateType = iconPath.length() == 0 ? ToastTemplateType_ToastText01 : ToastTemplateType_ToastImageAndText01; - hr = toastMgr->GetTemplateContent(templateType, toastXml); + hr = m_toastManager->GetTemplateContent(templateType, toastXml); if (SUCCEEDED(hr)) { const WCHAR* text = title != NULL ? title : msg; hr = SetXmlText(*toastXml, text); @@ -139,7 +125,7 @@ HRESULT WindowsToastNotification::GetToastXml( } else { // Title and body toast templateType = iconPath.length() == 0 ? ToastTemplateType_ToastText02 : ToastTemplateType_ToastImageAndText02; - hr = toastMgr->GetTemplateContent(templateType, toastXml); + hr = toastManager->GetTemplateContent(templateType, toastXml); if (SUCCEEDED(hr)) { hr = SetXmlText(*toastXml, title, msg); } @@ -164,7 +150,7 @@ HRESULT WindowsToastNotification::SetXmlText(IXmlDocument* doc, const WCHAR* tex ComPtr nodeList; HRESULT hr = GetTextNodeList(&tag, doc, &nodeList, 1); - do{ + do { BREAK_IF_BAD(hr); ComPtr node; @@ -186,7 +172,7 @@ HRESULT WindowsToastNotification::SetXmlText(IXmlDocument* doc, const WCHAR* tit HSTRING tag = NULL; ComPtr nodeList; HRESULT hr = GetTextNodeList(&tag, doc, &nodeList, 2); - do{ + do { BREAK_IF_BAD(hr); ComPtr node; diff --git a/brightray/browser/win/windows_toast_notification.h b/brightray/browser/win/windows_toast_notification.h index 8c43326ad051..474d55c767d6 100644 --- a/brightray/browser/win/windows_toast_notification.h +++ b/brightray/browser/win/windows_toast_notification.h @@ -1,4 +1,4 @@ -// Copyright (c) 2015 Felix Rieseberg . All rights reserved. +// Copyright (c) 2015 Felix Rieseberg and Jason Poon . All rights reserved. // Copyright (c) 2015 Ryan McShane and Brandon Smith // 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. @@ -6,24 +6,19 @@ #ifndef __WINDOWS_TOAST_NOTIFICATION_H__ #define __WINDOWS_TOAST_NOTIFICATION_H__ -#define WIN32_LEAN_AND_MEAN - #include "content/public/browser/desktop_notification_delegate.h" #include "content/public/common/platform_notification_data.h" #include "base/bind.h" #include #include -#include #include -#include using namespace Microsoft::WRL; using namespace ABI::Windows::UI::Notifications; using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::Data::Xml::Dom; -namespace WinToasts{ +namespace WinToasts { typedef ITypedEventHandler DesktopToastActivatedEventHandler; typedef ITypedEventHandler DesktopToastDismissedEventHandler; @@ -32,37 +27,35 @@ namespace WinToasts{ class WindowsToastNotification { - private: - static char s_appName[MAX_PATH]; - ToastEventHandler* m_eventHandler; - content::DesktopNotificationDelegate* n_delegate; - - HRESULT GetToastXml(IToastNotificationManagerStatics* toastMgr, const WCHAR* title, const WCHAR* msg, std::string iconPath, IXmlDocument** toastXml); - HRESULT SetXmlText(IXmlDocument* doc, const WCHAR* text); - HRESULT SetXmlText(IXmlDocument* doc, const WCHAR* title, const WCHAR* body); - HRESULT SetXmlImage(IXmlDocument* doc, std::string iconPath); - HRESULT GetTextNodeList(HSTRING* tag, IXmlDocument* doc, IXmlNodeList** nodeList, UINT32 reqLength); - HRESULT AppendTextToXml(IXmlDocument* doc, IXmlNode* node, const WCHAR* text); - HRESULT SetupCallbacks(IToastNotification* toast); - HRESULT CreateHString(const WCHAR* source, HSTRING* dest); - public: WindowsToastNotification(const char* appName, content::DesktopNotificationDelegate* delegate); ~WindowsToastNotification(); - void ShowNotification(const WCHAR* title, const WCHAR* msg, std::string iconPath); + void ShowNotification(const WCHAR* title, const WCHAR* msg, std::string iconPath, ComPtr& toast); + void DismissNotification(ComPtr toast); void NotificationClicked(); void NotificationDismissed(); + + private: + ToastEventHandler* m_eventHandler; + + 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 Implements < DesktopToastActivatedEventHandler, DesktopToastDismissedEventHandler > + public Implements { - private: - ULONG m_ref; - WindowsToastNotification* m_notification; - content::DesktopNotificationDelegate* n_delegate; - public: ToastEventHandler(WindowsToastNotification* notification, content::DesktopNotificationDelegate* delegate); ~ToastEventHandler(); @@ -92,6 +85,11 @@ namespace WinToasts{ return E_NOINTERFACE; } + + private: + ULONG m_ref; + WindowsToastNotification* m_notification; + content::DesktopNotificationDelegate* n_delegate; }; } // namespace