syncevo-dbus-server: notifications system made more generic.

The notifications system has been made template based. There is
a Factory object that creates NotificationManagers with the correct
template (mlite, libnotify, or a dummy no-op) according to the
platform.
This commit is contained in:
Salvatore Iovene 2011-06-13 01:27:33 -07:00
parent 9a849f6588
commit 8d771ab4d7
16 changed files with 764 additions and 133 deletions

View file

@ -494,12 +494,24 @@ if test $enable_dbus_service = "yes"; then
PKG_CHECK_MODULES(LIBNOTIFY, [libnotify gtk+-2.0], HAVE_LIBNOTIFY=yes, HAVE_LIBNOTIFY=no)
AC_ARG_ENABLE(notify,
AS_HELP_STRING([--enable-notify],
[send notifications for automatic sync events]),
[send notifications for automatic sync events, using libnotify]),
[ test "$enableval" = "no" || test $HAVE_LIBNOTIFY = "yes" || AC_ERROR([required libnotify package not found]) ],
[ test $HAVE_LIBNOTIFY = "yes" || AC_ERROR([required libnotify package not found, use --disable-notify to compile without notifications]) ])
[ test $HAVE_LIBNOTIFY = "yes" || AC_ERROR([required libnotify package not found, use --disable-notify to compile without libnotify based notifications]) ])
if test $HAVE_LIBNOTIFY = "yes"; then
AC_DEFINE(HAS_NOTIFY, 1, [define if libnotify could be used in dbus service])
fi
# Here we're using QtGui too because mlite fails to depend on it,
# despite using QAction.
PKG_CHECK_MODULES(MLITE, [mlite QtGui], HAVE_MLITE=yes, HAVE_MLITE=no)
AC_ARG_ENABLE(mlite,
AS_HELP_STRING([--enable-mlite],
[send notifications for automatic sync events, using mlite]),
[ test "$enableval" = "no" || test $HAVE_MLITE = "yes" || AC_ERROR([required mlite package not found]) ],
[ test $HAVE_MLITE = "yes" || AC_ERROR([required mlite package not found, use --disable-mlite to compile without mlite based notifications]) ])
if test $HAVE_MLITE = "yes"; then
AC_DEFINE(HAS_MLITE, 1, [define if mlite could be used in dbus service])
fi
AC_DEFINE(DBUS_SERVICE, 1, [define if dbus service is enabled])
fi
AC_SUBST(DBUS_CFLAGS)
@ -510,6 +522,8 @@ AC_SUBST(KEYRING_CFLAGS)
AC_SUBST(KEYRING_LIBS)
AC_SUBST(LIBNOTIFY_CFLAGS)
AC_SUBST(LIBNOTIFY_LIBS)
AC_SUBST(MLITE_CFLAGS)
AC_SUBST(MLITE_LIBS)
AC_SUBST(LIBEXECDIR)
AC_SUBST(BUTEOSYNCPROFILE_LIBS)
AC_SUBST(BUTEOSYNCPROFILE_CFLAGS)

View file

