gnome: add incoming call notifications

This patch requires libnotify.

Refs #73512

Change-Id: Icd98446ed64be42f5080b96924859973b28703dc
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 40f6ee2..da3d75a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,18 +19,6 @@
 SET(PROJECT_VERSION_MINOR 4)
 SET(PROJECT_VERSION_PATCH 0)
 
-# create config header file to pass cmake settings to source code
-CONFIGURE_FILE (
-   "${PROJECT_SOURCE_DIR}/src/config.h.in"
-   "${PROJECT_BINARY_DIR}/config.h"
-)
-
-# generate .desktop file
-CONFIGURE_FILE (
-   "${PROJECT_SOURCE_DIR}/gnome-ring.desktop.in"
-   "${PROJECT_BINARY_DIR}/gnome-ring.desktop"
-)
-
 # add the binary tree to the search path for include files
 # so that we will find config.h
 INCLUDE_DIRECTORIES("${PROJECT_BINARY_DIR}")
@@ -55,6 +43,7 @@
 PKG_CHECK_MODULES(CLUTTERGTK REQUIRED clutter-gtk-1.0)
 PKG_CHECK_MODULES(ICONSYMBLIC REQUIRED gnome-icon-theme-symbolic)
 PKG_CHECK_MODULES(EBOOK REQUIRED libebook-1.2>=3.10)
+PKG_CHECK_MODULES(LIBNOTIFY libnotify>=0.7.6) #optional
 
 # include libs
 INCLUDE_DIRECTORIES(${GTK3_INCLUDE_DIRS})
@@ -63,6 +52,7 @@
 INCLUDE_DIRECTORIES(${CLUTTER_INCLUDE_DIRS})
 INCLUDE_DIRECTORIES(${CLUTTERGTK_INCLUDE_DIRS})
 INCLUDE_DIRECTORIES(${EBOOK_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(${LIBNOTIFY_INCLUDE_DIRS})
 
 # link libs
 LINK_DIRECTORIES(${GTK3_LIBRARY_DIRS})
@@ -71,6 +61,7 @@
 LINK_DIRECTORIES(${CLUTTER_LIBRARY_DIRS})
 LINK_DIRECTORIES(${CLUTTERGTK_LIBRARY_DIRS})
 LINK_DIRECTORIES(${EBOOK_LIBRARY_DIRS})
+LINK_DIRECTORIES(${LIBNOTIFY_LIBRARY_DIRS})
 
 # lib compiler flags
 ADD_DEFINITIONS(${GTK3_CFLAGS})
@@ -80,6 +71,7 @@
 ADD_DEFINITIONS(${CLUTTER_CFLAGS})
 ADD_DEFINITIONS(${CLUTTERGTK_CFLAGS})
 ADD_DEFINITIONS(${EBOOK_CFLAGS})
+ADD_DEFINITIONS(${LIBNOTIFY_CFLAGS})
 
 IF(NOT ${ENABLE_STATIC} MATCHES false)
   SET(QT5_MODULE_PATH ${QT5_PATH}/lib/cmake)
@@ -213,6 +205,8 @@
    src/utils/models.cpp
    src/utils/calling.h
    src/utils/calling.cpp
+   src/ringnotify.h
+   src/ringnotify.cpp
 )
 
 # compile glib resource files to c code
@@ -241,6 +235,7 @@
    ${CLUTTER_LIBRARIES}
    ${CLUTTERGTK_LIBRARIES}
    ${EBOOK_LIBRARIES}
+   ${LIBNOTIFY_LIBRARIES}
    -lpthread
    -lrt
    )
@@ -252,9 +247,29 @@
    ${CLUTTER_LIBRARIES}
    ${CLUTTERGTK_LIBRARIES}
    ${EBOOK_LIBRARIES}
+   ${LIBNOTIFY_LIBRARIES}
    )
 ENDIF()
 
+# configure libnotify variable for config.h file
+IF( LIBNOTIFY_FOUND )
+   SET(USE_LIBNOTIFY 1)
+ELSE()
+   SET(USE_LIBNOTIFY 0)
+ENDIF()
+
+# create config header file to pass cmake settings to source code
+CONFIGURE_FILE (
+   "${PROJECT_SOURCE_DIR}/src/config.h.in"
+   "${PROJECT_BINARY_DIR}/config.h"
+)
+
+# generate .desktop file
+CONFIGURE_FILE (
+   "${PROJECT_SOURCE_DIR}/gnome-ring.desktop.in"
+   "${PROJECT_BINARY_DIR}/gnome-ring.desktop"
+)
+
 INSTALL(TARGETS gnome-ring
    RUNTIME DESTINATION bin
 )
diff --git a/src/config.h.in b/src/config.h.in
index 4b5a6d4..c42f439 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -2,4 +2,6 @@
 
 #define VERSION_MAJOR @PROJECT_VERSION_MAJOR@
 #define VERSION_MINOR @PROJECT_VERSION_MINOR@
