Blame SOURCES/0015-subman-Clean-up-notification-behavior.patch

e296c6
From 3412be1f63df2a5967ef92c27028368df1646b5c Mon Sep 17 00:00:00 2001
e296c6
From: Ray Strode <rstrode@redhat.com>
e296c6
Date: Sun, 24 Jan 2021 12:41:20 -0500
e296c6
Subject: [PATCH 15/15] subman: Clean up notification behavior
e296c6
e296c6
Notifications were only displayed for some status transitions.
e296c6
e296c6
This commit introduces some booleans based on the old and new
e296c6
statuses to make the code clearer and to make it easier to hit
e296c6
all the cases.
e296c6
---
e296c6
 plugins/subman/gsd-subman-common.h        |   1 +
e296c6
 plugins/subman/gsd-subscription-manager.c | 141 ++++++++++++++++++----
e296c6
 2 files changed, 120 insertions(+), 22 deletions(-)
e296c6
e296c6
diff --git a/plugins/subman/gsd-subman-common.h b/plugins/subman/gsd-subman-common.h
e296c6
index 88226564..9397dbe4 100644
e296c6
--- a/plugins/subman/gsd-subman-common.h
e296c6
+++ b/plugins/subman/gsd-subman-common.h
e296c6
@@ -1,40 +1,41 @@
e296c6
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
e296c6
  *
e296c6
  * Copyright (C) 2019 Richard Hughes <rhughes@redhat.com>
e296c6
  *
e296c6
  * This program is free software; you can redistribute it and/or modify
e296c6
  * it under the terms of the GNU General Public License as published by
e296c6
  * the Free Software Foundation; either version 2 of the License, or
e296c6
  * (at your option) any later version.
e296c6
  *
e296c6
  * This program is distributed in the hope that it will be useful,
e296c6
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
e296c6
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
e296c6
  * GNU General Public License for more details.
e296c6
  *
e296c6
  * You should have received a copy of the GNU General Public License
e296c6
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
e296c6
  *
e296c6
  */
e296c6
 
e296c6
 #ifndef __GSD_SUBMAN_COMMON_H
e296c6
 #define __GSD_SUBMAN_COMMON_H
e296c6
 
e296c6
 #include <glib-object.h>
e296c6
 
e296c6
 G_BEGIN_DECLS
e296c6
 
e296c6
 typedef enum {
e296c6
+	GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ = -1,
e296c6
 	GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN,
e296c6
 	GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID,
e296c6
 	GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID,
e296c6
 	GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED,
e296c6
 	GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID,
e296c6
 	GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS,
e296c6
 } GsdSubmanSubscriptionStatus;
e296c6
 
e296c6
 const gchar	*gsd_subman_subscription_status_to_string	(GsdSubmanSubscriptionStatus	 status);
e296c6
 
e296c6
 G_END_DECLS
e296c6
 
e296c6
 #endif /* __GSD_SUBMAN_COMMON_H */
e296c6
diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c
e296c6
index 6d80bfa9..aaccbbc6 100644
e296c6
--- a/plugins/subman/gsd-subscription-manager.c
e296c6
+++ b/plugins/subman/gsd-subscription-manager.c
e296c6
@@ -243,60 +243,61 @@ _client_installed_products_update (GsdSubscriptionManager *manager, GError **err
e296c6
 		product->version = g_strdup (json_array_get_string_element (json_product, 2));
e296c6
 		product->arch = g_strdup (json_array_get_string_element (json_product, 3));
e296c6
 		product->status = g_strdup (json_array_get_string_element (json_product, 4));
e296c6
 		product->starts = g_strdup (json_array_get_string_element (json_product, 6));
e296c6
 		product->ends = g_strdup (json_array_get_string_element (json_product, 7));
e296c6
 
e296c6
 		g_ptr_array_add (priv->installed_products, g_steal_pointer (&product));
e296c6
 	}
e296c6
 
e296c6
 	/* emit notification for g-c-c */
