diff --git a/brightray/browser/win/notification_presenter_win.cc b/brightray/browser/win/notification_presenter_win.cc index 447125f39117..29534d94beee 100644 --- a/brightray/browser/win/notification_presenter_win.cc +++ b/brightray/browser/win/notification_presenter_win.cc @@ -5,11 +5,15 @@ #include "browser/win/notification_presenter_win.h" +#include "base/files/file_util.h" +#include "base/md5.h" +#include "base/strings/utf_string_conversions.h" #include "base/win/windows_version.h" #include "browser/win/windows_toast_notification.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 "ui/gfx/codec/png_codec.h" #pragma comment(lib, "runtimeobject.lib") @@ -17,6 +21,16 @@ namespace brightray { namespace { +bool SaveIconToPath(const SkBitmap& bitmap, const base::FilePath& path) { + std::vector png_data; + if (!gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &png_data)) + return false; + + char* data = reinterpret_cast(&png_data[0]); + int size = static_cast(png_data.size()); + return base::WriteFile(path, data, size) == size; +} + void RemoveNotification(base::WeakPtr notification) { if (notification) notification->DismissNotification(); @@ -26,10 +40,12 @@ void RemoveNotification(base::WeakPtr notification) { // static NotificationPresenter* NotificationPresenter::Create() { - if (WindowsToastNotification::Initialize()) - return new NotificationPresenterWin; - else + if (!WindowsToastNotification::Initialize()) return nullptr; + scoped_ptr presenter(new NotificationPresenterWin); + if (!presenter->Init()) + return nullptr; + return presenter.release(); } NotificationPresenterWin::NotificationPresenterWin() { @@ -38,6 +54,10 @@ NotificationPresenterWin::NotificationPresenterWin() { NotificationPresenterWin::~NotificationPresenterWin() { } +bool NotificationPresenterWin::Init() { + return temp_dir_.CreateUniqueTempDir(); +} + void NotificationPresenterWin::ShowNotification( const content::PlatformNotificationData& data, const SkBitmap& icon, @@ -45,7 +65,8 @@ void NotificationPresenterWin::ShowNotification( base::Closure* cancel_callback) { // This class manages itself. auto notification = new WindowsToastNotification(delegate.Pass()); - notification->ShowNotification(data.title, data.body, data.icon.spec()); + notification->ShowNotification( + data.title, data.body, SaveIconToFilesystem(icon, data.icon)); if (cancel_callback) { *cancel_callback = base::Bind( @@ -53,4 +74,15 @@ void NotificationPresenterWin::ShowNotification( } } +std::wstring NotificationPresenterWin::SaveIconToFilesystem( + const SkBitmap& icon, const GURL& origin) { + std::string filename = base::MD5String(origin.spec()) + ".png"; + base::FilePath path = temp_dir_.path().Append(base::UTF8ToUTF16(filename)); + if (base::PathExists(path)) + return path.value(); + if (SaveIconToPath(icon, path)) + return path.value(); + return base::UTF8ToUTF16(origin.spec()); +} + } // namespace brightray diff --git a/brightray/browser/win/notification_presenter_win.h b/brightray/browser/win/notification_presenter_win.h index 5bc84feb92af..21152c9cab9f 100644 --- a/brightray/browser/win/notification_presenter_win.h +++ b/brightray/browser/win/notification_presenter_win.h @@ -16,8 +16,13 @@ #ifndef BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_ #define BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_ +#include + +#include "base/files/scoped_temp_dir.h" #include "browser/notification_presenter.h" +class GURL; + namespace brightray { class NotificationPresenterWin : public NotificationPresenter { @@ -25,6 +30,8 @@ class NotificationPresenterWin : public NotificationPresenter { NotificationPresenterWin(); ~NotificationPresenterWin(); + bool Init(); + void ShowNotification( const content::PlatformNotificationData&, const SkBitmap& icon, @@ -32,6 +39,10 @@ class NotificationPresenterWin : public NotificationPresenter { base::Closure* cancel_callback) override; private: + std::wstring SaveIconToFilesystem(const SkBitmap& icon, const GURL& origin); + + base::ScopedTempDir temp_dir_; + DISALLOW_COPY_AND_ASSIGN(NotificationPresenterWin); }; diff --git a/brightray/browser/win/windows_toast_notification.cc b/brightray/browser/win/windows_toast_notification.cc index 58b4756fed91..f2d77edf6775 100644 --- a/brightray/browser/win/windows_toast_notification.cc +++ b/brightray/browser/win/windows_toast_notification.cc @@ -72,7 +72,7 @@ WindowsToastNotification::~WindowsToastNotification() { void WindowsToastNotification::ShowNotification( const std::wstring& title, const std::wstring& msg, - std::string icon_path) { + const std::wstring& icon_path) { ComPtr toast_xml; if(FAILED(GetToastXml(toast_manager_.Get(), title, msg, icon_path, &toast_xml))) return; @@ -122,7 +122,7 @@ bool WindowsToastNotification::GetToastXml( ABI::Windows::UI::Notifications::IToastNotificationManagerStatics* toastManager, const std::wstring& title, const std::wstring& msg, - std::string icon_path, + const std::wstring& icon_path, IXmlDocument** toast_xml) { ABI::Windows::UI::Notifications::ToastTemplateType template_type; if (title.empty() || msg.empty()) { @@ -185,7 +185,7 @@ bool WindowsToastNotification::SetXmlText( } bool WindowsToastNotification::SetXmlImage( - IXmlDocument* doc, std::string icon_path) { + IXmlDocument* doc, const std::wstring& icon_path) { ScopedHString tag(L"image"); if (!tag.success()) return false; @@ -210,7 +210,7 @@ bool WindowsToastNotification::SetXmlImage( if (FAILED(attrs->GetNamedItem(src, &src_attr))) return false; - ScopedHString img_path(base::UTF8ToUTF16(icon_path).c_str()); + ScopedHString img_path(icon_path.c_str()); if (!img_path.success()) return false; diff --git a/brightray/browser/win/windows_toast_notification.h b/brightray/browser/win/windows_toast_notification.h index acae591bc478..a5c0a3d1d249 100644 --- a/brightray/browser/win/windows_toast_notification.h +++ b/brightray/browser/win/windows_toast_notification.h @@ -42,7 +42,7 @@ class WindowsToastNotification { void ShowNotification(const std::wstring& title, const std::wstring& msg, - std::string icon_path); + const std::wstring& icon_path); void DismissNotification(); base::WeakPtr GetWeakPtr() { @@ -59,7 +59,7 @@ class WindowsToastNotification { bool GetToastXml(ABI::Windows::UI::Notifications::IToastNotificationManagerStatics* toastManager, const std::wstring& title, const std::wstring& msg, - std::string icon_path, + const std::wstring& icon_path, ABI::Windows::Data::Xml::Dom::IXmlDocument** toastXml); bool SetXmlText(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, const std::wstring& text); @@ -67,7 +67,7 @@ class WindowsToastNotification { const std::wstring& title, const std::wstring& body); bool SetXmlImage(ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, - std::string icon_path); + const std::wstring& icon_path); bool GetTextNodeList(ScopedHString* tag, ABI::Windows::Data::Xml::Dom::IXmlDocument* doc, ABI::Windows::Data::Xml::Dom::IXmlNodeList** nodeList,