-#define VERSION_PATCH @PROJECT_VERSION_PATCH@
\ No newline at end of file
+#define VERSION_PATCH @PROJECT_VERSION_PATCH@
+
+#define USE_LIBNOTIFY @USE_LIBNOTIFY@
diff --git a/src/ring_client.cpp b/src/ring_client.cpp
index c8f6176..c1f04ed 100644
--- a/src/ring_client.cpp
+++ b/src/ring_client.cpp
@@ -50,6 +50,7 @@
 #include "dialogs.h"
 #include "backends/edscontactbackend.h"
 #include "delegates/pixbufdelegate.h"
+#include "ringnotify.h"
 
 struct _RingClientClass
 {
@@ -266,6 +267,12 @@
        }
     });
 
+    /* send call notifications */
+    ring_notify_init();
+    QObject::connect(CallModel::instance(), &CallModel::incomingCall,
+        [=] (Call *call) { ring_notify_incoming_call(call);}
+    );
+
 #if GLIB_CHECK_VERSION(2,40,0)
     G_APPLICATION_CLASS(ring_client_parent_class)->startup(app);
 #else
@@ -338,6 +345,8 @@
     /* free the copied cmd line args */
     g_strfreev(priv->argv);
 
+    ring_notify_uninit();
+
     /* Chain up to the parent class */
     G_APPLICATION_CLASS(ring_client_parent_class)->shutdown(app);
 }
diff --git a/src/ringnotify.cpp b/src/ringnotify.cpp
new file mode 100644
index 0000000..d76ac97
--- /dev/null
+++ b/src/ringnotify.cpp
@@ -0,0 +1,104 @@
+/*
+ *  Copyright (C) 2015 Savoir-Faire Linux Inc.
+ *  Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#include "ringnotify.h"
+#include "config.h"
+
+#if USE_LIBNOTIFY
+#include <libnotify/notify.h>
+#include <memory>
+#include "delegates/pixbufdelegate.h"
+#include <call.h>
+#include <QtCore/QSize>
+#endif
+
+void
+ring_notify_init()
+{
+#if USE_LIBNOTIFY
+    notify_init("Ring");
+#endif
+}
+
+void
+ring_notify_uninit()
+{
+#if USE_LIBNOTIFY
+    if (notify_is_initted())
+        notify_uninit();
+#endif
+}
+
+gboolean
+ring_notify_is_initted()
+{
+#if USE_LIBNOTIFY
+    return notify_is_initted();
+#else
+    return FALSE;
+#endif
+}
+
+gboolean
+ring_notify_incoming_call(
+#if !USE_LIBNOTIFY
+    G_GNUC_UNUSED
+#endif
+    Call* call)
+{
+#if USE_LIBNOTIFY
+    g_return_val_if_fail(call, FALSE);
+
+    gchar *body = g_strdup_printf("%s", call->formattedName().toUtf8().constData());
+    NotifyNotification *notification = notify_notification_new("Incoming call", body, NULL);
+
+    /* get photo */
+    QVariant var_p = PixbufDelegate::instance()->callPhoto(
+        call->peerContactMethod(), QSize(50, 50), false);
+    std::shared_ptr<GdkPixbuf> photo = var_p.value<std::shared_ptr<GdkPixbuf>>();
+    notify_notification_set_image_from_pixbuf(notification, photo.get());
+
+    /* calls have highest urgency */
+    notify_notification_set_urgency(notification, NOTIFY_URGENCY_CRITICAL);
+
+    notify_notification_set_timeout(notification, NOTIFY_EXPIRES_DEFAULT);
+
+    GError *error = NULL;
+    if (notify_notification_show(notification, &error)) {
+        return TRUE;
+    } else {
+        g_warning("failed to send notification: %s", error->message);
+        g_clear_error(&error);
+        return FALSE;
+    }
+#else
+    return FALSE;
+#endif
+}
diff --git a/src/ringnotify.h b/src/ringnotify.h
new file mode 100644
index 0000000..a67e000
--- /dev/null
+++ b/src/ringnotify.h
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (C) 2015 Savoir-Faire Linux Inc.
+ *  Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *  Additional permission under GNU GPL version 3 section 7:
+ *
+ *  If you modify this program, or any covered work, by linking or
+ *  combining it with the OpenSSL project's OpenSSL library (or a
+ *  modified version of that library), containing parts covered by the
+ *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ *  grants you additional permission to convey the resulting work.
+ *  Corresponding Source for a non-source form of such a combination
+ *  shall include the source code for the parts of OpenSSL used as well
+ *  as that of the covered work.
+ */
+
+#ifndef RING_NOTIFY_H_
+#define RING_NOTIFY_H_
+
+#include <glib.h>
+
+class Call;
+
+G_BEGIN_DECLS
+
+void     ring_notify_init();
+void     ring_notify_uninit();
+gboolean ring_notify_is_initted();
+gboolean ring_notify_incoming_call(Call *call);
+
+G_END_DECLS
+
+#endif /* RING_NOTIFY_H_ */