diff --git a/brightray/browser/platform_notification_service_impl.cc b/brightray/browser/platform_notification_service_impl.cc index 36045f6db4f..e93408ebe10 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 87fc6da55e4..9b981443dcb 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 9a1a1d6576b..5bc84feb92a 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 2187788332a..cbeda90c360 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 8a8c5293529..bab6612c9f3 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