@ -183,15 +183,19 @@ distclean-local:
if COND_DBUS
syncevo_dbus_server_SOURCES = \
NotificationBackendNoop.cpp \
NotificationBackendLibnotify.cpp \
NotificationBackendMLite.cpp \
NotificationManagerFactory.cpp \
syncevo-dbus-server.cpp \
$(CORE_SOURCES)
if ENABLE_UNIT_TESTS
nodist_syncevo_dbus_server_SOURCES = ../test/test.cpp
endif
syncevo_dbus_server_LDADD = gdbus/libgdbussyncevo.la $(CORE_LDADD) $(KEYRING_LIBS) $(LIBNOTIFY_LIBS) $(KDE_KWALLET_LIBS) $(DBUS_LIBS)
syncevo_dbus_server_LDADD = gdbus/libgdbussyncevo.la $(CORE_LDADD) $(KEYRING_LIBS) $(LIBNOTIFY_LIBS) $(MLITE_LIBS) $(KDE_KWALLET_LIBS) $(DBUS_LIBS)
syncevo_dbus_server_CPPFLAGS = -DHAVE_CONFIG_H -I$(srcdir)/gdbus $(AM_CPPFLAGS) -DSYNCEVOLUTION_LOCALEDIR=\"${SYNCEVOLUTION_LOCALEDIR}\"
syncevo_dbus_server_CXXFLAGS = $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(LIBSOUP_CFLAGS) $(KEYRING_CFLAGS) $(LIBNOTIFY_CFLAGS) $(KDE_KWALLET_CFLAGS)
syncevo_dbus_server_CXXFLAGS = $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(LIBSOUP_CFLAGS) $(KEYRING_CFLAGS) $(LIBNOTIFY_CFLAGS) $(MLITE_CFLAGS) $(KDE_KWALLET_CFLAGS)
syncevo_dbus_server_LDFLAGS = $(CORE_LD_FLAGS) $(LIBSOUP_LIBS)
syncevo_dbus_server_DEPENDENCIES = gdbus/libgdbussyncevo.la $(EXTRA_LTLIBRARIES) $(CORE_DEP) $(SYNTHESIS_DEP)
endif

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef __NOTIFICATION_BACKEND_BASE_H
#define __NOTIFICATION_BACKEND_BASE_H
#include "syncevo/declarations.h"
#include <string>
SE_BEGIN_CXX
class NotificationBackendBase {
public:
virtual bool init() = 0;
virtual void publish(const std::string& summary,
const std::string& body,
const std::string& viewParams = std::string()) = 0;
};
SE_END_CXX
#endif

View file

