[gnome-settings-daemon] updates: Notify about available offline updates
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] updates: Notify about available offline updates
- Date: Tue, 27 Aug 2013 11:55:43 +0000 (UTC)
commit 4067309278a6848a58aaa8b3203f42a5ccd15bcb
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Aug 23 19:15:58 2013 -0400
updates: Notify about available offline updates
gnome-shell no longer shows a menuitem when a prepared offline
update is available, so the updates plugin needs to take over
the responsibility and pop up a notification in this case.
We monitor /var/lib/PackageKit/prepared-update and show a notification
when the file is created. We don't show it more often than once
every 5 minutes. To handle the case that the file already exists
when gnome-settings-daemon is started, we check for its existence
once, 5 minutes after starting. The notification offers to launch
gnome-software to view details of the prepared update.
If gnome-software is not available, we just trigger the restart
to install the updates directly from the notification.
https://bugzilla.gnome.org/show_bug.cgi?id=706696
plugins/updates/gsd-updates-manager.c | 185 +++++++++++++++++++++++++++++++++
1 files changed, 185 insertions(+), 0 deletions(-)
---
diff --git a/plugins/updates/gsd-updates-manager.c b/plugins/updates/gsd-updates-manager.c
index a230e50..465e55a 100644
--- a/plugins/updates/gsd-updates-manager.c
+++ b/plugins/updates/gsd-updates-manager.c
@@ -66,6 +66,9 @@ struct GsdUpdatesManagerPrivate
GVolumeMonitor *volume_monitor;
guint failed_get_updates_count;
GPtrArray *update_packages;
+ GFile *offline_update_file;
+ GFileMonitor *offline_update_monitor;
+ gboolean offline_update_notified;
};
static void gsd_updates_manager_class_init (GsdUpdatesManagerClass *klass);
@@ -1278,6 +1281,177 @@ out:
return FALSE;
}
+static void
+reboot_failed (GObject *source, GAsyncResult *res, gpointer data)
+{
+ GVariant *ret;
+ const gchar *command;
+ GError *error = NULL;
+
+ ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), res, &error);
+ if (ret)
+ g_variant_unref (ret);
+
+ if (error) {
+ g_warning ("Calling org.gnome.SessionManager.Reboot failed: %s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ command = "pkexec /usr/libexec/pk-trigger-offline-update --cancel";
+ g_debug ("calling '%s'", command);
+ if (!g_spawn_command_line_sync (command, NULL, NULL, NULL, &error)) {
+ g_warning ("Failed to call '%s': %s\n", command, error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+restart_and_install_updates (void)
+{
+ GDBusConnection *bus;
+ const gchar *command;
+ GError *error = NULL;
+
+ command = "pkexec /usr/libexec/pk-trigger-offline-update";
+ g_debug ("calling '%s'", command);
+ if (!g_spawn_command_line_sync (command, NULL, NULL, NULL, &error)) {
+ g_warning ("Failed to call '%s': %s\n", command, error->message);
+ g_error_free (error);
+ return;
+ }
+
+ g_debug ("calling org.gnome.SessionManager.Reboot");
+ bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+ g_dbus_connection_call (bus,
+ "org.gnome.SessionManager",
+ "/org/gnome/SessionManager",
+ "org.gnome.SessionManager",
+ "Reboot",
+ NULL,
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ reboot_failed,
+ NULL);
+ g_object_unref (bus);
+}
+
+static void
+view_updates (void)
+{
+ gboolean ret;
+ GError *error = NULL;
+
+ ret = g_spawn_command_line_async (BINDIR "/gnome-software --mode updates", &error);
+ if (!ret) {
+ g_warning ("Failure launching gnome-software: %s",
+ error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+offline_update_action_cb (NotifyNotification *notification,
+ gchar *action,
+ gpointer user_data)
+{
+
+ notify_notification_close (notification, NULL);
+
+ if (g_strcmp0 (action, "view") == 0) {
+ view_updates ();
+ }
+ else if (g_strcmp0 (action, "install") == 0) {
+ restart_and_install_updates ();
+ }
+}
+
+static gboolean
+reenable_offline_update (gpointer data)
+{
+ GsdUpdatesManager *manager = data;
+
+ manager->priv->offline_update_notified = FALSE;
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+notify_offline_update_available (GsdUpdatesManager *manager)
+{
+ NotifyNotification *notification;
+ const gchar *title;
+ const gchar *body;
+ gboolean ret;
+ GError *error = NULL;
+
+ if (!g_file_query_exists (manager->priv->offline_update_file, NULL))
+ return;
+
+ if (manager->priv->offline_update_notified)
+ return;
+
+ manager->priv->offline_update_notified = TRUE;
+
+ /* don't notify more often than every 5 minutes */
+ g_timeout_add_seconds (300, reenable_offline_update, manager);
+
+ title = _("Software Updates available");
+ body = _("Important OS and application updates are ready to be installed");
+ notification = notify_notification_new (title, body,
+ GSD_UPDATES_ICON_NORMAL);
+ notify_notification_set_hint_string (notification, "desktop-entry", "gnome-software");
+ notify_notification_set_app_name (notification, _("GNOME Software"));
+ notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
+ notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
+ notify_notification_add_action (notification, "ignore",
+ /* TRANSLATORS: don't install updates now */
+ _("Not Now"),
+ offline_update_action_cb,
+ manager, NULL);
+ if (g_find_program_in_path ("gnome-software"))
+ notify_notification_add_action (notification, "view",
+ /* TRANSLATORS: view available updates */
+ _("View"),
+ offline_update_action_cb,
+ manager, NULL);
+ else
+ notify_notification_add_action (notification, "install",
+ /* TRANSLATORS: install available updates */
+ _("Restart & Install"),
+ offline_update_action_cb,
+ manager, NULL);
+ g_signal_connect (notification, "closed",
+ G_CALLBACK (on_notification_closed), NULL);
+ ret = notify_notification_show (notification, &error);
+ if (!ret) {
+ g_warning ("error: %s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+offline_update_cb (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ GsdUpdatesManager *manager)
+{
+ notify_offline_update_available (manager);
+}
+
+static gboolean
+initial_offline_update_check (gpointer data)
+{
+ GsdUpdatesManager *manager = data;
+
+ notify_offline_update_available (manager);
+
+ return G_SOURCE_REMOVE;
+}
+
gboolean
gsd_updates_manager_start (GsdUpdatesManager *manager,
GError **error)
@@ -1363,6 +1537,15 @@ gsd_updates_manager_start (GsdUpdatesManager *manager,
check_offline_update_cb,
manager);
+ manager->priv->offline_update_file = g_file_new_for_path ("/var/lib/PackageKit/prepared-update");
+ manager->priv->offline_update_monitor = g_file_monitor_file (manager->priv->offline_update_file, 0,
NULL, NULL);
+ g_signal_connect (manager->priv->offline_update_monitor, "changed",
+ G_CALLBACK (offline_update_cb), manager);
+
+ g_timeout_add_seconds (300,
+ initial_offline_update_check,
+ manager);
+
/* success */
ret = TRUE;
g_debug ("Started updates manager");
@@ -1385,6 +1568,8 @@ gsd_updates_manager_stop (GsdUpdatesManager *manager)
g_clear_object (&manager->priv->firmware);
g_clear_object (&manager->priv->proxy_session);
g_clear_object (&manager->priv->volume_monitor);
+ g_clear_object (&manager->priv->offline_update_file);
+ g_clear_object (&manager->priv->offline_update_monitor);
if (manager->priv->cancellable) {
g_cancellable_cancel (manager->priv->cancellable);
g_clear_object (&manager->priv->cancellable);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]