e296c6
 	_emit_property_changed (manager, "InstalledProducts",
e296c6
 			       _make_installed_products_variant (priv->installed_products));
e296c6
 
e296c6
 	return TRUE;
e296c6
 }
e296c6
 
e296c6
 static gboolean
e296c6
 _client_subscription_status_update (GsdSubscriptionManager *manager, GError **error)
e296c6
 {
e296c6
 	GsdSubscriptionManagerPrivate *priv = manager->priv;
e296c6
 	g_autoptr(GVariant) uuid = NULL;
e296c6
 	const gchar *uuid_txt = NULL;
e296c6
 	JsonNode *json_root;
e296c6
 	JsonObject *json_obj;
e296c6
 	const gchar *json_txt = NULL;
e296c6
 	g_autoptr(GVariant) status = NULL;
e296c6
 	g_autoptr(JsonParser) json_parser = json_parser_new ();
e296c6
 
e296c6
 	/* save old value */
e296c6
 	priv->subscription_status_last = priv->subscription_status;
e296c6
+
e296c6
 	if (!_client_installed_products_update (manager, error))
e296c6
 		goto out;
e296c6
 
e296c6
 	if (priv->installed_products->len == 0) {
e296c6
 		priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS;
e296c6
 		goto out;
e296c6
 	}
e296c6
 
e296c6
 	uuid = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONSUMER],
e296c6
 				       "GetUuid",
e296c6
 				       g_variant_new ("(s)",
e296c6
 				                      "C.UTF-8"),
e296c6
 				       G_DBUS_CALL_FLAGS_NONE,
e296c6
 				       -1, NULL, error);
e296c6
 	if (uuid == NULL)
e296c6
 		return FALSE;
e296c6
 
e296c6
 	g_variant_get (uuid, "(&s)", &uuid_txt);
e296c6
 
e296c6
 	if (uuid_txt[0] == '\0') {
e296c6
 		priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN;
e296c6
 		goto out;
e296c6
 	}
e296c6
 
e296c6
 	status = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT],
e296c6
 				         "GetStatus",
e296c6
 				         g_variant_new ("(ss)",
e296c6
 						        "", /* assumed as 'now' */
e296c6
 						        "C.UTF-8"),
e296c6
 				         G_DBUS_CALL_FLAGS_NONE,
e296c6
@@ -485,109 +486,203 @@ typedef enum {
e296c6
 static void
e296c6
 _show_notification (GsdSubscriptionManager *manager, _NotifyKind notify_kind)
e296c6
 {
e296c6
 	GsdSubscriptionManagerPrivate *priv = manager->priv;
e296c6
 	switch (notify_kind) {
e296c6
 	case _NOTIFY_EXPIRED:
e296c6
 		notify_notification_close (priv->notification_registered, NULL);
e296c6
 		notify_notification_close (priv->notification_registration_required, NULL);
e296c6
 		notify_notification_show (priv->notification_expired, NULL);
e296c6
 		break;
e296c6
 	case _NOTIFY_REGISTRATION_REQUIRED:
e296c6
 		notify_notification_close (priv->notification_registered, NULL);
e296c6
 		notify_notification_close (priv->notification_expired, NULL);
e296c6
 		notify_notification_show (priv->notification_registration_required, NULL);
e296c6
 		break;
e296c6
 	case _NOTIFY_REGISTERED:
e296c6
 		notify_notification_close (priv->notification_expired, NULL);
e296c6
 		notify_notification_close (priv->notification_registration_required, NULL);
e296c6
 		notify_notification_show (priv->notification_registered, NULL);
e296c6
 		break;
e296c6
 	default:
e296c6
 		break;
e296c6
 	}
e296c6
 	g_timer_reset (priv->timer_last_notified);
e296c6
 }
e296c6
 
e296c6
 static void
e296c6
 _client_maybe__show_notification (GsdSubscriptionManager *manager)
e296c6
 {
e296c6
 	GsdSubscriptionManagerPrivate *priv = manager->priv;
e296c6
+	gboolean was_read, was_registered, had_subscriptions, needed_subscriptions;
e296c6
+	gboolean is_read, is_registered, has_subscriptions, needs_subscriptions;
e296c6
+
e296c6
+	switch (priv->subscription_status_last) {
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ:
e296c6
+			was_read = FALSE;
e296c6
+			was_registered = FALSE;
e296c6
+			needed_subscriptions = TRUE;
e296c6
+			had_subscriptions = FALSE;
e296c6
+			break;
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN:
e296c6
+			was_read = TRUE;
e296c6
+			was_registered = FALSE;
e296c6
+			needed_subscriptions = TRUE;
e296c6
+			had_subscriptions = FALSE;
e296c6
+			break;
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID:
e296c6
+			was_read = TRUE;
e296c6
+			was_registered = TRUE;
e296c6
+			needed_subscriptions = TRUE;
e296c6
+			had_subscriptions = TRUE;
e296c6
+			break;
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID:
e296c6
+			was_read = TRUE;
e296c6
+			was_registered = TRUE;
e296c6
+			needed_subscriptions = TRUE;
e296c6
+			had_subscriptions = FALSE;
e296c6
+			break;
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED:
e296c6
+			was_read = TRUE;
e296c6
+			was_registered = TRUE;
e296c6
+			needed_subscriptions = FALSE;
e296c6
+			had_subscriptions = FALSE;
e296c6
+			break;
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID:
e296c6
+			was_read = TRUE;
e296c6
+			was_registered = TRUE;
e296c6
+			needed_subscriptions = TRUE;
e296c6
+			had_subscriptions = FALSE;
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS:
e296c6
+			was_read = TRUE;
e296c6
+			was_registered = FALSE;
e296c6
+			needed_subscriptions = FALSE;
e296c6
+			had_subscriptions = FALSE;
e296c6
+			break;
e296c6
+	}
e296c6
+
e296c6
+	switch (priv->subscription_status) {
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ:
e296c6
+			is_read = FALSE;
e296c6
+			is_registered = FALSE;
e296c6
+			needs_subscriptions = TRUE;
e296c6
+			has_subscriptions = FALSE;
e296c6
+			break;
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN:
e296c6
+			is_read = TRUE;
e296c6
+			is_registered = FALSE;
e296c6
+			needs_subscriptions = TRUE;
e296c6
+			has_subscriptions = FALSE;
e296c6
+			break;
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID:
e296c6
+			is_read = TRUE;
e296c6
+			is_registered = TRUE;
e296c6
+			needs_subscriptions = TRUE;
e296c6
+			has_subscriptions = TRUE;
e296c6
+			break;
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID:
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID:
e296c6
+			is_read = TRUE;
e296c6
+			is_registered = TRUE;
e296c6
+			needs_subscriptions = TRUE;
e296c6
+			has_subscriptions = FALSE;
e296c6
+			break;
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED:
e296c6
+			is_read = TRUE;
e296c6
+			is_registered = TRUE;
e296c6
+			needs_subscriptions = FALSE;
e296c6
+			has_subscriptions = FALSE;
e296c6
+			break;
e296c6
+		case GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS:
e296c6
+			is_read = TRUE;
e296c6
+			is_registered = FALSE;
e296c6
+			needs_subscriptions = FALSE;
e296c6
+			has_subscriptions = FALSE;
e296c6
+			break;
e296c6
+	}
e296c6
 
e296c6
 	/* startup */
e296c6
-	if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN &&
e296c6
-	    priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN) {
e296c6
+	if (!was_read && is_read && priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN) {
e296c6
 		_show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED);
e296c6
 		return;
e296c6
 	}
e296c6
 
e296c6
 	/* something changed */
e296c6
-	if (priv->subscription_status_last != priv->subscription_status) {
e296c6
+	if (was_read && is_read && priv->subscription_status_last != priv->subscription_status) {
e296c6
 		g_debug ("transisition from subscription status '%s' to '%s'",
e296c6
 			 gsd_subman_subscription_status_to_string (priv->subscription_status_last),
e296c6
 			 gsd_subman_subscription_status_to_string (priv->subscription_status));
e296c6
 
e296c6
-		/* needs registration */
e296c6
-		if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID &&
e296c6
-		    priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID) {
e296c6
-			_show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED);
e296c6
+		/* needs subscription */
e296c6
+		if (is_registered && needs_subscriptions && !has_subscriptions) {
e296c6
+			_show_notification (manager, _NOTIFY_EXPIRED);
e296c6
 			return;
e296c6
 		}
e296c6
 
e296c6
 		/* was unregistered */
e296c6
-		if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID &&
e296c6
-		    priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN) {
e296c6
+		if (was_registered && !is_registered) {
e296c6
 			_show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED);
e296c6
 			return;
e296c6
 		}
e296c6
 
e296c6
-		/* registered */
e296c6
-		if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN &&
e296c6
-		    priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID &&
e296c6
-		    g_timer_elapsed (priv->timer_last_notified, NULL) > 60) {
e296c6
-			_show_notification (manager, _NOTIFY_REGISTERED);
e296c6
-			return;
e296c6
+		/* just registered */
e296c6
+		if (!was_registered && is_registered) {
e296c6
+			if (!needs_subscriptions || has_subscriptions) {
e296c6
+				_show_notification (manager, _NOTIFY_REGISTERED);
e296c6
+				return;
e296c6
+			}
e296c6
+		}
e296c6
+
e296c6
+		/* subscriptions changed */
e296c6
+		if (was_registered && is_registered) {
e296c6
+			/* subscribed */
e296c6
+			if (!had_subscriptions &&
e296c6
+			    needs_subscriptions && has_subscriptions) {
e296c6
+				_show_notification (manager, _NOTIFY_REGISTERED);
e296c6
+				return;
e296c6
+			}
e296c6
+
e296c6
+			/* simple content access enabled */
e296c6
+			if (needed_subscriptions && !had_subscriptions && !needs_subscriptions) {
e296c6
+				_show_notification (manager, _NOTIFY_REGISTERED);
e296c6
+				return;
e296c6
+			}
e296c6
 		}
e296c6
 	}
e296c6
 
e296c6
 	/* nag again */
e296c6
-	if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN &&
e296c6
+	if (!is_registered &&
e296c6
 	    g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) {
e296c6
 		_show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED);
e296c6
 		return;
e296c6
 	}
e296c6
-	if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID &&
e296c6
-	    g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) {
e296c6
-		_show_notification (manager, _NOTIFY_EXPIRED);
e296c6
-		return;
e296c6
-	}
e296c6
-	if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID &&
e296c6
+	if (is_registered && !has_subscriptions && needs_subscriptions &&
e296c6
 	    g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) {
e296c6
 		_show_notification (manager, _NOTIFY_EXPIRED);
e296c6
 		return;
e296c6
 	}
e296c6
 }
e296c6
 
e296c6
 static gboolean
e296c6
 _client_register_with_keys (GsdSubscriptionManager *manager,
e296c6
 				  const gchar *hostname,
e296c6
 				  const gchar *organisation,
e296c6
 				  const gchar *activation_key,
e296c6
 				  GError **error)
e296c6
 {
e296c6
 	GsdSubscriptionManagerPrivate *priv = manager->priv;
e296c6
 	g_autoptr(GSubprocess) subprocess = NULL;
e296c6
 	g_autoptr(GBytes) stdin_buf = g_bytes_new (activation_key, strlen (activation_key) + 1);
e296c6
 	g_autoptr(GBytes) stderr_buf = NULL;
e296c6
 	gint rc;
e296c6
 
e296c6
 	/* apparently: "we can't send registration credentials over the regular
e296c6
 	 * system or session bus since those aren't really locked down..." */
e296c6
 	if (!_client_register_start (manager, error))
e296c6
 		return FALSE;
e296c6
 	g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper");
e296c6
 	subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE, error,
e296c6
 				       "pkexec", LIBEXECDIR "/gsd-subman-helper",
e296c6
 				       "--kind", "register-with-key",
e296c6
 				       "--address", priv->address,
e296c6
 				       "--hostname", hostname,
e296c6
 				       "--organisation", organisation,
e296c6
@@ -914,60 +1009,62 @@ gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass)
e296c6
 static void
e296c6
 _launch_info_overview (void)
e296c6
 {
e296c6
 	const gchar *argv[] = { "gnome-control-center", "info-overview", NULL };
e296c6
 	g_debug ("Running gnome-control-center info-overview");
e296c6
 	g_spawn_async (NULL, (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH,
e296c6
 		       NULL, NULL, NULL, NULL);
e296c6
 }
e296c6
 
e296c6
 static void
e296c6
 _notify_closed_cb (NotifyNotification *notification, gpointer user_data)
e296c6
 {
e296c6
 	/* FIXME: only launch when clicking on the main body, not the window close */
e296c6
 	if (notify_notification_get_closed_reason (notification) == 0x400)
e296c6
 		_launch_info_overview ();
e296c6
 }
e296c6
 
e296c6
 static void
e296c6
 _notify_clicked_cb (NotifyNotification *notification, char *action, gpointer user_data)
e296c6
 {
e296c6
 	_launch_info_overview ();
e296c6
 }
e296c6
 
e296c6
 static void
e296c6
 gsd_subscription_manager_init (GsdSubscriptionManager *manager)
e296c6
 {
e296c6
 	GsdSubscriptionManagerPrivate *priv = manager->priv = GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE (manager);
e296c6
 
e296c6
 	priv->installed_products = g_ptr_array_new_with_free_func ((GDestroyNotify) product_data_free);
e296c6
 	priv->timer_last_notified = g_timer_new ();
e296c6
+	priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ;
e296c6
+	priv->subscription_status_last = GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ;
e296c6
 
e296c6
 	/* expired */
e296c6
 	priv->notification_expired =
e296c6
 		notify_notification_new (_("Subscription Has Expired"),
e296c6
 					 _("Add or renew a subscription to continue receiving software updates."),
e296c6
 					 NULL);
e296c6
 	notify_notification_set_app_name (priv->notification_expired, _("Subscription"));
e296c6
 	notify_notification_set_hint_string (priv->notification_expired, "desktop-entry", "subman-panel");
e296c6
 	notify_notification_set_hint_string (priv->notification_expired, "x-gnome-privacy-scope", "system");
e296c6
 	notify_notification_set_urgency (priv->notification_expired, NOTIFY_URGENCY_CRITICAL);
e296c6
 	notify_notification_add_action (priv->notification_expired,
e296c6
 					"info-overview", _("Subscribe System…"),
e296c6
 					_notify_clicked_cb,
e296c6
 					manager, NULL);
e296c6
 	g_signal_connect (priv->notification_expired, "closed",
e296c6
 			  G_CALLBACK (_notify_closed_cb), manager);
e296c6
 
e296c6
 	/* registered */
e296c6
 	priv->notification_registered =
e296c6
 		notify_notification_new (_("Registration Successful"),
e296c6
 					 _("The system has been registered and software updates have been enabled."),
e296c6
 					 NULL);
e296c6
 	notify_notification_set_app_name (priv->notification_registered, _("Subscription"));
e296c6
 	notify_notification_set_hint_string (priv->notification_registered, "desktop-entry", "subman-panel");
e296c6
 	notify_notification_set_hint_string (priv->notification_registered, "x-gnome-privacy-scope", "system");
e296c6
 	notify_notification_set_urgency (priv->notification_registered, NOTIFY_URGENCY_CRITICAL);
e296c6
 	g_signal_connect (priv->notification_registered, "closed",
e296c6
 			  G_CALLBACK (_notify_closed_cb), manager);
e296c6
 
e296c6
 	/* registration required */
e296c6
-- 
e296c6
2.30.0
e296c6