@ -0,0 +1,126 @@
/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if HAS_NOTIFY
#include "NotificationBackendLibnotify.h"
#include <stdlib.h>
#include <glib/gi18n.h>
#include <boost/algorithm/string/predicate.hpp>
SE_BEGIN_CXX
NotificationBackendLibnotify::NotificationBackendLibnotify()
: m_initialized(false),
m_acceptsActions(false),
m_notification(false)
{
}
NotificationBackendLibnotify::~NotificationBackendLibnotify()
{
}
void NotificationBackendLibnotify::notifyAction(
NotifyNotification *notify,
gchar *action, gpointer userData)
{
if(boost::iequals(action, "view")) {
pid_t pid;
if((pid = fork()) == 0) {
// search sync-ui from $PATH
if(execlp("sync-ui", "sync-ui", (const char*)0) < 0) {
exit(0);
}
}
}
// if dismissed, ignore.
}
bool NotificationBackendLibnotify::init()
{
bindtextdomain (GETTEXT_PACKAGE, SYNCEVOLUTION_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
m_initialized = notify_init("SyncEvolution");
if(m_initialized) {
GList *list = notify_get_server_caps();
if(list) {
for(; list != NULL; list = list->next) {
if(boost::iequals((char *)list->data, "actions")) {
m_acceptsActions = true;
}
}
}
return true;
}
return false;
}
void NotificationBackendLibnotify::publish(
const std::string& summary, const std::string& body,
const std::string& viewParams)
{
if(!m_initialized)
return;
if(m_notification) {
notify_notification_clear_actions(m_notification);
notify_notification_close(m_notification, NULL);
}
#ifndef NOTIFY_CHECK_VERSION
# define NOTIFY_CHECK_VERSION(_x,_y,_z) 0
#endif
#if !NOTIFY_CHECK_VERSION(0,7,0)
m_notification = notify_notification_new(summary.c_str(), body.c_str(), NULL, NULL);
#else
m_notification = notify_notification_new(summary.c_str(), body.c_str(), NULL);
#endif
//if actions are not supported, don't add actions
//An example is Ubuntu Notify OSD. It uses an alert box
//instead of a bubble when a notification is appended with actions.
//the alert box won't be closed until user inputs.
//so disable it in case of no support of actions
if(m_acceptsActions) {
notify_notification_add_action(m_notification, "view",
_("View"), notifyAction,
(gpointer)viewParams.c_str(),
NULL);
// Use "default" as ID because that is what mutter-moblin
// recognizes: it then skips the action instead of adding it
// in addition to its own "Dismiss" button (always added).
notify_notification_add_action(m_notification, "default",
_("Dismiss"), notifyAction,
(gpointer)viewParams.c_str(),
NULL);
}
notify_notification_show(m_notification, NULL);
}
SE_END_CXX
#endif // HAS_NOTIFY

View file

@ -0,0 +1,75 @@
/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef __NOTIFICATION_BACKEND_LIBNOTIFY_H
#define __NOTIFICATION_BACKEND_LIBNOTIFY_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if HAS_NOTIFY
#include "syncevo/declarations.h"
#include "NotificationBackendBase.h"
#include <libnotify/notify.h>
SE_BEGIN_CXX
class NotificationBackendLibnotify : public NotificationBackendBase {
public:
NotificationBackendLibnotify();
virtual ~NotificationBackendLibnotify();
/**
* Callback for the notification action.
*/
static void notifyAction(NotifyNotification *notify,
gchar *action, gpointer userData);
bool init();
void publish(const std::string& summary, const std::string& body,
const std::string& viewParams = std::string());
private:
/**
* Flag to indicate whether libnotify has been successfully
* initialized.
*/
bool m_initialized;
/**
* Flag to indicate whether libnotify accepts actions.
*/
bool m_acceptsActions;
/**
* The current notification.
*/
NotifyNotification *m_notification;
};
SE_END_CXX
#endif // HAS_NOTIFY
#endif // __NOTIFICATION_BACKEND_LIBNOTIFY_H

View file

@ -0,0 +1,65 @@
/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "NotificationBackendMLite.h"
#include <mlite/MNotification>
#include <QString>
SE_BEGIN_CXX
/// TODO: these should really be in a common place.
#define SYNCEVOLUTION_SERVICE_NAME "org.syncevolution"
#define SYNCEVOLUTION_OBJECT_PATH "/org/syncevolution/Server"
#define SYNCEVOLUTION_INTERFACE "org.syncevolution.Server"
NotificationBackendMLite::NotificationBackendMLite()
{
}
NotificationBackendMLite::~NotificationBackendMLite()
{
}
bool NotificationBackendMLite::init()
{
return true;
}
void NotificationBackendMLite::publish(
const std::string& summary, const std::string& body,
const std::string& viewParams)
{
MNotification n ("Sync");
n.setSummary(QString::fromStdString(summary));
n.setBody(QString::fromStdString(body));
n.setImage("image://themedimage/icons/settings/sync");
MRemoteAction action(SYNCEVOLUTION_SERVICE_NAME,
SYNCEVOLUTION_OBJECT_PATH,
SYNCEVOLUTION_INTERFACE,
"org.syncevolution.Server.NotificationAction");
n.setAction(action);
n.publish();
}
SE_END_CXX

View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef __NOTIFICATION_BACKEND_MLITE_H
#define __NOTIFICATION_BACKEND_MLITE_H
#include "syncevo/declarations.h"
#include "NotificationBackendBase.h"
SE_BEGIN_CXX
class NotificationBackendMLite : public NotificationBackendBase {
public:
NotificationBackendMLite();
virtual ~NotificationBackendMLite();
bool init();
void publish(const std::string& summary, const std::string& body,
const std::string& viewParams = std::string());
};
SE_END_CXX
#endif // __NOTIFICATION_BACKEND_MLITE_H

View file

@ -0,0 +1,44 @@
/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "NotificationBackendNoop.h"
SE_BEGIN_CXX
NotificationBackendNoop::NotificationBackendNoop()
{
}
NotificationBackendNoop::~NotificationBackendNoop()
{
}
bool NotificationBackendNoop::init()
{
return true;
}
void NotificationBackendNoop::publish(
const std::string& summary, const std::string& body,
const std::string& viewParams)
{
}
SE_END_CXX

View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef __NOTIFICATION_BACKEND_NOOP_H
#define __NOTIFICATION_BACKEND_NOOP_H
#include "syncevo/declarations.h"
#include "NotificationBackendBase.h"
SE_BEGIN_CXX
class NotificationBackendNoop : public NotificationBackendBase {
public:
NotificationBackendNoop();
virtual ~NotificationBackendNoop();
bool init();
void publish(const std::string& summary, const std::string& body,
const std::string& viewParams = std::string());
};
SE_END_CXX
#endif // __NOTIFICATION_BACKEND_NOOP_H

View file

@ -0,0 +1,52 @@
/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "NotificationManager.h"
#include "syncevo/declarations.h"
#include <string>
SE_BEGIN_CXX
template <class T>
NotificationManager<T>::NotificationManager()
{
}
template <class T>
NotificationManager<T>::~NotificationManager()
{
}
template <class T>
bool NotificationManager<T>::init()
{
return m_backend->init();
}
template <class T>
void NotificationManager<T>::publish(const std::string& summary,
const std::string& body,
const std::string& viewParams)
{
m_backend->publish(summary, body, viewParams);
}
SE_END_CXX

73
src/NotificationManager.h Normal file
View file

@ -0,0 +1,73 @@
/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef __NOTIFICATION_MANAGER_H
#define __NOTIFICATION_MANAGER_H
#include "NotificationManagerBase.h"
#include "syncevo/declarations.h"
#include <string>
SE_BEGIN_CXX
template <class T>
class NotificationManager : public NotificationManagerBase {
public:
NotificationManager();
virtual ~NotificationManager();
bool init();
void publish(const std::string& summary, const std::string& body,
const std::string& viewParams = std::string());
private:
T m_backend;
};
template <class T>
NotificationManager<T>::NotificationManager()
{
}
template <class T>
NotificationManager<T>::~NotificationManager()
{
}
template <class T>
bool NotificationManager<T>::init()
{
return m_backend.init();
}
template <class T>
void NotificationManager<T>::publish(const std::string& summary,
const std::string& body,
const std::string& viewParams)
{
m_backend.publish(summary, body, viewParams);
}
SE_END_CXX
#endif

View file

@ -0,0 +1,48 @@
/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef __NOTIFICATION_MANAGER_BASE_H
#define __NOTIFICATION_MANAGER_BASE_H
#include "syncevo/declarations.h"
#include <string>
SE_BEGIN_CXX
class NotificationManagerBase {
public:
/** Initializes the backend. */
virtual bool init() { return true; }
/** Publishes the notification through the backend.
* @param summary The summary of the notification.
* @param body The main content of the notification.
* @param viewParams Parameters used by sync-ui (opened when the
* notification activated.
*/
virtual void publish(const std::string& summary,
const std::string& body,
const std::string& viewParams = std::string()) {}
};
SE_END_CXX
#endif

View file

@ -0,0 +1,58 @@
/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "NotificationManagerFactory.h"
#include "NotificationBackendNoop.h"
#include "NotificationBackendMLite.h"
#include "NotificationBackendLibnotify.h"
#include "NotificationManager.h"
#include <unistd.h>
SE_BEGIN_CXX
#define SYNC_UI_PATH "/usr/bin/sync-ui"
boost::shared_ptr<NotificationManagerBase> NotificationManagerFactory::createManager()
{
boost::shared_ptr<NotificationManagerBase> mgr;
/* Detect what kind of manager we need: if /usr/bin/sync-ui
* doesn't exists, we shall use the MLite backend; otherwise, if
* libnotify is enabled, we shall use the libnotify backend;
* if everything fails, then we'll use the no-op backend.
*/
if(access(SYNC_UI_PATH, F_OK) != 0) { // i.e. it does not exist
#if HAS_MLITE
mgr.reset(new NotificationManager<NotificationBackendMLite>());
#endif
} else { // it exists
#if HAS_NOTIFY
mgr.reset(new NotificationManager<NotificationBackendLibnotify>());
#else
mgr.reset(new NotificationManager<NotificationBackendNoop>());
#endif
}
return mgr;
}
SE_END_CXX

View file

@ -0,0 +1,45 @@
/*
* Copyright (C) 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef __NOTIFICATION_MANAGER_FACTORY_H
#define __NOTIFICATION_MANAGER_FACTORY_H
#include "syncevo/declarations.h"
#include "NotificationManager.h"
#include <boost/shared_ptr.hpp>
SE_BEGIN_CXX
class NotificationBackendBase;
class NotificationManagerFactory {
public:
/** Creates the appropriate NotificationManager for the current
* platform.
* Note: NotificationManagerFactory does not take ownership of
* the returned pointer: the user must delete it when done.
*/
static boost::shared_ptr<NotificationManagerBase> createManager();
};
SE_END_CXX
#endif

