Merge pull request #186 from atom/dlopen-notify
Load libnotify dynamically
This commit is contained in:
commit
53e8c8841b
5 changed files with 190 additions and 15 deletions
113
brightray/browser/linux/libnotify_loader.cc
Normal file
113
brightray/browser/linux/libnotify_loader.cc
Normal file
|
@ -0,0 +1,113 @@
|
|||
// This is generated file. Do not modify directly.
|
||||
// Path to the code generator: tools/generate_library_loader/generate_library_loader.py .
|
||||
|
||||
#include "browser/linux/libnotify_loader.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
LibNotifyLoader::LibNotifyLoader() : loaded_(false) {
|
||||
}
|
||||
|
||||
LibNotifyLoader::~LibNotifyLoader() {
|
||||
CleanUp(loaded_);
|
||||
}
|
||||
|
||||
bool LibNotifyLoader::Load(const std::string& library_name) {
|
||||
if (loaded_)
|
||||
return false;
|
||||
|
||||
library_ = dlopen(library_name.c_str(), RTLD_LAZY);
|
||||
if (!library_)
|
||||
return false;
|
||||
|
||||
notify_is_initted =
|
||||
reinterpret_cast<decltype(this->notify_is_initted)>(
|
||||
dlsym(library_, "notify_is_initted"));
|
||||
notify_is_initted = &::notify_is_initted;
|
||||
if (!notify_is_initted) {
|
||||
CleanUp(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
notify_init =
|
||||
reinterpret_cast<decltype(this->notify_init)>(
|
||||
dlsym(library_, "notify_init"));
|
||||
notify_init = &::notify_init;
|
||||
if (!notify_init) {
|
||||
CleanUp(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
notify_notification_new =
|
||||
reinterpret_cast<decltype(this->notify_notification_new)>(
|
||||
dlsym(library_, "notify_notification_new"));
|
||||
notify_notification_new = &::notify_notification_new;
|
||||
if (!notify_notification_new) {
|
||||
CleanUp(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
notify_notification_add_action =
|
||||
reinterpret_cast<decltype(this->notify_notification_add_action)>(
|
||||
dlsym(library_, "notify_notification_add_action"));
|
||||
notify_notification_add_action = &::notify_notification_add_action;
|
||||
if (!notify_notification_add_action) {
|
||||
CleanUp(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
notify_notification_set_image_from_pixbuf =
|
||||
reinterpret_cast<decltype(this->notify_notification_set_image_from_pixbuf)>(
|
||||
dlsym(library_, "notify_notification_set_image_from_pixbuf"));
|
||||
notify_notification_set_image_from_pixbuf = &::notify_notification_set_image_from_pixbuf;
|
||||
if (!notify_notification_set_image_from_pixbuf) {
|
||||
CleanUp(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
notify_notification_set_timeout =
|
||||
reinterpret_cast<decltype(this->notify_notification_set_timeout)>(
|
||||
dlsym(library_, "notify_notification_set_timeout"));
|
||||
notify_notification_set_timeout = &::notify_notification_set_timeout;
|
||||
if (!notify_notification_set_timeout) {
|
||||
CleanUp(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
notify_notification_show =
|
||||
reinterpret_cast<decltype(this->notify_notification_show)>(
|
||||
dlsym(library_, "notify_notification_show"));
|
||||
notify_notification_show = &::notify_notification_show;
|
||||
if (!notify_notification_show) {
|
||||
CleanUp(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
notify_notification_close =
|
||||
reinterpret_cast<decltype(this->notify_notification_close)>(
|
||||
dlsym(library_, "notify_notification_close"));
|
||||
notify_notification_close = &::notify_notification_close;
|
||||
if (!notify_notification_close) {
|
||||
CleanUp(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
loaded_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void LibNotifyLoader::CleanUp(bool unload) {
|
||||
if (unload) {
|
||||
dlclose(library_);
|
||||
library_ = NULL;
|
||||
}
|
||||
loaded_ = false;
|
||||
notify_is_initted = NULL;
|
||||
notify_init = NULL;
|
||||
notify_notification_new = NULL;
|
||||
notify_notification_add_action = NULL;
|
||||
notify_notification_set_image_from_pixbuf = NULL;
|
||||
notify_notification_set_timeout = NULL;
|
||||
notify_notification_show = NULL;
|
||||
notify_notification_close = NULL;
|
||||
}
|
41
brightray/browser/linux/libnotify_loader.h
Normal file
41
brightray/browser/linux/libnotify_loader.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
// This is generated file. Do not modify directly.
|
||||
// Path to the code generator: tools/generate_library_loader/generate_library_loader.py .
|
||||
|
||||
#ifndef BRIGHTRAY_BROWSER_LINUX_LIBNOTIFY_LOADER_H_
|
||||
#define BRIGHTRAY_BROWSER_LINUX_LIBNOTIFY_LOADER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <libnotify/notify.h>
|
||||
|
||||
class LibNotifyLoader {
|
||||
public:
|
||||
LibNotifyLoader();
|
||||
~LibNotifyLoader();
|
||||
|
||||
bool Load(const std::string& library_name)
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
bool loaded() const { return loaded_; }
|
||||
|
||||
decltype(&::notify_is_initted) notify_is_initted;
|
||||
decltype(&::notify_init) notify_init;
|
||||
decltype(&::notify_notification_new) notify_notification_new;
|
||||
decltype(&::notify_notification_add_action) notify_notification_add_action;
|
||||
decltype(&::notify_notification_set_image_from_pixbuf) notify_notification_set_image_from_pixbuf;
|
||||
decltype(&::notify_notification_set_timeout) notify_notification_set_timeout;
|
||||
decltype(&::notify_notification_show) notify_notification_show;
|
||||
decltype(&::notify_notification_close) notify_notification_close;
|
||||
|
||||
private:
|
||||
void CleanUp(bool unload);
|
||||
|
||||
void* library_;
|
||||
bool loaded_;
|
||||
|
||||
// Disallow copy constructor and assignment operator.
|
||||
LibNotifyLoader(const LibNotifyLoader&);
|
||||
void operator=(const LibNotifyLoader&);
|
||||
};
|
||||
|
||||
#endif // BRIGHTRAY_BROWSER_LINUX_LIBNOTIFY_LOADER_H_
|
|
@ -10,11 +10,10 @@
|
|||
#include "base/files/file_enumerator.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
|
||||
#include "common/application_info.h"
|
||||
#include "content/public/browser/desktop_notification_delegate.h"
|
||||
#include "content/public/common/platform_notification_data.h"
|
||||
#include "common/application_info.h"
|
||||
#include <stdlib.h>
|
||||
#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
|
||||
namespace brightray {
|
||||
|
@ -65,10 +64,12 @@ content::DesktopNotificationDelegate* GetDelegateFromNotification(
|
|||
|
||||
// static
|
||||
NotificationPresenter* NotificationPresenter::Create() {
|
||||
if (!notify_is_initted()) {
|
||||
notify_init(GetApplicationName().c_str());
|
||||
}
|
||||
return new NotificationPresenterLinux;
|
||||
scoped_ptr<NotificationPresenterLinux> presenter(
|
||||
new NotificationPresenterLinux);
|
||||
if (presenter->Init())
|
||||
return presenter.release();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NotificationPresenterLinux::NotificationPresenterLinux()
|
||||
|
@ -81,6 +82,19 @@ NotificationPresenterLinux::~NotificationPresenterLinux() {
|
|||
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,
|
||||
|
@ -88,7 +102,8 @@ void NotificationPresenterLinux::ShowNotification(
|
|||
base::Closure* cancel_callback) {
|
||||
std::string title = base::UTF16ToUTF8(data.title);
|
||||
std::string body = base::UTF16ToUTF8(data.body);
|
||||
NotifyNotification* notification = notify_notification_new(title.c_str(), body.c_str(), nullptr);
|
||||
NotifyNotification* notification = libnotify_loader_.notify_notification_new(
|
||||
title.c_str(), body.c_str(), nullptr);
|
||||
|
||||
content::DesktopNotificationDelegate* delegate = delegate_ptr.release();
|
||||
|
||||
|
@ -100,19 +115,21 @@ void NotificationPresenterLinux::ShowNotification(
|
|||
// Zen Nature" is difficult, we will test for the presence of the indicate
|
||||
// dbus service
|
||||
if (!UnityIsRunning()) {
|
||||
notify_notification_add_action(
|
||||
libnotify_loader_.notify_notification_add_action(
|
||||
notification, "default", "View", OnNotificationViewThunk, this, nullptr);
|
||||
}
|
||||
|
||||
if (!icon.drawsNothing()) {
|
||||
GdkPixbuf* pixbuf = libgtk2ui::GdkPixbufFromSkBitmap(icon);
|
||||
notify_notification_set_image_from_pixbuf(notification, pixbuf);
|
||||
notify_notification_set_timeout(notification, NOTIFY_EXPIRES_DEFAULT);
|
||||
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;
|
||||
notify_notification_show(notification, &error);
|
||||
libnotify_loader_.notify_notification_show(notification, &error);
|
||||
if (error) {
|
||||
log_and_clear_error(error, "notify_notification_show");
|
||||
g_object_unref(notification);
|
||||
|
@ -131,7 +148,7 @@ void NotificationPresenterLinux::ShowNotification(
|
|||
|
||||
void NotificationPresenterLinux::CancelNotification(NotifyNotification* notification) {
|
||||
GError* error = nullptr;
|
||||
notify_notification_close(notification, &error);
|
||||
libnotify_loader_.notify_notification_close(notification, &error);
|
||||
if (error)
|
||||
log_and_clear_error(error, "notify_notification_close");
|
||||
|
||||
|
|
|
@ -6,11 +6,10 @@
|
|||
#ifndef BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_LINUX_H_
|
||||
#define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_LINUX_H_
|
||||
|
||||
#include <libnotify/notify.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "browser/linux/libnotify_loader.h"
|
||||
#include "browser/notification_presenter.h"
|
||||
#include "ui/base/glib/glib_signal.h"
|
||||
|
||||
|
@ -21,6 +20,7 @@ class NotificationPresenterLinux : public NotificationPresenter {
|
|||
NotificationPresenterLinux();
|
||||
~NotificationPresenterLinux();
|
||||
|
||||
bool Init();
|
||||
void RemoveNotification(NotifyNotification *notification);
|
||||
|
||||
private:
|
||||
|
@ -38,6 +38,8 @@ class NotificationPresenterLinux : public NotificationPresenter {
|
|||
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
|
||||
|
|
|
@ -61,6 +61,8 @@
|
|||
'browser/permission_manager.h',
|
||||
'browser/platform_notification_service_impl.cc',
|
||||
'browser/platform_notification_service_impl.h',
|
||||
'browser/linux/libnotify_loader.h',
|
||||
'browser/linux/libnotify_loader.cc',
|
||||
'browser/linux/notification_presenter_linux.h',
|
||||
'browser/linux/notification_presenter_linux.cc',
|
||||
'browser/win/notification_presenter_win.h',
|
||||
|
|
Loading…
Reference in a new issue