Commit 9634da32 authored by Giovanni Panozzo's avatar Giovanni Panozzo

Start with usage stats

parent d70108c5
# Remmina - The GTK+ Remote Desktop Client
#
# Copyright (C) 2011 Marc-Andre Moreau
# Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
# Copyright (C) 2016-2018 Antenore Gatta, Giovanni Panozzo
#
# 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 2 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.
include(FindPackageHandleStandardArgs)
pkg_check_modules(PC_JSONGLIB json-glib-1.0)
find_path(JSONGLIB_INCLUDE_DIR NAMES json-glib/json-glib.h
HINTS ${PC_JSONGLIB_INCLUDEDIR} ${PC_JSONGLIB_INCLUDE_DIRS}
)
find_library(JSONGLIB_LIBRARY NAMES json-glib-1.0
HINTS ${PC_JSONGLIB_LIBDIR} ${PC_JSONGLIB_LIBRARY_DIRS}
)
if (JSONGLIB_INCLUDE_DIR AND JSONGLIB_LIBRARY)
find_package_handle_standard_args(JSONGLIB DEFAULT_MSG JSONGLIB_LIBRARY JSONGLIB_INCLUDE_DIR)
endif()
if (JSONGLIB_FOUND)
set(JSONGLIB_LIBRARIES ${JSONGLIB_LIBRARY})
set(JSONGLIB_INCLUDE_DIRS ${JSONGLIB_INCLUDE_DIR})
endif()
mark_as_advanced(JSONGLIB_INCLUDE_DIR JSONGLIB_LIBRARY)
# Remmina - The GTK+ Remote Desktop Client
#
# Copyright (C) 2011 Marc-Andre Moreau
# Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
# Copyright (C) 2016-2018 Antenore Gatta, Giovanni Panozzo
#
# 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 2 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.
include(FindPackageHandleStandardArgs)
pkg_check_modules(PC_LIBSOUP24 libsoup-2.4)
find_path(LIBSOUP24_INCLUDE_DIR NAMES libsoup/soup.h
HINTS ${PC_LIBSOUP24_INCLUDEDIR} ${PC_LIBSOUP24_INCLUDE_DIRS}
)
find_library(LIBSOUP24_LIBRARY
NAMES soup-2.4
HINTS ${PC_LIBSOUP24_LIBDIR} ${PC_LIBSOUP24_LIBRARY_DIRS}
)
if (LIBSOUP24_INCLUDE_DIR AND LIBSOUP24_LIBRARY)
find_package_handle_standard_args(LIBSOUP24 DEFAULT_MSG LIBSOUP24_LIBRARY LIBSOUP24_INCLUDE_DIR)
endif()
if (LIBSOUP24_FOUND)
set(LIBSOUP24_LIBRARIES ${LIBSOUP24_LIBRARY})
set(LIBSOUP24_INCLUDE_DIRS ${LIBSOUP24_INCLUDE_DIR})
endif()
mark_as_advanced(LIBSOUP24_INCLUDE_DIR LIBSOUP24_LIBRARY)
......@@ -112,6 +112,10 @@ list(APPEND REMMINA_SRCS
"src/remmina_connection_window.h"
"src/remmina_mpchange.c"
"src/remmina_mpchange.h"
"src/remmina_stats.c"
"src/remmina_stats.h"
"src/remmina_stats_sender.c"
"src/remmina_stats_sender.h"
)
add_executable(remmina ${REMMINA_SRCS})
......@@ -174,6 +178,20 @@ if(GTK3_FOUND)
include_directories(${APPINDICATOR_INCLUDE_DIRS})
target_link_libraries(remmina ${APPINDICATOR_LIBRARIES})
endif()
find_required_package(JSONGLIB)
if (JSONGLIB_FOUND)
include_directories(${JSONGLIB_INCLUDE_DIRS})
target_link_libraries(remmina ${JSONGLIB_LIBRARIES})
else()
message(FATAL_ERROR "json-glib library not found")
endif()
find_required_package(LIBSOUP24)
if (LIBSOUP24_FOUND)
include_directories(${LIBSOUP24_INCLUDE_DIRS})
target_link_libraries(remmina ${LIBSOUP24_LIBRARIES})
else()
message(FATAL_ERROR "libsoup 2.4 library not found")
endif()
endif()
find_package(Intl)
......
......@@ -53,6 +53,8 @@
#include "remmina_ssh_plugin.h"
#include "remmina_widget_pool.h"
#include "remmina/remmina_trace_calls.h"
#include "remmina_stats_sender.h"
#ifdef HAVE_ERRNO_H
#include <errno.h>
......@@ -201,6 +203,8 @@ static void remmina_on_startup(GApplication *app)
gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(),
REMMINA_RUNTIME_DATADIR G_DIR_SEPARATOR_S "icons");
g_application_hold(app);
remmina_stats_sender_schedule();
}
static gint remmina_on_local_cmdline(GApplication *app, GVariantDict *options, gpointer user_data)
......
......@@ -2,7 +2,7 @@
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2009-2011 Vic Lee
* Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
* Copyright (C) 2016-2017 Antenore Gatta, Giovanni Panozzo
* Copyright (C) 2016-2018 Antenore Gatta, Giovanni Panozzo
*
* 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
......@@ -56,6 +56,7 @@
#include "remmina_mpchange.h"
#include "remmina_external_tools.h"
#include "remmina/remmina_trace_calls.h"
#include "remmina_stats_sender.h"
static RemminaMain *remminamain;
......@@ -1094,6 +1095,38 @@ static void remmina_main_init(void)
remmina_widget_pool_register(GTK_WIDGET(remminamain->window));
}
/* Signal handler for "show" on remminamain->window */
void remmina_main_on_show(GtkWidget *w, gpointer user_data)
{
TRACE_CALL(__func__);
if (!remmina_pref.periodic_usage_stats_permission_asked) {
gtk_widget_set_visible(GTK_WIDGET(remminamain->box_ustat), TRUE);
}
}
void remmina_main_on_click_ustat_yes(GtkWidget *w, gpointer user_data)
{
remmina_pref.periodic_usage_stats_permission_asked = TRUE;
remmina_pref.periodic_usage_stats_permitted = TRUE;
remmina_pref_save();
gtk_widget_set_visible(GTK_WIDGET(remminamain->box_ustat), FALSE);
remmina_stats_sender_schedule();
}
void remmina_main_on_click_ustat_no(GtkWidget *w, gpointer user_data)
{
remmina_pref.periodic_usage_stats_permission_asked = TRUE;
remmina_pref.periodic_usage_stats_permitted = FALSE;
remmina_pref_save();
gtk_widget_set_visible(GTK_WIDGET(remminamain->box_ustat), FALSE);
}
static void remmina_main_on_click_test(GtkWidget *w, gpointer user_data)
{
remmina_stats_sender_send();
}
/* RemminaMain instance */
GtkWidget* remmina_main_new(void)
{
......@@ -1117,6 +1150,7 @@ GtkWidget* remmina_main_new(void)
remminamain->tree_files_list = GTK_TREE_VIEW(GET_OBJECT("tree_files_list"));
remminamain->column_files_list_group = GTK_TREE_VIEW_COLUMN(GET_OBJECT("column_files_list_group"));
remminamain->statusbar_main = GTK_STATUSBAR(GET_OBJECT("statusbar_main"));
remminamain->box_ustat = GTK_BOX(GET_OBJECT("box_ustat"));
/* Non widget objects */
remminamain->accelgroup_shortcuts = GTK_ACCEL_GROUP(GET_OBJECT("accelgroup_shortcuts"));
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
......@@ -1146,6 +1180,16 @@ GtkWidget* remmina_main_new(void)
remminamain->action_help_wiki = GTK_ACTION(GET_OBJECT("action_help_wiki"));
remminamain->action_help_debug = GTK_ACTION(GET_OBJECT("action_help_debug"));
G_GNUC_END_IGNORE_DEPRECATIONS
/* Temporary code to test statistics: add a button */
GtkHeaderBar *hb = GTK_HEADER_BAR(GET_OBJECT("main_headerbar"));
GtkWidget *statbutton = gtk_button_new_with_label("Send test stats");
gtk_header_bar_pack_end(hb, statbutton);
gtk_widget_show(statbutton);
g_signal_connect(G_OBJECT(statbutton), "clicked",
G_CALLBACK(remmina_main_on_click_test), NULL);
/* Connect signals */
gtk_builder_connect_signals(remminamain->builder, NULL);
/* Initialize the window and load the preferences */
......
......@@ -59,6 +59,7 @@ typedef struct _RemminaMain {
GtkTreeView *tree_files_list;
GtkTreeViewColumn *column_files_list_group;
GtkStatusbar *statusbar_main;
GtkBox *box_ustat;
/* Non widget objects */
GtkAccelGroup *accelgroup_shortcuts;
GtkActionGroup *actiongroup_connection;
......
......@@ -674,6 +674,21 @@ void remmina_pref_init(void)
else
remmina_pref.color15 = "#d5ccba";
if (g_key_file_has_key(gkeyfile, "usage_stats", "periodic_usage_stats_permission_asked", NULL))
remmina_pref.periodic_usage_stats_permission_asked = g_key_file_get_boolean(gkeyfile, "usage_stats", "periodic_usage_stats_permission_asked", NULL);
else
remmina_pref.periodic_usage_stats_permission_asked = FALSE;
if (g_key_file_has_key(gkeyfile, "usage_stats", "periodic_usage_stats_permitted", NULL))
remmina_pref.periodic_usage_stats_permitted = g_key_file_get_boolean(gkeyfile, "usage_stats", "periodic_usage_stats_permitted", NULL);
else
remmina_pref.periodic_usage_stats_permitted = FALSE;
if (g_key_file_has_key(gkeyfile, "usage_stats", "periodic_usage_stats_last_sent", NULL))
remmina_pref.periodic_usage_stats_last_sent = g_key_file_get_int64(gkeyfile, "usage_stats", "periodic_usage_stats_last_sent", NULL);
else
remmina_pref.periodic_usage_stats_last_sent = 0;
g_key_file_free(gkeyfile);
#if 0
......@@ -772,6 +787,10 @@ void remmina_pref_save(void)
g_key_file_set_string(gkeyfile, "ssh_colors", "color14", remmina_pref.color14 ? remmina_pref.color14 : "");
g_key_file_set_string(gkeyfile, "ssh_colors", "color15", remmina_pref.color15 ? remmina_pref.color15 : "");
g_key_file_set_boolean(gkeyfile, "usage_stats", "periodic_usage_stats_permission_asked", remmina_pref.periodic_usage_stats_permission_asked);
g_key_file_set_boolean(gkeyfile, "usage_stats", "periodic_usage_stats_permitted", remmina_pref.periodic_usage_stats_permitted);
g_key_file_set_int64(gkeyfile, "usage_stats", "periodic_usage_stats_last_sent", remmina_pref.periodic_usage_stats_last_sent);
content = g_key_file_to_data(gkeyfile, &length, NULL);
g_file_set_contents(remmina_pref_file, content, length, NULL);
......
......@@ -183,6 +183,12 @@ typedef struct _RemminaPref {
gchar *color14;
gchar *color15;
/* Usage stats */
gboolean periodic_usage_stats_permission_asked;
gboolean periodic_usage_stats_permitted;
glong periodic_usage_stats_last_sent;
} RemminaPref;
#define DEFAULT_SSH_PARSECONFIG TRUE
......
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2009-2011 Vic Lee
* Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
* Copyright (C) 2016-2018 Antenore Gatta, Giovanni Panozzo
*
* 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 2 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.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. * If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. * If you
* do not wish to do so, delete this exception statement from your
* version. * If you delete this exception statement from all source
* files in the program, then also delete it here.
*
*/
#include "config.h"
#include <gtk/gtk.h>
#include <string.h>
#include "remmina/remmina_trace_calls.h"
#ifdef GDK_WINDOWING_WAYLAND
#include <gdk/gdkwayland.h>
#endif
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#include "remmina_stats.h"
JsonNode *remmina_stats_get_gtk_version()
{
TRACE_CALL(__func__);
JsonBuilder *b;
JsonNode *r;
/* WARNING: this function is usually executed on a dedicated thread,
* not on the main thread */
b = json_builder_new();
json_builder_begin_object(b);
json_builder_set_member_name(b, "major");
json_builder_add_int_value(b, gtk_get_major_version());
json_builder_set_member_name(b, "minor");
json_builder_add_int_value(b, gtk_get_minor_version());
json_builder_set_member_name(b, "micro");
json_builder_add_int_value(b, gtk_get_micro_version());
json_builder_end_object (b);
r = json_builder_get_root(b);
g_object_unref(b);
return r;
}
JsonNode *remmina_stats_get_gtk_backend()
{
TRACE_CALL(__func__);
JsonNode *r;
GdkDisplay *disp;
gchar *bkend;
/* WARNING: this function is usually executed on a dedicated thread,
* not on the main thread */
disp = gdk_display_get_default();
#ifdef GDK_WINDOWING_WAYLAND
if (GDK_IS_WAYLAND_DISPLAY(disp))
{
bkend = "Wayland";
}
else
#endif
#ifdef GDK_WINDOWING_X11
if (GDK_IS_X11_DISPLAY (disp))
{
bkend = "X11";
}
else
#endif
bkend = "Unknown";
r = json_node_alloc();
json_node_init_string(r, bkend);
return r;
}
JsonNode *remmina_stats_get_uid()
{
TRACE_CALL(__func__);
JsonNode *r;
/* WARNING: this function is usually executed on a dedicated thread,
* not on the main thread */
/* ToDo: Improve UID */
GChecksum *chs;
const gchar *uname, *hname;
const gchar *chss;
uname = g_get_user_name();
hname = g_get_host_name();
chs = g_checksum_new(G_CHECKSUM_SHA256);
g_checksum_update(chs, (const guchar*)uname, strlen(uname));
g_checksum_update(chs, (const guchar*)hname, strlen(hname));
chss = g_checksum_get_string(chs);
r = json_node_alloc();
json_node_init_string(r, chss);
g_checksum_free(chs);
return r;
}
JsonNode *remmina_stats_get_version()
{
TRACE_CALL(__func__);
JsonBuilder *b;
JsonNode *r;
/* WARNING: this function is usually executed on a dedicated thread,
* not on the main thread */
b = json_builder_new();
json_builder_begin_object(b);
json_builder_set_member_name(b, "version");
json_builder_add_string_value(b, VERSION);
json_builder_set_member_name(b, "git_revision");
json_builder_add_string_value(b, REMMINA_GIT_REVISION);
json_builder_set_member_name(b, "snap_build");
#ifdef SNAP_BUILD
json_builder_add_int_value(b, 1);
#else
json_builder_add_int_value(b, 0);
#endif
json_builder_end_object (b);
r = json_builder_get_root(b);
g_object_unref(b);
return r;
}
JsonNode *remmina_stats_get_all()
{
/* Get all statistics in json format to send periodically to the PHP server.
* Return a pointer to the JSON string.
* The caller should free the returned buffer with g_free() */
/* WARNING: this function is usually executed on a dedicated thread,
* not on the main thread */
TRACE_CALL(__func__);
JsonBuilder *b;
JsonNode *n;
b = json_builder_new();
json_builder_begin_object(b);
n = remmina_stats_get_uid();
json_builder_set_member_name(b, "UID");
json_builder_add_value(b, n);
n = remmina_stats_get_version();
json_builder_set_member_name(b, "REMMINAVERSION");
json_builder_add_value(b, n);
n = remmina_stats_get_gtk_version();
json_builder_set_member_name(b, "GTKVERSION");
json_builder_add_value(b, n);
n = remmina_stats_get_gtk_backend();
json_builder_set_member_name(b, "GTKBACKEND");
json_builder_add_value(b, n);
json_builder_end_object(b);
n = json_builder_get_root(b);
g_object_unref(b);
return n;
}
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2009-2011 Vic Lee
* Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
* Copyright (C) 2016-2018 Antenore Gatta, Giovanni Panozzo
*
* 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 2 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.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. * If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. * If you
* do not wish to do so, delete this exception statement from your
* version. * If you delete this exception statement from all source
* files in the program, then also delete it here.
*
*/
#pragma once
G_BEGIN_DECLS
#include "json-glib/json-glib.h"
JsonNode *remmina_stats_get_all(void);
G_END_DECLS
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2009-2011 Vic Lee
* Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
* Copyright (C) 2016-2018 Antenore Gatta, Giovanni Panozzo
*
* 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 2 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.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. * If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. * If you
* do not wish to do so, delete this exception statement from your
* version. * If you delete this exception statement from all source
* files in the program, then also delete it here.
*
*/
#include "config.h"
#include <gtk/gtk.h>
#include <string.h>
#include <libsoup/soup.h>
#include "remmina/remmina_trace_calls.h"
#include "remmina_stats.h"
#include "remmina_pref.h"
#if !JSON_CHECK_VERSION(1,2,0)
#define json_node_unref(x) json_node_free(x)
#endif
/* Timers */
#define PERIODIC_CHECK_1ST_MS 60000
#define PERIODIC_CHECK_INTERVAL_MS 600000
#define PERIODIC_UPLOAD_INTERVAL_SEC 604800
#define PERIODIC_UPLOAD_URL "http://s1.casa.panozzo.it/remmina/upload_stats.php"
static gint periodic_check_source;
static gint periodic_check_counter;
#define DEBUG_HTTP_SERVER_RESPONSE
static void soup_callback(SoupSession *session, SoupMessage *msg, gpointer user_data)
{
TRACE_CALL(__func__);
gchar *s = (gchar *)user_data;
SoupBuffer *sb;
gboolean passed;
GTimeVal t;
g_free(s);
#ifdef DEBUG_HTTP_SERVER_RESPONSE
printf("soup_callback status code is %d\n", msg->status_code);
#endif
if (msg->status_code != 200)
return;
passed = FALSE;
sb = soup_message_body_flatten(msg->response_body);
if (strncmp(sb->data,"200 ", 4) != 0) {
#ifdef DEBUG_HTTP_SERVER_RESPONSE
puts("Error from server side script:");
puts(sb->data);
#endif
} else {
passed = TRUE;
}
soup_buffer_free(sb);
if (passed) {
g_get_current_time(&t);
remmina_pref.periodic_usage_stats_last_sent = t.tv_sec;
remmina_pref_save();
}
}
static gboolean remmina_stats_collector_done(gpointer data)
{
TRACE_CALL(__func__);
JsonNode *n;
JsonGenerator *g;
gchar *s;
SoupSession *ss;
SoupMessage *msg;
n = (JsonNode *)data;
if (n == NULL)
return G_SOURCE_REMOVE;
g = json_generator_new();
json_generator_set_root(g, n);
s = json_generator_to_data(g, NULL);
g_object_unref(g);
json_node_unref(n);
ss = soup_session_new();
msg = soup_message_new("POST", PERIODIC_UPLOAD_URL);
soup_message_set_request(msg, "application/json",
SOUP_MEMORY_COPY, s, strlen (s));
soup_session_queue_message(ss, msg, soup_callback, s);
#ifdef DEBUG_HTTP_SERVER_RESPONSE
printf("Starting upload to url %s\n", PERIODIC_UPLOAD_URL);
#endif
return G_SOURCE_REMOVE;
}
static gpointer remmina_stats_collector(gpointer data)
{
TRACE_CALL(__func__);
JsonNode *n;
n = remmina_stats_get_all();
/* stats collecting is done. Notify main thread calling
* remmina_stats_collector_done() */
g_idle_add(remmina_stats_collector_done, n);
return NULL;
}
void remmina_stats_sender_send()
{
TRACE_CALL(__func__);
g_thread_new("stats_collector", remmina_stats_collector, NULL);
}
static gboolean remmina_stats_sender_periodic_check(gpointer user_data)
{
TRACE_CALL(__func__);
GTimeVal t;
glong next;
if (!remmina_pref.periodic_usage_stats_permission_asked || !remmina_pref.periodic_usage_stats_permitted)
return G_SOURCE_REMOVE;
/* Calculate "next" upload time based on last sent time */
next = remmina_pref.periodic_usage_stats_last_sent + PERIODIC_UPLOAD_INTERVAL_SEC;
g_get_current_time(&t);
/* If current time is after "next" or clock is going back (but > 1/1/2018), then do send stats */
if (t.tv_sec > next || (t.tv_sec < remmina_pref.periodic_usage_stats_last_sent && t.tv_sec > 1514764800)) {
remmina_stats_sender_send();
} else {
#ifdef DEBUG_HTTP_SERVER_RESPONSE
printf("Doing nothing: next upload is scheduled in %ld seconds\n", (next-t.tv_sec));
#endif
}
periodic_check_counter ++;
if (periodic_check_counter <= 1) {
/* Reschedule periodic check less frequently after 1st tick.
* Note that PERIODIC_CHECK_INTERVAL_MS becomes also a retry interval in case of
* upload failure */
periodic_check_source = g_timeout_add_full(G_PRIORITY_LOW, PERIODIC_CHECK_INTERVAL_MS, remmina_stats_sender_periodic_check, NULL, NULL);
return G_SOURCE_REMOVE;
}
return G_SOURCE_CONTINUE;
}
void remmina_stats_sender_schedule()
{
TRACE_CALL(__func__);
/* If permitted, schedule the 1st statistics periodic check */
if (remmina_pref.periodic_usage_stats_permission_asked && remmina_pref.periodic_usage_stats_permitted) {
periodic_check_counter = 0;
periodic_check_source = g_timeout_add_full(G_PRIORITY_LOW, PERIODIC_CHECK_1ST_MS, remmina_stats_sender_periodic_check, NULL, NULL);
} else
periodic_check_source = 0;
}
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2009-2011 Vic Lee
* Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
* Copyright (C) 2016-2018 Antenore Gatta, Giovanni Panozzo
*
* 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 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,