View file

@ -190,6 +190,14 @@ sometimes also a beta or alpha suffix),
</arg>
</method>
<method name="NotificationAction">
<doc:doc>
<doc:description>
Launches sync-ui as a reaction of the user activating a notification.
</doc:description>
</doc:doc>
</method>
<method name ="GetConfigs">
<doc:doc><doc:description>
<doc:para>

View file

@ -92,9 +92,7 @@ extern "C" {
#include <kwallet.h>
#endif
#ifdef HAS_NOTIFY
#include <libnotify/notify.h>
#endif
#include "NotificationManagerFactory.h"
using namespace GDBusCXX;
using namespace SyncEvo;
@ -710,6 +708,7 @@ class AutoSyncManager : public SessionListener
{
DBusServer &m_server;
public:
/**
* A single task for automatic sync.
* Each task maintain one task for only one sync URL, which never combines
@ -733,7 +732,8 @@ class AutoSyncManager : public SessionListener
AutoSyncTask(const string &peer, unsigned int delay, const string &url)
: m_peer(peer), m_delay(delay), m_url(url)
{}
{
}
/** compare whether two tasks are the same. May refine it later with more information */
bool operator==(const AutoSyncTask &right) const
@ -779,40 +779,6 @@ class AutoSyncManager : public SessionListener
void scheduleTaskList();
};
#ifdef HAS_NOTIFY
/**
* This class is to send notifications to notification server.
* Notifications are sent via 'send'. Once a new noficication is
* to be sent, the old notification will be closed and a new one
* is created for the new requirement.
*/
class Notification
{
public:
Notification();
~Notification();
/** callback of click button(actions) of notification */
static void notifyAction(NotifyNotification *notify, gchar *action, gpointer userData);
/**
* send a notification in the notification server
* Action for 'view' may pop up a sync-ui, but needs some
* parameters. 'viewParams' is the params used by sync-ui.
*/
void send(const char *summary, const char *body, const char *viewParams = NULL);
private:
/** flag to indicate whether libnotify is initalized successfully */
bool m_init;
/** flag to indicate whether libnotify accepts actions */
bool m_actions;
/** the current notification */
NotifyNotification *m_notification;
};
#endif
/** init a config and set up auto sync task for it */
void initConfig(const string &configName);
@ -843,10 +809,8 @@ class AutoSyncManager : public SessionListener
/** the current sync of session is successfully started */
bool m_syncSuccessStart;
#ifdef HAS_NOTIFY
/** used to send notifications */
Notification m_notify;
#endif
boost::shared_ptr<NotificationManagerBase> m_notificationManager;
/**
* It reads all peers which are enabled to do auto sync and store them in
@ -879,7 +843,7 @@ class AutoSyncManager : public SessionListener
public:
AutoSyncManager(DBusServer &server)
: m_server(server), m_syncSuccessStart(false)
: m_server(server), m_syncSuccessStart(false)
{
init();
}
@ -1278,6 +1242,17 @@ class DBusServer : public DBusObjectHelper,
setNotifications(true, caller, notifications);
}
/** Server.NotificationAction() */
void notificationAction(const Caller_t &caller) {
pid_t pid;
if((pid = fork()) == 0) {
// search sync-ui from $PATH
if(execlp("sync-ui", "sync-ui", (const char*)0) < 0) {
exit(0);
}
}
}
/** actual implementation of enable and disable */
void setNotifications(bool enable,
const Caller_t &caller,
@ -5652,6 +5627,7 @@ DBusServer::DBusServer(GMainLoop *loop, const DBusConnectionPtr &conn, int durat
add(this, &DBusServer::detachClient, "Detach");
add(this, &DBusServer::enableNotifications, "EnableNotifications");
add(this, &DBusServer::disableNotifications, "DisableNotifications");
add(this, &DBusServer::notificationAction, "NotificationAction");
add(this, &DBusServer::connect, "Connect");
add(this, &DBusServer::startSession, "StartSession");
add(this, &DBusServer::startSessionWithFlags, "StartSessionWithFlags");
@ -6445,6 +6421,9 @@ void AutoSyncManager::init()
BOOST_FOREACH(const SyncConfig::ConfigList::value_type &server, list) {
initConfig(server.first);
}
m_notificationManager = NotificationManagerFactory::createManager();
m_notificationManager->init();
}
void AutoSyncManager::initConfig(const string &configName)
@ -6648,20 +6627,17 @@ void AutoSyncManager::syncSuccessStart()
{
m_syncSuccessStart = true;
SE_LOG_INFO(NULL, NULL,"Automatic sync for '%s' has been successfully started.\n", m_activeTask->m_peer.c_str());
#ifdef HAS_NOTIFY
if (m_server.notificationsEnabled()) {
string summary = StringPrintf(_("%s is syncing"), m_activeTask->m_peer.c_str());
string body = StringPrintf(_("We have just started to sync your computer with the %s sync service."), m_activeTask->m_peer.c_str());
//TODO: set config information for 'sync-ui'
m_notify.send(summary.c_str(), body.c_str());
m_notificationManager->publish(summary, body);
}
#endif
}
void AutoSyncManager::syncDone(SyncMLStatus status)
{
SE_LOG_INFO(NULL, NULL,"Automatic sync for '%s' has been done.\n", m_activeTask->m_peer.c_str());
#ifdef HAS_NOTIFY
if (m_server.notificationsEnabled()) {
// send a notification to notification server
string summary, body;
@ -6670,101 +6646,20 @@ void AutoSyncManager::syncDone(SyncMLStatus status)
summary = StringPrintf(_("%s sync complete"), m_activeTask->m_peer.c_str());
body = StringPrintf(_("We have just finished syncing your computer with the %s sync service."), m_activeTask->m_peer.c_str());
//TODO: set config information for 'sync-ui'
m_notify.send(summary.c_str(), body.c_str());
m_notificationManager->publish(summary, body);
} else if(m_syncSuccessStart || (!m_syncSuccessStart && status == STATUS_FATAL)) {
//if sync is successfully started and has errors, or not started successful with a fatal problem
summary = StringPrintf(_("Sync problem."));
body = StringPrintf(_("Sorry, there's a problem with your sync that you need to attend to."));
//TODO: set config information for 'sync-ui'
m_notify.send(summary.c_str(), body.c_str());
m_notificationManager->publish(summary, body);
}
}
#endif
m_session.reset();
m_activeTask.reset();
m_syncSuccessStart = false;
}
#ifdef HAS_NOTIFY
AutoSyncManager::Notification::Notification()
{
bindtextdomain (GETTEXT_PACKAGE, SYNCEVOLUTION_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
m_init = notify_init("SyncEvolution");
m_actions = false;
m_notification = NULL;
// check whether 'actions' are supported by notification server
if(m_init) {
GList *list = notify_get_server_caps();
if(list) {
for(; list != NULL; list = list->next) {
if(boost::iequals((char *)list->data, "actions")) {
m_actions = true;
}
}
}
}
}
AutoSyncManager::Notification::~Notification()
{
if(m_init) {
notify_uninit();
}
}
void AutoSyncManager::Notification::notifyAction(NotifyNotification *notify,
gchar *action,
gpointer userData)
{
if(boost::iequals("view", action)) {
pid_t pid;
if((pid = fork()) == 0) {
//search sync-ui from $PATH
if(execlp("sync-ui", "sync-ui", (const char*)0) < 0) {
exit(0);
}
}
}
//if dismiss, ignore
}
void AutoSyncManager::Notification::send(const char *summary,
const char *body,
const char *viewParams)
{
if(!m_init)
return;
if(m_notification) {
notify_notification_clear_actions(m_notification);
notify_notification_close(m_notification, NULL);
}
#ifndef NOTIFY_CHECK_VERSION
# define NOTIFY_CHECK_VERSION(_x,_y,_z) 0
#endif
#if !NOTIFY_CHECK_VERSION(0,7,0)
m_notification = notify_notification_new(summary, body, NULL, NULL);
#else
m_notification = notify_notification_new(summary, body, NULL);
#endif
//if actions are not supported, don't add actions
//An example is Ubuntu Notify OSD. It uses an alert box
//instead of a bubble when a notification is appended with actions.
//the alert box won't be closed until user inputs.
//so disable it in case of no support of actions
if(m_actions) {
notify_notification_add_action(m_notification, "view", _("View"), notifyAction, (gpointer)viewParams, NULL);
// Use "default" as ID because that is what mutter-moblin
// recognizes: it then skips the action instead of adding it
// in addition to its own "Dismiss" button (always added).
notify_notification_add_action(m_notification, "default", _("Dismiss"), notifyAction, (gpointer)viewParams, NULL);
}
notify_notification_show(m_notification, NULL);
}
#endif
void AutoSyncManager::AutoSyncTaskList::createTimeoutSource()
{
//if interval is 0, only run auto sync when changes are detected.