Merge pull request #188 from atom/improve-notifications
Decouple notification code from content module
This commit is contained in:
commit
47237cfbd2
29 changed files with 919 additions and 582 deletions
|
@ -4,15 +4,19 @@
|
||||||
|
|
||||||
#include "browser/browser_client.h"
|
#include "browser/browser_client.h"
|
||||||
|
|
||||||
|
#include "base/path_service.h"
|
||||||
#include "browser/browser_context.h"
|
#include "browser/browser_context.h"
|
||||||
#include "browser/browser_main_parts.h"
|
#include "browser/browser_main_parts.h"
|
||||||
#include "browser/devtools_manager_delegate.h"
|
#include "browser/devtools_manager_delegate.h"
|
||||||
#include "browser/media/media_capture_devices_dispatcher.h"
|
#include "browser/media/media_capture_devices_dispatcher.h"
|
||||||
#include "browser/platform_notification_service_impl.h"
|
#include "browser/notification_presenter.h"
|
||||||
|
#include "browser/platform_notification_service.h"
|
||||||
#include "base/path_service.h"
|
|
||||||
#include "content/public/common/url_constants.h"
|
#include "content/public/common/url_constants.h"
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#include "base/win/windows_version.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -38,6 +42,20 @@ BrowserContext* BrowserClient::browser_context() {
|
||||||
return browser_main_parts_->browser_context();
|
return browser_main_parts_->browser_context();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NotificationPresenter* BrowserClient::GetNotificationPresenter() {
|
||||||
|
#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_) {
|
||||||
|
// Create a new presenter if on OS X, Linux, or Windows 8+
|
||||||
|
notification_presenter_.reset(NotificationPresenter::Create());
|
||||||
|
}
|
||||||
|
return notification_presenter_.get();
|
||||||
|
}
|
||||||
|
|
||||||
BrowserMainParts* BrowserClient::OverrideCreateBrowserMainParts(
|
BrowserMainParts* BrowserClient::OverrideCreateBrowserMainParts(
|
||||||
const content::MainFunctionParams&) {
|
const content::MainFunctionParams&) {
|
||||||
return new BrowserMainParts;
|
return new BrowserMainParts;
|
||||||
|
@ -65,7 +83,9 @@ content::MediaObserver* BrowserClient::GetMediaObserver() {
|
||||||
}
|
}
|
||||||
|
|
||||||
content::PlatformNotificationService* BrowserClient::GetPlatformNotificationService() {
|
content::PlatformNotificationService* BrowserClient::GetPlatformNotificationService() {
|
||||||
return PlatformNotificationServiceImpl::GetInstance();
|
if (!notification_service_)
|
||||||
|
notification_service_.reset(new PlatformNotificationService(this));
|
||||||
|
return notification_service_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserClient::GetAdditionalAllowedSchemesForFileSystem(
|
void BrowserClient::GetAdditionalAllowedSchemesForFileSystem(
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace brightray {
|
||||||
class BrowserContext;
|
class BrowserContext;
|
||||||
class BrowserMainParts;
|
class BrowserMainParts;
|
||||||
class NetLog;
|
class NetLog;
|
||||||
|
class NotificationPresenter;
|
||||||
|
class PlatformNotificationService;
|
||||||
|
|
||||||
class BrowserClient : public content::ContentBrowserClient {
|
class BrowserClient : public content::ContentBrowserClient {
|
||||||
public:
|
public:
|
||||||
|
@ -24,6 +26,8 @@ class BrowserClient : public content::ContentBrowserClient {
|
||||||
BrowserContext* browser_context();
|
BrowserContext* browser_context();
|
||||||
BrowserMainParts* browser_main_parts() { return browser_main_parts_; }
|
BrowserMainParts* browser_main_parts() { return browser_main_parts_; }
|
||||||
|
|
||||||
|
NotificationPresenter* GetNotificationPresenter();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Subclasses should override this to provide their own BrowserMainParts
|
// Subclasses should override this to provide their own BrowserMainParts
|
||||||
// implementation. The lifetime of the returned instance is managed by the
|
// implementation. The lifetime of the returned instance is managed by the
|
||||||
|
@ -51,6 +55,9 @@ class BrowserClient : public content::ContentBrowserClient {
|
||||||
NetLog net_log_;
|
NetLog net_log_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
scoped_ptr<PlatformNotificationService> notification_service_;
|
||||||
|
scoped_ptr<NotificationPresenter> notification_presenter_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(BrowserClient);
|
DISALLOW_COPY_AND_ASSIGN(BrowserClient);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
157
brightray/browser/linux/libnotify_notification.cc
Normal file
157
brightray/browser/linux/libnotify_notification.cc
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "browser/linux/libnotify_notification.h"
|
||||||
|
|
||||||
|
#include "base/files/file_enumerator.h"
|
||||||
|
#include "base/strings/string_util.h"
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
#include "browser/notification_delegate.h"
|
||||||
|
#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
|
||||||
|
#include "common/application_info.h"
|
||||||
|
#include "third_party/skia/include/core/SkBitmap.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool unity_has_result = false;
|
||||||
|
bool unity_result = false;
|
||||||
|
|
||||||
|
bool UnityIsRunning() {
|
||||||
|
if (getenv("ELECTRON_USE_UBUNTU_NOTIFIER"))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (unity_has_result)
|
||||||
|
return unity_result;
|
||||||
|
|
||||||
|
unity_has_result = true;
|
||||||
|
|
||||||
|
// Look for the presence of libunity as our hint that we're under Ubuntu.
|
||||||
|
base::FileEnumerator enumerator(base::FilePath("/usr/lib"),
|
||||||
|
false, base::FileEnumerator::FILES);
|
||||||
|
base::FilePath haystack;
|
||||||
|
while (!((haystack = enumerator.Next()).empty())) {
|
||||||
|
if (base::StartsWith(haystack.value(), "/usr/lib/libunity-",
|
||||||
|
base::CompareCase::SENSITIVE)) {
|
||||||
|
unity_result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return unity_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_and_clear_error(GError* error, const char* context) {
|
||||||
|
LOG(ERROR) << context
|
||||||
|
<< ": domain=" << error->domain
|
||||||
|
<< " code=" << error->code
|
||||||
|
<< " message=\"" << error->message << '"';
|
||||||
|
g_error_free(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// static
|
||||||
|
Notification* Notification::Create(NotificationDelegate* delegate,
|
||||||
|
NotificationPresenter* presenter) {
|
||||||
|
return new LibnotifyNotification(delegate, presenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
LibNotifyLoader LibnotifyNotification::libnotify_loader_;
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool LibnotifyNotification::Initialize() {
|
||||||
|
if (!libnotify_loader_.Load("libnotify.so.4") &&
|
||||||
|
!libnotify_loader_.Load("libnotify.so.1") &&
|
||||||
|
!libnotify_loader_.Load("libnotify.so")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!libnotify_loader_.notify_is_initted() &&
|
||||||
|
!libnotify_loader_.notify_init(GetApplicationName().c_str())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LibnotifyNotification::LibnotifyNotification(NotificationDelegate* delegate,
|
||||||
|
NotificationPresenter* presenter)
|
||||||
|
: Notification(delegate, presenter),
|
||||||
|
notification_(nullptr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
LibnotifyNotification::~LibnotifyNotification() {
|
||||||
|
g_object_unref(notification_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibnotifyNotification::Show(const base::string16& title,
|
||||||
|
const base::string16& body,
|
||||||
|
const GURL& icon_url,
|
||||||
|
const SkBitmap& icon) {
|
||||||
|
notification_ = libnotify_loader_.notify_notification_new(
|
||||||
|
base::UTF16ToUTF8(title).c_str(),
|
||||||
|
base::UTF16ToUTF8(body).c_str(),
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
g_signal_connect(
|
||||||
|
notification_, "closed", G_CALLBACK(OnNotificationClosedThunk), this);
|
||||||
|
|
||||||
|
// NB: On Unity, adding a notification action will cause the notification
|
||||||
|
// to display as a modal dialog box. Testing for distros that have "Unity
|
||||||
|
// Zen Nature" is difficult, we will test for the presence of the indicate
|
||||||
|
// dbus service
|
||||||
|
if (!UnityIsRunning()) {
|
||||||
|
libnotify_loader_.notify_notification_add_action(
|
||||||
|
notification_, "default", "View", OnNotificationViewThunk, this,
|
||||||
|
nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!icon.drawsNothing()) {
|
||||||
|
GdkPixbuf* pixbuf = libgtk2ui::GdkPixbufFromSkBitmap(icon);
|
||||||
|
libnotify_loader_.notify_notification_set_image_from_pixbuf(
|
||||||
|
notification_, pixbuf);
|
||||||
|
libnotify_loader_.notify_notification_set_timeout(
|
||||||
|
notification_, NOTIFY_EXPIRES_DEFAULT);
|
||||||
|
g_object_unref(pixbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
GError* error = nullptr;
|
||||||
|
libnotify_loader_.notify_notification_show(notification_, &error);
|
||||||
|
if (error) {
|
||||||
|
log_and_clear_error(error, "notify_notification_show");
|
||||||
|
NotificationFailed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate()->NotificationDisplayed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibnotifyNotification::Dismiss() {
|
||||||
|
GError* error = nullptr;
|
||||||
|
libnotify_loader_.notify_notification_close(notification_, &error);
|
||||||
|
if (error) {
|
||||||
|
log_and_clear_error(error, "notify_notification_close");
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibnotifyNotification::OnNotificationClosed(
|
||||||
|
NotifyNotification* notification) {
|
||||||
|
delegate()->NotificationClosed();
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibnotifyNotification::OnNotificationView(
|
||||||
|
NotifyNotification* notification, char* action) {
|
||||||
|
delegate()->NotificationClick();
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibnotifyNotification::NotificationFailed() {
|
||||||
|
delegate()->NotificationFailed();
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace brightray
|
46
brightray/browser/linux/libnotify_notification.h
Normal file
46
brightray/browser/linux/libnotify_notification.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef BROWSER_LINUX_LIBNOTIFY_NOTIFICATION_H_
|
||||||
|
#define BROWSER_LINUX_LIBNOTIFY_NOTIFICATION_H_
|
||||||
|
|
||||||
|
#include "browser/linux/libnotify_loader.h"
|
||||||
|
#include "browser/notification.h"
|
||||||
|
#include "ui/base/glib/glib_signal.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
class LibnotifyNotification : public Notification {
|
||||||
|
public:
|
||||||
|
LibnotifyNotification(NotificationDelegate* delegate,
|
||||||
|
NotificationPresenter* presenter);
|
||||||
|
virtual ~LibnotifyNotification();
|
||||||
|
|
||||||
|
static bool Initialize();
|
||||||
|
|
||||||
|
// Notification:
|
||||||
|
void Show(const base::string16& title,
|
||||||
|
const base::string16& msg,
|
||||||
|
const GURL& icon_url,
|
||||||
|
const SkBitmap& icon) override;
|
||||||
|
void Dismiss() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CHROMEG_CALLBACK_0(LibnotifyNotification, void, OnNotificationClosed,
|
||||||
|
NotifyNotification*);
|
||||||
|
CHROMEG_CALLBACK_1(LibnotifyNotification, void, OnNotificationView,
|
||||||
|
NotifyNotification*, char*);
|
||||||
|
|
||||||
|
void NotificationFailed();
|
||||||
|
|
||||||
|
static LibNotifyLoader libnotify_loader_;
|
||||||
|
|
||||||
|
NotifyNotification* notification_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(LibnotifyNotification);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace brightray
|
||||||
|
|
||||||
|
#endif // BROWSER_LINUX_LIBNOTIFY_NOTIFICATION_H_
|
|
@ -5,175 +5,21 @@
|
||||||
|
|
||||||
#include "browser/linux/notification_presenter_linux.h"
|
#include "browser/linux/notification_presenter_linux.h"
|
||||||
|
|
||||||
#include "base/bind.h"
|
#include "browser/linux/libnotify_notification.h"
|
||||||
#include "base/logging.h"
|
|
||||||
#include "base/files/file_enumerator.h"
|
|
||||||
#include "base/strings/string_util.h"
|
|
||||||
#include "base/strings/utf_string_conversions.h"
|
|
||||||
#include "common/application_info.h"
|
|
||||||
#include "content/public/browser/desktop_notification_delegate.h"
|
|
||||||
#include "content/public/common/platform_notification_data.h"
|
|
||||||
#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
|
|
||||||
#include "third_party/skia/include/core/SkBitmap.h"
|
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
bool unity_has_result = false;
|
|
||||||
bool unity_result = false;
|
|
||||||
|
|
||||||
bool UnityIsRunning() {
|
|
||||||
if (getenv("ELECTRON_USE_UBUNTU_NOTIFIER"))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (unity_has_result)
|
|
||||||
return unity_result;
|
|
||||||
|
|
||||||
unity_has_result = true;
|
|
||||||
|
|
||||||
// Look for the presence of libunity as our hint that we're under Ubuntu.
|
|
||||||
base::FileEnumerator enumerator(base::FilePath("/usr/lib"),
|
|
||||||
false, base::FileEnumerator::FILES);
|
|
||||||
base::FilePath haystack;
|
|
||||||
while (!((haystack = enumerator.Next()).empty())) {
|
|
||||||
if (base::StartsWith(haystack.value(), "/usr/lib/libunity-", base::CompareCase::SENSITIVE)) {
|
|
||||||
unity_result = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return unity_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void log_and_clear_error(GError* error, const char* context) {
|
|
||||||
LOG(ERROR) << context
|
|
||||||
<< ": domain=" << error->domain
|
|
||||||
<< " code=" << error->code
|
|
||||||
<< " message=\"" << error->message << '"';
|
|
||||||
g_error_free(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
content::DesktopNotificationDelegate* GetDelegateFromNotification(
|
|
||||||
NotifyNotification* notification) {
|
|
||||||
return static_cast<content::DesktopNotificationDelegate*>(
|
|
||||||
g_object_get_data(G_OBJECT(notification), "delegate"));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
NotificationPresenter* NotificationPresenter::Create() {
|
NotificationPresenter* NotificationPresenter::Create() {
|
||||||
scoped_ptr<NotificationPresenterLinux> presenter(
|
if (!LibnotifyNotification::Initialize())
|
||||||
new NotificationPresenterLinux);
|
|
||||||
if (presenter->Init())
|
|
||||||
return presenter.release();
|
|
||||||
else
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
return new NotificationPresenterLinux;
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationPresenterLinux::NotificationPresenterLinux()
|
NotificationPresenterLinux::NotificationPresenterLinux() {
|
||||||
: notifications_(nullptr) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationPresenterLinux::~NotificationPresenterLinux() {
|
NotificationPresenterLinux::~NotificationPresenterLinux() {
|
||||||
// unref any outstanding notifications, and then free the list.
|
|
||||||
if (notifications_)
|
|
||||||
g_list_free_full(notifications_, g_object_unref);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NotificationPresenterLinux::Init() {
|
|
||||||
if (!libnotify_loader_.Load("libnotify.so.4") &&
|
|
||||||
!libnotify_loader_.Load("libnotify.so.1") &&
|
|
||||||
!libnotify_loader_.Load("libnotify.so")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!libnotify_loader_.notify_is_initted() &&
|
|
||||||
!libnotify_loader_.notify_init(GetApplicationName().c_str())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationPresenterLinux::ShowNotification(
|
|
||||||
const content::PlatformNotificationData& data,
|
|
||||||
const SkBitmap& icon,
|
|
||||||
scoped_ptr<content::DesktopNotificationDelegate> delegate_ptr,
|
|
||||||
base::Closure* cancel_callback) {
|
|
||||||
std::string title = base::UTF16ToUTF8(data.title);
|
|
||||||
std::string body = base::UTF16ToUTF8(data.body);
|
|
||||||
NotifyNotification* notification = libnotify_loader_.notify_notification_new(
|
|
||||||
title.c_str(), body.c_str(), nullptr);
|
|
||||||
|
|
||||||
content::DesktopNotificationDelegate* delegate = delegate_ptr.release();
|
|
||||||
|
|
||||||
g_object_set_data_full(G_OBJECT(notification), "delegate", delegate, operator delete);
|
|
||||||
g_signal_connect(notification, "closed", G_CALLBACK(OnNotificationClosedThunk), this);
|
|
||||||
|
|
||||||
// NB: On Unity, adding a notification action will cause the notification
|
|
||||||
// to display as a modal dialog box. Testing for distros that have "Unity
|
|
||||||
// Zen Nature" is difficult, we will test for the presence of the indicate
|
|
||||||
// dbus service
|
|
||||||
if (!UnityIsRunning()) {
|
|
||||||
libnotify_loader_.notify_notification_add_action(
|
|
||||||
notification, "default", "View", OnNotificationViewThunk, this, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!icon.drawsNothing()) {
|
|
||||||
GdkPixbuf* pixbuf = libgtk2ui::GdkPixbufFromSkBitmap(icon);
|
|
||||||
libnotify_loader_.notify_notification_set_image_from_pixbuf(
|
|
||||||
notification, pixbuf);
|
|
||||||
libnotify_loader_.notify_notification_set_timeout(
|
|
||||||
notification, NOTIFY_EXPIRES_DEFAULT);
|
|
||||||
g_object_unref(pixbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
GError* error = nullptr;
|
|
||||||
libnotify_loader_.notify_notification_show(notification, &error);
|
|
||||||
if (error) {
|
|
||||||
log_and_clear_error(error, "notify_notification_show");
|
|
||||||
g_object_unref(notification);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
notifications_ = g_list_append(notifications_, notification);
|
|
||||||
delegate->NotificationDisplayed();
|
|
||||||
|
|
||||||
if (cancel_callback)
|
|
||||||
*cancel_callback = base::Bind(
|
|
||||||
&NotificationPresenterLinux::CancelNotification,
|
|
||||||
base::Unretained(this),
|
|
||||||
notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationPresenterLinux::CancelNotification(NotifyNotification* notification) {
|
|
||||||
GError* error = nullptr;
|
|
||||||
libnotify_loader_.notify_notification_close(notification, &error);
|
|
||||||
if (error)
|
|
||||||
log_and_clear_error(error, "notify_notification_close");
|
|
||||||
|
|
||||||
GetDelegateFromNotification(notification)->NotificationClosed();
|
|
||||||
DeleteNotification(notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationPresenterLinux::DeleteNotification(NotifyNotification* notification) {
|
|
||||||
notifications_ = g_list_remove(notifications_, notification);
|
|
||||||
g_object_unref(notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationPresenterLinux::OnNotificationClosed(NotifyNotification* notification) {
|
|
||||||
if (!notification)
|
|
||||||
return;
|
|
||||||
GetDelegateFromNotification(notification)->NotificationClosed();
|
|
||||||
DeleteNotification(notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationPresenterLinux::OnNotificationView(
|
|
||||||
NotifyNotification* notification, char* action) {
|
|
||||||
if (!notification)
|
|
||||||
return;
|
|
||||||
GetDelegateFromNotification(notification)->NotificationClick();
|
|
||||||
DeleteNotification(notification);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace brightray
|
} // namespace brightray
|
||||||
|
|
|
@ -6,12 +6,7 @@
|
||||||
#ifndef BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_LINUX_H_
|
#ifndef BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_LINUX_H_
|
||||||
#define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_LINUX_H_
|
#define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_LINUX_H_
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "base/compiler_specific.h"
|
|
||||||
#include "browser/linux/libnotify_loader.h"
|
|
||||||
#include "browser/notification_presenter.h"
|
#include "browser/notification_presenter.h"
|
||||||
#include "ui/base/glib/glib_signal.h"
|
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
||||||
|
@ -20,34 +15,8 @@ class NotificationPresenterLinux : public NotificationPresenter {
|
||||||
NotificationPresenterLinux();
|
NotificationPresenterLinux();
|
||||||
~NotificationPresenterLinux();
|
~NotificationPresenterLinux();
|
||||||
|
|
||||||
bool Init();
|
|
||||||
void RemoveNotification(NotifyNotification *notification);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// NotificationPresenter:
|
DISALLOW_COPY_AND_ASSIGN(NotificationPresenterLinux);
|
||||||
void ShowNotification(
|
|
||||||
const content::PlatformNotificationData&,
|
|
||||||
const SkBitmap& icon,
|
|
||||||
scoped_ptr<content::DesktopNotificationDelegate> delegate,
|
|
||||||
base::Closure* cancel_callback) override;
|
|
||||||
|
|
||||||
void CancelNotification(NotifyNotification* notification);
|
|
||||||
void DeleteNotification(NotifyNotification* notification);
|
|
||||||
|
|
||||||
CHROMEG_CALLBACK_0(NotificationPresenterLinux, void, OnNotificationClosed, NotifyNotification*);
|
|
||||||
CHROMEG_CALLBACK_1(NotificationPresenterLinux, void, OnNotificationView, NotifyNotification*,
|
|
||||||
char*);
|
|
||||||
|
|
||||||
LibNotifyLoader libnotify_loader_;
|
|
||||||
|
|
||||||
// A list of all open NotifyNotification objects.
|
|
||||||
// We do lookups here both by NotifyNotification object (when the user
|
|
||||||
// clicks a notification) and by the <process,view,notification> ID
|
|
||||||
// tuple (when the browser asks to dismiss a notification). So it's not
|
|
||||||
// a map.
|
|
||||||
// Entries in this list count as refs, so removal from this list should
|
|
||||||
// always go with g_object_unref().
|
|
||||||
GList* notifications_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace brightray
|
} // namespace brightray
|
||||||
|
|
42
brightray/browser/mac/cocoa_notification.h
Normal file
42
brightray/browser/mac/cocoa_notification.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef BROWSER_MAC_COCOA_NOTIFICATION_H_
|
||||||
|
#define BROWSER_MAC_COCOA_NOTIFICATION_H_
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#include "base/mac/scoped_nsobject.h"
|
||||||
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
#include "browser/notification.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
class CocoaNotification : public Notification {
|
||||||
|
public:
|
||||||
|
CocoaNotification(NotificationDelegate* delegate,
|
||||||
|
NotificationPresenter* presenter);
|
||||||
|
~CocoaNotification();
|
||||||
|
|
||||||
|
// Notification:
|
||||||
|
void Show(const base::string16& title,
|
||||||
|
const base::string16& msg,
|
||||||
|
const GURL& icon_url,
|
||||||
|
const SkBitmap& icon) override;
|
||||||
|
void Dismiss() override;
|
||||||
|
|
||||||
|
void NotifyDisplayed();
|
||||||
|
void NotifyClick();
|
||||||
|
|
||||||
|
NSUserNotification* notification() const { return notification_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
base::scoped_nsobject<NSUserNotification> notification_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(CocoaNotification);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace brightray
|
||||||
|
|
||||||
|
#endif // BROWSER_MAC_COCOA_NOTIFICATION_H_
|
66
brightray/browser/mac/cocoa_notification.mm
Normal file
66
brightray/browser/mac/cocoa_notification.mm
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "browser/mac/cocoa_notification.h"
|
||||||
|
|
||||||
|
#include "base/mac/mac_util.h"
|
||||||
|
#include "base/strings/sys_string_conversions.h"
|
||||||
|
#include "browser/notification_delegate.h"
|
||||||
|
#include "browser/notification_presenter.h"
|
||||||
|
#include "skia/ext/skia_utils_mac.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
// static
|
||||||
|
Notification* Notification::Create(NotificationDelegate* delegate,
|
||||||
|
NotificationPresenter* presenter) {
|
||||||
|
return new CocoaNotification(delegate, presenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
CocoaNotification::CocoaNotification(NotificationDelegate* delegate,
|
||||||
|
NotificationPresenter* presenter)
|
||||||
|
: Notification(delegate, presenter) {
|
||||||
|
}
|
||||||
|
|
||||||
|
CocoaNotification::~CocoaNotification() {
|
||||||
|
[NSUserNotificationCenter.defaultUserNotificationCenter
|
||||||
|
removeDeliveredNotification:notification_];
|
||||||
|
}
|
||||||
|
|
||||||
|
void CocoaNotification::Show(const base::string16& title,
|
||||||
|
const base::string16& body,
|
||||||
|
const GURL& icon_url,
|
||||||
|
const SkBitmap& icon) {
|
||||||
|
notification_.reset([[NSUserNotification alloc] init]);
|
||||||
|
[notification_ setTitle:base::SysUTF16ToNSString(title)];
|
||||||
|
[notification_ setInformativeText:base::SysUTF16ToNSString(body)];
|
||||||
|
|
||||||
|
if ([notification_ respondsToSelector:@selector(setContentImage:)] &&
|
||||||
|
!icon.drawsNothing()) {
|
||||||
|
NSImage* image = gfx::SkBitmapToNSImageWithColorSpace(
|
||||||
|
icon, base::mac::GetGenericRGBColorSpace());
|
||||||
|
[notification_ setContentImage:image];
|
||||||
|
}
|
||||||
|
|
||||||
|
[NSUserNotificationCenter.defaultUserNotificationCenter
|
||||||
|
deliverNotification:notification_];
|
||||||
|
}
|
||||||
|
|
||||||
|
void CocoaNotification::Dismiss() {
|
||||||
|
[NSUserNotificationCenter.defaultUserNotificationCenter
|
||||||
|
removeDeliveredNotification:notification_];
|
||||||
|
delegate()->NotificationClosed();
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CocoaNotification::NotifyDisplayed() {
|
||||||
|
delegate()->NotificationDisplayed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CocoaNotification::NotifyClick() {
|
||||||
|
delegate()->NotificationClick();
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace brightray
|
22
brightray/browser/mac/notification_center_delegate.h
Normal file
22
brightray/browser/mac/notification_center_delegate.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef BROWSER_MAC_NOTIFICATION_DELEGATE_H_
|
||||||
|
#define BROWSER_MAC_NOTIFICATION_DELEGATE_H_
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
class NotificationPresenterMac;
|
||||||
|
}
|
||||||
|
|
||||||
|
@interface NotificationCenterDelegate :
|
||||||
|
NSObject<NSUserNotificationCenterDelegate> {
|
||||||
|
@private
|
||||||
|
brightray::NotificationPresenterMac* presenter_;
|
||||||
|
}
|
||||||
|
- (instancetype)initWithPresenter:(brightray::NotificationPresenterMac*)presenter;
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif // BROWSER_MAC_NOTIFICATION_DELEGATE_H_
|
41
brightray/browser/mac/notification_center_delegate.mm
Normal file
41
brightray/browser/mac/notification_center_delegate.mm
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "browser/mac/notification_center_delegate.h"
|
||||||
|
|
||||||
|
#include "browser/mac/cocoa_notification.h"
|
||||||
|
#include "browser/mac/notification_presenter_mac.h"
|
||||||
|
|
||||||
|
@implementation NotificationCenterDelegate
|
||||||
|
|
||||||
|
- (instancetype)initWithPresenter:(brightray::NotificationPresenterMac*)presenter {
|
||||||
|
self = [super init];
|
||||||
|
if (!self)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
presenter_ = presenter;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)userNotificationCenter:(NSUserNotificationCenter*)center
|
||||||
|
didDeliverNotification:(NSUserNotification*)notif {
|
||||||
|
auto notification = presenter_->GetNotification(notif);
|
||||||
|
if (notification)
|
||||||
|
notification->NotifyDisplayed();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)userNotificationCenter:(NSUserNotificationCenter*)center
|
||||||
|
didActivateNotification:(NSUserNotification *)notif {
|
||||||
|
auto notification = presenter_->GetNotification(notif);
|
||||||
|
if (notification)
|
||||||
|
notification->NotifyClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center
|
||||||
|
shouldPresentNotification:(NSUserNotification*)notification {
|
||||||
|
// Display notifications even if the app is active.
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
33
brightray/browser/mac/notification_presenter_mac.h
Normal file
33
brightray/browser/mac/notification_presenter_mac.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||||
|
// Copyright (c) 2013 Adam Roben <adam@roben.org>. 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_NOTIFICATION_PRESENTER_MAC_H_
|
||||||
|
#define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_MAC_H_
|
||||||
|
|
||||||
|
#include "base/mac/scoped_nsobject.h"
|
||||||
|
#include "browser/mac/notification_center_delegate.h"
|
||||||
|
#include "browser/notification_presenter.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
class CocoaNotification;
|
||||||
|
|
||||||
|
class NotificationPresenterMac : public NotificationPresenter {
|
||||||
|
public:
|
||||||
|
CocoaNotification* GetNotification(NSUserNotification* notif);
|
||||||
|
|
||||||
|
NotificationPresenterMac();
|
||||||
|
~NotificationPresenterMac();
|
||||||
|
|
||||||
|
private:
|
||||||
|
base::scoped_nsobject<NotificationCenterDelegate>
|
||||||
|
notification_center_delegate_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(NotificationPresenterMac);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace brightray
|
||||||
|
|
||||||
|
#endif
|
38
brightray/browser/mac/notification_presenter_mac.mm
Normal file
38
brightray/browser/mac/notification_presenter_mac.mm
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "browser/mac/notification_presenter_mac.h"
|
||||||
|
|
||||||
|
#include "browser/mac/cocoa_notification.h"
|
||||||
|
#include "browser/mac/notification_center_delegate.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
// static
|
||||||
|
NotificationPresenter* NotificationPresenter::Create() {
|
||||||
|
return new NotificationPresenterMac;
|
||||||
|
}
|
||||||
|
|
||||||
|
CocoaNotification* NotificationPresenterMac::GetNotification(
|
||||||
|
NSUserNotification* ns_notification) {
|
||||||
|
for (Notification* notification : notifications()) {
|
||||||
|
auto native_notification = static_cast<CocoaNotification*>(notification);
|
||||||
|
if ([native_notification->notification() isEqual:ns_notification])
|
||||||
|
return native_notification;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationPresenterMac::NotificationPresenterMac()
|
||||||
|
: notification_center_delegate_(
|
||||||
|
[[NotificationCenterDelegate alloc] initWithPresenter:this]) {
|
||||||
|
NSUserNotificationCenter.defaultUserNotificationCenter.delegate =
|
||||||
|
notification_center_delegate_;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationPresenterMac::~NotificationPresenterMac() {
|
||||||
|
NSUserNotificationCenter.defaultUserNotificationCenter.delegate = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace brightray
|
27
brightray/browser/notification.cc
Normal file
27
brightray/browser/notification.cc
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "browser/notification.h"
|
||||||
|
|
||||||
|
#include "browser/notification_delegate.h"
|
||||||
|
#include "browser/notification_presenter.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
Notification::Notification(NotificationDelegate* delegate,
|
||||||
|
NotificationPresenter* presenter)
|
||||||
|
: delegate_(delegate),
|
||||||
|
presenter_(presenter),
|
||||||
|
weak_factory_(this) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Notification::~Notification() {
|
||||||
|
delegate()->NotificationDestroyed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Notification::Destroy() {
|
||||||
|
presenter()->RemoveNotification(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace brightray
|
63
brightray/browser/notification.h
Normal file
63
brightray/browser/notification.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef BROWSER_NOTIFICATION_H_
|
||||||
|
#define BROWSER_NOTIFICATION_H_
|
||||||
|
|
||||||
|
#include "base/memory/weak_ptr.h"
|
||||||
|
#include "base/strings/string16.h"
|
||||||
|
|
||||||
|
class GURL;
|
||||||
|
class SkBitmap;
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
class NotificationDelegate;
|
||||||
|
class NotificationPresenter;
|
||||||
|
|
||||||
|
class Notification {
|
||||||
|
public:
|
||||||
|
// Shows the notification.
|
||||||
|
virtual void Show(const base::string16& title,
|
||||||
|
const base::string16& msg,
|
||||||
|
const GURL& icon_url,
|
||||||
|
const SkBitmap& icon) = 0;
|
||||||
|
// Closes the notification, this instance will be destroyed after the
|
||||||
|
// notification gets closed.
|
||||||
|
virtual void Dismiss() = 0;
|
||||||
|
|
||||||
|
base::WeakPtr<Notification> GetWeakPtr() {
|
||||||
|
return weak_factory_.GetWeakPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationDelegate* delegate() const { return delegate_; }
|
||||||
|
NotificationPresenter* presenter() const { return presenter_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Notification(NotificationDelegate* delegate,
|
||||||
|
NotificationPresenter* presenter);
|
||||||
|
virtual ~Notification();
|
||||||
|
|
||||||
|
// delete this.
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class NotificationPresenter;
|
||||||
|
|
||||||
|
// Can only be called by NotificationPresenter, the caller is responsible of
|
||||||
|
// freeing the returned instance.
|
||||||
|
static Notification* Create(NotificationDelegate* delegate,
|
||||||
|
NotificationPresenter* presenter);
|
||||||
|
|
||||||
|
NotificationDelegate* delegate_;
|
||||||
|
NotificationPresenter* presenter_;
|
||||||
|
|
||||||
|
base::WeakPtrFactory<Notification> weak_factory_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(Notification);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace brightray
|
||||||
|
|
||||||
|
#endif // BROWSER_NOTIFICATION_H_
|
23
brightray/browser/notification_delegate.h
Normal file
23
brightray/browser/notification_delegate.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef BROWSER_NOTIFICATION_DELEGATE_H_
|
||||||
|
#define BROWSER_NOTIFICATION_DELEGATE_H_
|
||||||
|
|
||||||
|
#include "content/public/browser/desktop_notification_delegate.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
class NotificationDelegate : public content::DesktopNotificationDelegate {
|
||||||
|
public:
|
||||||
|
// The native Notification object is destroyed.
|
||||||
|
virtual void NotificationDestroyed() {}
|
||||||
|
|
||||||
|
// Failed to send the notification.
|
||||||
|
virtual void NotificationFailed() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace brightray
|
||||||
|
|
||||||
|
#endif // BROWSER_NOTIFICATION_DELEGATE_H_
|
33
brightray/browser/notification_delegate_adapter.cc
Normal file
33
brightray/browser/notification_delegate_adapter.cc
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "browser/notification_delegate_adapter.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
NotificationDelegateAdapter::NotificationDelegateAdapter(
|
||||||
|
scoped_ptr<content::DesktopNotificationDelegate> delegate)
|
||||||
|
: delegate_(delegate.Pass()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationDelegateAdapter::~NotificationDelegateAdapter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationDelegateAdapter::NotificationDestroyed() {
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationDelegateAdapter::NotificationDisplayed() {
|
||||||
|
delegate_->NotificationDisplayed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationDelegateAdapter::NotificationClosed() {
|
||||||
|
delegate_->NotificationClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationDelegateAdapter::NotificationClick() {
|
||||||
|
delegate_->NotificationClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace brightray
|
36
brightray/browser/notification_delegate_adapter.h
Normal file
36
brightray/browser/notification_delegate_adapter.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef BROWSER_NOTIFICATION_DELEGATE_ADAPTER_H_
|
||||||
|
#define BROWSER_NOTIFICATION_DELEGATE_ADAPTER_H_
|
||||||
|
|
||||||
|
#include "base/memory/scoped_ptr.h"
|
||||||
|
#include "browser/notification_delegate.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
// Adapt the content::DesktopNotificationDelegate to NotificationDelegate.
|
||||||
|
class NotificationDelegateAdapter : public NotificationDelegate {
|
||||||
|
public:
|
||||||
|
explicit NotificationDelegateAdapter(
|
||||||
|
scoped_ptr<content::DesktopNotificationDelegate> delegate);
|
||||||
|
~NotificationDelegateAdapter() override;
|
||||||
|
|
||||||
|
// NotificationDelegate:
|
||||||
|
void NotificationDestroyed() override;
|
||||||
|
|
||||||
|
// content::DesktopNotificationDelegate:
|
||||||
|
void NotificationDisplayed() override;
|
||||||
|
void NotificationClosed() override;
|
||||||
|
void NotificationClick() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
scoped_ptr<content::DesktopNotificationDelegate> delegate_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(NotificationDelegateAdapter);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace brightray
|
||||||
|
|
||||||
|
#endif // BROWSER_NOTIFICATION_DELEGATE_ADAPTER_H_
|
31
brightray/browser/notification_presenter.cc
Normal file
31
brightray/browser/notification_presenter.cc
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "browser/notification_presenter.h"
|
||||||
|
|
||||||
|
#include "browser/notification.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
NotificationPresenter::NotificationPresenter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationPresenter::~NotificationPresenter() {
|
||||||
|
for (Notification* notification : notifications_)
|
||||||
|
delete notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
base::WeakPtr<Notification> NotificationPresenter::CreateNotification(
|
||||||
|
NotificationDelegate* delegate) {
|
||||||
|
Notification* notification = Notification::Create(delegate, this);
|
||||||
|
notifications_.insert(notification);
|
||||||
|
return notification->GetWeakPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationPresenter::RemoveNotification(Notification* notification) {
|
||||||
|
notifications_.erase(notification);
|
||||||
|
delete notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace brightray
|
|
@ -1,29 +1,41 @@
|
||||||
|
// Copyright (c) 2015 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#ifndef BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_H_
|
#ifndef BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_H_
|
||||||
#define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_H_
|
#define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_H_
|
||||||
|
|
||||||
#include "base/callback_forward.h"
|
#include <set>
|
||||||
#include "base/memory/scoped_ptr.h"
|
|
||||||
|
|
||||||
class SkBitmap;
|
#include "base/memory/weak_ptr.h"
|
||||||
|
|
||||||
namespace content {
|
|
||||||
class DesktopNotificationDelegate;
|
|
||||||
struct PlatformNotificationData;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
||||||
|
class Notification;
|
||||||
|
class NotificationDelegate;
|
||||||
|
|
||||||
class NotificationPresenter {
|
class NotificationPresenter {
|
||||||
public:
|
public:
|
||||||
virtual ~NotificationPresenter() {}
|
|
||||||
|
|
||||||
static NotificationPresenter* Create();
|
static NotificationPresenter* Create();
|
||||||
|
|
||||||
virtual void ShowNotification(
|
virtual ~NotificationPresenter();
|
||||||
const content::PlatformNotificationData&,
|
|
||||||
const SkBitmap& icon,
|
base::WeakPtr<Notification> CreateNotification(
|
||||||
scoped_ptr<content::DesktopNotificationDelegate> delegate,
|
NotificationDelegate* delegate);
|
||||||
base::Closure* cancel_callback) = 0;
|
|
||||||
|
std::set<Notification*> notifications() const { return notifications_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
NotificationPresenter();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Notification;
|
||||||
|
|
||||||
|
void RemoveNotification(Notification* notification);
|
||||||
|
|
||||||
|
std::set<Notification*> notifications_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(NotificationPresenter);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace brightray
|
} // namespace brightray
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
|
||||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. 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_NOTIFICATION_PRESENTER_MAC_H_
|
|
||||||
#define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_MAC_H_
|
|
||||||
|
|
||||||
#include "browser/notification_presenter.h"
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
#include "base/mac/scoped_nsobject.h"
|
|
||||||
|
|
||||||
@class BRYUserNotificationCenterDelegate;
|
|
||||||
|
|
||||||
namespace brightray {
|
|
||||||
|
|
||||||
class NotificationPresenterMac : public NotificationPresenter {
|
|
||||||
public:
|
|
||||||
NotificationPresenterMac();
|
|
||||||
~NotificationPresenterMac();
|
|
||||||
|
|
||||||
// NotificationPresenter:
|
|
||||||
void ShowNotification(
|
|
||||||
const content::PlatformNotificationData&,
|
|
||||||
const SkBitmap& icon,
|
|
||||||
scoped_ptr<content::DesktopNotificationDelegate> delegate,
|
|
||||||
base::Closure* cancel_callback) override;
|
|
||||||
|
|
||||||
// Get the delegate accroding from the notification object.
|
|
||||||
content::DesktopNotificationDelegate* GetDelegateFromNotification(
|
|
||||||
NSUserNotification* notification);
|
|
||||||
|
|
||||||
// Remove the notification object accroding to its delegate.
|
|
||||||
void RemoveNotification(content::DesktopNotificationDelegate* delegate);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void CancelNotification(content::DesktopNotificationDelegate* delegate);
|
|
||||||
|
|
||||||
// The userInfo of NSUserNotification can not store pointers (because they are
|
|
||||||
// not in property list), so we have to track them in a C++ map.
|
|
||||||
// Also notice that the delegate acts as "ID" or "Key", because it is certain
|
|
||||||
// that each notification has a unique delegate.
|
|
||||||
typedef std::map<content::DesktopNotificationDelegate*, base::scoped_nsobject<NSUserNotification>>
|
|
||||||
NotificationsMap;
|
|
||||||
NotificationsMap notifications_map_;
|
|
||||||
|
|
||||||
base::scoped_nsobject<BRYUserNotificationCenterDelegate> delegate_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace brightray
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,133 +0,0 @@
|
||||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
|
||||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE-CHROMIUM file.
|
|
||||||
|
|
||||||
#import "browser/notification_presenter_mac.h"
|
|
||||||
|
|
||||||
#include "base/bind.h"
|
|
||||||
#include "base/stl_util.h"
|
|
||||||
#include "base/mac/mac_util.h"
|
|
||||||
#include "base/strings/sys_string_conversions.h"
|
|
||||||
#include "content/public/common/platform_notification_data.h"
|
|
||||||
#include "content/public/browser/desktop_notification_delegate.h"
|
|
||||||
#include "skia/ext/skia_utils_mac.h"
|
|
||||||
|
|
||||||
@interface BRYUserNotificationCenterDelegate : NSObject<NSUserNotificationCenterDelegate> {
|
|
||||||
@private
|
|
||||||
brightray::NotificationPresenterMac* presenter_;
|
|
||||||
}
|
|
||||||
- (instancetype)initWithNotificationPresenter:(brightray::NotificationPresenterMac*)presenter;
|
|
||||||
@end
|
|
||||||
|
|
||||||
namespace brightray {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
NotificationPresenter* NotificationPresenter::Create() {
|
|
||||||
return new NotificationPresenterMac;
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationPresenterMac::NotificationPresenterMac()
|
|
||||||
: delegate_([[BRYUserNotificationCenterDelegate alloc] initWithNotificationPresenter:this]) {
|
|
||||||
NSUserNotificationCenter.defaultUserNotificationCenter.delegate = delegate_;
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationPresenterMac::~NotificationPresenterMac() {
|
|
||||||
NSUserNotificationCenter.defaultUserNotificationCenter.delegate = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationPresenterMac::ShowNotification(
|
|
||||||
const content::PlatformNotificationData& data,
|
|
||||||
const SkBitmap& icon,
|
|
||||||
scoped_ptr<content::DesktopNotificationDelegate> delegate,
|
|
||||||
base::Closure* cancel_callback) {
|
|
||||||
auto notification = [[NSUserNotification alloc] init];
|
|
||||||
notification.title = base::SysUTF16ToNSString(data.title);
|
|
||||||
notification.informativeText = base::SysUTF16ToNSString(data.body);
|
|
||||||
|
|
||||||
if ([notification respondsToSelector:@selector(setContentImage:)] && !icon.drawsNothing())
|
|
||||||
notification.contentImage = gfx::SkBitmapToNSImageWithColorSpace(icon, base::mac::GetGenericRGBColorSpace());
|
|
||||||
|
|
||||||
notifications_map_[delegate.get()].reset(notification);
|
|
||||||
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:notification];
|
|
||||||
|
|
||||||
if (cancel_callback)
|
|
||||||
*cancel_callback = base::Bind(
|
|
||||||
&NotificationPresenterMac::CancelNotification,
|
|
||||||
base::Unretained(this),
|
|
||||||
delegate.release());
|
|
||||||
}
|
|
||||||
|
|
||||||
content::DesktopNotificationDelegate* NotificationPresenterMac::GetDelegateFromNotification(
|
|
||||||
NSUserNotification* notification) {
|
|
||||||
for (NotificationsMap::const_iterator it = notifications_map_.begin();
|
|
||||||
it != notifications_map_.end(); ++it)
|
|
||||||
if ([it->second isEqual:notification])
|
|
||||||
return it->first;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationPresenterMac::RemoveNotification(content::DesktopNotificationDelegate* delegate) {
|
|
||||||
if (ContainsKey(notifications_map_, delegate)) {
|
|
||||||
delete delegate;
|
|
||||||
notifications_map_.erase(delegate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationPresenterMac::CancelNotification(content::DesktopNotificationDelegate* delegate) {
|
|
||||||
if (!ContainsKey(notifications_map_, delegate))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Notifications in -deliveredNotifications aren't the same objects we passed to
|
|
||||||
// -deliverNotification:, but they will respond YES to -isEqual:.
|
|
||||||
auto notification = notifications_map_[delegate];
|
|
||||||
auto center = NSUserNotificationCenter.defaultUserNotificationCenter;
|
|
||||||
for (NSUserNotification* deliveredNotification in center.deliveredNotifications)
|
|
||||||
if ([notification isEqual:deliveredNotification]) {
|
|
||||||
[center removeDeliveredNotification:deliveredNotification];
|
|
||||||
delegate->NotificationClosed();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveNotification(delegate);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace brightray
|
|
||||||
|
|
||||||
@implementation BRYUserNotificationCenterDelegate
|
|
||||||
|
|
||||||
- (instancetype)initWithNotificationPresenter:(brightray::NotificationPresenterMac*)presenter {
|
|
||||||
self = [super init];
|
|
||||||
if (!self)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
presenter_ = presenter;
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)userNotificationCenter:(NSUserNotificationCenter*)center
|
|
||||||
didDeliverNotification:(NSUserNotification*)notification {
|
|
||||||
auto delegate = presenter_->GetDelegateFromNotification(notification);
|
|
||||||
if (delegate)
|
|
||||||
delegate->NotificationDisplayed();
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)userNotificationCenter:(NSUserNotificationCenter*)center
|
|
||||||
didActivateNotification:(NSUserNotification *)notification {
|
|
||||||
auto delegate = presenter_->GetDelegateFromNotification(notification);
|
|
||||||
if (delegate) {
|
|
||||||
delegate->NotificationClick();
|
|
||||||
presenter_->RemoveNotification(delegate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center
|
|
||||||
shouldPresentNotification:(NSUserNotification*)notification {
|
|
||||||
// Display notifications even if the app is active.
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
84
brightray/browser/platform_notification_service.cc
Normal file
84
brightray/browser/platform_notification_service.cc
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
// 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/platform_notification_service.h"
|
||||||
|
|
||||||
|
#include "browser/browser_client.h"
|
||||||
|
#include "browser/notification.h"
|
||||||
|
#include "browser/notification_delegate_adapter.h"
|
||||||
|
#include "browser/notification_presenter.h"
|
||||||
|
#include "content/public/common/platform_notification_data.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void RemoveNotification(base::WeakPtr<Notification> notification) {
|
||||||
|
if (notification)
|
||||||
|
notification->Dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
PlatformNotificationService::PlatformNotificationService(
|
||||||
|
BrowserClient* browser_client)
|
||||||
|
: browser_client_(browser_client) {
|
||||||
|
}
|
||||||
|
|
||||||
|
PlatformNotificationService::~PlatformNotificationService() {}
|
||||||
|
|
||||||
|
blink::WebNotificationPermission PlatformNotificationService::CheckPermissionOnUIThread(
|
||||||
|
content::BrowserContext* browser_context,
|
||||||
|
const GURL& origin,
|
||||||
|
int render_process_id) {
|
||||||
|
return blink::WebNotificationPermissionAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
blink::WebNotificationPermission PlatformNotificationService::CheckPermissionOnIOThread(
|
||||||
|
content::ResourceContext* resource_context,
|
||||||
|
const GURL& origin,
|
||||||
|
int render_process_id) {
|
||||||
|
return blink::WebNotificationPermissionAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlatformNotificationService::DisplayNotification(
|
||||||
|
content::BrowserContext* browser_context,
|
||||||
|
const GURL& origin,
|
||||||
|
const SkBitmap& icon,
|
||||||
|
const content::PlatformNotificationData& data,
|
||||||
|
scoped_ptr<content::DesktopNotificationDelegate> delegate,
|
||||||
|
base::Closure* cancel_callback) {
|
||||||
|
auto presenter = browser_client_->GetNotificationPresenter();
|
||||||
|
if (!presenter)
|
||||||
|
return;
|
||||||
|
scoped_ptr<NotificationDelegateAdapter> adapter(
|
||||||
|
new NotificationDelegateAdapter(delegate.Pass()));
|
||||||
|
auto notification = presenter->CreateNotification(adapter.get());
|
||||||
|
if (notification) {
|
||||||
|
ignore_result(adapter.release()); // it will release itself automatically.
|
||||||
|
notification->Show(data.title, data.body, data.icon, icon);
|
||||||
|
*cancel_callback = base::Bind(&RemoveNotification, notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlatformNotificationService::DisplayPersistentNotification(
|
||||||
|
content::BrowserContext* browser_context,
|
||||||
|
int64_t service_worker_registration_id,
|
||||||
|
const GURL& origin,
|
||||||
|
const SkBitmap& icon,
|
||||||
|
const content::PlatformNotificationData& notification_data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlatformNotificationService::ClosePersistentNotification(
|
||||||
|
content::BrowserContext* browser_context,
|
||||||
|
int64_t persistent_notification_id) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlatformNotificationService::GetDisplayedPersistentNotifications(
|
||||||
|
content::BrowserContext* browser_context,
|
||||||
|
std::set<std::string>* displayed_notifications) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace brightray
|
|
@ -2,31 +2,22 @@
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE-CHROMIUM file.
|
// found in the LICENSE-CHROMIUM file.
|
||||||
|
|
||||||
#ifndef BROWSER_PLATFORM_NOTIFICATION_SERVICE_IMPL_H_
|
#ifndef BROWSER_PLATFORM_NOTIFICATION_SERVICE_H_
|
||||||
#define BROWSER_PLATFORM_NOTIFICATION_SERVICE_IMPL_H_
|
#define BROWSER_PLATFORM_NOTIFICATION_SERVICE_H_
|
||||||
|
|
||||||
#include "base/memory/singleton.h"
|
|
||||||
#include "content/public/browser/platform_notification_service.h"
|
#include "content/public/browser/platform_notification_service.h"
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
||||||
class NotificationPresenter;
|
class BrowserClient;
|
||||||
|
|
||||||
class PlatformNotificationServiceImpl
|
class PlatformNotificationService
|
||||||
: public content::PlatformNotificationService {
|
: public content::PlatformNotificationService {
|
||||||
public:
|
public:
|
||||||
// Returns the active instance of the service in the browser process. Safe to
|
explicit PlatformNotificationService(BrowserClient* browser_client);
|
||||||
// be called from any thread.
|
~PlatformNotificationService() override;
|
||||||
static PlatformNotificationServiceImpl* GetInstance();
|
|
||||||
|
|
||||||
NotificationPresenter* notification_presenter();
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend struct base::DefaultSingletonTraits<PlatformNotificationServiceImpl>;
|
|
||||||
|
|
||||||
PlatformNotificationServiceImpl();
|
|
||||||
~PlatformNotificationServiceImpl() override;
|
|
||||||
|
|
||||||
|
protected:
|
||||||
// content::PlatformNotificationService:
|
// content::PlatformNotificationService:
|
||||||
blink::WebNotificationPermission CheckPermissionOnUIThread(
|
blink::WebNotificationPermission CheckPermissionOnUIThread(
|
||||||
content::BrowserContext* browser_context,
|
content::BrowserContext* browser_context,
|
||||||
|
@ -56,11 +47,12 @@ class PlatformNotificationServiceImpl
|
||||||
content::BrowserContext* browser_context,
|
content::BrowserContext* browser_context,
|
||||||
std::set<std::string>* displayed_notifications) override;
|
std::set<std::string>* displayed_notifications) override;
|
||||||
|
|
||||||
scoped_ptr<NotificationPresenter> notification_presenter_;
|
private:
|
||||||
|
BrowserClient* browser_client_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(PlatformNotificationServiceImpl);
|
DISALLOW_COPY_AND_ASSIGN(PlatformNotificationService);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace brightray
|
} // namespace brightray
|
||||||
|
|
||||||
#endif // BROWSER_PLATFORM_NOTIFICATION_SERVICE_IMPL_H_
|
#endif // BROWSER_PLATFORM_NOTIFICATION_SERVICE_H_
|
|
@ -1,85 +0,0 @@
|
||||||
// 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/platform_notification_service_impl.h"
|
|
||||||
|
|
||||||
#include "browser/notification_presenter.h"
|
|
||||||
|
|
||||||
#include "content/public/browser/desktop_notification_delegate.h"
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
#include "base/win/windows_version.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace brightray {
|
|
||||||
|
|
||||||
// static
|
|
||||||
PlatformNotificationServiceImpl*
|
|
||||||
PlatformNotificationServiceImpl::GetInstance() {
|
|
||||||
return base::Singleton<PlatformNotificationServiceImpl>::get();
|
|
||||||
}
|
|
||||||
|
|
||||||
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_) {
|
|
||||||
// Create a new presenter if on OS X, Linux, or Windows 8+
|
|
||||||
notification_presenter_.reset(NotificationPresenter::Create());
|
|
||||||
}
|
|
||||||
return notification_presenter_.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
blink::WebNotificationPermission PlatformNotificationServiceImpl::CheckPermissionOnUIThread(
|
|
||||||
content::BrowserContext* browser_context,
|
|
||||||
const GURL& origin,
|
|
||||||
int render_process_id) {
|
|
||||||
return blink::WebNotificationPermissionAllowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
blink::WebNotificationPermission PlatformNotificationServiceImpl::CheckPermissionOnIOThread(
|
|
||||||
content::ResourceContext* resource_context,
|
|
||||||
const GURL& origin,
|
|
||||||
int render_process_id) {
|
|
||||||
return blink::WebNotificationPermissionAllowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlatformNotificationServiceImpl::DisplayNotification(
|
|
||||||
content::BrowserContext* browser_context,
|
|
||||||
const GURL& origin,
|
|
||||||
const SkBitmap& icon,
|
|
||||||
const content::PlatformNotificationData& notification_data,
|
|
||||||
scoped_ptr<content::DesktopNotificationDelegate> delegate,
|
|
||||||
base::Closure* cancel_callback) {
|
|
||||||
auto presenter = notification_presenter();
|
|
||||||
if (presenter)
|
|
||||||
presenter->ShowNotification(notification_data, icon, delegate.Pass(), cancel_callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlatformNotificationServiceImpl::DisplayPersistentNotification(
|
|
||||||
content::BrowserContext* browser_context,
|
|
||||||
int64_t service_worker_registration_id,
|
|
||||||
const GURL& origin,
|
|
||||||
const SkBitmap& icon,
|
|
||||||
const content::PlatformNotificationData& notification_data) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlatformNotificationServiceImpl::ClosePersistentNotification(
|
|
||||||
content::BrowserContext* browser_context,
|
|
||||||
int64_t persistent_notification_id) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PlatformNotificationServiceImpl::GetDisplayedPersistentNotifications(
|
|
||||||
content::BrowserContext* browser_context,
|
|
||||||
std::set<std::string>* displayed_notifications) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace brightray
|
|
|
@ -31,11 +31,6 @@ bool SaveIconToPath(const SkBitmap& bitmap, const base::FilePath& path) {
|
||||||
return base::WriteFile(path, data, size) == size;
|
return base::WriteFile(path, data, size) == size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveNotification(base::WeakPtr<WindowsToastNotification> notification) {
|
|
||||||
if (notification)
|
|
||||||
notification->DismissNotification();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -58,23 +53,7 @@ bool NotificationPresenterWin::Init() {
|
||||||
return temp_dir_.CreateUniqueTempDir();
|
return temp_dir_.CreateUniqueTempDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationPresenterWin::ShowNotification(
|
base::string16 NotificationPresenterWin::SaveIconToFilesystem(
|
||||||
const content::PlatformNotificationData& data,
|
|
||||||
const SkBitmap& icon,
|
|
||||||
scoped_ptr<content::DesktopNotificationDelegate> delegate,
|
|
||||||
base::Closure* cancel_callback) {
|
|
||||||
// This class manages itself.
|
|
||||||
auto notification = new WindowsToastNotification(delegate.Pass());
|
|
||||||
notification->ShowNotification(
|
|
||||||
data.title, data.body, SaveIconToFilesystem(icon, data.icon));
|
|
||||||
|
|
||||||
if (cancel_callback) {
|
|
||||||
*cancel_callback = base::Bind(
|
|
||||||
&RemoveNotification, notification->GetWeakPtr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring NotificationPresenterWin::SaveIconToFilesystem(
|
|
||||||
const SkBitmap& icon, const GURL& origin) {
|
const SkBitmap& icon, const GURL& origin) {
|
||||||
std::string filename = base::MD5String(origin.spec()) + ".png";
|
std::string filename = base::MD5String(origin.spec()) + ".png";
|
||||||
base::FilePath path = temp_dir_.path().Append(base::UTF8ToUTF16(filename));
|
base::FilePath path = temp_dir_.path().Append(base::UTF8ToUTF16(filename));
|
||||||
|
|
|
@ -16,12 +16,12 @@
|
||||||
#ifndef BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_
|
#ifndef BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_
|
||||||
#define BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_
|
#define BRIGHTRAY_BROWSER_WIN_NOTIFICATION_PRESENTER_WIN_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "base/files/scoped_temp_dir.h"
|
#include "base/files/scoped_temp_dir.h"
|
||||||
|
#include "base/strings/string16.h"
|
||||||
#include "browser/notification_presenter.h"
|
#include "browser/notification_presenter.h"
|
||||||
|
|
||||||
class GURL;
|
class GURL;
|
||||||
|
class SkBitmap;
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
|
||||||
|
@ -32,15 +32,9 @@ class NotificationPresenterWin : public NotificationPresenter {
|
||||||
|
|
||||||
bool Init();
|
bool Init();
|
||||||
|
|
||||||
void ShowNotification(
|
base::string16 SaveIconToFilesystem(const SkBitmap& icon, const GURL& origin);
|
||||||
const content::PlatformNotificationData&,
|
|
||||||
const SkBitmap& icon,
|
|
||||||
scoped_ptr<content::DesktopNotificationDelegate> delegate,
|
|
||||||
base::Closure* cancel_callback) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::wstring SaveIconToFilesystem(const SkBitmap& icon, const GURL& origin);
|
|
||||||
|
|
||||||
base::ScopedTempDir temp_dir_;
|
base::ScopedTempDir temp_dir_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(NotificationPresenterWin);
|
DISALLOW_COPY_AND_ASSIGN(NotificationPresenterWin);
|
||||||
|
|
|
@ -8,9 +8,10 @@
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
#include "browser/notification_delegate.h"
|
||||||
#include "browser/win/scoped_hstring.h"
|
#include "browser/win/scoped_hstring.h"
|
||||||
|
#include "browser/win/notification_presenter_win.h"
|
||||||
#include "common/application_info.h"
|
#include "common/application_info.h"
|
||||||
#include "content/public/browser/desktop_notification_delegate.h"
|
|
||||||
|
|
||||||
using namespace ABI::Windows::Data::Xml::Dom;
|
using namespace ABI::Windows::Data::Xml::Dom;
|
||||||
|
|
||||||
|
@ -31,6 +32,12 @@ bool GetAppUserModelId(ScopedHString* app_id) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
// static
|
||||||
|
Notification* Notification::Create(NotificationDelegate* delegate,
|
||||||
|
NotificationPresenter* presenter) {
|
||||||
|
return new WindowsToastNotification(delegate, presenter);
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ComPtr<ABI::Windows::UI::Notifications::IToastNotificationManagerStatics>
|
ComPtr<ABI::Windows::UI::Notifications::IToastNotificationManagerStatics>
|
||||||
WindowsToastNotification::toast_manager_;
|
WindowsToastNotification::toast_manager_;
|
||||||
|
@ -61,61 +68,83 @@ bool WindowsToastNotification::Initialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowsToastNotification::WindowsToastNotification(
|
WindowsToastNotification::WindowsToastNotification(
|
||||||
scoped_ptr<content::DesktopNotificationDelegate> delegate)
|
NotificationDelegate* delegate,
|
||||||
: delegate_(delegate.Pass()),
|
NotificationPresenter* presenter)
|
||||||
weak_factory_(this) {
|
: Notification(delegate, presenter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowsToastNotification::~WindowsToastNotification() {
|
WindowsToastNotification::~WindowsToastNotification() {
|
||||||
|
// Remove the notification on exit.
|
||||||
|
if (toast_notification_) {
|
||||||
|
RemoveCallbacks(toast_notification_.Get());
|
||||||
|
Dismiss();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowsToastNotification::ShowNotification(
|
void WindowsToastNotification::Show(
|
||||||
const std::wstring& title,
|
const base::string16& title,
|
||||||
const std::wstring& msg,
|
const base::string16& msg,
|
||||||
const std::wstring& icon_path) {
|
const GURL& icon_url,
|
||||||
|
const SkBitmap& icon) {
|
||||||
|
auto presenter_win = static_cast<NotificationPresenterWin*>(presenter());
|
||||||
|
std::wstring icon_path = presenter_win->SaveIconToFilesystem(icon, icon_url);
|
||||||
|
|
||||||
ComPtr<IXmlDocument> toast_xml;
|
ComPtr<IXmlDocument> toast_xml;
|
||||||
if(FAILED(GetToastXml(toast_manager_.Get(), title, msg, icon_path, &toast_xml)))
|
if(FAILED(GetToastXml(toast_manager_.Get(), title, msg, icon_path, &toast_xml))) {
|
||||||
|
NotificationFailed();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ScopedHString toast_str(
|
ScopedHString toast_str(
|
||||||
RuntimeClass_Windows_UI_Notifications_ToastNotification);
|
RuntimeClass_Windows_UI_Notifications_ToastNotification);
|
||||||
if (!toast_str.success())
|
if (!toast_str.success()) {
|
||||||
|
NotificationFailed();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ComPtr<ABI::Windows::UI::Notifications::IToastNotificationFactory> toast_factory;
|
ComPtr<ABI::Windows::UI::Notifications::IToastNotificationFactory> toast_factory;
|
||||||
if (FAILED(Windows::Foundation::GetActivationFactory(toast_str,
|
if (FAILED(Windows::Foundation::GetActivationFactory(toast_str,
|
||||||
&toast_factory)))
|
&toast_factory))) {
|
||||||
|
NotificationFailed();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (FAILED(toast_factory->CreateToastNotification(toast_xml.Get(),
|
if (FAILED(toast_factory->CreateToastNotification(toast_xml.Get(),
|
||||||
&toast_notification_)))
|
&toast_notification_))) {
|
||||||
|
NotificationFailed();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (FAILED(SetupCallbacks(toast_notification_.Get())))
|
if (FAILED(SetupCallbacks(toast_notification_.Get()))) {
|
||||||
|
NotificationFailed();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (FAILED(toast_notifier_->Show(toast_notification_.Get())))
|
if (FAILED(toast_notifier_->Show(toast_notification_.Get()))) {
|
||||||
|
NotificationFailed();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
delegate_->NotificationDisplayed();
|
delegate()->NotificationDisplayed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowsToastNotification::DismissNotification() {
|
void WindowsToastNotification::Dismiss() {
|
||||||
toast_notifier_->Hide(toast_notification_.Get());
|
toast_notifier_->Hide(toast_notification_.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowsToastNotification::NotificationClicked() {
|
void WindowsToastNotification::NotificationClicked() {
|
||||||
delegate_->NotificationClick();
|
delegate()->NotificationClick();
|
||||||
delete this;
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowsToastNotification::NotificationDismissed() {
|
void WindowsToastNotification::NotificationDismissed() {
|
||||||
delegate_->NotificationClosed();
|
delegate()->NotificationClosed();
|
||||||
delete this;
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowsToastNotification::NotificationFailed() {
|
void WindowsToastNotification::NotificationFailed() {
|
||||||
delete this;
|
delegate()->NotificationFailed();
|
||||||
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowsToastNotification::GetToastXml(
|
bool WindowsToastNotification::GetToastXml(
|
||||||
|
@ -263,16 +292,27 @@ bool WindowsToastNotification::AppendTextToXml(
|
||||||
return SUCCEEDED(node->AppendChild(text_node.Get(), &append_node));
|
return SUCCEEDED(node->AppendChild(text_node.Get(), &append_node));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowsToastNotification::SetupCallbacks(ABI::Windows::UI::Notifications::IToastNotification* toast) {
|
bool WindowsToastNotification::SetupCallbacks(
|
||||||
EventRegistrationToken activatedToken, dismissedToken, failedToken;
|
ABI::Windows::UI::Notifications::IToastNotification* toast) {
|
||||||
event_handler_ = Make<ToastEventHandler>(this);
|
event_handler_ = Make<ToastEventHandler>(this);
|
||||||
if (FAILED(toast->add_Activated(event_handler_.Get(), &activatedToken)))
|
if (FAILED(toast->add_Activated(event_handler_.Get(), &activated_token_)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (FAILED(toast->add_Dismissed(event_handler_.Get(), &dismissedToken)))
|
if (FAILED(toast->add_Dismissed(event_handler_.Get(), &dismissed_token_)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return SUCCEEDED(toast->add_Failed(event_handler_.Get(), &failedToken));
|
return SUCCEEDED(toast->add_Failed(event_handler_.Get(), &failed_token_));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowsToastNotification::RemoveCallbacks(
|
||||||
|
ABI::Windows::UI::Notifications::IToastNotification* toast) {
|
||||||
|
if (FAILED(toast->remove_Activated(activated_token_)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (FAILED(toast->remove_Dismissed(dismissed_token_)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return SUCCEEDED(toast->remove_Failed(failed_token_));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -10,10 +10,7 @@
|
||||||
#include <windows.ui.notifications.h>
|
#include <windows.ui.notifications.h>
|
||||||
#include <wrl/implements.h>
|
#include <wrl/implements.h>
|
||||||
|
|
||||||
#include "base/bind.h"
|
#include "browser/notification.h"
|
||||||
#include "base/memory/weak_ptr.h"
|
|
||||||
#include "content/public/browser/desktop_notification_delegate.h"
|
|
||||||
#include "content/public/common/platform_notification_data.h"
|
|
||||||
|
|
||||||
using namespace Microsoft::WRL;
|
using namespace Microsoft::WRL;
|
||||||
|
|
||||||
|
@ -31,23 +28,22 @@ using DesktopToastFailedEventHandler =
|
||||||
ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification*,
|
ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification*,
|
||||||
ABI::Windows::UI::Notifications::ToastFailedEventArgs*>;
|
ABI::Windows::UI::Notifications::ToastFailedEventArgs*>;
|
||||||
|
|
||||||
class WindowsToastNotification {
|
class WindowsToastNotification : public Notification {
|
||||||
public:
|
public:
|
||||||
// Should be called before using this class.
|
// Should only be called by NotificationPresenterWin.
|
||||||
static bool Initialize();
|
static bool Initialize();
|
||||||
|
|
||||||
WindowsToastNotification(
|
WindowsToastNotification(NotificationDelegate* delegate,
|
||||||
scoped_ptr<content::DesktopNotificationDelegate> delegate);
|
NotificationPresenter* presenter);
|
||||||
~WindowsToastNotification();
|
~WindowsToastNotification();
|
||||||
|
|
||||||
void ShowNotification(const std::wstring& title,
|
protected:
|
||||||
const std::wstring& msg,
|
// Notification:
|
||||||
const std::wstring& icon_path);
|
void Show(const base::string16& title,
|
||||||
void DismissNotification();
|
const base::string16& msg,
|
||||||
|
const GURL& icon_url,
|
||||||
base::WeakPtr<WindowsToastNotification> GetWeakPtr() {
|
const SkBitmap& icon) override;
|
||||||
return weak_factory_.GetWeakPtr();
|
void Dismiss() override;
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class ToastEventHandler;
|
friend class ToastEventHandler;
|
||||||
|
@ -76,16 +72,18 @@ class WindowsToastNotification {
|
||||||
ABI::Windows::Data::Xml::Dom::IXmlNode* node,
|
ABI::Windows::Data::Xml::Dom::IXmlNode* node,
|
||||||
const std::wstring& text);
|
const std::wstring& text);
|
||||||
bool SetupCallbacks(ABI::Windows::UI::Notifications::IToastNotification* toast);
|
bool SetupCallbacks(ABI::Windows::UI::Notifications::IToastNotification* toast);
|
||||||
|
bool RemoveCallbacks(ABI::Windows::UI::Notifications::IToastNotification* toast);
|
||||||
|
|
||||||
static ComPtr<ABI::Windows::UI::Notifications::IToastNotificationManagerStatics> toast_manager_;
|
static ComPtr<ABI::Windows::UI::Notifications::IToastNotificationManagerStatics> toast_manager_;
|
||||||
static ComPtr<ABI::Windows::UI::Notifications::IToastNotifier> toast_notifier_;
|
static ComPtr<ABI::Windows::UI::Notifications::IToastNotifier> toast_notifier_;
|
||||||
|
|
||||||
scoped_ptr<content::DesktopNotificationDelegate> delegate_;
|
EventRegistrationToken activated_token_;
|
||||||
|
EventRegistrationToken dismissed_token_;
|
||||||
|
EventRegistrationToken failed_token_;
|
||||||
|
|
||||||
ComPtr<ToastEventHandler> event_handler_;
|
ComPtr<ToastEventHandler> event_handler_;
|
||||||
ComPtr<ABI::Windows::UI::Notifications::IToastNotification> toast_notification_;
|
ComPtr<ABI::Windows::UI::Notifications::IToastNotification> toast_notification_;
|
||||||
|
|
||||||
base::WeakPtrFactory<WindowsToastNotification> weak_factory_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(WindowsToastNotification);
|
DISALLOW_COPY_AND_ASSIGN(WindowsToastNotification);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,12 @@
|
||||||
'browser/mac/bry_application.mm',
|
'browser/mac/bry_application.mm',
|
||||||
'browser/mac/bry_inspectable_web_contents_view.h',
|
'browser/mac/bry_inspectable_web_contents_view.h',
|
||||||
'browser/mac/bry_inspectable_web_contents_view.mm',
|
'browser/mac/bry_inspectable_web_contents_view.mm',
|
||||||
|
'browser/mac/cocoa_notification.h',
|
||||||
|
'browser/mac/cocoa_notification.mm',
|
||||||
|
'browser/mac/notification_center_delegate.h',
|
||||||
|
'browser/mac/notification_center_delegate.mm',
|
||||||
|
'browser/mac/notification_presenter_mac.h',
|
||||||
|
'browser/mac/notification_presenter_mac.mm',
|
||||||
'browser/media/media_capture_devices_dispatcher.cc',
|
'browser/media/media_capture_devices_dispatcher.cc',
|
||||||
'browser/media/media_capture_devices_dispatcher.h',
|
'browser/media/media_capture_devices_dispatcher.h',
|
||||||
'browser/media/media_stream_devices_controller.cc',
|
'browser/media/media_stream_devices_controller.cc',
|
||||||
|
@ -54,15 +60,21 @@
|
||||||
'browser/net_log.h',
|
'browser/net_log.h',
|
||||||
'browser/network_delegate.cc',
|
'browser/network_delegate.cc',
|
||||||
'browser/network_delegate.h',
|
'browser/network_delegate.h',
|
||||||
|
'browser/notification_delegate.h',
|
||||||
|
'browser/notification_delegate_adapter.cc',
|
||||||
|
'browser/notification_delegate_adapter.h',
|
||||||
|
'browser/notification_presenter.cc',
|
||||||
'browser/notification_presenter.h',
|
'browser/notification_presenter.h',
|
||||||
'browser/notification_presenter_mac.h',
|
'browser/notification.cc',
|
||||||
'browser/notification_presenter_mac.mm',
|
'browser/notification.h',
|
||||||
'browser/permission_manager.cc',
|
'browser/permission_manager.cc',
|
||||||
'browser/permission_manager.h',
|
'browser/permission_manager.h',
|
||||||
'browser/platform_notification_service_impl.cc',
|
'browser/platform_notification_service.cc',
|
||||||
'browser/platform_notification_service_impl.h',
|
'browser/platform_notification_service.h',
|
||||||
'browser/linux/libnotify_loader.h',
|
'browser/linux/libnotify_loader.h',
|
||||||
'browser/linux/libnotify_loader.cc',
|
'browser/linux/libnotify_loader.cc',
|
||||||
|
'browser/linux/libnotify_notification.h',
|
||||||
|
'browser/linux/libnotify_notification.cc',
|
||||||
'browser/linux/notification_presenter_linux.h',
|
'browser/linux/notification_presenter_linux.h',
|
||||||
'browser/linux/notification_presenter_linux.cc',
|
'browser/linux/notification_presenter_linux.cc',
|
||||||
'browser/win/notification_presenter_win.h',
|
'browser/win/notification_presenter_win.h',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue