From e1a933792dbf2114d66a3132d2ce29107ed25130 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 31 Aug 2011 13:09:57 +0100 Subject: apt race condition handled --- src/apt-watcher.c | 85 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 23 deletions(-) (limited to 'src/apt-watcher.c') diff --git a/src/apt-watcher.c b/src/apt-watcher.c index a4298a8..e757896 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; @@ -64,6 +65,7 @@ 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); @@ -75,6 +77,7 @@ apt_watcher_init (AptWatcher *self) self->current_state = UP_TO_DATE; self->proxy_cancel = g_cancellable_new(); self->proxy = NULL; + self->reboot_query = 0; self->current_transaction = NULL; g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, @@ -141,7 +144,11 @@ 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); + + /*self->reboot_query = g_timeout_add_seconds (5, + apt_watcher_query_reboot_status, + self);*/ } @@ -245,7 +252,16 @@ apt_watcher_transaction_state_update_cb (AptTransaction* trans, == SIMULATION){ g_object_unref (G_OBJECT(self->current_transaction)); self->current_transaction = NULL; - } + } + if (self->reboot_query != 0){ + g_source_remove (self->reboot_query); + self->reboot_query = 0; + } + // Wait a sec before querying for reboot status, + // race condition with Apt has been observed. + self->reboot_query = g_timeout_add_seconds (1, + apt_watcher_query_reboot_status, + self); } else if (state == UPDATES_AVAILABLE){ dbusmenu_menuitem_property_set (self->apt_item, @@ -266,27 +282,20 @@ apt_watcher_transaction_state_update_cb (AptTransaction* trans, _("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){ - dbusmenu_menuitem_property_set (self->apt_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Software Up to Date")); - } - else{ - 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); - } - g_debug ("Finished with a reboot value of %i", reboot); g_object_unref (G_OBJECT(self->current_transaction)); - self->current_transaction = NULL; + self->current_transaction = NULL; + if (self->reboot_query != 0){ + g_source_remove (self->reboot_query); + self->reboot_query = 0; + } + // Wait a sec before querying for reboot status, + // race condition with Apt has been observed. + self->reboot_query = g_timeout_add_seconds (1, + apt_watcher_query_reboot_status, + self); + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_LABEL, + _("Finished Updating…")); } self->current_state = state; } @@ -302,8 +311,38 @@ apt_watcher_manage_transactions (AptWatcher* self, gchar* transaction_id) } } +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")); + } + else{ + 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); + } + self->reboot_query = 0; + return FALSE; +} + // TODO - Ask MVO about this. -// Signal is of type s not sas which is on d-feet !!! +// Signal is of type s not sas which is on d-feet. static void apt_watcher_signal_cb ( GDBusProxy* proxy, gchar* sender_name, gchar* signal_name, -- cgit v1.2.3 From 55a161683098d17364d9f521d2f4b97f89298297 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 31 Aug 2011 14:32:07 +0100 Subject: tidy up --- src/apt-watcher.c | 6 +----- src/indicator-session.c | 1 - src/session-dbus.xml | 3 --- 3 files changed, 1 insertion(+), 9 deletions(-) (limited to 'src/apt-watcher.c') diff --git a/src/apt-watcher.c b/src/apt-watcher.c index e757896..346b8a9 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -144,11 +144,7 @@ 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->reboot_query = g_timeout_add_seconds (5, - apt_watcher_query_reboot_status, - self);*/ + self); } diff --git a/src/indicator-session.c b/src/indicator-session.c index 3b5a7c3..aacef49 100644 --- a/src/indicator-session.c +++ b/src/indicator-session.c @@ -498,7 +498,6 @@ receive_signal (GDBusProxy * proxy, } } else if (g_strcmp0(signal_name, "RestartRequired") == 0) { - g_debug ("Reboot required, icon changed to %s", ICON_RESTART); self->devices.image = indicator_image_helper (ICON_RESTART); } } diff --git a/src/session-dbus.xml b/src/session-dbus.xml index 076e595..96e9837 100644 --- a/src/session-dbus.xml +++ b/src/session-dbus.xml @@ -8,9 +8,6 @@ - - - -- cgit v1.2.3 From c7a50eedd6e9878547b73e8cf952f75f544cb5d2 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 31 Aug 2011 15:51:16 +0100 Subject: make sure to bring up logout dialog from apt menuitem when restart is required --- src/apt-watcher.c | 35 ++++++++++++++++++++++++------ src/device-menu-mgr.c | 59 --------------------------------------------------- 2 files changed, 28 insertions(+), 66 deletions(-) (limited to 'src/apt-watcher.c') diff --git a/src/apt-watcher.c b/src/apt-watcher.c index 346b8a9..779d02b 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -56,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, @@ -216,14 +216,35 @@ 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); + + gchar* 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); + g_debug("Showing dialog '%s'", dialog_line); + GError * error = NULL; + + 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 diff --git a/src/device-menu-mgr.c b/src/device-menu-mgr.c index 523ea8d..5a63be3 100644 --- a/src/device-menu-mgr.c +++ b/src/device-menu-mgr.c @@ -61,7 +61,6 @@ static DBusGProxyCall * hibernate_call = NULL; static DbusmenuMenuitem * hibernate_mi = NULL; static DbusmenuMenuitem * suspend_mi = NULL; static DbusmenuMenuitem * logout_mi = NULL; -static DbusmenuMenuitem * restart_mi = NULL; static DbusmenuMenuitem * shutdown_mi = NULL; static gboolean can_hibernate = TRUE; @@ -73,7 +72,6 @@ static DBusGProxy * up_main_proxy = NULL; static DBusGProxy * up_prop_proxy = NULL; static void device_menu_mgr_ensure_settings_client (DeviceMenuMgr* self); -static void setup_restart_watch (DeviceMenuMgr* self); static void setup_up (DeviceMenuMgr* self); static void device_menu_mgr_rebuild_items (DeviceMenuMgr *self); static void lock_if_possible (DeviceMenuMgr* self); @@ -106,7 +104,6 @@ device_menu_mgr_init (DeviceMenuMgr *self) { self->apt_watcher = NULL; self->root_item = dbusmenu_menuitem_new (); - setup_restart_watch(self); setup_up(self); g_idle_add(lock_screen_setup, NULL); } @@ -751,62 +748,6 @@ device_menu_mgr_rebuild_items (DeviceMenuMgr* self) can_suspend && allow_suspend); } -/* When the directory changes we need to figure out how our menu - item should look. */ -static void -restart_dir_changed (gpointer userdata) -{ - DeviceMenuMgr* self = DEVICE_MENU_MGR (userdata); - gboolean restart_required = g_file_test("/var/run/reboot-required", G_FILE_TEST_EXISTS); - - if (restart_required) { - if (supress_confirmations()) { - dbusmenu_menuitem_property_set (restart_mi, - RESTART_ITEM_LABEL, - _("Restart to Complete Update")); - } else { - dbusmenu_menuitem_property_set (restart_mi, - RESTART_ITEM_LABEL, - _("Restart to Complete Update\342\200\246")); - } - dbusmenu_menuitem_property_set (restart_mi, - RESTART_ITEM_ICON, - "system-restart-panel"); - if (self->session_dbus_interface != NULL) { - session_dbus_set_name (self->session_dbus_interface, ICON_RESTART); - } - } else { - if (supress_confirmations()) { - dbusmenu_menuitem_property_set(restart_mi, RESTART_ITEM_LABEL, _("Restart")); - } else { - dbusmenu_menuitem_property_set(restart_mi, RESTART_ITEM_LABEL, _("Restart\342\200\246")); - } - dbusmenu_menuitem_property_remove(restart_mi, RESTART_ITEM_ICON); - if (self->session_dbus_interface != NULL) { - session_dbus_set_name(self->session_dbus_interface, ICON_DEFAULT); - } - } - return; -} - -/* Buids a file watcher for the directory so that when it - changes we can check to see if our reboot-required is - there. */ -static void -setup_restart_watch (DeviceMenuMgr* self) -{ - GFile * filedir = g_file_new_for_path("/var/run"); - GFileMonitor * filemon = g_file_monitor_directory(filedir, G_FILE_MONITOR_NONE, NULL, NULL); - if (filemon != NULL) { - g_signal_connect (G_OBJECT(filemon), - "changed", - G_CALLBACK(restart_dir_changed), - self); - } - restart_dir_changed(self); - return; -} - /* Ensures that we have a GConf client and if we build one set up the signal handler. */ static void -- cgit v1.2.3 From 5f9ec570e2e9552273a9a7b4c15cc4f6ce03a3ab Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 31 Aug 2011 18:02:57 +0100 Subject: tidy up --- src/apt-watcher.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/apt-watcher.c') diff --git a/src/apt-watcher.c b/src/apt-watcher.c index 779d02b..d19dc4f 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -221,17 +221,14 @@ apt_watcher_show_apt_dialog (DbusmenuMenuitem * mi, GError * error = NULL; g_return_if_fail (APT_IS_WATCHER (userdata)); AptWatcher* self = APT_WATCHER (userdata); - - gchar* disposition = dbusmenu_menuitem_property_get (self->apt_item, - DBUSMENU_MENUITEM_PROP_DISPOSITION); + 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"); + gchar * dialog_line = g_strdup_printf ("%s --%s", helper, "restart"); g_free(helper); - g_debug("Showing dialog '%s'", dialog_line); - GError * error = NULL; - if (!g_spawn_command_line_async(dialog_line, &error)) { g_warning("Unable to show dialog: %s", error->message); g_error_free(error); -- cgit v1.2.3 From b8b29748d3346c1cabf7ccac301158c709e56f39 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 31 Aug 2011 18:20:08 +0100 Subject: set the menuitem's disposition back to normal just in case --- src/apt-watcher.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/apt-watcher.c') diff --git a/src/apt-watcher.c b/src/apt-watcher.c index d19dc4f..f5c9d55 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -341,6 +341,10 @@ apt_watcher_query_reboot_status (gpointer data) 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, -- cgit v1.2.3 From 374a403e76107ad6696fa67eb9d0313776f47647 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 2 Sep 2011 10:10:47 +0100 Subject: final apt menuitem bugs fixes --- src/apt-transaction.c | 2 +- src/apt-watcher.c | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'src/apt-watcher.c') diff --git a/src/apt-transaction.c b/src/apt-transaction.c index be1c57b..cd9e131 100644 --- a/src/apt-transaction.c +++ b/src/apt-transaction.c @@ -213,7 +213,7 @@ apt_transaction_receive_signal (GDBusProxy * proxy, if (g_variant_is_of_type (role, G_VARIANT_TYPE_STRING) == TRUE){ gchar* current_role = NULL; g_variant_get (role, "s", ¤t_role); - g_debug ("Current transaction role = %s", current_role); + //g_debug ("Current transaction role = %s", current_role); if (g_strcmp0 (current_role, "role-commit-packages") == 0 || g_strcmp0 (current_role, "role-upgrade-system") == 0){ g_debug ("UPGRADE IN PROGRESS"); diff --git a/src/apt-watcher.c b/src/apt-watcher.c index f5c9d55..480e174 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -298,6 +298,11 @@ apt_watcher_transaction_state_update_cb (AptTransaction* trans, else if (state == FINISHED){ g_object_unref (G_OBJECT(self->current_transaction)); self->current_transaction = NULL; + + if (self->current_state == UPDATES_AVAILABLE){ + return; + } + if (self->reboot_query != 0){ g_source_remove (self->reboot_query); self->reboot_query = 0; @@ -359,8 +364,6 @@ apt_watcher_query_reboot_status (gpointer data) return FALSE; } -// TODO - Ask MVO about this. -// Signal is of type s not sas which is on d-feet. static void apt_watcher_signal_cb ( GDBusProxy* proxy, gchar* sender_name, gchar* signal_name, @@ -374,10 +377,13 @@ 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"); + + //gchar** queued = NULL; + g_variant_get(value, "s", ¤t); + if (g_str_has_prefix (current, "/org/debian/apt/transaction/") == TRUE){ + g_debug ("ActiveTransactionsChanged - current is %s", current); if (self->current_transaction != NULL) { @@ -385,7 +391,7 @@ static void apt_watcher_signal_cb ( GDBusProxy* proxy, 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); -- cgit v1.2.3 From 00618412f6db4570b9708f9e4ee61bb64ce37c1b Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 6 Sep 2011 10:57:44 +0100 Subject: another bug found within the apt-menuitem --- src/apt-watcher.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/apt-watcher.c') diff --git a/src/apt-watcher.c b/src/apt-watcher.c index 480e174..167b847 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -380,11 +380,17 @@ static void apt_watcher_signal_cb ( GDBusProxy* proxy, gchar* current = NULL; g_debug ("ActiveTransactionsChanged"); - //gchar** queued = NULL; 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)); -- cgit v1.2.3 From 46db1068e1684293f02125872361f75204399e8f Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 6 Sep 2011 17:59:18 +0100 Subject: refactor the apt state callback because the use case of real and simulation were proving far too disparate --- src/apt-watcher.c | 95 ++++++++++++++++++++++++++++++++----------------- src/indicator-session.c | 3 +- 2 files changed, 65 insertions(+), 33 deletions(-) (limited to 'src/apt-watcher.c') diff --git a/src/apt-watcher.c b/src/apt-watcher.c index 167b847..b0d9688 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -66,6 +66,13 @@ static void apt_watcher_signal_cb (GDBusProxy* proxy, 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); + @@ -245,34 +252,23 @@ apt_watcher_show_apt_dialog (DbusmenuMenuitem * mi, } 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; - } if (self->reboot_query != 0){ g_source_remove (self->reboot_query); self->reboot_query = 0; } - // Wait a sec before querying for reboot status, - // race condition with Apt has been observed. self->reboot_query = g_timeout_add_seconds (1, apt_watcher_query_reboot_status, self); @@ -281,27 +277,15 @@ apt_watcher_transaction_state_update_cb (AptTransaction* trans, 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){ - g_object_unref (G_OBJECT(self->current_transaction)); - self->current_transaction = NULL; - } + 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){ - g_object_unref (G_OBJECT(self->current_transaction)); - self->current_transaction = NULL; - - if (self->current_state == UPDATES_AVAILABLE){ - return; - } if (self->reboot_query != 0){ g_source_remove (self->reboot_query); @@ -312,11 +296,57 @@ apt_watcher_transaction_state_update_cb (AptTransaction* trans, self->reboot_query = g_timeout_add_seconds (1, apt_watcher_query_reboot_status, self); + } + + self->current_state = state; + + if (self->current_state != UPGRADE_IN_PROGRESS){ + g_object_unref (G_OBJECT(self->current_transaction)); + self->current_transaction = NULL; + } +} + + +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 (state == UP_TO_DATE){ + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_LABEL, + _("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 if (state == UPDATES_AVAILABLE){ dbusmenu_menuitem_property_set (self->apt_item, DBUSMENU_MENUITEM_PROP_LABEL, - _("Finished Updating…")); + _("Updates Available…")); } + 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; + } } static void @@ -326,7 +356,7 @@ 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); } } @@ -359,6 +389,7 @@ apt_watcher_query_reboot_status (gpointer data) 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; @@ -384,7 +415,7 @@ static void apt_watcher_signal_cb ( GDBusProxy* proxy, 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); @@ -400,7 +431,7 @@ static void apt_watcher_signal_cb ( GDBusProxy* proxy, 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); } } g_variant_unref (parameters); diff --git a/src/indicator-session.c b/src/indicator-session.c index 2f1764f..f41c841 100644 --- a/src/indicator-session.c +++ b/src/indicator-session.c @@ -507,11 +507,12 @@ receive_signal (GDBusProxy * proxy, &self->users); } } - else if (g_strcmp0(signal_name, "RestartRequired") == 0) { + else if (g_strcmp0(signal_name, "RestartRequired") == 0) { if (greeter_mode == TRUE){ self->devices.image = indicator_image_helper (GREETER_ICON_RESTART); } else{ + g_debug ("reboot required"); self->devices.image = indicator_image_helper (ICON_RESTART); } } -- cgit v1.2.3 From d0d4fd57cf3a25547c570139cc6a311ce05eed44 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 7 Sep 2011 12:04:16 +0100 Subject: more revelations with regards the behaviour of the apt dbus 'api' --- src/apt-transaction.c | 33 ++++++++++++++++----------------- src/apt-watcher.c | 28 ++++++++++++++-------------- 2 files changed, 30 insertions(+), 31 deletions(-) (limited to 'src/apt-watcher.c') diff --git a/src/apt-transaction.c b/src/apt-transaction.c index cd9e131..317d74a 100644 --- a/src/apt-transaction.c +++ b/src/apt-transaction.c @@ -160,7 +160,7 @@ apt_transaction_receive_signal (GDBusProxy * proxy, AptTransaction* self = APT_TRANSACTION(user_data); AptState current_state = DONT_KNOW; - if (g_strcmp0(signal_name, "PropertyChanged") == 0 && self->type == SIMULATION) + if (g_strcmp0(signal_name, "PropertyChanged") == 0) { gchar* prop_name= NULL; GVariant* value = NULL; @@ -204,23 +204,22 @@ apt_transaction_receive_signal (GDBusProxy * proxy, current_state = UP_TO_DATE; } } - } - else if (g_strcmp0(signal_name, "PropertyChanged") == 0 && - self->type == REAL) - { - GVariant* role = g_dbus_proxy_get_cached_property (self->proxy, - "Role"); - if (g_variant_is_of_type (role, G_VARIANT_TYPE_STRING) == TRUE){ - gchar* current_role = NULL; - g_variant_get (role, "s", ¤t_role); - //g_debug ("Current transaction role = %s", current_role); - if (g_strcmp0 (current_role, "role-commit-packages") == 0 || - g_strcmp0 (current_role, "role-upgrade-system") == 0){ - g_debug ("UPGRADE IN PROGRESS"); - current_state = UPGRADE_IN_PROGRESS; + if (self->type == REAL) + { + GVariant* role = g_dbus_proxy_get_cached_property (self->proxy, + "Role"); + if (g_variant_is_of_type (role, G_VARIANT_TYPE_STRING) == TRUE){ + gchar* current_role = NULL; + g_variant_get (role, "s", ¤t_role); + //g_debug ("Current transaction role = %s", current_role); + if (g_strcmp0 (current_role, "role-commit-packages") == 0 || + g_strcmp0 (current_role, "role-upgrade-system") == 0){ + g_debug ("UPGRADE IN PROGRESS"); + current_state = UPGRADE_IN_PROGRESS; + } } - } - } + } + } else if (g_strcmp0(signal_name, "Finished") == 0) { g_debug ("TRANSACTION Finished"); diff --git a/src/apt-watcher.c b/src/apt-watcher.c index b0d9688..1f88868 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -269,7 +269,7 @@ apt_watcher_transaction_state_real_update_cb (AptTransaction* trans, g_source_remove (self->reboot_query); self->reboot_query = 0; } - self->reboot_query = g_timeout_add_seconds (1, + self->reboot_query = g_timeout_add_seconds (2, apt_watcher_query_reboot_status, self); } @@ -277,27 +277,27 @@ apt_watcher_transaction_state_real_update_cb (AptTransaction* trans, 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){ - - if (self->reboot_query != 0){ - g_source_remove (self->reboot_query); - self->reboot_query = 0; + // Only query if the previous state was an upgrade. + if (self->current_state == UPGRADE_IN_PROGRESS){ + if (self->reboot_query != 0){ + g_source_remove (self->reboot_query); + self->reboot_query = 0; + } + // Wait a sec before querying for reboot status, + // race condition with Apt has been observed. + self->reboot_query = g_timeout_add_seconds (2, + apt_watcher_query_reboot_status, + self); } - // Wait a sec before querying for reboot status, - // race condition with Apt has been observed. - self->reboot_query = g_timeout_add_seconds (1, - apt_watcher_query_reboot_status, - self); } - + // Set the current state self->current_state = state; if (self->current_state != UPGRADE_IN_PROGRESS){ @@ -326,7 +326,7 @@ apt_watcher_transaction_state_simulation_update_cb (AptTransaction* trans, g_source_remove (self->reboot_query); self->reboot_query = 0; } - self->reboot_query = g_timeout_add_seconds (1, + self->reboot_query = g_timeout_add_seconds (2, apt_watcher_query_reboot_status, self); } -- cgit v1.2.3 From bc14f0aeb2dbd61c077f1f61c41303f0db4b9781 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 7 Sep 2011 15:34:50 +0100 Subject: more hoop jumping for apt --- src/apt-watcher.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'src/apt-watcher.c') diff --git a/src/apt-watcher.c b/src/apt-watcher.c index 1f88868..d2cd1b5 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -272,18 +272,23 @@ apt_watcher_transaction_state_real_update_cb (AptTransaction* trans, self->reboot_query = g_timeout_add_seconds (2, apt_watcher_query_reboot_status, self); + 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){ if (self->reboot_query != 0){ @@ -296,14 +301,30 @@ apt_watcher_transaction_state_real_update_cb (AptTransaction* trans, apt_watcher_query_reboot_status, self); } - } - // Set the current state - self->current_state = state; - - if (self->current_state != UPGRADE_IN_PROGRESS){ + else{ + query_again = TRUE; + } + self->current_state = state; + g_object_unref (G_OBJECT(self->current_transaction)); self->current_transaction = NULL; - } + // Mental ah yes, because a real transaction (like one which is manually triggered by the user + // by hitting check on update-mgr) does not return a 'dependency' prop update which means + // I cannot figure out from that transaction if an update is available. + // Only when it finishes and I'm confident it was not an transaction concerned with actually updating should i then fire off another transaction, + // this time being a simulation which 'should' figure out if an update is available. + // The Reality is all APT transactions behave differently, an obsolutely nightmare of an API to use. + 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); + } + } } -- cgit v1.2.3 From 058f9cbcbfbe0ed93ce14ad31c5a7ccd14b6d61c Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 7 Sep 2011 16:03:22 +0100 Subject: more hoop jumping for apt --- src/apt-watcher.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src/apt-watcher.c') diff --git a/src/apt-watcher.c b/src/apt-watcher.c index d2cd1b5..bbb541a 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -261,17 +261,11 @@ apt_watcher_transaction_state_real_update_cb (AptTransaction* trans, 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")); - if (self->reboot_query != 0){ - g_source_remove (self->reboot_query); - self->reboot_query = 0; - } - self->reboot_query = g_timeout_add_seconds (2, - apt_watcher_query_reboot_status, - self); self->current_state = state; } else if (state == UPDATES_AVAILABLE){ -- cgit v1.2.3 From b85f29bbd848238a4b60fe2eccf3ead06c47b979 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 7 Sep 2011 21:20:42 +0100 Subject: tidy up --- src/apt-watcher.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/apt-watcher.c') diff --git a/src/apt-watcher.c b/src/apt-watcher.c index bbb541a..e5e1d0e 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -302,12 +302,9 @@ apt_watcher_transaction_state_real_update_cb (AptTransaction* trans, g_object_unref (G_OBJECT(self->current_transaction)); self->current_transaction = NULL; - // Mental ah yes, because a real transaction (like one which is manually triggered by the user - // by hitting check on update-mgr) does not return a 'dependency' prop update which means - // I cannot figure out from that transaction if an update is available. - // Only when it finishes and I'm confident it was not an transaction concerned with actually updating should i then fire off another transaction, - // this time being a simulation which 'should' figure out if an update is available. - // The Reality is all APT transactions behave differently, an obsolutely nightmare of an API to use. + + // It is impossible to determine from a 'real' transaction whether + // updates are available ? if (query_again){ g_dbus_proxy_call (self->proxy, "UpgradeSystem", -- cgit v1.2.3 From 1fc5955836adcb08e047a368b6cdb22f92a92698 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 14 Sep 2011 17:17:55 +0100 Subject: apt property changed reboot required listened for and now the whole apt interaction does not happen until after 60 secs --- src/apt-watcher.c | 196 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 110 insertions(+), 86 deletions(-) (limited to 'src/apt-watcher.c') diff --git a/src/apt-watcher.c b/src/apt-watcher.c index e5e1d0e..2c5ed0b 100644 --- a/src/apt-watcher.c +++ b/src/apt-watcher.c @@ -71,10 +71,8 @@ static void apt_watcher_transaction_state_simulation_update_cb (AptTransaction* gpointer user_data); static void apt_watcher_transaction_state_real_update_cb (AptTransaction* trans, gint update, - gpointer user_data); - - - + gpointer user_data); +static gboolean apt_watcher_start_apt_interaction (gpointer data); G_DEFINE_TYPE (AptWatcher, apt_watcher, G_TYPE_OBJECT); @@ -85,7 +83,17 @@ apt_watcher_init (AptWatcher *self) self->proxy_cancel = g_cancellable_new(); self->proxy = NULL; self->reboot_query = 0; - self->current_transaction = NULL; + 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, @@ -95,6 +103,7 @@ apt_watcher_init (AptWatcher *self) self->proxy_cancel, fetch_proxy_cb, self); + return FALSE; } static void @@ -154,7 +163,6 @@ fetch_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) self); } - static void apt_watcher_on_name_appeared (GDBusConnection *connection, const gchar *name, @@ -169,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), @@ -176,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, @@ -261,60 +272,52 @@ apt_watcher_transaction_state_real_update_cb (AptTransaction* trans, 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")); - 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){ - if (self->reboot_query != 0){ - g_source_remove (self->reboot_query); - self->reboot_query = 0; - } - // Wait a sec before querying for reboot status, - // race condition with Apt has been observed. - self->reboot_query = g_timeout_add_seconds (2, - apt_watcher_query_reboot_status, - self); + 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{ - 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 ? - 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); - } } } @@ -329,32 +332,32 @@ apt_watcher_transaction_state_simulation_update_cb (AptTransaction* trans, 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")); - if (self->reboot_query != 0){ - g_source_remove (self->reboot_query); - self->reboot_query = 0; + 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")); + 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); } - self->reboot_query = g_timeout_add_seconds (2, - apt_watcher_query_reboot_status, - self); - } - else if (state == UPDATES_AVAILABLE){ - dbusmenu_menuitem_property_set (self->apt_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Updates Available…")); - } - else if (state == UPGRADE_IN_PROGRESS){ - dbusmenu_menuitem_property_set (self->apt_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Updates Installing…")); + else if (state == UPDATES_AVAILABLE){ + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_LABEL, + _("Updates Available…")); + } + else if (state == UPGRADE_IN_PROGRESS){ + dbusmenu_menuitem_property_set (self->apt_item, + DBUSMENU_MENUITEM_PROP_LABEL, + _("Updates Installing…")); + } + self->current_state = state; } - - self->current_state = state; - if (self->current_state != UPGRADE_IN_PROGRESS){ g_object_unref (G_OBJECT(self->current_transaction)); self->current_transaction = NULL; @@ -383,7 +386,6 @@ apt_watcher_query_reboot_status (gpointer data) 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, @@ -396,7 +398,7 @@ apt_watcher_query_reboot_status (gpointer data) else{ dbusmenu_menuitem_property_set (self->apt_item, DBUSMENU_MENUITEM_PROP_LABEL, - _("Reboot Required")); + _("Restart to complete updates…")); dbusmenu_menuitem_property_set (self->apt_item, DBUSMENU_MENUITEM_PROP_DISPOSITION, DBUSMENU_MENUITEM_DISPOSITION_ALERT); @@ -446,6 +448,28 @@ static void apt_watcher_signal_cb ( GDBusProxy* proxy, 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); } -- cgit v1.2.3