diff options
author | Ted Gould <ted@gould.cx> | 2011-09-27 16:55:41 -0500 |
---|---|---|
committer | Ted Gould <ted@gould.cx> | 2011-09-27 16:55:41 -0500 |
commit | 1e3f1b724bfbb1283b482ddd11db1ee417e4eeb3 (patch) | |
tree | 831776c7d01e111e88cd7767aa3cfc3d9d1f93f6 /src/apt-watcher.c | |
parent | a316c5aac1ea8928f5da7cc916d534ea6eb7ab5e (diff) | |
parent | 18f3158453229388605760aa8e738a9adb65109b (diff) | |
download | ayatana-indicator-session-1e3f1b724bfbb1283b482ddd11db1ee417e4eeb3.tar.gz ayatana-indicator-session-1e3f1b724bfbb1283b482ddd11db1ee417e4eeb3.tar.bz2 ayatana-indicator-session-1e3f1b724bfbb1283b482ddd11db1ee417e4eeb3.zip |
Update to ubuntu-desktop version
Diffstat (limited to 'src/apt-watcher.c')
-rw-r--r-- | src/apt-watcher.c | 278 |
1 files changed, 207 insertions, 71 deletions
diff --git a/src/apt-watcher.c b/src/apt-watcher.c index a4298a8..2c5ed0b 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -27,6 +27,7 @@ static guint watcher_id; struct _AptWatcher { GObject parent_instance; + guint reboot_query; GCancellable * proxy_cancel; GDBusProxy * proxy; SessionDbus* session_dbus_interface; @@ -55,7 +56,7 @@ static void apt_watcher_upgrade_system_cb (GObject * obj, static void apt_watcher_show_apt_dialog (DbusmenuMenuitem* mi, guint timestamp, - gchar * type); + gpointer userdata); static void apt_watcher_signal_cb (GDBusProxy* proxy, gchar* sender_name, @@ -64,8 +65,14 @@ static void apt_watcher_signal_cb (GDBusProxy* proxy, gpointer user_data); static void apt_watcher_manage_transactions (AptWatcher* self, gchar* transaction_id); - - +static gboolean apt_watcher_query_reboot_status (gpointer self); +static void apt_watcher_transaction_state_simulation_update_cb (AptTransaction* trans, + gint update, + gpointer user_data); +static void apt_watcher_transaction_state_real_update_cb (AptTransaction* trans, + gint update, + gpointer user_data); +static gboolean apt_watcher_start_apt_interaction (gpointer data); G_DEFINE_TYPE (AptWatcher, apt_watcher, G_TYPE_OBJECT); @@ -75,7 +82,18 @@ apt_watcher_init (AptWatcher *self) self->current_state = UP_TO_DATE; self->proxy_cancel = g_cancellable_new(); self->proxy = NULL; - self->current_transaction = NULL; + self->reboot_query = 0; + self->current_transaction = NULL; + g_timeout_add_seconds (60, + apt_watcher_start_apt_interaction, + self); +} + +static gboolean +apt_watcher_start_apt_interaction (gpointer data) +{ + g_return_val_if_fail (APT_IS_WATCHER (data), FALSE); + AptWatcher* self = APT_WATCHER (data); g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, @@ -85,6 +103,7 @@ apt_watcher_init (AptWatcher *self) self->proxy_cancel, fetch_proxy_cb, self); + return FALSE; } static void @@ -141,10 +160,9 @@ fetch_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) g_signal_connect (self->proxy, "g-signal", G_CALLBACK(apt_watcher_signal_cb), - self); + self); } - static void apt_watcher_on_name_appeared (GDBusConnection *connection, const gchar *name, @@ -159,6 +177,8 @@ apt_watcher_on_name_appeared (GDBusConnection *connection, "the system bus", name_owner); + apt_watcher_query_reboot_status (user_data); + g_dbus_proxy_call (watcher->proxy, "UpgradeSystem", g_variant_new("(b)", TRUE), @@ -166,9 +186,10 @@ apt_watcher_on_name_appeared (GDBusConnection *connection, -1, NULL, apt_watcher_upgrade_system_cb, - user_data); + user_data); } + static void apt_watcher_on_name_vanished (GDBusConnection *connection, const gchar *name, @@ -213,82 +234,134 @@ apt_watcher_upgrade_system_cb (GObject * obj, static void apt_watcher_show_apt_dialog (DbusmenuMenuitem * mi, guint timestamp, - gchar * type) + gpointer userdata) { GError * error = NULL; - if (!g_spawn_command_line_async("update-manager", &error)) - { - g_warning("Unable to show update-manager: %s", error->message); - g_error_free(error); - } + g_return_if_fail (APT_IS_WATCHER (userdata)); + AptWatcher* self = APT_WATCHER (userdata); + const gchar* disposition = NULL; + disposition = dbusmenu_menuitem_property_get (self->apt_item, + DBUSMENU_MENUITEM_PROP_DISPOSITION); + + if (g_strcmp0 (disposition, DBUSMENU_MENUITEM_DISPOSITION_ALERT) == 0){ + gchar * helper = g_build_filename (LIBEXECDIR, "gtk-logout-helper", NULL); + gchar * dialog_line = g_strdup_printf ("%s --%s", helper, "restart"); + g_free(helper); + if (!g_spawn_command_line_async(dialog_line, &error)) { + g_warning("Unable to show dialog: %s", error->message); + g_error_free(error); + } + g_free(dialog_line); + } + else{ + if (!g_spawn_command_line_async("update-manager", &error)) + { + g_warning("Unable to show update-manager: %s", error->message); + g_error_free(error); + } + } } static void -apt_watcher_transaction_state_update_cb (AptTransaction* trans, - gint update, - gpointer user_data) +apt_watcher_transaction_state_real_update_cb (AptTransaction* trans, + gint update, + gpointer user_data) { g_debug ("apt-watcher -transaction update %i", update); g_return_if_fail (APT_IS_WATCHER (user_data)); AptWatcher* self = APT_WATCHER (user_data); AptState state = (AptState)update; - - if (state == UP_TO_DATE){ - dbusmenu_menuitem_property_set (self->apt_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Software Up to Date")); - // Simulations don't send a finished signal for some reason - // Anyway from a simulation we just need one state update - // (updates available or not) - if (apt_transaction_get_transaction_type (self->current_transaction) - == SIMULATION){ - g_object_unref (G_OBJECT(self->current_transaction)); - self->current_transaction = NULL; - } - } - else if (state == UPDATES_AVAILABLE){ - dbusmenu_menuitem_property_set (self->apt_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Updates Available…")); - // Simulations don't send a finished signal for some reason - // Anyway from a simulation we just need one state update - // (updates available or not) - if (apt_transaction_get_transaction_type (self->current_transaction) - == SIMULATION){ + if (self->current_state != RESTART_NEEDED) + { + if (state == UP_TO_DATE){ + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_LABEL, + _("Software Up to Date")); + self->current_state = state; + } + else if (state == UPDATES_AVAILABLE){ + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_LABEL, + _("Updates Available…")); + self->current_state = state; + } + else if (state == UPGRADE_IN_PROGRESS){ + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_LABEL, + _("Updates Installing…")); + self->current_state = state; + } + else if (state == FINISHED){ + gboolean query_again = FALSE; + + // Only query if the previous state was an upgrade. + if (self->current_state != UPGRADE_IN_PROGRESS){ + query_again = TRUE; + } + self->current_state = state; + g_object_unref (G_OBJECT(self->current_transaction)); self->current_transaction = NULL; - } + + // It is impossible to determine from a 'real' transaction whether + // updates are available therefore it is necessary to check again via a + // simulation whether there are updates available. + if (query_again){ + g_dbus_proxy_call (self->proxy, + "UpgradeSystem", + g_variant_new("(b)", TRUE), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + apt_watcher_upgrade_system_cb, + self); + } + } } - else if (state == UPGRADE_IN_PROGRESS){ - dbusmenu_menuitem_property_set (self->apt_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Updates Installing…")); - } - else if (state == FINISHED){ - GVariant* reboot_result = g_dbus_proxy_get_cached_property (self->proxy, - "RebootRequired"); - gboolean reboot; - g_variant_get (reboot_result, "b", &reboot); - if (reboot == FALSE){ +} + + +static void +apt_watcher_transaction_state_simulation_update_cb (AptTransaction* trans, + gint update, + gpointer user_data) +{ + g_debug ("apt-watcher -transaction update %i", update); + g_return_if_fail (APT_IS_WATCHER (user_data)); + AptWatcher* self = APT_WATCHER (user_data); + + AptState state = (AptState)update; + if (self->current_state != RESTART_NEEDED) + { + if (state == UP_TO_DATE){ dbusmenu_menuitem_property_set (self->apt_item, DBUSMENU_MENUITEM_PROP_LABEL, - _("Software Up to Date")); + _("Software Up to Date")); + if (self->reboot_query != 0){ + g_source_remove (self->reboot_query); + self->reboot_query = 0; + } + self->reboot_query = g_timeout_add_seconds (1, + apt_watcher_query_reboot_status, + self); } - else{ + else if (state == UPDATES_AVAILABLE){ dbusmenu_menuitem_property_set (self->apt_item, DBUSMENU_MENUITEM_PROP_LABEL, - _("Reboot Required")); - dbusmenu_menuitem_property_set (self->apt_item, - DBUSMENU_MENUITEM_PROP_DISPOSITION, - DBUSMENU_MENUITEM_DISPOSITION_ALERT); - session_dbus_restart_required (self->session_dbus_interface); + _("Updates Available…")); } - g_debug ("Finished with a reboot value of %i", reboot); + else if (state == UPGRADE_IN_PROGRESS){ + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_LABEL, + _("Updates Installing…")); + } + self->current_state = state; + } + if (self->current_state != UPGRADE_IN_PROGRESS){ g_object_unref (G_OBJECT(self->current_transaction)); - self->current_transaction = NULL; + self->current_transaction = NULL; } - self->current_state = state; } static void @@ -298,12 +371,44 @@ apt_watcher_manage_transactions (AptWatcher* self, gchar* transaction_id) self->current_transaction = apt_transaction_new (transaction_id, SIMULATION); g_signal_connect (G_OBJECT(self->current_transaction), "state-update", - G_CALLBACK(apt_watcher_transaction_state_update_cb), self); + G_CALLBACK(apt_watcher_transaction_state_simulation_update_cb), self); } } -// TODO - Ask MVO about this. -// Signal is of type s not sas which is on d-feet !!! +static gboolean +apt_watcher_query_reboot_status (gpointer data) +{ + g_return_val_if_fail (APT_IS_WATCHER (data), FALSE); + AptWatcher* self = APT_WATCHER (data); + + GVariant* reboot_result = g_dbus_proxy_get_cached_property (self->proxy, + "RebootRequired"); + gboolean reboot; + g_variant_get (reboot_result, "b", &reboot); + g_debug ("apt_watcher_query_reboot_status: reboot prop = %i", reboot); + if (reboot == FALSE){ + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_LABEL, + _("Software Up to Date")); + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_DISPOSITION, + DBUSMENU_MENUITEM_DISPOSITION_NORMAL); + + } + else{ + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_LABEL, + _("Restart to complete updates…")); + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_DISPOSITION, + DBUSMENU_MENUITEM_DISPOSITION_ALERT); + session_dbus_restart_required (self->session_dbus_interface); + self->current_state = RESTART_NEEDED; + } + self->reboot_query = 0; + return FALSE; +} + static void apt_watcher_signal_cb ( GDBusProxy* proxy, gchar* sender_name, gchar* signal_name, @@ -317,23 +422,54 @@ static void apt_watcher_signal_cb ( GDBusProxy* proxy, GVariant *value = g_variant_get_child_value (parameters, 0); if (g_strcmp0(signal_name, "ActiveTransactionsChanged") == 0){ - gchar* input = NULL; - g_variant_get(value, "s", & input); - if (g_str_has_prefix (input, "/org/debian/apt/transaction/") == TRUE){ - g_debug ("Active Transactions signal - input is null = %i", input == NULL); - + gchar* current = NULL; + g_debug ("ActiveTransactionsChanged"); + + g_variant_get(value, "s", ¤t); + + if (g_str_has_prefix (current, "/org/debian/apt/transaction/") == TRUE){ + g_debug ("ActiveTransactionsChanged - current is %s", current); + + // Cancel all existing operations. + if (self->reboot_query != 0){ + g_source_remove (self->reboot_query); + self->reboot_query = 0; + } + if (self->current_transaction != NULL) { g_object_unref (G_OBJECT(self->current_transaction)); self->current_transaction = NULL; } - self->current_transaction = apt_transaction_new (input, REAL); + self->current_transaction = apt_transaction_new (current, REAL); g_signal_connect (G_OBJECT(self->current_transaction), "state-update", - G_CALLBACK(apt_watcher_transaction_state_update_cb), self); + G_CALLBACK(apt_watcher_transaction_state_real_update_cb), self); } } + else if (g_strcmp0(signal_name, "PropertyChanged") == 0) + { + gchar* prop_name= NULL; + GVariant* value = NULL; + g_variant_get (parameters, "(sv)", &prop_name, &value); + g_debug ("transaction prop update - prop = %s", prop_name); + + if (g_strcmp0 (prop_name, "RebootRequired") == 0){ + gboolean reboot_required = FALSE; + g_variant_get (value, "(b)", &reboot_required); + if (reboot_required){ + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_LABEL, + _("Restart to complete updates…")); + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_DISPOSITION, + DBUSMENU_MENUITEM_DISPOSITION_ALERT); + self->current_state = RESTART_NEEDED; + } + } + } + g_variant_unref (parameters); } |